From 55fcc908ef26703c8d3da79248ecbc5749ca85dd Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 7 Apr 2025 11:51:24 +0200 Subject: [PATCH] feat(nestjs): migrate to NestJS --- packages/server-nest/.eslintrc.js | 25 - packages/server-nest/.gitignore | 56 - packages/server-nest/README.md | 1 - packages/server-nest/package.json | 151 - ...29121920_add_seed_at_column_to_accounts.ts | 7 - .../20220429121920_create_projects_table.ts | 93 - ...9121922_add_project_id_to_expense_lines.ts | 7 - .../core/20190423085242_seed_accounts.ts | 21 - .../core/20200810121809_seed_settings.ts | 53 - .../20200810121909_seed_items_settings.ts | 34 - .../seeds/core/20210810121909_seed_roles.ts | 28 - .../20210812121909_seed_roles_permissions.ts | 49 - .../20210912121909_seed_credit_settings.ts | 22 - .../core/20230912121909_seed_tax_rates.ts | 14 - ...230912121909_update_tax_payable_account.ts | 16 - .../src/database/seeds/core/index.ts | 1 - .../src/database/seeds/data/TaxRates.ts | 30 - .../server-nest/src/interfaces/Account.ts | 170 - packages/server-nest/src/interfaces/Item.ts | 165 - packages/server-nest/src/interfaces/Model.ts | 195 - packages/server-nest/src/models/Model.ts | 43 - .../src/utils/address-text-format.ts | 113 - packages/server-nest/src/utils/deepdash.ts | 131 - packages/server-nest/tsconfig.json | 25 - packages/server/.babelrc | 8 - packages/{server-nest => server}/.env.example | 0 packages/server/.eslintrc.js | 41 +- packages/server/.gitignore | 60 +- packages/{server-nest => server}/.prettierrc | 0 packages/{server-nest => server}/.todo | 0 packages/server/Dockerfile | 110 - packages/server/README.md | 2 +- packages/server/knexfile.js | 17 - .../{server-nest => server}/nest-cli.json | 0 packages/server/package.json | 240 +- packages/server/public/.DS_Store | Bin 6148 -> 0 bytes packages/server/public/imports/.DS_Store | Bin 6148 -> 0 bytes .../resources/css/modules/credit-rtl.css | 553 -- .../server/resources/css/modules/credit.css | 553 -- .../resources/css/modules/estimate-rtl.css | 544 -- .../server/resources/css/modules/estimate.css | 544 -- .../resources/css/modules/invoice-rtl.css | 553 -- .../server/resources/css/modules/invoice.css | 553 -- .../resources/css/modules/payment-rtl.css | 553 -- .../server/resources/css/modules/payment.css | 553 -- .../resources/css/modules/receipt-rtl.css | 546 -- .../server/resources/css/modules/receipt.css | 546 -- packages/server/resources/locales/ar.json | 640 -- packages/server/resources/locales/en.json | 675 -- packages/server/resources/scss/base.css | 40 - packages/server/resources/scss/base.scss | 1 - packages/server/resources/scss/fonts.scss | 26 - .../resources/scss/layouts/paper-layout.scss | 19 - .../server/resources/scss/modules/credit.scss | 193 - .../resources/scss/modules/estimate.scss | 174 - .../scss/modules/export-resource-table.scss | 38 - .../scss/modules/financial-sheet.scss | 57 - .../resources/scss/modules/invoice.scss | 183 - .../resources/scss/modules/payment.scss | 178 - .../resources/scss/modules/receipt.scss | 185 - packages/server/resources/scss/normalize.css | 379 - packages/server/resources/scss/normalize.scss | 379 - .../resources/views/PaperTemplateLayout.pug | 10 - .../views/modules/credit-note-standard.pug | 227 - .../views/modules/export-resource-table.pug | 24 - .../views/modules/financial-sheet.pug | 25 - packages/server/scripts/gulpConfig.js | 147 - packages/server/scripts/gulpfile.js | 50 - packages/server/scripts/install.sh | 4 - packages/server/scripts/run_test_db.sh | 31 - packages/server/scripts/webpack.cli.js | 11 - packages/server/scripts/webpack.common.js | 79 - packages/server/scripts/webpack.config.js | 11 - .../src/api/controllers/Account/index.ts | 52 - .../src/api/controllers/AccountTypes.ts | 42 - .../server/src/api/controllers/Accounts.ts | 519 -- .../server/src/api/controllers/Agendash.ts | 24 - .../Attachments/AttachmentsController.ts | 266 - .../src/api/controllers/Authentication.ts | 375 - .../Banking/BankAccountsController.ts | 218 - .../BankTransactionsMatchingController.ts | 101 - .../controllers/Banking/BankingController.ts | 39 - .../Banking/BankingRulesController.ts | 214 - .../Banking/BankingUncategorizedController.ts | 57 - .../ExcludeBankTransactionsController.ts | 201 - .../Banking/PlaidBankingController.ts | 53 - .../RecognizedTransactionsController.ts | 91 - .../src/api/controllers/BaseController.ts | 140 - .../src/api/controllers/Branches/index.ts | 335 - .../Cashflow/CashflowController.ts | 25 - .../Cashflow/DeleteCashflowTransaction.ts | 112 - .../Cashflow/GetCashflowAccounts.ts | 69 - .../Cashflow/GetCashflowTransaction.ts | 143 - .../Cashflow/NewCashflowTransaction.ts | 412 -- .../src/api/controllers/Contacts/Contacts.ts | 379 - .../src/api/controllers/Contacts/Customers.ts | 344 - .../src/api/controllers/Contacts/Vendors.ts | 329 - .../server/src/api/controllers/Currencies.ts | 213 - .../src/api/controllers/Dashboard/index.ts | 47 - .../src/api/controllers/ExchangeRates.ts | 123 - .../src/api/controllers/Expenses/Expenses.ts | 466 -- .../src/api/controllers/Expenses/index.ts | 15 - .../controllers/Export/ExportController.ts | 87 - .../src/api/controllers/Export/_utils.ts | 13 - .../api/controllers/FinancialStatements.ts | 112 - .../FinancialStatements/APAgingSummary.ts | 121 - .../FinancialStatements/ARAgingSummary.ts | 119 - .../FinancialStatements/BalanceSheet.ts | 150 - .../BaseFinancialReportController.ts | 23 - .../FinancialStatements/CashFlow/CashFlow.ts | 129 - .../CashflowAccountTransactions/index.ts | 168 - .../CustomerBalanceSummary/index.ts | 137 - .../FinancialStatements/GeneralLedger.ts | 116 - .../InventoryDetails/index.ts | 150 - .../InventoryValuationSheet.ts | 126 - .../FinancialStatements/JournalSheet.ts | 115 - .../FinancialStatements/ProfitLossSheet.ts | 146 - .../ProjectProfitabilitySummary/index.ts | 151 - .../FinancialStatements/PurchasesByItem.ts | 119 - .../FinancialStatements/SalesByItems.ts | 113 - .../SalesTaxLiabilitySummary/index.ts | 122 - .../TransactionsByCustomers/index.ts | 128 - .../TransactionsByReference/index.ts | 89 - .../TransactionsByVendors/index.ts | 128 - .../FinancialStatements/TrialBalanceSheet.ts | 135 - .../VendorBalanceSummary/index.ts | 127 - .../controllers/Import/ImportController.ts | 246 - .../src/api/controllers/Import/_utils.ts | 34 - .../Inventory/InventortyItemsCosts.ts | 57 - .../Inventory/InventoryAdjustments.ts | 345 - .../server/src/api/controllers/InviteUsers.ts | 270 - .../src/api/controllers/ItemCategories.ts | 306 - .../server/src/api/controllers/Items/Items.ts | 536 -- .../controllers/Items/ItemsTransactions.ts | 137 - .../server/src/api/controllers/Items/index.ts | 17 - packages/server/src/api/controllers/Jobs.ts | 60 - .../src/api/controllers/ManualJournals.ts | 476 -- packages/server/src/api/controllers/Media.ts | 211 - .../api/controllers/Miscellaneous/index.ts | 41 - .../OneClickDemo/OneClickDemoController.ts | 87 - .../src/api/controllers/Organization.ts | 225 - .../api/controllers/OrganizationDashboard.ts | 124 - .../PaymentServicesController.ts | 179 - .../PdfTemplates/PdfTemplatesController.ts | 195 - packages/server/src/api/controllers/Ping.ts | 28 - .../src/api/controllers/Projects/Projects.ts | 248 - .../src/api/controllers/Projects/Tasks.ts | 211 - .../src/api/controllers/Projects/Times.ts | 253 - .../src/api/controllers/Purchases/Bills.ts | 599 -- .../controllers/Purchases/BillsPayments.ts | 469 -- .../api/controllers/Purchases/LandedCost.ts | 305 - .../api/controllers/Purchases/VendorCredit.ts | 680 -- .../Purchases/VendorCreditApplyToBills.ts | 226 - .../src/api/controllers/Purchases/index.ts | 25 - .../server/src/api/controllers/Resources.ts | 78 - .../controllers/Roles/PermissionsSchema.ts | 41 - .../server/src/api/controllers/Roles/Roles.ts | 254 - .../server/src/api/controllers/Roles/index.ts | 22 - .../Sales/CreditNoteApplyToBills.ts | 0 .../src/api/controllers/Sales/CreditNotes.ts | 883 --- .../api/controllers/Sales/PaymentReceives.ts | 754 -- .../api/controllers/Sales/SalesEstimates.ts | 733 -- .../api/controllers/Sales/SalesInvoices.ts | 987 --- .../api/controllers/Sales/SalesReceipts.ts | 666 -- .../server/src/api/controllers/Sales/index.ts | 24 - .../Settings/EasySmsIntegration.ts | 110 - .../src/api/controllers/Settings/Settings.ts | 111 - .../Settings/SmsNotificationsSettings.ts | 168 - .../src/api/controllers/Settings/index.ts | 23 - .../ShareLink/PublicSharableLinkController.ts | 118 - .../ShareLink/ShareLinkController.ts | 63 - .../StripeIntegrationController.ts | 122 - .../StripeWebhooksController.ts | 83 - .../Subscription/SubscriptionController.ts | 180 - .../src/api/controllers/Subscription/index.ts | 1 - .../src/api/controllers/TaxRates/TaxRates.ts | 278 - .../controllers/TransactionsLocking/index.ts | 284 - .../controllers/TransactionsLocking/utils.ts | 24 - packages/server/src/api/controllers/Users.ts | 289 - packages/server/src/api/controllers/Views.ts | 123 - .../Warehouses/WarehouseTransfers.ts | 407 -- .../controllers/Warehouses/WarehousesItem.ts | 47 - .../src/api/controllers/Warehouses/index.ts | 337 - .../src/api/controllers/Webhooks/Webhooks.ts | 83 - .../api/exceptions/GlobalErrorException.ts | 20 - .../api/exceptions/ObjectionErrorException.ts | 120 - .../api/exceptions/ServiceErrorException.ts | 25 - packages/server/src/api/index.ts | 184 - .../api/middleware/AsyncRenderMiddleware.ts | 23 - .../api/middleware/AttachCurrentTenantUser.ts | 39 - .../api/middleware/AuthorizationMiddleware.ts | 92 - .../src/api/middleware/CheckPolicies.ts | 18 - .../middleware/ConvertEmptyStringsToNull.ts | 13 - .../middleware/EnsureTenantIsInitialized.ts | 21 - .../api/middleware/EnsureTenantIsSeeded.ts | 21 - .../api/middleware/FeatureActivationGuard.ts | 18 - .../middleware/I18nAuthenticatedMiddlware.ts | 37 - .../src/api/middleware/I18nMiddleware.ts | 22 - .../api/middleware/JSONResponseTransformer.ts | 37 - .../src/api/middleware/LoggerMiddleware.ts | 11 - .../middleware/LoginThrottlerMiddleware.ts | 24 - .../api/middleware/RateLimiterMiddleware.ts | 16 - .../src/api/middleware/SettingsMiddleware.ts | 32 - .../api/middleware/SubscriptionMiddleware.ts | 33 - .../src/api/middleware/TenancyMiddleware.ts | 36 - .../middleware/TenantDependencyInjection.ts | 69 - .../src/api/middleware/asyncMiddleware.ts | 14 - packages/server/src/api/middleware/jwtAuth.ts | 32 - packages/server/src/before.ts | 12 - .../server/src/collection/BudgetEntriesSet.ts | 76 - packages/server/src/collection/Cachable.ts | 0 packages/server/src/collection/Metable.ts | 279 - .../server/src/collection/NestedSet/index.ts | 116 - .../ResourceFieldMetadataCollection.ts | 14 - .../src/collection/SoftDeleteQueryBuilder.ts | 73 - packages/server/src/commands/bigcapital.ts | 296 - packages/server/src/commands/index.ts | 4 - .../src/common/config/gotenberg.ts | 0 .../src/common/config/index.ts | 0 .../src/common/config/inventory.ts | 0 .../src/common/config/jwt.ts | 0 .../src/common/config/lemonsqueezy.ts | 0 .../src/common/config/loops.ts | 0 .../src/common/config/mail.ts | 0 .../src/common/config/open-exchange.ts | 0 .../src/common/config/plaid.ts | 0 .../src/common/config/posthog.ts | 0 .../src/common/config/redis.ts | 0 .../src/common/config/s3.ts | 0 .../src/common/config/signup-confirmation.ts | 0 .../src/common/config/signup-restrictions.ts | 0 .../src/common/config/signup.ts | 0 .../src/common/config/stripe-payment.ts | 0 .../src/common/config/system-database.ts | 0 .../src/common/config/tenant-database.ts | 0 .../src/common/constants/files.constants.ts | 0 .../src/common/constants/multer.constants.ts | 0 .../src/common/constants/multer.utils.ts | 0 .../src/common/events/events.ts | 0 .../common/exceptions/ModelEntityNotFound.ts | 0 .../common/filters/service-error.filter.ts | 0 .../common/interceptors/file.interceptor.ts | 0 .../interceptors/serialize.interceptor.ts | 0 .../src/common/pipes/ClassValidation.pipe.ts | 0 .../src/common/pipes/ZodValidation.pipe.ts | 0 .../common/repository/CachableRepository.ts | 0 .../src/common/repository/EntityRepository.ts | 0 .../src/common/repository/TenantRepository.ts | 0 .../src/common/types/Constructor.ts | 0 .../src/common/types/Date.ts | 0 .../src/common/types/Discount.ts | 0 .../src/common/types/Features.ts | 0 packages/server/src/config/index.ts | 275 - packages/server/src/config/knexConfig.ts | 59 - .../server/src/config/smsNotifications.ts | 207 - .../src/constants/accept-type.ts | 0 .../src/constants/accounts.ts | 0 .../src/constants/data-types.ts | 0 .../server/src/constants/event-tracker.ts | 130 - .../src/constants/metable-options.ts | 0 packages/server/src/data/AccountTypes.ts | 230 - .../server/src/data/BalanceSheetStructure.ts | 96 - packages/server/src/data/DataTypes.ts | 8 - .../server/src/data/ResourceFieldsKeys.ts | 205 - packages/server/src/data/TransactionTypes.ts | 35 - packages/server/src/data/options.ts | 241 - .../server/src/database/factories/index.js | 390 -- .../server/src/database/factories/system.js | 16 - .../20190822214303_create_accounts_table.js | 19 - .../20190822214303_create_accounts_table.ts | 0 ...822214304_create_items_categories_table.js | 19 - ...822214304_create_items_categories_table.ts | 0 .../20190822214306_create_items_table.js | 30 - .../20190822214306_create_items_table.ts | 0 .../20190822214903_create_views_table.js | 15 - .../20190822214903_create_views_table.ts | 0 .../20190822214904_create_settings_table.js | 13 - .../20190822214904_create_settings_table.ts | 0 .../20190822214905_create_views_columns.js | 11 - .../20190822214905_create_views_columns.ts | 0 ...20190822214905_create_views_roles_table.js | 19 - ...20190822214905_create_views_roles_table.ts | 0 .../20200104232644_create_contacts_table.js | 54 - .../20200104232644_create_contacts_table.ts | 0 ...2647_create_accounts_transactions_table.js | 36 - ...2647_create_accounts_transactions_table.ts | 0 .../20200105014405_create_expenses_table.js | 29 - .../20200105014405_create_expenses_table.ts | 0 ...0105195823_create_manual_journals_table.js | 21 - ...0105195823_create_manual_journals_table.ts | 0 ...25_create_manual_journals_entries_table.js | 17 - ...25_create_manual_journals_entries_table.ts | 0 .../20200419171451_create_currencies_table.js | 14 - .../20200419171451_create_currencies_table.ts | 0 ...00419191832_create_exchange_rates_table.js | 14 - ...00419191832_create_exchange_rates_table.ts | 0 .../20200423201600_create_media_table.js | 12 - .../20200423201600_create_media_table.ts | 0 ...20200503032011_create_media_links_table.js | 13 - ...20200503032011_create_media_links_table.ts | 0 ...e_expense_transactions_categories_table.js | 29 - ...e_expense_transactions_categories_table.ts | 0 ...0713192127_create_sales_estimates_table.js | 35 - ...0713192127_create_sales_estimates_table.ts | 0 ...200713213303_create_sales_receipt_table.js | 22 - ...200713213303_create_sales_receipt_table.ts | 0 ...200715193633_create_sale_invoices_table.js | 34 - ...200715193633_create_sale_invoices_table.ts | 0 ...715194514_create_payment_receives_table.js | 30 - ...715194514_create_payment_receives_table.ts | 0 ...1_create_payment_receives_entries_table.js | 23 - ...1_create_payment_receives_entries_table.ts | 0 .../20200719152005_create_bills_table.js | 31 - .../20200719152005_create_bills_table.ts | 0 ...00719153909_create_bills_payments_table.js | 21 - ...00719153909_create_bills_payments_table.ts | 0 ...251_create_inventory_transactions_table.js | 24 - ...251_create_inventory_transactions_table.ts | 0 ...20200722164252_create_landed_cost_table.js | 21 - ...20200722164252_create_landed_cost_table.ts | 0 ...164253_create_landed_cost_entries_table.js | 11 - ...164253_create_landed_cost_entries_table.ts | 0 ...create_inventory_transaction_meta_table.js | 11 - ...create_inventory_transaction_meta_table.ts | 0 ...200722173423_create_items_entries_table.js | 39 - ...200722173423_create_items_entries_table.ts | 0 ...0728161617_create_bill_payments_entries.js | 23 - ...0728161617_create_bill_payments_entries.ts | 0 ...create_inventory_cost_lot_tracker_table.js | 26 - ...create_inventory_cost_lot_tracker_table.ts | 0 ...1809_create_inventory_adjustments_table.js | 19 - ...1809_create_inventory_adjustments_table.ts | 0 ...ate_inventory_adjustments_entries_table.js | 25 - ...ate_inventory_adjustments_entries_table.ts | 0 ...1910_create_cashflow_transactions_table.js | 18 - ...1910_create_cashflow_transactions_table.ts | 0 ...create_cashflow_transaction_lines_table.js | 23 - ...create_cashflow_transaction_lines_table.ts | 0 ...0121910_add_invoices_writtenoff_columns.js | 13 - ...0121910_add_invoices_writtenoff_columns.ts | 0 ...costable_column_to_account_transactions.js | 11 - ...costable_column_to_account_transactions.ts | 0 .../20211014121910_add_roles_table.js | 21 - .../20211014121910_add_roles_table.ts | 0 .../20211112121920_create_users_table.js | 19 - .../20211112121920_create_users_table.ts | 0 ...0211122121920_create_credit_notes_table.js | 28 - ...0211122121920_create_credit_notes_table.ts | 0 ...11122121920_create_vendor_credits_table.js | 23 - ...11122121920_create_vendor_credits_table.ts | 0 ...121920_create_refund_transactions_table.js | 45 - ...121920_create_refund_transactions_table.ts | 0 ...920_create_credit_note_applies_invoices.js | 35 - ...920_create_credit_note_applies_invoices.ts | 0 .../20220124121920_create_branches_table.js | 24 - .../20220124121920_create_branches_table.ts | 0 .../20220124121920_create_warehouses_table.js | 59 - .../20220124121920_create_warehouses_table.ts | 0 ...021920_create_items_warehouses_quantity.js | 16 - ...021920_create_items_warehouses_quantity.ts | 0 ..._branch_column_to_accounts_transactions.js | 86 - ..._branch_column_to_accounts_transactions.ts | 0 ...d_branch_warehouse_columns_to_purchases.js | 65 - ...d_branch_warehouse_columns_to_purchases.ts | 0 ...0_add_branch_warehouse_columns_to_sales.js | 84 - ...0_add_branch_warehouse_columns_to_sales.ts | 0 ...ehouse_column_to_inventory_transactions.js | 40 - ...ehouse_column_to_inventory_transactions.ts | 0 ...0_add_warehouse_column_to_items_entries.js | 15 - ...0_add_warehouse_column_to_items_entries.ts | 0 ...21920_add_exchange_rate_to_transactions.js | 114 - ...21920_add_exchange_rate_to_transactions.ts | 0 ..._writtenoff_expense_account_to_invoices.js | 15 - ..._writtenoff_expense_account_to_invoices.ts | 0 ...ame_contacts_shipping_billing_addresses.js | 19 - ...ame_contacts_shipping_billing_addresses.ts | 0 ...20329121920_add_cashflow_credit_account.js | 18 - ...20329121920_add_cashflow_credit_account.ts | 0 ...0405232607_drop_phone_number_from_users.js | 9 - ...0405232607_drop_phone_number_from_users.ts | 0 .../20230810191606_create_tax_rates.js | 52 - .../20230810191606_create_tax_rates.ts | 0 ..._add_tax_amount_withheld_to_bills_table.js | 10 - ..._add_tax_amount_withheld_to_bills_table.ts | 0 ...36_add_sell_purchase_tax_to_items_table.js | 18 - ...36_add_sell_purchase_tax_to_items_table.ts | 0 .../20231108170207_create_storage_table.js | 14 - .../20231108170207_create_storage_table.ts | 0 ...24014_change_item_entries_rate_to_float.js | 9 - ...24014_change_item_entries_rate_to_float.ts | 0 ...20240201160214_create_plaid_items_Table.js | 14 - ...20240201160214_create_plaid_items_Table.ts | 0 ..._add_plaid_account_id_to_accounts_table.js | 9 - ..._add_plaid_account_id_to_accounts_table.ts | 0 ..._transaction_id_to_cashflow_transaction.js | 7 - ..._transaction_id_to_cashflow_transaction.ts | 0 ...cateogrized_cashflow_transactions_table.js | 28 - ...cateogrized_cashflow_transactions_table.ts | 0 ...d_transactions_column_to_accounts_table.js | 10 - ...d_transactions_column_to_accounts_table.ts | 0 ...transaction_id_to_cashflow_transactions.js | 15 - ...transaction_id_to_cashflow_transactions.ts | 0 .../20240604153938_drop_storage_table.js | 5 - .../20240604153938_drop_storage_table.ts | 0 .../20240604153951_create_documents_table.js | 14 - .../20240604153951_create_documents_table.ts | 0 ...0604154005_create_documents_links_table.js | 14 - ...0604154005_create_documents_links_table.ts | 0 .../20240618100137_create_bank_rules_table.js | 45 - .../20240618100137_create_bank_rules_table.ts | 0 ...eate_recognized_bank_transactions_table.js | 31 - ...eate_recognized_bank_transactions_table.ts | 0 ...n_id_to_uncategorized_transactins_table.js | 16 - ...n_id_to_uncategorized_transactins_table.ts | 0 ..._create_matched_bank_transactions_table.js | 18 - ..._create_matched_bank_transactions_table.ts | 0 ...categorized_cashflow_transactions_table.js | 11 - ...categorized_cashflow_transactions_table.ts | 0 ...categorized_cashflow_transactions_table.js | 11 - ...categorized_cashflow_transactions_table.ts | 0 ...704064858_change_settings_value_to_text.js | 11 - ...704064858_change_settings_value_to_text.ts | 0 ...saction_type_to_transaction_type_column.js | 60 - ...saction_type_to_transaction_type_column.ts | 0 ...732_add_plaid_item_id_to_accounts_table.js | 11 - ...732_add_plaid_item_id_to_accounts_table.ts | 0 ..._add_is_syncing_owner_to_accounts_table.js | 19 - ..._add_is_syncing_owner_to_accounts_table.ts | 0 ...sion_in_bills_and_sales_invoices_tables.js | 18 - ...sion_in_bills_and_sales_invoices_tables.ts | 0 ...e_paused_at_column_to_plaid_items_table.js | 11 - ...e_paused_at_column_to_plaid_items_table.ts | 0 ...umn_to_uncategorized_transactions_table.js | 13 - ...umn_to_uncategorized_transactions_table.ts | 0 ..._stripe_pintent_id_to_payments_received.js | 19 - ..._stripe_pintent_id_to_payments_received.ts | 0 ...240911112147_create_pdf_templates_table.js | 75 - ...240911112147_create_pdf_templates_table.ts | 0 .../20240915155403_payment_integration.js | 25 - .../20240915155403_payment_integration.ts | 0 ...creat_transaction_payment_service_table.js | 27 - ...creat_transaction_payment_service_table.ts | 0 ...40915195024_seed_standard_pdf_templates.js | 44 - ...40915195024_seed_standard_pdf_templates.ts | 0 ...ge_quantity_in_items_entries_to_decimal.js | 39 - ...ge_quantity_in_items_entries_to_decimal.ts | 0 ...28080734_add_discount_to_invoices_table.js | 23 - ...28080734_add_discount_to_invoices_table.ts | 0 ...8081259_add_discount_to_estimates_table.js | 24 - ...8081259_add_discount_to_estimates_table.ts | 0 ...28084550_add_discount_to_receipts_table.js | 24 - ...28084550_add_discount_to_receipts_table.ts | 0 ...41128085243_add_discount_to_bills_table.js | 26 - ...41128085243_add_discount_to_bills_table.ts | 0 ...0222_add_discount_to_credit_notes_table.js | 23 - ...0222_add_discount_to_credit_notes_table.ts | 0 ...04_add_discount_to_vendor_credits_table.js | 23 - ...04_add_discount_to_vendor_credits_table.ts | 0 ...dd_discount_type_to_items_entries_table.js | 19 - ...dd_discount_type_to_items_entries_table.ts | 0 packages/server/src/database/objection.ts | 8 - .../core/20190423085242_seed_accounts.ts | 8 +- .../core/20200810121809_seed_settings.ts | 2 +- .../20200810121909_seed_items_settings.ts | 2 +- .../seeds/core/20210810121909_seed_roles.ts | 2 +- .../20210812121909_seed_roles_permissions.ts | 2 +- .../20210912121909_seed_credit_settings.ts | 2 +- .../core/20230912121909_seed_tax_rates.ts | 2 +- ...230912121909_update_tax_payable_account.ts | 2 +- .../src/database/seeds/data/accounts.js | 395 -- .../src/database/seeds/data/accounts.ts | 0 .../server/src/decorators/eventDispatcher.ts | 11 - .../server/src/exceptions/HttpException.ts | 9 - .../src/exceptions/ModelEntityNotFound.ts | 8 - .../NotAllowedChangeSubscriptionPlan.ts | 8 - .../server/src/exceptions/ServiceError.ts | 14 - .../server/src/exceptions/ServiceErrors.ts | 15 - .../exceptions/TenantAlreadyInitialized.ts | 3 - .../src/exceptions/TenantAlreadySeeded.ts | 3 - .../src/exceptions/TenantDBAlreadyExists.ts | 9 - .../src/exceptions/TenantDatabaseNotBuilt.ts | 3 - packages/server/src/exceptions/index.ts | 17 - .../src/i18n/en/test.json | 0 .../interceptors/ExcludeNull.interceptor.ts | 0 .../interceptors/global-prefix.interceptor.ts | 0 .../src/interceptors/user-ip.interceptor.ts | 0 .../src/interfaces/APAgingSummaryReport.ts | 45 - .../src/interfaces/ARAgingSummaryReport.ts | 42 - packages/server/src/interfaces/Account.ts | 9 +- packages/server/src/interfaces/AgingReport.ts | 51 - packages/server/src/interfaces/Attachments.ts | 3 - .../server/src/interfaces/Authentication.ts | 95 - .../server/src/interfaces/BalanceSheet.ts | 223 - packages/server/src/interfaces/Bill.ts | 177 - packages/server/src/interfaces/BillPayment.ts | 121 - packages/server/src/interfaces/Branches.ts | 50 - packages/server/src/interfaces/CashFlow.ts | 301 - .../server/src/interfaces/CashflowService.ts | 185 - packages/server/src/interfaces/Contact.ts | 392 -- .../src/interfaces/ContactBalanceSummary.ts | 47 - packages/server/src/interfaces/CreditNote.ts | 323 - packages/server/src/interfaces/Currency.ts | 27 - .../src/interfaces/CustomerBalanceSummary.ts | 60 - .../server/src/interfaces/DynamicFilter.ts | 38 - packages/server/src/interfaces/Entry.ts | 18 - .../server/src/interfaces/ExchangeRate.ts | 10 - packages/server/src/interfaces/Expenses.ts | 204 - packages/server/src/interfaces/Features.ts | 16 - .../CashflowAccountTransactions/index.ts | 37 - .../src/interfaces/FinancialStatements.ts | 54 - .../src/interfaces/GeneralLedgerSheet.ts | 92 - packages/server/src/interfaces/Http.ts | 8 - .../interfaces/IInventoryValuationSheet.ts | 61 - packages/server/src/interfaces/Import.ts | 8 - .../src/interfaces/InventoryAdjustment.ts | 100 - .../server/src/interfaces/InventoryCost.ts | 16 - .../src/interfaces/InventoryCostMethod.ts | 6 - .../server/src/interfaces/InventoryDetails.ts | 100 - .../src/interfaces/InventoryTransaction.ts | 95 - packages/server/src/interfaces/Item.ts | 103 +- .../server/src/interfaces/ItemCategory.ts | 87 - packages/server/src/interfaces/ItemEntry.ts | 71 - packages/server/src/interfaces/Jobs.ts | 14 - packages/server/src/interfaces/Journal.ts | 55 - .../server/src/interfaces/JournalReport.ts | 53 - packages/server/src/interfaces/LandedCost.ts | 153 - packages/server/src/interfaces/Ledger.ts | 87 - packages/server/src/interfaces/License.ts | 25 - packages/server/src/interfaces/Mailable.ts | 44 - .../server/src/interfaces/ManualJournal.ts | 176 - packages/server/src/interfaces/Media.ts | 25 - packages/server/src/interfaces/Metable.ts | 28 - packages/server/src/interfaces/Model.ts | 11 +- packages/server/src/interfaces/Options.ts | 11 - packages/server/src/interfaces/Payment.ts | 20 - .../server/src/interfaces/PaymentReceive.ts | 246 - packages/server/src/interfaces/Plaid.ts | 65 - packages/server/src/interfaces/Preferences.ts | 6 - .../server/src/interfaces/ProfitLossSheet.ts | 187 - packages/server/src/interfaces/Project.ts | 160 - .../interfaces/ProjectProfitabilitySummary.ts | 54 - .../src/interfaces/PurchasesByItemsSheet.ts | 58 - packages/server/src/interfaces/Resource.ts | 22 - packages/server/src/interfaces/Roles.ts | 122 - .../server/src/interfaces/SaleEstimate.ts | 165 - packages/server/src/interfaces/SaleInvoice.ts | 391 -- packages/server/src/interfaces/SaleReceipt.ts | 238 - .../src/interfaces/SalesByItemsSheet.ts | 58 - .../interfaces/SalesTaxLiabilitySummary.ts | 60 - packages/server/src/interfaces/Setup.ts | 51 - .../server/src/interfaces/SmsNotifications.ts | 51 - .../server/src/interfaces/StripePayment.ts | 20 - .../server/src/interfaces/Subscription.ts | 8 - .../src/interfaces/SubscriptionPlan.ts | 0 packages/server/src/interfaces/Table.ts | 40 - packages/server/src/interfaces/Tasks.ts | 78 - packages/server/src/interfaces/TaxRate.ts | 89 - packages/server/src/interfaces/Tenancy.ts | 54 - .../src/interfaces/Tenant.ts | 0 packages/server/src/interfaces/Times.ts | 72 - .../src/interfaces/TransactionsByContacts.ts | 33 - .../src/interfaces/TransactionsByCustomers.ts | 51 - .../src/interfaces/TransactionsByReference.ts | 31 - .../src/interfaces/TransactionsByVendors.ts | 50 - .../src/interfaces/TransactionsLocking.ts | 71 - .../src/interfaces/TrialBalanceSheet.ts | 59 - packages/server/src/interfaces/User.ts | 188 - .../src/interfaces/VendorBalanceSummary.ts | 64 - .../server/src/interfaces/VendorCredit.ts | 249 - packages/server/src/interfaces/View.ts | 68 - packages/server/src/interfaces/Warehouses.ts | 212 - packages/server/src/interfaces/index.ts | 82 - packages/server/src/jobs/ComputeItemCost.ts | 73 - packages/server/src/jobs/OrganizationSetup.ts | 34 - .../server/src/jobs/OrganizationUpgrade.ts | 31 - packages/server/src/jobs/ResetPasswordMail.ts | 35 - packages/server/src/jobs/UserInviteMail.ts | 39 - .../server/src/jobs/WriteInvoicesJEntries.ts | 50 - packages/server/src/lib/AccountTypes/index.ts | 101 - .../server/src/lib/Cachable/CachableModel.js | 16 - .../src/lib/Cachable/CachableQueryBuilder.js | 69 - .../server/src/lib/Chromiumly/Chromiumly.ts | 26 - .../server/src/lib/Chromiumly/ConvertUtils.ts | 66 - .../server/src/lib/Chromiumly/Converter.ts | 10 - .../src/lib/Chromiumly/GotenbergUtils.ts | 24 - .../server/src/lib/Chromiumly/HTMLConvert.ts | 38 - .../server/src/lib/Chromiumly/UrlConvert.ts | 38 - packages/server/src/lib/Chromiumly/_types.ts | 51 - .../server/src/lib/DependencyGraph/index.js | 350 - .../src/lib/DynamicFilter/DynamicFilter.ts | 91 - .../DynamicFilter/DynamicFilterAbstractor.ts | 50 - .../DynamicFilterAdvancedFilter.ts | 27 - .../DynamicFilter/DynamicFilterFilterRoles.ts | 52 - .../DynamicFilter/DynamicFilterQueryParser.ts | 72 - .../DynamicFilterRoleAbstractor.ts | 387 -- .../lib/DynamicFilter/DynamicFilterSearch.ts | 48 - .../lib/DynamicFilter/DynamicFilterSortBy.ts | 92 - .../lib/DynamicFilter/DynamicFilterViews.ts | 56 - .../server/src/lib/DynamicFilter/constants.ts | 43 - .../server/src/lib/DynamicFilter/index.ts | 13 - .../src/lib/EventPublisher/EventPublisher.ts | 66 - .../src/lib/ExchangeRate/ExchangeRate.ts | 45 - .../src/lib/ExchangeRate/OpenExchangeRate.ts | 81 - packages/server/src/lib/ExchangeRate/types.ts | 17 - packages/server/src/lib/KnexFactory/index.js | 55 - .../server/src/lib/LogicEvaluation/Lexer.js | 172 - .../server/src/lib/LogicEvaluation/Parser.js | 159 - .../src/lib/LogicEvaluation/QueryParser.js | 61 - packages/server/src/lib/Mail/index.ts | 131 - .../server/src/lib/Metable/MetableConfig.ts | 40 - .../server/src/lib/Metable/MetableModel.js | 12 - .../server/src/lib/Metable/MetableStore.ts | 215 - .../server/src/lib/Metable/MetableStoreDB.ts | 243 - .../server/src/lib/MomentFormats/index.ts | 48 - .../server/src/lib/NestedSet/NestedSetNode.js | 9 - packages/server/src/lib/Plaid/Plaid.ts | 30 - .../src/lib/Plaid/PlaidApiEventsDBSync.ts | 48 - packages/server/src/lib/Plaid/index.ts | 1 - .../QueryBuilder.js | 27 - packages/server/src/lib/S3/S3.ts | 12 - .../server/src/lib/Seeder/FsMigrations.ts | 100 - .../server/src/lib/Seeder/MigrateUtils.ts | 192 - .../server/src/lib/Seeder/SeedMigration.ts | 222 - packages/server/src/lib/Seeder/Seeder.ts | 11 - .../server/src/lib/Seeder/SeederConfig.ts | 44 - packages/server/src/lib/Seeder/TableUtils.ts | 43 - .../server/src/lib/Seeder/TenantSeeder.ts | 25 - packages/server/src/lib/Seeder/Utils.ts | 42 - packages/server/src/lib/Seeder/constants.ts | 12 - packages/server/src/lib/Seeder/interfaces.ts | 20 - .../server/src/lib/Transformer/Transformer.ts | 243 - .../lib/Transformer/TransformerInjectable.ts | 71 - .../FilterRolesDynamicFilter.js | 44 - .../server/src/lib/ViewRolesBuilder/index.ts | 129 - packages/server/src/lib/Xlsx/TableSheet.ts | 134 - .../libs/accounts-utils/AccountTypesUtils.ts | 0 .../src/libs/chromiumly/Chromiumly.ts | 0 .../src/libs/chromiumly/ConvertUtils.ts | 0 .../src/libs/chromiumly/Converter.ts | 0 .../src/libs/chromiumly/GotenbergUtils.ts | 0 .../src/libs/chromiumly/HTMLConvert.ts | 0 .../src/libs/chromiumly/UrlConvert.ts | 0 .../src/libs/chromiumly/_types.ts | 0 .../src/libs/dependency-graph/index.ts | 0 .../src/libs/logic-evaluation/Lexer.ts | 0 .../src/libs/logic-evaluation/Parser.ts | 0 .../src/libs/logic-evaluation/QueryParser.ts | 0 .../src/libs/migration-seed/FsMigrations.ts | 0 .../src/libs/migration-seed/MigrateUtils.ts | 0 .../src/libs/migration-seed/SeedMigration.ts | 0 .../src/libs/migration-seed/Seeder.ts | 0 .../src/libs/migration-seed/SeederConfig.ts | 0 .../src/libs/migration-seed/TableUtils.ts | 0 .../src/libs/migration-seed/TenantSeeder.ts | 0 .../src/libs/migration-seed/Utils.ts | 0 .../src/libs/migration-seed/constants.ts | 0 .../src/libs/migration-seed/interfaces.ts | 0 packages/server/src/loaders/agenda.ts | 11 - packages/server/src/loaders/database.ts | 10 - .../server/src/loaders/dependencyInjector.ts | 56 - packages/server/src/loaders/eventEmitter.ts | 302 - packages/server/src/loaders/events.ts | 37 - packages/server/src/loaders/express.ts | 104 - packages/server/src/loaders/i18n.ts | 9 - packages/server/src/loaders/index.ts | 34 - packages/server/src/loaders/jobs.ts | 42 - packages/server/src/loaders/logger.ts | 13 - packages/server/src/loaders/mail.ts | 15 - packages/server/src/loaders/mongoose.ts | 11 - .../server/src/loaders/rateLimiterLoader.ts | 24 - packages/server/src/loaders/smsClient.ts | 9 - .../server/src/loaders/systemRepositories.ts | 17 - packages/server/src/loaders/tenantCache.ts | 8 - packages/server/src/loaders/tenantModels.ts | 150 - .../server/src/loaders/tenantRepositories.ts | 41 - packages/{server-nest => server}/src/main.ts | 0 .../src/middleware/logger.middleware.ts | 0 .../server/src/models/Account.Settings.ts | 199 - packages/server/src/models/Account.ts | 448 -- .../server/src/models/AccountTransaction.ts | 214 - packages/server/src/models/Auth.ts | 38 - packages/server/src/models/BankRule.ts | 70 - .../server/src/models/BankRuleCondition.ts | 24 - packages/server/src/models/Bill.Settings.ts | 286 - packages/server/src/models/Bill.ts | 625 -- packages/server/src/models/BillLandedCost.ts | 92 - .../server/src/models/BillLandedCostEntry.ts | 32 - .../server/src/models/BillPayment.Settings.ts | 224 - packages/server/src/models/BillPayment.ts | 170 - .../server/src/models/BillPaymentEntry.ts | 45 - packages/server/src/models/Branch.settings.ts | 11 - packages/server/src/models/Branch.ts | 181 - .../src/models/CashflowAccount.Settings.ts | 54 - packages/server/src/models/CashflowAccount.ts | 132 - .../server/src/models/CashflowTransaction.ts | 207 - .../src/models/CashflowTransactionLine.ts | 45 - packages/server/src/models/Contact.ts | 190 - packages/server/src/models/CreditNote.Meta.ts | 249 - packages/server/src/models/CreditNote.ts | 411 -- .../src/models/CreditNoteAppliedInvoice.ts | 53 - .../models/CreditNoteAppliedInvoiceEntry.ts | 25 - packages/server/src/models/Currency.ts | 21 - .../server/src/models/CustomViewBaseModel.ts | 24 - .../server/src/models/Customer.Settings.ts | 422 -- packages/server/src/models/Customer.ts | 196 - packages/server/src/models/DateSession.ts | 34 - packages/server/src/models/Document.ts | 23 - packages/server/src/models/DocumentLink.ts | 44 - packages/server/src/models/ExchangeRate.ts | 44 - .../server/src/models/Expense.Settings.ts | 206 - packages/server/src/models/Expense.ts | 283 - packages/server/src/models/ExpenseCategory.ts | 46 - .../models/InventoryAdjustment.Settings.ts | 107 - .../server/src/models/InventoryAdjustment.ts | 113 - .../src/models/InventoryAdjustmentEntry.ts | 42 - .../src/models/InventoryCostLotTracker.ts | 112 - .../server/src/models/InventoryTransaction.ts | 152 - .../src/models/InventoryTransactionMeta.ts | 29 - packages/server/src/models/Item.Settings.ts | 309 - packages/server/src/models/Item.ts | 243 - .../src/models/ItemCategory.Settings.ts | 62 - packages/server/src/models/ItemCategory.ts | 62 - packages/server/src/models/ItemEntry.ts | 267 - .../src/models/ItemWarehouseQuantity.ts | 35 - .../src/models/ManualJournal.Settings.ts | 230 - packages/server/src/models/ManualJournal.ts | 190 - .../server/src/models/ManualJournalEntry.ts | 54 - .../src/models/MatchedBankTransaction.ts | 32 - packages/server/src/models/Media.ts | 36 - packages/server/src/models/MediaLink.ts | 10 - packages/server/src/models/Metable.ts | 281 - packages/server/src/models/Model.ts | 81 +- packages/server/src/models/ModelSearchable.ts | 18 - packages/server/src/models/ModelSetting.ts | 77 - packages/server/src/models/Option.ts | 30 - packages/server/src/models/Pagination.ts | 68 - .../server/src/models/PaymentIntegration.ts | 61 - .../src/models/PaymentReceive.Settings.ts | 209 - packages/server/src/models/PaymentReceive.ts | 193 - .../server/src/models/PaymentReceiveEntry.ts | 51 - packages/server/src/models/PdfTemplate.ts | 72 - packages/server/src/models/PlaidItem.ts | 41 - packages/server/src/models/Project.ts | 157 - .../server/src/models/ProjectItemEntryRef.ts | 47 - .../src/models/RecognizedBankTransaction.ts | 79 - .../server/src/models/RefundCreditNote.ts | 52 - .../server/src/models/RefundVendorCredit.ts | 52 - .../server/src/models/ResourcableModel.ts | 8 - packages/server/src/models/Role.ts | 33 - packages/server/src/models/RolePermission.ts | 39 - .../src/models/SaleEstimate.Settings.ts | 294 - packages/server/src/models/SaleEstimate.ts | 380 - .../server/src/models/SaleEstimateEntry.ts | 30 - .../server/src/models/SaleInvoice.Settings.ts | 316 - packages/server/src/models/SaleInvoice.ts | 716 -- .../server/src/models/SaleInvoiceEntry.ts | 29 - .../server/src/models/SaleReceipt.Settings.ts | 287 - packages/server/src/models/SaleReceipt.ts | 353 - .../server/src/models/SaleReceiptEntry.ts | 29 - packages/server/src/models/Setting.ts | 21 - packages/server/src/models/Task.ts | 173 - .../server/src/models/TaxRate.settings.ts | 69 - packages/server/src/models/TaxRate.ts | 60 - .../server/src/models/TaxRateTransaction.ts | 61 - packages/server/src/models/TenantModel.ts | 22 - packages/server/src/models/Time.ts | 66 - .../models/TransactionPaymentServiceEntry.ts | 46 - .../UncategorizedCashflowTransaction.meta.ts | 72 - .../UncategorizedCashflowTransaction.ts | 248 - packages/server/src/models/User.ts | 60 - packages/server/src/models/Vendor.Settings.ts | 407 -- packages/server/src/models/Vendor.ts | 179 - .../server/src/models/VendorCredit.Meta.ts | 259 - packages/server/src/models/VendorCredit.ts | 369 - .../src/models/VendorCreditAppliedBill.ts | 53 - packages/server/src/models/View.ts | 72 - packages/server/src/models/ViewColumn.ts | 21 - packages/server/src/models/ViewRole.ts | 46 - .../server/src/models/Warehouse.settings.ts | 11 - packages/server/src/models/Warehouse.ts | 162 - .../src/models/WarehouseTransfer.Settings.ts | 69 - .../server/src/models/WarehouseTransfer.ts | 148 - .../src/models/WarehouseTransferEntry.ts | 44 - packages/server/src/models/index.ts | 55 - .../modules/Accounts/Account.transformer.ts | 0 .../AccountTransaction.transformer.ts | 0 .../modules/Accounts/Accounts.constants.ts | 0 .../modules/Accounts/Accounts.controller.ts | 0 .../src/modules/Accounts/Accounts.module.ts | 0 .../src/modules/Accounts/Accounts.types.ts | 0 .../Accounts/AccountsApplication.service.ts | 0 .../Accounts/AccountsExportable.service.ts | 0 .../Accounts/AccountsImportable.SampleData.ts | 0 .../Accounts/AccountsImportable.service.ts | 0 .../Accounts/ActivateAccount.service.ts | 0 .../CommandAccountValidators.service.ts | 0 .../src/modules/Accounts/CreateAccount.dto.ts | 0 .../modules/Accounts/CreateAccount.service.ts | 0 .../modules/Accounts/DeleteAccount.service.ts | 0 .../src/modules/Accounts/EditAccount.dto.ts | 0 .../modules/Accounts/EditAccount.service.ts | 0 .../modules/Accounts/GetAccount.service.ts | 0 .../GetAccountTransactions.service.ts | 0 .../Accounts/GetAccountTypes.service.ts | 0 .../modules/Accounts/GetAccounts.service.ts | 0 .../Accounts/MutateBaseCurrencyAccounts.ts | 0 .../src/modules/Accounts/constants.ts | 0 .../modules/Accounts/models/Account.model.ts | 0 .../models/AccountTransaction.model.ts | 0 .../repositories/Account.repository.ts | 0 .../susbcribers/MutateBaseCurrencyAccounts.ts | 0 .../Accounts/utils/AccountType.utils.ts | 0 .../src/modules/App/App.controller.spec.ts | 0 .../src/modules/App/App.controller.ts | 0 .../src/modules/App/App.module.ts | 0 .../src/modules/App/App.service.ts | 0 .../modules/Attachments/Attachment.module.ts | 0 .../Attachments/Attachment.transformer.ts | 0 .../Attachments/AttachmentTransformer.ts | 0 .../Attachments/Attachments.controller.ts | 0 .../modules/Attachments/Attachments.types.ts | 0 .../Attachments/AttachmentsApplication.ts | 0 .../modules/Attachments/DeleteAttachment.ts | 0 .../src/modules/Attachments/GetAttachment.ts | 0 .../Attachments/GetAttachmentPresignedUrl.ts | 0 .../src/modules/Attachments/LinkAttachment.ts | 0 .../modules/Attachments/S3UploadPipeline.ts | 0 .../modules/Attachments/UnlinkAttachment.ts | 0 .../src/modules/Attachments/UploadDocument.ts | 0 .../Attachments/ValidateAttachments.ts | 0 .../src/modules/Attachments/_utils.ts | 0 .../src/modules/Attachments/constants.ts | 0 .../decorators/InjectAttachable.decorator.ts | 0 .../Attachments/dtos/Attachment.dto.ts | 0 .../Attachments/events/AttachmentsOnBills.ts | 0 .../events/AttachmentsOnCreditNote.ts | 0 .../events/AttachmentsOnExpenses.ts | 0 .../events/AttachmentsOnManualJournals.ts | 0 .../events/AttachmentsOnPaymentsMade.ts | 0 .../events/AttachmentsOnPaymentsReceived.ts | 0 .../events/AttachmentsOnSaleEstimates.ts | 0 .../events/AttachmentsOnSaleInvoice.ts | 0 .../events/AttachmentsOnSaleReceipts.ts | 0 .../events/AttachmentsOnVendorCredits.ts | 0 .../Attachments/models/Document.model.ts | 0 .../Attachments/models/DocumentLink.model.ts | 0 .../src/modules/Attachments/utils.ts | 0 .../src/modules/Auth/Auth.constants.ts | 0 .../src/modules/Auth/Auth.controller.ts | 0 .../src/modules/Auth/Auth.interfaces.ts | 0 .../src/modules/Auth/Auth.module.ts | 0 .../src/modules/Auth/Auth.utils.ts | 0 .../modules/Auth/AuthApplication.sevice.ts | 0 .../modules/Auth/AuthMailMessages.esrvice.ts | 0 .../commands/AuthResetPassword.service.ts | 0 .../commands/AuthSendResetPassword.service.ts | 0 .../Auth/commands/AuthSignin.service.ts | 0 .../Auth/commands/AuthSignup.service.ts | 0 .../commands/AuthSignupConfirm.service.ts | 0 .../AuthSignupConfirmResend.service.ts | 0 .../src/modules/Auth/dtos/AuthSignin.dto.ts | 0 .../src/modules/Auth/dtos/AuthSignup.dto.ts | 0 .../src/modules/Auth/guards/Local.guard.ts | 0 .../src/modules/Auth/guards/jwt.guard.ts | 0 .../src/modules/Auth/models/PasswordReset.ts | 0 .../SendResetPasswordMail.processor.ts | 0 .../SendSignupVerificationMail.processor.ts | 0 .../Auth/queries/GetAuthMeta.service.ts | 0 .../modules/Auth/strategies/Jwt.strategy.ts | 0 .../modules/Auth/strategies/Local.strategy.ts | 0 .../Auth/subscribers/AuthMail.subscriber.ts | 0 .../AutoIncrementOrders.module.ts | 0 .../AutoIncrementOrders.service.ts | 0 .../modules/BankRules/BankRules.controller.ts | 0 .../src/modules/BankRules/BankRules.module.ts | 0 .../modules/BankRules/BankRulesApplication.ts | 0 .../commands/CreateBankRule.service.ts | 0 .../commands/DeleteBankRule.service.ts | 0 .../commands/DeleteBankRules.service.ts | 0 .../commands/EditBankRule.service.ts | 0 .../modules/BankRules/dtos/BankRule.dto.ts | 0 .../events/UnlinkBankRuleOnDeleteBankRule.ts | 0 .../src/modules/BankRules/models/BankRule.ts | 0 .../BankRules/models/BankRuleCondition.ts | 0 .../BankRules/queries/GetBankRule.service.ts | 0 .../queries/GetBankRuleTransformer.ts | 0 .../BankRules/queries/GetBankRules.service.ts | 0 .../queries/GetBankRulesTransformer.ts | 0 .../src/modules/BankRules/types.ts | 0 .../BankAccounts.controller.ts | 0 .../BankingAccounts/BankAccounts.module.ts | 0 .../BankAccountsApplication.service.ts | 0 .../commands/DisconnectBankAccount.service.ts | 0 .../commands/PauseBankAccountFeeds.service.ts | 0 .../commands/RefreshBankAccount.service.ts | 0 .../ResumeBankAccountFeeds.service.ts | 0 .../queries/GetBankAccountSummary.ts | 0 ...ategorizedTransactionsOnAccountDeleting.ts | 0 .../DisconnectPlaidItemOnAccountDeleted.ts | 0 .../types/BankAccounts.types.ts | 0 .../BankingCategorize.module.ts | 0 .../commands/CategorizeCashflowTransaction.ts | 0 .../CategorizeTransactionAsExpense.ts | 0 .../CreateUncategorizedTransaction.service.ts | 0 ...UncategorizeCashflowTransaction.service.ts | 0 ...egorizeCashflowTransactionsBulk.service.ts | 0 .../UncategorizedTransaction.transformer.ts | 0 .../UncategorizedTransactionsImportable.ts | 0 .../types/BankingCategorize.types.ts | 0 .../BankingMatching.controller.ts | 0 .../BankingMatching/BankingMatching.module.ts | 0 .../BankingMatchingApplication.ts | 0 .../src/modules/BankingMatching/_utils.ts | 0 .../commands/MatchTransactions.ts | 0 .../commands/MatchTransactionsTypes.ts | 0 .../MatchTransactionsTypesRegistry.ts | 0 .../UnmatchMatchedTransaction.service.ts | 0 .../ValidateTransactionsMatched.service.ts | 0 .../dtos/MatchBankTransaction.dto.ts | 0 ...crementUncategorizedTransactionsOnMatch.ts | 0 .../ValidateMatchingOnCashflowDelete.ts | 0 .../events/ValidateMatchingOnExpenseDelete.ts | 0 .../ValidateMatchingOnManualJournalDelete.ts | 0 .../ValidateMatchingOnPaymentMadeDelete.ts | 0 ...ValidateMatchingOnPaymentReceivedDelete.ts | 0 .../models/MatchedBankTransaction.ts | 0 .../GetMatchedTransactionBillsTransformer.ts | 0 ...etMatchedTransactionCashflowTransformer.ts | 0 ...etMatchedTransactionExpensesTransformer.ts | 0 ...etMatchedTransactionInvoicesTransformer.ts | 0 ...hedTransactionManualJournalsTransformer.ts | 0 .../queries/GetMatchedTransactions.service.ts | 0 .../GetMatchedTransactionsByBills.service.ts | 0 .../GetMatchedTransactionsByCashflow.ts | 0 .../GetMatchedTransactionsByExpenses.ts | 0 ...etMatchedTransactionsByInvoices.service.ts | 0 ...hedTransactionsByManualJournals.service.ts | 0 .../queries/GetMatchedTransactionsByType.ts | 0 .../src/modules/BankingMatching/types.ts | 0 .../BankingPlaid/BankingPlaid.module.ts | 0 .../modules/BankingPlaid/PlaidApplication.ts | 0 .../PlaidWebhookTenantBootMiddleware.ts | 0 .../modules/BankingPlaid/command/PlaidItem.ts | 0 .../BankingPlaid/command/PlaidSyncDB.ts | 0 .../command/PlaidUpdateTransactions.ts | 0 .../BankingPlaid/command/PlaidWebhooks.ts | 0 .../jobs/PlaidFetchTransactionsJob.ts | 0 .../modules/BankingPlaid/models/PlaidItem.ts | 0 .../BankingPlaid/models/SystemPlaidItem.ts | 0 .../queries/GetPlaidLinkToken.service.ts | 0 ...dateTransactionsOnItemCreatedSubscriber.ts | 0 ...ognizeSyncedBankTransactions.subscriber.ts | 0 .../BankingPlaid/types/BankingPlaid.types.ts | 0 .../src/modules/BankingPlaid/utils.ts | 0 .../BankingTransactionsRegonize.module.ts | 0 .../BankingTranasctionsRegonize/_types.ts | 0 .../BankingTranasctionsRegonize/_utils.ts | 0 .../commands/RecognizeTranasctions.service.ts | 0 .../RevertRecognizedTransactions.service.ts | 0 .../events/TriggerRecognizedTransactions.ts | 0 .../jobs/RecognizeTransactionsJob.ts | 0 .../jobs/RerecognizeTransactionsJob.ts | 0 .../jobs/RevertRecognizedTransactionsJob.ts | 0 .../models/RecognizedBankTransaction.ts | 0 ...etAutofillCategorizeTransaction.service.ts | 0 ...utofillCategorizeTransactionTransformer.ts | 0 .../BankingTransactions.controller.ts | 0 .../BankingTransactions.module.ts | 0 .../BankingTransactionsApplication.service.ts | 0 .../BankTransactionAutoIncrement.service.ts | 0 .../commands/BankTransactionGL.ts | 0 .../commands/BankTransactionGLEntries.ts | 0 .../CommandCasflowValidator.service.ts | 0 .../commands/CreateBankTransaction.service.ts | 0 .../DeleteCashflowTransaction.service.ts | 0 ...PendingUncategorizedTransaction.service.ts | 0 ...teDeleteBankAccountTransactions.service.ts | 0 .../modules/BankingTransactions/constants.ts | 0 .../dtos/CreateBankTransaction.dto.ts | 0 .../BankingTransactions/models/BankAccount.ts | 0 .../models/BankTransaction.ts | 0 .../models/BankTransactionLine.ts | 0 .../models/UncategorizedBankTransaction.ts | 0 .../queries/BankAccountTransformer.ts | 0 .../queries/BankTransactionTransformer.ts | 0 .../queries/BankTransactionsTransformer.ts | 0 .../queries/GetBankAccounts.service.ts | 0 .../queries/GetBankTransaction.service.ts | 0 ...etPendingBankAccountTransaction.service.ts | 0 ...endingBankAccountTransactionTransformer.ts | 0 .../GetRecognizedTransaction.service.ts | 0 .../GetRecognizedTransactionTransformer.ts | 0 .../queries/GetRecongizedTransactions.ts | 0 ...GetUncategorizedBankTransaction.service.ts | 0 .../queries/GetUncategorizedTransactions.ts | 0 .../CashflowTransactionSubscriber.ts | 0 .../CashflowWithAccountSubscriber.ts | 0 ...entUncategorizedTransactionOnCategorize.ts | 0 ...DeleteCashflowTransactionOnUncategorize.ts | 0 .../PreventDeleteTransactionsOnDelete.ts | 0 .../types/BankingTransactions.types.ts | 0 .../src/modules/BankingTransactions/utils.ts | 0 .../BankingTransactionsExclude.controller.ts | 0 .../BankingTransactionsExclude.module.ts | 0 .../ExcludeBankTransactionsApplication.ts | 0 .../ExcludeBankTransaction.service.ts | 0 .../ExcludeBankTransactions.service.ts | 0 .../UnexcludeBankTransaction.service.ts | 0 .../UnexcludeBankTransactions.service.ts | 0 .../commands/utils.ts | 0 .../queries/GetExcludedBankTransactions.ts | 0 ...rementUncategorizedTransactionOnExclude.ts | 0 .../types/BankTransactionsExclude.types.ts | 0 .../BankingTransactionsExclude/utils.ts | 0 .../BillLandedCosts/BillLandedCosts.module.ts | 0 .../TransactionLandedCostEntries.service.ts | 0 .../BillLandedCosts/models/BillLandedCost.ts | 0 .../models/BillLandedCostEntry.ts | 0 .../types/BillLandedCosts.types.ts | 0 .../BillPayments/BillPayments.controller.ts | 0 .../BillPayments/BillPayments.module.ts | 0 .../BillPaymentsApplication.service.ts | 0 .../modules/BillPayments/GetBillPayments.ts | 0 .../commands/BillPaymentBillSync.service.ts | 0 .../commands/BillPaymentExportable.ts | 0 .../BillPayments/commands/BillPaymentGL.ts | 0 .../commands/BillPaymentGLEntries.ts | 0 .../commands/BillPaymentValidators.service.ts | 0 .../commands/BillPaymentsImportable.ts | 0 .../commands/BillPaymentsPages.service.ts | 0 ...ommandBillPaymentDTOTransformer.service.ts | 0 .../commands/CreateBillPayment.service.ts | 0 .../commands/DeleteBillPayment.service.ts | 0 .../commands/EditBillPayment.service.ts | 0 .../src/modules/BillPayments/constants.ts | 0 .../BillPayments/dtos/BillPayment.dto.ts | 0 .../BillPayments/models/BillPayment.ts | 0 .../BillPayments/models/BillPaymentEntry.ts | 0 .../queries/BillPaymentEntry.transformer.ts | 0 .../BillPaymentTransactionTransformer.ts | 0 .../queries/BillPaymentTransformer.ts | 0 .../queries/GetBillPayment.service.ts | 0 .../queries/GetPaymentBills.service.ts | 0 .../BillPaymentGLEntriesSubscriber.ts | 0 .../BillPayments/types/BillPayments.types.ts | 0 .../src/modules/Bills/Bills.application.ts | 0 .../src/modules/Bills/Bills.constants.ts | 0 .../src/modules/Bills/Bills.controller.ts | 0 .../src/modules/Bills/Bills.module.ts | 0 .../src/modules/Bills/Bills.types.ts | 0 .../commands/BillDTOTransformer.service.ts | 0 .../commands/BillInventoryTransactions.ts | 0 .../commands/BillPaymentsGLEntriesRewrite.ts | 0 .../BillPaymentsGLEntriesRewriteSubscriber.ts | 0 .../modules/Bills/commands/BillsExportable.ts | 0 .../src/modules/Bills/commands/BillsGL.ts | 0 .../modules/Bills/commands/BillsGLEntries.ts | 0 .../modules/Bills/commands/BillsImportable.ts | 0 .../Bills/commands/BillsValidators.service.ts | 0 .../Bills/commands/CreateBill.service.ts | 0 .../Bills/commands/DeleteBill.service.ts | 0 .../Bills/commands/EditBill.service.ts | 0 .../Bills/commands/OpenBill.service.ts | 0 .../src/modules/Bills/dtos/Bill.dto.ts | 0 .../src/modules/Bills/models/Bill.ts | 0 .../modules/Bills/queries/Bill.transformer.ts | 0 .../src/modules/Bills/queries/GetBill.ts | 0 .../modules/Bills/queries/GetBillPayments.ts | 0 .../modules/Bills/queries/GetBills.service.ts | 0 .../Bills/queries/GetDueBills.service.ts | 0 .../subscribers/BillGLEntriesSubscriber.ts | 0 ...illWriteInventoryTransactionsSubscriber.ts | 0 .../BranchIntegrationErrorsMiddleware.ts | 0 .../modules/Branches/Branches.controller.ts | 0 .../src/modules/Branches/Branches.module.ts | 0 .../src/modules/Branches/Branches.types.ts | 0 .../Branches/BranchesApplication.service.ts | 0 .../src/modules/Branches/BranchesSettings.ts | 0 .../src/modules/Branches/CRUDBranch.ts | 0 .../src/modules/Branches/EventsProvider.ts | 0 .../ActivateBranchesFeature.service.ts | 0 .../BranchCommandValidator.service.ts | 0 .../Branches/commands/CreateBranch.service.ts | 0 .../Branches/commands/DeleteBranch.service.ts | 0 .../Branches/commands/EditBranch.service.ts | 0 .../commands/MarkBranchAsPrimary.service.ts | 0 .../src/modules/Branches/constants.ts | 0 .../src/modules/Branches/dtos/Branch.dto.ts | 0 .../BranchTransactionDTOTransform.ts | 0 .../Cashflow/CashflowActivateBranches.ts | 0 .../Expense/ExpensesActivateBranches.ts | 0 .../ManualJournalBranchesActivate.ts | 0 .../ManualJournalDTOTransformer.service.ts | 0 .../ManualJournalsBranchesValidator.ts | 0 .../integrations/ManualJournals/constants.ts | 0 .../Purchases/BillBranchesActivate.ts | 0 .../Purchases/PaymentMadeBranchesActivate.ts | 0 .../Purchases/VendorCreditBranchesActivate.ts | 0 .../Sales/CreditNoteBranchesActivate.ts | 0 .../Sales/PaymentReceiveBranchesActivate.ts | 0 .../Sales/SaleEstimatesBranchesActivate.ts | 0 .../Sales/SaleInvoiceBranchesActivate.ts | 0 .../Sales/SaleReceiptBranchesActivate.ts | 0 .../integrations/ValidateBranchExistance.ts | 0 .../Branches/integrations/constants.ts | 0 .../modules/Branches/models/Branch.model.ts | 0 .../Branches/queries/GetBranch.service.ts | 0 .../Branches/queries/GetBranches.service.ts | 0 .../CashflowBranchesActivateSubscriber.ts | 0 .../CreditNoteBranchesActivateSubscriber.ts | 0 .../ExpenseBranchesActivateSubscriber.ts | 0 .../PaymentMadeBranchesActivateSubscriber.ts | 0 ...aymentReceiveBranchesActivateSubscriber.ts | 0 ...SaleEstiamtesBranchesActivateSubscriber.ts | 0 .../SaleInvoiceBranchesActivateSubscriber.ts | 0 .../SaleReceiptsBranchesActivateSubscriber.ts | 0 .../Validators/BillBranchSubscriber.ts | 0 .../CashflowBranchDTOValidatorSubscriber.ts | 0 .../ContactOpeningBalanceBranchSubscriber.ts | 0 .../CreditNoteBranchesSubscriber.ts | 0 .../CreditNoteRefundBranchSubscriber.ts | 0 .../Validators/ExpenseBranchSubscriber.ts | 0 ...toryAdjustmentBranchValidatorSubscriber.ts | 0 .../InvoiceBranchValidatorSubscriber.ts | 0 .../ManualJournalBranchSubscriber.ts | 0 .../Validators/PaymentMadeBranchSubscriber.ts | 0 .../PaymentReceiveBranchSubscriber.ts | 0 .../SaleEstimateMultiBranchesSubscriber.ts | 0 .../SaleReceiptBranchesSubscriber.ts | 0 .../VendorCreditBranchSubscriber.ts | 0 .../VendorCreditRefundBranchSubscriber.ts | 0 .../ChromiumlyHtmlConvert.service.ts | 0 .../ChromiumlyTenancy.module.ts | 0 .../ChromiumlyTenancy.service.ts | 0 .../ChromiumlyTenancy/models/Document.ts | 0 .../ChromiumlyTenancy/models/DocumentLink.ts | 0 .../src/modules/ChromiumlyTenancy/utils.ts | 0 .../modules/Contacts/Contact.transformer.ts | 0 .../src/modules/Contacts/models/Contact.ts | 0 .../modules/Contacts/types/Contacts.types.ts | 0 .../CreditNoteRefunds.controller.ts | 0 .../CreditNoteRefunds.module.ts | 0 .../CreditNotesRefundsApplication.service.ts | 0 .../CreateRefundCreditNote.service.ts | 0 .../DeleteRefundCreditNote.service.ts | 0 .../commands/RefundCreditNote.service.ts | 0 .../commands/RefundCreditNoteGLEntries.ts | 0 .../commands/RefundSyncCreditNoteBalance.ts | 0 .../dto/CreditNoteRefund.dto.ts | 0 .../models/RefundCreditNote.ts | 0 .../queries/GetCreditNoteRefunds.service.ts | 0 .../GetRefundCreditNoteTransaction.service.ts | 0 .../types/CreditNoteRefunds.types.ts | 0 .../CreditNoteApplication.service.ts | 0 .../CreditNotes/CreditNotes.controller.ts | 0 .../modules/CreditNotes/CreditNotes.module.ts | 0 .../CommandCreditNoteDTOTransform.service.ts | 0 .../commands/CreateCreditNote.service.ts | 0 .../CreditNoteAutoIncrement.service.ts | 0 .../CreditNotes/commands/CreditNoteGL.ts | 0 .../commands/CreditNoteGLEntries.ts | 0 .../commands/CreditNotesExportable.ts | 0 .../commands/CreditNotesImportable.ts | 0 .../CreditNotesInventoryTransactions.ts | 0 .../commands/DeleteCreditNote.service.ts | 0 .../commands/EditCreditNote.service.ts | 0 .../commands/OpenCreditNote.service.ts | 0 .../src/modules/CreditNotes/constants.ts | 0 .../CreditNotes/dtos/CreditNote.dto.ts | 0 .../CreditNotes/dtos/RefundCreditNote.dto.ts | 0 .../modules/CreditNotes/models/CreditNote.ts | 0 .../CreditNoteBrandingTemplate.service.ts | 0 .../queries/CreditNoteTransformer.ts | 0 .../queries/GetCreditNote.service.ts | 0 .../queries/GetCreditNotePdf.serivce.ts | 0 .../queries/GetCreditNoteState.service.ts | 0 .../queries/GetCreditNotes.service.ts | 0 .../queries/RefundCreditNoteTransformer.ts | 0 .../CreditNoteAutoSerialSubscriber.ts | 0 .../CreditNoteGLEntriesSubscriber.ts | 0 ...editNoteInventoryTransactionsSubscriber.ts | 0 .../DeleteCustomerLinkedCreditSubscriber.ts | 0 .../RefundCreditNoteGLEntriesSubscriber.ts | 0 .../RefundSyncCreditNoteBalanceSubscriber.ts | 0 .../CreditNotes/types/CreditNotes.types.ts | 0 .../src/modules/CreditNotes/utils.ts | 0 .../CreditNoteApplySyncCredit.service.ts | 0 .../CreditNoteApplySyncInvoices.service.ts | 0 .../CreditNoteApplyToInvoices.service.ts | 0 ...DeleteCreditNoteApplyToInvoices.service.ts | 0 .../DeleteCustomerLinkedCreditNote.service.ts | 0 .../models/CreditNoteAppliedInvoice.ts | 0 .../CreditNoteAppliedInvoiceTransformer.ts | 0 ...reditNoteWithInvoicesToApplyTransformer.ts | 0 ...itNoteAssociatedAppliedInvoices.service.ts | 0 ...itNoteAssociatedInvoicesToApply.service.ts | 0 .../CreditNoteApplySyncCreditSubscriber.ts | 0 .../CreditNoteApplySyncInvoicesSubscriber.ts | 0 .../types/CreditNoteApplyInvoice.types.ts | 0 .../CustomViews/CustomViewBaseModel.ts | 0 .../modules/Customers/CustomerGLEntries.ts | 0 .../Customers/CustomerGLEntriesStorage.ts | 0 .../modules/Customers/Customers.controller.ts | 0 .../src/modules/Customers/Customers.module.ts | 0 .../Customers/CustomersApplication.service.ts | 0 .../modules/Customers/CustomersExportable.ts | 0 .../modules/Customers/CustomersImportable.ts | 0 .../src/modules/Customers/_SampleData.ts | 0 .../commands/ActivateCustomer.service.ts | 0 .../commands/CreateCustomer.service.ts | 0 .../commands/CreateEditCustomerDTO.service.ts | 0 .../commands/CustomerValidators.service.ts | 0 .../commands/DeleteCustomer.service.ts | 0 .../commands/EditCustomer.service.ts | 0 .../EditOpeningBalanceCustomer.service.ts | 0 .../src/modules/Customers/constants.ts | 0 .../Customers/dtos/ContactAddress.dto.ts | 0 .../Customers/dtos/CreateCustomer.dto.ts | 0 .../Customers/dtos/EditCustomer.dto.ts | 0 .../src/modules/Customers/models/Customer.ts | 0 .../Customers/queries/CustomerTransformer.ts | 0 .../Customers/queries/GetCustomer.service.ts | 0 .../Customers/queries/GetCustomers.service.ts | 0 .../CustomerGLEntriesSubscriber.ts | 0 .../Customers/types/Customers.types.ts | 0 .../modules/Dashboard/Dashboard.controller.ts | 0 .../src/modules/Dashboard/Dashboard.module.ts | 0 .../modules/Dashboard/Dashboard.service.ts | 0 .../DynamicFilter/DynamicFilter.ts | 0 .../DynamicFilter/DynamicFilter.types.ts | 0 .../DynamicFilter/DynamicFilterAbstractor.ts | 0 .../DynamicFilterAdvancedFilter.ts | 0 .../DynamicFilter/DynamicFilterFilterRoles.ts | 0 .../DynamicFilter/DynamicFilterQueryParser.ts | 0 .../DynamicFilterRoleAbstractor.ts | 0 .../DynamicFilter/DynamicFilterSearch.ts | 0 .../DynamicFilter/DynamicFilterSortBy.ts | 0 .../DynamicFilter/DynamicFilterViews.ts | 0 .../DynamicListing/DynamicFilter/constants.ts | 0 .../DynamicListing/DynamicFilter/index.ts | 0 .../DynamicListing/DynamicList.module.ts | 0 .../DynamicListing/DynamicList.service.ts | 0 .../DynamicListCustomView.service.ts | 0 .../DynamicListFilterRoles.service.ts | 0 .../DynamicListSearch.service.ts | 0 .../DynamicListServiceAbstract.ts | 0 .../DynamicListSortBy.service.ts | 0 .../src/modules/DynamicListing/constants.ts | 0 .../models/CustomViewBaseModel.ts | 0 .../DynamicListing/models/MetadataModel.ts | 0 .../models/SearchableBaseModel.ts | 0 .../DynamicListing/types/DynamicList.types.ts | 0 .../src/modules/DynamicListing/validators.ts | 0 .../EventsTracker/EventTracker.module.ts | 0 .../EventsTracker/EventTracker.service.ts | 0 .../EventsTracker/PostHog.constants.ts | 0 .../modules/EventsTracker/event-tracker.ts | 0 .../events/AccountEventsTracker.ts | 0 .../events/AuthenticationEventsTracker.ts | 0 .../events/BankRuleEventsTracker.ts | 0 .../events/BankTransactionEventsTracker.ts | 0 .../EventsTracker/events/BillEventsTracker.ts | 0 .../events/CustomerEventsTracker.ts | 0 .../events/ExpenseEventsTracker.ts | 0 .../EventsTracker/events/ItemEventsTracker.ts | 0 .../events/ManualJournalEventsTracker.ts | 0 .../events/PaymentLinkEventsTracker.ts | 0 .../events/PaymentMadeEventsTracker.ts | 0 .../events/PaymentMethodEventsTracker.ts | 0 .../events/PaymentReceivedEventsTracker.ts | 0 .../events/PdfTemplateEventsTracker.ts | 0 .../events/ReportsEventsTracker.ts | 0 .../events/SaleEstimateEventsTracker.ts | 0 .../events/SaleInvoicesEventsTracker.ts | 0 .../events/StripeIntegrationEventsTracker.ts | 0 .../events/SubscriptionEventsTracker.ts | 0 .../TransactionsLockingEventsTracker.ts | 0 .../events/VendorEventsTracker.ts | 0 .../modules/EventsTracker/postHog.module.ts | 0 .../modules/Expenses/Expenses.controller.ts | 0 .../src/modules/Expenses/Expenses.module.ts | 0 .../src/modules/Expenses/Expenses.types.ts | 0 .../Expenses/ExpensesApplication.service.ts | 0 .../modules/Expenses/ExpensesExportable.ts | 0 .../modules/Expenses/ExpensesImportable.ts | 0 .../commands/CommandExpenseDTO.transformer.ts | 0 .../CommandExpenseValidator.service.ts | 0 .../commands/CreateExpense.service.ts | 0 .../commands/DeleteExpense.service.ts | 0 .../Expenses/commands/EditExpense.service.ts | 0 .../commands/PublishExpense.service.ts | 0 .../src/modules/Expenses/constants.ts | 0 .../src/modules/Expenses/dtos/Expense.dto.ts | 0 .../Expenses/interfaces/Expenses.interface.ts | 0 .../modules/Expenses/models/Expense.model.ts | 0 .../Expenses/models/ExpenseCategory.model.ts | 0 .../Expenses/queries/Expense.transformer.ts | 0 .../queries/ExpenseCategory.transformer.ts | 0 .../Expenses/queries/GetExpense.service.ts | 0 .../Expenses/queries/GetExpenses.service.ts | 0 .../modules/Expenses/subscribers/ExpenseGL.ts | 0 .../subscribers/ExpenseGLEntries.service.ts | 0 .../ExpenseGLEntries.subscriber.ts | 0 .../ExpenseGLEntriesStorage.sevice.ts | 0 .../src/modules/Export/Export.controller.ts | 0 .../src/modules/Export/Export.module.ts | 0 .../src/modules/Export/ExportAls.ts | 0 .../src/modules/Export/ExportApplication.ts | 0 .../src/modules/Export/ExportPdf.ts | 0 .../src/modules/Export/ExportRegistery.ts | 0 .../src/modules/Export/ExportResources.ts | 0 .../src/modules/Export/ExportService.ts | 0 .../src/modules/Export/Exportable.ts | 0 .../src/modules/Export/common.ts | 0 .../src/modules/Export/constants.ts | 0 .../modules/Export/dtos/ExportQuery.dto.ts | 0 .../src/modules/Export/utils.ts | 0 .../src/modules/Features/Features.module.ts | 0 .../src/modules/Features/FeaturesConfigure.ts | 0 .../Features/FeaturesConfigureManager.ts | 0 .../src/modules/Features/FeaturesManager.ts | 0 .../Features/FeaturesSettingsDriver.ts | 0 .../FinancialStatements.module.ts | 0 .../common/FinancialDatePeriods.ts | 0 .../common/FinancialDateRanges.ts | 0 .../common/FinancialEvaluateEquation.ts | 0 .../common/FinancialFilter.ts | 0 .../common/FinancialHorizTotals.ts | 0 .../common/FinancialPreviousPeriod.ts | 0 .../common/FinancialPreviousYear.ts | 0 .../common/FinancialReportService.ts | 0 .../common/FinancialSchema.ts | 0 .../common/FinancialSheet.ts | 0 .../common/FinancialSheetCommon.module.ts | 0 .../common/FinancialSheetMeta.ts | 0 .../common/FinancialSheetStructure.ts | 0 .../common/FinancialTable.ts | 0 .../common/FinancialTablePreviousPeriod.ts | 0 .../common/FinancialTablePreviousYear.ts | 0 .../common/FinancialTableStructure.ts | 0 .../FinancialStatements/common/TableSheet.ts | 0 .../common/TableSheetPdf.ts | 0 .../APAgingSummary.controller.ts | 0 .../APAgingSummary/APAgingSummary.module.ts | 0 .../APAgingSummary/APAgingSummary.types.ts | 0 .../APAgingSummaryApplication.ts | 0 .../APAgingSummaryExportInjectable.ts | 0 .../APAgingSummary/APAgingSummaryMeta.ts | 0 .../APAgingSummaryPdfInjectable.ts | 0 .../APAgingSummaryRepository.ts | 0 .../APAgingSummary/APAgingSummaryService.ts | 0 .../APAgingSummary/APAgingSummarySheet.ts | 0 .../APAgingSummary/APAgingSummaryTable.ts | 0 .../APAgingSummaryTableInjectable.ts | 0 .../modules/APAgingSummary/utils.ts | 0 .../ARAgingSummary.controller.ts | 0 .../ARAgingSummary/ARAgingSummary.module.ts | 0 .../ARAgingSummary/ARAgingSummary.types.ts | 0 .../ARAgingSummaryApplication.ts | 0 .../ARAgingSummaryExportInjectable.ts | 0 .../ARAgingSummary/ARAgingSummaryMeta.ts | 0 .../ARAgingSummaryPdfInjectable.ts | 0 .../ARAgingSummaryRepository.ts | 0 .../ARAgingSummary/ARAgingSummaryService.ts | 0 .../ARAgingSummary/ARAgingSummarySheet.ts | 0 .../ARAgingSummary/ARAgingSummaryTable.ts | 0 .../ARAgingSummaryTableInjectable.ts | 0 .../modules/ARAgingSummary/utils.ts | 0 .../modules/AgingSummary/AgingReport.ts | 0 .../AgingSummary/AgingSummary.module.ts | 0 .../modules/AgingSummary/AgingSummary.ts | 0 .../AgingSummary/AgingSummary.types.ts | 0 .../modules/AgingSummary/AgingSummaryMeta.ts | 0 .../modules/AgingSummary/AgingSummaryTable.ts | 0 .../modules/AgingSummary/_constants.ts | 0 .../BalanceSheet/BalanceSheet.controller.ts | 0 .../BalanceSheet/BalanceSheet.module.ts | 0 .../modules/BalanceSheet/BalanceSheet.ts | 0 .../BalanceSheet/BalanceSheet.types.ts | 0 .../BalanceSheet/BalanceSheetAccounts.ts | 0 .../BalanceSheet/BalanceSheetAggregators.ts | 0 .../BalanceSheet/BalanceSheetApplication.ts | 0 .../modules/BalanceSheet/BalanceSheetBase.ts | 0 .../BalanceSheetComparsionPreviousPeriod.ts | 0 .../BalanceSheetComparsionPreviousYear.ts | 0 .../BalanceSheet/BalanceSheetDatePeriods.ts | 0 .../BalanceSheetExportInjectable.ts | 0 .../BalanceSheet/BalanceSheetFiltering.ts | 0 .../BalanceSheet/BalanceSheetInjectable.ts | 0 .../modules/BalanceSheet/BalanceSheetMeta.ts | 0 .../BalanceSheet/BalanceSheetNetIncome.ts | 0 .../BalanceSheetNetIncomeDatePeriods.ts | 0 .../BalanceSheetNetIncomeDatePeriodsPP.ts | 0 .../BalanceSheetNetIncomeDatePeriodsPY.ts | 0 .../BalanceSheet/BalanceSheetNetIncomePP.ts | 0 .../BalanceSheet/BalanceSheetNetIncomePY.ts | 0 .../BalanceSheet/BalanceSheetPdfInjectable.ts | 0 .../BalanceSheet/BalanceSheetPercentage.ts | 0 .../modules/BalanceSheet/BalanceSheetQuery.ts | 0 .../BalanceSheet/BalanceSheetRepository.ts | 0 .../BalanceSheetRepositoryNetIncome.ts | 0 .../BalanceSheet/BalanceSheetSchema.ts | 0 .../modules/BalanceSheet/BalanceSheetTable.ts | 0 .../BalanceSheetTableDatePeriods.ts | 0 .../BalanceSheetTableInjectable.ts | 0 .../BalanceSheetTablePercentage.ts | 0 .../BalanceSheetTablePreviousPeriod.ts | 0 .../BalanceSheetTablePreviousYear.ts | 0 .../modules/BalanceSheet/BalanceSheetTotal.ts | 0 .../modules/BalanceSheet/constants.ts | 0 .../modules/CashFlowStatement/CashFlow.ts | 0 .../CashFlowStatement/CashFlowDatePeriods.ts | 0 .../CashFlowStatement/CashFlowRepository.ts | 0 .../CashFlowStatement/CashFlowService.ts | 0 .../CashFlowStatement/CashFlowTable.ts | 0 .../CashFlowStatement/Cashflow.controller.ts | 0 .../CashFlowStatement/Cashflow.types.ts | 0 .../CashflowExportInjectable.ts | 0 .../CashflowSheetApplication.ts | 0 .../CashFlowStatement/CashflowSheetMeta.ts | 0 .../CashflowStatement.module.ts | 0 .../CashflowStatementBase.ts | 0 .../CashflowTableInjectable.ts | 0 .../CashflowTablePdfInjectable.ts | 0 .../modules/CashFlowStatement/constants.ts | 0 .../modules/CashFlowStatement/schema.ts | 0 .../ContactBalanceSummary.ts | 0 .../ContactBalanceSummary.types.ts | 0 .../CustomerBalanceSummary.controller.ts | 0 .../CustomerBalanceSummary.module.ts | 0 .../CustomerBalanceSummary.ts | 0 .../CustomerBalanceSummary.types.ts | 0 .../CustomerBalanceSummaryApplication.ts | 0 .../CustomerBalanceSummaryExportInjectable.ts | 0 .../CustomerBalanceSummaryMeta.ts | 0 .../CustomerBalanceSummaryPdf.ts | 0 .../CustomerBalanceSummaryRepository.ts | 0 .../CustomerBalanceSummaryService.ts | 0 .../CustomerBalanceSummaryTableInjectable.ts | 0 .../CustomerBalanceSummaryTableRows.ts | 0 .../modules/CustomerBalanceSummary/_utils.ts | 0 .../CustomerBalanceSummary/constants.ts | 0 .../GeneralLedger/GeneralLedger.controller.ts | 0 .../GeneralLedger/GeneralLedger.module.ts | 0 .../modules/GeneralLedger/GeneralLedger.ts | 0 .../GeneralLedger/GeneralLedger.types.ts | 0 .../GeneralLedger/GeneralLedgerApplication.ts | 0 .../GeneralLedger/GeneralLedgerExport.ts | 0 .../GeneralLedger/GeneralLedgerMeta.ts | 0 .../modules/GeneralLedger/GeneralLedgerPdf.ts | 0 .../GeneralLedger/GeneralLedgerRepository.ts | 0 .../GeneralLedger/GeneralLedgerService.ts | 0 .../GeneralLedger/GeneralLedgerTable.ts | 0 .../GeneralLedgerTableInjectable.ts | 0 .../modules/GeneralLedger/_utils.ts | 0 .../modules/GeneralLedger/constants.ts | 0 .../modules/GeneralLedger/utils.ts | 0 .../InventoryItemDetails.controller.ts | 0 .../InventoryItemDetails.module.ts | 0 .../InventoryItemDetails.service.ts | 0 .../InventoryItemDetails.ts | 0 .../InventoryItemDetails.types.ts | 0 .../InventoryItemDetailsApplication.ts | 0 .../InventoryItemDetailsExportInjectable.ts | 0 .../InventoryItemDetailsMeta.ts | 0 .../InventoryItemDetailsRepository.ts | 0 .../InventoryItemDetailsTable.ts | 0 .../InventoryItemDetailsTableInjectable.ts | 0 .../InventoryItemDetailsTablePdf.ts | 0 .../modules/InventoryItemDetails/constant.ts | 0 .../InventoryValuation.controller.ts | 0 .../InventoryValuationSheet.module.ts | 0 .../InventoryValuationSheet.ts | 0 .../InventoryValuationSheet.types.ts | 0 .../InventoryValuationSheetApplication.ts | 0 .../InventoryValuationSheetExportable.ts | 0 .../InventoryValuationSheetMeta.ts | 0 .../InventoryValuationSheetPdf.ts | 0 .../InventoryValuationSheetRepository.ts | 0 .../InventoryValuationSheetService.ts | 0 .../InventoryValuationSheetTable.ts | 0 .../InventoryValuationSheetTableInjectable.ts | 0 .../InventoryValuationSheet/_constants.ts | 0 .../JournalSheet/JournalSheet.controller.ts | 0 .../JournalSheet/JournalSheet.module.ts | 0 .../modules/JournalSheet/JournalSheet.ts | 0 .../JournalSheet/JournalSheet.types.ts | 0 .../JournalSheet/JournalSheetApplication.ts | 0 .../JournalSheet/JournalSheetExport.ts | 0 .../modules/JournalSheet/JournalSheetMeta.ts | 0 .../JournalSheet/JournalSheetPdfInjectable.ts | 0 .../JournalSheet/JournalSheetRepository.ts | 0 .../JournalSheet/JournalSheetService.ts | 0 .../modules/JournalSheet/JournalSheetTable.ts | 0 .../JournalSheetTableInjectable.ts | 0 .../modules/JournalSheet/constant.ts | 0 .../modules/JournalSheet/types.ts | 0 .../ProfitLossSheet/ProfitLossSchema.ts | 0 .../ProfitLossSheet.controller.ts | 0 .../ProfitLossSheet/ProfitLossSheet.module.ts | 0 .../ProfitLossSheet/ProfitLossSheet.ts | 0 .../ProfitLossSheet/ProfitLossSheet.types.ts | 0 .../ProfitLossSheetApplication.ts | 0 .../ProfitLossSheet/ProfitLossSheetBase.ts | 0 .../ProfitLossSheetDatePeriods.ts | 0 .../ProfitLossSheetExportInjectable.ts | 0 .../ProfitLossSheet/ProfitLossSheetFilter.ts | 0 .../ProfitLossSheet/ProfitLossSheetMeta.ts | 0 .../ProfitLossSheetPercentage.ts | 0 .../ProfitLossSheetPreviousPeriod.ts | 0 .../ProfitLossSheetPreviousYear.ts | 0 .../ProfitLossSheet/ProfitLossSheetQuery.ts | 0 .../ProfitLossSheetRepository.ts | 0 .../ProfitLossSheet/ProfitLossSheetService.ts | 0 .../ProfitLossSheet/ProfitLossSheetTable.ts | 0 .../ProfitLossSheetTableDatePeriods.ts | 0 .../ProfitLossSheetTableInjectable.ts | 0 .../ProfitLossSheetTablePercentage.ts | 0 .../ProfitLossTablePdfInjectable.ts | 0 .../ProfitLossTablePreviousPeriod.ts | 0 .../ProfitLossTablePreviousYear.ts | 0 .../modules/ProfitLossSheet/constants.ts | 0 .../modules/ProfitLossSheet/utils.ts | 0 .../PurchasesByItems.controller.ts | 0 .../PurchasesByItems.module.ts | 0 .../PurchasesByItems.service.ts | 0 .../PurchasesByItems/PurchasesByItems.ts | 0 .../PurchasesByItemsApplication.ts | 0 .../PurchasesByItemsExport.ts | 0 .../PurchasesByItems/PurchasesByItemsMeta.ts | 0 .../PurchasesByItems/PurchasesByItemsPdf.ts | 0 .../PurchasesByItems/PurchasesByItemsTable.ts | 0 .../PurchasesByItemsTableInjectable.ts | 0 .../modules/PurchasesByItems/_types.ts | 0 .../types/PurchasesByItems.types.ts | 0 .../modules/PurchasesByItems/utils.ts | 0 .../SalesByItems/SalesByItems.controller.ts | 0 .../SalesByItems/SalesByItems.module.ts | 0 .../modules/SalesByItems/SalesByItems.ts | 0 .../SalesByItems/SalesByItems.types.ts | 0 .../SalesByItems/SalesByItemsApplication.ts | 0 .../SalesByItems/SalesByItemsExport.ts | 0 .../modules/SalesByItems/SalesByItemsMeta.ts | 0 .../SalesByItems/SalesByItemsPdfInjectable.ts | 0 .../SalesByItems/SalesByItemsService.ts | 0 .../modules/SalesByItems/SalesByItemsTable.ts | 0 .../SalesByItemsTableInjectable.ts | 0 .../modules/SalesByItems/constants.ts | 0 .../modules/SalesByItems/utils.ts | 0 .../SalesTaxLiability.module.ts | 0 .../SalesTaxLiability.types.ts | 0 .../SalesTaxLiabilitySummary.controller.ts | 0 .../SalesTaxLiabilitySummary.ts | 0 .../SalesTaxLiabilitySummaryApplication.ts | 0 ...alesTaxLiabilitySummaryExportInjectable.ts | 0 .../SalesTaxLiabilitySummaryMeta.ts | 0 .../SalesTaxLiabilitySummaryRepository.ts | 0 .../SalesTaxLiabilitySummaryService.ts | 0 .../SalesTaxLiabilitySummaryTable.ts | 0 ...SalesTaxLiabilitySummaryTableInjectable.ts | 0 .../SalesTaxLiabiltiySummaryPdf.ts | 0 .../SalesTaxLiabilitySummary/_constants.ts | 0 .../TransactionsByContact.ts | 0 .../TransactionsByContact.types.ts | 0 .../TransactionsByContactRepository.ts | 0 .../TransactionsByContactTableRows.ts | 0 .../TransactionsByCustomer.controller.ts | 0 .../TransactionsByCustomer.module.ts | 0 .../TransactionsByCustomer.types.ts | 0 .../TransactionsByCustomers.ts | 0 .../TransactionsByCustomersApplication.ts | 0 ...TransactionsByCustomersExportInjectable.ts | 0 .../TransactionsByCustomersMeta.ts | 0 .../TransactionsByCustomersPdf.ts | 0 .../TransactionsByCustomersRepository.ts | 0 .../TransactionsByCustomersService.ts | 0 .../TransactionsByCustomersTable.ts | 0 .../TransactionsByCustomersTableInjectable.ts | 0 .../modules/TransactionsByCustomer/utils.ts | 0 .../TransactionByReference.module.ts | 0 .../TransactionsByReference.controller.ts | 0 .../TransactionsByReference.service.ts | 0 .../TransactionsByReference.types.ts | 0 .../TransactionsByReferenceApplication.ts | 0 .../TransactionsByReferenceReport.ts | 0 .../TransactionsByReferenceRepository.ts | 0 .../modules/TransactionsByReference/_utils.ts | 0 .../TransactionsByVendor.controller.ts | 0 .../TransactionsByVendor.module.ts | 0 .../TransactionsByVendor.ts | 0 .../TransactionsByVendor.types.ts | 0 .../TransactionsByVendorApplication.ts | 0 .../TransactionsByVendorExportInjectable.ts | 0 .../TransactionsByVendorInjectable.ts | 0 .../TransactionsByVendorMeta.ts | 0 .../TransactionsByVendorPdf.ts | 0 .../TransactionsByVendorRepository.ts | 0 .../TransactionsByVendorTable.ts | 0 .../TransactionsByVendorTableInjectable.ts | 0 .../modules/TransactionsByVendor/constants.ts | 0 .../modules/TransactionsByVendor/utils.ts | 0 .../TrialBalanceExportInjectable.ts | 0 .../TrialBalanceSheet.controller.ts | 0 .../TrialBalanceSheet.module.ts | 0 .../TrialBalanceSheet/TrialBalanceSheet.ts | 0 .../TrialBalanceSheet.types.ts | 0 .../TrialBalanceSheetApplication.ts | 0 .../TrialBalanceSheetInjectable.ts | 0 .../TrialBalanceSheetMeta.ts | 0 .../TrialBalanceSheetPdfInjectsable.ts | 0 .../TrialBalanceSheetRepository.ts | 0 .../TrialBalanceSheetTable.ts | 0 .../TrialBalanceSheetTableInjectable.ts | 0 .../modules/TrialBalanceSheet/_constants.ts | 0 .../modules/TrialBalanceSheet/_types.ts | 0 .../modules/TrialBalanceSheet/_utils.ts | 0 .../VendorBalanceSummary.controller.ts | 0 .../VendorBalanceSummary.module.ts | 0 .../VendorBalanceSummary.ts | 0 .../VendorBalanceSummary.types.ts | 0 .../VendorBalanceSummaryApplication.ts | 0 .../VendorBalanceSummaryExportInjectable.ts | 0 .../VendorBalanceSummaryMeta.ts | 0 .../VendorBalanceSummaryPdf.ts | 0 .../VendorBalanceSummaryRepository.ts | 0 .../VendorBalanceSummaryService.ts | 0 .../VendorBalanceSummaryTableInjectable.ts | 0 .../VendorBalanceSummaryTableRows.ts | 0 .../modules/VendorBalanceSummary/constants.ts | 0 .../modules/VendorBalanceSummary/utils.ts | 0 .../FinancialStatements/types/Report.types.ts | 0 .../FinancialStatements/types/Table.types.ts | 0 .../src/modules/FinancialStatements/utils.ts | 0 .../FinancialStatements/utils/Table.utils.ts | 0 .../src/modules/Import/Import.module.ts | 0 .../src/modules/Import/ImportALS.ts | 0 .../src/modules/Import/ImportFileCommon.ts | 0 .../Import/ImportFileDataTransformer.ts | 0 .../modules/Import/ImportFileDataValidator.ts | 0 .../src/modules/Import/ImportFileMapping.ts | 0 .../src/modules/Import/ImportFileMeta.ts | 0 .../Import/ImportFileMetaTransformer.ts | 0 .../src/modules/Import/ImportFilePreview.ts | 0 .../src/modules/Import/ImportFileProcess.ts | 0 .../modules/Import/ImportFileProcessCommit.ts | 0 .../src/modules/Import/ImportFileUpload.ts | 0 .../Import/ImportRemoveExpiredFiles.ts | 0 .../modules/Import/ImportResource.module.ts | 0 .../Import/ImportResourceApplication.ts | 0 .../src/modules/Import/ImportSample.ts | 0 .../src/modules/Import/Importable.ts | 0 .../src/modules/Import/ImportableRegistry.ts | 0 .../src/modules/Import/ImportableResources.ts | 0 .../src/modules/Import/_constants.ts | 0 .../src/modules/Import/_utils.ts | 0 .../src/modules/Import/interfaces.ts | 0 .../jobs/ImportDeleteExpiredFilesJob.ts | 0 .../src/modules/Import/models/Import.ts | 0 .../src/modules/Import/sheet_utils.ts | 0 .../InventoryAdjustmentTransformer.ts | 0 .../InventoryAdjustments.controller.ts | 0 .../InventoryAdjustments.module.ts | 0 ...InventoryAdjustmentsApplication.service.ts | 0 .../CreateQuickInventoryAdjustment.service.ts | 0 .../DeleteInventoryAdjustment.service.ts | 0 .../PublishInventoryAdjustment.service.ts | 0 .../commands/ledger/InventoryAdjustmentGL.ts | 0 .../ledger/InventoryAdjustmentsGLEntries.ts | 0 .../InventoryAdjustments.constants.ts | 0 .../CreateQuickInventoryAdjustment.dto.ts | 0 ...nventoryAdjustmentInventoryTransactions.ts | 0 ...justmentInventoryTransactionsSubscriber.ts | 0 .../models/InventoryAdjustment.ts | 0 .../models/InventoryAdjustmentEntry.ts | 0 .../queries/GetInventoryAdjustment.service.ts | 0 .../GetInventoryAdjustments.service.ts | 0 .../InventoryAdjustmentGL.subscriber.ts | 0 .../types/InventoryAdjustments.types.ts | 0 .../InventoryCost/InventoryCost.module.ts | 0 .../InventoryCost/InventoryCostApplication.ts | 0 .../InventoryAverageCostMethod.service.ts | 0 .../commands/InventoryAverageCostMethod.ts | 0 .../commands/InventoryComputeCost.service.ts | 0 .../InventoryCostGLStorage.service.ts | 0 .../commands/InventoryCosts.service.ts | 0 .../InventoryItemOpeningAvgCost.service.ts | 0 .../InventoryItemsQuantitySync.service.ts | 0 .../commands/InventoryTransactions.service.ts | 0 .../StoreInventortyLotsCost.service.ts | 0 .../models/InventoryCostLotTracker.ts | 0 .../models/InventoryTransaction.ts | 0 .../models/InventoryTransactionMeta.ts | 0 .../processors/ComputeItemCost.processor.ts | 0 ...nventoryTransactionsGLEntries.processor.ts | 0 .../subscribers/InventoryCost.subscriber.ts | 0 .../InventoryCostGLBeforeWriteSubscriber.ts | 0 .../types/InventoryCost.types.ts | 0 .../src/modules/InventoryCost/utils.ts | 0 .../ItemCategoriesExportable.ts | 0 .../ItemCategoriesImportable.ts | 0 .../ItemCategory.application.ts | 0 .../ItemCategories/ItemCategory.controller.ts | 0 .../ItemCategories/ItemCategory.interfaces.ts | 0 .../ItemCategories/ItemCategory.module.ts | 0 .../CommandItemCategoryValidator.service.ts | 0 .../commands/CreateItemCategory.service.ts | 0 .../commands/DeleteItemCategory.service.ts | 0 .../commands/EditItemCategory.service.ts | 0 .../src/modules/ItemCategories/constants.ts | 0 .../ItemCategories/dtos/ItemCategory.dto.ts | 0 .../models/ItemCategory.model.ts | 0 .../queries/GetItemCategories.service.ts | 0 .../queries/GetItemCategory.service.ts | 0 .../src/modules/Items/ActivateItem.service.ts | 0 .../src/modules/Items/CreateItem.service.ts | 0 .../src/modules/Items/DeleteItem.service.ts | 0 .../src/modules/Items/EditItem.service.ts | 0 .../src/modules/Items/GetItem.service.ts | 0 .../src/modules/Items/GetItems.service.ts | 0 .../modules/Items/InactivateItem.service.ts | 0 .../src/modules/Items/Item.controller.ts | 0 .../src/modules/Items/Item.schema.ts | 0 .../src/modules/Items/Item.transformer.ts | 0 .../ItemBillsTransactions.transformer.ts | 0 .../ItemEstimatesTransaction.transformer.ts | 0 .../ItemInvoicesTransactions.transformer.ts | 0 .../ItemReceiptsTransactions.transformer.ts | 0 .../modules/Items/ItemTransactions.service.ts | 0 .../modules/Items/ItemValidator.service.ts | 0 .../src/modules/Items/Items.constants.ts | 0 .../src/modules/Items/Items.module.ts | 0 .../modules/Items/ItemsApplication.service.ts | 0 .../src/modules/Items/ItemsEntries.service.ts | 0 .../src/modules/Items/ServiceError.ts | 0 .../src/modules/Items/dtos/Item.dto.ts | 0 .../modules/Items/events/ItemCreated.event.ts | 0 .../Items/listeners/ItemCreated.listener.ts | 0 .../src/modules/Items/models/Item.ts | 0 .../src/modules/Items/types/Items.types.ts | 0 .../src/modules/Ledger/JournalEntry.ts | 0 .../src/modules/Ledger/Ledger.module.ts | 0 .../src/modules/Ledger/Ledger.ts | 0 .../Ledger/LedgerContactStorage.service.ts | 0 .../Ledger/LedgerEntriesStorage.service.ts | 0 .../modules/Ledger/LedgerStorage.service.ts | 0 .../Ledger/LedgerStorageRevert.service.ts | 0 .../Ledger/LedgetAccountStorage.service.ts | 0 .../src/modules/Ledger/types/Ledger.types.ts | 0 .../src/modules/Ledger/utils.ts | 0 .../src/modules/Loops/Loops.module.ts | 0 .../modules/Loops/LoopsEvents.subscriber.ts | 0 .../src/modules/Mail/Mail.constants.ts | 0 .../src/modules/Mail/Mail.module.ts | 0 .../src/modules/Mail/Mail.ts | 0 .../src/modules/Mail/Mail.types.ts | 0 .../modules/Mail/MailTransporter.service.ts | 0 .../ContactMailNotification.ts | 0 .../MailNotification.module.ts | 0 .../MailNotification.types.ts | 0 .../src/modules/MailNotification/constants.ts | 0 .../src/modules/MailNotification/utils.ts | 0 .../modules/MailTenancy/MailTenancy.module.ts | 0 .../MailTenancy/MailTenancy.service.ts | 0 .../ManualJournals.controller.ts | 0 .../ManualJournals/ManualJournals.module.ts | 0 .../ManualJournalsApplication.service.ts | 0 .../AutoIncrementManualJournal.service.ts | 0 .../CommandManualJournalValidators.service.ts | 0 .../commands/CreateManualJournal.service.ts | 0 .../commands/DeleteManualJournal.service.ts | 0 .../commands/EditManualJournal.service.ts | 0 .../commands/ManualJournalExportable.ts | 0 .../commands/ManualJournalGL.ts | 0 .../commands/ManualJournalGLEntries.ts | 0 .../ManualJournalGLEntriesSubscriber.ts | 0 .../commands/ManualJournalsImport.ts | 0 .../commands/PublishManualJournal.service.ts | 0 .../src/modules/ManualJournals/constants.ts | 0 .../ManualJournals/dtos/ManualJournal.dto.ts | 0 .../ManualJournals/models/ManualJournal.ts | 0 .../models/ManualJournalEntry.ts | 0 .../queries/GetManualJournal.service.ts | 0 .../queries/GetManualJournals.service.ts | 0 .../queries/ManualJournalTransformer.ts | 0 .../types/ManualJournals.types.ts | 0 .../src/modules/Metable/MetableConfig.ts | 0 .../src/modules/Metable/MetableModel.ts | 0 .../src/modules/Metable/MetableStore.ts | 0 .../src/modules/Metable/MetableStoreDB.ts | 0 .../src/modules/Metable/types.ts | 0 .../Organization/Organization.constants.ts | 0 .../Organization/Organization.controller.ts | 0 .../Organization/Organization.module.ts | 0 .../Organization/Organization.types.ts | 0 .../Organization/Organization.utils.ts | 0 ...OrganizationBaseCurrencyLocking.service.ts | 0 .../Organization/OrganizationUpgrade.ts | 0 .../Organization/Organization/_utils.ts | 0 .../Organization/Organization/constants.ts | 0 .../commands/BuildOrganization.service.ts | 0 .../CommandOrganizationValidators.service.ts | 0 .../commands/UpdateOrganization.service.ts | 0 .../Organization/dtos/Organization.dto.ts | 0 .../processors/OrganizationBuild.processor.ts | 0 .../queries/GetCurrentOrganization.service.ts | 0 ...GetOrganizationBaseCurrencyLock.service.ts | 0 .../CreateInvoiceCheckoutSession.ts | 0 .../GetInvoicePaymentLinkMetadata.ts | 0 .../PaymentLinks/GetPaymentLinkInvoicePdf.ts | 0 .../PaymentLinks/PaymentLinks.controller.ts | 0 .../PaymentLinks/PaymentLinks.module.ts | 0 .../PaymentLinks/PaymentLinksApplication.ts | 0 .../PaymentLinks/models/PaymentLink.ts | 0 .../PaymentReceived.application.ts | 0 .../PaymentsReceived.controller.ts | 0 .../PaymentsReceived.module.ts | 0 .../commands/CreatePaymentReceived.serivce.ts | 0 .../commands/DeletePaymentReceived.service.ts | 0 .../commands/EditPaymentReceived.service.ts | 0 .../commands/PaymentReceivedDTOTransformer.ts | 0 .../commands/PaymentReceivedGL.ts | 0 .../commands/PaymentReceivedGLEntries.ts | 0 .../PaymentReceivedIncrement.service.ts | 0 .../PaymentReceivedInvoiceSync.service.ts | 0 .../PaymentReceivedMailNotification.ts | 0 .../PaymentReceivedMailNotificationJob.ts | 0 .../commands/PaymentReceivedSmsNotify.ts | 0 .../PaymentReceivedValidators.service.ts | 0 .../commands/PaymentsReceivedExportable.ts | 0 .../commands/PaymentsReceivedImportable.ts | 0 .../src/modules/PaymentReceived/constants.ts | 0 .../dtos/PaymentReceived.dto.ts | 0 .../PaymentReceived/models/PaymentReceived.ts | 0 .../models/PaymentReceivedEntry.ts | 0 ...ymentReceivedMailNotification.processor.ts | 0 .../queries/GetPaymentReceived.service.ts | 0 .../GetPaymentReceivedInvoices.service.ts | 0 .../queries/GetPaymentReceivedPdf.service.ts | 0 .../GetPaymentReceivedState.service.ts | 0 .../queries/GetPaymentsReceived.service.ts | 0 ...PaymentReceivedBrandingTemplate.service.ts | 0 .../PaymentReceivedEntryTransformer.ts | 0 .../queries/PaymentReceivedTransformer.ts | 0 .../queries/PaymentsReceivedPages.service.ts | 0 .../PaymentReceivedAutoIncrementSubscriber.ts | 0 .../PaymentReceivedGLEntriesSubscriber.ts | 0 ...aymentReceivedSmsNotificationSubscriber.ts | 0 .../PaymentReceivedSmsSubscriber.ts | 0 .../PaymentReceivedSyncInvoices.ts | 0 .../types/PaymentReceived.types.ts | 0 .../src/modules/PaymentReceived/utils.ts | 0 .../PaymentServices.controller.ts | 0 .../PaymentServices/PaymentServices.module.ts | 0 .../PaymentServicesApplication.ts | 0 .../commands/DeletePaymentMethodService.ts | 0 .../commands/EditPaymentMethodService.ts | 0 .../models/PaymentIntegration.model.ts | 0 .../TransactionPaymentServiceEntry.model.ts | 0 .../queries/GetPaymentMethodsState.ts | 0 .../queries/GetPaymentService.ts | 0 .../GetPaymentServicesSpecificInvoice.ts | 0 ...ymentServicesSpecificInvoiceTransformer.ts | 0 .../src/modules/PaymentServices/types.ts | 0 .../src/modules/PaymentServices/utils.ts | 0 .../BrandingTemplateDTOTransformer.ts | 0 .../GetPdfTemplateBrandingState.ts | 0 .../PdfTemplate/PdfTemplate.application.ts | 0 .../PdfTemplate/PdfTemplates.controller.ts | 0 .../PdfTemplate/PdfTemplates.module.ts | 0 .../AssignPdfTemplateDefault.service.ts | 0 .../commands/CreatePdfTemplate.service.ts | 0 .../commands/DeletePdfTemplate.service.ts | 0 .../commands/EditPdfTemplate.service.ts | 0 .../PdfTemplate/dtos/PdfTemplate.dto.ts | 0 .../modules/PdfTemplate/models/PdfTemplate.ts | 0 ...tOrganizationBrandingAttributes.service.ts | 0 .../queries/GetPdfTemplate.service.ts | 0 .../queries/GetPdfTemplate.transformer.ts | 0 .../queries/GetPdfTemplates.service.ts | 0 .../queries/GetPdfTemplates.transformer.ts | 0 .../src/modules/PdfTemplate/types.ts | 0 .../src/modules/Plaid/Plaid.module.ts | 0 .../src/modules/Resource/Resource.module.ts | 0 .../src/modules/Resource/ResourceService.ts | 0 .../src/modules/Resource/_utils.ts | 0 .../Resource/models/ResourcableModel.ts | 0 .../src/modules/Roles/AbilitySchema.ts | 0 .../src/modules/Roles/Authorization.guard.ts | 0 .../src/modules/Roles/Roles.application.ts | 0 .../src/modules/Roles/Roles.controller.ts | 0 .../src/modules/Roles/Roles.module.ts | 0 .../src/modules/Roles/Roles.types.ts | 0 .../src/modules/Roles/Roles.utils.ts | 0 .../src/modules/Roles/TenantAbilities.ts | 0 .../Roles/commands/CreateRole.service.ts | 0 .../Roles/commands/DeleteRole.service.ts | 0 .../Roles/commands/EditRole.service.ts | 0 .../src/modules/Roles/constants.ts | 0 .../src/modules/Roles/dtos/Role.dto.ts | 0 .../src/modules/Roles/models/Role.model.ts | 0 .../Roles/models/RolePermission.model.ts | 0 .../modules/Roles/queries/GetRole.service.ts | 0 .../modules/Roles/queries/GetRoles.service.ts | 0 .../Roles/queries/RolePermissionsSchema.ts | 0 .../modules/Roles/queries/RoleTransformer.ts | 0 .../src/modules/Roles/utils.ts | 0 .../src/modules/S3/S3.module.ts | 0 .../SaleEstimates.application.ts | 0 .../SaleEstimates/SaleEstimates.controller.ts | 0 .../SaleEstimates/SaleEstimates.module.ts | 0 .../SaleEstimates/SaleEstimatesExportable.ts | 0 .../SaleEstimates/SaleEstimatesImportable.ts | 0 .../commands/ApproveSaleEstimate.service.ts | 0 .../commands/ConvetSaleEstimate.service.ts | 0 .../commands/CreateSaleEstimate.service.ts | 0 .../commands/DeleteSaleEstimate.service.ts | 0 .../commands/DeliverSaleEstimate.service.ts | 0 .../commands/EditSaleEstimate.service.ts | 0 .../commands/RejectSaleEstimate.service.ts | 0 .../SaleEstimateDTOTransformer.service.ts | 0 .../commands/SaleEstimateIncrement.service.ts | 0 .../commands/SaleEstimateSmsNotify.ts | 0 .../SaleEstimateValidators.service.ts | 0 .../commands/SendSaleEstimateMail.ts | 0 .../commands/SendSaleEstimateMailJob.ts | 0 .../UnlinkConvertedSaleEstimate.service.ts | 0 .../src/modules/SaleEstimates/constants.ts | 0 .../SaleEstimates/dtos/SaleEstimate.dto.ts | 0 .../SaleEstimates/models/SaleEstimate.ts | 0 .../processes/SendSaleEstimateMail.process.ts | 0 .../queries/GetSaleEstimate.service.ts | 0 .../queries/GetSaleEstimatePdf.ts | 0 .../queries/GetSaleEstimateState.service.ts | 0 .../queries/GetSaleEstimates.service.ts | 0 .../queries/SaleEstimate.transformer.ts | 0 .../SaleEstimateMarkApprovedOnMailSent.ts | 0 .../types/SaleEstimates.types.ts | 0 .../src/modules/SaleEstimates/utils.ts | 0 .../InvoiceInventoryTransactions.ts | 0 .../SaleInvoices/InvoicePaymentsGLRewrite.ts | 0 .../modules/SaleInvoices/SaleInvoice.types.ts | 0 .../SaleInvoices/SaleInvoiceCostGLEntries.ts | 0 .../SaleInvoices/SaleInvoiceNotifyBySms.ts | 0 .../SaleInvoices/SaleInvoices.application.ts | 0 .../SaleInvoices/SaleInvoices.controller.ts | 0 .../SaleInvoices/SaleInvoices.module.ts | 0 .../modules/SaleInvoices/SalesInvoicesCost.ts | 0 ...ommandSaleInvoiceDTOTransformer.service.ts | 0 .../CommandSaleInvoiceValidators.service.ts | 0 .../commands/CreateSaleInvoice.service.ts | 0 .../commands/DeleteSaleInvoice.service.ts | 0 .../commands/DeliverSaleInvoice.service.ts | 0 .../commands/EditSaleInvoice.service.ts | 0 .../GenerateInvoicePaymentLink.service.ts | 0 .../GeneratePaymentLink.transformer.ts | 0 .../commands/SaleInvoiceIncrement.service.ts | 0 .../commands/SaleInvoicesExportable.ts | 0 .../commands/SaleInvoicesImportable.ts | 0 .../SendInvoiceInvoiceMailCommon.service.ts | 0 .../commands/SendSaleInvoiceMail.ts | 0 .../commands/SendSaleInvoiceMailJob.ts | 0 .../SendSaleInvoiceMailReminderJob.ts | 0 .../commands/WriteoffSaleInvoice.service.ts | 0 .../inventory/InvoiceInventoryTransactions.ts | 0 .../writeoff/SaleInvoiceWriteoffGL.ts | 0 .../writeoff/SaleInvoiceWriteoffGLStorage.ts | 0 .../src/modules/SaleInvoices/constants.ts | 0 .../SaleInvoices/dtos/SaleInvoice.dto.ts | 0 .../modules/SaleInvoices/ledger/InvoiceGL.ts | 0 .../SaleInvoices/ledger/InvoiceGLEntries.ts | 0 .../SaleInvoices/models/SaleInvoice.ts | 0 .../SendSaleInvoiceMail.processor.ts | 0 .../GetInvoicePaymentLink.transformer.ts | 0 .../queries/GetInvoicePaymentMail.service.ts | 0 ...nvoicePaymentMailAttributes.transformer.ts | 0 .../queries/GetInvoicePayments.service.ts | 0 .../queries/GetSaleInvoice.service.ts | 0 .../queries/GetSaleInvoiceMailReminder.ts | 0 .../GetSaleInvoiceMailState.service.ts | 0 .../GetSaleInvoiceMailState.transformer.ts | 0 .../queries/GetSaleInvoiceState.service.ts | 0 .../SaleInvoices/queries/GetSaleInvoices.ts | 0 .../queries/GetSaleInvoicesPayable.service.ts | 0 .../InvoicePaymentTransaction.transformer.ts | 0 .../SaleEstimatePdfTemplate.service.ts | 0 .../queries/SaleInvoice.transformer.ts | 0 .../queries/SaleInvoicePdf.service.ts | 0 .../queries/SaleInvoicePdfTemplate.service.ts | 0 .../SaleInvoiceTaxEntry.transformer.ts | 0 ...InvoiceChangeStatusOnMailSentSubscriber.ts | 0 .../InvoiceCostGLEntriesSubscriber.ts | 0 .../subscribers/InvoiceGLEntriesSubscriber.ts | 0 .../InvoicePaymentGLRewriteSubscriber.ts | 0 .../InvoicePaymentIntegrationSubscriber.ts | 0 .../InvoiceWriteInventoryTransactions.ts | 0 .../SaleInvoiceWriteoffSubscriber.ts | 0 .../src/modules/SaleInvoices/utils.ts | 0 .../SaleReceiptApplication.service.ts | 0 .../SaleReceipts/SaleReceipts.controller.ts | 0 .../SaleReceipts/SaleReceipts.module.ts | 0 .../commands/CloseSaleReceipt.service.ts | 0 .../commands/CreateSaleReceipt.service.ts | 0 .../commands/DeleteSaleReceipt.service.ts | 0 .../commands/EditSaleReceipt.service.ts | 0 .../commands/SaleReceiptCostGLEntries.ts | 0 .../SaleReceiptDTOTransformer.service.ts | 0 .../commands/SaleReceiptIncrement.service.ts | 0 .../SaleReceiptInventoryTransactions.ts | 0 .../commands/SaleReceiptMailNotification.ts | 0 .../SaleReceiptMailNotificationJob.ts | 0 .../commands/SaleReceiptNotifyBySms.ts | 0 .../commands/SaleReceiptValidators.service.ts | 0 .../commands/SaleReceiptsExportable.ts | 0 .../commands/SaleReceiptsImportable.ts | 0 .../src/modules/SaleReceipts/constants.ts | 0 .../SaleReceipts/dtos/SaleReceipt.dto.ts | 0 .../SaleReceiptInventoryTransactions.ts | 0 .../SaleReceiptWriteInventoryTransactions.ts | 0 .../SaleReceipts/ledger/SaleReceiptGL.ts | 0 .../ledger/SaleReceiptGLEntries.ts | 0 .../SaleReceipts/models/SaleReceipt.ts | 0 .../processes/SendSaleReceiptMail.process.ts | 0 .../queries/GetSaleReceipt.service.ts | 0 .../queries/GetSaleReceiptState.service.ts | 0 .../queries/GetSaleReceipts.service.ts | 0 .../SaleReceiptBrandingTemplate.service.ts | 0 .../queries/SaleReceiptTransformer.ts | 0 .../queries/SaleReceiptsPdf.service.ts | 0 .../SaleReceiptCostGLEntriesSubscriber.ts | 0 .../SaleReceiptGLEntriesSubscriber.ts | 0 ...aleReceiptMarkClosedOnMailSentSubcriber.ts | 0 .../SaleReceipts/types/SaleReceipts.types.ts | 0 .../src/modules/SaleReceipts/utils.ts | 0 .../src/modules/Search/SearchableMdel.ts | 0 .../src/modules/Settings/ModelSettings.ts | 0 .../modules/Settings/Settings.controller.ts | 0 .../src/modules/Settings/Settings.module.ts | 0 .../src/modules/Settings/Settings.types.ts | 0 .../Settings/SettingsApplication.service.ts | 0 .../src/modules/Settings/SettingsStore.ts | 0 .../Settings/commands/SaveSettings.service.ts | 0 .../src/modules/Settings/models/Setting.ts | 0 .../Settings/queries/GetSettings.service.ts | 0 .../repositories/Setting.repository.ts | 0 .../CreatePaymentReceivedStripePayment.ts | 0 .../StripePayment/CreateStripeAccountLink.ts | 0 .../CreateStripeAccountService.ts | 0 .../StripePayment/ExchangeStripeOauthToken.ts | 0 .../GetStripeAuthorizationLink.ts | 0 .../StripePayment/StripePayment.controller.ts | 0 .../StripePayment/StripePayment.module.ts | 0 .../StripePayment/StripePayment.types.ts | 0 .../StripePayment/StripePaymentApplication.ts | 0 .../StripePayment/StripePaymentService.ts | 0 .../models/PaymentIntegration.model.ts | 0 .../subscribers/SeedStripeAccounts.ts | 0 .../subscribers/StripeWebhooksSubscriber.ts | 0 .../src/modules/StripePayment/types.ts | 0 .../Subscription/Subscription.module.ts | 0 .../Subscription/SubscriptionApplication.ts | 0 .../Subscription/SubscriptionPeriod.ts | 0 .../Subscription/Subscriptions.controller.ts | 0 .../SubscriptionsLemonWebhook.controller.ts | 0 .../CancelLemonSubscription.service.ts | 0 .../ChangeLemonSubscription.service.ts | 0 .../MarkSubscriptionCanceled.service.ts | 0 .../MarkSubscriptionChanged.service.ts | 0 .../MarkSubscriptionPaymentFailed.service.ts | 0 ...arkSubscriptionPaymentSuccessed.service.ts | 0 .../MarkSubscriptionResumed.sevice.ts | 0 .../commands/NewSubscription.service.ts | 0 .../ResumeLemonSubscription.service.ts | 0 .../NotAllowedChangeSubscriptionPlan.ts | 0 .../interceptors/Subscription.guard.ts | 0 .../src/modules/Subscription/models/Plan.ts | 0 .../Subscription/models/PlanSubscription.ts | 0 .../GetLemonSqueezyCheckout.service.ts | 0 .../queries/GetSubscriptions.service.ts | 0 .../queries/GetSubscriptionsTransformer.ts | 0 .../PlanSubscription.repository.ts | 0 .../SubscribeFreeOnSignupCommunity.ts | 0 ...ggerInvalidateCacheOnSubscriptionChange.ts | 0 .../src/modules/Subscription/types.ts | 0 .../src/modules/Subscription/utils.ts | 0 .../webhooks/LemonSqueezyWebhooks.ts | 0 .../System/SystemDB/SystemDB.constants.ts | 0 .../System/SystemDB/SystemDB.controller.ts | 0 .../System/SystemDB/SystemDB.module.ts | 0 .../SystemModels/SystemModels.constants.ts | 0 .../SystemModels/SystemModels.module.ts | 0 .../src/modules/System/models/SystemModel.ts | 0 .../src/modules/System/models/SystemUser.ts | 0 .../modules/System/models/TenantBaseModel.ts | 0 .../System/models/TenantMetadataModel.ts | 0 .../src/modules/System/models/TenantModel.ts | 0 .../System/repositories/Tenant.repository.ts | 0 .../ItemEntriesTaxTransactions.service.ts | 0 .../TaxRates/SyncItemTaxRateOnEditTaxRate.ts | 0 .../modules/TaxRates/TaxRate.application.ts | 0 .../modules/TaxRates/TaxRate.controller.ts | 0 .../src/modules/TaxRates/TaxRate.module.ts | 0 .../src/modules/TaxRates/TaxRates.types.ts | 0 .../modules/TaxRates/TaxRatesExportable.ts | 0 .../TaxRates/TaxRatesImportable.SampleData.ts | 0 .../modules/TaxRates/TaxRatesImportable.ts | 0 .../WriteTaxTransactionsItemEntries.ts | 0 .../commands/ActivateTaxRate.service.ts | 0 .../CommandTaxRatesValidator.service.ts | 0 .../commands/CreateTaxRate.service.ts | 0 .../commands/DeleteTaxRate.service.ts | 0 .../TaxRates/commands/EditTaxRate.service.ts | 0 .../TaxRates/commands/InactivateTaxRate.ts | 0 .../src/modules/TaxRates/constants.ts | 0 .../src/modules/TaxRates/dtos/TaxRate.dto.ts | 0 .../modules/TaxRates/models/TaxRate.model.ts | 0 .../models/TaxRateTransaction.model.ts | 0 .../TaxRates/queries/GetTaxRate.service.ts | 0 .../TaxRates/queries/GetTaxRates.service.ts | 0 .../TaxRates/queries/TaxRate.transformer.ts | 0 .../BillTaxRateValidateSubscriber.ts | 0 .../SaleInvoiceTaxRateValidateSubscriber.ts | 0 .../SyncItemTaxRateOnEditTaxSubscriber.ts | 0 .../WriteBillTaxTransactionsSubscriber.ts | 0 .../WriteInvoiceTaxTransactionsSubscriber.ts | 0 .../src/modules/TaxRates/utils.ts | 0 .../TemplateInjectable.module.ts | 0 .../TemplateInjectable.service.ts | 0 .../EnsureTenantIsInitialized.guard.ts | 0 .../Tenancy/EnsureTenantIsSeeded.guards.ts | 0 .../src/modules/Tenancy/Tenancy.module.ts | 0 .../TenancyCache/TenancyCache.module.ts | 0 .../modules/Tenancy/TenancyContext.service.ts | 0 .../Tenancy/TenancyDB/TenancyDB.constants.ts | 0 .../Tenancy/TenancyDB/TenancyDB.module.ts | 0 .../Tenancy/TenancyDB/TransactionsHooks.ts | 0 .../Tenancy/TenancyDB/UnitOfWork.service.ts | 0 .../modules/Tenancy/TenancyGlobal.guard.ts | 0 .../TenancyModels/Tenancy.constants.ts | 0 .../Tenancy/TenancyModels/Tenancy.module.ts | 0 .../TenancyModels/models/TenantUser.model.ts | 0 .../src/modules/Tenancy/Tenant.controller.ts | 0 .../TenantDBManager/TenantDBManager.module.ts | 0 .../TenantDBManager/TenantDBManager.ts | 0 .../modules/TenantDBManager/TenantsManager.ts | 0 .../src/modules/TenantDBManager/_utils.ts | 0 .../exceptions/TenantAlreadyInitialized.ts | 0 .../exceptions/TenantAlreadySeeded.ts | 0 .../exceptions/TenantDBAlreadyExists.ts | 0 .../exceptions/TenantDatabaseNotBuilt.ts | 0 .../ItemEntry.transformer.ts | 0 .../TransactionItemEntry/ItemEntry.types.ts | 0 .../TransactionItemEntry/dto/ItemEntry.dto.ts | 0 .../TransactionItemEntry/models/ItemEntry.ts | 0 .../TransactionsLocking.controller.ts | 0 .../TransactionsLocking.module.ts | 0 .../TransactionsLockingRepository.ts | 0 .../CommandTransactionsLockingService.ts | 0 .../modules/TransactionsLocking/constants.ts | 0 .../dtos/TransactionsLocking.dto.ts | 0 .../FinancialTransactionLockingGuard.ts | 0 .../PurchasesTransactionLockingGuard.ts | 0 .../guards/SalesTransactionLockingGuard.ts | 0 .../guards/TransactionsLockingGuard.ts | 0 .../queries/QueryTransactionsLocking.ts | 0 .../TransactionsLockingMetaTransformer.ts | 0 ...ncialsTransactionLockingGuardSubscriber.ts | 0 ...chasesTransactionLockingGuardSubscriber.ts | 0 .../SalesTransactionLockingGuardSubscriber.ts | 0 .../types/TransactionsLocking.types.ts | 0 .../modules/Transformer/Transformer.module.ts | 0 .../src/modules/Transformer/Transformer.ts | 0 .../modules/Transformer/Transformer.types.ts | 0 .../TransformerInjectable.service.ts | 0 .../VendorCredit/VendorCredits.controller.ts | 0 .../VendorCredit/VendorCredits.module.ts | 0 .../VendorCreditsApplication.service.ts | 0 .../commands/CreateVendorCredit.service.ts | 0 .../commands/DeleteVendorCredit.service.ts | 0 .../commands/EditVendorCredit.service.ts | 0 .../commands/OpenVendorCredit.service.ts | 0 .../VendorCreditAutoIncrement.service.ts | 0 .../VendorCreditDTOTransform.service.ts | 0 .../VendorCredit/commands/VendorCreditGL.ts | 0 .../commands/VendorCreditGLEntries.ts | 0 .../VendorCreditInventoryTransactions.ts | 0 .../commands/VendorCreditsExportable.ts | 0 .../commands/VendorCreditsImportable.ts | 0 .../src/modules/VendorCredit/constants.ts | 0 .../VendorCredit/dtos/VendorCredit.dto.ts | 0 .../VendorCredit/models/VendorCredit.ts | 0 .../queries/GetVendorCredit.service.ts | 0 .../queries/GetVendorCredits.service.ts | 0 .../queries/VendorCreditTransformer.ts | 0 .../DeleteVendorAssociatedVendorCredit.ts | 0 ...RefundSyncVendorCreditBalanceSubscriber.ts | 0 .../RefundVendorCreditGLEntriesSubscriber.ts | 0 .../VendorCreditAutoSerialSubscriber.ts | 0 .../VendorCreditGLEntriesSubscriber.ts | 0 ...orCreditInventoryTransactionsSusbcriber.ts | 0 .../VendorCredit/types/VendorCredit.types.ts | 0 .../VendorCreditApplyBills.controller.ts | 0 .../VendorCreditApplyBills.module.ts | 0 ...ndorCreditApplyBillsApplication.service.ts | 0 .../VendorCreditsApplyBills.constants.ts | 0 .../ApplyVendorCreditSyncBills.service.ts | 0 .../ApplyVendorCreditSyncInvoiced.service.ts | 0 .../ApplyVendorCreditToBills.service.ts | 0 .../DeleteApplyVendorCreditToBill.service.ts | 0 .../models/VendorCreditAppliedBill.ts | 0 .../GetAppliedBillsToVendorCredit.service.ts | 0 .../GetVendorCreditToApplyBills.service.ts | 0 .../VendorCreditAppliedBillTransformer.ts | 0 .../VendorCreditToApplyBillTransformer.ts | 0 .../ApplyVendorCreditSyncBillsSubscriber.ts | 0 ...ApplyVendorCreditSyncInvoicedSubscriber.ts | 0 .../types/VendorCreditApplyBills.types.ts | 0 .../RefundCreditSyncBills.ts | 0 .../VendorCreditsRefund.application.ts | 0 .../VendorCreditsRefund.controller.ts | 0 .../VendorCreditsRefund.module.ts | 0 .../CreateRefundVendorCredit.service.ts | 0 .../DeleteRefundVendorCredit.service.ts | 0 .../RefundSyncCreditRefundedAmount.service.ts | 0 .../RefundSyncVendorCreditBalance.service.ts | 0 .../commands/RefundVendorCredit.service.ts | 0 .../commands/RefundVendorCreditGLEntries.ts | 0 .../commands/RefundVendorCreditTransformer.ts | 0 .../modules/VendorCreditsRefund/constants.ts | 0 .../dtos/RefundVendorCredit.dto.ts | 0 .../models/RefundVendorCredit.ts | 0 .../queries/GetRefundVendorCredit.service.ts | 0 .../queries/GetRefundVendorCredits.service.ts | 0 .../types/VendorCreditRefund.types.ts | 0 .../src/modules/Vendors/VendorGLEntries.ts | 0 .../modules/Vendors/VendorGLEntriesStorage.ts | 0 .../src/modules/Vendors/Vendors.controller.ts | 0 .../src/modules/Vendors/Vendors.module.ts | 0 .../Vendors/VendorsApplication.service.ts | 0 .../src/modules/Vendors/VendorsExportable.ts | 0 .../src/modules/Vendors/VendorsImportable.ts | 0 .../src/modules/Vendors/_SampleData.ts | 0 .../commands/ActivateVendor.service.ts | 0 .../Vendors/commands/CreateEditVendorDTO.ts | 0 .../Vendors/commands/CreateVendor.service.ts | 0 .../Vendors/commands/DeleteVendor.service.ts | 0 .../EditOpeningBalanceVendor.service.ts | 0 .../Vendors/commands/EditVendor.service.ts | 0 .../Vendors/commands/VendorValidators.ts | 0 .../src/modules/Vendors/constants.ts | 0 .../modules/Vendors/dtos/CreateVendor.dto.ts | 0 .../modules/Vendors/dtos/EditVendor.dto.ts | 0 .../src/modules/Vendors/models/Vendor.ts | 0 .../src/modules/Vendors/queries/GetVendor.ts | 0 .../Vendors/queries/GetVendors.service.ts | 0 .../Vendors/queries/VendorTransformer.ts | 0 .../subscribers/VendorGLEntriesSubscriber.ts | 0 .../modules/Vendors/types/Vendors.types.ts | 0 .../Views/GetResourceColumns.service.ts | 0 .../modules/Views/GetResourceViews.service.ts | 0 .../src/modules/Views/Views.types.ts | 0 .../src/modules/Views/models/View.model.ts | 0 .../modules/Views/models/ViewColumn.model.ts | 0 .../modules/Views/models/ViewRole.model.ts | 0 .../AccountsTransactionsWarehouses.ts | 0 ...AccountsTransactionsWarehousesSubscribe.ts | 0 .../Activate/BillWarehousesActivate.ts | 0 .../Activate/CreditNoteWarehousesActivate.ts | 0 .../Activate/EstimateWarehousesActivate.ts | 0 ...InventoryTransactionsWarehousesActivate.ts | 0 .../Activate/InvoiceWarehousesActivate.ts | 0 .../Activate/ReceiptWarehousesActivate.ts | 0 .../VendorCreditWarehousesActivate.ts | 0 .../ActivateWarehousesSubscriber.ts | 0 .../src/modules/Warehouses/CRUDWarehouse.ts | 0 .../CreateInitialWarehousesitemsQuantity.ts | 0 .../ValidateWarehouseExistance.ts | 0 .../WarehouseTransactionDTOTransform.ts | 0 .../Integrations/WarehousesDTOValidators.ts | 0 .../Integrations/WarehousesItemsQuantity.ts | 0 .../WarehousesItemsQuantitySynSubscriber.ts | 0 .../WarehousesItemsQuantitySync.ts | 0 .../Warehouses/Integrations/constants.ts | 0 .../Warehouses/Items/GetItemWarehouses.ts | 0 .../Items/GettItemWarehouseTransformer.ts | 0 ...pdateInventoryTransactionsWithWarehouse.ts | 0 .../src/modules/Warehouses/Warehouse.types.ts | 0 .../Warehouses/Warehouses.controller.ts | 0 .../modules/Warehouses/Warehouses.module.ts | 0 .../WarehousesApplication.service.ts | 0 .../modules/Warehouses/WarehousesSettings.ts | 0 .../commands/ActivateWarehouses.service.ts | 0 .../CreateInitialWarehouse.service.ts | 0 .../commands/CreateWarehouse.service.ts | 0 .../commands/DeleteItemWarehousesQuantity.ts | 0 .../commands/DeleteWarehouse.service.ts | 0 .../commands/EditWarehouse.service.ts | 0 .../commands/WarehouseMarkPrimary.service.ts | 0 .../commands/WarehouseValidator.service.ts | 0 .../src/modules/Warehouses/contants.ts | 0 .../modules/Warehouses/dtos/Warehouse.dto.ts | 0 .../models/ItemWarehouseQuantity.ts | 0 .../Warehouses/models/Warehouse.model.ts | 0 .../Warehouses/queries/GetWarehouse.ts | 0 .../Warehouses/queries/GetWarehouses.ts | 0 .../BillWarehousesActivateSubscriber.ts | 0 .../CreditNoteWarehousesActivateSubscriber.ts | 0 .../EstimateWarehousesActivateSubscriber.ts | 0 ...ransactionsWarehousesActivateSubscriber.ts | 0 .../InvoiceWarehousesActivateSubscriber.ts | 0 .../ReceiptWarehousesActivateSubscriber.ts | 0 ...endorCreditWarehousesActivateSubscriber.ts | 0 .../DeleteItemWarehousesQuantitySubscriber.ts | 0 ...yAdjustmentWarehouseValidatorSubscriber.ts | 0 .../Purchases/BillWarehousesSubscriber.ts | 0 .../VendorCreditWarehousesSubscriber.ts | 0 .../Sales/CreditNoteWarehousesSubscriber.ts | 0 .../Sales/SaleEstimateWarehousesSubscriber.ts | 0 .../Sales/SaleInvoicesWarehousesSubscriber.ts | 0 .../Sales/SaleReceiptWarehousesSubscriber.ts | 0 .../WarehouseTransferApplication.ts | 0 .../WarehouseTransfers.controller.ts | 0 .../WarehouseTransfers.module.ts | 0 .../commands/CommandWarehouseTransfer.ts | 0 .../commands/CreateWarehouseTransfer.ts | 0 .../commands/DeleteWarehouseTransfer.ts | 0 .../commands/EditWarehouseTransfer.ts | 0 .../commands/InitiateWarehouseTransfer.ts | 0 .../commands/TransferredWarehouseTransfer.ts | 0 .../WarehouseTransferAutoIncrement.ts | 0 ...houseTransferWriteInventoryTransactions.ts | 0 .../modules/WarehousesTransfers/constants.ts | 0 .../dtos/WarehouseTransfer.dto.ts | 0 .../models/WarehouseTransfer.ts | 0 .../models/WarehouseTransferEntry.ts | 0 .../queries/GetWarehouseTransfer.ts | 0 .../queries/GetWarehouseTransfers.ts | 0 .../WarehouseTransferItemTransformer.ts | 0 .../queries/WarehouseTransferTransfomer.ts | 0 ...arehouseTransferAutoIncrementSubscriber.ts | 0 ...TransferInventoryTransactionsSubscriber.ts | 0 .../src/repositories/AccountRepository.ts | 397 -- .../AccountTransactionRepository.ts | 99 - .../src/repositories/BaseModelRepository.ts | 5 - .../server/src/repositories/BillRepository.ts | 30 - .../src/repositories/CachableRepository.ts | 261 - .../src/repositories/ContactRepository.ts | 12 - .../src/repositories/CustomerRepository.ts | 46 - .../src/repositories/EntityRepository.ts | 241 - .../repositories/ExpenseEntryRepository.ts | 11 - .../src/repositories/ExpenseRepository.ts | 35 - .../InventoryTransactionRepository.ts | 11 - .../server/src/repositories/ItemRepository.ts | 12 - .../src/repositories/JournalRepository.ts | 11 - .../PaymentReceiveEntryRepository.ts | 11 - .../repositories/PaymentReceiveRepository.ts | 11 - .../src/repositories/SaleInvoiceRepository.ts | 30 - .../src/repositories/SettingRepository.ts | 11 - .../src/repositories/TenantRepository.ts | 20 - .../src/repositories/VendorRepository.ts | 50 - .../server/src/repositories/ViewRepository.ts | 18 - .../src/repositories/ViewRoleRepository.ts | 6 - packages/server/src/server.ts | 16 - .../AccountsTransactionsWarehouses.ts | 26 - ...AccountsTransactionsWarehousesSubscribe.ts | 38 - .../services/Accounting/JournalCommands.ts | 66 - .../services/Accounting/JournalContacts.ts | 74 - .../src/services/Accounting/JournalEntry.ts | 10 - .../services/Accounting/JournalFinancial.ts | 17 - .../src/services/Accounting/JournalPoster.ts | 759 -- .../server/src/services/Accounting/Ledger.ts | 291 - .../Accounting/LedgerContactStorage.ts | 139 - .../Accounting/LedgerEntriesStorage.ts | 90 - .../Accounting/LedgerStorageRevert.ts | 61 - .../Accounting/LedgerStorageService.ts | 98 - .../Accounting/LedgetAccountStorage.ts | 155 - .../server/src/services/Accounting/utils.ts | 41 - .../Accounts/AccountTransactionTransformer.ts | 124 - .../src/services/Accounts/AccountTransform.ts | 126 - .../services/Accounts/AccountsApplication.ts | 147 - .../services/Accounts/AccountsExportable.ts | 32 - .../Accounts/AccountsImportable.SampleData.ts | 50 - .../services/Accounts/AccountsImportable.ts | 45 - .../Accounts/AccountsTypesServices.ts | 21 - .../src/services/Accounts/ActivateAccount.ts | 60 - .../Accounts/CommandAccountValidators.ts | 236 - .../src/services/Accounts/CreateAccount.ts | 159 - .../src/services/Accounts/DeleteAccount.ts | 108 - .../src/services/Accounts/EditAccount.ts | 116 - .../src/services/Accounts/GetAccount.ts | 50 - .../Accounts/GetAccountTransactions.ts | 51 - .../src/services/Accounts/GetAccounts.ts | 78 - .../Accounts/MutateBaseCurrencyAccounts.ts | 22 - .../server/src/services/Accounts/constants.ts | 103 - .../susbcribers/MutateBaseCurrencyAccounts.ts | 34 - .../Attachments/AttachmentTransformer.ts | 19 - .../Attachments/AttachmentsApplication.ts | 106 - .../services/Attachments/DeleteAttachment.ts | 45 - .../src/services/Attachments/GetAttachment.ts | 22 - .../Attachments/GetAttachmentPresignedUrl.ts | 37 - .../services/Attachments/LinkAttachment.ts | 82 - .../services/Attachments/S3UploadPipeline.ts | 60 - .../services/Attachments/UnlinkAttachment.ts | 125 - .../services/Attachments/UploadDocument.ts | 26 - .../Attachments/ValidateAttachments.ts | 29 - .../server/src/services/Attachments/_utils.ts | 14 - .../src/services/Attachments/constants.ts | 5 - .../Attachments/events/AttachmentsOnBills.ts | 151 - .../events/AttachmentsOnCreditNote.ts | 155 - .../events/AttachmentsOnExpenses.ts | 151 - .../events/AttachmentsOnManualJournals.ts | 157 - .../events/AttachmentsOnPaymentsMade.ts | 157 - .../events/AttachmentsOnPaymentsReceived.ts | 157 - .../events/AttachmentsOnSaleEstimates.ts | 154 - .../events/AttachmentsOnSaleInvoice.ts | 159 - .../events/AttachmentsOnSaleReceipts.ts | 157 - .../events/AttachmentsOnVendorCredits.ts | 157 - .../server/src/services/Attachments/utils.ts | 9 - .../services/AuthenticatedAccount/index.ts | 15 - .../Authentication/AuthApplication.ts | 104 - .../Authentication/AuthSendResetPassword.ts | 130 - .../src/services/Authentication/AuthSignin.ts | 105 - .../src/services/Authentication/AuthSignup.ts | 121 - .../Authentication/AuthSignupConfirm.ts | 57 - .../Authentication/AuthSignupResend.ts | 34 - .../AuthenticationMailMessages.ts | 65 - .../services/Authentication/GetAuthMeta.ts | 20 - .../services/Authentication/RateLimiter.ts | 49 - .../src/services/Authentication/_constants.ts | 14 - .../src/services/Authentication/_utils.ts | 22 - .../events/SendVerfiyMailOnSignUp.ts | 34 - .../Authentication/jobs/SendVerifyMailJob.ts | 35 - .../BankAccounts/BankAccountsApplication.tsx | 72 - .../BankAccounts/DisconnectBankAccount.tsx | 78 - .../BankAccounts/GetBankAccountSummary.ts | 116 - .../BankAccounts/PauseBankAccountFeeds.tsx | 44 - .../BankAccounts/RefreshBankAccount.tsx | 36 - .../BankAccounts/ResumeBankAccountFeeds.tsx | 43 - ...ategorizedTransactionsOnAccountDeleting.ts | 78 - .../DisconnectPlaidItemOnAccountDeleted.ts | 64 - .../services/Banking/BankAccounts/types.ts | 19 - .../Banking/Exclude/ExcludeBankTransaction.ts | 70 - .../Exclude/ExcludeBankTransactions.ts | 32 - .../ExcludeBankTransactionsApplication.ts | 99 - .../Exclude/GetExcludedBankTransactions.ts | 65 - .../Exclude/UnexcludeBankTransaction.ts | 74 - .../Exclude/UnexcludeBankTransactions.ts | 31 - .../src/services/Banking/Exclude/_types.ts | 34 - ...rementUncategorizedTransactionOnExclude.ts | 68 - .../src/services/Banking/Exclude/utils.ts | 32 - .../GetMatchedTransactionBillsTransformer.ts | 131 - ...etMatchedTransactionCashflowTransformer.ts | 142 - ...etMatchedTransactionExpensesTransformer.ts | 142 - ...etMatchedTransactionInvoicesTransformer.ts | 138 - ...hedTransactionManualJournalsTransformer.ts | 149 - .../Matching/GetMatchedTransactions.ts | 117 - .../Matching/GetMatchedTransactionsByBills.ts | 139 - .../GetMatchedTransactionsByCashflow.ts | 85 - .../GetMatchedTransactionsByExpenses.ts | 85 - .../GetMatchedTransactionsByInvoices.ts | 145 - .../GetMatchedTransactionsByManualJournals.ts | 83 - .../Matching/GetMatchedTransactionsByType.ts | 71 - .../MatchBankTransactionsApplication.ts | 70 - .../Banking/Matching/MatchTransactions.ts | 162 - .../Matching/MatchTransactionsTypes.ts | 63 - .../MatchTransactionsTypesRegistry.ts | 50 - .../Matching/UnmatchMatchedTransaction.ts | 49 - .../Matching/ValidateTransactionsMatched.ts | 36 - .../src/services/Banking/Matching/_utils.ts | 65 - ...crementUncategorizedTransactionsOnMatch.ts | 73 - .../ValidateMatchingOnCashflowDelete.ts | 37 - .../events/ValidateMatchingOnExpenseDelete.ts | 37 - .../ValidateMatchingOnManualJournalDelete.ts | 37 - .../ValidateMatchingOnPaymentMadeDelete.ts | 40 - ...ValidateMatchingOnPaymentReceivedDelete.ts | 37 - .../src/services/Banking/Matching/types.ts | 73 - .../Banking/Plaid/PlaidApplication.ts | 59 - .../Plaid/PlaidFetchTransactionsJob.ts | 43 - .../src/services/Banking/Plaid/PlaidItem.ts | 58 - .../services/Banking/Plaid/PlaidLinkToken.ts | 34 - .../src/services/Banking/Plaid/PlaidSyncDB.ts | 270 - .../Banking/Plaid/PlaidUpdateTransactions.ts | 173 - .../Plaid/PlaidWebhookTenantBootMiddleware.ts | 32 - .../services/Banking/Plaid/PlaidWebhooks.ts | 158 - ...dateTransactionsOnItemCreatedSubscriber.ts | 34 - .../RecognizeSyncedBankTransactions.ts | 43 - .../src/services/Banking/Plaid/utils.ts | 87 - .../GetAutofillCategorizeTransaction.ts | 45 - ...utofillCategorizeTransactionTransformer.ts | 176 - .../RecognizeTranasctionsService.ts | 130 - .../RevertRecognizedTransactions.ts | 72 - .../Banking/RegonizeTranasctions/_types.ts | 11 - .../Banking/RegonizeTranasctions/_utils.ts | 121 - .../events/TriggerRecognizedTransactions.ts | 113 - .../jobs/RecognizeTransactionsJob.ts | 36 - .../jobs/RerecognizeTransactionsJob.ts | 45 - .../jobs/RevertRecognizedTransactionsJob.ts | 38 - .../Banking/Rules/BankRulesApplication.ts | 82 - .../services/Banking/Rules/CreateBankRule.ts | 72 - .../services/Banking/Rules/DeleteBankRule.ts | 64 - .../services/Banking/Rules/DeleteBankRules.ts | 34 - .../services/Banking/Rules/EditBankRule.ts | 84 - .../src/services/Banking/Rules/GetBankRule.ts | 35 - .../Banking/Rules/GetBankRuleTransformer.ts | 11 - .../services/Banking/Rules/GetBankRules.ts | 33 - .../Banking/Rules/GetBankRulesTransformer.ts | 49 - .../events/UnlinkBankRuleOnDeleteBankRule.ts | 34 - .../src/services/Banking/Rules/types.ts | 131 - .../src/services/Branches/ActivateBranches.ts | 90 - .../BranchIntegrationErrorsMiddleware.ts | 35 - .../src/services/Branches/BranchValidate.ts | 52 - .../services/Branches/BranchesApplication.ts | 112 - .../src/services/Branches/BranchesSettings.ts | 29 - .../src/services/Branches/CRUDBranch.ts | 30 - .../src/services/Branches/CreateBranch.ts | 64 - .../src/services/Branches/DeleteBranch.ts | 77 - .../src/services/Branches/EditBranch.ts | 65 - .../src/services/Branches/EventsProvider.ts | 50 - .../server/src/services/Branches/GetBranch.ts | 26 - .../src/services/Branches/GetBranches.ts | 22 - .../BranchTransactionDTOTransform.ts | 35 - .../Cashflow/CashflowActivateBranches.ts | 26 - .../Expense/ExpensesActivateBranches.ts | 26 - .../ManualJournalBranchesActivate.ts | 26 - .../ManualJournalDTOTransformer.ts | 32 - .../ManualJournalsBranchesValidator.ts | 23 - .../Integrations/ManualJournals/constants.ts | 4 - .../Purchases/BillBranchesActivate.ts | 26 - .../Purchases/PaymentMadeBranchesActivate.ts | 26 - .../Purchases/VendorCreditBranchesActivate.ts | 26 - .../Sales/CreditNoteBranchesActivate.ts | 26 - .../Sales/PaymentReceiveBranchesActivate.ts | 26 - .../Sales/SaleEstimatesBranchesActivate.ts | 26 - .../Sales/SaleInvoiceBranchesActivate.ts | 26 - .../Sales/SaleReceiptBranchesActivate.ts | 26 - .../Integrations/ValidateBranchExistance.ts | 75 - .../Branches/Integrations/constants.ts | 6 - .../services/Branches/MarkBranchAsPrimary.ts | 67 - .../CashflowBranchesActivateSubscriber.ts | 38 - .../CreditNoteBranchesActivateSubscriber.ts | 38 - .../ExpenseBranchesActivateSubscriber.ts | 38 - .../PaymentMadeBranchesActivateSubscriber.ts | 38 - ...aymentReceiveBranchesActivateSubscriber.ts | 38 - ...SaleEstiamtesBranchesActivateSubscriber.ts | 38 - .../SaleInvoiceBranchesActivateSubscriber.ts | 38 - .../SaleReceiptsBranchesActivateSubscriber.ts | 38 - .../Branches/Subscribers/Activate/index.ts | 8 - .../Validators/BillBranchSubscriber.ts | 53 - .../CashflowBranchDTOValidatorSubscriber.ts | 35 - .../ContactOpeningBalanceBranchSubscriber.ts | 104 - .../CreditNoteBranchesSubscriber.ts | 56 - .../CreditNoteRefundBranchSubscriber.ts | 35 - .../Validators/ExpenseBranchSubscriber.ts | 56 - ...toryAdjustmentBranchValidatorSubscriber.ts | 35 - .../InvoiceBranchValidatorSubscriber.ts | 56 - .../ManualJournalBranchSubscriber.ts | 76 - .../Validators/PaymentMadeBranchSubscriber.ts | 56 - .../PaymentReceiveBranchSubscriber.ts | 56 - .../SaleEstimateMultiBranchesSubscriber.ts | 56 - .../SaleReceiptBranchesSubscriber.ts | 56 - .../VendorCreditBranchSubscriber.ts | 56 - .../VendorCreditRefundBranchSubscriber.ts | 35 - .../Branches/Subscribers/Validators/index.ts | 15 - .../server/src/services/Branches/constants.ts | 7 - packages/server/src/services/Cache/index.ts | 49 - .../Cashflow/CashflowAccountTransformer.ts | 63 - .../services/Cashflow/CashflowApplication.ts | 277 - .../Cashflow/CashflowDeleteAccount.ts | 30 - .../CashflowTransactionAutoIncrement.ts | 31 - .../CashflowTransactionJournalEntries.ts | 166 - .../Cashflow/CashflowTransactionSubscriber.ts | 83 - .../CashflowTransactionTransformer.ts | 56 - .../CashflowTransactionsTransformer.ts | 71 - .../Cashflow/CashflowWithAccountSubscriber.ts | 34 - .../Cashflow/CategorizeCashflowTransaction.ts | 120 - .../CategorizeRecognizedTransaction.ts | 8 - .../CategorizeTransactionAsExpense.ts | 80 - .../Cashflow/CommandCasflowValidator.ts | 108 - .../CreateUncategorizedTransaction.ts | 67 - .../DeleteCashflowTransactionService.ts | 96 - .../Cashflow/GetCashflowAccountsService.ts | 61 - .../GetCashflowTransactionsService.ts | 58 - .../GetPendingBankAccountTransaction.ts | 53 - ...endingBankAccountTransactionTransformer.ts | 73 - .../Cashflow/GetRecognizedTransaction.ts | 40 - .../GetRecognizedTransactionTransformer.ts | 262 - .../Cashflow/GetRecongizedTransactions.ts | 72 - .../Cashflow/GetUncategorizedTransaction.ts | 36 - .../Cashflow/GetUncategorizedTransactions.ts | 91 - .../Cashflow/NewCashflowTransactionService.ts | 183 - .../RemovePendingUncategorizedTransaction.ts | 72 - .../UncategorizeCashflowTransaction.ts | 100 - .../UncategorizeCashflowTransactionsBulk.ts | 37 - .../UncategorizedTransactionTransformer.ts | 146 - .../UncategorizedTransactionsImportable.ts | 101 - .../server/src/services/Cashflow/constants.ts | 111 - ...entUncategorizedTransactionOnCategorize.ts | 100 - ...DeleteCashflowTransactionOnUncategorize.ts | 46 - .../PreventDeleteTransactionsOnDelete.ts | 52 - .../server/src/services/Cashflow/utils.ts | 96 - .../ChromiumlyHtmlConvert.ts | 74 - .../ChromiumlyTenancy/ChromiumlyTenancy.ts | 29 - .../src/services/ChromiumlyTenancy/utils.ts | 14 - .../services/Contacts/ContactTransformer.ts | 41 - .../src/services/Contacts/ContactsService.ts | 378 - .../Customers/CRUD/ActivateCustomer.ts | 70 - .../Contacts/Customers/CRUD/CreateCustomer.ts | 76 - .../Customers/CRUD/CreateEditCustomerDTO.ts | 73 - .../Customers/CRUD/CustomerValidators.ts | 16 - .../Contacts/Customers/CRUD/DeleteCustomer.ts | 69 - .../Contacts/Customers/CRUD/EditCustomer.ts | 77 - .../CRUD/EditOpeningBalanceCustomer.ts | 74 - .../Contacts/Customers/CRUD/GetCustomer.ts | 36 - .../Contacts/Customers/CRUD/GetCustomers.ts | 77 - .../Contacts/Customers/CustomerGLEntries.ts | 117 - .../Customers/CustomerGLEntriesStorage.ts | 90 - .../Contacts/Customers/CustomerTransformer.ts | 38 - .../Customers/CustomersApplication.ts | 122 - .../Contacts/Customers/CustomersExportable.ts | 30 - .../Contacts/Customers/CustomersImportable.ts | 34 - .../CustomerGLEntriesSubscriber.ts | 91 - .../Contacts/Customers/_SampleData.ts | 158 - .../services/Contacts/Customers/constants.ts | 27 - .../Contacts/Vendors/CRUD/ActivateVendor.ts | 67 - .../Vendors/CRUD/CreateEditVendorDTO.ts | 71 - .../Contacts/Vendors/CRUD/CreateVendor.ts | 75 - .../Contacts/Vendors/CRUD/DeleteVendor.ts | 68 - .../Vendors/CRUD/EditOpeningBalanceVendor.ts | 72 - .../Contacts/Vendors/CRUD/EditVendor.ts | 78 - .../Contacts/Vendors/CRUD/GetVendor.ts | 34 - .../Contacts/Vendors/CRUD/GetVendors.ts | 80 - .../Contacts/Vendors/CRUD/VendorValidators.ts | 16 - .../Subscribers/VendorGLEntriesSubscriber.ts | 91 - .../Contacts/Vendors/VendorGLEntries.ts | 115 - .../Vendors/VendorGLEntriesStorage.ts | 88 - .../Contacts/Vendors/VendorTransformer.ts | 16 - .../Contacts/Vendors/VendorsApplication.ts | 129 - .../Contacts/Vendors/VendorsExportable.ts | 30 - .../Contacts/Vendors/VendorsImportable.ts | 32 - .../services/Contacts/Vendors/_SampleData.ts | 122 - .../services/Contacts/Vendors/constants.ts | 27 - .../server/src/services/Contacts/constants.ts | 29 - .../services/CreditNotes/CreateCreditNote.ts | 96 - .../CreditNotes/CreateRefundCreditNote.ts | 101 - .../CreditNoteAppliedInvoiceTransformer.ts | 53 - .../CreditNotes/CreditNoteApplySyncCredit.ts | 47 - .../CreditNoteApplySyncCreditSubscriber.ts | 67 - .../CreditNoteApplySyncInvoices.ts | 53 - .../CreditNoteApplySyncInvoicesSubscriber.ts | 61 - .../CreditNotes/CreditNoteApplyToInvoices.ts | 135 - .../CreditNoteAutoSerialSubscriber.ts | 30 - .../CreditNotes/CreditNoteBrandingTemplate.ts | 51 - .../CreditNotes/CreditNoteGLEntries.ts | 297 - .../CreditNoteGLEntriesSubscriber.ts | 113 - ...editNoteInventoryTransactionsSubscriber.ts | 98 - .../CreditNotes/CreditNoteTransformer.ts | 196 - ...reditNoteWithInvoicesToApplyTransformer.ts | 69 - .../src/services/CreditNotes/CreditNotes.ts | 160 - .../CreditNotes/CreditNotesExportable.ts | 35 - .../CreditNotes/CreditNotesImportable.ts | 44 - .../CreditNotesInventoryTransactions.ts | 90 - .../services/CreditNotes/DeleteCreditNote.ts | 119 - .../DeleteCreditNoteApplyToInvoices.ts | 65 - .../DeleteCustomerLinkedCreditNote.ts | 30 - .../DeleteCustomerLinkedCreditSubscriber.ts | 48 - .../CreditNotes/DeleteRefundCreditNote.ts | 73 - .../services/CreditNotes/EditCreditNote.ts | 100 - .../src/services/CreditNotes/GetCreditNote.ts | 44 - .../GetCreditNoteAssociatedAppliedInvoices.ts | 41 - .../GetCreditNoteAssociatedInvoicesToApply.ts | 42 - .../services/CreditNotes/GetCreditNotePdf.ts | 119 - .../CreditNotes/GetCreditNoteState.ts | 26 - .../GetRefundCreditNoteTransaction.ts | 37 - .../CreditNotes/ListCreditNoteRefunds.ts | 41 - .../services/CreditNotes/ListCreditNotes.ts | 68 - .../services/CreditNotes/OpenCreditNote.ts | 92 - .../services/CreditNotes/RefundCreditNote.ts | 45 - .../CreditNotes/RefundCreditNoteGLEntries.ts | 160 - .../RefundCreditNoteGLEntriesSubscriber.ts | 61 - .../RefundCreditNoteTransformer.ts | 30 - .../RefundSyncCreditNoteBalance.ts | 47 - .../RefundSyncCreditNoteBalanceSubscriber.ts | 62 - .../src/services/CreditNotes/constants.ts | 132 - .../server/src/services/CreditNotes/utils.ts | 25 - .../services/Currencies/CurrenciesService.ts | 188 - .../Currencies/CurrencyTransformer.ts | 19 - .../Currencies/InitialCurrenciesSeed.ts | 53 - .../src/services/Currencies/constants.ts | 11 - .../SeedInitialCurrenciesOnSetupSubscriber.ts | 32 - .../services/Dashboard/DashboardService.ts | 78 - .../DynamicListing/DynamicListAbstract.ts | 6 - .../DynamicListing/DynamicListCustomView.ts | 57 - .../DynamicListing/DynamicListFilterRoles.ts | 103 - .../DynamicListing/DynamicListSearch.ts | 18 - .../DynamicListing/DynamicListService.ts | 181 - .../DynamicListing/DynamicListSortBy.ts | 40 - .../DynamicListing/DynamicListing.types.ts | 31 - .../src/services/DynamicListing/constants.ts | 6 - .../src/services/DynamicListing/validators.ts | 0 packages/server/src/services/Entries/index.ts | 78 - .../src/services/EventsTracker/PostHog.ts | 24 - .../events/AccountEventsTracker.ts | 75 - .../events/AuthenticationEventsTracker.ts | 35 - .../events/BankRuleEventsTracker.ts | 68 - .../events/BankTransactionEventsTracker.ts | 97 - .../EventsTracker/events/BillEventsTracker.ts | 59 - .../events/CustomerEventsTracker.ts | 65 - .../events/ExpenseEventsTracker.ts | 65 - .../EventsTracker/events/ItemEventsTracker.ts | 71 - .../events/ManualJournalEventsTracker.ts | 68 - .../events/PaymentLinkEventsTracker.ts | 29 - .../events/PaymentMadeEventsTracker.ts | 68 - .../events/PaymentMethodEventsTracker.ts | 44 - .../events/PaymentReceivedEventsTracker.ts | 98 - .../events/PdfTemplateEventsTracker.ts | 67 - .../events/ReportsEventsTracker.ts | 240 - .../events/SaleEstimateEventsTracker.ts | 109 - .../events/SaleInvoicesEventsTracker.ts | 106 - .../events/StripeIntegrationEventsTracker.ts | 32 - .../events/SubscriptionEventsTracker.ts | 76 - .../TransactionsLockingEventsTracker.ts | 81 - .../events/VendorEventsTracker.ts | 56 - .../services/EventsTracker/events/events.ts | 41 - .../ExchangeRates/ExchangeRateApplication.ts | 21 - .../ExchangeRates/ExchangeRatesService.ts | 37 - .../Expenses/CRUD/CommandExpenseValidator.ts | 119 - .../services/Expenses/CRUD/CreateExpense.ts | 136 - .../services/Expenses/CRUD/DeleteExpense.ts | 77 - .../src/services/Expenses/CRUD/EditExpense.ts | 157 - .../CRUD/ExpenseCategoryTransformer.ts | 25 - .../Expenses/CRUD/ExpenseDTOTransformer.ts | 121 - .../Expenses/CRUD/ExpenseTransformer.ts | 104 - .../src/services/Expenses/CRUD/GetExpense.ts | 42 - .../src/services/Expenses/CRUD/GetExpenses.ts | 81 - .../services/Expenses/CRUD/PublishExpense.ts | 79 - .../server/src/services/Expenses/ExpenseGL.ts | 113 - .../Expenses/ExpenseGLEntriesService.ts | 45 - .../Expenses/ExpenseGLEntriesStorage.ts | 72 - .../Expenses/ExpenseGLEntriesSubscriber.ts | 117 - .../services/Expenses/ExpensesApplication.ts | 132 - .../services/Expenses/ExpensesExportable.ts | 34 - .../services/Expenses/ExpensesImportable.ts | 46 - .../server/src/services/Expenses/constants.ts | 89 - .../server/src/services/Export/ExportAls.ts | 48 - .../src/services/Export/ExportApplication.ts | 18 - .../server/src/services/Export/ExportPdf.ts | 47 - .../src/services/Export/ExportRegistery.ts | 49 - .../src/services/Export/ExportResources.ts | 74 - .../src/services/Export/ExportService.ts | 233 - .../server/src/services/Export/Exportable.ts | 22 - packages/server/src/services/Export/common.ts | 9 - .../server/src/services/Export/constants.ts | 2 - packages/server/src/services/Export/utils.ts | 45 - .../Features/FeaturesConfigureManager.ts | 18 - .../src/services/Features/FeaturesManager.ts | 48 - .../Features/FeaturesSettingsDriver.ts | 75 - .../server/src/services/Features/constants.ts | 18 - .../AgingSummary/APAgingSummaryApplication.ts | 67 - .../APAgingSummaryExportInjectable.ts | 43 - .../AgingSummary/APAgingSummaryMeta.ts | 26 - .../APAgingSummaryPdfInjectable.ts | 35 - .../AgingSummary/APAgingSummaryService.ts | 117 - .../AgingSummary/APAgingSummarySheet.ts | 183 - .../AgingSummary/APAgingSummaryTable.ts | 46 - .../APAgingSummaryTableInjectable.ts | 36 - .../AgingSummary/ARAgingSummaryApplication.ts | 67 - .../ARAgingSummaryExportInjectable.ts | 46 - .../AgingSummary/ARAgingSummaryMeta.ts | 26 - .../ARAgingSummaryPdfInjectable.ts | 35 - .../AgingSummary/ARAgingSummaryService.ts | 115 - .../AgingSummary/ARAgingSummarySheet.ts | 197 - .../AgingSummary/ARAgingSummaryTable.ts | 38 - .../ARAgingSummaryTableInjectable.ts | 37 - .../AgingSummary/AgingReport.ts | 54 - .../AgingSummary/AgingSummary.ts | 228 - .../AgingSummary/AgingSummaryMeta.ts | 30 - .../AgingSummary/AgingSummaryTable.ts | 211 - .../AgingSummary/_constants.ts | 21 - .../BalanceSheet/BalanceSheet.ts | 108 - .../BalanceSheet/BalanceSheetAccounts.ts | 204 - .../BalanceSheet/BalanceSheetAggregators.ts | 140 - .../BalanceSheet/BalanceSheetApplication.ts | 67 - .../BalanceSheet/BalanceSheetBase.ts | 32 - .../BalanceSheetComparsionPreviousPeriod.ts | 268 - .../BalanceSheetComparsionPreviousYear.ts | 266 - .../BalanceSheet/BalanceSheetDatePeriods.ts | 211 - .../BalanceSheetExportInjectable.ts | 60 - .../BalanceSheet/BalanceSheetFiltering.ts | 167 - .../BalanceSheet/BalanceSheetInjectable.ts | 116 - .../BalanceSheet/BalanceSheetMeta.ts | 32 - .../BalanceSheet/BalanceSheetNetIncome.ts | 226 - .../BalanceSheetNetIncomeDatePeriods.ts | 120 - .../BalanceSheetNetIncomeDatePeriodsPP.ts | 127 - .../BalanceSheetNetIncomeDatePeriodsPY.ts | 122 - .../BalanceSheet/BalanceSheetNetIncomePP.ts | 75 - .../BalanceSheet/BalanceSheetNetIncomePY.ts | 79 - .../BalanceSheet/BalanceSheetPdfInjectable.ts | 35 - .../BalanceSheet/BalanceSheetPercentage.ts | 225 - .../BalanceSheet/BalanceSheetQuery.ts | 182 - .../BalanceSheet/BalanceSheetRepository.ts | 402 -- .../BalanceSheetRepositoryNetIncome.ts | 222 - .../BalanceSheet/BalanceSheetSchema.ts | 128 - .../BalanceSheet/BalanceSheetTable.ts | 278 - .../BalanceSheetTableDatePeriods.ts | 137 - .../BalanceSheetTableInjectable.ts | 42 - .../BalanceSheetTablePercentage.ts | 83 - .../BalanceSheetTablePreviousPeriod.ts | 109 - .../BalanceSheetTablePreviousYear.ts | 97 - .../BalanceSheet/BalanceSheetTotal.ts | 3 - .../BalanceSheet/constants.ts | 64 - .../FinancialStatements/CashFlow/CashFlow.ts | 703 -- .../CashFlow/CashFlowDatePeriods.ts | 411 -- .../CashFlow/CashFlowRepository.ts | 173 - .../CashFlow/CashFlowService.ts | 154 - .../CashFlow/CashFlowTable.ts | 373 - .../CashFlow/CashflowExportInjectable.ts | 46 - .../CashFlow/CashflowSheetApplication.ts | 75 - .../CashFlow/CashflowSheetMeta.ts | 36 - .../CashFlow/CashflowTableInjectable.ts | 37 - .../CashFlow/CashflowTablePdfInjectable.ts | 34 - .../FinancialStatements/CashFlow/constants.ts | 33 - .../FinancialStatements/CashFlow/schema.ts | 75 - .../CashflowAccountTransactions.ts | 200 - .../CashflowAccountTransactionsRepo.ts | 127 - .../CashflowAccountTransactionsService.ts | 63 - .../CashflowAccountTransactions/constants.ts | 9 - .../CashflowAccountTransactions/utils.ts | 40 - .../ContactBalanceSummary.ts | 204 - .../CustomerBalanceSummary.ts | 111 - .../CustomerBalanceSummaryApplication.ts | 74 - .../CustomerBalanceSummaryExportInjectable.ts | 43 - .../CustomerBalanceSummaryMeta.ts | 35 - .../CustomerBalanceSummaryPdf.ts | 36 - .../CustomerBalanceSummaryRepository.ts | 69 - .../CustomerBalanceSummaryService.ts | 127 - .../CustomerBalanceSummaryTableInjectable.ts | 45 - .../CustomerBalanceSummaryTableRows.ts | 150 - .../CustomerBalanceSummary/constants.ts | 14 - .../FinancialDatePeriods.ts | 113 - .../FinancialDateRanges.ts | 110 - .../FinancialEvaluateEquation.ts | 62 - .../FinancialStatements/FinancialFilter.ts | 22 - .../FinancialHorizTotals.ts | 96 - .../FinancialPreviousPeriod.ts | 127 - .../FinancialPreviousYear.ts | 118 - .../FinancialReportService.ts | 8 - .../FinancialStatements/FinancialSchema.ts | 24 - .../FinancialStatements/FinancialSheet.ts | 177 - .../FinancialStatements/FinancialSheetMeta.ts | 34 - .../FinancialSheetStructure.ts | 107 - .../FinancialStatements/FinancialTable.ts | 48 - .../FinancialTablePreviousPeriod.ts | 130 - .../FinancialTablePreviousYear.ts | 130 - .../FinancialTableStructure.ts | 48 - .../GeneralLedger/GeneralLedger.ts | 382 -- .../GeneralLedger/GeneralLedgerApplication.ts | 83 - .../GeneralLedger/GeneralLedgerExport.ts | 43 - .../GeneralLedger/GeneralLedgerMeta.ts | 33 - .../GeneralLedger/GeneralLedgerPdf.ts | 35 - .../GeneralLedger/GeneralLedgerRepository.ts | 180 - .../GeneralLedger/GeneralLedgerService.ts | 91 - .../GeneralLedger/GeneralLedgerTable.ts | 322 - .../GeneralLedgerTableInjectable.ts | 45 - .../GeneralLedger/_utils.ts | 13 - .../GeneralLedger/constants.ts | 29 - .../GeneralLedger/utils.ts | 6 - .../InventoryDetails/InventoryDetails.ts | 433 -- .../InventoryDetailsApplication.ts | 80 - .../InventoryDetailsExportInjectable.ts | 43 - .../InventoryDetails/InventoryDetailsMeta.ts | 35 - .../InventoryDetailsRepository.ts | 120 - .../InventoryDetailsService.ts | 94 - .../InventoryDetails/InventoryDetailsTable.ts | 197 - .../InventoryDetailsTableInjectable.ts | 45 - .../InventoryDetailsTablePdf.ts | 35 - .../InventoryDetails/constant.ts | 7 - .../InventoryValuationSheet.ts | 264 - .../InventoryValuationSheetApplication.ts | 93 - .../InventoryValuationSheetExportable.ts | 46 - .../InventoryValuationSheetMeta.ts | 33 - .../InventoryValuationSheetPdf.ts | 36 - .../InventoryValuationSheetService.ts | 139 - .../InventoryValuationSheetTable.ts | 105 - .../InventoryValuationSheetTableInjectable.ts | 39 - .../InventoryValuationSheet/_constants.ts | 12 - .../JournalSheet/JournalSheet.ts | 141 - .../JournalSheet/JournalSheetApplication.ts | 73 - .../JournalSheet/JournalSheetExport.ts | 43 - .../JournalSheet/JournalSheetMeta.ts | 34 - .../JournalSheet/JournalSheetPdfInjectable.ts | 35 - .../JournalSheet/JournalSheetService.ts | 121 - .../JournalSheet/JournalSheetTable.ts | 232 - .../JournalSheetTableInjectable.ts | 39 - .../JournalSheet/constant.ts | 17 - .../FinancialStatements/JournalSheet/types.ts | 5 - .../ProfitLossSheet/ProfitLossSchema.ts | 76 - .../ProfitLossSheet/ProfitLossSheet.ts | 334 - .../ProfitLossSheetApplication.ts | 74 - .../ProfitLossSheet/ProfitLossSheetBase.ts | 30 - .../ProfitLossSheetDatePeriods.ts | 236 - .../ProfitLossSheetExportInjectable.ts | 43 - .../ProfitLossSheet/ProfitLossSheetFilter.ts | 170 - .../ProfitLossSheet/ProfitLossSheetMeta.ts | 35 - .../ProfitLossSheetPercentage.ts | 301 - .../ProfitLossSheetPreviousPeriod.ts | 395 -- .../ProfitLossSheetPreviousYear.ts | 367 - .../ProfitLossSheet/ProfitLossSheetQuery.ts | 209 - .../ProfitLossSheetRepository.ts | 370 - .../ProfitLossSheet/ProfitLossSheetService.ts | 85 - .../ProfitLossSheet/ProfitLossSheetTable.ts | 233 - .../ProfitLossSheetTableDatePeriods.ts | 150 - .../ProfitLossSheetTableInjectable.ts | 42 - .../ProfitLossSheetTablePercentage.ts | 131 - .../ProfitLossTablePdfInjectable.ts | 35 - .../ProfitLossTablePreviousPeriod.ts | 93 - .../ProfitLossTablePreviousYear.ts | 107 - .../ProfitLossSheet/constants.ts | 69 - .../ProfitLossSheet/utils.ts | 54 - .../ProjectProfitabilitySummary.ts | 216 - .../ProjectProfitabilitySummaryRepository.ts | 147 - .../ProjectProfitabilitySummaryService.ts | 75 - .../ProjectProfitabilitySummaryTable.ts | 116 - .../PurchasesByItems/PurchasesByItems.ts | 185 - .../PurchasesByItemsApplication.ts | 90 - .../PurchasesByItemsExport.ts | 46 - .../PurchasesByItems/PurchasesByItemsMeta.ts | 36 - .../PurchasesByItems/PurchasesByItemsPdf.ts | 35 - .../PurchasesByItemsService.ts | 115 - .../PurchasesByItems/PurchasesByItemsTable.ts | 111 - .../PurchasesByItemsTableInjectable.ts | 38 - .../PurchasesByItems/_types.ts | 23 - .../SalesByItems/SalesByItems.ts | 175 - .../SalesByItems/SalesByItemsApplication.ts | 91 - .../SalesByItems/SalesByItemsExport.ts | 43 - .../SalesByItems/SalesByItemsMeta.ts | 35 - .../SalesByItems/SalesByItemsPdfInjectable.ts | 35 - .../SalesByItems/SalesByItemsService.ts | 109 - .../SalesByItems/SalesByItemsTable.ts | 104 - .../SalesByItemsTableInjectable.ts | 33 - .../SalesByItems/constants.ts | 23 - .../SalesTaxLiabilitySummary.ts | 131 - .../SalesTaxLiabilitySummaryApplication.ts | 80 - ...alesTaxLiabilitySummaryExportInjectable.ts | 46 - .../SalesTaxLiabilitySummaryMeta.ts | 32 - .../SalesTaxLiabilitySummaryRepository.ts | 79 - .../SalesTaxLiabilitySummaryService.ts | 47 - .../SalesTaxLiabilitySummaryTable.ts | 161 - ...SalesTaxLiabilitySummaryTableInjectable.ts | 40 - .../SalesTaxLiabiltiySummaryPdf.ts | 36 - .../SalesTaxLiabilitySummary/_constants.ts | 4 - .../FinancialStatements/TableSheetPdf.ts | 79 - .../TransactionsByContact.ts | 195 - .../TransactionsByContactTableRows.ts | 81 - .../TransactionsByCustomers.ts | 142 - .../TransactionsByCustomersApplication.ts | 89 - ...TransactionsByCustomersExportInjectable.ts | 46 - .../TransactionsByCustomersMeta.ts | 36 - .../TransactionsByCustomersPdf.ts | 34 - .../TransactionsByCustomersRepository.ts | 98 - .../TransactionsByCustomersService.ts | 189 - .../TransactionsByCustomersTable.ts | 95 - .../TransactionsByCustomersTableInjectable.ts | 45 - .../TransactionsByReferenceReport.ts | 81 - .../TransactionsByReferenceRepository.ts | 29 - .../TransactionsByReference/index.ts | 77 - .../TransactionsByVendor.ts | 140 - .../TransactionsByVendorApplication.ts | 90 - .../TransactionsByVendorExportInjectable.ts | 46 - .../TransactionsByVendorInjectable.ts | 194 - .../TransactionsByVendorMeta.ts | 38 - .../TransactionsByVendorPdf.ts | 35 - .../TransactionsByVendorRepository.ts | 101 - .../TransactionsByVendorTable.ts | 94 - .../TransactionsByVendorTableInjectable.ts | 45 - .../TransactionsByVendor/constants.ts | 23 - .../TrialBalanceExportInjectable.ts | 60 - .../TrialBalanceSheet/TrialBalanceSheet.ts | 263 - .../TrialBalanceSheetApplication.ts | 70 - .../TrialBalanceSheetInjectable.ts | 104 - .../TrialBalanceSheetMeta.ts | 37 - .../TrialBalanceSheetPdfInjectsable.ts | 35 - .../TrialBalanceSheetRepository.ts | 105 - .../TrialBalanceSheetTable.ts | 146 - .../TrialBalanceSheetTableInjectable.ts | 33 - .../TrialBalanceSheet/_constants.ts | 25 - .../VendorBalanceSummary.ts | 104 - .../VendorBalanceSummaryApplication.ts | 76 - .../VendorBalanceSummaryExportInjectable.ts | 43 - .../VendorBalanceSummaryMeta.ts | 32 - .../VendorBalanceSummaryPdf.ts | 35 - .../VendorBalanceSummaryRepository.ts | 69 - .../VendorBalanceSummaryService.ts | 130 - .../VendorBalanceSummaryTableInjectable.ts | 47 - .../VendorBalanceSummaryTableRows.ts | 150 - .../VendorBalanceSummary/constants.ts | 14 - .../src/services/FinancialStatements/utils.ts | 30 - .../server/src/services/I18n/I18nService.ts | 66 - .../server/src/services/Import/ImportALS.ts | 105 - .../src/services/Import/ImportFileCommon.ts | 175 - .../Import/ImportFileDataTransformer.ts | 151 - .../Import/ImportFileDataValidator.ts | 46 - .../src/services/Import/ImportFileMapping.ts | 156 - .../src/services/Import/ImportFileMeta.ts | 33 - .../Import/ImportFileMetaTransformer.ts | 19 - .../src/services/Import/ImportFilePreview.ts | 53 - .../src/services/Import/ImportFileProcess.ts | 104 - .../Import/ImportFileProcessCommit.ts | 66 - .../src/services/Import/ImportFileUpload.ts | 123 - .../Import/ImportRemoveExpiredFiles.ts | 34 - .../Import/ImportResourceApplication.ts | 106 - .../src/services/Import/ImportSample.ts | 46 - .../server/src/services/Import/Importable.ts | 72 - .../src/services/Import/ImportableRegistry.ts | 46 - .../services/Import/ImportableResources.ts | 73 - .../server/src/services/Import/_constants.ts | 3 - packages/server/src/services/Import/_utils.ts | 459 -- .../server/src/services/Import/interfaces.ts | 77 - .../jobs/ImportDeleteExpiredFilesJob.ts | 28 - .../server/src/services/Import/sheet_utils.ts | 56 - .../src/services/Inventory/Inventory.ts | 384 -- .../Inventory/InventoryAdjustmentGL.ts | 226 - .../Inventory/InventoryAdjustmentService.ts | 475 -- .../InventoryAdjustmentTransformer.ts | 25 - .../Inventory/InventoryAverageCost.ts | 257 - .../Inventory/InventoryCostApplication.ts | 29 - .../Inventory/InventoryCostGLStorage.ts | 40 - .../Inventory/InventoryCostLotTracker.ts | 302 - .../services/Inventory/InventoryCostMethod.ts | 46 - .../Inventory/InventoryCostsService.ts | 147 - .../Inventory/InventoryItemsQuantitySync.ts | 95 - .../InventoryCostGLBeforeWriteSubscriber.ts | 36 - .../server/src/services/Inventory/utils.ts | 15 - .../services/InviteUsers/AcceptInviteUser.ts | 128 - .../InviteSendMailNotificationSubscribe.ts | 36 - .../InviteUsers/SendInviteUsersMailMessage.ts | 46 - .../InviteUsers/SyncSystemSendInvite.ts | 112 - .../InviteUsers/SyncTenantAcceptInvite.ts | 39 - .../services/InviteUsers/TenantInviteUser.ts | 170 - .../src/services/InviteUsers/constants.ts | 11 - .../ItemCategoriesExportable.ts | 29 - .../ItemCategoriesImportable.ts | 38 - .../ItemCategories/ItemCategoriesService.ts | 383 -- .../src/services/ItemCategories/constants.ts | 35 - .../server/src/services/Items/ActivateItem.ts | 40 - .../server/src/services/Items/CreateItem.ts | 133 - .../server/src/services/Items/DeleteItem.ts | 62 - .../server/src/services/Items/EditItem.ts | 171 - packages/server/src/services/Items/GetItem.ts | 51 - .../server/src/services/Items/GetItems.ts | 70 - .../src/services/Items/InactivateItem.ts | 40 - .../Items/ItemBillsTransactionsTransformer.ts | 97 - .../ItemEstimatesTransactionTransformer.ts | 82 - .../ItemInvoicesTransactionsTransformer.ts | 85 - .../ItemReceiptsTransactionsTransformer.ts | 84 - .../services/Items/ItemTransactionsService.ts | 123 - .../src/services/Items/ItemTransformer.ts | 62 - .../src/services/Items/ItemValidators.ts | 319 - .../src/services/Items/ItemsApplication.ts | 112 - .../src/services/Items/ItemsEntriesService.ts | 251 - .../src/services/Items/ItemsExportable.ts | 30 - .../src/services/Items/ItemsImportable.ts | 34 - .../server/src/services/Items/constants.ts | 141 - packages/server/src/services/Items/utils.ts | 16 - .../src/services/Jobs/JobTransformer.ts | 45 - .../server/src/services/Jobs/JobsService.ts | 52 - .../src/services/Ledger/LedgerRepository.ts | 56 - .../services/Loops/LoopsEventsSubscriber.ts | 51 - .../ContactMailNotification.ts | 87 - .../services/MailNotification/constants.ts | 6 - .../src/services/MailNotification/utils.ts | 56 - .../src/services/MailTenancy/MailTenancy.ts | 25 - .../AutoIncrementManualJournal.ts | 36 - .../CommandManualJournalValidators.ts | 308 - .../ManualJournals/CreateManualJournal.ts | 193 - .../ManualJournals/DeleteManualJournal.ts | 71 - .../ManualJournals/EditManualJournal.ts | 153 - .../ManualJournals/GetManualJournal.ts | 40 - .../ManualJournals/GetManualJournals.ts | 77 - .../ManualJournals/ManualJournalExportable.ts | 30 - .../ManualJournals/ManualJournalGLEntries.ts | 161 - .../ManualJournalGLEntriesSubscriber.ts | 131 - .../ManualJournalTransformer.ts | 67 - .../ManualJournalsApplication.ts | 124 - .../ManualJournals/ManualJournalsImport.ts | 60 - .../ManualJournals/PublishManualJournal.ts | 87 - .../src/services/ManualJournals/constants.ts | 64 - .../server/src/services/Media/MediaService.ts | 223 - .../Miscellaneous/DateFormats/constants.ts | 11 - .../Miscellaneous/DateFormats/index.ts | 15 - .../src/services/Miscellaneous/MiscService.ts | 8 - .../OneClickDemo/CreateOneClickDemo.ts | 74 - .../DemoSeeders/SeedDemoAbstract.ts | 17 - .../DemoSeeders/SeedDemoBankTransactions.ts | 35 - .../DemoSeeders/SeedDemoCustomers.ts | 37 - .../DemoSeeders/SeedDemoExpenses.ts | 39 - .../OneClickDemo/DemoSeeders/SeedDemoItems.ts | 45 - .../DemoSeeders/SeedDemoManualJournals.ts | 36 - .../DemoSeeders/SeedDemoSaleInvoices.ts | 37 - .../DemoSeeders/SeedDemoVendors.ts | 36 - .../OneClickDemo/OneClickDemoApplication.ts | 25 - .../src/services/OneClickDemo/_constants.ts | 12 - .../events/SeedInitialDemoAccountData.ts | 113 - .../src/services/OneClickDemo/interfaces.ts | 8 - .../OrganizationBaseCurrencyLocking.ts | 84 - .../Organization/OrganizationService.ts | 338 - .../Organization/OrganizationUpgrade.ts | 102 - .../src/services/Organization/constants.ts | 43 - .../CreateInvoiceCheckoutSession.ts | 102 - .../GetInvoicePaymentLinkMetadata.ts | 58 - .../PaymentLinks/GetPaymentLinkInvoicePdf.ts | 35 - .../PaymentLinks/PaymentLinksApplication.ts | 55 - .../DeletePaymentMethodService.ts | 54 - .../EditPaymentMethodService.ts | 60 - .../PaymentServices/GetPaymentMethodsState.ts | 62 - .../PaymentServices/GetPaymentService.ts | 27 - .../GetPaymentServicesSpecificInvoice.ts | 33 - ...ymentServicesSpecificInvoiceTransformer.ts | 19 - .../PaymentServicesApplication.ts | 95 - .../src/services/PaymentServices/types.ts | 33 - .../src/services/PaymentServices/utils.ts | 9 - .../PdfTemplate/AssignPdfTemplateDefault.ts | 63 - .../BrandingTemplateDTOTransformer.ts | 37 - .../services/PdfTemplate/CreatePdfTemplate.ts | 51 - .../services/PdfTemplate/DeletePdfTemplate.ts | 55 - .../services/PdfTemplate/EditPdfTemplate.ts | 58 - .../GetOrganizationBrandingAttributes.ts | 31 - .../services/PdfTemplate/GetPdfTemplate.ts | 38 - .../GetPdfTemplateBrandingState.ts | 15 - .../PdfTemplate/GetPdfTemplateTransformer.ts | 52 - .../services/PdfTemplate/GetPdfTemplates.ts | 37 - .../PdfTemplate/GetPdfTemplatesTransformer.ts | 38 - .../PdfTemplate/PdfTemplateApplication.ts | 135 - .../server/src/services/PdfTemplate/types.ts | 75 - .../Projects/Projects/CreateProject.ts | 74 - .../Projects/Projects/DeleteProject.ts | 61 - .../services/Projects/Projects/EditProject.ts | 87 - .../Projects/Projects/EditProjectStatus.ts | 46 - .../services/Projects/Projects/GetProject.ts | 43 - .../Projects/GetProjectBillableEntries.ts | 139 - .../services/Projects/Projects/GetProjects.ts | 38 - .../Projects/Projects/ProjectBillableBill.ts | 45 - .../Projects/ProjectBillableBillInvoiced.ts | 116 - .../Projects/ProjectBillableBillSubscriber.ts | 87 - .../ProjectBillableBillTransformer.ts | 101 - .../Projects/ProjectBillableExpense.ts | 49 - .../ProjectBillableExpenseInvoiced.ts | 120 - .../ProjectBillableExpenseSubscriber.ts | 84 - .../ProjectBillableExpenseTransformer.ts | 100 - .../ProjectBillableTaskTransformer.ts | 108 - .../Projects/Projects/ProjectBillableTasks.ts | 48 - .../Projects/ProjectBillableTasksInvoiced.ts | 116 - .../ProjectBillableTasksSubscriber.ts | 104 - .../Projects/ProjectDetailedTransformer.ts | 391 -- .../Projects/ProjectInvoiceValidator.ts | 48 - .../Projects/Projects/ProjectTransformer.ts | 64 - .../Projects/Projects/ProjectsApplication.ts | 147 - .../Projects/Projects/ProjectsValidator.ts | 23 - .../src/services/Projects/Projects/_types.ts | 22 - .../src/services/Projects/Projects/_utils.ts | 8 - .../services/Projects/Projects/constants.ts | 3 - .../src/services/Projects/Tasks/CreateTask.ts | 74 - .../src/services/Projects/Tasks/DeleteTask.ts | 64 - .../src/services/Projects/Tasks/EditTask.ts | 77 - .../src/services/Projects/Tasks/GetTask.ts | 33 - .../src/services/Projects/Tasks/GetTasks.ts | 33 - .../Projects/Tasks/TaskTransformer.ts | 49 - .../Projects/Tasks/TasksApplication.ts | 97 - .../src/services/Projects/Tasks/constants.ts | 5 - .../src/services/Projects/Times/CreateTime.ts | 72 - .../src/services/Projects/Times/DeleteTime.ts | 61 - .../src/services/Projects/Times/EditTime.ts | 76 - .../src/services/Projects/Times/GetTime.ts | 37 - .../src/services/Projects/Times/GetTimes.ts | 36 - .../Projects/Times/SyncActualTimeTask.ts | 49 - .../Times/SyncActualTimeTaskSubscriber.ts | 91 - .../Projects/Times/TimeTransformer.ts | 57 - .../Projects/Times/TimesApplication.ts | 96 - .../BillPayments/BillPaymentBillSync.ts | 48 - .../BillPaymentEntryTransformer.ts | 28 - .../BillPayments/BillPaymentExportable.ts | 34 - .../BillPayments/BillPaymentGLEntries.ts | 277 - .../BillPaymentGLEntriesSubscriber.ts | 76 - .../BillPaymentTransactionTransformer.ts | 61 - .../BillPayments/BillPaymentTransformer.ts | 66 - .../BillPayments/BillPaymentValidators.ts | 264 - .../BillPayments/BillPaymentsApplication.ts | 109 - .../BillPayments/BillPaymentsImportable.ts | 45 - .../BillPayments/BillPaymentsPages.ts | 100 - .../CommandBillPaymentDTOTransformer.ts | 49 - .../BillPayments/CreateBillPayment.ts | 129 - .../BillPayments/DeleteBillPayment.ts | 65 - .../Purchases/BillPayments/EditBillPayment.ts | 147 - .../Purchases/BillPayments/GetBillPayment.ts | 43 - .../Purchases/BillPayments/GetBillPayments.ts | 75 - .../Purchases/BillPayments/GetPaymentBills.ts | 31 - .../Purchases/BillPayments/constants.ts | 50 - .../Purchases/Bills/BillDTOTransformer.ts | 149 - .../services/Purchases/Bills/BillGLEntries.ts | 363 - .../Bills/BillGLEntriesSubscriber.ts | 75 - .../Bills/BillInventoryTransactions.ts | 82 - .../Bills/BillPaymentsGLEntriesRewrite.ts | 76 - .../BillPaymentsGLEntriesRewriteSubscriber.ts | 36 - .../Purchases/Bills/BillsApplication.ts | 147 - .../Purchases/Bills/BillsExportable.ts | 37 - .../Purchases/Bills/BillsImportable.ts | 46 - .../Purchases/Bills/BillsValidators.ts | 171 - .../services/Purchases/Bills/CreateBill.ts | 122 - .../services/Purchases/Bills/DeleteBill.ts | 80 - .../src/services/Purchases/Bills/EditBill.ts | 158 - .../src/services/Purchases/Bills/GetBill.ts | 44 - .../Purchases/Bills/GetBillPayments.ts | 35 - .../src/services/Purchases/Bills/GetBills.ts | 80 - .../services/Purchases/Bills/GetDueBills.ts | 32 - .../src/services/Purchases/Bills/OpenBill.ts | 69 - .../Bills/PurchaseInvoiceTransformer.ts | 284 - .../src/services/Purchases/Bills/constants.ts | 123 - .../LandedCost/AllocateLandedCost.ts | 104 - .../Purchases/LandedCost/BaseLandedCost.ts | 195 - .../BillAllocatedLandedCostTransactions.ts | 170 - .../Purchases/LandedCost/BillLandedCost.ts | 58 - .../Purchases/LandedCost/ExpenseLandedCost.ts | 59 - .../LandedCost/LandedCostGLEntries.ts | 249 - .../LandedCostGLEntriesSubscriber.ts | 57 - .../LandedCostInventoryTransactions.ts | 68 - ...ndedCostInventoryTransactionsSubscriber.ts | 63 - .../LandedCostSyncCostTransactions.ts | 76 - ...andedCostSyncCostTransactionsSubscriber.ts | 67 - .../LandedCost/LandedCostTransactions.ts | 132 - .../LandedCost/RevertAllocatedLandedCost.ts | 78 - .../LandedCost/TransctionLandedCost.ts | 88 - .../services/Purchases/LandedCost/utils.ts | 46 - .../Purchases/PurchasesTransactionsLocking.ts | 27 - .../ApplyVendorCreditSyncBills.ts | 52 - .../ApplyVendorCreditSyncBillsSubscriber.ts | 65 - .../ApplyVendorCreditSyncInvoiced.ts | 48 - ...ApplyVendorCreditSyncInvoicedSubscriber.ts | 70 - .../ApplyVendorCreditToBills.ts | 128 - .../DeleteApplyVendorCreditToBill.ts | 61 - .../GetAppliedBillsToVendorCredit.ts | 36 - .../GetVendorCreditToApplyBills.ts | 41 - .../VendorCreditAppliedBillTransformer.ts | 62 - .../VendorCreditToApplyBillTransformer.ts | 70 - .../VendorCredits/BaseVendorCredit.ts | 149 - .../VendorCredits/CreateVendorCredit.ts | 91 - .../DeleteVendorAssociatedVendorCredit.ts | 57 - .../VendorCredits/DeleteVendorCredit.ts | 119 - .../VendorCredits/EditVendorCredit.ts | 103 - .../VendorCredits/GetVendorCredit.ts | 41 - .../VendorCredits/ListVendorCredits.ts | 70 - .../VendorCredits/OpenVendorCredit.ts | 90 - .../CreateRefundVendorCredit.ts | 128 - .../DeleteRefundVendorCredit.ts | 73 - .../GetRefundVendorCredit.ts | 43 - .../ListRefundVendorCredits.ts | 41 - .../RefundCreditSyncBills.ts | 0 .../RefundSyncCreditRefundedAmount.ts | 47 - .../RefundSyncVendorCreditBalance.ts | 48 - ...RefundSyncVendorCreditBalanceSubscriber.ts | 62 - .../RefundVendorCredits/RefundVendorCredit.ts | 55 - .../RefundVendorCreditGLEntries.ts | 159 - .../RefundVendorCreditGLEntriesSubscriber.ts | 59 - .../RefundVendorCreditTransformer.ts | 30 - .../RefundVendorCredits/constants.ts | 5 - .../VendorCreditAutoSerialSubscriber.ts | 27 - .../VendorCredits/VendorCreditGLEntries.ts | 252 - .../VendorCreditGLEntriesSubscriber.ts | 110 - .../VendorCreditInventoryTransactions.ts | 84 - ...orCreditInventoryTransactionsSusbcriber.ts | 93 - .../VendorCredits/VendorCreditTransformer.ts | 179 - .../VendorCredits/VendorCreditsExportable.ts | 36 - .../VendorCredits/VendorCreditsImportable.ts | 45 - .../Purchases/VendorCredits/constants.ts | 82 - .../src/services/Resource/ResourceService.ts | 181 - .../src/services/Roles/AbilitySchema.ts | 339 - .../src/services/Roles/PurgeAuthorizedUser.ts | 22 - .../services/Roles/RolePermissionsSchema.ts | 31 - .../src/services/Roles/RoleTransformer.ts | 31 - .../server/src/services/Roles/RolesService.ts | 291 - .../server/src/services/Roles/constants.ts | 6 - packages/server/src/services/Roles/utils.ts | 42 - .../src/services/SMSClient/EasySmsClient.ts | 60 - .../server/src/services/SMSClient/SMSAPI.ts | 39 - .../services/SMSClient/SMSClientInterface.ts | 5 - .../server/src/services/SMSClient/index.ts | 3 - .../Sales/AutoIncrementOrdersService.ts | 63 - .../Sales/Estimates/ApproveSaleEstimate.ts | 75 - .../Sales/Estimates/ConvetSaleEstimate.ts | 46 - .../Sales/Estimates/CreateSaleEstimate.ts | 107 - .../Sales/Estimates/DeleteSaleEstimate.ts | 74 - .../Sales/Estimates/DeliverSaleEstimate.ts | 71 - .../Sales/Estimates/EditSaleEstimate.ts | 124 - .../Estimates/GetEstimateMailTemplate.ts | 75 - ...timateMailTemplateAttributesTransformer.ts | 205 - .../Sales/Estimates/GetSaleEstimate.ts | 57 - .../Estimates/GetSaleEstimateMailState.ts | 52 - .../GetSaleEstimateMailStateTransformer.ts | 180 - .../Sales/Estimates/GetSaleEstimateState.ts | 28 - .../Sales/Estimates/GetSaleEstimates.ts | 79 - .../Sales/Estimates/RejectSaleEstimate.ts | 57 - .../Estimates/SaleEstimateDTOTransformer.ts | 123 - .../Sales/Estimates/SaleEstimateIncrement.ts | 31 - .../Sales/Estimates/SaleEstimateSmsNotify.ts | 217 - .../Estimates/SaleEstimateTransformer.ts | 181 - .../Sales/Estimates/SaleEstimateValidators.ts | 90 - .../Estimates/SaleEstimatesApplication.ts | 297 - .../Estimates/SaleEstimatesExportable.ts | 35 - .../Estimates/SaleEstimatesImportable.ts | 45 - .../Sales/Estimates/SaleEstimatesPdf.ts | 123 - .../Sales/Estimates/SendSaleEstimateMail.ts | 240 - .../Estimates/SendSaleEstimateMailJob.ts | 36 - .../Estimates/UnlinkConvertedSaleEstimate.ts | 32 - .../src/services/Sales/Estimates/constants.ts | 295 - .../SaleEstimateMarkApprovedOnMailSent.ts | 43 - .../src/services/Sales/Estimates/utils.ts | 41 - .../src/services/Sales/HasItemsEntries.ts | 30 - .../CommandSaleInvoiceDTOTransformer.ts | 159 - .../Invoices/CommandSaleInvoiceValidators.ts | 89 - .../Sales/Invoices/CreateSaleInvoice.ts | 152 - .../Sales/Invoices/DeleteSaleInvoice.ts | 162 - .../Sales/Invoices/DeliverSaleInvoice.ts | 78 - .../Sales/Invoices/EditSaleInvoice.ts | 165 - .../GeneratePaymentLinkTransformer.ts | 28 - .../Invoices/GenerateeInvoicePaymentLink.ts | 83 - .../GetInvoicePaymentLinkTransformer.ts | 223 - .../Sales/Invoices/GetInvoicePaymentMail.ts | 67 - ...InvoicePaymentMailAttributesTransformer.ts | 169 - .../Invoices/GetInvoicePaymentsService.ts | 34 - .../services/Sales/Invoices/GetSaleInvoice.ts | 65 - .../Invoices/GetSaleInvoiceMailReminder.ts | 3 - .../Sales/Invoices/GetSaleInvoiceMailState.ts | 53 - .../GetSaleInvoiceMailStateTransformer.ts | 149 - .../Sales/Invoices/GetSaleInvoiceState.ts | 28 - .../Sales/Invoices/GetSaleInvoices.ts | 81 - .../Sales/Invoices/GetSaleInvoicesPayable.ts | 31 - .../Sales/Invoices/InvoiceGLEntries.ts | 354 - .../Invoices/InvoiceInventoryTransactions.ts | 78 - .../InvoicePaymentTransactionTransformer.ts | 61 - .../Invoices/InvoicePaymentsGLRewrite.ts | 76 - .../Sales/Invoices/ItemEntryTransformer.ts | 82 - .../Sales/Invoices/SaleEstimatePdfTemplate.ts | 49 - .../Invoices/SaleInvoiceCostGLEntries.ts | 146 - .../Sales/Invoices/SaleInvoiceIncrement.ts | 31 - .../Sales/Invoices/SaleInvoiceNotifyBySms.ts | 260 - .../services/Sales/Invoices/SaleInvoicePdf.ts | 133 - .../Sales/Invoices/SaleInvoicePdfTemplate.ts | 48 - .../SaleInvoiceTaxEntryTransformer.ts | 78 - .../Sales/Invoices/SaleInvoiceTransformer.ts | 253 - .../Invoices/SaleInvoiceWriteoffGLEntries.ts | 104 - .../Invoices/SaleInvoiceWriteoffGLStorage.ts | 88 - .../Invoices/SaleInvoiceWriteoffSubscriber.ts | 58 - .../Sales/Invoices/SaleInvoicesApplication.ts | 389 -- .../Sales/Invoices/SaleInvoicesExportable.ts | 35 - .../Sales/Invoices/SaleInvoicesImportable.ts | 46 - .../Sales/Invoices/SalesInvoicesCost.ts | 161 - .../Invoices/SendInvoiceInvoiceMailCommon.ts | 139 - .../Sales/Invoices/SendSaleInvoiceMail.ts | 136 - .../Sales/Invoices/SendSaleInvoiceMailJob.ts | 33 - .../Invoices/SendSaleInvoiceMailReminder.ts | 112 - .../SendSaleInvoiceMailReminderJob.ts | 32 - .../Sales/Invoices/WriteoffSaleInvoice.ts | 161 - .../src/services/Sales/Invoices/constants.ts | 238 - ...InvoiceChangeStatusOnMailSentSubscriber.ts | 49 - .../InvoiceCostGLEntriesSubscriber.ts | 36 - .../InvoicePaymentGLRewriteSubscriber.ts | 37 - .../InvoicePaymentIntegrationSubscriber.ts | 93 - .../src/services/Sales/Invoices/utils.ts | 56 - .../services/Sales/JournalPosterService.ts | 36 - .../PaymentReceived/CreatePaymentReceived.ts | 142 - .../PaymentReceived/DeletePaymentReceived.ts | 79 - .../PaymentReceived/EditPaymentReceived.ts | 179 - .../PaymentReceived/GetPaymentReceived.ts | 46 - .../GetPaymentReceivedInvoices.ts | 41 - .../GetPaymentReceivedMailState.tsx | 52 - .../GetPaymentReceivedMailStateTransformer.ts | 186 - .../GetPaymentReceivedMailTemplate.ts | 75 - ...entReceivedMailTemplateAttrsTransformer.ts | 149 - .../PaymentReceived/GetPaymentReceivedPdf.ts | 131 - .../GetPaymentReceivedState.ts | 28 - .../PaymentReceived/GetPaymentsReceived.ts | 79 - .../PaymentReceivedApplication.ts | 264 - .../PaymentReceivedBrandingTemplate.ts | 53 - .../PaymentReceivedDTOTransformer.ts | 88 - .../PaymentReceivedEntryTransformer.ts | 29 - .../PaymentReceivedGLEntries.ts | 299 - .../PaymentReceivedIncrement.ts | 31 - .../PaymentReceivedInvoiceSync.ts | 48 - .../PaymentReceivedMailNotification.ts | 237 - .../PaymentReceivedMailNotificationJob.ts | 32 - .../PaymentReceivedSmsNotify.ts | 213 - .../PaymentReceivedSmsSubscriber.ts | 27 - .../PaymentReceivedTransformer.ts | 78 - .../PaymentReceivedValidators.ts | 295 - .../PaymentsReceivedExportable.ts | 39 - .../PaymentsReceivedImportable.ts | 46 - .../PaymentReceived/PaymentsReceivedPages.ts | 110 - .../Sales/PaymentReceived/constants.ts | 94 - .../services/Sales/PaymentReceived/utils.ts | 32 - .../Sales/Receipts/CloseSaleReceipt.ts | 76 - .../Sales/Receipts/CreateSaleReceipt.ts | 113 - .../Sales/Receipts/DeleteSaleReceipt.ts | 67 - .../Sales/Receipts/EditSaleReceipt.ts | 120 - .../services/Sales/Receipts/GetSaleReceipt.ts | 43 - .../Sales/Receipts/GetSaleReceiptMailState.ts | 45 - .../GetSaleReceiptMailStateTransformer.ts | 221 - .../Receipts/GetSaleReceiptMailTemplate.ts | 75 - ...eceiptMailTemplateAttributesTransformer.ts | 201 - .../Sales/Receipts/GetSaleReceiptState.ts | 28 - .../Sales/Receipts/GetSaleReceipts.ts | 84 - .../Sales/Receipts/SaleReceiptApplication.ts | 257 - .../Receipts/SaleReceiptBrandingTemplate.ts | 53 - .../Receipts/SaleReceiptCostGLEntries.ts | 148 - .../Receipts/SaleReceiptDTOTransformer.ts | 108 - .../Sales/Receipts/SaleReceiptGLEntries.ts | 258 - .../Sales/Receipts/SaleReceiptIncrement.ts | 31 - .../SaleReceiptInventoryTransactions.ts | 72 - .../Receipts/SaleReceiptMailNotification.ts | 238 - .../SaleReceiptMailNotificationJob.ts | 36 - .../Sales/Receipts/SaleReceiptNotifyBySms.ts | 206 - .../Sales/Receipts/SaleReceiptTransformer.ts | 183 - .../Sales/Receipts/SaleReceiptValidators.ts | 106 - .../Sales/Receipts/SaleReceiptsExportable.ts | 35 - .../Sales/Receipts/SaleReceiptsImportable.ts | 45 - .../Sales/Receipts/SaleReceiptsPdfService.ts | 127 - .../src/services/Sales/Receipts/constants.ts | 122 - .../SaleReceiptCostGLEntriesSubscriber.ts | 36 - ...aleReceiptMarkClosedOnMailSentSubcriber.ts | 41 - .../src/services/Sales/Receipts/utils.ts | 39 - .../src/services/Sales/SaleNotifyBySms.ts | 34 - .../Sales/SalesTransactionsLocking.ts | 32 - .../src/services/Sales/ServiceItemsEntries.js | 16 - .../SessionModel/SessionQueryBuilder.js | 13 - .../server/src/services/SessionModel/index.js | 24 - .../src/services/Settings/SettingsService.ts | 53 - .../src/services/Settings/SettingsStore.ts | 15 - .../Settings/SmsNotificationsSettings.ts | 193 - .../server/src/services/Setup/SetupService.ts | 119 - .../SmsIntegration/EasySmsIntegration.ts | 63 - .../CreatePaymentReceivedStripePayment.ts | 59 - .../StripePayment/CreateStripeAccountLink.ts | 16 - .../CreateStripeAccountService.ts | 55 - .../StripePayment/ExchangeStripeOauthToken.ts | 73 - .../GetStripeAuthorizationLink.ts | 14 - .../StripePayment/StripePaymentApplication.ts | 68 - .../StripePayment/StripePaymentService.ts | 75 - .../events/SeedStripeAccounts.ts | 49 - .../events/StripeWebhooksSubscriber.ts | 89 - .../src/services/StripePayment/types.ts | 11 - .../GetSubscriptionsTransformer.ts | 168 - .../Subscription/LemonCancelSubscription.ts | 47 - .../LemonChangeSubscriptionPlan.ts | 52 - .../Subscription/LemonResumeSubscription.ts | 48 - .../Subscription/LemonSqueezyService.ts | 38 - .../Subscription/LemonSqueezyWebhooks.ts | 134 - .../src/services/Subscription/Subscription.ts | 220 - .../Subscription/SubscriptionApplication.ts | 60 - .../Subscription/SubscriptionPeriod.ts | 49 - .../Subscription/SubscriptionService.ts | 50 - .../events/SubscribeFreeOnSignupCommunity.tsx | 36 - ...gerInvalidateCacheOnSubscriptionChange.tsx | 29 - .../server/src/services/Subscription/types.ts | 33 - .../server/src/services/Subscription/utils.ts | 100 - .../src/services/TaxRates/ActivateTaxRate.ts | 67 - .../TaxRates/CommandTaxRatesValidators.ts | 118 - .../src/services/TaxRates/CreateTaxRate.ts | 72 - .../src/services/TaxRates/DeleteTaxRate.ts | 56 - .../src/services/TaxRates/EditTaxRate.ts | 127 - .../src/services/TaxRates/GetTaxRate.ts | 39 - .../src/services/TaxRates/GetTaxRates.ts | 32 - .../services/TaxRates/InactivateTaxRate.ts | 67 - .../TaxRates/ItemEntriesTaxTransactions.ts | 72 - .../TaxRates/SyncItemTaxRateOnEditTaxRate.ts | 55 - .../SyncItemTaxRateOnEditTaxSubscriber.ts | 45 - .../services/TaxRates/TaxRateTransformer.ts | 29 - .../services/TaxRates/TaxRatesApplication.ts | 109 - .../services/TaxRates/TaxRatesExportable.ts | 18 - .../TaxRates/TaxRatesImportable.SampleData.ts | 18 - .../services/TaxRates/TaxRatesImportable.ts | 46 - .../WriteTaxTransactionsItemEntries.ts | 99 - .../server/src/services/TaxRates/constants.ts | 8 - .../BillTaxRateValidateSubscriber.ts | 89 - .../SaleInvoiceTaxRateValidateSubscriber.ts | 92 - .../WriteBillTaxTransactionsSubscriber.ts | 87 - .../WriteInvoiceTaxTransactionsSubscriber.ts | 84 - .../TemplateInjectable/TemplateInjectable.ts | 35 - .../src/services/Tenancy/SystemService.ts | 21 - .../src/services/Tenancy/TenancyService.ts | 137 - .../src/services/Tenancy/TenantDBManager.ts | 153 - .../src/services/Tenancy/TenantService.ts | 0 .../src/services/Tenancy/TenantsManager.ts | 197 - .../CommandTransactionsLockingService.ts | 214 - .../FinancialTransactionLockingGuard.ts | 26 - ...ncialsTransactionLockingGuardSubscriber.ts | 335 - .../PurchasesTransactionLockingGuard.ts | 25 - ...chasesTransactionLockingGuardSubscriber.ts | 286 - .../QueryTransactionsLocking.ts | 93 - .../SalesTransactionLockingGuard.ts | 25 - .../SalesTransactionLockingGuardSubscriber.ts | 503 -- .../TransactionsLockingGuard.ts | 121 - .../TransactionsLockingMetaTransformer.ts | 83 - .../TransactionsLockingRepository.ts | 151 - .../services/TransactionsLocking/constants.ts | 36 - .../services/UnitOfWork/TransactionsHooks.ts | 36 - .../server/src/services/UnitOfWork/index.ts | 65 - .../services/Users/PurgeUserAbilityCache.ts | 39 - .../services/Users/SyncTenantUserDeleted.ts | 26 - .../src/services/Users/SyncTenantUserSaved.ts | 71 - .../src/services/Users/UserTransformer.ts | 50 - .../server/src/services/Users/UsersService.ts | 315 - .../server/src/services/Users/constants.ts | 10 - .../server/src/services/Views/ViewsService.ts | 52 - .../Activate/BillWarehousesActivate.ts | 30 - .../Activate/CreditNoteWarehousesActivate.ts | 30 - .../Activate/EstimateWarehousesActivate.ts | 30 - ...InventoryTransactionsWarehousesActivate.ts | 31 - .../Activate/InvoiceWarehousesActivate.ts | 30 - .../Activate/ReceiptWarehousesActivate.ts | 30 - .../VendorCreditWarehousesActivate.ts | 30 - .../services/Warehouses/ActivateWarehouses.ts | 76 - .../ActivateWarehousesSubscriber.ts | 58 - .../src/services/Warehouses/CRUDWarehouse.ts | 26 - .../Warehouses/CreateInitialWarehouse.ts | 26 - .../CreateInitialWarehousesitemsQuantity.ts | 57 - .../services/Warehouses/CreateWarehouse.ts | 83 - .../DeleteItemWarehousesQuantity.ts | 25 - .../services/Warehouses/DeleteWarehouse.ts | 86 - .../src/services/Warehouses/EditWarehouse.ts | 82 - .../src/services/Warehouses/EventsProvider.ts | 39 - .../src/services/Warehouses/GetWarehouse.ts | 24 - .../src/services/Warehouses/GetWarehouses.ts | 21 - .../ValidateWarehouseExistance.ts | 79 - .../WarehouseTransactionDTOTransform.ts | 38 - .../Integrations/WarehousesDTOValidators.ts | 66 - .../Integrations/WarehousesItemsQuantity.ts | 117 - .../WarehousesItemsQuantitySynSubscriber.ts | 74 - .../WarehousesItemsQuantitySync.ts | 131 - .../Warehouses/Integrations/constants.ts | 4 - .../Warehouses/Items/GetItemWarehouses.ts | 37 - .../Items/GettItemWarehouseTransformer.ts | 42 - .../BillWarehousesActivateSubscriber.ts | 36 - .../CreditNoteWarehousesActivateSubscriber.ts | 36 - .../EstimateWarehousesActivateSubscriber.ts | 36 - ...ransactionsWarehousesActivateSubscriber.ts | 36 - .../InvoiceWarehousesActivateSubscriber.ts | 36 - .../ReceiptWarehousesActivateSubscriber.ts | 36 - ...endorCreditWarehousesActivateSubscriber.ts | 36 - .../Warehouses/Subscribers/Activate/index.ts | 8 - .../DeleteItemWarehousesQuantitySubscriber.ts | 36 - ...yAdjustmentWarehouseValidatorSubscriber.ts | 35 - .../Purchases/BillWarehousesSubscriber.ts | 53 - .../VendorCreditWarehousesSubscriber.ts | 56 - .../Sales/CreditNoteWarehousesSubscriber.ts | 56 - .../Sales/SaleEstimateWarehousesSubscriber.ts | 56 - .../Sales/SaleInvoicesWarehousesSubscriber.ts | 56 - .../Sales/SaleReceiptWarehousesSubscriber.ts | 56 - .../Subscribers/Validators/index.ts | 9 - ...pdateInventoryTransactionsWithWarehouse.ts | 21 - .../Warehouses/WarehouseMarkPrimary.ts | 64 - .../services/Warehouses/WarehouseValidator.ts | 57 - .../Warehouses/WarehousesApplication.ts | 137 - .../services/Warehouses/WarehousesService.ts | 36 - .../services/Warehouses/WarehousesSettings.ts | 29 - .../CRUDWarehouseTransfer.ts | 32 - .../CommandWarehouseTransfer.ts | 79 - .../CreateWarehouseTransfer.ts | 204 - .../DeleteWarehouseTransfer.ts | 67 - .../EditWarehouseTransfer.ts | 95 - .../GetWarehouseTransfer.ts | 45 - .../GetWarehouseTransfers.ts | 72 - .../InitiateWarehouseTransfer.ts | 92 - .../TransferredWarehouseTransfer.ts | 107 - .../WarehouseTransferApplication.ts | 152 - .../WarehouseTransferAutoIncrement.ts | 31 - ...arehouseTransferAutoIncrementSubscriber.ts | 33 - ...TransferInventoryTransactionsSubscriber.ts | 155 - .../WarehouseTransferItemTransformer.ts | 38 - .../WarehouseTransferTransfomer.ts | 28 - .../WriteInventoryTransactions.ts | 176 - .../WarehousesTransfers/constants.ts | 57 - .../Warehouses/WarehousesTransfersService.ts | 23 - .../src/services/Warehouses/contants.ts | 7 - .../Authentication/ResetLoginThrottle.ts | 29 - .../Authentication/SendResetPasswordMail.ts | 25 - .../Bills/WriteInventoryTransactions.ts | 94 - .../server/src/subscribers/Bills/index.ts | 22 - .../src/subscribers/Inventory/Inventory.ts | 193 - .../Inventory/InventoryAdjustment.ts | 134 - .../src/subscribers/LandedCost/index.ts | 37 - .../Organization/BuildSmsNotification.ts | 26 - .../Organization/SyncTenantAdminUser.ts | 27 - .../PaymentMades/PaymentSyncBillBalance.ts | 68 - .../PaymentReceive/AutoSerialIncrement.ts | 34 - .../PaymentReceiveSyncInvoices.ts | 88 - .../SendSmsNotificationToCustomer.ts | 40 - .../PaymentReceive/WriteGLEntries.ts | 77 - .../SaleEstimate/AutoIncrementSerial.ts | 38 - .../SaleEstimate/SmsNotifications.ts | 43 - .../SaleInvoices/AutoIncrementSerial.ts | 31 - .../SaleInvoices/ConvertFromEstimate.ts | 41 - .../SendSmsNotificationToCustomer.ts | 44 - .../WriteInventoryTransactions.ts | 91 - .../SaleInvoices/WriteJournalEntries.ts | 94 - .../SaleReceipt/AutoIncrementSerial.ts | 31 - .../SendSmsNotificationToCustomer.ts | 45 - .../SaleReceipt/WriteInventoryTransactions.ts | 89 - .../SaleReceipt/WriteJournalEntries.ts | 95 - packages/server/src/subscribers/events.ts | 775 --- ...0104195900_create_password_resets_table.js | 9 - .../20200420134631_create_tenants_table.js | 22 - .../20200420134633_create_users_table.js | 26 - ...0200422225247_create_user_invites_table.js | 15 - ...091642_create_subscriptions_plans_table.js | 22 - .../20200823234134_create_plans_table.js | 30 - ...6_create_subscription_plan_subscription.js | 22 - ...823235340_create_tenants_metadata_table.js | 22 - ...op_phone_number_column_from_users_table.js | 9 - ...number_column_to_tenants_metadata_table.js | 11 - .../20231209230719_create_imports_table.js | 22 - ...20240222134235_create_plaid_items_table.js | 15 - ...34235_seed_free_subscription_to_tenants.js | 7 - ...00821_add_confirmation_columns_to_users.js | 12 - ..._lemon_variant_id_to_subscription_plans.js | 11 - ...4101229_seed_monthly_subscription_plans.js | 96 - ..._subscription_id_to_subscriptions_table.js | 11 - ...add_trial_columns_to_subscription_table.js | 13 - ...40819164614_create_oneclick_demos_table.js | 21 - ...d_payment_status_to_subscriptions_table.js | 19 - ...20_create_stripe_connect_accounts_table.js | 20 - ...240915070439_create_payment_links_table.js | 24 - ...8145627_add_logo_key_to_tenant_metadata.js | 23 - packages/server/src/system/models/Import.ts | 86 - packages/server/src/system/models/Invite.ts | 30 - .../server/src/system/models/OneclickDemo.ts | 17 - .../server/src/system/models/PasswordReset.ts | 17 - .../server/src/system/models/PaymentLink.ts | 26 - .../server/src/system/models/StripeAccount.ts | 49 - .../src/system/models/Subscriptions/Plan.ts | 86 - .../models/Subscriptions/PlanSubscription.ts | 250 - .../server/src/system/models/SystemModel.ts | 19 - .../src/system/models/SystemPlaidItem.ts | 49 - .../server/src/system/models/SystemUser.ts | 115 - packages/server/src/system/models/Tenant.ts | 236 - .../src/system/models/TenantMetadata.ts | 87 - packages/server/src/system/models/index.ts | 25 - .../repositories/SubscriptionRepository.ts | 22 - .../system/repositories/SystemRepository.ts | 5 - .../repositories/SystemUserRepository.ts | 101 - .../system/repositories/TenantRepository.ts | 43 - .../server/src/system/repositories/index.ts | 9 - .../system/seeds/seed_subscriptions_plans.js | 26 - .../seeds/seed_tenants_free_subscription.js | 26 - .../src/utils/accum-sum.ts | 0 .../server/src/utils/address-text-format.ts | 4 +- .../src/utils/all-conditions-passed.ts | 0 .../utils/assoc-depth-level-to-object-tree.ts | 0 .../src/utils/associate-item-entries-index.ts | 0 .../src/utils/cast-comma-list-envvar-Array.ts | 0 .../src/utils/date-range-collection.ts | 0 packages/server/src/utils/deepdash.ts | 7 +- .../src/utils/entries-amount-diff.ts | 0 .../src/utils/flat-to-nested-array.ts | 0 .../src/utils/format-date-fields.ts | 0 .../src/utils/format-message.ts | 0 .../src/utils/format-number.ts | 0 packages/server/src/utils/formatMinutes.ts | 11 - .../src/utils/increment.ts | 0 packages/server/src/utils/index.ts | 522 -- .../src/utils/is-blank.ts | 0 .../src/utils/items-start-with.ts | 0 .../src/utils/moment-mysql.ts | 0 .../src/utils/multi-number-parse.test.ts | 51 - .../server/src/utils/multi-number-parse.ts | 130 - .../src/utils/nested-array-to-flatten.ts | 0 .../src/utils/parse-boolean.ts | 0 packages/server/src/utils/parse-json-safe.ts | 7 - .../src/utils/sanitize-database-name.ts | 0 packages/server/src/utils/sanitizers.ts | 4 - packages/server/src/utils/table.ts | 34 - packages/server/src/utils/taxRate.ts | 19 - .../src/utils/template-render.ts | 0 .../src/utils/transaction-increment.ts | 0 .../server/src/utils/transactions-types.ts | 36 - .../src/utils/transform-to-key.ts | 0 .../src/utils/transform-to-map-by.ts | 0 .../src/utils/transform-to-map-key-value.ts | 0 .../static/demo-sheets/Expenses.csv | 0 .../static/demo-sheets/bank-transactions.csv | 0 .../static/demo-sheets/customers.csv | 0 .../static/demo-sheets/items.csv | 0 .../static/demo-sheets/manual-journals.csv | 0 .../static/demo-sheets/sale-invoices.csv | 0 .../static/demo-sheets/vendors.csv | 0 .../static/images/bigcapital.png | Bin .../static/mail/ResetPassword.html | 0 .../static/mail/SignupVerifyEmail.html | 0 .../static/mail/UserInvite.html | 0 packages/server/storage/.gitignore | 4 - packages/server/storage/imports/.gitignore | 2 - packages/server/storage/pdf/.gitignore | 2 - .../test/auth.e2e-spec.ts | 0 .../test/bank-rules.e2e-spec.ts | 0 .../test/banking-transactions.e2e-spec.ts | 0 .../test/branches.e2e-spec.ts | 0 .../test/credit-notes.e2e-spec.ts | 0 .../test/customers.e2e-spec.ts | 0 .../test/expenses.e2e-spec.ts | 0 .../test/init-app-test.ts | 0 .../test/inventory-adjustment.e2e-spec.ts | 0 .../test/item-categories.e2e-spec.ts | 0 .../test/items.e2e-spec.ts | 0 .../test/jest-e2e.json | 0 .../test/manual-journal.e2e-spec.ts | 0 .../test/organization.e2e-spec.ts | 0 .../test/payment-received.e2e-spec.ts | 0 .../test/pdf-templates.e2e-spec.ts | 0 .../test/sale-estimates.e2e-spec.ts | 0 .../test/sale-invoices.e2e-spec.ts | 0 .../test/sale-receipts.e2e-spec.ts | 0 .../test/settings.e2e-spec.ts | 0 .../test/tax-rates.e2e-spec.ts | 0 .../test/transactions-locking.e2e-spec.ts | 0 .../test/vendor-credits.e2e-spec.ts | 0 .../test/vendors.e2e-spec.ts | 0 .../test/warehouses.e2e-spec.ts | 0 .../server/tests/collection/NestedSet.test.js | 130 - packages/server/tests/dbInit.js | 40 - packages/server/tests/docker-compose.yml | 14 - .../server/tests/lib/CachableModel.test.js | 32 - .../server/tests/lib/MetableStore.test.ts | 39 - packages/server/tests/models/Account.test.js | 50 - .../server/tests/models/AccountType.test.js | 22 - packages/server/tests/models/Expense.test.js | 39 - .../tests/models/ExpenseCategory.test.js | 5 - packages/server/tests/models/Item.test.js | 22 - .../tests/models/ItemCategories.test.js | 24 - packages/server/tests/models/Resource.test.js | 31 - packages/server/tests/models/User.test.js | 23 - packages/server/tests/models/View.test.js | 47 - packages/server/tests/mysql-tmpfs.sh | 31 - .../server/tests/routes/accounting.test.js | 887 --- packages/server/tests/routes/accounts.test.js | 758 -- packages/server/tests/routes/auth.test.js | 288 - .../server/tests/routes/balance_sheet.test.js | 541 -- .../server/tests/routes/bill_payments.test.js | 113 - packages/server/tests/routes/bills.test.js | 217 - .../server/tests/routes/currencies.test.js | 191 - .../server/tests/routes/customers.test.js | 250 - .../tests/routes/exchange_rates.test.js | 230 - packages/server/tests/routes/expenses.test.js | 739 -- .../tests/routes/financial_statements.test.js | 956 --- .../server/tests/routes/inviteUsers.test.js | 259 - packages/server/tests/routes/items.test.js | 729 -- .../tests/routes/itemsCategories.test.js | 311 - packages/server/tests/routes/options.test.js | 120 - .../server/tests/routes/payable_aging.test.js | 0 .../tests/routes/payment_receives.test.js | 274 - .../tests/routes/receivable_aging.test.js | 234 - .../tests/routes/sales_estimates.test.js | 439 -- .../tests/routes/sales_invoices.test.js | 494 -- .../tests/routes/sales_receipts.test.js | 294 - packages/server/tests/routes/users.test.js | 203 - packages/server/tests/routes/vendors.test.js | 193 - packages/server/tests/routes/views.test.js | 936 --- .../tests/services/JournalPoster.test.js | 406 -- packages/server/tests/testInit.js | 88 - packages/server/tests/utils/utils.test.js | 16 - .../tsconfig.build.json | 0 packages/server/tsconfig.json | 51 +- packages/server/views/.DS_Store | Bin 6148 -> 0 bytes .../server/views/demo-sheets/Expenses.csv | 23 - .../views/demo-sheets/bank-transactions.csv | 123 - .../server/views/demo-sheets/customers.csv | 6 - packages/server/views/demo-sheets/items.csv | 61 - .../views/demo-sheets/manual-journals.csv | 11 - .../views/demo-sheets/sale-invoices.csv | 50 - packages/server/views/demo-sheets/vendors.csv | 5 - packages/server/views/images/bigcapital.png | Bin 2427 -> 0 bytes packages/server/views/mail/ResetPassword.html | 424 -- .../server/views/mail/SignupVerifyEmail.html | 424 -- packages/server/views/mail/UserInvite.html | 421 -- pnpm-lock.yaml | 6087 +---------------- 3779 files changed, 631 insertions(+), 195332 deletions(-) delete mode 100644 packages/server-nest/.eslintrc.js delete mode 100644 packages/server-nest/.gitignore delete mode 100644 packages/server-nest/README.md delete mode 100644 packages/server-nest/package.json delete mode 100644 packages/server-nest/src/database/migrations/20220329121920_add_seed_at_column_to_accounts.ts delete mode 100644 packages/server-nest/src/database/migrations/20220429121920_create_projects_table.ts delete mode 100644 packages/server-nest/src/database/migrations/20220429121922_add_project_id_to_expense_lines.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20190423085242_seed_accounts.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20200810121809_seed_settings.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20200810121909_seed_items_settings.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20210810121909_seed_roles.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20210812121909_seed_roles_permissions.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20210912121909_seed_credit_settings.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20230912121909_seed_tax_rates.ts delete mode 100644 packages/server-nest/src/database/seeds/core/20230912121909_update_tax_payable_account.ts delete mode 100644 packages/server-nest/src/database/seeds/core/index.ts delete mode 100644 packages/server-nest/src/database/seeds/data/TaxRates.ts delete mode 100644 packages/server-nest/src/interfaces/Account.ts delete mode 100644 packages/server-nest/src/interfaces/Item.ts delete mode 100644 packages/server-nest/src/interfaces/Model.ts delete mode 100644 packages/server-nest/src/models/Model.ts delete mode 100644 packages/server-nest/src/utils/address-text-format.ts delete mode 100644 packages/server-nest/src/utils/deepdash.ts delete mode 100644 packages/server-nest/tsconfig.json delete mode 100644 packages/server/.babelrc rename packages/{server-nest => server}/.env.example (100%) rename packages/{server-nest => server}/.prettierrc (100%) rename packages/{server-nest => server}/.todo (100%) delete mode 100644 packages/server/Dockerfile delete mode 100644 packages/server/knexfile.js rename packages/{server-nest => server}/nest-cli.json (100%) delete mode 100644 packages/server/public/.DS_Store delete mode 100644 packages/server/public/imports/.DS_Store delete mode 100644 packages/server/resources/css/modules/credit-rtl.css delete mode 100644 packages/server/resources/css/modules/credit.css delete mode 100644 packages/server/resources/css/modules/estimate-rtl.css delete mode 100644 packages/server/resources/css/modules/estimate.css delete mode 100644 packages/server/resources/css/modules/invoice-rtl.css delete mode 100644 packages/server/resources/css/modules/invoice.css delete mode 100644 packages/server/resources/css/modules/payment-rtl.css delete mode 100644 packages/server/resources/css/modules/payment.css delete mode 100644 packages/server/resources/css/modules/receipt-rtl.css delete mode 100644 packages/server/resources/css/modules/receipt.css delete mode 100644 packages/server/resources/locales/ar.json delete mode 100644 packages/server/resources/locales/en.json delete mode 100644 packages/server/resources/scss/base.css delete mode 100644 packages/server/resources/scss/base.scss delete mode 100644 packages/server/resources/scss/fonts.scss delete mode 100644 packages/server/resources/scss/layouts/paper-layout.scss delete mode 100644 packages/server/resources/scss/modules/credit.scss delete mode 100644 packages/server/resources/scss/modules/estimate.scss delete mode 100644 packages/server/resources/scss/modules/export-resource-table.scss delete mode 100644 packages/server/resources/scss/modules/financial-sheet.scss delete mode 100644 packages/server/resources/scss/modules/invoice.scss delete mode 100644 packages/server/resources/scss/modules/payment.scss delete mode 100644 packages/server/resources/scss/modules/receipt.scss delete mode 100644 packages/server/resources/scss/normalize.css delete mode 100644 packages/server/resources/scss/normalize.scss delete mode 100644 packages/server/resources/views/PaperTemplateLayout.pug delete mode 100644 packages/server/resources/views/modules/credit-note-standard.pug delete mode 100644 packages/server/resources/views/modules/export-resource-table.pug delete mode 100644 packages/server/resources/views/modules/financial-sheet.pug delete mode 100644 packages/server/scripts/gulpConfig.js delete mode 100644 packages/server/scripts/gulpfile.js delete mode 100644 packages/server/scripts/install.sh delete mode 100644 packages/server/scripts/run_test_db.sh delete mode 100644 packages/server/scripts/webpack.cli.js delete mode 100644 packages/server/scripts/webpack.common.js delete mode 100644 packages/server/scripts/webpack.config.js delete mode 100644 packages/server/src/api/controllers/Account/index.ts delete mode 100644 packages/server/src/api/controllers/AccountTypes.ts delete mode 100644 packages/server/src/api/controllers/Accounts.ts delete mode 100644 packages/server/src/api/controllers/Agendash.ts delete mode 100644 packages/server/src/api/controllers/Attachments/AttachmentsController.ts delete mode 100644 packages/server/src/api/controllers/Authentication.ts delete mode 100644 packages/server/src/api/controllers/Banking/BankAccountsController.ts delete mode 100644 packages/server/src/api/controllers/Banking/BankTransactionsMatchingController.ts delete mode 100644 packages/server/src/api/controllers/Banking/BankingController.ts delete mode 100644 packages/server/src/api/controllers/Banking/BankingRulesController.ts delete mode 100644 packages/server/src/api/controllers/Banking/BankingUncategorizedController.ts delete mode 100644 packages/server/src/api/controllers/Banking/ExcludeBankTransactionsController.ts delete mode 100644 packages/server/src/api/controllers/Banking/PlaidBankingController.ts delete mode 100644 packages/server/src/api/controllers/Banking/RecognizedTransactionsController.ts delete mode 100644 packages/server/src/api/controllers/BaseController.ts delete mode 100644 packages/server/src/api/controllers/Branches/index.ts delete mode 100644 packages/server/src/api/controllers/Cashflow/CashflowController.ts delete mode 100644 packages/server/src/api/controllers/Cashflow/DeleteCashflowTransaction.ts delete mode 100644 packages/server/src/api/controllers/Cashflow/GetCashflowAccounts.ts delete mode 100644 packages/server/src/api/controllers/Cashflow/GetCashflowTransaction.ts delete mode 100644 packages/server/src/api/controllers/Cashflow/NewCashflowTransaction.ts delete mode 100644 packages/server/src/api/controllers/Contacts/Contacts.ts delete mode 100644 packages/server/src/api/controllers/Contacts/Customers.ts delete mode 100644 packages/server/src/api/controllers/Contacts/Vendors.ts delete mode 100644 packages/server/src/api/controllers/Currencies.ts delete mode 100644 packages/server/src/api/controllers/Dashboard/index.ts delete mode 100644 packages/server/src/api/controllers/ExchangeRates.ts delete mode 100644 packages/server/src/api/controllers/Expenses/Expenses.ts delete mode 100644 packages/server/src/api/controllers/Expenses/index.ts delete mode 100644 packages/server/src/api/controllers/Export/ExportController.ts delete mode 100644 packages/server/src/api/controllers/Export/_utils.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/BaseFinancialReportController.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/CashflowAccountTransactions/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/CustomerBalanceSummary/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/GeneralLedger.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/InventoryDetails/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/InventoryValuationSheet.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/ProjectProfitabilitySummary/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/PurchasesByItem.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/TransactionsByCustomers/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/TransactionsByReference/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/TransactionsByVendors/index.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts delete mode 100644 packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts delete mode 100644 packages/server/src/api/controllers/Import/ImportController.ts delete mode 100644 packages/server/src/api/controllers/Import/_utils.ts delete mode 100644 packages/server/src/api/controllers/Inventory/InventortyItemsCosts.ts delete mode 100644 packages/server/src/api/controllers/Inventory/InventoryAdjustments.ts delete mode 100644 packages/server/src/api/controllers/InviteUsers.ts delete mode 100644 packages/server/src/api/controllers/ItemCategories.ts delete mode 100644 packages/server/src/api/controllers/Items/Items.ts delete mode 100644 packages/server/src/api/controllers/Items/ItemsTransactions.ts delete mode 100644 packages/server/src/api/controllers/Items/index.ts delete mode 100644 packages/server/src/api/controllers/Jobs.ts delete mode 100644 packages/server/src/api/controllers/ManualJournals.ts delete mode 100644 packages/server/src/api/controllers/Media.ts delete mode 100644 packages/server/src/api/controllers/Miscellaneous/index.ts delete mode 100644 packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts delete mode 100644 packages/server/src/api/controllers/Organization.ts delete mode 100644 packages/server/src/api/controllers/OrganizationDashboard.ts delete mode 100644 packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts delete mode 100644 packages/server/src/api/controllers/PdfTemplates/PdfTemplatesController.ts delete mode 100644 packages/server/src/api/controllers/Ping.ts delete mode 100644 packages/server/src/api/controllers/Projects/Projects.ts delete mode 100644 packages/server/src/api/controllers/Projects/Tasks.ts delete mode 100644 packages/server/src/api/controllers/Projects/Times.ts delete mode 100644 packages/server/src/api/controllers/Purchases/Bills.ts delete mode 100644 packages/server/src/api/controllers/Purchases/BillsPayments.ts delete mode 100644 packages/server/src/api/controllers/Purchases/LandedCost.ts delete mode 100644 packages/server/src/api/controllers/Purchases/VendorCredit.ts delete mode 100644 packages/server/src/api/controllers/Purchases/VendorCreditApplyToBills.ts delete mode 100644 packages/server/src/api/controllers/Purchases/index.ts delete mode 100644 packages/server/src/api/controllers/Resources.ts delete mode 100644 packages/server/src/api/controllers/Roles/PermissionsSchema.ts delete mode 100644 packages/server/src/api/controllers/Roles/Roles.ts delete mode 100644 packages/server/src/api/controllers/Roles/index.ts delete mode 100644 packages/server/src/api/controllers/Sales/CreditNoteApplyToBills.ts delete mode 100644 packages/server/src/api/controllers/Sales/CreditNotes.ts delete mode 100644 packages/server/src/api/controllers/Sales/PaymentReceives.ts delete mode 100644 packages/server/src/api/controllers/Sales/SalesEstimates.ts delete mode 100644 packages/server/src/api/controllers/Sales/SalesInvoices.ts delete mode 100644 packages/server/src/api/controllers/Sales/SalesReceipts.ts delete mode 100644 packages/server/src/api/controllers/Sales/index.ts delete mode 100644 packages/server/src/api/controllers/Settings/EasySmsIntegration.ts delete mode 100644 packages/server/src/api/controllers/Settings/Settings.ts delete mode 100644 packages/server/src/api/controllers/Settings/SmsNotificationsSettings.ts delete mode 100644 packages/server/src/api/controllers/Settings/index.ts delete mode 100644 packages/server/src/api/controllers/ShareLink/PublicSharableLinkController.ts delete mode 100644 packages/server/src/api/controllers/ShareLink/ShareLinkController.ts delete mode 100644 packages/server/src/api/controllers/StripeIntegration/StripeIntegrationController.ts delete mode 100644 packages/server/src/api/controllers/StripeIntegration/StripeWebhooksController.ts delete mode 100644 packages/server/src/api/controllers/Subscription/SubscriptionController.ts delete mode 100644 packages/server/src/api/controllers/Subscription/index.ts delete mode 100644 packages/server/src/api/controllers/TaxRates/TaxRates.ts delete mode 100644 packages/server/src/api/controllers/TransactionsLocking/index.ts delete mode 100644 packages/server/src/api/controllers/TransactionsLocking/utils.ts delete mode 100644 packages/server/src/api/controllers/Users.ts delete mode 100644 packages/server/src/api/controllers/Views.ts delete mode 100644 packages/server/src/api/controllers/Warehouses/WarehouseTransfers.ts delete mode 100644 packages/server/src/api/controllers/Warehouses/WarehousesItem.ts delete mode 100644 packages/server/src/api/controllers/Warehouses/index.ts delete mode 100644 packages/server/src/api/controllers/Webhooks/Webhooks.ts delete mode 100644 packages/server/src/api/exceptions/GlobalErrorException.ts delete mode 100644 packages/server/src/api/exceptions/ObjectionErrorException.ts delete mode 100644 packages/server/src/api/exceptions/ServiceErrorException.ts delete mode 100644 packages/server/src/api/index.ts delete mode 100644 packages/server/src/api/middleware/AsyncRenderMiddleware.ts delete mode 100644 packages/server/src/api/middleware/AttachCurrentTenantUser.ts delete mode 100644 packages/server/src/api/middleware/AuthorizationMiddleware.ts delete mode 100644 packages/server/src/api/middleware/CheckPolicies.ts delete mode 100644 packages/server/src/api/middleware/ConvertEmptyStringsToNull.ts delete mode 100644 packages/server/src/api/middleware/EnsureTenantIsInitialized.ts delete mode 100644 packages/server/src/api/middleware/EnsureTenantIsSeeded.ts delete mode 100644 packages/server/src/api/middleware/FeatureActivationGuard.ts delete mode 100644 packages/server/src/api/middleware/I18nAuthenticatedMiddlware.ts delete mode 100644 packages/server/src/api/middleware/I18nMiddleware.ts delete mode 100644 packages/server/src/api/middleware/JSONResponseTransformer.ts delete mode 100644 packages/server/src/api/middleware/LoggerMiddleware.ts delete mode 100644 packages/server/src/api/middleware/LoginThrottlerMiddleware.ts delete mode 100644 packages/server/src/api/middleware/RateLimiterMiddleware.ts delete mode 100644 packages/server/src/api/middleware/SettingsMiddleware.ts delete mode 100644 packages/server/src/api/middleware/SubscriptionMiddleware.ts delete mode 100644 packages/server/src/api/middleware/TenancyMiddleware.ts delete mode 100644 packages/server/src/api/middleware/TenantDependencyInjection.ts delete mode 100644 packages/server/src/api/middleware/asyncMiddleware.ts delete mode 100644 packages/server/src/api/middleware/jwtAuth.ts delete mode 100644 packages/server/src/before.ts delete mode 100644 packages/server/src/collection/BudgetEntriesSet.ts delete mode 100644 packages/server/src/collection/Cachable.ts delete mode 100644 packages/server/src/collection/Metable.ts delete mode 100644 packages/server/src/collection/NestedSet/index.ts delete mode 100644 packages/server/src/collection/ResourceFieldMetadataCollection.ts delete mode 100644 packages/server/src/collection/SoftDeleteQueryBuilder.ts delete mode 100644 packages/server/src/commands/bigcapital.ts delete mode 100644 packages/server/src/commands/index.ts rename packages/{server-nest => server}/src/common/config/gotenberg.ts (100%) rename packages/{server-nest => server}/src/common/config/index.ts (100%) rename packages/{server-nest => server}/src/common/config/inventory.ts (100%) rename packages/{server-nest => server}/src/common/config/jwt.ts (100%) rename packages/{server-nest => server}/src/common/config/lemonsqueezy.ts (100%) rename packages/{server-nest => server}/src/common/config/loops.ts (100%) rename packages/{server-nest => server}/src/common/config/mail.ts (100%) rename packages/{server-nest => server}/src/common/config/open-exchange.ts (100%) rename packages/{server-nest => server}/src/common/config/plaid.ts (100%) rename packages/{server-nest => server}/src/common/config/posthog.ts (100%) rename packages/{server-nest => server}/src/common/config/redis.ts (100%) rename packages/{server-nest => server}/src/common/config/s3.ts (100%) rename packages/{server-nest => server}/src/common/config/signup-confirmation.ts (100%) rename packages/{server-nest => server}/src/common/config/signup-restrictions.ts (100%) rename packages/{server-nest => server}/src/common/config/signup.ts (100%) rename packages/{server-nest => server}/src/common/config/stripe-payment.ts (100%) rename packages/{server-nest => server}/src/common/config/system-database.ts (100%) rename packages/{server-nest => server}/src/common/config/tenant-database.ts (100%) rename packages/{server-nest => server}/src/common/constants/files.constants.ts (100%) rename packages/{server-nest => server}/src/common/constants/multer.constants.ts (100%) rename packages/{server-nest => server}/src/common/constants/multer.utils.ts (100%) rename packages/{server-nest => server}/src/common/events/events.ts (100%) rename packages/{server-nest => server}/src/common/exceptions/ModelEntityNotFound.ts (100%) rename packages/{server-nest => server}/src/common/filters/service-error.filter.ts (100%) rename packages/{server-nest => server}/src/common/interceptors/file.interceptor.ts (100%) rename packages/{server-nest => server}/src/common/interceptors/serialize.interceptor.ts (100%) rename packages/{server-nest => server}/src/common/pipes/ClassValidation.pipe.ts (100%) rename packages/{server-nest => server}/src/common/pipes/ZodValidation.pipe.ts (100%) rename packages/{server-nest => server}/src/common/repository/CachableRepository.ts (100%) rename packages/{server-nest => server}/src/common/repository/EntityRepository.ts (100%) rename packages/{server-nest => server}/src/common/repository/TenantRepository.ts (100%) rename packages/{server-nest => server}/src/common/types/Constructor.ts (100%) rename packages/{server-nest => server}/src/common/types/Date.ts (100%) rename packages/{server-nest => server}/src/common/types/Discount.ts (100%) rename packages/{server-nest => server}/src/common/types/Features.ts (100%) delete mode 100644 packages/server/src/config/index.ts delete mode 100644 packages/server/src/config/knexConfig.ts delete mode 100644 packages/server/src/config/smsNotifications.ts rename packages/{server-nest => server}/src/constants/accept-type.ts (100%) rename packages/{server-nest => server}/src/constants/accounts.ts (100%) rename packages/{server-nest => server}/src/constants/data-types.ts (100%) delete mode 100644 packages/server/src/constants/event-tracker.ts rename packages/{server-nest => server}/src/constants/metable-options.ts (100%) delete mode 100644 packages/server/src/data/AccountTypes.ts delete mode 100644 packages/server/src/data/BalanceSheetStructure.ts delete mode 100644 packages/server/src/data/DataTypes.ts delete mode 100644 packages/server/src/data/ResourceFieldsKeys.ts delete mode 100755 packages/server/src/data/TransactionTypes.ts delete mode 100644 packages/server/src/data/options.ts delete mode 100644 packages/server/src/database/factories/index.js delete mode 100644 packages/server/src/database/factories/system.js delete mode 100644 packages/server/src/database/migrations/20190822214303_create_accounts_table.js rename packages/{server-nest => server}/src/database/migrations/20190822214303_create_accounts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20190822214304_create_items_categories_table.js rename packages/{server-nest => server}/src/database/migrations/20190822214304_create_items_categories_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20190822214306_create_items_table.js rename packages/{server-nest => server}/src/database/migrations/20190822214306_create_items_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20190822214903_create_views_table.js rename packages/{server-nest => server}/src/database/migrations/20190822214903_create_views_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20190822214904_create_settings_table.js rename packages/{server-nest => server}/src/database/migrations/20190822214904_create_settings_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20190822214905_create_views_columns.js rename packages/{server-nest => server}/src/database/migrations/20190822214905_create_views_columns.ts (100%) delete mode 100644 packages/server/src/database/migrations/20190822214905_create_views_roles_table.js rename packages/{server-nest => server}/src/database/migrations/20190822214905_create_views_roles_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200104232644_create_contacts_table.js rename packages/{server-nest => server}/src/database/migrations/20200104232644_create_contacts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20200104232647_create_accounts_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200105014405_create_expenses_table.js rename packages/{server-nest => server}/src/database/migrations/20200105014405_create_expenses_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200105195823_create_manual_journals_table.js rename packages/{server-nest => server}/src/database/migrations/20200105195823_create_manual_journals_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200105195825_create_manual_journals_entries_table.js rename packages/{server-nest => server}/src/database/migrations/20200105195825_create_manual_journals_entries_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200419171451_create_currencies_table.js rename packages/{server-nest => server}/src/database/migrations/20200419171451_create_currencies_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200419191832_create_exchange_rates_table.js rename packages/{server-nest => server}/src/database/migrations/20200419191832_create_exchange_rates_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200423201600_create_media_table.js rename packages/{server-nest => server}/src/database/migrations/20200423201600_create_media_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200503032011_create_media_links_table.js rename packages/{server-nest => server}/src/database/migrations/20200503032011_create_media_links_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200606113848_create_expense_transactions_categories_table.js rename packages/{server-nest => server}/src/database/migrations/20200606113848_create_expense_transactions_categories_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200713192127_create_sales_estimates_table.js rename packages/{server-nest => server}/src/database/migrations/20200713192127_create_sales_estimates_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200713213303_create_sales_receipt_table.js rename packages/{server-nest => server}/src/database/migrations/20200713213303_create_sales_receipt_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200715193633_create_sale_invoices_table.js rename packages/{server-nest => server}/src/database/migrations/20200715193633_create_sale_invoices_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200715194514_create_payment_receives_table.js rename packages/{server-nest => server}/src/database/migrations/20200715194514_create_payment_receives_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200718161031_create_payment_receives_entries_table.js rename packages/{server-nest => server}/src/database/migrations/20200718161031_create_payment_receives_entries_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200719152005_create_bills_table.js rename packages/{server-nest => server}/src/database/migrations/20200719152005_create_bills_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200719153909_create_bills_payments_table.js rename packages/{server-nest => server}/src/database/migrations/20200719153909_create_bills_payments_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20200722164251_create_inventory_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200722164252_create_landed_cost_table.js rename packages/{server-nest => server}/src/database/migrations/20200722164252_create_landed_cost_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200722164253_create_landed_cost_entries_table.js rename packages/{server-nest => server}/src/database/migrations/20200722164253_create_landed_cost_entries_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.js rename packages/{server-nest => server}/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200722173423_create_items_entries_table.js rename packages/{server-nest => server}/src/database/migrations/20200722173423_create_items_entries_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200728161617_create_bill_payments_entries.js rename packages/{server-nest => server}/src/database/migrations/20200728161617_create_bill_payments_entries.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js rename packages/{server-nest => server}/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200810121809_create_inventory_adjustments_table.js rename packages/{server-nest => server}/src/database/migrations/20200810121809_create_inventory_adjustments_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.js rename packages/{server-nest => server}/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20200810121910_create_cashflow_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20200810121910_create_cashflow_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.js rename packages/{server-nest => server}/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.js rename packages/{server-nest => server}/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.js rename packages/{server-nest => server}/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211014121910_add_roles_table.js rename packages/{server-nest => server}/src/database/migrations/20211014121910_add_roles_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211112121920_create_users_table.js rename packages/{server-nest => server}/src/database/migrations/20211112121920_create_users_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211122121920_create_credit_notes_table.js rename packages/{server-nest => server}/src/database/migrations/20211122121920_create_credit_notes_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211122121920_create_vendor_credits_table.js rename packages/{server-nest => server}/src/database/migrations/20211122121920_create_vendor_credits_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211123121920_create_refund_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20211123121920_create_refund_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20211124121920_create_credit_note_applies_invoices.js rename packages/{server-nest => server}/src/database/migrations/20211124121920_create_credit_note_applies_invoices.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220124121920_create_branches_table.js rename packages/{server-nest => server}/src/database/migrations/20220124121920_create_branches_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220124121920_create_warehouses_table.js rename packages/{server-nest => server}/src/database/migrations/20220124121920_create_warehouses_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220125021920_create_items_warehouses_quantity.js rename packages/{server-nest => server}/src/database/migrations/20220125021920_create_items_warehouses_quantity.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.js rename packages/{server-nest => server}/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.js rename packages/{server-nest => server}/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.js rename packages/{server-nest => server}/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.js rename packages/{server-nest => server}/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.js rename packages/{server-nest => server}/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.js rename packages/{server-nest => server}/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.js rename packages/{server-nest => server}/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.js rename packages/{server-nest => server}/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.ts (100%) delete mode 100644 packages/server/src/database/migrations/20220329121920_add_cashflow_credit_account.js rename packages/{server-nest => server}/src/database/migrations/20220329121920_add_cashflow_credit_account.ts (100%) delete mode 100644 packages/server/src/database/migrations/20230405232607_drop_phone_number_from_users.js rename packages/{server-nest => server}/src/database/migrations/20230405232607_drop_phone_number_from_users.ts (100%) delete mode 100644 packages/server/src/database/migrations/20230810191606_create_tax_rates.js rename packages/{server-nest => server}/src/database/migrations/20230810191606_create_tax_rates.ts (100%) delete mode 100644 packages/server/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.js rename packages/{server-nest => server}/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js rename packages/{server-nest => server}/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20231108170207_create_storage_table.js rename packages/{server-nest => server}/src/database/migrations/20231108170207_create_storage_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20231202124014_change_item_entries_rate_to_float.js rename packages/{server-nest => server}/src/database/migrations/20231202124014_change_item_entries_rate_to_float.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240201160214_create_plaid_items_Table.js rename packages/{server-nest => server}/src/database/migrations/20240201160214_create_plaid_items_Table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.js rename packages/{server-nest => server}/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.js rename packages/{server-nest => server}/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.js rename packages/{server-nest => server}/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.js rename packages/{server-nest => server}/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240604153938_drop_storage_table.js rename packages/{server-nest => server}/src/database/migrations/20240604153938_drop_storage_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240604153951_create_documents_table.js rename packages/{server-nest => server}/src/database/migrations/20240604153951_create_documents_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240604154005_create_documents_links_table.js rename packages/{server-nest => server}/src/database/migrations/20240604154005_create_documents_links_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240618100137_create_bank_rules_table.js rename packages/{server-nest => server}/src/database/migrations/20240618100137_create_bank_rules_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.js rename packages/{server-nest => server}/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240619133733_create_matched_bank_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20240619133733_create_matched_bank_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240704064858_change_settings_value_to_text.js rename packages/{server-nest => server}/src/database/migrations/20240704064858_change_settings_value_to_text.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.js rename packages/{server-nest => server}/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.js rename packages/{server-nest => server}/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.js rename packages/{server-nest => server}/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.js rename packages/{server-nest => server}/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.js rename packages/{server-nest => server}/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.js rename packages/{server-nest => server}/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.js rename packages/{server-nest => server}/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240911112147_create_pdf_templates_table.js rename packages/{server-nest => server}/src/database/migrations/20240911112147_create_pdf_templates_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240915155403_payment_integration.js rename packages/{server-nest => server}/src/database/migrations/20240915155403_payment_integration.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240915163722_creat_transaction_payment_service_table.js rename packages/{server-nest => server}/src/database/migrations/20240915163722_creat_transaction_payment_service_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20240915195024_seed_standard_pdf_templates.js rename packages/{server-nest => server}/src/database/migrations/20240915195024_seed_standard_pdf_templates.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.js rename packages/{server-nest => server}/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241128080734_add_discount_to_invoices_table.js rename packages/{server-nest => server}/src/database/migrations/20241128080734_add_discount_to_invoices_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241128081259_add_discount_to_estimates_table.js rename packages/{server-nest => server}/src/database/migrations/20241128081259_add_discount_to_estimates_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241128084550_add_discount_to_receipts_table.js rename packages/{server-nest => server}/src/database/migrations/20241128084550_add_discount_to_receipts_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241128085243_add_discount_to_bills_table.js rename packages/{server-nest => server}/src/database/migrations/20241128085243_add_discount_to_bills_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.js rename packages/{server-nest => server}/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.js rename packages/{server-nest => server}/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.ts (100%) delete mode 100644 packages/server/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.js rename packages/{server-nest => server}/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.ts (100%) delete mode 100644 packages/server/src/database/objection.ts delete mode 100644 packages/server/src/database/seeds/data/accounts.js rename packages/{server-nest => server}/src/database/seeds/data/accounts.ts (100%) delete mode 100644 packages/server/src/decorators/eventDispatcher.ts delete mode 100644 packages/server/src/exceptions/HttpException.ts delete mode 100644 packages/server/src/exceptions/ModelEntityNotFound.ts delete mode 100644 packages/server/src/exceptions/NotAllowedChangeSubscriptionPlan.ts delete mode 100644 packages/server/src/exceptions/ServiceError.ts delete mode 100644 packages/server/src/exceptions/ServiceErrors.ts delete mode 100644 packages/server/src/exceptions/TenantAlreadyInitialized.ts delete mode 100644 packages/server/src/exceptions/TenantAlreadySeeded.ts delete mode 100644 packages/server/src/exceptions/TenantDBAlreadyExists.ts delete mode 100644 packages/server/src/exceptions/TenantDatabaseNotBuilt.ts delete mode 100644 packages/server/src/exceptions/index.ts rename packages/{server-nest => server}/src/i18n/en/test.json (100%) rename packages/{server-nest => server}/src/interceptors/ExcludeNull.interceptor.ts (100%) rename packages/{server-nest => server}/src/interceptors/global-prefix.interceptor.ts (100%) rename packages/{server-nest => server}/src/interceptors/user-ip.interceptor.ts (100%) delete mode 100644 packages/server/src/interfaces/APAgingSummaryReport.ts delete mode 100644 packages/server/src/interfaces/ARAgingSummaryReport.ts delete mode 100644 packages/server/src/interfaces/AgingReport.ts delete mode 100644 packages/server/src/interfaces/Attachments.ts delete mode 100644 packages/server/src/interfaces/Authentication.ts delete mode 100644 packages/server/src/interfaces/BalanceSheet.ts delete mode 100644 packages/server/src/interfaces/Bill.ts delete mode 100644 packages/server/src/interfaces/BillPayment.ts delete mode 100644 packages/server/src/interfaces/Branches.ts delete mode 100644 packages/server/src/interfaces/CashFlow.ts delete mode 100644 packages/server/src/interfaces/CashflowService.ts delete mode 100644 packages/server/src/interfaces/Contact.ts delete mode 100644 packages/server/src/interfaces/ContactBalanceSummary.ts delete mode 100644 packages/server/src/interfaces/CreditNote.ts delete mode 100644 packages/server/src/interfaces/Currency.ts delete mode 100644 packages/server/src/interfaces/CustomerBalanceSummary.ts delete mode 100644 packages/server/src/interfaces/DynamicFilter.ts delete mode 100644 packages/server/src/interfaces/Entry.ts delete mode 100644 packages/server/src/interfaces/ExchangeRate.ts delete mode 100644 packages/server/src/interfaces/Expenses.ts delete mode 100644 packages/server/src/interfaces/Features.ts delete mode 100644 packages/server/src/interfaces/FinancialReports/CashflowAccountTransactions/index.ts delete mode 100644 packages/server/src/interfaces/FinancialStatements.ts delete mode 100644 packages/server/src/interfaces/GeneralLedgerSheet.ts delete mode 100644 packages/server/src/interfaces/Http.ts delete mode 100644 packages/server/src/interfaces/IInventoryValuationSheet.ts delete mode 100644 packages/server/src/interfaces/Import.ts delete mode 100644 packages/server/src/interfaces/InventoryAdjustment.ts delete mode 100644 packages/server/src/interfaces/InventoryCost.ts delete mode 100644 packages/server/src/interfaces/InventoryCostMethod.ts delete mode 100644 packages/server/src/interfaces/InventoryDetails.ts delete mode 100644 packages/server/src/interfaces/InventoryTransaction.ts delete mode 100644 packages/server/src/interfaces/ItemCategory.ts delete mode 100644 packages/server/src/interfaces/ItemEntry.ts delete mode 100644 packages/server/src/interfaces/Jobs.ts delete mode 100644 packages/server/src/interfaces/Journal.ts delete mode 100644 packages/server/src/interfaces/JournalReport.ts delete mode 100644 packages/server/src/interfaces/LandedCost.ts delete mode 100644 packages/server/src/interfaces/Ledger.ts delete mode 100644 packages/server/src/interfaces/License.ts delete mode 100644 packages/server/src/interfaces/Mailable.ts delete mode 100644 packages/server/src/interfaces/ManualJournal.ts delete mode 100644 packages/server/src/interfaces/Media.ts delete mode 100644 packages/server/src/interfaces/Metable.ts delete mode 100644 packages/server/src/interfaces/Options.ts delete mode 100644 packages/server/src/interfaces/Payment.ts delete mode 100644 packages/server/src/interfaces/PaymentReceive.ts delete mode 100644 packages/server/src/interfaces/Plaid.ts delete mode 100644 packages/server/src/interfaces/Preferences.ts delete mode 100644 packages/server/src/interfaces/ProfitLossSheet.ts delete mode 100644 packages/server/src/interfaces/Project.ts delete mode 100644 packages/server/src/interfaces/ProjectProfitabilitySummary.ts delete mode 100644 packages/server/src/interfaces/PurchasesByItemsSheet.ts delete mode 100644 packages/server/src/interfaces/Resource.ts delete mode 100644 packages/server/src/interfaces/Roles.ts delete mode 100644 packages/server/src/interfaces/SaleEstimate.ts delete mode 100644 packages/server/src/interfaces/SaleInvoice.ts delete mode 100644 packages/server/src/interfaces/SaleReceipt.ts delete mode 100644 packages/server/src/interfaces/SalesByItemsSheet.ts delete mode 100644 packages/server/src/interfaces/SalesTaxLiabilitySummary.ts delete mode 100644 packages/server/src/interfaces/Setup.ts delete mode 100644 packages/server/src/interfaces/SmsNotifications.ts delete mode 100644 packages/server/src/interfaces/StripePayment.ts delete mode 100644 packages/server/src/interfaces/Subscription.ts rename packages/{server-nest => server}/src/interfaces/SubscriptionPlan.ts (100%) delete mode 100644 packages/server/src/interfaces/Table.ts delete mode 100644 packages/server/src/interfaces/Tasks.ts delete mode 100644 packages/server/src/interfaces/TaxRate.ts delete mode 100644 packages/server/src/interfaces/Tenancy.ts rename packages/{server-nest => server}/src/interfaces/Tenant.ts (100%) delete mode 100644 packages/server/src/interfaces/Times.ts delete mode 100644 packages/server/src/interfaces/TransactionsByContacts.ts delete mode 100644 packages/server/src/interfaces/TransactionsByCustomers.ts delete mode 100644 packages/server/src/interfaces/TransactionsByReference.ts delete mode 100644 packages/server/src/interfaces/TransactionsByVendors.ts delete mode 100644 packages/server/src/interfaces/TransactionsLocking.ts delete mode 100644 packages/server/src/interfaces/TrialBalanceSheet.ts delete mode 100644 packages/server/src/interfaces/User.ts delete mode 100644 packages/server/src/interfaces/VendorBalanceSummary.ts delete mode 100644 packages/server/src/interfaces/VendorCredit.ts delete mode 100644 packages/server/src/interfaces/View.ts delete mode 100644 packages/server/src/interfaces/Warehouses.ts delete mode 100644 packages/server/src/interfaces/index.ts delete mode 100644 packages/server/src/jobs/ComputeItemCost.ts delete mode 100644 packages/server/src/jobs/OrganizationSetup.ts delete mode 100644 packages/server/src/jobs/OrganizationUpgrade.ts delete mode 100644 packages/server/src/jobs/ResetPasswordMail.ts delete mode 100644 packages/server/src/jobs/UserInviteMail.ts delete mode 100644 packages/server/src/jobs/WriteInvoicesJEntries.ts delete mode 100644 packages/server/src/lib/AccountTypes/index.ts delete mode 100644 packages/server/src/lib/Cachable/CachableModel.js delete mode 100644 packages/server/src/lib/Cachable/CachableQueryBuilder.js delete mode 100644 packages/server/src/lib/Chromiumly/Chromiumly.ts delete mode 100644 packages/server/src/lib/Chromiumly/ConvertUtils.ts delete mode 100644 packages/server/src/lib/Chromiumly/Converter.ts delete mode 100644 packages/server/src/lib/Chromiumly/GotenbergUtils.ts delete mode 100644 packages/server/src/lib/Chromiumly/HTMLConvert.ts delete mode 100644 packages/server/src/lib/Chromiumly/UrlConvert.ts delete mode 100644 packages/server/src/lib/Chromiumly/_types.ts delete mode 100644 packages/server/src/lib/DependencyGraph/index.js delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilter.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterAbstractor.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterAdvancedFilter.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterFilterRoles.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterQueryParser.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterRoleAbstractor.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterSearch.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterSortBy.ts delete mode 100644 packages/server/src/lib/DynamicFilter/DynamicFilterViews.ts delete mode 100644 packages/server/src/lib/DynamicFilter/constants.ts delete mode 100644 packages/server/src/lib/DynamicFilter/index.ts delete mode 100644 packages/server/src/lib/EventPublisher/EventPublisher.ts delete mode 100644 packages/server/src/lib/ExchangeRate/ExchangeRate.ts delete mode 100644 packages/server/src/lib/ExchangeRate/OpenExchangeRate.ts delete mode 100644 packages/server/src/lib/ExchangeRate/types.ts delete mode 100644 packages/server/src/lib/KnexFactory/index.js delete mode 100644 packages/server/src/lib/LogicEvaluation/Lexer.js delete mode 100644 packages/server/src/lib/LogicEvaluation/Parser.js delete mode 100644 packages/server/src/lib/LogicEvaluation/QueryParser.js delete mode 100644 packages/server/src/lib/Mail/index.ts delete mode 100644 packages/server/src/lib/Metable/MetableConfig.ts delete mode 100644 packages/server/src/lib/Metable/MetableModel.js delete mode 100644 packages/server/src/lib/Metable/MetableStore.ts delete mode 100644 packages/server/src/lib/Metable/MetableStoreDB.ts delete mode 100644 packages/server/src/lib/MomentFormats/index.ts delete mode 100644 packages/server/src/lib/NestedSet/NestedSetNode.js delete mode 100644 packages/server/src/lib/Plaid/Plaid.ts delete mode 100644 packages/server/src/lib/Plaid/PlaidApiEventsDBSync.ts delete mode 100644 packages/server/src/lib/Plaid/index.ts delete mode 100644 packages/server/src/lib/QueryBuilderBulkOperations/QueryBuilder.js delete mode 100644 packages/server/src/lib/S3/S3.ts delete mode 100644 packages/server/src/lib/Seeder/FsMigrations.ts delete mode 100644 packages/server/src/lib/Seeder/MigrateUtils.ts delete mode 100644 packages/server/src/lib/Seeder/SeedMigration.ts delete mode 100644 packages/server/src/lib/Seeder/Seeder.ts delete mode 100644 packages/server/src/lib/Seeder/SeederConfig.ts delete mode 100644 packages/server/src/lib/Seeder/TableUtils.ts delete mode 100644 packages/server/src/lib/Seeder/TenantSeeder.ts delete mode 100644 packages/server/src/lib/Seeder/Utils.ts delete mode 100644 packages/server/src/lib/Seeder/constants.ts delete mode 100644 packages/server/src/lib/Seeder/interfaces.ts delete mode 100644 packages/server/src/lib/Transformer/Transformer.ts delete mode 100644 packages/server/src/lib/Transformer/TransformerInjectable.ts delete mode 100644 packages/server/src/lib/ViewRolesBuilder/FilterRolesDynamicFilter.js delete mode 100644 packages/server/src/lib/ViewRolesBuilder/index.ts delete mode 100644 packages/server/src/lib/Xlsx/TableSheet.ts rename packages/{server-nest => server}/src/libs/accounts-utils/AccountTypesUtils.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/Chromiumly.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/ConvertUtils.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/Converter.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/GotenbergUtils.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/HTMLConvert.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/UrlConvert.ts (100%) rename packages/{server-nest => server}/src/libs/chromiumly/_types.ts (100%) rename packages/{server-nest => server}/src/libs/dependency-graph/index.ts (100%) rename packages/{server-nest => server}/src/libs/logic-evaluation/Lexer.ts (100%) rename packages/{server-nest => server}/src/libs/logic-evaluation/Parser.ts (100%) rename packages/{server-nest => server}/src/libs/logic-evaluation/QueryParser.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/FsMigrations.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/MigrateUtils.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/SeedMigration.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/Seeder.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/SeederConfig.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/TableUtils.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/TenantSeeder.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/Utils.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/constants.ts (100%) rename packages/{server-nest => server}/src/libs/migration-seed/interfaces.ts (100%) delete mode 100644 packages/server/src/loaders/agenda.ts delete mode 100644 packages/server/src/loaders/database.ts delete mode 100644 packages/server/src/loaders/dependencyInjector.ts delete mode 100644 packages/server/src/loaders/eventEmitter.ts delete mode 100644 packages/server/src/loaders/events.ts delete mode 100644 packages/server/src/loaders/express.ts delete mode 100644 packages/server/src/loaders/i18n.ts delete mode 100644 packages/server/src/loaders/index.ts delete mode 100644 packages/server/src/loaders/jobs.ts delete mode 100644 packages/server/src/loaders/logger.ts delete mode 100644 packages/server/src/loaders/mail.ts delete mode 100644 packages/server/src/loaders/mongoose.ts delete mode 100644 packages/server/src/loaders/rateLimiterLoader.ts delete mode 100644 packages/server/src/loaders/smsClient.ts delete mode 100644 packages/server/src/loaders/systemRepositories.ts delete mode 100644 packages/server/src/loaders/tenantCache.ts delete mode 100644 packages/server/src/loaders/tenantModels.ts delete mode 100644 packages/server/src/loaders/tenantRepositories.ts rename packages/{server-nest => server}/src/main.ts (100%) rename packages/{server-nest => server}/src/middleware/logger.middleware.ts (100%) delete mode 100644 packages/server/src/models/Account.Settings.ts delete mode 100644 packages/server/src/models/Account.ts delete mode 100644 packages/server/src/models/AccountTransaction.ts delete mode 100644 packages/server/src/models/Auth.ts delete mode 100644 packages/server/src/models/BankRule.ts delete mode 100644 packages/server/src/models/BankRuleCondition.ts delete mode 100644 packages/server/src/models/Bill.Settings.ts delete mode 100644 packages/server/src/models/Bill.ts delete mode 100644 packages/server/src/models/BillLandedCost.ts delete mode 100644 packages/server/src/models/BillLandedCostEntry.ts delete mode 100644 packages/server/src/models/BillPayment.Settings.ts delete mode 100644 packages/server/src/models/BillPayment.ts delete mode 100644 packages/server/src/models/BillPaymentEntry.ts delete mode 100644 packages/server/src/models/Branch.settings.ts delete mode 100644 packages/server/src/models/Branch.ts delete mode 100644 packages/server/src/models/CashflowAccount.Settings.ts delete mode 100644 packages/server/src/models/CashflowAccount.ts delete mode 100644 packages/server/src/models/CashflowTransaction.ts delete mode 100644 packages/server/src/models/CashflowTransactionLine.ts delete mode 100644 packages/server/src/models/Contact.ts delete mode 100644 packages/server/src/models/CreditNote.Meta.ts delete mode 100644 packages/server/src/models/CreditNote.ts delete mode 100644 packages/server/src/models/CreditNoteAppliedInvoice.ts delete mode 100644 packages/server/src/models/CreditNoteAppliedInvoiceEntry.ts delete mode 100644 packages/server/src/models/Currency.ts delete mode 100644 packages/server/src/models/CustomViewBaseModel.ts delete mode 100644 packages/server/src/models/Customer.Settings.ts delete mode 100644 packages/server/src/models/Customer.ts delete mode 100644 packages/server/src/models/DateSession.ts delete mode 100644 packages/server/src/models/Document.ts delete mode 100644 packages/server/src/models/DocumentLink.ts delete mode 100644 packages/server/src/models/ExchangeRate.ts delete mode 100644 packages/server/src/models/Expense.Settings.ts delete mode 100644 packages/server/src/models/Expense.ts delete mode 100644 packages/server/src/models/ExpenseCategory.ts delete mode 100644 packages/server/src/models/InventoryAdjustment.Settings.ts delete mode 100644 packages/server/src/models/InventoryAdjustment.ts delete mode 100644 packages/server/src/models/InventoryAdjustmentEntry.ts delete mode 100644 packages/server/src/models/InventoryCostLotTracker.ts delete mode 100644 packages/server/src/models/InventoryTransaction.ts delete mode 100644 packages/server/src/models/InventoryTransactionMeta.ts delete mode 100644 packages/server/src/models/Item.Settings.ts delete mode 100644 packages/server/src/models/Item.ts delete mode 100644 packages/server/src/models/ItemCategory.Settings.ts delete mode 100644 packages/server/src/models/ItemCategory.ts delete mode 100644 packages/server/src/models/ItemEntry.ts delete mode 100644 packages/server/src/models/ItemWarehouseQuantity.ts delete mode 100644 packages/server/src/models/ManualJournal.Settings.ts delete mode 100644 packages/server/src/models/ManualJournal.ts delete mode 100644 packages/server/src/models/ManualJournalEntry.ts delete mode 100644 packages/server/src/models/MatchedBankTransaction.ts delete mode 100644 packages/server/src/models/Media.ts delete mode 100644 packages/server/src/models/MediaLink.ts delete mode 100644 packages/server/src/models/Metable.ts delete mode 100644 packages/server/src/models/ModelSearchable.ts delete mode 100644 packages/server/src/models/ModelSetting.ts delete mode 100644 packages/server/src/models/Option.ts delete mode 100644 packages/server/src/models/Pagination.ts delete mode 100644 packages/server/src/models/PaymentIntegration.ts delete mode 100644 packages/server/src/models/PaymentReceive.Settings.ts delete mode 100644 packages/server/src/models/PaymentReceive.ts delete mode 100644 packages/server/src/models/PaymentReceiveEntry.ts delete mode 100644 packages/server/src/models/PdfTemplate.ts delete mode 100644 packages/server/src/models/PlaidItem.ts delete mode 100644 packages/server/src/models/Project.ts delete mode 100644 packages/server/src/models/ProjectItemEntryRef.ts delete mode 100644 packages/server/src/models/RecognizedBankTransaction.ts delete mode 100644 packages/server/src/models/RefundCreditNote.ts delete mode 100644 packages/server/src/models/RefundVendorCredit.ts delete mode 100644 packages/server/src/models/ResourcableModel.ts delete mode 100644 packages/server/src/models/Role.ts delete mode 100644 packages/server/src/models/RolePermission.ts delete mode 100644 packages/server/src/models/SaleEstimate.Settings.ts delete mode 100644 packages/server/src/models/SaleEstimate.ts delete mode 100644 packages/server/src/models/SaleEstimateEntry.ts delete mode 100644 packages/server/src/models/SaleInvoice.Settings.ts delete mode 100644 packages/server/src/models/SaleInvoice.ts delete mode 100644 packages/server/src/models/SaleInvoiceEntry.ts delete mode 100644 packages/server/src/models/SaleReceipt.Settings.ts delete mode 100644 packages/server/src/models/SaleReceipt.ts delete mode 100644 packages/server/src/models/SaleReceiptEntry.ts delete mode 100644 packages/server/src/models/Setting.ts delete mode 100644 packages/server/src/models/Task.ts delete mode 100644 packages/server/src/models/TaxRate.settings.ts delete mode 100644 packages/server/src/models/TaxRate.ts delete mode 100644 packages/server/src/models/TaxRateTransaction.ts delete mode 100644 packages/server/src/models/TenantModel.ts delete mode 100644 packages/server/src/models/Time.ts delete mode 100644 packages/server/src/models/TransactionPaymentServiceEntry.ts delete mode 100644 packages/server/src/models/UncategorizedCashflowTransaction.meta.ts delete mode 100644 packages/server/src/models/UncategorizedCashflowTransaction.ts delete mode 100644 packages/server/src/models/User.ts delete mode 100644 packages/server/src/models/Vendor.Settings.ts delete mode 100644 packages/server/src/models/Vendor.ts delete mode 100644 packages/server/src/models/VendorCredit.Meta.ts delete mode 100644 packages/server/src/models/VendorCredit.ts delete mode 100644 packages/server/src/models/VendorCreditAppliedBill.ts delete mode 100644 packages/server/src/models/View.ts delete mode 100644 packages/server/src/models/ViewColumn.ts delete mode 100644 packages/server/src/models/ViewRole.ts delete mode 100644 packages/server/src/models/Warehouse.settings.ts delete mode 100644 packages/server/src/models/Warehouse.ts delete mode 100644 packages/server/src/models/WarehouseTransfer.Settings.ts delete mode 100644 packages/server/src/models/WarehouseTransfer.ts delete mode 100644 packages/server/src/models/WarehouseTransferEntry.ts delete mode 100644 packages/server/src/models/index.ts rename packages/{server-nest => server}/src/modules/Accounts/Account.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/AccountTransaction.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/Accounts.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/Accounts.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/Accounts.module.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/Accounts.types.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/AccountsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/AccountsExportable.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/AccountsImportable.SampleData.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/AccountsImportable.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/ActivateAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/CommandAccountValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/CreateAccount.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/CreateAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/DeleteAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/EditAccount.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/EditAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/GetAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/GetAccountTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/GetAccountTypes.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/GetAccounts.service.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/MutateBaseCurrencyAccounts.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/models/Account.model.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/models/AccountTransaction.model.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/repositories/Account.repository.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts (100%) rename packages/{server-nest => server}/src/modules/Accounts/utils/AccountType.utils.ts (100%) rename packages/{server-nest => server}/src/modules/App/App.controller.spec.ts (100%) rename packages/{server-nest => server}/src/modules/App/App.controller.ts (100%) rename packages/{server-nest => server}/src/modules/App/App.module.ts (100%) rename packages/{server-nest => server}/src/modules/App/App.service.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/Attachment.module.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/Attachment.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/AttachmentTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/Attachments.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/Attachments.types.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/AttachmentsApplication.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/DeleteAttachment.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/GetAttachment.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/GetAttachmentPresignedUrl.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/LinkAttachment.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/S3UploadPipeline.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/UnlinkAttachment.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/UploadDocument.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/ValidateAttachments.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/decorators/InjectAttachable.decorator.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/dtos/Attachment.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnBills.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnCreditNote.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnExpenses.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnManualJournals.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnPaymentsMade.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnPaymentsReceived.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnSaleEstimates.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnSaleInvoice.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnSaleReceipts.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/events/AttachmentsOnVendorCredits.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/models/Document.model.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/models/DocumentLink.model.ts (100%) rename packages/{server-nest => server}/src/modules/Attachments/utils.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/Auth.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/Auth.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/Auth.interfaces.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/Auth.module.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/Auth.utils.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/AuthApplication.sevice.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/AuthMailMessages.esrvice.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/commands/AuthResetPassword.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/commands/AuthSendResetPassword.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/commands/AuthSignin.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/commands/AuthSignup.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/commands/AuthSignupConfirm.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/commands/AuthSignupConfirmResend.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/dtos/AuthSignin.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/dtos/AuthSignup.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/guards/Local.guard.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/guards/jwt.guard.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/models/PasswordReset.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/processors/SendResetPasswordMail.processor.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/processors/SendSignupVerificationMail.processor.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/queries/GetAuthMeta.service.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/strategies/Jwt.strategy.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/strategies/Local.strategy.ts (100%) rename packages/{server-nest => server}/src/modules/Auth/subscribers/AuthMail.subscriber.ts (100%) rename packages/{server-nest => server}/src/modules/AutoIncrementOrders/AutoIncrementOrders.module.ts (100%) rename packages/{server-nest => server}/src/modules/AutoIncrementOrders/AutoIncrementOrders.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/BankRules.controller.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/BankRules.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/BankRulesApplication.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/commands/CreateBankRule.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/commands/DeleteBankRule.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/commands/DeleteBankRules.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/commands/EditBankRule.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/dtos/BankRule.dto.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/events/UnlinkBankRuleOnDeleteBankRule.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/models/BankRule.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/models/BankRuleCondition.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/queries/GetBankRule.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/queries/GetBankRuleTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/queries/GetBankRules.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/queries/GetBankRulesTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankRules/types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/BankAccounts.controller.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/BankAccounts.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/BankAccountsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/commands/DisconnectBankAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/commands/PauseBankAccountFeeds.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/commands/RefreshBankAccount.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/commands/ResumeBankAccountFeeds.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/queries/GetBankAccountSummary.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/subscribers/DeleteUncategorizedTransactionsOnAccountDeleting.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/subscribers/DisconnectPlaidItemOnAccountDeleted.ts (100%) rename packages/{server-nest => server}/src/modules/BankingAccounts/types/BankAccounts.types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/BankingCategorize.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/CategorizeCashflowTransaction.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/CategorizeTransactionAsExpense.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/CreateUncategorizedTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/UncategorizeCashflowTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/UncategorizeCashflowTransactionsBulk.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/UncategorizedTransaction.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/commands/UncategorizedTransactionsImportable.ts (100%) rename packages/{server-nest => server}/src/modules/BankingCategorize/types/BankingCategorize.types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/BankingMatching.controller.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/BankingMatching.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/BankingMatchingApplication.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/commands/MatchTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/commands/MatchTransactionsTypes.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/commands/MatchTransactionsTypesRegistry.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/commands/UnmatchMatchedTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/commands/ValidateTransactionsMatched.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/events/DecrementUncategorizedTransactionsOnMatch.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/events/ValidateMatchingOnCashflowDelete.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/events/ValidateMatchingOnExpenseDelete.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/events/ValidateMatchingOnManualJournalDelete.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/events/ValidateMatchingOnPaymentMadeDelete.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/events/ValidateMatchingOnPaymentReceivedDelete.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/models/MatchedBankTransaction.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionBillsTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionCashflowTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionExpensesTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionInvoicesTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionManualJournalsTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionsByCashflow.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionsByExpenses.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionsByInvoices.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionsByManualJournals.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/queries/GetMatchedTransactionsByType.ts (100%) rename packages/{server-nest => server}/src/modules/BankingMatching/types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/BankingPlaid.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/PlaidApplication.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/PlaidWebhookTenantBootMiddleware.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/command/PlaidItem.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/command/PlaidSyncDB.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/command/PlaidUpdateTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/command/PlaidWebhooks.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/jobs/PlaidFetchTransactionsJob.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/models/PlaidItem.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/models/SystemPlaidItem.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/queries/GetPlaidLinkToken.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/subscribers/RecognizeSyncedBankTransactions.subscriber.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/types/BankingPlaid.types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingPlaid/utils.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/_types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/jobs/RerecognizeTransactionsJob.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/jobs/RevertRecognizedTransactionsJob.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/models/RecognizedBankTransaction.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransactionTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/BankingTransactions.controller.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/BankingTransactions.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/BankTransactionAutoIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/BankTransactionGL.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/BankTransactionGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/CommandCasflowValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/DeleteCashflowTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/RemovePendingUncategorizedTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/commands/ValidateDeleteBankAccountTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/constants.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/models/BankAccount.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/models/BankTransaction.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/models/BankTransactionLine.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/models/UncategorizedBankTransaction.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/BankAccountTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/BankTransactionTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/BankTransactionsTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetBankAccounts.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetBankTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetPendingBankAccountTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetPendingBankAccountTransactionTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetRecognizedTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetRecognizedTransactionTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetRecongizedTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetUncategorizedBankTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/queries/GetUncategorizedTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/subscribers/CashflowTransactionSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/subscribers/CashflowWithAccountSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/subscribers/DecrementUncategorizedTransactionOnCategorize.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/subscribers/DeleteCashflowTransactionOnUncategorize.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/subscribers/PreventDeleteTransactionsOnDelete.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/types/BankingTransactions.types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactions/utils.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.controller.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.module.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/ExcludeBankTransactionsApplication.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/commands/utils.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/queries/GetExcludedBankTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/types/BankTransactionsExclude.types.ts (100%) rename packages/{server-nest => server}/src/modules/BankingTransactionsExclude/utils.ts (100%) rename packages/{server-nest => server}/src/modules/BillLandedCosts/BillLandedCosts.module.ts (100%) rename packages/{server-nest => server}/src/modules/BillLandedCosts/TransactionLandedCostEntries.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillLandedCosts/models/BillLandedCost.ts (100%) rename packages/{server-nest => server}/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts (100%) rename packages/{server-nest => server}/src/modules/BillLandedCosts/types/BillLandedCosts.types.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/BillPayments.controller.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/BillPayments.module.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/BillPaymentsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/GetBillPayments.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentExportable.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentGL.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentsImportable.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/BillPaymentsPages.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/CreateBillPayment.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/DeleteBillPayment.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/commands/EditBillPayment.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/constants.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/dtos/BillPayment.dto.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/models/BillPayment.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/models/BillPaymentEntry.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/queries/BillPaymentEntry.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/queries/BillPaymentTransactionTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/queries/BillPaymentTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/queries/GetBillPayment.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/queries/GetPaymentBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/subscribers/BillPaymentGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/BillPayments/types/BillPayments.types.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/Bills.application.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/Bills.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/Bills.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/Bills.module.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/Bills.types.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillDTOTransformer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillPaymentsGLEntriesRewrite.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillPaymentsGLEntriesRewriteSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillsExportable.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillsGL.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillsGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillsImportable.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/BillsValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/CreateBill.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/DeleteBill.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/EditBill.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/commands/OpenBill.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/dtos/Bill.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/models/Bill.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/queries/Bill.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/queries/GetBill.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/queries/GetBillPayments.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/queries/GetBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/queries/GetDueBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/subscribers/BillGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Bills/subscribers/BillWriteInventoryTransactionsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/BranchIntegrationErrorsMiddleware.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/Branches.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/Branches.module.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/Branches.types.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/BranchesApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/BranchesSettings.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/CRUDBranch.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/EventsProvider.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/commands/ActivateBranchesFeature.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/commands/BranchCommandValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/commands/CreateBranch.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/commands/DeleteBranch.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/commands/EditBranch.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/commands/MarkBranchAsPrimary.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/dtos/Branch.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/BranchTransactionDTOTransform.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Cashflow/CashflowActivateBranches.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Expense/ExpensesActivateBranches.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/ManualJournals/ManualJournalBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/ManualJournals/ManualJournalDTOTransformer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/ManualJournals/ManualJournalsBranchesValidator.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/ManualJournals/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Purchases/BillBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Purchases/PaymentMadeBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Purchases/VendorCreditBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Sales/CreditNoteBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Sales/PaymentReceiveBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Sales/SaleEstimatesBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Sales/SaleInvoiceBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/Sales/SaleReceiptBranchesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/ValidateBranchExistance.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/integrations/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/models/Branch.model.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/queries/GetBranch.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/queries/GetBranches.service.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/CashflowBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/ExpenseBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/BillBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/CreditNoteBranchesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/CreditNoteRefundBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/ExpenseBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/InvoiceBranchValidatorSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/ManualJournalBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/PaymentMadeBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/PaymentReceiveBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/SaleReceiptBranchesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/VendorCreditBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Branches/subscribers/Validators/VendorCreditRefundBranchSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/ChromiumlyTenancy/ChromiumlyHtmlConvert.service.ts (100%) rename packages/{server-nest => server}/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.module.ts (100%) rename packages/{server-nest => server}/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.service.ts (100%) rename packages/{server-nest => server}/src/modules/ChromiumlyTenancy/models/Document.ts (100%) rename packages/{server-nest => server}/src/modules/ChromiumlyTenancy/models/DocumentLink.ts (100%) rename packages/{server-nest => server}/src/modules/ChromiumlyTenancy/utils.ts (100%) rename packages/{server-nest => server}/src/modules/Contacts/Contact.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Contacts/models/Contact.ts (100%) rename packages/{server-nest => server}/src/modules/Contacts/types/Contacts.types.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/commands/DeleteRefundCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/commands/RefundCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/commands/RefundSyncCreditNoteBalance.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/queries/GetCreditNoteRefunds.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/queries/GetRefundCreditNoteTransaction.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/CreditNoteApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/CreditNotes.controller.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/CreditNotes.module.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreateCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreditNoteAutoIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreditNoteGL.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreditNoteGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreditNotesExportable.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreditNotesImportable.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/CreditNotesInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/DeleteCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/EditCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/commands/OpenCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/constants.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/dtos/CreditNote.dto.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/models/CreditNote.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/CreditNoteTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/GetCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/GetCreditNotePdf.serivce.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/GetCreditNoteState.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/GetCreditNotes.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/queries/RefundCreditNoteTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/subscribers/CreditNoteGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/subscribers/CreditNoteInventoryTransactionsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/types/CreditNotes.types.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotes/utils.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncInvoices.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/commands/DeleteCustomerLinkedCreditNote.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/queries/CreditNoteAppliedInvoiceTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/queries/CreditNoteWithInvoicesToApplyTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedAppliedInvoices.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedInvoicesToApply.service.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts (100%) rename packages/{server-nest => server}/src/modules/CustomViews/CustomViewBaseModel.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/CustomerGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/CustomerGLEntriesStorage.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/Customers.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/Customers.module.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/CustomersApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/CustomersExportable.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/CustomersImportable.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/_SampleData.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/ActivateCustomer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/CreateCustomer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/CreateEditCustomerDTO.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/CustomerValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/DeleteCustomer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/EditCustomer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/commands/EditOpeningBalanceCustomer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/dtos/ContactAddress.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/dtos/CreateCustomer.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/dtos/EditCustomer.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/models/Customer.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/queries/CustomerTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/queries/GetCustomer.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/queries/GetCustomers.service.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/subscribers/CustomerGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Customers/types/Customers.types.ts (100%) rename packages/{server-nest => server}/src/modules/Dashboard/Dashboard.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Dashboard/Dashboard.module.ts (100%) rename packages/{server-nest => server}/src/modules/Dashboard/Dashboard.service.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilter.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilter.types.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterAbstractor.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterAdvancedFilter.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterFilterRoles.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterQueryParser.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterRoleAbstractor.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterSearch.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterSortBy.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/DynamicFilterViews.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/constants.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicFilter/index.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicList.module.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicList.service.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicListCustomView.service.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicListFilterRoles.service.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicListSearch.service.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicListServiceAbstract.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/DynamicListSortBy.service.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/constants.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/models/CustomViewBaseModel.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/models/MetadataModel.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/models/SearchableBaseModel.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/types/DynamicList.types.ts (100%) rename packages/{server-nest => server}/src/modules/DynamicListing/validators.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/EventTracker.module.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/EventTracker.service.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/PostHog.constants.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/event-tracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/AccountEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/AuthenticationEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/BankRuleEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/BankTransactionEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/BillEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/CustomerEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/ExpenseEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/ItemEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/ManualJournalEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/PaymentLinkEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/PaymentMadeEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/PaymentMethodEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/PaymentReceivedEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/PdfTemplateEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/ReportsEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/SaleEstimateEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/SaleInvoicesEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/StripeIntegrationEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/SubscriptionEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/TransactionsLockingEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/events/VendorEventsTracker.ts (100%) rename packages/{server-nest => server}/src/modules/EventsTracker/postHog.module.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/Expenses.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/Expenses.module.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/Expenses.types.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/ExpensesApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/ExpensesExportable.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/ExpensesImportable.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/commands/CommandExpenseDTO.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/commands/CommandExpenseValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/commands/CreateExpense.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/commands/DeleteExpense.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/commands/EditExpense.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/commands/PublishExpense.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/dtos/Expense.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/interfaces/Expenses.interface.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/models/Expense.model.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/models/ExpenseCategory.model.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/queries/Expense.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/queries/ExpenseCategory.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/queries/GetExpense.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/queries/GetExpenses.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/subscribers/ExpenseGL.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/subscribers/ExpenseGLEntries.service.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/subscribers/ExpenseGLEntries.subscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Expenses/subscribers/ExpenseGLEntriesStorage.sevice.ts (100%) rename packages/{server-nest => server}/src/modules/Export/Export.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Export/Export.module.ts (100%) rename packages/{server-nest => server}/src/modules/Export/ExportAls.ts (100%) rename packages/{server-nest => server}/src/modules/Export/ExportApplication.ts (100%) rename packages/{server-nest => server}/src/modules/Export/ExportPdf.ts (100%) rename packages/{server-nest => server}/src/modules/Export/ExportRegistery.ts (100%) rename packages/{server-nest => server}/src/modules/Export/ExportResources.ts (100%) rename packages/{server-nest => server}/src/modules/Export/ExportService.ts (100%) rename packages/{server-nest => server}/src/modules/Export/Exportable.ts (100%) rename packages/{server-nest => server}/src/modules/Export/common.ts (100%) rename packages/{server-nest => server}/src/modules/Export/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Export/dtos/ExportQuery.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Export/utils.ts (100%) rename packages/{server-nest => server}/src/modules/Features/Features.module.ts (100%) rename packages/{server-nest => server}/src/modules/Features/FeaturesConfigure.ts (100%) rename packages/{server-nest => server}/src/modules/Features/FeaturesConfigureManager.ts (100%) rename packages/{server-nest => server}/src/modules/Features/FeaturesManager.ts (100%) rename packages/{server-nest => server}/src/modules/Features/FeaturesSettingsDriver.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/FinancialStatements.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialDateRanges.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialEvaluateEquation.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialFilter.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialHorizTotals.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialPreviousPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialPreviousYear.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialReportService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialSchema.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialSheetCommon.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialSheetStructure.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialTablePreviousPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialTablePreviousYear.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/FinancialTableStructure.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/TableSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/common/TableSheetPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryPdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummarySheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/APAgingSummary/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryPdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummarySheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ARAgingSummary/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/AgingReport.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/AgingSummary/_constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAccounts.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAggregators.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetBase.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousYear.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetFiltering.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncome.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePP.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePY.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPercentage.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetQuery.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepositoryNetIncome.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetSchema.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePercentage.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousYear.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTotal.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/BalanceSheet/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlow.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatement.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementBase.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CashFlowStatement/schema.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/CustomerBalanceSummary/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerExport.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/GeneralLedger/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.service.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTablePdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryItemDetails/constant.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetExportable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/InventoryValuationSheet/_constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetExport.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetPdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/constant.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/JournalSheet/types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSchema.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetBase.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetFilter.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPercentage.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousYear.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetQuery.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTablePercentage.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousYear.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/ProfitLossSheet/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.service.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsExport.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/_types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/types/PurchasesByItems.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/PurchasesByItems/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsExport.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsPdfInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesByItems/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/_constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactTableRows.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomers.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByCustomer/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionByReference.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.service.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceReport.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByReference/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TransactionsByVendor/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/_constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/_types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/TrialBalanceSheet/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.module.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryApplication.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryMeta.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryPdf.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryRepository.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryService.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/constants.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/modules/VendorBalanceSummary/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/types/Report.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/types/Table.types.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/utils.ts (100%) rename packages/{server-nest => server}/src/modules/FinancialStatements/utils/Table.utils.ts (100%) rename packages/{server-nest => server}/src/modules/Import/Import.module.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportALS.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileCommon.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileDataTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileDataValidator.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileMapping.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileMeta.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileMetaTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFilePreview.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileProcess.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileProcessCommit.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportFileUpload.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportRemoveExpiredFiles.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportResource.module.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportResourceApplication.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportSample.ts (100%) rename packages/{server-nest => server}/src/modules/Import/Importable.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportableRegistry.ts (100%) rename packages/{server-nest => server}/src/modules/Import/ImportableResources.ts (100%) rename packages/{server-nest => server}/src/modules/Import/_constants.ts (100%) rename packages/{server-nest => server}/src/modules/Import/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/Import/interfaces.ts (100%) rename packages/{server-nest => server}/src/modules/Import/jobs/ImportDeleteExpiredFilesJob.ts (100%) rename packages/{server-nest => server}/src/modules/Import/models/Import.ts (100%) rename packages/{server-nest => server}/src/modules/Import/sheet_utils.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/InventoryAdjustmentTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/InventoryAdjustments.module.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/commands/DeleteInventoryAdjustment.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/commands/PublishInventoryAdjustment.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentGL.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/constants/InventoryAdjustments.constants.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactionsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/queries/GetInventoryAdjustment.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/queries/GetInventoryAdjustments.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/subscribers/InventoryAdjustmentGL.subscriber.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/InventoryCost.module.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/InventoryCostApplication.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryAverageCostMethod.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryAverageCostMethod.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryComputeCost.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryCostGLStorage.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryCosts.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryItemOpeningAvgCost.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryItemsQuantitySync.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/InventoryTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/commands/StoreInventortyLotsCost.service.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/models/InventoryCostLotTracker.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/models/InventoryTransaction.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/models/InventoryTransactionMeta.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/processors/ComputeItemCost.processor.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/processors/WriteInventoryTransactionsGLEntries.processor.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/subscribers/InventoryCost.subscriber.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/subscribers/InventoryCostGLBeforeWriteSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/types/InventoryCost.types.ts (100%) rename packages/{server-nest => server}/src/modules/InventoryCost/utils.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/ItemCategoriesExportable.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/ItemCategoriesImportable.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/ItemCategory.application.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/ItemCategory.controller.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/ItemCategory.interfaces.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/ItemCategory.module.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/commands/CommandItemCategoryValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/commands/CreateItemCategory.service.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/commands/DeleteItemCategory.service.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/commands/EditItemCategory.service.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/constants.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/dtos/ItemCategory.dto.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/models/ItemCategory.model.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/queries/GetItemCategories.service.ts (100%) rename packages/{server-nest => server}/src/modules/ItemCategories/queries/GetItemCategory.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ActivateItem.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/CreateItem.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/DeleteItem.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/EditItem.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/GetItem.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/GetItems.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/InactivateItem.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/Item.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Items/Item.schema.ts (100%) rename packages/{server-nest => server}/src/modules/Items/Item.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemBillsTransactions.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemEstimatesTransaction.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemInvoicesTransactions.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemReceiptsTransactions.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/Items.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Items/Items.module.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ItemsEntries.service.ts (100%) rename packages/{server-nest => server}/src/modules/Items/ServiceError.ts (100%) rename packages/{server-nest => server}/src/modules/Items/dtos/Item.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Items/events/ItemCreated.event.ts (100%) rename packages/{server-nest => server}/src/modules/Items/listeners/ItemCreated.listener.ts (100%) rename packages/{server-nest => server}/src/modules/Items/models/Item.ts (100%) rename packages/{server-nest => server}/src/modules/Items/types/Items.types.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/JournalEntry.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/Ledger.module.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/Ledger.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/LedgerContactStorage.service.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/LedgerEntriesStorage.service.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/LedgerStorage.service.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/LedgerStorageRevert.service.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/LedgetAccountStorage.service.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/types/Ledger.types.ts (100%) rename packages/{server-nest => server}/src/modules/Ledger/utils.ts (100%) rename packages/{server-nest => server}/src/modules/Loops/Loops.module.ts (100%) rename packages/{server-nest => server}/src/modules/Loops/LoopsEvents.subscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Mail/Mail.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Mail/Mail.module.ts (100%) rename packages/{server-nest => server}/src/modules/Mail/Mail.ts (100%) rename packages/{server-nest => server}/src/modules/Mail/Mail.types.ts (100%) rename packages/{server-nest => server}/src/modules/Mail/MailTransporter.service.ts (100%) rename packages/{server-nest => server}/src/modules/MailNotification/ContactMailNotification.ts (100%) rename packages/{server-nest => server}/src/modules/MailNotification/MailNotification.module.ts (100%) rename packages/{server-nest => server}/src/modules/MailNotification/MailNotification.types.ts (100%) rename packages/{server-nest => server}/src/modules/MailNotification/constants.ts (100%) rename packages/{server-nest => server}/src/modules/MailNotification/utils.ts (100%) rename packages/{server-nest => server}/src/modules/MailTenancy/MailTenancy.module.ts (100%) rename packages/{server-nest => server}/src/modules/MailTenancy/MailTenancy.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/ManualJournals.controller.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/ManualJournals.module.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/ManualJournalsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/AutoIncrementManualJournal.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/CommandManualJournalValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/CreateManualJournal.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/DeleteManualJournal.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/EditManualJournal.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/ManualJournalExportable.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/ManualJournalGL.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/ManualJournalGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/ManualJournalGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/ManualJournalsImport.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/commands/PublishManualJournal.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/constants.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/dtos/ManualJournal.dto.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/models/ManualJournal.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/models/ManualJournalEntry.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/queries/GetManualJournal.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/queries/GetManualJournals.service.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/queries/ManualJournalTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/ManualJournals/types/ManualJournals.types.ts (100%) rename packages/{server-nest => server}/src/modules/Metable/MetableConfig.ts (100%) rename packages/{server-nest => server}/src/modules/Metable/MetableModel.ts (100%) rename packages/{server-nest => server}/src/modules/Metable/MetableStore.ts (100%) rename packages/{server-nest => server}/src/modules/Metable/MetableStoreDB.ts (100%) rename packages/{server-nest => server}/src/modules/Metable/types.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization.module.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization.types.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization.utils.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization/OrganizationBaseCurrencyLocking.service.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization/OrganizationUpgrade.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/Organization/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/commands/BuildOrganization.service.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/commands/CommandOrganizationValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/commands/UpdateOrganization.service.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/dtos/Organization.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/processors/OrganizationBuild.processor.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/queries/GetCurrentOrganization.service.ts (100%) rename packages/{server-nest => server}/src/modules/Organization/queries/GetOrganizationBaseCurrencyLock.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/CreateInvoiceCheckoutSession.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/GetInvoicePaymentLinkMetadata.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/GetPaymentLinkInvoicePdf.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/PaymentLinks.controller.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/PaymentLinks.module.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/PaymentLinksApplication.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentLinks/models/PaymentLink.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/PaymentReceived.application.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/PaymentsReceived.controller.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/PaymentsReceived.module.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/DeletePaymentReceived.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedDTOTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedGL.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedInvoiceSync.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedMailNotification.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedMailNotificationJob.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedSmsNotify.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/constants.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/models/PaymentReceived.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/models/PaymentReceivedEntry.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/processors/PaymentReceivedMailNotification.processor.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/GetPaymentReceived.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/GetPaymentReceivedInvoices.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/GetPaymentReceivedPdf.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/GetPaymentReceivedState.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/GetPaymentsReceived.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/PaymentReceivedEntryTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/PaymentReceivedTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/queries/PaymentsReceivedPages.service.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/subscribers/PaymentReceivedAutoIncrementSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/subscribers/PaymentReceivedGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsNotificationSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/subscribers/PaymentReceivedSyncInvoices.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/types/PaymentReceived.types.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentReceived/utils.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/PaymentServices.controller.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/PaymentServices.module.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/PaymentServicesApplication.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/commands/DeletePaymentMethodService.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/commands/EditPaymentMethodService.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/models/PaymentIntegration.model.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/models/TransactionPaymentServiceEntry.model.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/queries/GetPaymentMethodsState.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/queries/GetPaymentService.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoice.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoiceTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/types.ts (100%) rename packages/{server-nest => server}/src/modules/PaymentServices/utils.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/BrandingTemplateDTOTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/GetPdfTemplateBrandingState.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/PdfTemplate.application.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/PdfTemplates.controller.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/PdfTemplates.module.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/commands/AssignPdfTemplateDefault.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/commands/CreatePdfTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/commands/DeletePdfTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/commands/EditPdfTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/dtos/PdfTemplate.dto.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/models/PdfTemplate.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/queries/GetPdfTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/queries/GetPdfTemplate.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/queries/GetPdfTemplates.service.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/queries/GetPdfTemplates.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/PdfTemplate/types.ts (100%) rename packages/{server-nest => server}/src/modules/Plaid/Plaid.module.ts (100%) rename packages/{server-nest => server}/src/modules/Resource/Resource.module.ts (100%) rename packages/{server-nest => server}/src/modules/Resource/ResourceService.ts (100%) rename packages/{server-nest => server}/src/modules/Resource/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/Resource/models/ResourcableModel.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/AbilitySchema.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/Authorization.guard.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/Roles.application.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/Roles.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/Roles.module.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/Roles.types.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/Roles.utils.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/TenantAbilities.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/commands/CreateRole.service.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/commands/DeleteRole.service.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/commands/EditRole.service.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/dtos/Role.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/models/Role.model.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/models/RolePermission.model.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/queries/GetRole.service.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/queries/GetRoles.service.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/queries/RolePermissionsSchema.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/queries/RoleTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Roles/utils.ts (100%) rename packages/{server-nest => server}/src/modules/S3/S3.module.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/SaleEstimates.application.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/SaleEstimates.controller.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/SaleEstimates.module.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/SaleEstimatesExportable.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/SaleEstimatesImportable.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/ApproveSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/ConvetSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/DeleteSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/DeliverSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/RejectSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/SaleEstimateIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/SaleEstimateSmsNotify.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/SaleEstimateValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/SendSaleEstimateMail.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/SendSaleEstimateMailJob.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/commands/UnlinkConvertedSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/constants.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/models/SaleEstimate.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/processes/SendSaleEstimateMail.process.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/queries/GetSaleEstimate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/queries/GetSaleEstimatePdf.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/queries/GetSaleEstimateState.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/queries/GetSaleEstimates.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/queries/SaleEstimate.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/types/SaleEstimates.types.ts (100%) rename packages/{server-nest => server}/src/modules/SaleEstimates/utils.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/InvoiceInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/InvoicePaymentsGLRewrite.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SaleInvoice.types.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SaleInvoiceCostGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SaleInvoiceNotifyBySms.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SaleInvoices.application.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SaleInvoices.controller.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SaleInvoices.module.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/SalesInvoicesCost.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/CommandSaleInvoiceValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/DeleteSaleInvoice.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/DeliverSaleInvoice.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/GenerateInvoicePaymentLink.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/GeneratePaymentLink.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SaleInvoiceIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SendInvoiceInvoiceMailCommon.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SendSaleInvoiceMail.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SendSaleInvoiceMailJob.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/SendSaleInvoiceMailReminderJob.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/WriteoffSaleInvoice.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/inventory/InvoiceInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGL.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGLStorage.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/constants.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/ledger/InvoiceGL.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/ledger/InvoiceGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/models/SaleInvoice.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/processors/SendSaleInvoiceMail.processor.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetInvoicePaymentLink.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetInvoicePaymentMail.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetInvoicePaymentMailAttributes.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetInvoicePayments.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoiceMailReminder.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoiceState.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoices.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/GetSaleInvoicesPayable.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/InvoicePaymentTransaction.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/SaleInvoice.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/SaleInvoicePdf.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/queries/SaleInvoiceTaxEntry.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/InvoiceCostGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/InvoiceGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/InvoicePaymentIntegrationSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/InvoiceWriteInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/subscribers/SaleInvoiceWriteoffSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleInvoices/utils.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/SaleReceiptApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/SaleReceipts.controller.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/SaleReceipts.module.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/CloseSaleReceipt.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/DeleteSaleReceipt.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptCostGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptMailNotification.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptMailNotificationJob.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptNotifyBySms.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptValidators.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/commands/SaleReceiptsImportable.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/constants.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/inventory/SaleReceiptInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/inventory/SaleReceiptWriteInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/ledger/SaleReceiptGL.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/ledger/SaleReceiptGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/models/SaleReceipt.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/processes/SendSaleReceiptMail.process.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/queries/GetSaleReceipt.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/queries/GetSaleReceiptState.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/queries/GetSaleReceipts.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/queries/SaleReceiptBrandingTemplate.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/queries/SaleReceiptTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/queries/SaleReceiptsPdf.service.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/subscribers/SaleReceiptGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/types/SaleReceipts.types.ts (100%) rename packages/{server-nest => server}/src/modules/SaleReceipts/utils.ts (100%) rename packages/{server-nest => server}/src/modules/Search/SearchableMdel.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/ModelSettings.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/Settings.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/Settings.module.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/Settings.types.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/SettingsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/SettingsStore.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/commands/SaveSettings.service.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/models/Setting.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/queries/GetSettings.service.ts (100%) rename packages/{server-nest => server}/src/modules/Settings/repositories/Setting.repository.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/CreateStripeAccountLink.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/CreateStripeAccountService.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/ExchangeStripeOauthToken.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/GetStripeAuthorizationLink.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/StripePayment.controller.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/StripePayment.module.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/StripePayment.types.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/StripePaymentApplication.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/StripePaymentService.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/models/PaymentIntegration.model.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/subscribers/SeedStripeAccounts.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/StripePayment/types.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/Subscription.module.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/SubscriptionApplication.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/SubscriptionPeriod.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/Subscriptions.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/SubscriptionsLemonWebhook.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/CancelLemonSubscription.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/ChangeLemonSubscription.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/MarkSubscriptionCanceled.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/MarkSubscriptionChanged.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/MarkSubscriptionPaymentFailed.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/MarkSubscriptionPaymentSuccessed.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/MarkSubscriptionResumed.sevice.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/NewSubscription.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/commands/ResumeLemonSubscription.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/exceptions/NotAllowedChangeSubscriptionPlan.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/interceptors/Subscription.guard.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/models/Plan.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/models/PlanSubscription.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/queries/GetLemonSqueezyCheckout.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/queries/GetSubscriptions.service.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/queries/GetSubscriptionsTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/repositories/PlanSubscription.repository.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/subscribers/SubscribeFreeOnSignupCommunity.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/subscribers/TriggerInvalidateCacheOnSubscriptionChange.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/types.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/utils.ts (100%) rename packages/{server-nest => server}/src/modules/Subscription/webhooks/LemonSqueezyWebhooks.ts (100%) rename packages/{server-nest => server}/src/modules/System/SystemDB/SystemDB.constants.ts (100%) rename packages/{server-nest => server}/src/modules/System/SystemDB/SystemDB.controller.ts (100%) rename packages/{server-nest => server}/src/modules/System/SystemDB/SystemDB.module.ts (100%) rename packages/{server-nest => server}/src/modules/System/SystemModels/SystemModels.constants.ts (100%) rename packages/{server-nest => server}/src/modules/System/SystemModels/SystemModels.module.ts (100%) rename packages/{server-nest => server}/src/modules/System/models/SystemModel.ts (100%) rename packages/{server-nest => server}/src/modules/System/models/SystemUser.ts (100%) rename packages/{server-nest => server}/src/modules/System/models/TenantBaseModel.ts (100%) rename packages/{server-nest => server}/src/modules/System/models/TenantMetadataModel.ts (100%) rename packages/{server-nest => server}/src/modules/System/models/TenantModel.ts (100%) rename packages/{server-nest => server}/src/modules/System/repositories/Tenant.repository.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/ItemEntriesTaxTransactions.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/SyncItemTaxRateOnEditTaxRate.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRate.application.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRate.controller.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRate.module.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRates.types.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRatesExportable.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRatesImportable.SampleData.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/TaxRatesImportable.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/commands/ActivateTaxRate.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/commands/CreateTaxRate.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/commands/DeleteTaxRate.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/commands/EditTaxRate.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/commands/InactivateTaxRate.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/constants.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/dtos/TaxRate.dto.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/models/TaxRate.model.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/models/TaxRateTransaction.model.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/queries/GetTaxRate.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/queries/GetTaxRates.service.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/queries/TaxRate.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/subscribers/SyncItemTaxRateOnEditTaxSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TaxRates/utils.ts (100%) rename packages/{server-nest => server}/src/modules/TemplateInjectable/TemplateInjectable.module.ts (100%) rename packages/{server-nest => server}/src/modules/TemplateInjectable/TemplateInjectable.service.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/EnsureTenantIsInitialized.guard.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/EnsureTenantIsSeeded.guards.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/Tenancy.module.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyCache/TenancyCache.module.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyContext.service.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyDB/TenancyDB.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyDB/TenancyDB.module.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyDB/TransactionsHooks.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyDB/UnitOfWork.service.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyGlobal.guard.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyModels/Tenancy.constants.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyModels/Tenancy.module.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts (100%) rename packages/{server-nest => server}/src/modules/Tenancy/Tenant.controller.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/TenantDBManager.module.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/TenantDBManager.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/TenantsManager.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/_utils.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/exceptions/TenantAlreadyInitialized.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/exceptions/TenantAlreadySeeded.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/exceptions/TenantDBAlreadyExists.ts (100%) rename packages/{server-nest => server}/src/modules/TenantDBManager/exceptions/TenantDatabaseNotBuilt.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionItemEntry/ItemEntry.transformer.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionItemEntry/ItemEntry.types.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionItemEntry/models/ItemEntry.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/TransactionsLocking.controller.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/TransactionsLocking.module.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/TransactionsLockingRepository.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/constants.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/guards/FinancialTransactionLockingGuard.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/guards/PurchasesTransactionLockingGuard.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/guards/SalesTransactionLockingGuard.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/guards/TransactionsLockingGuard.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/queries/QueryTransactionsLocking.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/queries/TransactionsLockingMetaTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/subscribers/FinancialsTransactionLockingGuardSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/subscribers/PurchasesTransactionLockingGuardSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/subscribers/SalesTransactionLockingGuardSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/TransactionsLocking/types/TransactionsLocking.types.ts (100%) rename packages/{server-nest => server}/src/modules/Transformer/Transformer.module.ts (100%) rename packages/{server-nest => server}/src/modules/Transformer/Transformer.ts (100%) rename packages/{server-nest => server}/src/modules/Transformer/Transformer.types.ts (100%) rename packages/{server-nest => server}/src/modules/Transformer/TransformerInjectable.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/VendorCredits.controller.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/VendorCredits.module.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/VendorCreditsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/DeleteVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/EditVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/OpenVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditAutoIncrement.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditGL.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditsExportable.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/commands/VendorCreditsImportable.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/constants.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/dtos/VendorCredit.dto.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/models/VendorCredit.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/queries/GetVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/queries/GetVendorCredits.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/queries/VendorCreditTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/subscribers/DeleteVendorAssociatedVendorCredit.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/subscribers/RefundSyncVendorCreditBalanceSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/subscribers/RefundVendorCreditGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/subscribers/VendorCreditAutoSerialSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/subscribers/VendorCreditGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCredit/types/VendorCredit.types.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.controller.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.module.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/VendorCreditApplyBillsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/VendorCreditsApplyBills.constants.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncInvoiced.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditToBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/command/DeleteApplyVendorCreditToBill.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/queries/GetAppliedBillsToVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/queries/GetVendorCreditToApplyBills.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/queries/VendorCreditAppliedBillTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/queries/VendorCreditToApplyBillTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncBillsSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncInvoicedSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsApplyBills/types/VendorCreditApplyBills.types.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/RefundCreditSyncBills.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/VendorCreditsRefund.application.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/VendorCreditsRefund.controller.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/CreateRefundVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/DeleteRefundVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/RefundSyncCreditRefundedAmount.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/RefundSyncVendorCreditBalance.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/RefundVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/commands/RefundVendorCreditTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/constants.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/dtos/RefundVendorCredit.dto.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredit.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredits.service.ts (100%) rename packages/{server-nest => server}/src/modules/VendorCreditsRefund/types/VendorCreditRefund.types.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/VendorGLEntries.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/VendorGLEntriesStorage.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/Vendors.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/Vendors.module.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/VendorsApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/VendorsExportable.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/VendorsImportable.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/_SampleData.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/ActivateVendor.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/CreateEditVendorDTO.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/CreateVendor.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/DeleteVendor.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/EditOpeningBalanceVendor.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/EditVendor.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/commands/VendorValidators.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/dtos/CreateVendor.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/dtos/EditVendor.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/models/Vendor.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/queries/GetVendor.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/queries/GetVendors.service.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/queries/VendorTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/subscribers/VendorGLEntriesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Vendors/types/Vendors.types.ts (100%) rename packages/{server-nest => server}/src/modules/Views/GetResourceColumns.service.ts (100%) rename packages/{server-nest => server}/src/modules/Views/GetResourceViews.service.ts (100%) rename packages/{server-nest => server}/src/modules/Views/Views.types.ts (100%) rename packages/{server-nest => server}/src/modules/Views/models/View.model.ts (100%) rename packages/{server-nest => server}/src/modules/Views/models/ViewColumn.model.ts (100%) rename packages/{server-nest => server}/src/modules/Views/models/ViewRole.model.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/AccountsTransactionsWarehouses.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/AccountsTransactionsWarehousesSubscribe.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/BillWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/CreditNoteWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/EstimateWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/InvoiceWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/ReceiptWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Activate/VendorCreditWarehousesActivate.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/ActivateWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/CRUDWarehouse.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/CreateInitialWarehousesitemsQuantity.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/ValidateWarehouseExistance.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/WarehousesItemsQuantity.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySync.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Integrations/constants.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Items/GetItemWarehouses.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Items/GettItemWarehouseTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Warehouse.types.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Warehouses.controller.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/Warehouses.module.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/WarehousesApplication.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/WarehousesSettings.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/ActivateWarehouses.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/CreateInitialWarehouse.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/CreateWarehouse.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/DeleteItemWarehousesQuantity.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/DeleteWarehouse.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/EditWarehouse.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/commands/WarehouseValidator.service.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/contants.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/dtos/Warehouse.dto.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/models/ItemWarehouseQuantity.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/models/Warehouse.model.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/queries/GetWarehouse.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/queries/GetWarehouses.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/BillWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/EstimateWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/DeleteItemWarehousesQuantitySubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/Purchases/BillWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/Warehouses/subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/WarehouseTransfers.module.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/DeleteWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/InitiateWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/TransferredWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/WarehouseTransferAutoIncrement.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/commands/WarehouseTransferWriteInventoryTransactions.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/constants.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/queries/GetWarehouseTransfer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/queries/GetWarehouseTransfers.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/queries/WarehouseTransferItemTransformer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/queries/WarehouseTransferTransfomer.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferAutoIncrementSubscriber.ts (100%) rename packages/{server-nest => server}/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferInventoryTransactionsSubscriber.ts (100%) delete mode 100644 packages/server/src/repositories/AccountRepository.ts delete mode 100644 packages/server/src/repositories/AccountTransactionRepository.ts delete mode 100644 packages/server/src/repositories/BaseModelRepository.ts delete mode 100644 packages/server/src/repositories/BillRepository.ts delete mode 100644 packages/server/src/repositories/CachableRepository.ts delete mode 100644 packages/server/src/repositories/ContactRepository.ts delete mode 100644 packages/server/src/repositories/CustomerRepository.ts delete mode 100644 packages/server/src/repositories/EntityRepository.ts delete mode 100644 packages/server/src/repositories/ExpenseEntryRepository.ts delete mode 100644 packages/server/src/repositories/ExpenseRepository.ts delete mode 100644 packages/server/src/repositories/InventoryTransactionRepository.ts delete mode 100644 packages/server/src/repositories/ItemRepository.ts delete mode 100644 packages/server/src/repositories/JournalRepository.ts delete mode 100644 packages/server/src/repositories/PaymentReceiveEntryRepository.ts delete mode 100644 packages/server/src/repositories/PaymentReceiveRepository.ts delete mode 100644 packages/server/src/repositories/SaleInvoiceRepository.ts delete mode 100644 packages/server/src/repositories/SettingRepository.ts delete mode 100644 packages/server/src/repositories/TenantRepository.ts delete mode 100644 packages/server/src/repositories/VendorRepository.ts delete mode 100644 packages/server/src/repositories/ViewRepository.ts delete mode 100644 packages/server/src/repositories/ViewRoleRepository.ts delete mode 100644 packages/server/src/server.ts delete mode 100644 packages/server/src/services/Accounting/AccountsTransactionsWarehouses.ts delete mode 100644 packages/server/src/services/Accounting/AccountsTransactionsWarehousesSubscribe.ts delete mode 100644 packages/server/src/services/Accounting/JournalCommands.ts delete mode 100644 packages/server/src/services/Accounting/JournalContacts.ts delete mode 100644 packages/server/src/services/Accounting/JournalEntry.ts delete mode 100644 packages/server/src/services/Accounting/JournalFinancial.ts delete mode 100644 packages/server/src/services/Accounting/JournalPoster.ts delete mode 100644 packages/server/src/services/Accounting/Ledger.ts delete mode 100644 packages/server/src/services/Accounting/LedgerContactStorage.ts delete mode 100644 packages/server/src/services/Accounting/LedgerEntriesStorage.ts delete mode 100644 packages/server/src/services/Accounting/LedgerStorageRevert.ts delete mode 100644 packages/server/src/services/Accounting/LedgerStorageService.ts delete mode 100644 packages/server/src/services/Accounting/LedgetAccountStorage.ts delete mode 100644 packages/server/src/services/Accounting/utils.ts delete mode 100644 packages/server/src/services/Accounts/AccountTransactionTransformer.ts delete mode 100644 packages/server/src/services/Accounts/AccountTransform.ts delete mode 100644 packages/server/src/services/Accounts/AccountsApplication.ts delete mode 100644 packages/server/src/services/Accounts/AccountsExportable.ts delete mode 100644 packages/server/src/services/Accounts/AccountsImportable.SampleData.ts delete mode 100644 packages/server/src/services/Accounts/AccountsImportable.ts delete mode 100644 packages/server/src/services/Accounts/AccountsTypesServices.ts delete mode 100644 packages/server/src/services/Accounts/ActivateAccount.ts delete mode 100644 packages/server/src/services/Accounts/CommandAccountValidators.ts delete mode 100644 packages/server/src/services/Accounts/CreateAccount.ts delete mode 100644 packages/server/src/services/Accounts/DeleteAccount.ts delete mode 100644 packages/server/src/services/Accounts/EditAccount.ts delete mode 100644 packages/server/src/services/Accounts/GetAccount.ts delete mode 100644 packages/server/src/services/Accounts/GetAccountTransactions.ts delete mode 100644 packages/server/src/services/Accounts/GetAccounts.ts delete mode 100644 packages/server/src/services/Accounts/MutateBaseCurrencyAccounts.ts delete mode 100644 packages/server/src/services/Accounts/constants.ts delete mode 100644 packages/server/src/services/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts delete mode 100644 packages/server/src/services/Attachments/AttachmentTransformer.ts delete mode 100644 packages/server/src/services/Attachments/AttachmentsApplication.ts delete mode 100644 packages/server/src/services/Attachments/DeleteAttachment.ts delete mode 100644 packages/server/src/services/Attachments/GetAttachment.ts delete mode 100644 packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts delete mode 100644 packages/server/src/services/Attachments/LinkAttachment.ts delete mode 100644 packages/server/src/services/Attachments/S3UploadPipeline.ts delete mode 100644 packages/server/src/services/Attachments/UnlinkAttachment.ts delete mode 100644 packages/server/src/services/Attachments/UploadDocument.ts delete mode 100644 packages/server/src/services/Attachments/ValidateAttachments.ts delete mode 100644 packages/server/src/services/Attachments/_utils.ts delete mode 100644 packages/server/src/services/Attachments/constants.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnBills.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnCreditNote.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnExpenses.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnManualJournals.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnPaymentsMade.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnPaymentsReceived.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnSaleEstimates.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnSaleInvoice.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnSaleReceipts.ts delete mode 100644 packages/server/src/services/Attachments/events/AttachmentsOnVendorCredits.ts delete mode 100644 packages/server/src/services/Attachments/utils.ts delete mode 100644 packages/server/src/services/AuthenticatedAccount/index.ts delete mode 100644 packages/server/src/services/Authentication/AuthApplication.ts delete mode 100644 packages/server/src/services/Authentication/AuthSendResetPassword.ts delete mode 100644 packages/server/src/services/Authentication/AuthSignin.ts delete mode 100644 packages/server/src/services/Authentication/AuthSignup.ts delete mode 100644 packages/server/src/services/Authentication/AuthSignupConfirm.ts delete mode 100644 packages/server/src/services/Authentication/AuthSignupResend.ts delete mode 100644 packages/server/src/services/Authentication/AuthenticationMailMessages.ts delete mode 100644 packages/server/src/services/Authentication/GetAuthMeta.ts delete mode 100644 packages/server/src/services/Authentication/RateLimiter.ts delete mode 100644 packages/server/src/services/Authentication/_constants.ts delete mode 100644 packages/server/src/services/Authentication/_utils.ts delete mode 100644 packages/server/src/services/Authentication/events/SendVerfiyMailOnSignUp.ts delete mode 100644 packages/server/src/services/Authentication/jobs/SendVerifyMailJob.ts delete mode 100644 packages/server/src/services/Banking/BankAccounts/BankAccountsApplication.tsx delete mode 100644 packages/server/src/services/Banking/BankAccounts/DisconnectBankAccount.tsx delete mode 100644 packages/server/src/services/Banking/BankAccounts/GetBankAccountSummary.ts delete mode 100644 packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx delete mode 100644 packages/server/src/services/Banking/BankAccounts/RefreshBankAccount.tsx delete mode 100644 packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx delete mode 100644 packages/server/src/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting.ts delete mode 100644 packages/server/src/services/Banking/BankAccounts/events/DisconnectPlaidItemOnAccountDeleted.ts delete mode 100644 packages/server/src/services/Banking/BankAccounts/types.ts delete mode 100644 packages/server/src/services/Banking/Exclude/ExcludeBankTransaction.ts delete mode 100644 packages/server/src/services/Banking/Exclude/ExcludeBankTransactions.ts delete mode 100644 packages/server/src/services/Banking/Exclude/ExcludeBankTransactionsApplication.ts delete mode 100644 packages/server/src/services/Banking/Exclude/GetExcludedBankTransactions.ts delete mode 100644 packages/server/src/services/Banking/Exclude/UnexcludeBankTransaction.ts delete mode 100644 packages/server/src/services/Banking/Exclude/UnexcludeBankTransactions.ts delete mode 100644 packages/server/src/services/Banking/Exclude/_types.ts delete mode 100644 packages/server/src/services/Banking/Exclude/events/DecrementUncategorizedTransactionOnExclude.ts delete mode 100644 packages/server/src/services/Banking/Exclude/utils.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionBillsTransformer.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionCashflowTransformer.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionExpensesTransformer.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionInvoicesTransformer.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionManualJournalsTransformer.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactions.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionsByBills.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionsByCashflow.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionsByExpenses.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionsByInvoices.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionsByManualJournals.ts delete mode 100644 packages/server/src/services/Banking/Matching/GetMatchedTransactionsByType.ts delete mode 100644 packages/server/src/services/Banking/Matching/MatchBankTransactionsApplication.ts delete mode 100644 packages/server/src/services/Banking/Matching/MatchTransactions.ts delete mode 100644 packages/server/src/services/Banking/Matching/MatchTransactionsTypes.ts delete mode 100644 packages/server/src/services/Banking/Matching/MatchTransactionsTypesRegistry.ts delete mode 100644 packages/server/src/services/Banking/Matching/UnmatchMatchedTransaction.ts delete mode 100644 packages/server/src/services/Banking/Matching/ValidateTransactionsMatched.ts delete mode 100644 packages/server/src/services/Banking/Matching/_utils.ts delete mode 100644 packages/server/src/services/Banking/Matching/events/DecrementUncategorizedTransactionsOnMatch.ts delete mode 100644 packages/server/src/services/Banking/Matching/events/ValidateMatchingOnCashflowDelete.ts delete mode 100644 packages/server/src/services/Banking/Matching/events/ValidateMatchingOnExpenseDelete.ts delete mode 100644 packages/server/src/services/Banking/Matching/events/ValidateMatchingOnManualJournalDelete.ts delete mode 100644 packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentMadeDelete.ts delete mode 100644 packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentReceivedDelete.ts delete mode 100644 packages/server/src/services/Banking/Matching/types.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidApplication.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidFetchTransactionsJob.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidItem.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidLinkToken.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidSyncDB.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidUpdateTransactions.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidWebhookTenantBootMiddleware.ts delete mode 100644 packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts delete mode 100644 packages/server/src/services/Banking/Plaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts delete mode 100644 packages/server/src/services/Banking/Plaid/subscribers/RecognizeSyncedBankTransactions.ts delete mode 100644 packages/server/src/services/Banking/Plaid/utils.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransaction.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransactionTransformer.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/RecognizeTranasctionsService.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/RevertRecognizedTransactions.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/_types.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/_utils.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/events/TriggerRecognizedTransactions.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/jobs/RecognizeTransactionsJob.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/jobs/RerecognizeTransactionsJob.ts delete mode 100644 packages/server/src/services/Banking/RegonizeTranasctions/jobs/RevertRecognizedTransactionsJob.ts delete mode 100644 packages/server/src/services/Banking/Rules/BankRulesApplication.ts delete mode 100644 packages/server/src/services/Banking/Rules/CreateBankRule.ts delete mode 100644 packages/server/src/services/Banking/Rules/DeleteBankRule.ts delete mode 100644 packages/server/src/services/Banking/Rules/DeleteBankRules.ts delete mode 100644 packages/server/src/services/Banking/Rules/EditBankRule.ts delete mode 100644 packages/server/src/services/Banking/Rules/GetBankRule.ts delete mode 100644 packages/server/src/services/Banking/Rules/GetBankRuleTransformer.ts delete mode 100644 packages/server/src/services/Banking/Rules/GetBankRules.ts delete mode 100644 packages/server/src/services/Banking/Rules/GetBankRulesTransformer.ts delete mode 100644 packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts delete mode 100644 packages/server/src/services/Banking/Rules/types.ts delete mode 100644 packages/server/src/services/Branches/ActivateBranches.ts delete mode 100644 packages/server/src/services/Branches/BranchIntegrationErrorsMiddleware.ts delete mode 100644 packages/server/src/services/Branches/BranchValidate.ts delete mode 100644 packages/server/src/services/Branches/BranchesApplication.ts delete mode 100644 packages/server/src/services/Branches/BranchesSettings.ts delete mode 100644 packages/server/src/services/Branches/CRUDBranch.ts delete mode 100644 packages/server/src/services/Branches/CreateBranch.ts delete mode 100644 packages/server/src/services/Branches/DeleteBranch.ts delete mode 100644 packages/server/src/services/Branches/EditBranch.ts delete mode 100644 packages/server/src/services/Branches/EventsProvider.ts delete mode 100644 packages/server/src/services/Branches/GetBranch.ts delete mode 100644 packages/server/src/services/Branches/GetBranches.ts delete mode 100644 packages/server/src/services/Branches/Integrations/BranchTransactionDTOTransform.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Cashflow/CashflowActivateBranches.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Expense/ExpensesActivateBranches.ts delete mode 100644 packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer.ts delete mode 100644 packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalsBranchesValidator.ts delete mode 100644 packages/server/src/services/Branches/Integrations/ManualJournals/constants.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Purchases/BillBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Purchases/PaymentMadeBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Purchases/VendorCreditBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Sales/CreditNoteBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Sales/PaymentReceiveBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Sales/SaleEstimatesBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Sales/SaleInvoiceBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/Sales/SaleReceiptBranchesActivate.ts delete mode 100644 packages/server/src/services/Branches/Integrations/ValidateBranchExistance.ts delete mode 100644 packages/server/src/services/Branches/Integrations/constants.ts delete mode 100644 packages/server/src/services/Branches/MarkBranchAsPrimary.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/CashflowBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/ExpenseBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Activate/index.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/BillBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/CreditNoteBranchesSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/CreditNoteRefundBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/ExpenseBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/InvoiceBranchValidatorSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/ManualJournalBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/PaymentMadeBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/PaymentReceiveBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/SaleReceiptBranchesSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/VendorCreditBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/VendorCreditRefundBranchSubscriber.ts delete mode 100644 packages/server/src/services/Branches/Subscribers/Validators/index.ts delete mode 100644 packages/server/src/services/Branches/constants.ts delete mode 100644 packages/server/src/services/Cache/index.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowAccountTransformer.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowApplication.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowDeleteAccount.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowTransactionAutoIncrement.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowTransactionJournalEntries.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowTransactionSubscriber.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowTransactionTransformer.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowTransactionsTransformer.ts delete mode 100644 packages/server/src/services/Cashflow/CashflowWithAccountSubscriber.ts delete mode 100644 packages/server/src/services/Cashflow/CategorizeCashflowTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/CategorizeRecognizedTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/CategorizeTransactionAsExpense.ts delete mode 100644 packages/server/src/services/Cashflow/CommandCasflowValidator.ts delete mode 100644 packages/server/src/services/Cashflow/CreateUncategorizedTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/DeleteCashflowTransactionService.ts delete mode 100644 packages/server/src/services/Cashflow/GetCashflowAccountsService.ts delete mode 100644 packages/server/src/services/Cashflow/GetCashflowTransactionsService.ts delete mode 100644 packages/server/src/services/Cashflow/GetPendingBankAccountTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/GetPendingBankAccountTransactionTransformer.ts delete mode 100644 packages/server/src/services/Cashflow/GetRecognizedTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/GetRecognizedTransactionTransformer.ts delete mode 100644 packages/server/src/services/Cashflow/GetRecongizedTransactions.ts delete mode 100644 packages/server/src/services/Cashflow/GetUncategorizedTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/GetUncategorizedTransactions.ts delete mode 100644 packages/server/src/services/Cashflow/NewCashflowTransactionService.ts delete mode 100644 packages/server/src/services/Cashflow/RemovePendingUncategorizedTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/UncategorizeCashflowTransaction.ts delete mode 100644 packages/server/src/services/Cashflow/UncategorizeCashflowTransactionsBulk.ts delete mode 100644 packages/server/src/services/Cashflow/UncategorizedTransactionTransformer.ts delete mode 100644 packages/server/src/services/Cashflow/UncategorizedTransactionsImportable.ts delete mode 100644 packages/server/src/services/Cashflow/constants.ts delete mode 100644 packages/server/src/services/Cashflow/subscribers/DecrementUncategorizedTransactionOnCategorize.ts delete mode 100644 packages/server/src/services/Cashflow/subscribers/DeleteCashflowTransactionOnUncategorize.ts delete mode 100644 packages/server/src/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete.ts delete mode 100644 packages/server/src/services/Cashflow/utils.ts delete mode 100644 packages/server/src/services/ChromiumlyTenancy/ChromiumlyHtmlConvert.ts delete mode 100644 packages/server/src/services/ChromiumlyTenancy/ChromiumlyTenancy.ts delete mode 100644 packages/server/src/services/ChromiumlyTenancy/utils.ts delete mode 100644 packages/server/src/services/Contacts/ContactTransformer.ts delete mode 100644 packages/server/src/services/Contacts/ContactsService.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/ActivateCustomer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/CreateEditCustomerDTO.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/CustomerValidators.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/DeleteCustomer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/EditCustomer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/EditOpeningBalanceCustomer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/GetCustomer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CRUD/GetCustomers.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CustomerGLEntries.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CustomerGLEntriesStorage.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CustomerTransformer.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CustomersApplication.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CustomersExportable.ts delete mode 100644 packages/server/src/services/Contacts/Customers/CustomersImportable.ts delete mode 100644 packages/server/src/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Contacts/Customers/_SampleData.ts delete mode 100644 packages/server/src/services/Contacts/Customers/constants.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/ActivateVendor.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/CreateEditVendorDTO.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/CreateVendor.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/DeleteVendor.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/EditOpeningBalanceVendor.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/EditVendor.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/GetVendor.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/GetVendors.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/CRUD/VendorValidators.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/VendorGLEntries.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/VendorGLEntriesStorage.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/VendorTransformer.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/VendorsApplication.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/VendorsExportable.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/VendorsImportable.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/_SampleData.ts delete mode 100644 packages/server/src/services/Contacts/Vendors/constants.ts delete mode 100644 packages/server/src/services/Contacts/constants.ts delete mode 100644 packages/server/src/services/CreditNotes/CreateCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/CreateRefundCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteAppliedInvoiceTransformer.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteApplySyncCredit.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteApplySyncCreditSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoices.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoicesSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteApplyToInvoices.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteAutoSerialSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteGLEntries.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteInventoryTransactionsSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteTransformer.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNoteWithInvoicesToApplyTransformer.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNotes.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNotesExportable.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNotesImportable.ts delete mode 100644 packages/server/src/services/CreditNotes/CreditNotesInventoryTransactions.ts delete mode 100644 packages/server/src/services/CreditNotes/DeleteCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/DeleteCreditNoteApplyToInvoices.ts delete mode 100644 packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/DeleteRefundCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/EditCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/GetCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices.ts delete mode 100644 packages/server/src/services/CreditNotes/GetCreditNoteAssociatedInvoicesToApply.ts delete mode 100644 packages/server/src/services/CreditNotes/GetCreditNotePdf.ts delete mode 100644 packages/server/src/services/CreditNotes/GetCreditNoteState.ts delete mode 100644 packages/server/src/services/CreditNotes/GetRefundCreditNoteTransaction.ts delete mode 100644 packages/server/src/services/CreditNotes/ListCreditNoteRefunds.ts delete mode 100644 packages/server/src/services/CreditNotes/ListCreditNotes.ts delete mode 100644 packages/server/src/services/CreditNotes/OpenCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/RefundCreditNote.ts delete mode 100644 packages/server/src/services/CreditNotes/RefundCreditNoteGLEntries.ts delete mode 100644 packages/server/src/services/CreditNotes/RefundCreditNoteGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/RefundCreditNoteTransformer.ts delete mode 100644 packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalance.ts delete mode 100644 packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalanceSubscriber.ts delete mode 100644 packages/server/src/services/CreditNotes/constants.ts delete mode 100644 packages/server/src/services/CreditNotes/utils.ts delete mode 100644 packages/server/src/services/Currencies/CurrenciesService.ts delete mode 100644 packages/server/src/services/Currencies/CurrencyTransformer.ts delete mode 100644 packages/server/src/services/Currencies/InitialCurrenciesSeed.ts delete mode 100644 packages/server/src/services/Currencies/constants.ts delete mode 100644 packages/server/src/services/Currencies/subscribers/SeedInitialCurrenciesOnSetupSubscriber.ts delete mode 100644 packages/server/src/services/Dashboard/DashboardService.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListAbstract.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListCustomView.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListFilterRoles.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListSearch.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListService.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListSortBy.ts delete mode 100644 packages/server/src/services/DynamicListing/DynamicListing.types.ts delete mode 100644 packages/server/src/services/DynamicListing/constants.ts delete mode 100644 packages/server/src/services/DynamicListing/validators.ts delete mode 100644 packages/server/src/services/Entries/index.ts delete mode 100644 packages/server/src/services/EventsTracker/PostHog.ts delete mode 100644 packages/server/src/services/EventsTracker/events/AccountEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/AuthenticationEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/BankRuleEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/BankTransactionEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/BillEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/CustomerEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/ExpenseEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/ItemEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/ManualJournalEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/PaymentLinkEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/PaymentMadeEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/PaymentMethodEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/PaymentReceivedEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/PdfTemplateEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/ReportsEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/SaleEstimateEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/SaleInvoicesEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/StripeIntegrationEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/SubscriptionEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/TransactionsLockingEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/VendorEventsTracker.ts delete mode 100644 packages/server/src/services/EventsTracker/events/events.ts delete mode 100644 packages/server/src/services/ExchangeRates/ExchangeRateApplication.ts delete mode 100644 packages/server/src/services/ExchangeRates/ExchangeRatesService.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/CommandExpenseValidator.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/CreateExpense.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/DeleteExpense.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/EditExpense.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/ExpenseCategoryTransformer.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/ExpenseDTOTransformer.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/ExpenseTransformer.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/GetExpense.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/GetExpenses.ts delete mode 100644 packages/server/src/services/Expenses/CRUD/PublishExpense.ts delete mode 100644 packages/server/src/services/Expenses/ExpenseGL.ts delete mode 100644 packages/server/src/services/Expenses/ExpenseGLEntriesService.ts delete mode 100644 packages/server/src/services/Expenses/ExpenseGLEntriesStorage.ts delete mode 100644 packages/server/src/services/Expenses/ExpenseGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Expenses/ExpensesApplication.ts delete mode 100644 packages/server/src/services/Expenses/ExpensesExportable.ts delete mode 100644 packages/server/src/services/Expenses/ExpensesImportable.ts delete mode 100644 packages/server/src/services/Expenses/constants.ts delete mode 100644 packages/server/src/services/Export/ExportAls.ts delete mode 100644 packages/server/src/services/Export/ExportApplication.ts delete mode 100644 packages/server/src/services/Export/ExportPdf.ts delete mode 100644 packages/server/src/services/Export/ExportRegistery.ts delete mode 100644 packages/server/src/services/Export/ExportResources.ts delete mode 100644 packages/server/src/services/Export/ExportService.ts delete mode 100644 packages/server/src/services/Export/Exportable.ts delete mode 100644 packages/server/src/services/Export/common.ts delete mode 100644 packages/server/src/services/Export/constants.ts delete mode 100644 packages/server/src/services/Export/utils.ts delete mode 100644 packages/server/src/services/Features/FeaturesConfigureManager.ts delete mode 100644 packages/server/src/services/Features/FeaturesManager.ts delete mode 100644 packages/server/src/services/Features/FeaturesSettingsDriver.ts delete mode 100644 packages/server/src/services/Features/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryService.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummarySheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryService.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummarySheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/AgingReport.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/AgingSummary.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/_constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAccounts.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAggregators.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetBase.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousYear.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetFiltering.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncome.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePP.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePY.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPercentage.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetQuery.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepositoryNetIncome.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetSchema.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePercentage.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousPeriod.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousYear.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTotal.ts delete mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashFlow.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashFlowDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashFlowRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashFlowService.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashFlowTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashflowExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashflowTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashFlow/schema.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactions.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsRepo.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsService.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashflowAccountTransactions/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/CashflowAccountTransactions/utils.ts delete mode 100644 packages/server/src/services/FinancialStatements/ContactBalanceSummary/ContactBalanceSummary.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummary.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryService.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts delete mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialDateRanges.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialEvaluateEquation.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialFilter.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialHorizTotals.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialPreviousPeriod.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialPreviousYear.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialReportService.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialSchema.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialSheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialSheetStructure.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialTablePreviousPeriod.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialTablePreviousYear.ts delete mode 100644 packages/server/src/services/FinancialStatements/FinancialTableStructure.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedger.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerExport.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerService.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/_utils.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/GeneralLedger/utils.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetails.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsService.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTablePdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryDetails/constant.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetExportable.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/InventoryValuationSheet/_constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetExport.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/constant.ts delete mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/types.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSchema.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetBase.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetFilter.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPercentage.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousYear.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetQuery.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetService.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTablePercentage.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousYear.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/utils.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummary.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryService.ts delete mode 100644 packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsExport.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsService.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/PurchasesByItems/_types.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsExport.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsService.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/TableSheetPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContact.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContactTableRows.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomers.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersService.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceReport.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByReference/index.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendor.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TransactionsByVendor/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/_constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummary.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryMeta.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryRepository.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryService.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts delete mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/constants.ts delete mode 100644 packages/server/src/services/FinancialStatements/utils.ts delete mode 100644 packages/server/src/services/I18n/I18nService.ts delete mode 100644 packages/server/src/services/Import/ImportALS.ts delete mode 100644 packages/server/src/services/Import/ImportFileCommon.ts delete mode 100644 packages/server/src/services/Import/ImportFileDataTransformer.ts delete mode 100644 packages/server/src/services/Import/ImportFileDataValidator.ts delete mode 100644 packages/server/src/services/Import/ImportFileMapping.ts delete mode 100644 packages/server/src/services/Import/ImportFileMeta.ts delete mode 100644 packages/server/src/services/Import/ImportFileMetaTransformer.ts delete mode 100644 packages/server/src/services/Import/ImportFilePreview.ts delete mode 100644 packages/server/src/services/Import/ImportFileProcess.ts delete mode 100644 packages/server/src/services/Import/ImportFileProcessCommit.ts delete mode 100644 packages/server/src/services/Import/ImportFileUpload.ts delete mode 100644 packages/server/src/services/Import/ImportRemoveExpiredFiles.ts delete mode 100644 packages/server/src/services/Import/ImportResourceApplication.ts delete mode 100644 packages/server/src/services/Import/ImportSample.ts delete mode 100644 packages/server/src/services/Import/Importable.ts delete mode 100644 packages/server/src/services/Import/ImportableRegistry.ts delete mode 100644 packages/server/src/services/Import/ImportableResources.ts delete mode 100644 packages/server/src/services/Import/_constants.ts delete mode 100644 packages/server/src/services/Import/_utils.ts delete mode 100644 packages/server/src/services/Import/interfaces.ts delete mode 100644 packages/server/src/services/Import/jobs/ImportDeleteExpiredFilesJob.ts delete mode 100644 packages/server/src/services/Import/sheet_utils.ts delete mode 100644 packages/server/src/services/Inventory/Inventory.ts delete mode 100644 packages/server/src/services/Inventory/InventoryAdjustmentGL.ts delete mode 100644 packages/server/src/services/Inventory/InventoryAdjustmentService.ts delete mode 100644 packages/server/src/services/Inventory/InventoryAdjustmentTransformer.ts delete mode 100644 packages/server/src/services/Inventory/InventoryAverageCost.ts delete mode 100644 packages/server/src/services/Inventory/InventoryCostApplication.ts delete mode 100644 packages/server/src/services/Inventory/InventoryCostGLStorage.ts delete mode 100644 packages/server/src/services/Inventory/InventoryCostLotTracker.ts delete mode 100644 packages/server/src/services/Inventory/InventoryCostMethod.ts delete mode 100644 packages/server/src/services/Inventory/InventoryCostsService.ts delete mode 100644 packages/server/src/services/Inventory/InventoryItemsQuantitySync.ts delete mode 100644 packages/server/src/services/Inventory/subscribers/InventoryCostGLBeforeWriteSubscriber.ts delete mode 100644 packages/server/src/services/Inventory/utils.ts delete mode 100644 packages/server/src/services/InviteUsers/AcceptInviteUser.ts delete mode 100644 packages/server/src/services/InviteUsers/InviteSendMailNotificationSubscribe.ts delete mode 100644 packages/server/src/services/InviteUsers/SendInviteUsersMailMessage.ts delete mode 100644 packages/server/src/services/InviteUsers/SyncSystemSendInvite.ts delete mode 100644 packages/server/src/services/InviteUsers/SyncTenantAcceptInvite.ts delete mode 100644 packages/server/src/services/InviteUsers/TenantInviteUser.ts delete mode 100644 packages/server/src/services/InviteUsers/constants.ts delete mode 100644 packages/server/src/services/ItemCategories/ItemCategoriesExportable.ts delete mode 100644 packages/server/src/services/ItemCategories/ItemCategoriesImportable.ts delete mode 100644 packages/server/src/services/ItemCategories/ItemCategoriesService.ts delete mode 100644 packages/server/src/services/ItemCategories/constants.ts delete mode 100644 packages/server/src/services/Items/ActivateItem.ts delete mode 100644 packages/server/src/services/Items/CreateItem.ts delete mode 100644 packages/server/src/services/Items/DeleteItem.ts delete mode 100644 packages/server/src/services/Items/EditItem.ts delete mode 100644 packages/server/src/services/Items/GetItem.ts delete mode 100644 packages/server/src/services/Items/GetItems.ts delete mode 100644 packages/server/src/services/Items/InactivateItem.ts delete mode 100644 packages/server/src/services/Items/ItemBillsTransactionsTransformer.ts delete mode 100644 packages/server/src/services/Items/ItemEstimatesTransactionTransformer.ts delete mode 100644 packages/server/src/services/Items/ItemInvoicesTransactionsTransformer.ts delete mode 100644 packages/server/src/services/Items/ItemReceiptsTransactionsTransformer.ts delete mode 100644 packages/server/src/services/Items/ItemTransactionsService.ts delete mode 100644 packages/server/src/services/Items/ItemTransformer.ts delete mode 100644 packages/server/src/services/Items/ItemValidators.ts delete mode 100644 packages/server/src/services/Items/ItemsApplication.ts delete mode 100644 packages/server/src/services/Items/ItemsEntriesService.ts delete mode 100644 packages/server/src/services/Items/ItemsExportable.ts delete mode 100644 packages/server/src/services/Items/ItemsImportable.ts delete mode 100644 packages/server/src/services/Items/constants.ts delete mode 100644 packages/server/src/services/Items/utils.ts delete mode 100644 packages/server/src/services/Jobs/JobTransformer.ts delete mode 100644 packages/server/src/services/Jobs/JobsService.ts delete mode 100644 packages/server/src/services/Ledger/LedgerRepository.ts delete mode 100644 packages/server/src/services/Loops/LoopsEventsSubscriber.ts delete mode 100644 packages/server/src/services/MailNotification/ContactMailNotification.ts delete mode 100644 packages/server/src/services/MailNotification/constants.ts delete mode 100644 packages/server/src/services/MailNotification/utils.ts delete mode 100644 packages/server/src/services/MailTenancy/MailTenancy.ts delete mode 100644 packages/server/src/services/ManualJournals/AutoIncrementManualJournal.ts delete mode 100644 packages/server/src/services/ManualJournals/CommandManualJournalValidators.ts delete mode 100644 packages/server/src/services/ManualJournals/CreateManualJournal.ts delete mode 100644 packages/server/src/services/ManualJournals/DeleteManualJournal.ts delete mode 100644 packages/server/src/services/ManualJournals/EditManualJournal.ts delete mode 100644 packages/server/src/services/ManualJournals/GetManualJournal.ts delete mode 100644 packages/server/src/services/ManualJournals/GetManualJournals.ts delete mode 100644 packages/server/src/services/ManualJournals/ManualJournalExportable.ts delete mode 100644 packages/server/src/services/ManualJournals/ManualJournalGLEntries.ts delete mode 100644 packages/server/src/services/ManualJournals/ManualJournalGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/ManualJournals/ManualJournalTransformer.ts delete mode 100644 packages/server/src/services/ManualJournals/ManualJournalsApplication.ts delete mode 100644 packages/server/src/services/ManualJournals/ManualJournalsImport.ts delete mode 100644 packages/server/src/services/ManualJournals/PublishManualJournal.ts delete mode 100644 packages/server/src/services/ManualJournals/constants.ts delete mode 100644 packages/server/src/services/Media/MediaService.ts delete mode 100644 packages/server/src/services/Miscellaneous/DateFormats/constants.ts delete mode 100644 packages/server/src/services/Miscellaneous/DateFormats/index.ts delete mode 100644 packages/server/src/services/Miscellaneous/MiscService.ts delete mode 100644 packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoAbstract.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoBankTransactions.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoCustomers.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoExpenses.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoItems.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoManualJournals.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoSaleInvoices.ts delete mode 100644 packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoVendors.ts delete mode 100644 packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts delete mode 100644 packages/server/src/services/OneClickDemo/_constants.ts delete mode 100644 packages/server/src/services/OneClickDemo/events/SeedInitialDemoAccountData.ts delete mode 100644 packages/server/src/services/OneClickDemo/interfaces.ts delete mode 100644 packages/server/src/services/Organization/OrganizationBaseCurrencyLocking.ts delete mode 100644 packages/server/src/services/Organization/OrganizationService.ts delete mode 100644 packages/server/src/services/Organization/OrganizationUpgrade.ts delete mode 100644 packages/server/src/services/Organization/constants.ts delete mode 100644 packages/server/src/services/PaymentLinks/CreateInvoiceCheckoutSession.ts delete mode 100644 packages/server/src/services/PaymentLinks/GetInvoicePaymentLinkMetadata.ts delete mode 100644 packages/server/src/services/PaymentLinks/GetPaymentLinkInvoicePdf.ts delete mode 100644 packages/server/src/services/PaymentLinks/PaymentLinksApplication.ts delete mode 100644 packages/server/src/services/PaymentServices/DeletePaymentMethodService.ts delete mode 100644 packages/server/src/services/PaymentServices/EditPaymentMethodService.ts delete mode 100644 packages/server/src/services/PaymentServices/GetPaymentMethodsState.ts delete mode 100644 packages/server/src/services/PaymentServices/GetPaymentService.ts delete mode 100644 packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoice.ts delete mode 100644 packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoiceTransformer.ts delete mode 100644 packages/server/src/services/PaymentServices/PaymentServicesApplication.ts delete mode 100644 packages/server/src/services/PaymentServices/types.ts delete mode 100644 packages/server/src/services/PaymentServices/utils.ts delete mode 100644 packages/server/src/services/PdfTemplate/AssignPdfTemplateDefault.ts delete mode 100644 packages/server/src/services/PdfTemplate/BrandingTemplateDTOTransformer.ts delete mode 100644 packages/server/src/services/PdfTemplate/CreatePdfTemplate.ts delete mode 100644 packages/server/src/services/PdfTemplate/DeletePdfTemplate.ts delete mode 100644 packages/server/src/services/PdfTemplate/EditPdfTemplate.ts delete mode 100644 packages/server/src/services/PdfTemplate/GetOrganizationBrandingAttributes.ts delete mode 100644 packages/server/src/services/PdfTemplate/GetPdfTemplate.ts delete mode 100644 packages/server/src/services/PdfTemplate/GetPdfTemplateBrandingState.ts delete mode 100644 packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts delete mode 100644 packages/server/src/services/PdfTemplate/GetPdfTemplates.ts delete mode 100644 packages/server/src/services/PdfTemplate/GetPdfTemplatesTransformer.ts delete mode 100644 packages/server/src/services/PdfTemplate/PdfTemplateApplication.ts delete mode 100644 packages/server/src/services/PdfTemplate/types.ts delete mode 100644 packages/server/src/services/Projects/Projects/CreateProject.ts delete mode 100644 packages/server/src/services/Projects/Projects/DeleteProject.ts delete mode 100644 packages/server/src/services/Projects/Projects/EditProject.ts delete mode 100644 packages/server/src/services/Projects/Projects/EditProjectStatus.ts delete mode 100644 packages/server/src/services/Projects/Projects/GetProject.ts delete mode 100644 packages/server/src/services/Projects/Projects/GetProjectBillableEntries.ts delete mode 100644 packages/server/src/services/Projects/Projects/GetProjects.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableBill.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableBillInvoiced.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableBillSubscriber.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableBillTransformer.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableExpense.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableExpenseInvoiced.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableExpenseSubscriber.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableExpenseTransformer.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableTaskTransformer.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableTasks.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableTasksInvoiced.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectBillableTasksSubscriber.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectDetailedTransformer.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectInvoiceValidator.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectTransformer.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectsApplication.ts delete mode 100644 packages/server/src/services/Projects/Projects/ProjectsValidator.ts delete mode 100644 packages/server/src/services/Projects/Projects/_types.ts delete mode 100644 packages/server/src/services/Projects/Projects/_utils.ts delete mode 100644 packages/server/src/services/Projects/Projects/constants.ts delete mode 100644 packages/server/src/services/Projects/Tasks/CreateTask.ts delete mode 100644 packages/server/src/services/Projects/Tasks/DeleteTask.ts delete mode 100644 packages/server/src/services/Projects/Tasks/EditTask.ts delete mode 100644 packages/server/src/services/Projects/Tasks/GetTask.ts delete mode 100644 packages/server/src/services/Projects/Tasks/GetTasks.ts delete mode 100644 packages/server/src/services/Projects/Tasks/TaskTransformer.ts delete mode 100644 packages/server/src/services/Projects/Tasks/TasksApplication.ts delete mode 100644 packages/server/src/services/Projects/Tasks/constants.ts delete mode 100644 packages/server/src/services/Projects/Times/CreateTime.ts delete mode 100644 packages/server/src/services/Projects/Times/DeleteTime.ts delete mode 100644 packages/server/src/services/Projects/Times/EditTime.ts delete mode 100644 packages/server/src/services/Projects/Times/GetTime.ts delete mode 100644 packages/server/src/services/Projects/Times/GetTimes.ts delete mode 100644 packages/server/src/services/Projects/Times/SyncActualTimeTask.ts delete mode 100644 packages/server/src/services/Projects/Times/SyncActualTimeTaskSubscriber.ts delete mode 100644 packages/server/src/services/Projects/Times/TimeTransformer.ts delete mode 100644 packages/server/src/services/Projects/Times/TimesApplication.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentBillSync.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentEntryTransformer.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentExportable.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntries.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentTransactionTransformer.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentTransformer.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentValidators.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentsApplication.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentsImportable.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/BillPaymentsPages.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/CommandBillPaymentDTOTransformer.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/CreateBillPayment.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/DeleteBillPayment.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/EditBillPayment.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/GetBillPayment.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/GetBillPayments.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/GetPaymentBills.ts delete mode 100644 packages/server/src/services/Purchases/BillPayments/constants.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillDTOTransformer.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillGLEntries.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillInventoryTransactions.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewrite.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewriteSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillsApplication.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillsExportable.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillsImportable.ts delete mode 100644 packages/server/src/services/Purchases/Bills/BillsValidators.ts delete mode 100644 packages/server/src/services/Purchases/Bills/CreateBill.ts delete mode 100644 packages/server/src/services/Purchases/Bills/DeleteBill.ts delete mode 100644 packages/server/src/services/Purchases/Bills/EditBill.ts delete mode 100644 packages/server/src/services/Purchases/Bills/GetBill.ts delete mode 100644 packages/server/src/services/Purchases/Bills/GetBillPayments.ts delete mode 100644 packages/server/src/services/Purchases/Bills/GetBills.ts delete mode 100644 packages/server/src/services/Purchases/Bills/GetDueBills.ts delete mode 100644 packages/server/src/services/Purchases/Bills/OpenBill.ts delete mode 100644 packages/server/src/services/Purchases/Bills/PurchaseInvoiceTransformer.ts delete mode 100644 packages/server/src/services/Purchases/Bills/constants.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/AllocateLandedCost.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/BaseLandedCost.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/BillAllocatedLandedCostTransactions.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/BillLandedCost.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/ExpenseLandedCost.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostGLEntries.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactions.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactions.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/LandedCostTransactions.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/RevertAllocatedLandedCost.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/TransctionLandedCost.ts delete mode 100644 packages/server/src/services/Purchases/LandedCost/utils.ts delete mode 100644 packages/server/src/services/Purchases/PurchasesTransactionsLocking.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBills.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBillsSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoiced.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoicedSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditToBills.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/DeleteApplyVendorCreditToBill.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetAppliedBillsToVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetVendorCreditToApplyBills.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditAppliedBillTransformer.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditToApplyBillTransformer.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/BaseVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/CreateVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/DeleteVendorAssociatedVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/DeleteVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/EditVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/GetVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/ListVendorCredits.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/OpenVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/CreateRefundVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/DeleteRefundVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/GetRefundVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/ListRefundVendorCredits.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundCreditSyncBills.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncCreditRefundedAmount.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalance.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalanceSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCredit.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntries.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditTransformer.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/constants.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditAutoSerialSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntries.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactions.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactionsSusbcriber.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditTransformer.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditsExportable.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/VendorCreditsImportable.ts delete mode 100644 packages/server/src/services/Purchases/VendorCredits/constants.ts delete mode 100644 packages/server/src/services/Resource/ResourceService.ts delete mode 100644 packages/server/src/services/Roles/AbilitySchema.ts delete mode 100644 packages/server/src/services/Roles/PurgeAuthorizedUser.ts delete mode 100644 packages/server/src/services/Roles/RolePermissionsSchema.ts delete mode 100644 packages/server/src/services/Roles/RoleTransformer.ts delete mode 100644 packages/server/src/services/Roles/RolesService.ts delete mode 100644 packages/server/src/services/Roles/constants.ts delete mode 100644 packages/server/src/services/Roles/utils.ts delete mode 100644 packages/server/src/services/SMSClient/EasySmsClient.ts delete mode 100644 packages/server/src/services/SMSClient/SMSAPI.ts delete mode 100644 packages/server/src/services/SMSClient/SMSClientInterface.ts delete mode 100644 packages/server/src/services/SMSClient/index.ts delete mode 100644 packages/server/src/services/Sales/AutoIncrementOrdersService.ts delete mode 100644 packages/server/src/services/Sales/Estimates/ApproveSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/ConvetSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/CreateSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/DeleteSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/DeliverSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/EditSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetEstimateMailTemplate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetSaleEstimateMailState.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetSaleEstimateState.ts delete mode 100644 packages/server/src/services/Sales/Estimates/GetSaleEstimates.ts delete mode 100644 packages/server/src/services/Sales/Estimates/RejectSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimateDTOTransformer.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimateIncrement.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimateSmsNotify.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimateValidators.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimatesApplication.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimatesExportable.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimatesImportable.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts delete mode 100644 packages/server/src/services/Sales/Estimates/SendSaleEstimateMailJob.ts delete mode 100644 packages/server/src/services/Sales/Estimates/UnlinkConvertedSaleEstimate.ts delete mode 100644 packages/server/src/services/Sales/Estimates/constants.ts delete mode 100644 packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts delete mode 100644 packages/server/src/services/Sales/Estimates/utils.ts delete mode 100644 packages/server/src/services/Sales/HasItemsEntries.ts delete mode 100644 packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/CommandSaleInvoiceValidators.ts delete mode 100644 packages/server/src/services/Sales/Invoices/CreateSaleInvoice.ts delete mode 100644 packages/server/src/services/Sales/Invoices/DeleteSaleInvoice.ts delete mode 100644 packages/server/src/services/Sales/Invoices/DeliverSaleInvoice.ts delete mode 100644 packages/server/src/services/Sales/Invoices/EditSaleInvoice.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GeneratePaymentLinkTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GenerateeInvoicePaymentLink.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetInvoicePaymentMail.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetInvoicePaymentsService.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoice.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailReminder.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoiceState.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoices.ts delete mode 100644 packages/server/src/services/Sales/Invoices/GetSaleInvoicesPayable.ts delete mode 100644 packages/server/src/services/Sales/Invoices/InvoiceGLEntries.ts delete mode 100644 packages/server/src/services/Sales/Invoices/InvoiceInventoryTransactions.ts delete mode 100644 packages/server/src/services/Sales/Invoices/InvoicePaymentTransactionTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/InvoicePaymentsGLRewrite.ts delete mode 100644 packages/server/src/services/Sales/Invoices/ItemEntryTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceCostGLEntries.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceIncrement.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceNotifyBySms.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoicePdf.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceTaxEntryTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceTransformer.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLEntries.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLStorage.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffSubscriber.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoicesExportable.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SaleInvoicesImportable.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SalesInvoicesCost.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SendInvoiceInvoiceMailCommon.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SendSaleInvoiceMail.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailJob.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminder.ts delete mode 100644 packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminderJob.ts delete mode 100644 packages/server/src/services/Sales/Invoices/WriteoffSaleInvoice.ts delete mode 100644 packages/server/src/services/Sales/Invoices/constants.ts delete mode 100644 packages/server/src/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts delete mode 100644 packages/server/src/services/Sales/Invoices/subscribers/InvoiceCostGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts delete mode 100644 packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentIntegrationSubscriber.ts delete mode 100644 packages/server/src/services/Sales/Invoices/utils.ts delete mode 100644 packages/server/src/services/Sales/JournalPosterService.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/CreatePaymentReceived.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/DeletePaymentReceived.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/EditPaymentReceived.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceived.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedInvoices.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailState.tsx delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailStateTransformer.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplate.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedPdf.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedState.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/GetPaymentsReceived.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedApplication.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedDTOTransformer.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedEntryTransformer.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedGLEntries.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedIncrement.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedInvoiceSync.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotification.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotificationJob.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsNotify.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsSubscriber.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedTransformer.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentReceivedValidators.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedExportable.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedImportable.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedPages.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/constants.ts delete mode 100644 packages/server/src/services/Sales/PaymentReceived/utils.ts delete mode 100644 packages/server/src/services/Sales/Receipts/CloseSaleReceipt.ts delete mode 100644 packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts delete mode 100644 packages/server/src/services/Sales/Receipts/DeleteSaleReceipt.ts delete mode 100644 packages/server/src/services/Sales/Receipts/EditSaleReceipt.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceipt.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceiptMailState.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceiptMailStateTransformer.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplate.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceiptState.ts delete mode 100644 packages/server/src/services/Sales/Receipts/GetSaleReceipts.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptApplication.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptCostGLEntries.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptDTOTransformer.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptGLEntries.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptIncrement.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptInventoryTransactions.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptMailNotificationJob.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptNotifyBySms.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptTransformer.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptValidators.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptsExportable.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts delete mode 100644 packages/server/src/services/Sales/Receipts/SaleReceiptsPdfService.ts delete mode 100644 packages/server/src/services/Sales/Receipts/constants.ts delete mode 100644 packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts delete mode 100644 packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts delete mode 100644 packages/server/src/services/Sales/Receipts/utils.ts delete mode 100644 packages/server/src/services/Sales/SaleNotifyBySms.ts delete mode 100644 packages/server/src/services/Sales/SalesTransactionsLocking.ts delete mode 100644 packages/server/src/services/Sales/ServiceItemsEntries.js delete mode 100644 packages/server/src/services/SessionModel/SessionQueryBuilder.js delete mode 100644 packages/server/src/services/SessionModel/index.js delete mode 100644 packages/server/src/services/Settings/SettingsService.ts delete mode 100644 packages/server/src/services/Settings/SettingsStore.ts delete mode 100644 packages/server/src/services/Settings/SmsNotificationsSettings.ts delete mode 100644 packages/server/src/services/Setup/SetupService.ts delete mode 100644 packages/server/src/services/SmsIntegration/EasySmsIntegration.ts delete mode 100644 packages/server/src/services/StripePayment/CreatePaymentReceivedStripePayment.ts delete mode 100644 packages/server/src/services/StripePayment/CreateStripeAccountLink.ts delete mode 100644 packages/server/src/services/StripePayment/CreateStripeAccountService.ts delete mode 100644 packages/server/src/services/StripePayment/ExchangeStripeOauthToken.ts delete mode 100644 packages/server/src/services/StripePayment/GetStripeAuthorizationLink.ts delete mode 100644 packages/server/src/services/StripePayment/StripePaymentApplication.ts delete mode 100644 packages/server/src/services/StripePayment/StripePaymentService.ts delete mode 100644 packages/server/src/services/StripePayment/events/SeedStripeAccounts.ts delete mode 100644 packages/server/src/services/StripePayment/events/StripeWebhooksSubscriber.ts delete mode 100644 packages/server/src/services/StripePayment/types.ts delete mode 100644 packages/server/src/services/Subscription/GetSubscriptionsTransformer.ts delete mode 100644 packages/server/src/services/Subscription/LemonCancelSubscription.ts delete mode 100644 packages/server/src/services/Subscription/LemonChangeSubscriptionPlan.ts delete mode 100644 packages/server/src/services/Subscription/LemonResumeSubscription.ts delete mode 100644 packages/server/src/services/Subscription/LemonSqueezyService.ts delete mode 100644 packages/server/src/services/Subscription/LemonSqueezyWebhooks.ts delete mode 100644 packages/server/src/services/Subscription/Subscription.ts delete mode 100644 packages/server/src/services/Subscription/SubscriptionApplication.ts delete mode 100644 packages/server/src/services/Subscription/SubscriptionPeriod.ts delete mode 100644 packages/server/src/services/Subscription/SubscriptionService.ts delete mode 100644 packages/server/src/services/Subscription/events/SubscribeFreeOnSignupCommunity.tsx delete mode 100644 packages/server/src/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange.tsx delete mode 100644 packages/server/src/services/Subscription/types.ts delete mode 100644 packages/server/src/services/Subscription/utils.ts delete mode 100644 packages/server/src/services/TaxRates/ActivateTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts delete mode 100644 packages/server/src/services/TaxRates/CreateTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/DeleteTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/EditTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/GetTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/GetTaxRates.ts delete mode 100644 packages/server/src/services/TaxRates/InactivateTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/ItemEntriesTaxTransactions.ts delete mode 100644 packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts delete mode 100644 packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts delete mode 100644 packages/server/src/services/TaxRates/TaxRateTransformer.ts delete mode 100644 packages/server/src/services/TaxRates/TaxRatesApplication.ts delete mode 100644 packages/server/src/services/TaxRates/TaxRatesExportable.ts delete mode 100644 packages/server/src/services/TaxRates/TaxRatesImportable.SampleData.ts delete mode 100644 packages/server/src/services/TaxRates/TaxRatesImportable.ts delete mode 100644 packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts delete mode 100644 packages/server/src/services/TaxRates/constants.ts delete mode 100644 packages/server/src/services/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts delete mode 100644 packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts delete mode 100644 packages/server/src/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts delete mode 100644 packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts delete mode 100644 packages/server/src/services/TemplateInjectable/TemplateInjectable.ts delete mode 100644 packages/server/src/services/Tenancy/SystemService.ts delete mode 100644 packages/server/src/services/Tenancy/TenancyService.ts delete mode 100644 packages/server/src/services/Tenancy/TenantDBManager.ts delete mode 100644 packages/server/src/services/Tenancy/TenantService.ts delete mode 100644 packages/server/src/services/Tenancy/TenantsManager.ts delete mode 100644 packages/server/src/services/TransactionsLocking/CommandTransactionsLockingService.ts delete mode 100644 packages/server/src/services/TransactionsLocking/FinancialTransactionLockingGuard.ts delete mode 100644 packages/server/src/services/TransactionsLocking/FinancialsTransactionLockingGuardSubscriber.ts delete mode 100644 packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuard.ts delete mode 100644 packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuardSubscriber.ts delete mode 100644 packages/server/src/services/TransactionsLocking/QueryTransactionsLocking.ts delete mode 100644 packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuard.ts delete mode 100644 packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuardSubscriber.ts delete mode 100644 packages/server/src/services/TransactionsLocking/TransactionsLockingGuard.ts delete mode 100644 packages/server/src/services/TransactionsLocking/TransactionsLockingMetaTransformer.ts delete mode 100644 packages/server/src/services/TransactionsLocking/TransactionsLockingRepository.ts delete mode 100644 packages/server/src/services/TransactionsLocking/constants.ts delete mode 100644 packages/server/src/services/UnitOfWork/TransactionsHooks.ts delete mode 100644 packages/server/src/services/UnitOfWork/index.ts delete mode 100644 packages/server/src/services/Users/PurgeUserAbilityCache.ts delete mode 100644 packages/server/src/services/Users/SyncTenantUserDeleted.ts delete mode 100644 packages/server/src/services/Users/SyncTenantUserSaved.ts delete mode 100644 packages/server/src/services/Users/UserTransformer.ts delete mode 100644 packages/server/src/services/Users/UsersService.ts delete mode 100644 packages/server/src/services/Users/constants.ts delete mode 100644 packages/server/src/services/Views/ViewsService.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/BillWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/CreditNoteWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/EstimateWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/InvoiceWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/ReceiptWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/Activate/VendorCreditWarehousesActivate.ts delete mode 100644 packages/server/src/services/Warehouses/ActivateWarehouses.ts delete mode 100644 packages/server/src/services/Warehouses/ActivateWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/CRUDWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/CreateInitialWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/CreateInitialWarehousesitemsQuantity.ts delete mode 100644 packages/server/src/services/Warehouses/CreateWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/DeleteItemWarehousesQuantity.ts delete mode 100644 packages/server/src/services/Warehouses/DeleteWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/EditWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/EventsProvider.ts delete mode 100644 packages/server/src/services/Warehouses/GetWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/GetWarehouses.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/ValidateWarehouseExistance.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/WarehousesDTOValidators.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantity.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySync.ts delete mode 100644 packages/server/src/services/Warehouses/Integrations/constants.ts delete mode 100644 packages/server/src/services/Warehouses/Items/GetItemWarehouses.ts delete mode 100644 packages/server/src/services/Warehouses/Items/GettItemWarehouseTransformer.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/BillWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/EstimateWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Activate/index.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/DeleteItemWarehousesQuantitySubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/BillWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/Subscribers/Validators/index.ts delete mode 100644 packages/server/src/services/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts delete mode 100644 packages/server/src/services/Warehouses/WarehouseMarkPrimary.ts delete mode 100644 packages/server/src/services/Warehouses/WarehouseValidator.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesApplication.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesService.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesSettings.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/CRUDWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/CommandWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/CreateWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/DeleteWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/EditWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfers.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/InitiateWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/TransferredWarehouseTransfer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferApplication.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrement.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferInventoryTransactionsSubscriber.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferItemTransformer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferTransfomer.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/WriteInventoryTransactions.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfers/constants.ts delete mode 100644 packages/server/src/services/Warehouses/WarehousesTransfersService.ts delete mode 100644 packages/server/src/services/Warehouses/contants.ts delete mode 100644 packages/server/src/subscribers/Authentication/ResetLoginThrottle.ts delete mode 100644 packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts delete mode 100644 packages/server/src/subscribers/Bills/WriteInventoryTransactions.ts delete mode 100644 packages/server/src/subscribers/Bills/index.ts delete mode 100644 packages/server/src/subscribers/Inventory/Inventory.ts delete mode 100644 packages/server/src/subscribers/Inventory/InventoryAdjustment.ts delete mode 100644 packages/server/src/subscribers/LandedCost/index.ts delete mode 100644 packages/server/src/subscribers/Organization/BuildSmsNotification.ts delete mode 100644 packages/server/src/subscribers/Organization/SyncTenantAdminUser.ts delete mode 100644 packages/server/src/subscribers/PaymentMades/PaymentSyncBillBalance.ts delete mode 100644 packages/server/src/subscribers/PaymentReceive/AutoSerialIncrement.ts delete mode 100644 packages/server/src/subscribers/PaymentReceive/PaymentReceiveSyncInvoices.ts delete mode 100644 packages/server/src/subscribers/PaymentReceive/SendSmsNotificationToCustomer.ts delete mode 100644 packages/server/src/subscribers/PaymentReceive/WriteGLEntries.ts delete mode 100644 packages/server/src/subscribers/SaleEstimate/AutoIncrementSerial.ts delete mode 100644 packages/server/src/subscribers/SaleEstimate/SmsNotifications.ts delete mode 100644 packages/server/src/subscribers/SaleInvoices/AutoIncrementSerial.ts delete mode 100644 packages/server/src/subscribers/SaleInvoices/ConvertFromEstimate.ts delete mode 100644 packages/server/src/subscribers/SaleInvoices/SendSmsNotificationToCustomer.ts delete mode 100644 packages/server/src/subscribers/SaleInvoices/WriteInventoryTransactions.ts delete mode 100644 packages/server/src/subscribers/SaleInvoices/WriteJournalEntries.ts delete mode 100644 packages/server/src/subscribers/SaleReceipt/AutoIncrementSerial.ts delete mode 100644 packages/server/src/subscribers/SaleReceipt/SendSmsNotificationToCustomer.ts delete mode 100644 packages/server/src/subscribers/SaleReceipt/WriteInventoryTransactions.ts delete mode 100644 packages/server/src/subscribers/SaleReceipt/WriteJournalEntries.ts delete mode 100644 packages/server/src/subscribers/events.ts delete mode 100644 packages/server/src/system/migrations/20190104195900_create_password_resets_table.js delete mode 100644 packages/server/src/system/migrations/20200420134631_create_tenants_table.js delete mode 100644 packages/server/src/system/migrations/20200420134633_create_users_table.js delete mode 100644 packages/server/src/system/migrations/20200422225247_create_user_invites_table.js delete mode 100644 packages/server/src/system/migrations/20200527091642_create_subscriptions_plans_table.js delete mode 100644 packages/server/src/system/migrations/20200823234134_create_plans_table.js delete mode 100644 packages/server/src/system/migrations/20200823234636_create_subscription_plan_subscription.js delete mode 100644 packages/server/src/system/migrations/20200823235340_create_tenants_metadata_table.js delete mode 100644 packages/server/src/system/migrations/20230405011450_drop_phone_number_column_from_users_table.js delete mode 100644 packages/server/src/system/migrations/20231012112401_add_tax_number_column_to_tenants_metadata_table.js delete mode 100644 packages/server/src/system/migrations/20231209230719_create_imports_table.js delete mode 100644 packages/server/src/system/migrations/20240222134235_create_plaid_items_table.js delete mode 100644 packages/server/src/system/migrations/20240222134235_seed_free_subscription_to_tenants.js delete mode 100644 packages/server/src/system/migrations/20240425100821_add_confirmation_columns_to_users.js delete mode 100644 packages/server/src/system/migrations/20240714101006_add_lemon_variant_id_to_subscription_plans.js delete mode 100644 packages/server/src/system/migrations/20240714101229_seed_monthly_subscription_plans.js delete mode 100644 packages/server/src/system/migrations/20240727094214_add_lemon_subscription_id_to_subscriptions_table.js delete mode 100644 packages/server/src/system/migrations/20240728123419_add_trial_columns_to_subscription_table.js delete mode 100644 packages/server/src/system/migrations/20240819164614_create_oneclick_demos_table.js delete mode 100644 packages/server/src/system/migrations/20240824151006_add_payment_status_to_subscriptions_table.js delete mode 100644 packages/server/src/system/migrations/20240909091320_create_stripe_connect_accounts_table.js delete mode 100644 packages/server/src/system/migrations/20240915070439_create_payment_links_table.js delete mode 100644 packages/server/src/system/migrations/20240928145627_add_logo_key_to_tenant_metadata.js delete mode 100644 packages/server/src/system/models/Import.ts delete mode 100644 packages/server/src/system/models/Invite.ts delete mode 100644 packages/server/src/system/models/OneclickDemo.ts delete mode 100644 packages/server/src/system/models/PasswordReset.ts delete mode 100644 packages/server/src/system/models/PaymentLink.ts delete mode 100644 packages/server/src/system/models/StripeAccount.ts delete mode 100644 packages/server/src/system/models/Subscriptions/Plan.ts delete mode 100644 packages/server/src/system/models/Subscriptions/PlanSubscription.ts delete mode 100644 packages/server/src/system/models/SystemModel.ts delete mode 100644 packages/server/src/system/models/SystemPlaidItem.ts delete mode 100644 packages/server/src/system/models/SystemUser.ts delete mode 100644 packages/server/src/system/models/Tenant.ts delete mode 100644 packages/server/src/system/models/TenantMetadata.ts delete mode 100644 packages/server/src/system/models/index.ts delete mode 100644 packages/server/src/system/repositories/SubscriptionRepository.ts delete mode 100644 packages/server/src/system/repositories/SystemRepository.ts delete mode 100644 packages/server/src/system/repositories/SystemUserRepository.ts delete mode 100644 packages/server/src/system/repositories/TenantRepository.ts delete mode 100644 packages/server/src/system/repositories/index.ts delete mode 100644 packages/server/src/system/seeds/seed_subscriptions_plans.js delete mode 100644 packages/server/src/system/seeds/seed_tenants_free_subscription.js rename packages/{server-nest => server}/src/utils/accum-sum.ts (100%) rename packages/{server-nest => server}/src/utils/all-conditions-passed.ts (100%) rename packages/{server-nest => server}/src/utils/assoc-depth-level-to-object-tree.ts (100%) rename packages/{server-nest => server}/src/utils/associate-item-entries-index.ts (100%) rename packages/{server-nest => server}/src/utils/cast-comma-list-envvar-Array.ts (100%) rename packages/{server-nest => server}/src/utils/date-range-collection.ts (100%) rename packages/{server-nest => server}/src/utils/entries-amount-diff.ts (100%) rename packages/{server-nest => server}/src/utils/flat-to-nested-array.ts (100%) rename packages/{server-nest => server}/src/utils/format-date-fields.ts (100%) rename packages/{server-nest => server}/src/utils/format-message.ts (100%) rename packages/{server-nest => server}/src/utils/format-number.ts (100%) delete mode 100644 packages/server/src/utils/formatMinutes.ts rename packages/{server-nest => server}/src/utils/increment.ts (100%) delete mode 100644 packages/server/src/utils/index.ts rename packages/{server-nest => server}/src/utils/is-blank.ts (100%) rename packages/{server-nest => server}/src/utils/items-start-with.ts (100%) rename packages/{server-nest => server}/src/utils/moment-mysql.ts (100%) delete mode 100644 packages/server/src/utils/multi-number-parse.test.ts delete mode 100644 packages/server/src/utils/multi-number-parse.ts rename packages/{server-nest => server}/src/utils/nested-array-to-flatten.ts (100%) rename packages/{server-nest => server}/src/utils/parse-boolean.ts (100%) delete mode 100644 packages/server/src/utils/parse-json-safe.ts rename packages/{server-nest => server}/src/utils/sanitize-database-name.ts (100%) delete mode 100644 packages/server/src/utils/sanitizers.ts delete mode 100644 packages/server/src/utils/table.ts delete mode 100644 packages/server/src/utils/taxRate.ts rename packages/{server-nest => server}/src/utils/template-render.ts (100%) rename packages/{server-nest => server}/src/utils/transaction-increment.ts (100%) delete mode 100644 packages/server/src/utils/transactions-types.ts rename packages/{server-nest => server}/src/utils/transform-to-key.ts (100%) rename packages/{server-nest => server}/src/utils/transform-to-map-by.ts (100%) rename packages/{server-nest => server}/src/utils/transform-to-map-key-value.ts (100%) rename packages/{server-nest => server}/static/demo-sheets/Expenses.csv (100%) rename packages/{server-nest => server}/static/demo-sheets/bank-transactions.csv (100%) rename packages/{server-nest => server}/static/demo-sheets/customers.csv (100%) rename packages/{server-nest => server}/static/demo-sheets/items.csv (100%) rename packages/{server-nest => server}/static/demo-sheets/manual-journals.csv (100%) rename packages/{server-nest => server}/static/demo-sheets/sale-invoices.csv (100%) rename packages/{server-nest => server}/static/demo-sheets/vendors.csv (100%) rename packages/{server-nest => server}/static/images/bigcapital.png (100%) rename packages/{server-nest => server}/static/mail/ResetPassword.html (100%) rename packages/{server-nest => server}/static/mail/SignupVerifyEmail.html (100%) rename packages/{server-nest => server}/static/mail/UserInvite.html (100%) delete mode 100644 packages/server/storage/.gitignore delete mode 100644 packages/server/storage/imports/.gitignore delete mode 100644 packages/server/storage/pdf/.gitignore rename packages/{server-nest => server}/test/auth.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/bank-rules.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/banking-transactions.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/branches.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/credit-notes.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/customers.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/expenses.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/init-app-test.ts (100%) rename packages/{server-nest => server}/test/inventory-adjustment.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/item-categories.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/items.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/jest-e2e.json (100%) rename packages/{server-nest => server}/test/manual-journal.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/organization.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/payment-received.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/pdf-templates.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/sale-estimates.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/sale-invoices.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/sale-receipts.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/settings.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/tax-rates.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/transactions-locking.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/vendor-credits.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/vendors.e2e-spec.ts (100%) rename packages/{server-nest => server}/test/warehouses.e2e-spec.ts (100%) delete mode 100644 packages/server/tests/collection/NestedSet.test.js delete mode 100644 packages/server/tests/dbInit.js delete mode 100644 packages/server/tests/docker-compose.yml delete mode 100644 packages/server/tests/lib/CachableModel.test.js delete mode 100644 packages/server/tests/lib/MetableStore.test.ts delete mode 100644 packages/server/tests/models/Account.test.js delete mode 100644 packages/server/tests/models/AccountType.test.js delete mode 100644 packages/server/tests/models/Expense.test.js delete mode 100644 packages/server/tests/models/ExpenseCategory.test.js delete mode 100644 packages/server/tests/models/Item.test.js delete mode 100644 packages/server/tests/models/ItemCategories.test.js delete mode 100644 packages/server/tests/models/Resource.test.js delete mode 100644 packages/server/tests/models/User.test.js delete mode 100644 packages/server/tests/models/View.test.js delete mode 100644 packages/server/tests/mysql-tmpfs.sh delete mode 100644 packages/server/tests/routes/accounting.test.js delete mode 100644 packages/server/tests/routes/accounts.test.js delete mode 100644 packages/server/tests/routes/auth.test.js delete mode 100644 packages/server/tests/routes/balance_sheet.test.js delete mode 100644 packages/server/tests/routes/bill_payments.test.js delete mode 100644 packages/server/tests/routes/bills.test.js delete mode 100644 packages/server/tests/routes/currencies.test.js delete mode 100644 packages/server/tests/routes/customers.test.js delete mode 100644 packages/server/tests/routes/exchange_rates.test.js delete mode 100644 packages/server/tests/routes/expenses.test.js delete mode 100644 packages/server/tests/routes/financial_statements.test.js delete mode 100644 packages/server/tests/routes/inviteUsers.test.js delete mode 100644 packages/server/tests/routes/items.test.js delete mode 100644 packages/server/tests/routes/itemsCategories.test.js delete mode 100644 packages/server/tests/routes/options.test.js delete mode 100644 packages/server/tests/routes/payable_aging.test.js delete mode 100644 packages/server/tests/routes/payment_receives.test.js delete mode 100644 packages/server/tests/routes/receivable_aging.test.js delete mode 100644 packages/server/tests/routes/sales_estimates.test.js delete mode 100644 packages/server/tests/routes/sales_invoices.test.js delete mode 100644 packages/server/tests/routes/sales_receipts.test.js delete mode 100644 packages/server/tests/routes/users.test.js delete mode 100644 packages/server/tests/routes/vendors.test.js delete mode 100644 packages/server/tests/routes/views.test.js delete mode 100644 packages/server/tests/services/JournalPoster.test.js delete mode 100644 packages/server/tests/testInit.js delete mode 100644 packages/server/tests/utils/utils.test.js rename packages/{server-nest => server}/tsconfig.build.json (100%) delete mode 100644 packages/server/views/.DS_Store delete mode 100644 packages/server/views/demo-sheets/Expenses.csv delete mode 100644 packages/server/views/demo-sheets/bank-transactions.csv delete mode 100644 packages/server/views/demo-sheets/customers.csv delete mode 100644 packages/server/views/demo-sheets/items.csv delete mode 100644 packages/server/views/demo-sheets/manual-journals.csv delete mode 100644 packages/server/views/demo-sheets/sale-invoices.csv delete mode 100644 packages/server/views/demo-sheets/vendors.csv delete mode 100644 packages/server/views/images/bigcapital.png delete mode 100644 packages/server/views/mail/ResetPassword.html delete mode 100644 packages/server/views/mail/SignupVerifyEmail.html delete mode 100644 packages/server/views/mail/UserInvite.html diff --git a/packages/server-nest/.eslintrc.js b/packages/server-nest/.eslintrc.js deleted file mode 100644 index 259de13c7..000000000 --- a/packages/server-nest/.eslintrc.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: __dirname, - sourceType: 'module', - }, - plugins: ['@typescript-eslint/eslint-plugin'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], - root: true, - env: { - node: true, - jest: true, - }, - ignorePatterns: ['.eslintrc.js'], - rules: { - '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', - }, -}; diff --git a/packages/server-nest/.gitignore b/packages/server-nest/.gitignore deleted file mode 100644 index 4b56acfbe..000000000 --- a/packages/server-nest/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -# compiled output -/dist -/node_modules -/build - -# Logs -logs -*.log -npm-debug.log* -pnpm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# OS -.DS_Store - -# Tests -/coverage -/.nyc_output - -# IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# IDE - VSCode -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# temp directory -.temp -.tmp - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/packages/server-nest/README.md b/packages/server-nest/README.md deleted file mode 100644 index f149ff9af..000000000 --- a/packages/server-nest/README.md +++ /dev/null @@ -1 +0,0 @@ -## @bigcapitalhq/server \ No newline at end of file diff --git a/packages/server-nest/package.json b/packages/server-nest/package.json deleted file mode 100644 index 9eb37819a..000000000 --- a/packages/server-nest/package.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "name": "@bigcapital/server2", - "version": "0.0.1", - "description": "", - "author": "", - "private": true, - "license": "UNLICENSED", - "scripts": { - "build": "nest build", - "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", - "start": "nest start", - "start:dev": "nest start --watch", - "start:debug": "nest start --debug --watch", - "start:prod": "node dist/main", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", - "test": "jest", - "test:watch": "jest --watch", - "test:cov": "jest --coverage", - "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json --watchAll" - }, - "dependencies": { - "@aws-sdk/client-s3": "^3.576.0", - "@aws-sdk/s3-request-presigner": "^3.583.0", - "@bigcapital/email-components": "*", - "@bigcapital/pdf-templates": "*", - "@bigcapital/utils": "*", - "@casl/ability": "^5.4.3", - "@lemonsqueezy/lemonsqueezy.js": "^2.2.0", - "@liaoliaots/nestjs-redis": "^10.0.0", - "@types/multer": "^1.4.11", - "@nestjs/bull": "^10.2.1", - "@nestjs/bullmq": "^10.2.2", - "@nestjs/cache-manager": "^2.2.2", - "@nestjs/common": "^10.0.0", - "@nestjs/config": "^3.2.3", - "@nestjs/core": "^10.0.0", - "@nestjs/event-emitter": "^2.0.4", - "@nestjs/jwt": "^10.2.0", - "@nestjs/passport": "^11.0.5", - "@nestjs/platform-express": "^10.0.0", - "@nestjs/swagger": "^7.4.2", - "@nestjs/throttler": "^6.2.1", - "@supercharge/promise-pool": "^3.2.0", - "@types/nodemailer": "^6.4.17", - "@types/passport-local": "^1.0.38", - "@types/ramda": "^0.30.2", - "accounting": "^0.4.1", - "async": "^3.2.0", - "async-mutex": "^0.5.0", - "axios": "^1.6.0", - "bcrypt": "^5.1.1", - "bcryptjs": "^2.4.3", - "bluebird": "^3.7.2", - "bull": "^4.16.3", - "bullmq": "^5.25.6", - "cache-manager": "^6.1.1", - "cache-manager-redis-store": "^3.0.1", - "class-transformer": "^0.5.1", - "class-validator": "^0.14.1", - "deepdash": "^5.3.9", - "express-validator": "^7.2.0", - "form-data": "^4.0.0", - "fp-ts": "^2.16.9", - "ioredis": "^5.6.0", - "is-my-json-valid": "^2.20.5", - "js-money": "^0.6.3", - "knex": "^3.1.0", - "lamda": "^0.4.1", - "lodash": "^4.17.21", - "lru-cache": "^6.0.0", - "mathjs": "^9.4.0", - "mime-types": "^2.1.35", - "moment": "^2.30.1", - "moment-range": "^4.0.2", - "moment-timezone": "^0.5.43", - "mysql": "^2.18.1", - "mysql2": "^3.11.3", - "multer": "1.4.5-lts.1", - "multer-s3": "^3.0.1", - "nestjs-cls": "^5.2.0", - "nestjs-i18n": "^10.4.9", - "nestjs-redis": "^1.3.3", - "nodemailer": "^6.3.0", - "object-hash": "^2.0.3", - "objection": "^3.1.5", - "passport": "^0.7.0", - "passport-jwt": "^4.0.1", - "passport-local": "^1.0.0", - "plaid": "^10.3.0", - "pluralize": "^8.0.0", - "posthog-node": "^4.3.2", - "pug": "^3.0.2", - "ramda": "^0.30.1", - "redis": "^4.7.0", - "reflect-metadata": "^0.2.0", - "remeda": "^2.19.2", - "rxjs": "^7.8.1", - "serialize-interceptor": "^1.1.7", - "strategy": "^1.1.1", - "stripe": "^16.10.0", - "uniqid": "^5.2.0", - "uuid": "^10.0.0", - "xlsx": "^0.18.5", - "yup": "^0.28.1", - "zod": "^3.23.8" - }, - "devDependencies": { - "@nestjs/cli": "^10.0.0", - "@nestjs/schematics": "^10.0.0", - "@nestjs/testing": "^10.0.0", - "@types/express": "^5.0.0", - "@types/jest": "^29.5.2", - "@types/mathjs": "^6.0.12", - "@types/node": "^20.3.1", - "@types/supertest": "^6.0.0", - "@types/yup": "^0.29.13", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "eslint": "^9.0.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^5.0.0", - "jest": "^29.5.0", - "mustache": "^3.0.3", - "prettier": "^3.0.0", - "source-map-support": "^0.5.21", - "supertest": "^7.0.0", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.3", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "typescript": "^5.1.3" - }, - "jest": { - "moduleFileExtensions": [ - "js", - "json", - "ts" - ], - "rootDir": "src", - "testRegex": ".*\\.spec\\.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - }, - "collectCoverageFrom": [ - "**/*.(t|j)s" - ], - "coverageDirectory": "../coverage", - "testEnvironment": "node" - } -} diff --git a/packages/server-nest/src/database/migrations/20220329121920_add_seed_at_column_to_accounts.ts b/packages/server-nest/src/database/migrations/20220329121920_add_seed_at_column_to_accounts.ts deleted file mode 100644 index 257602b05..000000000 --- a/packages/server-nest/src/database/migrations/20220329121920_add_seed_at_column_to_accounts.ts +++ /dev/null @@ -1,7 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('accounts', (table) => { - table.date('seeded_at').after('currency_code').nullable(); - }); -}; - -exports.down = (knex) => {}; diff --git a/packages/server-nest/src/database/migrations/20220429121920_create_projects_table.ts b/packages/server-nest/src/database/migrations/20220429121920_create_projects_table.ts deleted file mode 100644 index 96518246f..000000000 --- a/packages/server-nest/src/database/migrations/20220429121920_create_projects_table.ts +++ /dev/null @@ -1,93 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .createTable('projects', (table) => { - table.increments('id').comment('Auto-generated id'); - table.string('name'); - table.integer('contact_id').unsigned(); - table.date('deadline'); - table.decimal('cost_estimate'); - table.string('status'); - table.timestamps(); - }) - .createTable('tasks', (table) => { - table.increments('id').comment('Auto-generated id'); - table.string('name'); - table.string('charge_type'); - table.decimal('rate'); - table.decimal('estimate_hours').unsigned(); - table.decimal('actual_hours').unsigned(); - table.decimal('invoiced_hours').unsigned().default(0); - table - .integer('project_id') - .unsigned() - .references('id') - .inTable('projects'); - table.timestamps(); - }) - .createTable('times', (table) => { - table.increments('id').comment('Auto-generated id'); - table.integer('duration').unsigned(); - table.string('description'); - table.date('date'); - - table.integer('taskId').unsigned().references('id').inTable('tasks'); - table - .integer('project_id') - .unsigned() - .references('id') - .inTable('projects'); - table.timestamps(); - }) - .table('accounts_transactions', (table) => { - table - .integer('projectId') - .unsigned() - .references('id') - .inTable('projects'); - }) - .table('manual_journals_entries', (table) => { - table - .integer('projectId') - .unsigned() - .references('id') - .inTable('projects'); - }) - .table('bills', (table) => { - table - .integer('projectId') - .unsigned() - .references('id') - .inTable('projects'); - table.decimal('invoiced_amount').unsigned().defaultTo(0); - }) - .table('items_entries', (table) => { - table - .integer('projectId') - .unsigned() - .references('id') - .inTable('projects'); - - table.integer('project_ref_id').unsigned(); - table.string('project_ref_type'); - table.decimal('project_ref_invoiced_amount').unsigned().defaultTo(0); - }) - .table('sales_invoices', (table) => { - table - .integer('projectId') - .unsigned() - .references('id') - .inTable('projects'); - }) - .table('expenses_transactions', (table) => { - table - .integer('projectId') - .unsigned() - .references('id') - .inTable('projects'); - table.decimal('invoiced_amount').unsigned().defaultTo(0); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTable('tasks'); -}; diff --git a/packages/server-nest/src/database/migrations/20220429121922_add_project_id_to_expense_lines.ts b/packages/server-nest/src/database/migrations/20220429121922_add_project_id_to_expense_lines.ts deleted file mode 100644 index 7d3931f35..000000000 --- a/packages/server-nest/src/database/migrations/20220429121922_add_project_id_to_expense_lines.ts +++ /dev/null @@ -1,7 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('expense_transaction_categories', (table) => { - table.integer('projectId').unsigned().references('id').inTable('projects'); - }); -}; - -exports.down = (knex) => {}; diff --git a/packages/server-nest/src/database/seeds/core/20190423085242_seed_accounts.ts b/packages/server-nest/src/database/seeds/core/20190423085242_seed_accounts.ts deleted file mode 100644 index 303a4281a..000000000 --- a/packages/server-nest/src/database/seeds/core/20190423085242_seed_accounts.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; -import { AccountsData } from '../data/accounts'; - -export default class SeedAccounts extends TenantSeeder { - /** - * Seeds initial accounts to the organization. - */ - up(knex) { - const data = AccountsData.map((account) => ({ - ...account, - name: this.i18n.t(account.name), - description: account.description ? this.i18n.t(account.description) : '', - currencyCode: this.tenant.metadata.baseCurrency, - seededAt: new Date(), - })); - return knex('accounts').then(async () => { - // Inserts seed entries. - return knex('accounts').insert(data); - }); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20200810121809_seed_settings.ts b/packages/server-nest/src/database/seeds/core/20200810121809_seed_settings.ts deleted file mode 100644 index 70948f36c..000000000 --- a/packages/server-nest/src/database/seeds/core/20200810121809_seed_settings.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; - -export default class SeedSettings extends TenantSeeder { - /** - * - * @returns - */ - up() { - const settings = [ - // Orgnization settings. - { group: 'organization', key: 'accounting_basis', value: 'accrual' }, - - // Accounts settings. - { group: 'accounts', key: 'account_code_unique', value: true }, - - // Manual journals settings. - { group: 'manual_journals', key: 'next_number', value: '00001' }, - { group: 'manual_journals', key: 'number_prefix', value: 'J-' }, - { group: 'manual_journals', key: 'auto_increment', value: true }, - - // Sale invoices settings. - { group: 'sales_invoices', key: 'next_number', value: '00001' }, - { group: 'sales_invoices', key: 'number_prefix', value: 'INV-' }, - { group: 'sales_invoices', key: 'auto_increment', value: true }, - - // Sale receipts settings. - { group: 'sales_receipts', key: 'next_number', value: '00001' }, - { group: 'sales_receipts', key: 'number_prefix', value: 'REC-' }, - { group: 'sales_receipts', key: 'auto_increment', value: true }, - - // Sale estimates settings. - { group: 'sales_estimates', key: 'next_number', value: '00001' }, - { group: 'sales_estimates', key: 'number_prefix', value: 'EST-' }, - { group: 'sales_estimates', key: 'auto_increment', value: true }, - - // Payment receives settings. - { group: 'payment_receives', key: 'number_prefix', value: 'PAY-' }, - { group: 'payment_receives', key: 'next_number', value: '00001' }, - { group: 'payment_receives', key: 'auto_increment', value: true }, - - // Cashflow settings. - { group: 'cashflow', key: 'number_prefix', value: 'CF-' }, - { group: 'cashflow', key: 'next_number', value: '00001' }, - { group: 'cashflow', key: 'auto_increment', value: true }, - - // warehouse transfers settings. - { group: 'warehouse_transfers', key: 'next_number', value: '00001' }, - { group: 'warehouse_transfers', key: 'number_prefix', value: 'WT-' }, - { group: 'warehouse_transfers', key: 'auto_increment', value: true }, - ]; - return this.knex('settings').insert(settings); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20200810121909_seed_items_settings.ts b/packages/server-nest/src/database/seeds/core/20200810121909_seed_items_settings.ts deleted file mode 100644 index b07e5c39e..000000000 --- a/packages/server-nest/src/database/seeds/core/20200810121909_seed_items_settings.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; - -export default class SeedSettings extends TenantSeeder { - /** - * - * @param knex - * @returns - */ - async up(knex) { - const costAccount = await knex('accounts') - .where('slug', 'cost-of-goods-sold') - .first(); - - const sellAccount = await knex('accounts') - .where('slug', 'sales-of-product-income') - .first(); - - const inventoryAccount = await knex('accounts') - .where('slug', 'inventory-asset') - .first(); - - const settings = [ - // Items settings. - { group: 'items', key: 'preferred_sell_account', value: sellAccount?.id }, - { group: 'items', key: 'preferred_cost_account', value: costAccount?.id }, - { - group: 'items', - key: 'preferred_inventory_account', - value: inventoryAccount?.id, - }, - ]; - return knex('settings').insert(settings); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20210810121909_seed_roles.ts b/packages/server-nest/src/database/seeds/core/20210810121909_seed_roles.ts deleted file mode 100644 index 10ac1e49a..000000000 --- a/packages/server-nest/src/database/seeds/core/20210810121909_seed_roles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; - -export default class SeedRolesAndPermissions extends TenantSeeder { - /** - * Seeds roles and associated permissiojns. - * @param knex - * @returns - */ - // eslint-disable-next-line class-methods-use-this - async up(knex) { - return knex('roles').insert([ - { - id: 1, - name: 'role.admin.name', - predefined: true, - slug: 'admin', - description: 'role.admin.desc', - }, - { - id: 2, - name: 'role.staff.name', - predefined: true, - slug: 'staff', - description: 'role.staff.desc', - }, - ]); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20210812121909_seed_roles_permissions.ts b/packages/server-nest/src/database/seeds/core/20210812121909_seed_roles_permissions.ts deleted file mode 100644 index b6493f1e6..000000000 --- a/packages/server-nest/src/database/seeds/core/20210812121909_seed_roles_permissions.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; - -export default class SeedRolesAndPermissions extends TenantSeeder { - /** - * Seeds roles and associated permissiojns. - * @param knex - * @returns - */ - // eslint-disable-next-line class-methods-use-this - async up(knex) { - return knex('role_permissions').insert([ - // Assign sale invoice permissions to staff role. - { roleId: 2, subject: 'SaleInvoice', ability: 'create' }, - { roleId: 2, subject: 'SaleInvoice', ability: 'delete' }, - { roleId: 2, subject: 'SaleInvoice', ability: 'view' }, - { roleId: 2, subject: 'SaleInvoice', ability: 'edit' }, - - // Assign sale estimate permissions to staff role. - { roleId: 2, subject: 'SaleEstimate', ability: 'create' }, - { roleId: 2, subject: 'SaleEstimate', ability: 'delete' }, - { roleId: 2, subject: 'SaleEstimate', ability: 'view' }, - { roleId: 2, subject: 'SaleEstimate', ability: 'edit' }, - - // Assign sale receipt permissions to staff role. - { roleId: 2, subject: 'SaleReceipt', ability: 'create' }, - { roleId: 2, subject: 'SaleReceipt', ability: 'delete' }, - { roleId: 2, subject: 'SaleReceipt', ability: 'view' }, - { roleId: 2, subject: 'SaleReceipt', ability: 'edit' }, - - // Assign payment receive permissions to staff role. - { roleId: 2, subject: 'PaymentReceive', ability: 'create' }, - { roleId: 2, subject: 'PaymentReceive', ability: 'delete' }, - { roleId: 2, subject: 'PaymentReceive', ability: 'view' }, - { roleId: 2, subject: 'PaymentReceive', ability: 'edit' }, - - // Assign bill permissions to staff role. - { roleId: 2, subject: 'Bill', ability: 'create' }, - { roleId: 2, subject: 'Bill', ability: 'delete' }, - { roleId: 2, subject: 'Bill', ability: 'view' }, - { roleId: 2, subject: 'Bill', ability: 'edit' }, - - // Assign payment made permissions to staff role. - { roleId: 2, subject: 'PaymentMade', ability: 'create' }, - { roleId: 2, subject: 'PaymentMade', ability: 'delete' }, - { roleId: 2, subject: 'PaymentMade', ability: 'view' }, - { roleId: 2, subject: 'PaymentMade', ability: 'edit' }, - ]); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20210912121909_seed_credit_settings.ts b/packages/server-nest/src/database/seeds/core/20210912121909_seed_credit_settings.ts deleted file mode 100644 index 6defb942e..000000000 --- a/packages/server-nest/src/database/seeds/core/20210912121909_seed_credit_settings.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; - -export default class SeedCustomerVendorCreditSettings extends TenantSeeder { - /** - * - * @returns - */ - up() { - const settings = [ - // Credit note. - { group: 'credit_note', key: 'number_prefix', value: 'CN-' }, - { group: 'credit_note', key: 'next_number', value: '00001' }, - { group: 'credit_note', key: 'auto_increment', value: true }, - - // Vendor credit. - { group: 'vendor_credit', key: 'number_prefix', value: 'VC-' }, - { group: 'vendor_credit', key: 'next_number', value: '00001' }, - { group: 'vendor_credit', key: 'auto_increment', value: true }, - ]; - return this.knex('settings').insert(settings); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20230912121909_seed_tax_rates.ts b/packages/server-nest/src/database/seeds/core/20230912121909_seed_tax_rates.ts deleted file mode 100644 index 4a11fa4fc..000000000 --- a/packages/server-nest/src/database/seeds/core/20230912121909_seed_tax_rates.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; -import { InitialTaxRates } from '../data/TaxRates'; - -export default class SeedTaxRates extends TenantSeeder { - /** - * Seeds initial tax rates to the organization. - */ - up(knex) { - return knex('tax_rates').then(async () => { - // Inserts seed entries. - return knex('tax_rates').insert(InitialTaxRates); - }); - } -} diff --git a/packages/server-nest/src/database/seeds/core/20230912121909_update_tax_payable_account.ts b/packages/server-nest/src/database/seeds/core/20230912121909_update_tax_payable_account.ts deleted file mode 100644 index 352d2b0b3..000000000 --- a/packages/server-nest/src/database/seeds/core/20230912121909_update_tax_payable_account.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; -import { InitialTaxRates } from '../data/TaxRates'; - -export default class UpdateTaxPayableAccount extends TenantSeeder { - /** - * Seeds initial tax rates to the organization. - */ - up(knex) { - return knex('accounts').then(async () => { - // Inserts seed entries. - return knex('accounts').where('slug', 'tax-payable').update({ - account_type: 'tax-payable', - }); - }); - } -} diff --git a/packages/server-nest/src/database/seeds/core/index.ts b/packages/server-nest/src/database/seeds/core/index.ts deleted file mode 100644 index 0b95c889d..000000000 --- a/packages/server-nest/src/database/seeds/core/index.ts +++ /dev/null @@ -1 +0,0 @@ -// .gitkeep \ No newline at end of file diff --git a/packages/server-nest/src/database/seeds/data/TaxRates.ts b/packages/server-nest/src/database/seeds/data/TaxRates.ts deleted file mode 100644 index 592b60565..000000000 --- a/packages/server-nest/src/database/seeds/data/TaxRates.ts +++ /dev/null @@ -1,30 +0,0 @@ -export const InitialTaxRates = [ - { - name: 'Tax Exempt', - code: 'TAX-EXEMPT', - description: 'Exempts goods or services from taxes.', - rate: 0, - active: 1, - }, - { - name: 'Tax on Purchases', - code: 'TAX-PURCHASES', - description: 'Fee added to the cost when you buy items.', - rate: 0, - active: 1, - }, - { - name: 'Tax on Sales', - code: 'TAX-SALES', - description: 'Fee added to the cost when you sell items.', - rate: 0, - active: 1, - }, - { - name: 'Sales Tax on Imports', - code: 'TAX-IMPORTS', - description: 'Fee added to the cost when you sale to another country.', - rate: 0, - active: 1, - }, -]; diff --git a/packages/server-nest/src/interfaces/Account.ts b/packages/server-nest/src/interfaces/Account.ts deleted file mode 100644 index 9fb905e3f..000000000 --- a/packages/server-nest/src/interfaces/Account.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { Knex } from 'knex'; - -export interface IAccountDTO { - name: string; - code: string; - description: string; - accountType: string; - parentAccountId?: number; - active: boolean; - bankBalance?: number; - accountMask?: string; -} - -export interface IAccountCreateDTO extends IAccountDTO { - currencyCode?: string; - plaidAccountId?: string; - plaidItemId?: string; -} - -export interface IAccountEditDTO extends IAccountDTO {} - -export interface IAccount { - id: number; - name: string; - slug: string; - code: string; - index: number; - description: string; - accountType: string; - parentAccountId: number; - active: boolean; - predefined: boolean; - amount: number; - currencyCode: string; - transactions?: any[]; - type?: any[]; - accountNormal: string; - accountParentType: string; - bankBalance: string; - plaidItemId: number | null; - lastFeedsUpdatedAt: Date; -} - -export enum AccountNormal { - DEBIT = 'debit', - CREDIT = 'credit', -} - -export interface IAccountsTransactionsFilter { - accountId?: number; - limit?: number; -} - -export interface IAccountTransaction { - id?: number; - - credit: number; - debit: number; - currencyCode: string; - exchangeRate: number; - - accountId: number; - contactId?: number | null; - date: string | Date; - - referenceType: string; - referenceTypeFormatted: string; - referenceId: number; - - referenceNumber?: string; - - transactionNumber?: string; - transactionType?: string; - - note?: string; - - index: number; - indexGroup?: number; - - costable?: boolean; - - userId?: number; - itemId?: number; - branchId?: number; - projectId?: number; - - account?: IAccount; - - taxRateId?: number; - taxRate?: number; -} -export interface IAccountResponse extends IAccount {} - -export enum IAccountsStructureType { - Tree = 'tree', - Flat = 'flat', -} - -export interface IAccountsFilter { - stringifiedFilterRoles?: string; - onlyInactive: boolean; - structure?: IAccountsStructureType; -} - -export interface IAccountType { - label: string; - key: string; - normal: string; - rootType: string; - childType: string; - balanceSheet: boolean; - incomeSheet: boolean; -} - -export interface IAccountsTypesService { - getAccountsTypes(tenantId: number): Promise; -} - -export interface IAccountEventCreatingPayload { - accountDTO: any; - trx: Knex.Transaction; -} -export interface IAccountEventCreatedPayload { - account: IAccount; - accountId: number; - trx: Knex.Transaction; -} - -export interface IAccountEventEditedPayload { - account: IAccount; - oldAccount: IAccount; - trx: Knex.Transaction; -} - -export interface IAccountEventDeletedPayload { - accountId: number; - oldAccount: IAccount; - trx: Knex.Transaction; -} - -export interface IAccountEventDeletePayload { - trx: Knex.Transaction; - oldAccount: IAccount; - tenantId: number; -} - -export interface IAccountEventActivatedPayload { - tenantId: number; - accountId: number; - trx: Knex.Transaction; -} - -export enum AccountAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', - TransactionsLocking = 'TransactionsLocking', -} - -export enum TaxRateAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} - -export interface CreateAccountParams { - ignoreUniqueName: boolean; -} diff --git a/packages/server-nest/src/interfaces/Item.ts b/packages/server-nest/src/interfaces/Item.ts deleted file mode 100644 index 63816bdff..000000000 --- a/packages/server-nest/src/interfaces/Item.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Knex } from 'knex'; -import { Item } from '@/modules/Items/models/Item'; -// import { AbilitySubject } from '@/interfaces'; -// import { IFilterRole } from '@/interfaces/DynamicFilter'; - -export interface IItem { - id: number; - name: string; - type: string; - code: string; - - sellable: boolean; - purchasable: boolean; - - costPrice: number; - sellPrice: number; - currencyCode: string; - - costAccountId: number; - sellAccountId: number; - inventoryAccountId: number; - - sellDescription: string; - purchaseDescription: string; - - sellTaxRateId: number; - purchaseTaxRateId: number; - - quantityOnHand: number; - - note: string; - active: boolean; - - categoryId: number; - userId: number; - - createdAt: Date; - updatedAt: Date; -} - -export class IItemDTO { - @ApiProperty() - name: string; - - @ApiProperty() - type: string; - - @ApiProperty() - code: string; - - @ApiProperty() - sellable: boolean; - - @ApiProperty() - purchasable: boolean; - - @ApiProperty() - costPrice: number; - - @ApiProperty() - sellPrice: number; - - @ApiProperty() - currencyCode: string; - - @ApiProperty() - costAccountId: number; - - @ApiProperty() - sellAccountId: number; - - @ApiProperty() - inventoryAccountId: number; - - @ApiProperty() - sellDescription: string; - - @ApiProperty() - purchaseDescription: string; - - @ApiProperty() - sellTaxRateId: number; - - @ApiProperty() - purchaseTaxRateId: number; - - @ApiProperty() - quantityOnHand: number; - - @ApiProperty() - note: string; - - @ApiProperty() - active: boolean; - - @ApiProperty() - categoryId: number; -} - -export interface IItemCreateDTO extends IItemDTO {} -export interface IItemEditDTO extends IItemDTO {} - -// export interface IItemsService { -// getItem(tenantId: number, itemId: number): Promise; -// deleteItem(tenantId: number, itemId: number): Promise; -// editItem(tenantId: number, itemId: number, itemDTO: IItemDTO): Promise; -// newItem(tenantId: number, itemDTO: IItemDTO): Promise; -// itemsList( -// tenantId: number, -// itemsFilter: IItemsFilter, -// ): Promise<{ items: IItem[] }>; -// } - -// export interface IItemsFilter extends IDynamicListFilterDTO { -// stringifiedFilterRoles?: string; -// page: number; -// pageSize: number; -// inactiveMode: boolean; -// viewSlug?: string; -// } - -// export interface IItemsAutoCompleteFilter { -// limit: number; -// keyword: string; -// filterRoles?: IFilterRole[]; -// columnSortBy: string; -// sortOrder: string; -// } - -export interface IItemEventCreatedPayload { - // tenantId: number; - item: Item; - itemId: number; - trx: Knex.Transaction; -} - -export interface IItemEventEditedPayload { - item: Item; - oldItem: Item; - itemId: number; - trx: Knex.Transaction; -} - -export interface IItemEventDeletingPayload { - // tenantId: number; - trx: Knex.Transaction; - oldItem: Item; -} - -export interface IItemEventDeletedPayload { - // tenantId: number; - itemId: number; - oldItem: Item; - trx: Knex.Transaction; -} - -export enum ItemAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} - -// export type ItemAbility = [ItemAction, AbilitySubject.Item]; diff --git a/packages/server-nest/src/interfaces/Model.ts b/packages/server-nest/src/interfaces/Model.ts deleted file mode 100644 index 3230dddb3..000000000 --- a/packages/server-nest/src/interfaces/Model.ts +++ /dev/null @@ -1,195 +0,0 @@ -export interface IModel { - name: string; - tableName: string; - fields: { [key: string]: any }; -} - -export interface IFilterMeta { - sortOrder: string; - sortBy: string; -} - -export interface IPaginationMeta { - pageSize: number; - page: number; -} - -export interface IModelMetaDefaultSort { - sortOrder: ISortOrder; - sortField: string; -} - -export type IModelColumnType = - | 'text' - | 'number' - | 'enumeration' - | 'boolean' - | 'relation'; - -export type ISortOrder = 'DESC' | 'ASC'; - -export interface IModelMetaFieldCommon { - name: string; - column: string; - columnable?: boolean; - customQuery?: Function; - required?: boolean; - importHint?: string; - importableRelationLabel?: string; - order?: number; - unique?: number; - dataTransferObjectKey?: string; - filterCustomQuery?: Function; - sortCustomQuery?: Function; -} - -export interface IModelMetaFieldText { - fieldType: 'text'; - minLength?: number; - maxLength?: number; -} -export interface IModelMetaFieldBoolean { - fieldType: 'boolean'; -} -export interface IModelMetaFieldNumber { - fieldType: 'number'; - min?: number; - max?: number; -} -export interface IModelMetaFieldDate { - fieldType: 'date'; -} -export interface IModelMetaFieldUrl { - fieldType: 'url'; -} -export type IModelMetaField = IModelMetaFieldCommon & - ( - | IModelMetaFieldText - | IModelMetaFieldNumber - | IModelMetaFieldBoolean - | IModelMetaFieldDate - | IModelMetaFieldUrl - | IModelMetaEnumerationField - | IModelMetaRelationField - | IModelMetaCollectionField - ); - -export interface IModelMetaEnumerationOption { - key: string; - label: string; -} - -export interface IModelMetaEnumerationField { - fieldType: 'enumeration'; - options: IModelMetaEnumerationOption[]; -} - -export interface IModelMetaRelationFieldCommon { - fieldType: 'relation'; -} - -export interface IModelMetaRelationEnumerationField { - relationType: 'enumeration'; - relationKey: string; - relationEntityLabel: string; - relationEntityKey: string; -} - -export interface IModelMetaFieldWithFields { - fields: IModelMetaFieldCommon2 & - ( - | IModelMetaFieldText - | IModelMetaFieldNumber - | IModelMetaFieldBoolean - | IModelMetaFieldDate - | IModelMetaFieldUrl - | IModelMetaEnumerationField - | IModelMetaRelationField - ); -} - -interface IModelMetaCollectionObjectField extends IModelMetaFieldWithFields { - collectionOf: 'object'; -} - -export interface IModelMetaCollectionFieldCommon { - fieldType: 'collection'; - collectionMinLength?: number; - collectionMaxLength?: number; -} - -export type IModelMetaCollectionField = IModelMetaCollectionFieldCommon & - IModelMetaCollectionObjectField; - -export type IModelMetaRelationField = IModelMetaRelationFieldCommon & - IModelMetaRelationEnumerationField; - -interface IModelPrintMeta { - pageTitle: string; -} - -export interface IModelMeta { - defaultFilterField: string; - defaultSort: IModelMetaDefaultSort; - - exportable?: boolean; - exportFlattenOn?: string; - - importable?: boolean; - importAggregator?: string; - importAggregateOn?: string; - importAggregateBy?: string; - - print?: IModelPrintMeta; - - fields: Record; - fields2: Record; - columns: Record; -} - -// ---- -export interface IModelMetaFieldCommon2 { - name: string; - required?: boolean; - importHint?: string; - order?: number; - unique?: number; - features?: Array; -} - -export interface IModelMetaRelationField2 { - fieldType: 'relation'; - relationModel: string; - importableRelationLabel: string | string[]; -} - -export type IModelMetaField2 = IModelMetaFieldCommon2 & - ( - | IModelMetaFieldText - | IModelMetaFieldNumber - | IModelMetaFieldBoolean - | IModelMetaFieldDate - | IModelMetaFieldUrl - | IModelMetaEnumerationField - | IModelMetaRelationField2 - | IModelMetaCollectionField - ); - -export interface ImodelMetaColumnMeta { - name: string; - accessor?: string; - exportable?: boolean; -} - -interface IModelMetaColumnText { - type: 'text;'; -} - -interface IModelMetaColumnCollection { - type: 'collection'; - collectionOf: 'object'; - columns: { [key: string]: ImodelMetaColumnMeta & IModelMetaColumnText }; -} - -export type IModelMetaColumn = ImodelMetaColumnMeta & - (IModelMetaColumnText | IModelMetaColumnCollection); diff --git a/packages/server-nest/src/models/Model.ts b/packages/server-nest/src/models/Model.ts deleted file mode 100644 index 45d09b2f3..000000000 --- a/packages/server-nest/src/models/Model.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { QueryBuilder, Model } from 'objection'; - -interface PaginationResult { - results: M[]; - pagination: { - total: number; - page: number; - pageSize: number; - }; -} - -export type PaginationQueryBuilderType = QueryBuilder< - M, - PaginationResult ->; - -class PaginationQueryBuilder extends QueryBuilder< - M, - R -> { - pagination(page: number, pageSize: number): PaginationQueryBuilderType { - const query = super.page(page, pageSize); - - return query.runAfter(({ results, total }) => { - return { - results, - pagination: { - total, - page: page + 1, - pageSize, - }, - }; - }) as unknown as PaginationQueryBuilderType; - } -} - -export class BaseModel extends Model { - public readonly id: number; - public readonly tableName: string; - - QueryBuilderType!: PaginationQueryBuilder; - static QueryBuilder = PaginationQueryBuilder; -} diff --git a/packages/server-nest/src/utils/address-text-format.ts b/packages/server-nest/src/utils/address-text-format.ts deleted file mode 100644 index 3813f7e04..000000000 --- a/packages/server-nest/src/utils/address-text-format.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Contact } from "@/modules/Contacts/models/Contact"; - -interface OrganizationAddressFormatArgs { - organizationName?: string; - address1?: string; - address2?: string; - state?: string; - city?: string; - country?: string; - postalCode?: string; - phone?: string; -} - -export const defaultOrganizationAddressFormat = ` -{ORGANIZATION_NAME} -{ADDRESS_1} -{ADDRESS_2} -{CITY} {STATE} {POSTAL_CODE} -{COUNTRY} -{PHONE} -`; -/** - * Formats the address text based on the provided message and arguments. - * This function replaces placeholders in the message with actual values - * from the OrganizationAddressFormatArgs. It ensures that the final - * formatted message is clean and free of excessive newlines. - * - * @param {string} message - The message template containing placeholders. - * @param {Record} args - The arguments containing the values to replace in the message. - * @returns {string} - The formatted address text. - */ -const formatText = (message: string, replacements: Record) => { - let formattedMessage = Object.entries(replacements).reduce( - (msg, [key, value]) => { - return msg.split(`{${key}}`).join(value || ''); - }, - message - ); - // Removes any empty lines. - formattedMessage = formattedMessage.replace(/^\s*[\r\n]/gm, ''); - formattedMessage = formattedMessage.replace(/\n{2,}/g, '\n'); - formattedMessage = formattedMessage.replace(/\n/g, '
'); - formattedMessage = formattedMessage.trim(); - - return formattedMessage; -}; - -export const organizationAddressTextFormat = ( - message: string, - args: OrganizationAddressFormatArgs -) => { - const replacements: Record = { - ORGANIZATION_NAME: args.organizationName || '', - ADDRESS_1: args.address1 || '', - ADDRESS_2: args.address2 || '', - CITY: args.city || '', - STATE: args.state || '', - POSTAL_CODE: args.postalCode || '', - COUNTRY: args.country || '', - PHONE: args.phone || '', - }; - return formatText(message, replacements); -}; - -interface ContactAddressTextFormatArgs { - displayName?: string; - state?: string; - postalCode?: string; - email?: string; - country?: string; - city?: string; - address2?: string; - address1?: string; - phone?: string; -} - -export const defaultContactAddressFormat = `{CONTACT_NAME} -{ADDRESS_1} -{ADDRESS_2} -{CITY} {STATE} {POSTAL_CODE} -{COUNTRY} -{PHONE} -`; - -export const contactAddressTextFormat = ( - contact: Contact, - message: string = defaultContactAddressFormat -) => { - const args = { - displayName: contact.displayName, - address1: contact.billingAddress1, - address2: contact.billingAddress2, - state: contact.billingAddressState, - country: contact.billingAddressCountry, - postalCode: contact?.billingAddressPostcode, - city: contact?.billingAddressCity, - email: contact?.email, - phone: contact?.billingAddressPhone, - } as ContactAddressTextFormatArgs; - - const replacements: Record = { - CONTACT_NAME: args.displayName || '', - ADDRESS_1: args.address1 || '', - ADDRESS_2: args.address2 || '', - CITY: args.city || '', - STATE: args.state || '', - POSTAL_CODE: args.postalCode || '', - COUNTRY: args.country || '', - EMAIL: args?.email || '', - PHONE: args?.phone || '', - }; - return formatText(message, replacements); -}; diff --git a/packages/server-nest/src/utils/deepdash.ts b/packages/server-nest/src/utils/deepdash.ts deleted file mode 100644 index 7c44d298a..000000000 --- a/packages/server-nest/src/utils/deepdash.ts +++ /dev/null @@ -1,131 +0,0 @@ -// @ts-nocheck -import * as _ from 'lodash'; -import * as addDeepdash from 'deepdash'; - -const { - condense, - condenseDeep, - eachDeep, - exists, - filterDeep, - findDeep, - findPathDeep, - findValueDeep, - forEachDeep, - index, - keysDeep, - mapDeep, - mapKeysDeep, - mapValuesDeep, - mapValues, - omitDeep, - pathMatches, - pathToString, - paths, - pickDeep, - reduceDeep, - someDeep, - iteratee, -} = addDeepdash(_); - -const mapValuesDeepReverse = (nodes, callback, config?) => { - const clonedNodes = _.clone(nodes); - const nodesPaths = paths(nodes, config); - const reversedPaths = _.reverse(nodesPaths); - - reversedPaths.forEach((pathStack: string[], i) => { - const node = _.get(clonedNodes, pathStack); - const pathString = pathToString(pathStack); - const children = _.get( - clonedNodes, - `${pathString}.${config.childrenPath}`, - [] - ); - const mappedNode = callback(node, children); - - if (!mappedNode.children && children) { - mappedNode.children = children; - } - _.set(clonedNodes, pathString, mappedNode); - }); - return clonedNodes; -}; - -const filterNodesDeep = (predicate, nodes) => { - return condense( - reduceDeep( - nodes, - (accumulator, value, key, parent, context) => { - const newValue = { ...value }; - - if (newValue.children) { - _.set(newValue, 'children', condense(value.children)); - } - const isTrue = predicate(newValue, key, parent, context); - - if (isTrue === true) { - _.set(accumulator, context.path, newValue); - } else if (isTrue === false) { - _.unset(accumulator, context.path); - } - return accumulator; - }, - [], - { - childrenPath: 'children', - pathFormat: 'array', - callbackAfterIterate: true, - } - ) - ); -}; - -const flatNestedTree = (obj, mapper, options) => { - return reduceDeep( - obj, - (accumulator, value, key, parentValue, context) => { - const computedValue = _.omit(value, ['children']); - const mappedValue = mapper - ? mapper(computedValue, key, context) - : computedValue; - - accumulator.push(mappedValue); - return accumulator; - }, - [], - { - childrenPath: 'children', - pathFormat: 'array', - ...options, - } - ); -}; - -export { - iteratee, - condense, - condenseDeep, - eachDeep, - exists, - filterDeep, - findDeep, - findPathDeep, - findValueDeep, - forEachDeep, - index, - keysDeep, - mapDeep, - mapKeysDeep, - mapValuesDeep, - mapValues, - omitDeep, - pathMatches, - pathToString, - paths, - pickDeep, - reduceDeep, - someDeep, - mapValuesDeepReverse, - filterNodesDeep, - flatNestedTree, -}; diff --git a/packages/server-nest/tsconfig.json b/packages/server-nest/tsconfig.json deleted file mode 100644 index 5f0ef4040..000000000 --- a/packages/server-nest/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "declaration": false, - "removeComments": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "allowSyntheticDefaultImports": true, - "target": "ES2021", - "sourceMap": true, - "outDir": "./dist", - "baseUrl": "./", - "incremental": true, - "skipLibCheck": true, - "strictNullChecks": false, - "noImplicitAny": false, - "strictBindCallApply": false, - "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false, - "paths": { - "@/*": ["./src/*"], - "@bigcapital/server/*": ["../server/*"] - } - } -} diff --git a/packages/server/.babelrc b/packages/server/.babelrc deleted file mode 100644 index 662559d1b..000000000 --- a/packages/server/.babelrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presets": ["@babel/preset-env"], - "retainLines": true, - "plugins": [ - "@babel/plugin-transform-runtime", - "@babel/plugin-syntax-dynamic-import" - ] -} \ No newline at end of file diff --git a/packages/server-nest/.env.example b/packages/server/.env.example similarity index 100% rename from packages/server-nest/.env.example rename to packages/server/.env.example diff --git a/packages/server/.eslintrc.js b/packages/server/.eslintrc.js index 1ad00ade5..259de13c7 100644 --- a/packages/server/.eslintrc.js +++ b/packages/server/.eslintrc.js @@ -1,34 +1,25 @@ module.exports = { - env: { - browser: true, - es6: true, - }, - extends: ['airbnb-base', 'airbnb-typescript'], parser: '@typescript-eslint/parser', parserOptions: { - ecmaVersion: 2018, - sourceType: 'module', project: 'tsconfig.json', - tsconfigRootDir: './', + tsconfigRootDir: __dirname, + sourceType: 'module', }, - globals: { - Atomics: 'readonly', - SharedArrayBuffer: 'readonly', + plugins: ['@typescript-eslint/eslint-plugin'], + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + ], + root: true, + env: { + node: true, + jest: true, }, - plugins: ['import'], + ignorePatterns: ['.eslintrc.js'], rules: { - 'import/no-unresolved': 'error', - 'import/prefer-default-export': 'off', - }, - settings: { - 'import/parsers': { - '@typescript-eslint/parser': ['.ts', '.tsx'], - }, - 'import/resolver': { - typescript: { - alwaysTryTypes: true, - project: 'tsconfig.json', - }, - }, + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', }, }; diff --git a/packages/server/.gitignore b/packages/server/.gitignore index 1389d5314..4b56acfbe 100644 --- a/packages/server/.gitignore +++ b/packages/server/.gitignore @@ -1,8 +1,56 @@ -/node_modules/ -/.env -stdout.log +# compiled output /dist +/node_modules /build -/public/imports -dist -newrelic_agent.log + +# Logs +logs +*.log +npm-debug.log* +pnpm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# temp directory +.temp +.tmp + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/packages/server-nest/.prettierrc b/packages/server/.prettierrc similarity index 100% rename from packages/server-nest/.prettierrc rename to packages/server/.prettierrc diff --git a/packages/server-nest/.todo b/packages/server/.todo similarity index 100% rename from packages/server-nest/.todo rename to packages/server/.todo diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile deleted file mode 100644 index 9b8baa051..000000000 --- a/packages/server/Dockerfile +++ /dev/null @@ -1,110 +0,0 @@ -FROM node:18.16.0-alpine as build - -USER root - -ARG MAIL_HOST= \ - MAIL_USERNAME= \ - MAIL_PASSWORD= \ - MAIL_PORT= \ - MAIL_SECURE= \ - MAIL_FROM_NAME= \ - MAIL_FROM_ADDRESS= \ - # Database - DB_HOST= \ - DB_USER= \ - DB_PASSWORD= \ - DB_CHARSET= \ - # System database. - SYSTEM_DB_NAME= \ - SYSTEM_DB_PASSWORD= \ - SYSTEM_DB_USER= \ - SYSTEM_DB_HOST= \ - SYSTEM_DB_CHARSET= \ - # Tenant databases. - TENANT_DB_USER= \ - TENANT_DB_PASSWORD= \ - TENANT_DB_HOST= \ - TENANT_DB_NAME_PERFIX= \ - TENANT_DB_CHARSET= \ - # MongoDB - MONGODB_DATABASE_URL= \ - # Authentication - JWT_SECRET= \ - # Application - BASE_URL= \ - # Agendash - AGENDASH_AUTH_USER=agendash \ - AGENDASH_AUTH_PASSWORD=123123 \ - # Sign-up restriction - SIGNUP_DISABLED= \ - SIGNUP_ALLOWED_DOMAINS= \ - SIGNUP_ALLOWED_EMAILS= - -ENV MAIL_HOST=$MAIL_HOST \ - MAIL_USERNAME=$MAIL_USERNAME \ - MAIL_PASSWORD=$MAIL_PASSWORD \ - MAIL_PORT=$MAIL_PORT \ - MAIL_SECURE=$MAIL_SECURE \ - MAIL_FROM_NAME=$MAIL_FROM_NAME \ - MAIL_FROM_ADDRESS=$MAIL_FROM_ADDRESS \ - # Database - DB_HOST=$DB_HOST \ - DB_USER=$DB_USER \ - DB_PASSWORD=$DB_PASSWORD \ - DB_CHARSET=$DB_CHARSET \ - # System database. - SYSTEM_DB_HOST=$SYSTEM_DB_HOST \ - SYSTEM_DB_USER=$SYSTEM_DB_USER \ - SYSTEM_DB_PASSWORD=$SYSTEM_DB_PASSWORD \ - SYSTEM_DB_NAME=$SYSTEM_DB_NAME \ - SYSTEM_DB_CHARSET=$SYSTEM_DB_CHARSET \ - # Tenant databases. - TENANT_DB_NAME_PERFIX=$TENANT_DB_NAME_PERFIX \ - TENANT_DB_HOST=$TENANT_DB_HOST \ - TENANT_DB_PASSWORD=$TENANT_DB_PASSWORD \ - TENANT_DB_USER=$TENANT_DB_USER \ - TENANT_DB_CHARSET=$TENANT_DB_CHARSET \ - # Authentication - JWT_SECRET=$JWT_SECRET \ - # Agendash - AGENDASH_AUTH_USER=$AGENDASH_AUTH_USER \ - AGENDASH_AUTH_PASSWORD=$AGENDASH_AUTH_PASSWORD \ - # MongoDB - MONGODB_DATABASE_URL=$MONGODB_DATABASE_URL \ - # Application - BASE_URL=$BASE_URL \ - # Sign-up restriction - SIGNUP_DISABLED=$SIGNUP_DISABLED \ - SIGNUP_ALLOWED_DOMAINS=$SIGNUP_ALLOWED_DOMAINS \ - SIGNUP_ALLOWED_EMAILS=$SIGNUP_ALLOWED_EMAILS - -# New Relic config file. -ENV NEW_RELIC_NO_CONFIG_FILE=true - -# Create app directory. -WORKDIR /app - -RUN chown node:node / - -# Install pnpm -RUN npm install -g pnpm - -# Copy application dependency manifests to the container image. -COPY --chown=node:node ./ ./ - -# Install application dependencies -RUN apk update -RUN apk add python3 build-base chromium - -# Set PYHTON env -ENV PYTHON=/usr/bin/python3 - -# Install packages dependencies for production. -RUN pnpm install - -COPY --chown=node:node ./packages/server ./packages/server - -# # Creates a "dist" folder with the production build -RUN pnpm run build:server --skip-nx-cache - -CMD [ "node", "./packages/server/build/index.js" ] \ No newline at end of file diff --git a/packages/server/README.md b/packages/server/README.md index ec9f9de18..f149ff9af 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -1 +1 @@ -# @bigcapital/server \ No newline at end of file +## @bigcapitalhq/server \ No newline at end of file diff --git a/packages/server/knexfile.js b/packages/server/knexfile.js deleted file mode 100644 index 927f6574d..000000000 --- a/packages/server/knexfile.js +++ /dev/null @@ -1,17 +0,0 @@ -const { knexSnakeCaseMappers } = require('objection'); - -module.exports = { - client: 'mysql', - connection: { - host: '127.0.0.1', - user: 'root', - password: 'root', - database: 'bigcapital_tenant_hqde5zqkylsho06', - charset: 'utf8', - }, - migrations: { - directory: './src/database/migrations', - }, - pool: { min: 0, max: 7 }, - ...knexSnakeCaseMappers({ upperCase: true }), -}; diff --git a/packages/server-nest/nest-cli.json b/packages/server/nest-cli.json similarity index 100% rename from packages/server-nest/nest-cli.json rename to packages/server/nest-cli.json diff --git a/packages/server/package.json b/packages/server/package.json index 1f5a1f293..9eb37819a 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,173 +1,151 @@ { - "name": "@bigcapital/server", - "version": "0.10.2", + "name": "@bigcapital/server2", + "version": "0.0.1", "description": "", - "main": "src/server.ts", + "author": "", + "private": true, + "license": "UNLICENSED", "scripts": { - "inspect": "cross-env NODE_PATH=./src nodemon src/server.ts", - "clear": "rimraf build", - "dev": "cross-env NODE_ENV=development webpack --config scripts/webpack.config.js", - "build:resources": "gulp --gulpfile=scripts/gulpfile.js styles styles-rtl", - "build:app": "cross-env NODE_ENV=production webpack --config scripts/webpack.config.js", - "build:commands": "cross-env NODE_ENV=production webpack --config scripts/webpack.cli.js", - "build": "npm-run-all build:*", - "serve": "node ./build/index.js", - "lint:fix": "eslint --fix ./**/*.ts" - }, - "author": "Ahmed Bouhuolia, ", - "license": "ISC", - "bin": { - "bigcapital": "./bin/bigcapital.js" + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json --watchAll" }, "dependencies": { - "@bigcapital/utils": "*", - "@bigcapital/email-components": "*", - "@bigcapital/pdf-templates": "*", "@aws-sdk/client-s3": "^3.576.0", "@aws-sdk/s3-request-presigner": "^3.583.0", + "@bigcapital/email-components": "*", + "@bigcapital/pdf-templates": "*", + "@bigcapital/utils": "*", "@casl/ability": "^5.4.3", - "@hapi/boom": "^7.4.3", "@lemonsqueezy/lemonsqueezy.js": "^2.2.0", + "@liaoliaots/nestjs-redis": "^10.0.0", + "@types/multer": "^1.4.11", + "@nestjs/bull": "^10.2.1", + "@nestjs/bullmq": "^10.2.2", + "@nestjs/cache-manager": "^2.2.2", + "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.2.3", + "@nestjs/core": "^10.0.0", + "@nestjs/event-emitter": "^2.0.4", + "@nestjs/jwt": "^10.2.0", + "@nestjs/passport": "^11.0.5", + "@nestjs/platform-express": "^10.0.0", + "@nestjs/swagger": "^7.4.2", + "@nestjs/throttler": "^6.2.1", "@supercharge/promise-pool": "^3.2.0", - "@types/express": "^4.17.21", - "@types/i18n": "^0.8.7", - "@types/knex": "^0.16.1", - "@types/mathjs": "^6.0.12", - "@types/yup": "^0.29.13", - "accepts": "^1.3.7", + "@types/nodemailer": "^6.4.17", + "@types/passport-local": "^1.0.38", + "@types/ramda": "^0.30.2", "accounting": "^0.4.1", - "agenda": "^4.2.1", - "agendash": "^3.1.0", - "app-root-path": "^3.0.0", "async": "^3.2.0", "async-mutex": "^0.5.0", "axios": "^1.6.0", - "babel-loader": "^9.1.2", + "bcrypt": "^5.1.1", "bcryptjs": "^2.4.3", "bluebird": "^3.7.2", - "body-parser": "^1.20.2", - "compression": "^1.7.4", - "country-codes-list": "^1.6.8", - "cpy": "^8.1.2", - "cpy-cli": "^3.1.1", - "crypto-random-string": "^3.2.0", - "csurf": "^1.10.0", - "deep-map": "^2.0.0", + "bull": "^4.16.3", + "bullmq": "^5.25.6", + "cache-manager": "^6.1.1", + "cache-manager-redis-store": "^3.0.1", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.1", "deepdash": "^5.3.9", - "dotenv": "^8.1.0", - "errorhandler": "^1.5.1", - "es6-weak-map": "^2.0.3", - "esm": "^3.2.25", - "event-dispatch": "^0.4.1", - "eventemitter2": "^6.4.5", - "express": "^4.17.1", - "express-basic-auth": "^1.2.0", - "express-boom": "^3.0.0", - "express-oauth-server": "^2.0.0", - "express-validator": "^6.12.2", + "express-validator": "^7.2.0", "form-data": "^4.0.0", - "gulp": "^4.0.2", - "gulp-sass": "^5.0.0", - "helmet": "^3.21.0", - "i18n": "^0.13.3", + "fp-ts": "^2.16.9", + "ioredis": "^5.6.0", "is-my-json-valid": "^2.20.5", "js-money": "^0.6.3", - "jsonwebtoken": "^8.5.1", "knex": "^3.1.0", - "knex-cleaner": "^1.3.0", - "libphonenumber-js": "^1.9.6", - "lodash": "^4.17.15", + "lamda": "^0.4.1", + "lodash": "^4.17.21", "lru-cache": "^6.0.0", "mathjs": "^9.4.0", - "memory-cache": "^0.2.0", "mime-types": "^2.1.35", - "moment": "^2.24.0", + "moment": "^2.30.1", "moment-range": "^4.0.2", "moment-timezone": "^0.5.43", - "mongodb": "^6.1.0", - "mongoose": "^5.10.0", + "mysql": "^2.18.1", + "mysql2": "^3.11.3", "multer": "1.4.5-lts.1", "multer-s3": "^3.0.1", - "mustache": "^3.0.3", - "mysql": "^2.17.1", - "mysql2": "^1.6.5", - "newrelic": "^11.15.0", - "node-cache": "^4.2.1", + "nestjs-cls": "^5.2.0", + "nestjs-i18n": "^10.4.9", + "nestjs-redis": "^1.3.3", "nodemailer": "^6.3.0", - "nodemon": "^1.19.1", "object-hash": "^2.0.3", - "objection": "^3.0.0", - "objection-filter": "^4.0.1", - "objection-soft-delete": "^1.0.7", - "objection-unique": "^1.2.2", + "objection": "^3.1.5", + "passport": "^0.7.0", + "passport-jwt": "^4.0.1", + "passport-local": "^1.0.0", "plaid": "^10.3.0", "pluralize": "^8.0.0", "posthog-node": "^4.3.2", "pug": "^3.0.2", - "puppeteer": "^10.2.0", - "qim": "0.0.52", - "ramda": "^0.27.1", - "rate-limiter-flexible": "^2.1.14", - "reflect-metadata": "^0.1.13", - "rtl-detect": "^1.0.4", - "socket.io": "^4.7.4", - "source-map-loader": "^4.0.1", + "ramda": "^0.30.1", + "redis": "^4.7.0", + "reflect-metadata": "^0.2.0", + "remeda": "^2.19.2", + "rxjs": "^7.8.1", + "serialize-interceptor": "^1.1.7", + "strategy": "^1.1.1", "stripe": "^16.10.0", - "tmp-promise": "^3.0.3", - "ts-transformer-keys": "^0.4.2", - "tsyringe": "^4.3.0", - "typedi": "^0.8.0", "uniqid": "^5.2.0", "uuid": "^10.0.0", - "winston": "^3.2.1", "xlsx": "^0.18.5", - "yup": "^0.28.1" + "yup": "^0.28.1", + "zod": "^3.23.8" }, "devDependencies": { - "@types/lodash": "^4.14.158", - "@types/multer": "^1.4.11", - "@types/ramda": "^0.27.64", - "@typescript-eslint/eslint-plugin": "^5.50.0", - "@typescript-eslint/parser": "^5.50.0", - "chai": "^4.2.0", - "chai-http": "^4.3.0", - "chai-things": "^0.2.0", - "colorette": "^1.2.0", - "commander": "^5.0.0", - "cross-env": "^5.2.0", - "eslint": "^8.33.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-friendly-formatter": "^4.0.1", - "eslint-import-resolver-typescript": "^3.5.3", - "eslint-import-resolver-webpack": "^0.11.1", - "eslint-loader": "^2.2.1", - "eslint-plugin-import": "^2.27.5", - "faker": "^4.1.0", - "getopts": "^2.2.5", - "gulp-postcss": "^9.0.0", - "gulp-rename": "^2.0.0", - "knex-factory": "0.0.6", - "merge-stream": "^2.0.0", - "mocha": "^5.2.0", - "npm-run-all": "^4.1.5", - "nyc": "^14.1.1", - "progress-bar-webpack-plugin": "^2.1.0", - "regenerator-runtime": "^0.13.7", - "rimraf": "^3.0.2", - "rtlcss": "^3.3.0", - "run-script-webpack-plugin": "^0.1.1", - "sass": "^1.58.0", - "sinon": "^7.4.2", - "start-server-webpack-plugin": "^2.2.5", - "ts-loader": "^9.4.2", - "ts-node": "^9.0.0", - "tsconfig-paths-webpack-plugin": "^4.0.0", - "typescript": "^3.9.7", - "webpack": "^5.75.0", - "webpack-cli": "^4.10.0", - "webpack-merge": "^5.8.0", - "webpack-node-externals": "^3.0.0", - "webpack-watch-changed": "^1.0.0" + "@nestjs/cli": "^10.0.0", + "@nestjs/schematics": "^10.0.0", + "@nestjs/testing": "^10.0.0", + "@types/express": "^5.0.0", + "@types/jest": "^29.5.2", + "@types/mathjs": "^6.0.12", + "@types/node": "^20.3.1", + "@types/supertest": "^6.0.0", + "@types/yup": "^0.29.13", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "eslint": "^9.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.0", + "jest": "^29.5.0", + "mustache": "^3.0.3", + "prettier": "^3.0.0", + "source-map-support": "^0.5.21", + "supertest": "^7.0.0", + "ts-jest": "^29.1.0", + "ts-loader": "^9.4.3", + "ts-node": "^10.9.1", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.1.3" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" } } diff --git a/packages/server/public/.DS_Store b/packages/server/public/.DS_Store deleted file mode 100644 index e02f2f664bca30e96431f5d436db21c832881118..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5T3QwrWBzE1;NXL*NTZkQM`m&U%-eSRBA$t2GeY5QhO+cynw!t@8R<} zv%3MSJ$MqaGqC&3&d+YRPkGghJ0Th8(hJnvJ4l z$wYtAMBiS67=|zc1)siOMd*2pMoFCIuKO<5D%JIknp1Nc&Ry`Rra>O&ldKbtZ)kL> zR1%eX7+uAKX|K6;rqVo&)4^CL#Qgz=++N3NUrjq|lJ+y58yJUEcj~?7?ri3H?omtb zA0M8~TXN>Pp4*b`wmYBKo$bAY(~I6yGECKrVN)RSS~e|~@QTWp!k&Y1nyB;vJ!MuI z&BzQe1Iz$3utE&jL%?aQP|aK_Gr$b|i~-soBsN0dVqs8k9oW(Jnfz5k64dD}K`1Ty z77K&uK@lbu(WDCd#1JMO?b62i77K$W9fV#P=dml7j~Ag=N4wPFAbf+|GXu=PA_EmO zY|{CEj=#*(NB&|8kC*{w;GZ!ds@H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 * { - flex: 1 1; - } - .#{prefix}-table { - width: 100%; - border-collapse: collapse; - text-align: left; - font-size: inherit; - } - .#{prefix}-table__header { - font-weight: 400; - border-bottom: 1px solid #000; - padding: 2px 10px; - color: #333; - } - .#{prefix}-table__header:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__header:last-of-type{ - padding-right: 0; - } - .#{prefix}-table__header--right { - text-align: right; - } - .#{prefix}-table__cell { - border-bottom: 1px solid #F6F6F6; - padding: 12px 10px; - } - .#{prefix}-table__cell:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__cell:last-of-type { - padding-right: 0; - } - .#{prefix}-table__cell--right { - text-align: right; - } - .#{prefix}-table__cell--item .item { - display: flex; - flex-direction: column; - gap: 2px; - } - .#{prefix}-table__cell--item .item .item__description{ - color: #5f6b7c; - } - .#{prefix}-totals { - display: flex; - flex-direction: column; - margin-left: auto; - width: 300px; - margin-bottom: 24px; - } - .#{prefix}-totals__item { - display: flex; - padding: 4px 0; - } - .#{prefix}-totals__item--border-gray { - border-bottom: 1px solid #DADADA; - } - .#{prefix}-totals__item--border-dark { - border-bottom: 1px solid #000; - } - .#{prefix}-totals__item--font-weight-bold { - font-weight: bold; - } - .#{prefix}-totals__item-label { - min-width: 160px; - } - .#{prefix}-totals__item-amount { - flex: 1 1 auto; - text-align: right; - } - .#{prefix}-statement { - margin-bottom: 20px; - } - .#{prefix}-statement__label { - color: #666; - } - .#{prefix}-statement__value { - white-space: pre-line; - } - -block content - div(class=`${prefix}-root`) - - //- Header (includes big title, details and logo) - div(class=`${prefix}-header`) - //- Header details (includes big title and details) - div(class=`${prefix}-header-details`) - div(class=`${prefix}-big-title`) Credit Note - - div(class=`${prefix}-terms-list`) - if showCreditNoteNumber - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{creditNoteNumberLabel}: - div(class=`${prefix}-terms-item__value`) #{creditNoteNumebr} - - if showCreditNoteDate - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{creditNoteDateLabel}: - div(class=`${prefix}-terms-item__value`) #{creditNoteDate} - - if showCompanyLogo && companyLogoUri - div(class=`${prefix}-logo-wrap`) - img(src=companyLogoUri alt=`Company Logo`) - - div(class=`${prefix}-address-section`) - if showCompanyAddress - div(class=`${prefix}-address-from`) - div !{companyAddress} - - if showCustomerAddress - div(class=`${prefix}-address-to`) - strong #{billedToLabel} - div !{customerAddress} - - table(class=`${prefix}-table`) - thead - tr - th(class=`${prefix}-table__header ${prefix}-table__header--item`) #{'Item'} - th(class=`${prefix}-table__header ${prefix}-table__header--quantity ${prefix}-table__header--right`) #{'Quantity'} - th(class=`${prefix}-table__header ${prefix}-table__header--rate ${prefix}-table__header--right`) #{'Rate'} - th(class=`${prefix}-table__header ${prefix}-table__header--total ${prefix}-table__header--right`) #{'Total'} - tbody - each line in lines - tr(class=`${prefix}-table__row`) - td(class=`${prefix}-table__cell ${prefix}-table__cell--item ${prefix}-table__cell--item`) - div.item - div.item__label #{line.item} - div.item__description #{line.description} - td(class=`${prefix}-table__cell ${prefix}-table__cell--quantity ${prefix}-table__cell--right`) #{line.quantity} - td(class=`${prefix}-table__cell ${prefix}-table__cell--rate ${prefix}-table__cell--right`) #{line.rate} - td(class=`${prefix}-table__cell ${prefix}-table__cell--total ${prefix}-table__cell--right`) #{line.total} - - div(class=`${prefix}-totals`) - if showSubtotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-gray`) - div(class=`${prefix}-totals__item-label`) #{subtotallabel} - div(class=`${prefix}-totals__item-amount`) #{subtotal} - - if showTotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-dark`) - div(class=`${prefix}-totals__item-amount`) #{totalLabel}: - div(class=`${prefix}-totals__item-label`) #{total} - - if showCustomerNote && customerNote - div(class=`${prefix}-statement`) - div(class=`${prefix}-statement__label`) #{customerNoteLabel}: - div(class=`${prefix}-statement__value`) #{customerNote} - - if showTermsConditions && termsConditions - div(class=`${prefix}-statement`) - div(class=`${prefix}-statement__label`) #{termsConditionsLabel}: - div(class=`${prefix}-statement__value`) #{termsConditions} diff --git a/packages/server/resources/views/modules/export-resource-table.pug b/packages/server/resources/views/modules/export-resource-table.pug deleted file mode 100644 index 1d1486586..000000000 --- a/packages/server/resources/views/modules/export-resource-table.pug +++ /dev/null @@ -1,24 +0,0 @@ -block head - style - include ../../css/modules/export-resource-table.css - -style. - !{customCSS} - -block content - .sheet - .sheet__title - h2.sheetTitle= sheetTitle - p.sheetDesc= sheetDescription - - table.sheet__table - thead - tr - each column in table.columns - th(style=column.style class='column--' + column.key)= column.name - tbody - each row in table.rows - tr(class=row.classNames) - each cell in row.cells - td(class='cell--' + cell.key) - span!= cell.value \ No newline at end of file diff --git a/packages/server/resources/views/modules/financial-sheet.pug b/packages/server/resources/views/modules/financial-sheet.pug deleted file mode 100644 index 9292c61de..000000000 --- a/packages/server/resources/views/modules/financial-sheet.pug +++ /dev/null @@ -1,25 +0,0 @@ -block head - style - include ../../css/modules/financial-sheet.css - -style. - !{customCSS} - -block content - .sheet - .sheet__header - .sheet__company-name=organizationName - .sheet__sheet-type=sheetName - .sheet__sheet-date=sheetDate - - table.sheet__table - thead - tr - each column in table.columns - th(style=column.style class='column--' + column.key)= column.label - tbody - each row in table.rows - tr(class=row.classNames) - each cell in row.cells - td(class='cell--' + cell.key) - span!= cell.value \ No newline at end of file diff --git a/packages/server/scripts/gulpConfig.js b/packages/server/scripts/gulpConfig.js deleted file mode 100644 index 92324d0cc..000000000 --- a/packages/server/scripts/gulpConfig.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * # Gulp Configuration. - * ------------------------------------------------------------------ - */ - -const RESOURCES_PATH = '../resources/'; -module.exports = { - banner: [ - '/**', - ' * <%= pkg.name %> - <%= pkg.description %>', - ' * @version v<%= pkg.version %>', - ' * @link <%= pkg.homepage %>', - ' * @author <%= pkg.author %>', - ' * @license <%= pkg.license %>', - '**/', - '', - ].join('\n'), - - // Browser Sync - browsersync: { - files: ['**/*', '!**.map', '!**.css'], // Exclude map files. - notify: false, // - open: true, // Set it to false if you don't like the broser window opening automatically. - port: 8080, // - proxy: 'localhost/customatic', // - watchOptions: { - debounceDelay: 2000, // This introduces a small delay when watching for file change events to avoid triggering too many reloads - }, - snippetOptions: { - whitelist: ['/wp-admin/admin-ajax.php'], - blacklist: ['/wp-admin/**'], - }, - }, - - // Style Related. - style: { - clean: ['style.css', 'style.min.css', 'style-rtl.css', 'style-rtl.min.css'], - build: [ - { - src: `${RESOURCES_PATH}/scss/modules/invoice.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - // sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it. - // minify: true, // Allow to enable/disable minify the source. - }, - { - src: `${RESOURCES_PATH}/scss/modules/estimate.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - // sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it. - // minify: true, // Allow to enable/disable minify the source. - }, - { - src: `${RESOURCES_PATH}/scss/modules/receipt.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - // sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it. - // minify: true, // Allow to enable/disable minify the source. - }, - { - src: `${RESOURCES_PATH}/scss/modules/credit.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - // sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it. - // minify: true, // Allow to enable/disable minify the source. - }, - { - src: `${RESOURCES_PATH}/scss/modules/payment.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - // sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it. - // minify: true, // Allow to enable/disable minify the source. - }, - { - src: `${RESOURCES_PATH}/scss/modules/financial-sheet.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - { - src: `${RESOURCES_PATH}/scss/modules/export-resource-table.scss`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - ], - // RTL builds. - rtl: [ - { - src: `${RESOURCES_PATH}/css/modules/invoice.css`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - { - src: `${RESOURCES_PATH}/css/modules/estimate.css`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - { - src: `${RESOURCES_PATH}/css/modules/receipt.css`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - { - src: `${RESOURCES_PATH}/css/modules/credit.css`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - { - src: `${RESOURCES_PATH}/css/modules/payment.css`, - dest: `${RESOURCES_PATH}/css/modules`, - }, - ], - - // Browsers you care about for auto-prefixing. - autoprefixer: { - browsers: [ - 'Android 2.3', - 'Android >= 4', - 'Chrome >= 20', - 'Firefox >= 24', - 'Explorer >= 9', - 'iOS >= 6', - 'Opera >= 12', - 'Safari >= 6', - ], - }, - - // SASS Configuration for all builds. - sass: { - errLogToConsole: true, - // outputStyle: 'compact', - }, - - // CSS MQ Packer configuration for all builds and style tasks. - cssMqpacker: {}, - - // CSS nano configuration for all builds. - cssnano: {}, - - // rtlcss configuration for all builds. - rtlcss: {}, - }, - - // Clean specific files. - clean: [ - '**/.DS_Store', - './assets/js/**/*.min.js', - '**/*.map', - '**/*.min.css', - 'assets/js/hypernews.js', - ], - - // Watch related. - watch: { - css: ['./assets/sass/**/*'], - js: ['assets/js/**/*.js', '!assets/js/**/*.min.js'], - images: ['./assets/images/**/*'], - }, -}; diff --git a/packages/server/scripts/gulpfile.js b/packages/server/scripts/gulpfile.js deleted file mode 100644 index 00eb828a5..000000000 --- a/packages/server/scripts/gulpfile.js +++ /dev/null @@ -1,50 +0,0 @@ -const gulp = require('gulp'); -const sass = require('sass'); -const gulpSass = require('gulp-sass')(sass); // Gulp pluign for Sass compilation. -const mergeStream = require('merge-stream'); - -const rename = require('gulp-rename'); // Renames files E.g. style.css -> style.min.css - -// Style related. -const postcss = require('gulp-postcss'); // Transforming styles with JS plugins -const rtlcss = require('rtlcss'); // Convert LTR CSS to RTL. - -const config = require('./gulpConfig'); - -gulp.task('styles', () => { - const builds = config.style.build.map((build) => { - return gulp - .src(build.src) - .pipe(gulpSass(config.style.sass)) - .pipe(gulp.dest(build.dest)); - }); - return mergeStream(builds); -}); - -/** - * Task: `styles-rtl` - * - * This task does the following. - * 1. Gets the source css files. - * 2. Covert LTR CSS to RTL. - * 3. Suffix all CSS files to `-rtl`. - * 4. Reloads css files via browser sync stream. - * 5. Combine matching media queries for `.min.css` version. - * 6. Minify all CSS files. - * 7. Reload minified css files via browser sync stream. - */ -gulp.task('styles-rtl', () => { - const builds = config.style.rtl.map((build) => { - return gulp - .src(build.src) - .pipe( - postcss([ - rtlcss(config.style.rtlcss), // Convert LTR CSS to RTL. - ]), - ) - .pipe(rename({ suffix: '-rtl' })) // Append "-rtl" to the filename. - .pipe(gulp.dest(build.dest)); - }); - - return mergeStream(builds); -}); diff --git a/packages/server/scripts/install.sh b/packages/server/scripts/install.sh deleted file mode 100644 index ad899bf99..000000000 --- a/packages/server/scripts/install.sh +++ /dev/null @@ -1,4 +0,0 @@ - -npm install -npm run build -npm run copy-i18n \ No newline at end of file diff --git a/packages/server/scripts/run_test_db.sh b/packages/server/scripts/run_test_db.sh deleted file mode 100644 index 80412012d..000000000 --- a/packages/server/scripts/run_test_db.sh +++ /dev/null @@ -1,31 +0,0 @@ -MYSQL_USER="ratteb" -MYSQL_DATABASE="ratteb" -MYSQL_CONTAINER_NAME="ratteb_test" - -MYSQL_ROOT_PASSWORD="root" -MYSQL_PASSWORD="root" - -echo "Start the testing MySql database..." - -docker \ - run \ - --detach \ - --env MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \ - --env MYSQL_USER=${MYSQL_USER} \ - --env MYSQL_PASSWORD=${MYSQL_PASSWORD} \ - --env MYSQL_DATABASE=${MYSQL_DATABASE} \ - --name ${MYSQL_CONTAINER_NAME} \ - --publish 3306:3306 \ - --tmpfs /var/lib/mysql:rw \ - mysql:5.7; - -echo "Sleeping for 10 seconds to allow time for the DB to be provisioned:" -for i in `seq 1 10`; -do - echo "." - sleep 1 -done - -echo "Database '${MYSQL_DATABASE}' running." -echo " Username: ${MYSQL_USER}" -echo " Password: ${MYSQL_PASSWORD}" diff --git a/packages/server/scripts/webpack.cli.js b/packages/server/scripts/webpack.cli.js deleted file mode 100644 index b4ca9edc5..000000000 --- a/packages/server/scripts/webpack.cli.js +++ /dev/null @@ -1,11 +0,0 @@ -const { getCommonWebpackOptions } = require('./webpack.common'); - -const inputEntry = './src/commands/index.ts'; -const outputDir = '../build'; -const outputFilename = 'commands.js'; - -module.exports = getCommonWebpackOptions({ - inputEntry, - outputDir, - outputFilename, -}); diff --git a/packages/server/scripts/webpack.common.js b/packages/server/scripts/webpack.common.js deleted file mode 100644 index 9d12c56bb..000000000 --- a/packages/server/scripts/webpack.common.js +++ /dev/null @@ -1,79 +0,0 @@ -const path = require('path'); -const { NormalModuleReplacementPlugin } = require('webpack'); -const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); -const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin'); -const nodeExternals = require('webpack-node-externals'); -const ProgressBarPlugin = require('progress-bar-webpack-plugin'); - -const isDev = process.env.NODE_ENV === 'development'; - -exports.getCommonWebpackOptions = ({ - inputEntry, - outputDir, - outputFilename, -}) => { - const webpackOptions = { - entry: ['regenerator-runtime/runtime', inputEntry], - target: 'node', - mode: isDev ? 'development' : 'production', - watch: isDev, - watchOptions: { - aggregateTimeout: 200, - poll: 1000, - }, - output: { - path: path.resolve(__dirname, outputDir), - filename: outputFilename, - }, - resolve: { - extensions: ['.ts', '.tsx', '.js'], - extensionAlias: { - '.ts': ['.js', '.ts'], - '.cts': ['.cjs', '.cts'], - '.mts': ['.mjs', '.mts'], - }, - plugins: [ - new TsconfigPathsPlugin({ - configFile: './tsconfig.json', - extensions: ['.ts', '.tsx', '.js'], - }), - ], - }, - plugins: [ - // Ignore knex dynamic required dialects that we don't use - new NormalModuleReplacementPlugin( - /m[sy]sql2?|oracle(db)?|sqlite3|pg-(native|query)/, - 'noop2' - ), - new ProgressBarPlugin(), - ], - externals: [nodeExternals(), 'aws-sdk', 'prettier'], - module: { - rules: [ - { - test: /\.([cm]?ts|tsx|js)$/, - use: [ - { - loader: 'ts-loader', - options: { - transpileOnly: true, - configFile: 'tsconfig.json', - }, - }, - ], - exclude: /(node_modules)/, - }, - ], - }, - optimization: { - minimize: false, - }, - }; - - if (isDev) { - webpackOptions.plugins.push( - new RunScriptWebpackPlugin({ name: outputFilename }) - ); - } - return webpackOptions; -}; diff --git a/packages/server/scripts/webpack.config.js b/packages/server/scripts/webpack.config.js deleted file mode 100644 index 5a4cda373..000000000 --- a/packages/server/scripts/webpack.config.js +++ /dev/null @@ -1,11 +0,0 @@ -const { getCommonWebpackOptions } = require('./webpack.common'); - -const inputEntry = './src/server.ts'; -const outputDir = '../build'; -const outputFilename = 'index.js'; - -module.exports = getCommonWebpackOptions({ - inputEntry, - outputDir, - outputFilename, -}); diff --git a/packages/server/src/api/controllers/Account/index.ts b/packages/server/src/api/controllers/Account/index.ts deleted file mode 100644 index 15111fe8e..000000000 --- a/packages/server/src/api/controllers/Account/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import BaseController from '@/api/controllers/BaseController'; -import AuthenticatedAccount from '@/services/AuthenticatedAccount'; -import TenancyMiddleware from '@/api/middleware/TenancyMiddleware'; -import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser'; -import JWTAuth from '@/api/middleware/jwtAuth'; - -@Service() -export default class AccountController extends BaseController { - @Inject() - accountService: AuthenticatedAccount; - - /** - * Router constructor method. - */ - public router() { - const router = Router(); - - // Should before build tenant database the user be authorized and - // most important than that, should be subscribed to any plan. - router.use(JWTAuth); - router.use(AttachCurrentTenantUser); - router.use(TenancyMiddleware); - - router.get('/', this.getAccount); - - return router; - } - - /** - * Creates a new account. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private getAccount = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - - try { - const account = await this.accountService.getAccount(tenantId, user); - - return res.status(200).send({ data: account }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/AccountTypes.ts b/packages/server/src/api/controllers/AccountTypes.ts deleted file mode 100644 index a80a2e7df..000000000 --- a/packages/server/src/api/controllers/AccountTypes.ts +++ /dev/null @@ -1,42 +0,0 @@ - import { Service, Inject } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import AccountsTypesService from '@/services/Accounts/AccountsTypesServices'; - -@Service() -export default class AccountsTypesController extends BaseController { - @Inject() - accountsTypesService: AccountsTypesService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get('/', asyncMiddleware(this.getAccountTypesList.bind(this))); - - return router; - } - - /** - * Retrieve accounts types list. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @return {Response} - */ - getAccountTypesList(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - try { - const accountTypes = this.accountsTypesService.getAccountsTypes(tenantId); - - return res.status(200).send({ - account_types: this.transfromToResponse(accountTypes, ['label'], req), - }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Accounts.ts b/packages/server/src/api/controllers/Accounts.ts deleted file mode 100644 index bcc7b651f..000000000 --- a/packages/server/src/api/controllers/Accounts.ts +++ /dev/null @@ -1,519 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { - AbilitySubject, - AccountAction, - IAccountDTO, - IAccountsStructureType, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AccountsApplication } from '@/services/Accounts/AccountsApplication'; -import { MAX_ACCOUNTS_CHART_DEPTH } from 'services/Accounts/constants'; - -@Service() -export default class AccountsController extends BaseController { - @Inject() - private accountsApplication: AccountsApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor method. - */ - public router() { - const router = Router(); - - router.get( - '/transactions', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Account), - [query('account_id').optional().isInt().toInt()], - this.asyncMiddleware(this.accountTransactions.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:id/activate', - CheckPolicies(AccountAction.EDIT, AbilitySubject.Account), - [...this.accountParamSchema], - asyncMiddleware(this.activateAccount.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:id/inactivate', - CheckPolicies(AccountAction.EDIT, AbilitySubject.Account), - [...this.accountParamSchema], - asyncMiddleware(this.inactivateAccount.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:id', - CheckPolicies(AccountAction.EDIT, AbilitySubject.Account), - [...this.editAccountDTOSchema, ...this.accountParamSchema], - this.validationResult, - asyncMiddleware(this.editAccount.bind(this)), - this.catchServiceErrors - ); - router.post( - '/', - CheckPolicies(AccountAction.CREATE, AbilitySubject.Account), - [...this.createAccountDTOSchema], - this.validationResult, - asyncMiddleware(this.newAccount.bind(this)), - this.catchServiceErrors - ); - router.get( - '/:id', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Account), - [...this.accountParamSchema], - this.validationResult, - asyncMiddleware(this.getAccount.bind(this)), - this.catchServiceErrors - ); - router.get( - '/', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Account), - [...this.accountsListSchema], - this.validationResult, - asyncMiddleware(this.getAccountsList.bind(this)), - this.dynamicListService.handlerErrorsToResponse, - this.catchServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(AccountAction.DELETE, AbilitySubject.Account), - [...this.accountParamSchema], - this.validationResult, - asyncMiddleware(this.deleteAccount.bind(this)), - this.catchServiceErrors - ); - return router; - } - - /** - * Create account DTO Schema validation. - */ - private get createAccountDTOSchema() { - return [ - check('name') - .exists() - .isLength({ min: 3, max: DATATYPES_LENGTH.STRING }) - .trim(), - check('code') - .optional({ nullable: true }) - .isLength({ min: 3, max: 6 }) - .trim(), - check('currency_code').optional(), - check('account_type') - .exists() - .isLength({ min: 3, max: DATATYPES_LENGTH.STRING }) - .trim(), - check('description') - .optional({ nullable: true }) - .isLength({ max: DATATYPES_LENGTH.TEXT }) - .trim(), - check('parent_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - ]; - } - - /** - * Account DTO Schema validation. - */ - private get editAccountDTOSchema() { - return [ - check('name') - .exists() - .isLength({ min: 3, max: DATATYPES_LENGTH.STRING }) - .trim(), - check('code') - .optional({ nullable: true }) - .isLength({ min: 3, max: 6 }) - .trim(), - check('account_type') - .exists() - .isLength({ min: 3, max: DATATYPES_LENGTH.STRING }) - .trim(), - check('description') - .optional({ nullable: true }) - .isLength({ max: DATATYPES_LENGTH.TEXT }) - .trim(), - check('parent_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - ]; - } - - private get accountParamSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Accounts list validation schema. - */ - private get accountsListSchema() { - return [ - query('view_slug').optional({ nullable: true }).isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('inactive_mode').optional().isBoolean().toBoolean(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - - query('structure') - .optional() - .isString() - .isIn([IAccountsStructureType.Tree, IAccountsStructureType.Flat]), - ]; - } - - get closingAccountSchema() { - return [ - check('to_account_id').exists().isNumeric().toInt(), - check('delete_after_closing').exists().isBoolean(), - ]; - } - - /** - * Creates a new account. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async newAccount(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const accountDTO: IAccountDTO = this.matchedBodyData(req); - - try { - const account = await this.accountsApplication.createAccount( - tenantId, - accountDTO - ); - return res.status(200).send({ - id: account.id, - message: 'The account has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit account details. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async editAccount(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: accountId } = req.params; - const accountDTO: IAccountDTO = this.matchedBodyData(req); - - try { - const account = await this.accountsApplication.editAccount( - tenantId, - accountId, - accountDTO - ); - - return res.status(200).send({ - id: account.id, - message: 'The account has been edited successfully', - }); - } catch (error) { - next(error); - } - } - - /** - * Get details of the given account. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async getAccount(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: accountId } = req.params; - - try { - const account = await this.accountsApplication.getAccount( - tenantId, - accountId - ); - return res - .status(200) - .send({ account: this.transfromToResponse(account) }); - } catch (error) { - next(error); - } - } - - /** - * Delete the given account. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async deleteAccount(req: Request, res: Response, next: NextFunction) { - const { id: accountId } = req.params; - const { tenantId } = req; - - try { - await this.accountsApplication.deleteAccount(tenantId, accountId); - - return res.status(200).send({ - id: accountId, - message: 'The deleted account has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Activate the given account. - * @param {Response} res - - * @param {Request} req - - * @return {Response} - */ - async activateAccount(req: Request, res: Response, next: Function) { - const { id: accountId } = req.params; - const { tenantId } = req; - - try { - await this.accountsApplication.activateAccount(tenantId, accountId); - - return res.status(200).send({ - id: accountId, - message: 'The account has been activated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Inactive the given account. - * @param {Response} res - - * @param {Request} req - - * @return {Response} - */ - async inactivateAccount(req: Request, res: Response, next: Function) { - const { id: accountId } = req.params; - const { tenantId } = req; - - try { - await this.accountsApplication.inactivateAccount(tenantId, accountId); - - return res.status(200).send({ - id: accountId, - message: 'The account has been inactivated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve accounts datatable list. - * @param {Request} req - * @param {Response} res - * @param {Response} - */ - public async getAccountsList( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - // Filter query. - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - inactiveMode: false, - structure: IAccountsStructureType.Tree, - ...this.matchedQueryData(req), - }; - - try { - const { accounts, filterMeta } = - await this.accountsApplication.getAccounts(tenantId, filter); - - return res.status(200).send({ - accounts: this.transfromToResponse(accounts, 'accountTypeLabel', req), - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve accounts transactions list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - async accountTransactions(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const transactionsFilter = this.matchedQueryData(req); - - try { - const transactions = - await this.accountsApplication.getAccountsTransactions( - tenantId, - transactionsFilter - ); - return res.status(200).send({ - transactions: this.transfromToResponse(transactions), - }); - } catch (error) { - next(error); - } - } - - /** - * Transforms service errors to response. - * @param {Error} - * @param {Request} req - * @param {Response} res - * @param {ServiceError} error - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'account_not_found') { - return res.boom.notFound('The given account not found.', { - errors: [{ type: 'ACCOUNT.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'account_name_not_unqiue') { - return res.boom.badRequest('The given account not unique.', { - errors: [{ type: 'ACCOUNT.NAME.NOT.UNIQUE', code: 150 }], - }); - } - if (error.errorType === 'account_type_not_found') { - return res.boom.badRequest('The given account type not found.', { - errors: [{ type: 'ACCOUNT_TYPE_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'account_type_not_allowed_to_changed') { - return res.boom.badRequest( - 'Not allowed to change account type of the account.', - { - errors: [{ type: 'NOT.ALLOWED.TO.CHANGE.ACCOUNT.TYPE', code: 300 }], - } - ); - } - if (error.errorType === 'parent_account_not_found') { - return res.boom.badRequest('The parent account not found.', { - errors: [{ type: 'PARENT_ACCOUNT_NOT_FOUND', code: 400 }], - }); - } - if (error.errorType === 'parent_has_different_type') { - return res.boom.badRequest('The parent account has different type.', { - errors: [ - { type: 'PARENT.ACCOUNT.HAS.DIFFERENT.ACCOUNT.TYPE', code: 500 }, - ], - }); - } - if (error.errorType === 'account_code_not_unique') { - return res.boom.badRequest('The given account code is not unique.', { - errors: [{ type: 'NOT_UNIQUE_CODE', code: 600 }], - }); - } - if (error.errorType === 'account_has_associated_transactions') { - return res.boom.badRequest( - 'You could not delete account has associated transactions.', - { - errors: [ - { type: 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS', code: 800 }, - ], - } - ); - } - if (error.errorType === 'account_predefined') { - return res.boom.badRequest('You could not delete predefined account', { - errors: [{ type: 'ACCOUNT.PREDEFINED', code: 900 }], - }); - } - if (error.errorType === 'accounts_not_found') { - return res.boom.notFound('Some of the given accounts not found.', { - errors: [{ type: 'SOME.ACCOUNTS.NOT_FOUND', code: 1000 }], - }); - } - if (error.errorType === 'predefined_accounts') { - return res.boom.badRequest( - 'Some of the given accounts are predefined.', - { errors: [{ type: 'ACCOUNTS_PREDEFINED', code: 1100 }] } - ); - } - if (error.errorType === 'close_account_and_to_account_not_same_type') { - return res.boom.badRequest( - 'The close account has different root type with to account.', - { - errors: [ - { - type: 'CLOSE_ACCOUNT_AND_TO_ACCOUNT_NOT_SAME_TYPE', - code: 1200, - }, - ], - } - ); - } - if (error.errorType === 'ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY') { - return res.boom.badRequest( - 'The given account type does not support multi-currency.', - { - errors: [ - { type: 'ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY', code: 1300 }, - ], - } - ); - } - if (error.errorType === 'ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT') { - return res.boom.badRequest( - 'You could not add account has currency different on the parent account.', - { - errors: [ - { type: 'ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT', code: 1400 }, - ], - } - ); - } - if (error.errorType === 'PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL') { - return res.boom.badRequest( - 'The parent account exceeded the depth level of accounts chart.', - { - errors: [ - { - type: 'PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL', - code: 1500, - data: { - maxDepth: MAX_ACCOUNTS_CHART_DEPTH, - }, - }, - ], - } - ); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Agendash.ts b/packages/server/src/api/controllers/Agendash.ts deleted file mode 100644 index 810915073..000000000 --- a/packages/server/src/api/controllers/Agendash.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Router } from 'express'; -import basicAuth from 'express-basic-auth'; -import agendash from 'agendash'; -import { Container } from 'typedi'; -import config from '@/config'; - -export default class AgendashController { - static router() { - const router = Router(); - const agendaInstance = Container.get('agenda'); - - router.use( - '/dash', - basicAuth({ - users: { - [config.agendash.user]: config.agendash.password, - }, - challenge: true, - }), - agendash(agendaInstance) - ); - return router; - } -} diff --git a/packages/server/src/api/controllers/Attachments/AttachmentsController.ts b/packages/server/src/api/controllers/Attachments/AttachmentsController.ts deleted file mode 100644 index ad75ef550..000000000 --- a/packages/server/src/api/controllers/Attachments/AttachmentsController.ts +++ /dev/null @@ -1,266 +0,0 @@ -import mime from 'mime-types'; -import { Service, Inject } from 'typedi'; -import { Router, Response, NextFunction, Request } from 'express'; -import { body, param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication'; -import { AttachmentUploadPipeline } from '@/services/Attachments/S3UploadPipeline'; - -@Service() -export class AttachmentsController extends BaseController { - @Inject() - private attachmentsApplication: AttachmentsApplication; - - @Inject() - private uploadPipelineService: AttachmentUploadPipeline; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/', - this.uploadPipelineService.validateS3Configured, - this.uploadPipelineService.uploadPipeline().single('file'), - this.validateUploadedFileExistance, - this.uploadAttachment.bind(this) - ); - router.delete( - '/:id', - [param('id').exists()], - this.validationResult, - this.deleteAttachment.bind(this) - ); - router.get( - '/:id', - [param('id').exists()], - this.validationResult, - this.getAttachment.bind(this) - ); - router.post( - '/:id/link', - [body('modelRef').exists(), body('modelId').exists()], - this.validationResult - ); - router.post( - '/:id/link', - [body('modelRef').exists(), body('modelId').exists()], - this.validationResult, - this.linkDocument.bind(this) - ); - router.post( - '/:id/unlink', - [body('modelRef').exists(), body('modelId').exists()], - this.validationResult, - this.unlinkDocument.bind(this) - ); - router.get( - '/:id/presigned-url', - [param('id').exists()], - this.validationResult, - this.getAttachmentPresignedUrl.bind(this) - ); - return router; - } - - /** - * Validates the upload file existance. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response|void} - */ - private validateUploadedFileExistance( - req: Request, - res: Response, - next: NextFunction - ) { - if (!req.file) { - return res.boom.badRequest(null, { - errorType: 'FILE_UPLOAD_FAILED', - message: 'Now file uploaded.', - }); - } - next(); - } - - /** - * Uploads the attachments to S3 and store the file metadata to DB. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response|void} - */ - private async uploadAttachment( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const file = req.file; - - try { - const data = await this.attachmentsApplication.upload(tenantId, file); - - return res.status(200).send({ - status: 200, - message: 'The document has uploaded successfully.', - data, - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the given attachment key. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async getAttachment( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { id } = req.params; - - try { - const data = await this.attachmentsApplication.get(tenantId, id); - - const byte = await data.Body.transformToByteArray(); - const extension = mime.extension(data.ContentType); - const buffer = Buffer.from(byte); - - res.set( - 'Content-Disposition', - `filename="${req.params.id}.${extension}"` - ); - res.set('Content-Type', data.ContentType); - res.send(buffer); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given document key. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async deleteAttachment( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { id: documentId } = req.params; - - try { - await this.attachmentsApplication.delete(tenantId, documentId); - - return res.status(200).send({ - status: 200, - message: 'The document has been delete successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Links the given document key. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async linkDocument( - req: Request, - res: Response, - next: Function - ): Promise { - const { tenantId } = req; - const { id: documentId } = req.params; - const { modelRef, modelId } = this.matchedBodyData(req); - - try { - await this.attachmentsApplication.link( - tenantId, - documentId, - modelRef, - modelId - ); - return res.status(200).send({ - status: 200, - message: 'The document has been linked successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Links the given document key. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async unlinkDocument( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { id: documentId } = req.params; - const { modelRef, modelId } = this.matchedBodyData(req); - - try { - await this.attachmentsApplication.link( - tenantId, - documentId, - modelRef, - modelId - ); - return res.status(200).send({ - status: 200, - message: 'The document has been linked successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retreives the presigned url of the given attachment key. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async getAttachmentPresignedUrl( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { id: documentKey } = req.params; - - try { - const presignedUrl = await this.attachmentsApplication.getPresignedUrl( - tenantId, - documentKey - ); - return res.status(200).send({ presignedUrl }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Authentication.ts b/packages/server/src/api/controllers/Authentication.ts deleted file mode 100644 index 052454350..000000000 --- a/packages/server/src/api/controllers/Authentication.ts +++ /dev/null @@ -1,375 +0,0 @@ -import { Request, Response, Router } from 'express'; -import { check, ValidationChain } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { ILoginDTO, ISystemUser, IRegisterDTO } from '@/interfaces'; -import { ServiceError, ServiceErrors } from '@/exceptions'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; -import LoginThrottlerMiddleware from '@/api/middleware/LoginThrottlerMiddleware'; -import AuthenticationApplication from '@/services/Authentication/AuthApplication'; - -import JWTAuth from '@/api/middleware/jwtAuth'; -import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser'; -@Service() -export default class AuthenticationController extends BaseController { - @Inject() - private authApplication: AuthenticationApplication; - - /** - * Constructor method. - */ - public router() { - const router = Router(); - - router.post( - '/login', - this.loginSchema, - this.validationResult, - LoginThrottlerMiddleware, - asyncMiddleware(this.login.bind(this)), - this.handlerErrors - ); - router.use('/register/verify/resend', JWTAuth); - router.use('/register/verify/resend', AttachCurrentTenantUser); - router.post( - '/register/verify/resend', - asyncMiddleware(this.registerVerifyResendMail.bind(this)), - this.handlerErrors - ); - router.post( - '/register/verify', - this.signupVerifySchema, - this.validationResult, - asyncMiddleware(this.registerVerify.bind(this)), - this.handlerErrors - ); - router.post( - '/register', - this.registerSchema, - this.validationResult, - asyncMiddleware(this.register.bind(this)), - this.handlerErrors - ); - router.post( - '/send_reset_password', - this.sendResetPasswordSchema, - this.validationResult, - asyncMiddleware(this.sendResetPassword.bind(this)), - this.handlerErrors - ); - router.post( - '/reset/:token', - this.resetPasswordSchema, - this.validationResult, - asyncMiddleware(this.resetPassword.bind(this)), - this.handlerErrors - ); - router.get('/meta', asyncMiddleware(this.getAuthMeta.bind(this))); - return router; - } - - /** - * Login validation schema. - * @returns {ValidationChain[]} - */ - private get loginSchema(): ValidationChain[] { - return [ - check('crediential').exists().isEmail(), - check('password').exists().isLength({ min: 5 }), - ]; - } - - /** - * Register validation schema. - * @returns {ValidationChain[]} - */ - private get registerSchema(): ValidationChain[] { - return [ - check('first_name') - .exists() - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('last_name') - .exists() - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('email') - .exists() - .isString() - .isEmail() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('password') - .exists() - .isString() - .isLength({ min: 6 }) - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - ]; - } - - private get signupVerifySchema(): ValidationChain[] { - return [ - check('email') - .exists() - .isString() - .isEmail() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('token').exists().isString(), - ]; - } - - /** - * Reset password schema. - * @returns {ValidationChain[]} - */ - private get resetPasswordSchema(): ValidationChain[] { - return [ - check('password') - .exists() - .isLength({ min: 6 }) - .custom((value, { req }) => { - if (value !== req.body.confirm_password) { - throw new Error("Passwords don't match"); - } else { - return value; - } - }), - ]; - } - - /** - * Send reset password validation schema. - * @returns {ValidationChain[]} - */ - private get sendResetPasswordSchema(): ValidationChain[] { - return [check('email').exists().isEmail().trim()]; - } - - /** - * Handle user login. - * @param {Request} req - * @param {Response} res - */ - private async login( - req: Request, - res: Response, - next: Function - ): Promise { - const userDTO: ILoginDTO = this.matchedBodyData(req); - - try { - const { token, user, tenant } = await this.authApplication.signIn( - userDTO.crediential, - userDTO.password - ); - return res.status(200).send({ token, user, tenant }); - } catch (error) { - next(error); - } - } - - /** - * Organization register handler. - * @param {Request} req - * @param {Response} res - */ - private async register(req: Request, res: Response, next: Function) { - const registerDTO: IRegisterDTO = this.matchedBodyData(req); - - try { - await this.authApplication.signUp(registerDTO); - - return res.status(200).send({ - type: 'success', - code: 'REGISTER.SUCCESS', - message: 'Register organization has been success.', - }); - } catch (error) { - next(error); - } - } - - /** - * Verifies the provider user's email after signin-up. - * @param {Request} req - * @param {Response}| res - * @param {Function} next - * @returns {Response|void} - */ - private async registerVerify(req: Request, res: Response, next: Function) { - const signUpVerifyDTO: { email: string; token: string } = - this.matchedBodyData(req); - - try { - const user = await this.authApplication.signUpConfirm( - signUpVerifyDTO.email, - signUpVerifyDTO.token - ); - return res.status(200).send({ - type: 'success', - message: 'The given user has verified successfully', - user, - }); - } catch (error) { - next(error); - } - } - - /** - * Resends the confirmation email to the user. - * @param {Request} req - * @param {Response}| res - * @param {Function} next - */ - private async registerVerifyResendMail( - req: Request, - res: Response, - next: Function - ) { - const { user } = req; - - try { - const data = await this.authApplication.signUpConfirmResend(user.id); - - return res.status(200).send({ - type: 'success', - message: 'The given user has verified successfully', - data, - }); - } catch (error) { - next(error); - } - } - - /** - * Send reset password handler - * @param {Request} req - * @param {Response} res - */ - private async sendResetPassword(req: Request, res: Response, next: Function) { - const { email } = this.matchedBodyData(req); - - try { - await this.authApplication.sendResetPassword(email); - - return res.status(200).send({ - code: 'SEND_RESET_PASSWORD_SUCCESS', - message: 'The reset password message has been sent successfully.', - }); - } catch (error) { - if (error instanceof ServiceError) { - } - next(error); - } - } - - /** - * Reset password handler - * @param {Request} req - * @param {Response} res - */ - private async resetPassword(req: Request, res: Response, next: Function) { - const { token } = req.params; - const { password } = req.body; - - try { - await this.authApplication.resetPassword(token, password); - - return res.status(200).send({ - type: 'RESET_PASSWORD_SUCCESS', - message: 'The password has been reset successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the authentication meta for SPA. - * @param {Request} req - * @param {Response} res - * @param {Function} next - * @returns {Response|void} - */ - private async getAuthMeta(req: Request, res: Response, next: Function) { - try { - const meta = await this.authApplication.getAuthMeta(); - - return res.status(200).send({ meta }); - } catch (error) { - next(error); - } - } - - /** - * Handles the service errors. - */ - private handlerErrors(error, req: Request, res: Response, next: Function) { - if (error instanceof ServiceError) { - if ( - ['INVALID_DETAILS', 'invalid_password'].indexOf(error.errorType) !== -1 - ) { - return res.boom.badRequest(null, { - errors: [{ type: 'INVALID_DETAILS', code: 100 }], - }); - } - if (error.errorType === 'USER_INACTIVE') { - return res.boom.badRequest(null, { - errors: [{ type: 'USER_INACTIVE', code: 200 }], - }); - } - if ( - error.errorType === 'TOKEN_INVALID' || - error.errorType === 'TOKEN_EXPIRED' - ) { - return res.boom.badRequest(null, { - errors: [{ type: 'TOKEN_INVALID', code: 300 }], - }); - } - if (error.errorType === 'USER_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'USER_NOT_FOUND', code: 400 }], - }); - } - if (error.errorType === 'EMAIL_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'EMAIL.NOT.REGISTERED', code: 500 }], - }); - } - if (error.errorType === 'EMAIL_EXISTS') { - return res.status(400).send({ - errors: [{ type: 'EMAIL.EXISTS', code: 600 }], - }); - } - if (error.errorType === 'SIGNUP_RESTRICTED') { - return res.status(400).send({ - errors: [ - { - type: 'SIGNUP_RESTRICTED', - message: - 'Sign-up is restricted no one can sign-up to the system.', - code: 700, - }, - ], - }); - } - if (error.errorType === 'SIGNUP_RESTRICTED_NOT_ALLOWED') { - return res.status(400).send({ - errors: [ - { - type: 'SIGNUP_RESTRICTED_NOT_ALLOWED', - message: - 'Sign-up is restricted the given email address is not allowed to sign-up.', - code: 710, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Banking/BankAccountsController.ts b/packages/server/src/api/controllers/Banking/BankAccountsController.ts deleted file mode 100644 index e02aad096..000000000 --- a/packages/server/src/api/controllers/Banking/BankAccountsController.ts +++ /dev/null @@ -1,218 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { NextFunction, Request, Response, Router } from 'express'; -import { param, query } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { GetBankAccountSummary } from '@/services/Banking/BankAccounts/GetBankAccountSummary'; -import { BankAccountsApplication } from '@/services/Banking/BankAccounts/BankAccountsApplication'; -import { GetPendingBankAccountTransactions } from '@/services/Cashflow/GetPendingBankAccountTransaction'; - -@Service() -export class BankAccountsController extends BaseController { - @Inject() - private getBankAccountSummaryService: GetBankAccountSummary; - - @Inject() - private bankAccountsApp: BankAccountsApplication; - - @Inject() - private getPendingTransactionsService: GetPendingBankAccountTransactions; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get('/:bankAccountId/meta', this.getBankAccountSummary.bind(this)); - router.get( - '/pending_transactions', - [ - query('account_id').optional().isNumeric().toInt(), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - ], - this.validationResult, - this.getBankAccountsPendingTransactions.bind(this) - ); - router.post( - '/:bankAccountId/disconnect', - this.disconnectBankAccount.bind(this) - ); - router.post('/:bankAccountId/update', this.refreshBankAccount.bind(this)); - router.post( - '/:bankAccountId/pause_feeds', - [param('bankAccountId').exists().isNumeric().toInt()], - this.validationResult, - this.pauseBankAccountFeeds.bind(this) - ); - router.post( - '/:bankAccountId/resume_feeds', - [param('bankAccountId').exists().isNumeric().toInt()], - this.validationResult, - this.resumeBankAccountFeeds.bind(this) - ); - - return router; - } - - /** - * Retrieves the bank account meta summary. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async getBankAccountSummary( - req: Request<{ bankAccountId: number }>, - res: Response, - next: NextFunction - ) { - const { bankAccountId } = req.params; - const { tenantId } = req; - - try { - const data = - await this.getBankAccountSummaryService.getBankAccountSummary( - tenantId, - bankAccountId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the bank account pending transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async getBankAccountsPendingTransactions( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const query = this.matchedQueryData(req); - - try { - const data = - await this.getPendingTransactionsService.getPendingTransactions( - tenantId, - query - ); - return res.status(200).send(data); - } catch (error) { - next(error); - } - } - - /** - * Disonnect the given bank account. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async disconnectBankAccount( - req: Request<{ bankAccountId: number }>, - res: Response, - next: NextFunction - ) { - const { bankAccountId } = req.params; - const { tenantId } = req; - - try { - await this.bankAccountsApp.disconnectBankAccount(tenantId, bankAccountId); - - return res.status(200).send({ - id: bankAccountId, - message: 'The bank account has been disconnected.', - }); - } catch (error) { - next(error); - } - } - - /** - * Refresh the given bank account. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async refreshBankAccount( - req: Request<{ bankAccountId: number }>, - res: Response, - next: NextFunction - ) { - const { bankAccountId } = req.params; - const { tenantId } = req; - - try { - await this.bankAccountsApp.refreshBankAccount(tenantId, bankAccountId); - - return res.status(200).send({ - id: bankAccountId, - message: 'The bank account has been disconnected.', - }); - } catch (error) { - next(error); - } - } - - /** - * Resumes the bank account feeds sync. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async resumeBankAccountFeeds( - req: Request<{ bankAccountId: number }>, - res: Response, - next: NextFunction - ) { - const { bankAccountId } = req.params; - const { tenantId } = req; - - try { - await this.bankAccountsApp.resumeBankAccount(tenantId, bankAccountId); - - return res.status(200).send({ - message: 'The bank account feeds syncing has been resumed.', - id: bankAccountId, - }); - } catch (error) { - next(error); - } - } - - /** - * Pauses the bank account feeds sync. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async pauseBankAccountFeeds( - req: Request<{ bankAccountId: number }>, - res: Response, - next: NextFunction - ) { - const { bankAccountId } = req.params; - const { tenantId } = req; - - try { - await this.bankAccountsApp.pauseBankAccount(tenantId, bankAccountId); - - return res.status(200).send({ - message: 'The bank account feeds syncing has been paused.', - id: bankAccountId, - }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Banking/BankTransactionsMatchingController.ts b/packages/server/src/api/controllers/Banking/BankTransactionsMatchingController.ts deleted file mode 100644 index a1db1faf6..000000000 --- a/packages/server/src/api/controllers/Banking/BankTransactionsMatchingController.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { body, param } from 'express-validator'; -import { NextFunction, Request, Response, Router } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import { MatchBankTransactionsApplication } from '@/services/Banking/Matching/MatchBankTransactionsApplication'; - -@Service() -export class BankTransactionsMatchingController extends BaseController { - @Inject() - private bankTransactionsMatchingApp: MatchBankTransactionsApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/unmatch/:transactionId', - [param('transactionId').exists()], - this.validationResult, - this.unmatchMatchedBankTransaction.bind(this) - ); - router.post( - '/match', - [ - body('uncategorizedTransactions').exists().isArray({ min: 1 }), - body('uncategorizedTransactions.*').isNumeric().toInt(), - - body('matchedTransactions').isArray({ min: 1 }), - body('matchedTransactions.*.reference_type').exists(), - body('matchedTransactions.*.reference_id').isNumeric().toInt(), - ], - this.validationResult, - this.matchBankTransaction.bind(this) - ); - return router; - } - - /** - * Matches the given bank transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async matchBankTransaction( - req: Request<{ transactionId: number }>, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const bodyData = this.matchedBodyData(req); - - const uncategorizedTransactions = bodyData?.uncategorizedTransactions; - const matchedTransactions = bodyData?.matchedTransactions; - - try { - await this.bankTransactionsMatchingApp.matchTransaction( - tenantId, - uncategorizedTransactions, - matchedTransactions - ); - return res.status(200).send({ - ids: uncategorizedTransactions, - message: 'The bank transaction has been matched.', - }); - } catch (error) { - next(error); - } - } - - /** - * Unmatches the matched bank transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async unmatchMatchedBankTransaction( - req: Request<{ transactionId: number }>, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { transactionId } = req.params; - - try { - await this.bankTransactionsMatchingApp.unmatchMatchedTransaction( - tenantId, - transactionId - ); - return res.status(200).send({ - id: transactionId, - message: 'The bank matched transaction has been unmatched.', - }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Banking/BankingController.ts b/packages/server/src/api/controllers/Banking/BankingController.ts deleted file mode 100644 index 69933f16d..000000000 --- a/packages/server/src/api/controllers/Banking/BankingController.ts +++ /dev/null @@ -1,39 +0,0 @@ -import Container, { Inject, Service } from 'typedi'; -import { Router } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import { PlaidBankingController } from './PlaidBankingController'; -import { BankingRulesController } from './BankingRulesController'; -import { BankTransactionsMatchingController } from './BankTransactionsMatchingController'; -import { RecognizedTransactionsController } from './RecognizedTransactionsController'; -import { BankAccountsController } from './BankAccountsController'; -import { BankingUncategorizedController } from './BankingUncategorizedController'; - -@Service() -export class BankingController extends BaseController { - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.use('/plaid', Container.get(PlaidBankingController).router()); - router.use('/rules', Container.get(BankingRulesController).router()); - router.use( - '/matches', - Container.get(BankTransactionsMatchingController).router() - ); - router.use( - '/recognized', - Container.get(RecognizedTransactionsController).router() - ); - router.use( - '/bank_accounts', - Container.get(BankAccountsController).router() - ); - router.use( - '/categorize', - Container.get(BankingUncategorizedController).router() - ); - return router; - } -} diff --git a/packages/server/src/api/controllers/Banking/BankingRulesController.ts b/packages/server/src/api/controllers/Banking/BankingRulesController.ts deleted file mode 100644 index 008b753d9..000000000 --- a/packages/server/src/api/controllers/Banking/BankingRulesController.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { NextFunction, Request, Response, Router } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import { BankRulesApplication } from '@/services/Banking/Rules/BankRulesApplication'; -import { body, param } from 'express-validator'; -import { - ICreateBankRuleDTO, - IEditBankRuleDTO, -} from '@/services/Banking/Rules/types'; - -@Service() -export class BankingRulesController extends BaseController { - @Inject() - private bankRulesApplication: BankRulesApplication; - - /** - * Bank rule DTO validation schema. - */ - private get bankRuleValidationSchema() { - return [ - body('name').isString().exists(), - body('order').isInt({ min: 0 }), - - // Apply to if transaction is. - body('apply_if_account_id') - .isInt({ min: 0 }) - .optional({ nullable: true }), - body('apply_if_transaction_type').isIn(['deposit', 'withdrawal']), - - // Conditions - body('conditions_type').isString().isIn(['and', 'or']).default('and'), - body('conditions').isArray({ min: 1 }), - body('conditions.*.field').exists().isIn(['description', 'amount']), - body('conditions.*.comparator') - .exists() - .isIn([ - 'equals', - 'equal', - 'contains', - 'not_contain', - 'bigger', - 'bigger_or_equal', - 'smaller', - 'smaller_or_equal', - ]) - .default('contain') - .trim(), - body('conditions.*.value').exists().trim(), - - // Assign - body('assign_category').isString(), - body('assign_account_id').isInt({ min: 0 }), - body('assign_payee').isString().optional({ nullable: true }), - body('assign_memo').isString().optional({ nullable: true }), - ]; - } - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/', - [...this.bankRuleValidationSchema], - this.validationResult, - this.createBankRule.bind(this) - ); - router.post( - '/:id', - [param('id').toInt().exists(), ...this.bankRuleValidationSchema], - this.validationResult, - this.editBankRule.bind(this) - ); - router.delete( - '/:id', - [param('id').toInt().exists()], - this.validationResult, - this.deleteBankRule.bind(this) - ); - router.get( - '/:id', - [param('id').toInt().exists()], - this.validationResult, - this.getBankRule.bind(this) - ); - router.get( - '/', - [param('id').toInt().exists()], - this.validationResult, - this.getBankRules.bind(this) - ); - return router; - } - - /** - * Creates a new bank rule. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async createBankRule( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const createBankRuleDTO = this.matchedBodyData(req) as ICreateBankRuleDTO; - - try { - const bankRule = await this.bankRulesApplication.createBankRule( - tenantId, - createBankRuleDTO - ); - return res.status(200).send({ - id: bankRule.id, - message: 'The bank rule has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edits the given bank rule. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async editBankRule(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: ruleId } = req.params; - const editBankRuleDTO = this.matchedBodyData(req) as IEditBankRuleDTO; - - try { - await this.bankRulesApplication.editBankRule( - tenantId, - ruleId, - editBankRuleDTO - ); - return res.status(200).send({ - id: ruleId, - message: 'The bank rule has been updated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given bank rule. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async deleteBankRule( - req: Request<{ id: number }>, - res: Response, - next: NextFunction - ) { - const { id: ruleId } = req.params; - const { tenantId } = req; - - try { - await this.bankRulesApplication.deleteBankRule(tenantId, ruleId); - - return res - .status(200) - .send({ message: 'The bank rule has been deleted.', id: ruleId }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the given bank rule. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getBankRule(req: Request, res: Response, next: NextFunction) { - const { id: ruleId } = req.params; - const { tenantId } = req; - - try { - const bankRule = await this.bankRulesApplication.getBankRule( - tenantId, - ruleId - ); - - return res.status(200).send({ bankRule }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the bank rules. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getBankRules(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - try { - const bankRules = await this.bankRulesApplication.getBankRules(tenantId); - return res.status(200).send({ bankRules }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Banking/BankingUncategorizedController.ts b/packages/server/src/api/controllers/Banking/BankingUncategorizedController.ts deleted file mode 100644 index 396ccbcda..000000000 --- a/packages/server/src/api/controllers/Banking/BankingUncategorizedController.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { NextFunction, Request, Response, Router } from 'express'; -import { query } from 'express-validator'; -import BaseController from '../BaseController'; -import { GetAutofillCategorizeTransaction } from '@/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransaction'; - -@Service() -export class BankingUncategorizedController extends BaseController { - @Inject() - private getAutofillCategorizeTransactionService: GetAutofillCategorizeTransaction; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/autofill', - [ - query('uncategorizedTransactionIds').isArray({ min: 1 }), - query('uncategorizedTransactionIds.*').isNumeric().toInt(), - ], - this.validationResult, - this.getAutofillCategorizeTransaction.bind(this) - ); - return router; - } - - /** - * Retrieves the autofill values of the categorize form of the given - * uncategorized transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - public async getAutofillCategorizeTransaction( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const uncategorizedTransactionIds = req.query.uncategorizedTransactionIds; - - try { - const data = - await this.getAutofillCategorizeTransactionService.getAutofillCategorizeTransaction( - tenantId, - uncategorizedTransactionIds - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Banking/ExcludeBankTransactionsController.ts b/packages/server/src/api/controllers/Banking/ExcludeBankTransactionsController.ts deleted file mode 100644 index e38e818b3..000000000 --- a/packages/server/src/api/controllers/Banking/ExcludeBankTransactionsController.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { body, param, query } from 'express-validator'; -import { NextFunction, Request, Response, Router } from 'express'; -import BaseController from '../BaseController'; -import { ExcludeBankTransactionsApplication } from '@/services/Banking/Exclude/ExcludeBankTransactionsApplication'; -import { map, parseInt, trim } from 'lodash'; - -@Service() -export class ExcludeBankTransactionsController extends BaseController { - @Inject() - private excludeBankTransactionApp: ExcludeBankTransactionsApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.put( - '/transactions/exclude', - [body('ids').exists()], - this.validationResult, - this.excludeBulkBankTransactions.bind(this) - ); - router.put( - '/transactions/unexclude', - [body('ids').exists()], - this.validationResult, - this.unexcludeBulkBankTransactins.bind(this) - ); - router.put( - '/transactions/:transactionId/exclude', - [param('transactionId').exists().toInt()], - this.validationResult, - this.excludeBankTransaction.bind(this) - ); - router.put( - '/transactions/:transactionId/unexclude', - [param('transactionId').exists()], - this.validationResult, - this.unexcludeBankTransaction.bind(this) - ); - router.get( - '/excluded', - [ - query('account_id').optional().isNumeric().toInt(), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('min_date').optional({ nullable: true }).isISO8601().toDate(), - query('max_date').optional({ nullable: true }).isISO8601().toDate(), - query('min_amount').optional({ nullable: true }).isFloat().toFloat(), - query('max_amount').optional({ nullable: true }).isFloat().toFloat(), - ], - this.validationResult, - this.getExcludedBankTransactions.bind(this) - ); - return router; - } - - /** - * Marks a bank transaction as excluded. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - private async excludeBankTransaction( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { transactionId } = req.params; - - try { - await this.excludeBankTransactionApp.excludeBankTransaction( - tenantId, - transactionId - ); - return res.status(200).send({ - message: 'The bank transaction has been excluded.', - id: transactionId, - }); - } catch (error) { - next(error); - } - } - - /** - * Marks a bank transaction as not excluded. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async unexcludeBankTransaction( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { transactionId } = req.params; - - try { - await this.excludeBankTransactionApp.unexcludeBankTransaction( - tenantId, - transactionId - ); - return res.status(200).send({ - message: 'The bank transaction has been unexcluded.', - id: transactionId, - }); - } catch (error) { - next(error); - } - } - - /** - * Exclude bank transactions in bulk. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async excludeBulkBankTransactions( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { ids } = this.matchedBodyData(req); - - try { - await this.excludeBankTransactionApp.excludeBankTransactions( - tenantId, - ids - ); - return res.status(200).send({ - message: 'The given bank transactions have been excluded', - ids, - }); - } catch (error) { - next(error); - } - } - - /** - * Unexclude the given bank transactions in bulk. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async unexcludeBulkBankTransactins( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const { ids } = this.matchedBodyData(req); - - try { - await this.excludeBankTransactionApp.unexcludeBankTransactions( - tenantId, - ids - ); - return res.status(200).send({ - message: 'The given bank transactions have been excluded', - ids, - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the excluded uncategorized bank transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async getExcludedBankTransactions( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const data = - await this.excludeBankTransactionApp.getExcludedBankTransactions( - tenantId, - filter - ); - return res.status(200).send(data); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Banking/PlaidBankingController.ts b/packages/server/src/api/controllers/Banking/PlaidBankingController.ts deleted file mode 100644 index 079fdf8bb..000000000 --- a/packages/server/src/api/controllers/Banking/PlaidBankingController.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import { PlaidApplication } from '@/services/Banking/Plaid/PlaidApplication'; - -@Service() -export class PlaidBankingController extends BaseController { - @Inject() - private plaidApp: PlaidApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post('/link-token', this.linkToken.bind(this)); - router.post('/exchange-token', this.exchangeToken.bind(this)); - - return router; - } - - /** - * Retrieves the Plaid link token. - * @param {Request} req - * @param {response} res - * @returns {Response} - */ - private async linkToken(req: Request, res: Response) { - const { tenantId } = req; - - const linkToken = await this.plaidApp.getLinkToken(tenantId); - - return res.status(200).send(linkToken); - } - - /** - * Exchanges the given public token. - * @param {Request} req - * @param {response} res - * @returns {Response} - */ - public async exchangeToken(req: Request, res: Response) { - const { tenantId } = req; - const { public_token, institution_id } = req.body; - - await this.plaidApp.exchangeToken(tenantId, { - institutionId: institution_id, - publicToken: public_token, - }); - return res.status(200).send({}); - } -} diff --git a/packages/server/src/api/controllers/Banking/RecognizedTransactionsController.ts b/packages/server/src/api/controllers/Banking/RecognizedTransactionsController.ts deleted file mode 100644 index 15de0ae89..000000000 --- a/packages/server/src/api/controllers/Banking/RecognizedTransactionsController.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { NextFunction, Request, Response, Router } from 'express'; -import { query } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { CashflowApplication } from '@/services/Cashflow/CashflowApplication'; - -@Service() -export class RecognizedTransactionsController extends BaseController { - @Inject() - private cashflowApplication: CashflowApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - [ - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('account_id').optional().isNumeric().toInt(), - query('min_date').optional({ nullable: true }).isISO8601().toDate(), - query('max_date').optional({ nullable: true }).isISO8601().toDate(), - query('min_amount').optional({ nullable: true }).isFloat().toFloat(), - query('max_amount').optional({ nullable: true }).isFloat().isFloat(), - ], - this.validationResult, - this.getRecognizedTransactions.bind(this) - ); - router.get( - '/transactions/:uncategorizedTransactionId', - this.getRecognizedTransaction.bind(this) - ); - - return router; - } - - /** - * Retrieves the recognized bank transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async getRecognizedTransactions( - req: Request<{ accountId: number }>, - res: Response, - next: NextFunction - ) { - const filter = this.matchedQueryData(req); - const { tenantId } = req; - - try { - const data = await this.cashflowApplication.getRecognizedTransactions( - tenantId, - filter - ); - return res.status(200).send(data); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the recognized transaction of the ginen uncategorized transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - async getRecognizedTransaction( - req: Request<{ uncategorizedTransactionId: number }>, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { uncategorizedTransactionId } = req.params; - - try { - const data = await this.cashflowApplication.getRecognizedTransaction( - tenantId, - uncategorizedTransactionId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/BaseController.ts b/packages/server/src/api/controllers/BaseController.ts deleted file mode 100644 index 4ae651518..000000000 --- a/packages/server/src/api/controllers/BaseController.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { Response, Request, NextFunction } from 'express'; -import { matchedData, validationResult } from 'express-validator'; -import accepts from 'accepts'; -import { isArray, drop, first, camelCase, snakeCase, omit, set, get } from 'lodash'; -import { mapKeysDeep } from 'utils'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; - -export default class BaseController { - /** - * Converts plain object keys to cameCase style. - * @param {Object} data - */ - protected dataToCamelCase(data) { - return mapKeysDeep(data, (v, k) => camelCase(k)); - } - - /** - * Matches the body data from validation schema. - * @param {Request} req - * @param options - */ - protected matchedBodyData(req: Request, options: any = {}) { - const data = matchedData(req, { - locations: ['body'], - includeOptionals: true, - ...omit(options, ['locations']), // override any propery except locations. - }); - return this.dataToCamelCase(data); - } - - /** - * Matches the query data from validation schema. - * @param {Request} req - */ - protected matchedQueryData(req: Request) { - const data = matchedData(req, { - locations: ['query'], - }); - return this.dataToCamelCase(data); - } - - /** - * Validate validation schema middleware. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - protected validationResult(req: Request, res: Response, next: NextFunction) { - const validationErrors = validationResult(req); - - if (!validationErrors.isEmpty()) { - return res.boom.badData(null, { - code: 'validation_error', - ...validationErrors, - }); - } - next(); - } - - /** - * Sets localization to response object by the given path. - * @param {Response} response - - * @param {string} path - - * @param {Request} req - - */ - private setLocalizationByPath( - response: any, - path: string, - req: Request, - ) { - const DOT = '.'; - - if (isArray(response)) { - response.forEach((va) => { - const currentPath = first(path.split(DOT)); - const value = get(va, currentPath); - - if (isArray(value)) { - const nextPath = drop(path.split(DOT)).join(DOT); - this.setLocalizationByPath(value, nextPath, req); - } else { - set(va, path, req.__(value)); - } - }) - } else { - const value = get(response, path); - set(response, path, req.__(value)); - } - } - - /** - * Transform the given data to response. - * @param {any} data - */ - protected transfromToResponse( - data: any, - translatable?: string | string[], - req?: Request - ) { - const response = mapKeysDeep(data, (v, k) => snakeCase(k)); - - if (translatable) { - const translatables = Array.isArray(translatable) - ? translatable - : [translatable]; - - translatables.forEach((path) => { - this.setLocalizationByPath(response, path, req); - }); - } - return response; - } - - /** - * Async middleware. - * @param {function} callback - */ - protected asyncMiddleware(callback) { - return asyncMiddleware(callback); - } - - /** - * - * @param {Request} req - * @returns - */ - protected accepts(req) { - return accepts(req); - } - - /** - * - * @param {Request} req - * @param {string[]} types - * @returns {string} - */ - protected acceptTypes(req: Request, types: string[]) { - return this.accepts(req).types(types); - } -} diff --git a/packages/server/src/api/controllers/Branches/index.ts b/packages/server/src/api/controllers/Branches/index.ts deleted file mode 100644 index 56704ffe4..000000000 --- a/packages/server/src/api/controllers/Branches/index.ts +++ /dev/null @@ -1,335 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { check, param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { Features, ICreateBranchDTO, IEditBranchDTO } from '@/interfaces'; -import { BranchesApplication } from '@/services/Branches/BranchesApplication'; -import { ServiceError } from '@/exceptions'; -import { FeatureActivationGuard } from '@/api/middleware/FeatureActivationGuard'; - -@Service() -export class BranchesController extends BaseController { - @Inject() - branchesApplication: BranchesApplication; - - /** - * Branches routes. - * @returns {Router} - */ - router() { - const router = Router(); - - router.post( - '/activate', - [], - this.validationResult, - this.asyncMiddleware(this.activateBranches), - this.handlerServiceErrors - ); - router.post( - '/', - FeatureActivationGuard(Features.BRANCHES), - [ - check('name').exists(), - check('code').optional({ nullable: true }), - - check('address').optional({ nullable: true }), - check('city').optional({ nullable: true }), - check('country').optional({ nullable: true }), - - check('phone_number').optional({ nullable: true }), - check('email').optional({ nullable: true }).isEmail(), - check('website').optional({ nullable: true }).isURL(), - ], - this.validationResult, - this.asyncMiddleware(this.createBranch), - this.handlerServiceErrors - ); - router.post( - '/:id', - FeatureActivationGuard(Features.BRANCHES), - [ - param('id').exists().isInt().toInt(), - check('name').exists(), - check('code').optional({ nullable: true }), - - check('address').optional({ nullable: true }), - check('city').optional({ nullable: true }), - check('country').optional({ nullable: true }), - - check('phone_number').optional({ nullable: true }), - check('email').optional({ nullable: true }).isEmail(), - check('website').optional({ nullable: true }).isURL(), - ], - this.validationResult, - this.asyncMiddleware(this.editBranch), - this.handlerServiceErrors - ); - router.post( - '/:id/mark-primary', - FeatureActivationGuard(Features.BRANCHES), - [], - this.validationResult, - this.asyncMiddleware(this.markBranchAsPrimary), - this.handlerServiceErrors - ); - router.delete( - '/:id', - FeatureActivationGuard(Features.BRANCHES), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteBranch), - this.handlerServiceErrors - ); - router.get( - '/:id', - FeatureActivationGuard(Features.BRANCHES), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.getBranch), - this.handlerServiceErrors - ); - router.get( - '/', - FeatureActivationGuard(Features.BRANCHES), - [], - this.validationResult, - this.asyncMiddleware(this.getBranches), - this.handlerServiceErrors - ); - return router; - } - - /** - * Creates a new branch. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public createBranch = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const createBranchDTO: ICreateBranchDTO = this.matchedBodyData(req); - - try { - const branch = await this.branchesApplication.createBranch( - tenantId, - createBranchDTO - ); - return res.status(200).send({ - id: branch.id, - message: 'The branch has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Edits the given branch. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public editBranch = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: branchId } = req.params; - const editBranchDTO: IEditBranchDTO = this.matchedBodyData(req); - - try { - const branch = await this.branchesApplication.editBranch( - tenantId, - branchId, - editBranchDTO - ); - return res.status(200).send({ - id: branch.id, - message: 'The branch has been edited successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the given branch. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public deleteBranch = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: branchId } = req.params; - - try { - await this.branchesApplication.deleteBranch(tenantId, branchId); - - return res.status(200).send({ - id: branchId, - message: 'The branch has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves specific branch. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public getBranch = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: branchId } = req.params; - - try { - const branch = await this.branchesApplication.getBranch( - tenantId, - branchId - ); - return res.status(200).send({ branch }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves branches list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public getBranches = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const branches = await this.branchesApplication.getBranches(tenantId); - - return res.status(200).send({ branches }); - } catch (error) { - next(error); - } - }; - - /** - * Activates the multi-branches feature. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public activateBranches = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - await this.branchesApplication.activateBranches(tenantId); - - return res.status(200).send({ - message: 'Multi-branches feature has been activated successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Marks the given branch as primary. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public markBranchAsPrimary = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: branchId } = req.params; - - try { - await this.branchesApplication.markBranchAsPrimary(tenantId, branchId); - - return res.status(200).send({ - id: branchId, - message: 'The branch has been marked as primary.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'BRANCH_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'BRANCH_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'MUTLI_BRANCHES_ALREADY_ACTIVATED') { - return res.status(400).send({ - errors: [{ type: 'MUTLI_BRANCHES_ALREADY_ACTIVATED', code: 100 }], - }); - } - if (error.errorType === 'COULD_NOT_DELETE_ONLY_BRANCH') { - return res.status(400).send({ - errors: [{ type: 'COULD_NOT_DELETE_ONLY_BRANCH', code: 300 }], - }); - } - if (error.errorType === 'BRANCH_CODE_NOT_UNIQUE') { - return res.status(400).send({ - errors: [{ type: 'BRANCH_CODE_NOT_UNIQUE', code: 400 }], - }); - } - if (error.errorType === 'BRANCH_HAS_ASSOCIATED_TRANSACTIONS') { - return res.status(400).send({ - errors: [ - { type: 'BRANCH_HAS_ASSOCIATED_TRANSACTIONS', code: 500 }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Cashflow/CashflowController.ts b/packages/server/src/api/controllers/Cashflow/CashflowController.ts deleted file mode 100644 index 4ef98d267..000000000 --- a/packages/server/src/api/controllers/Cashflow/CashflowController.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Service, Inject, Container } from 'typedi'; -import { Router } from 'express'; -import CommandCashflowTransaction from './NewCashflowTransaction'; -import DeleteCashflowTransaction from './DeleteCashflowTransaction'; -import GetCashflowTransaction from './GetCashflowTransaction'; -import GetCashflowAccounts from './GetCashflowAccounts'; -import { ExcludeBankTransactionsController } from '../Banking/ExcludeBankTransactionsController'; - -@Service() -export default class CashflowController { - /** - * Constructor method. - */ - router() { - const router = Router(); - - router.use(Container.get(CommandCashflowTransaction).router()); - router.use(Container.get(ExcludeBankTransactionsController).router()); - router.use(Container.get(GetCashflowTransaction).router()); - router.use(Container.get(GetCashflowAccounts).router()); - router.use(Container.get(DeleteCashflowTransaction).router()); - - return router; - } -} diff --git a/packages/server/src/api/controllers/Cashflow/DeleteCashflowTransaction.ts b/packages/server/src/api/controllers/Cashflow/DeleteCashflowTransaction.ts deleted file mode 100644 index 5e0a763d9..000000000 --- a/packages/server/src/api/controllers/Cashflow/DeleteCashflowTransaction.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { param } from 'express-validator'; -import BaseController from '../BaseController'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; - -import { AbilitySubject, CashflowAction } from '@/interfaces'; -import { CashflowApplication } from '@/services/Cashflow/CashflowApplication'; - -@Service() -export default class DeleteCashflowTransactionController extends BaseController { - @Inject() - private cashflowApplication: CashflowApplication; - - /** - * Controller router. - */ - public router() { - const router = Router(); - - router.delete( - '/transactions/:transactionId', - CheckPolicies(CashflowAction.Delete, AbilitySubject.Cashflow), - [param('transactionId').exists().isInt().toInt()], - this.asyncMiddleware(this.deleteCashflowTransaction), - this.catchServiceErrors - ); - return router; - } - - /** - * Retrieve the cashflow account transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private deleteCashflowTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { transactionId } = req.params; - - try { - const { oldCashflowTransaction } = - await this.cashflowApplication.deleteTransaction( - tenantId, - transactionId - ); - - return res.status(200).send({ - id: oldCashflowTransaction.id, - message: 'The cashflow transaction has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Catches the service errors. - * @param error - * @param req - * @param res - * @param next - * @returns - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'CASHFLOW_TRANSACTION_NOT_FOUND') { - return res.boom.badRequest( - 'The given cashflow transaction not found.', - { - errors: [{ type: 'CASHFLOW_TRANSACTION_NOT_FOUND', code: 100 }], - } - ); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if ( - error.errorType === - 'CANNOT_DELETE_TRANSACTION_CONVERTED_FROM_UNCATEGORIZED' - ) { - return res.boom.badRequest(null, { - errors: [ - { - type: 'CANNOT_DELETE_TRANSACTION_CONVERTED_FROM_UNCATEGORIZED', - code: 4100, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Cashflow/GetCashflowAccounts.ts b/packages/server/src/api/controllers/Cashflow/GetCashflowAccounts.ts deleted file mode 100644 index 6e0d2dfec..000000000 --- a/packages/server/src/api/controllers/Cashflow/GetCashflowAccounts.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import BaseController from '../BaseController'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, CashflowAction } from '@/interfaces'; -import { CashflowApplication } from '@/services/Cashflow/CashflowApplication'; - -@Service() -export default class GetCashflowAccounts extends BaseController { - @Inject() - private cashflowApplication: CashflowApplication; - - /** - * Controller router. - */ - public router() { - const router = Router(); - - router.get( - '/accounts', - CheckPolicies(CashflowAction.View, AbilitySubject.Cashflow), - [ - query('stringified_filter_roles').optional().isJSON(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('inactive_mode').optional().isBoolean().toBoolean(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ], - this.asyncMiddleware(this.getCashflowAccounts), - ); - return router; - } - - /** - * Retrieve the cashflow accounts. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getCashflowAccounts = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - // Filter query. - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - inactiveMode: false, - ...this.matchedQueryData(req), - }; - - try { - const cashflowAccounts = - await this.cashflowApplication.getCashflowAccounts(tenantId, filter); - - return res.status(200).send({ - cashflow_accounts: this.transfromToResponse(cashflowAccounts), - }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Cashflow/GetCashflowTransaction.ts b/packages/server/src/api/controllers/Cashflow/GetCashflowTransaction.ts deleted file mode 100644 index c7d57105c..000000000 --- a/packages/server/src/api/controllers/Cashflow/GetCashflowTransaction.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { param, query } from 'express-validator'; -import BaseController from '../BaseController'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, CashflowAction } from '@/interfaces'; -import { CashflowApplication } from '@/services/Cashflow/CashflowApplication'; -import { GetMatchedTransactionsFilter } from '@/services/Banking/Matching/types'; -import { MatchBankTransactionsApplication } from '@/services/Banking/Matching/MatchBankTransactionsApplication'; - -@Service() -export default class GetCashflowAccounts extends BaseController { - @Inject() - private cashflowApplication: CashflowApplication; - - @Inject() - private bankTransactionsMatchingApp: MatchBankTransactionsApplication; - - /** - * Controller router. - */ - public router() { - const router = Router(); - - router.get( - '/transactions/matches', - [ - query('uncategorizeTransactionsIds').exists().isArray({ min: 1 }), - query('uncategorizeTransactionsIds.*').exists().isNumeric().toInt(), - ], - this.validationResult, - this.getMatchedTransactions.bind(this) - ); - router.get( - '/transactions/:transactionId', - CheckPolicies(CashflowAction.View, AbilitySubject.Cashflow), - [param('transactionId').exists().isInt().toInt()], - this.asyncMiddleware(this.getCashflowTransaction), - this.catchServiceErrors - ); - return router; - } - - /** - * Retrieve the cashflow account transactions. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - */ - private getCashflowTransaction = async ( - req: Request<{ transactionId: number }>, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { transactionId } = req.params; - - try { - const cashflowTransaction = await this.cashflowApplication.getTransaction( - tenantId, - transactionId - ); - return res.status(200).send({ - cashflow_transaction: this.transfromToResponse(cashflowTransaction), - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the matched transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getMatchedTransactions( - req: Request< - { transactionId: number }, - null, - null, - { uncategorizeTransactionsIds: Array } - >, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const uncategorizeTransactionsIds = req.query.uncategorizeTransactionsIds; - const filter = this.matchedQueryData(req) as GetMatchedTransactionsFilter; - - try { - const data = - await this.bankTransactionsMatchingApp.getMatchedTransactions( - tenantId, - uncategorizeTransactionsIds, - filter - ); - return res.status(200).send(data); - } catch (error) { - next(error); - } - } - - /** - * Catches the service errors. - * @param {Error} error - Error. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @param {NextFunction} next - - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'CASHFLOW_TRANSACTION_NOT_FOUND') { - return res.boom.badRequest( - 'The given cashflow tranasction not found.', - { - errors: [{ type: 'CASHFLOW_TRANSACTION_NOT_FOUND', code: 200 }], - } - ); - } - if (error.errorType === 'ACCOUNT_ID_HAS_INVALID_TYPE') { - return res.boom.badRequest( - 'The given cashflow account has invalid type.', - { - errors: [{ type: 'ACCOUNT_ID_HAS_INVALID_TYPE', code: 300 }], - } - ); - } - if (error.errorType === 'ACCOUNT_NOT_FOUND') { - return res.boom.badRequest('The given account not found.', { - errors: [{ type: 'ACCOUNT_NOT_FOUND', code: 400 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Cashflow/NewCashflowTransaction.ts b/packages/server/src/api/controllers/Cashflow/NewCashflowTransaction.ts deleted file mode 100644 index 554d22bf6..000000000 --- a/packages/server/src/api/controllers/Cashflow/NewCashflowTransaction.ts +++ /dev/null @@ -1,412 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ValidationChain, body, check, param, query } from 'express-validator'; -import { Router, Request, Response, NextFunction } from 'express'; -import { omit } from 'lodash'; -import BaseController from '../BaseController'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { - AbilitySubject, - CashflowAction, - ICategorizeCashflowTransactioDTO, -} from '@/interfaces'; -import { CashflowApplication } from '@/services/Cashflow/CashflowApplication'; - -@Service() -export default class NewCashflowTransactionController extends BaseController { - @Inject() - private cashflowApplication: CashflowApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/transactions/uncategorized/:id', - this.asyncMiddleware(this.getUncategorizedCashflowTransaction), - this.catchServiceErrors - ); - router.get( - '/transactions/:id/uncategorized', - this.getUncategorizedTransactionsValidationSchema, - this.validationResult, - this.asyncMiddleware(this.getUncategorizedCashflowTransactions), - this.catchServiceErrors - ); - router.post( - '/transactions', - CheckPolicies(CashflowAction.Create, AbilitySubject.Cashflow), - this.newTransactionValidationSchema, - this.validationResult, - this.asyncMiddleware(this.newCashflowTransaction), - this.catchServiceErrors - ); - router.post( - '/transactions/uncategorize/bulk', - [ - body('ids').isArray({ min: 1 }), - body('ids.*').exists().isNumeric().toInt(), - ], - this.validationResult, - this.uncategorizeBulkTransactions.bind(this), - this.catchServiceErrors - ); - router.post( - '/transactions/:id/uncategorize', - this.revertCategorizedCashflowTransaction, - this.catchServiceErrors - ); - router.post( - '/transactions/categorize', - this.categorizeCashflowTransactionValidationSchema, - this.validationResult, - this.categorizeCashflowTransaction, - this.catchServiceErrors - ); - router.post( - '/transaction/:id/categorize/expense', - this.categorizeAsExpenseValidationSchema, - this.validationResult, - this.categorizesCashflowTransactionAsExpense, - this.catchServiceErrors - ); - return router; - } - - /** - * Getting uncategorized transactions validation schema. - * @returns {ValidationChain} - */ - public get getUncategorizedTransactionsValidationSchema() { - return [ - param('id').exists().isNumeric().toInt(), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('min_date').optional({ nullable: true }).isISO8601().toDate(), - query('max_date').optional({ nullable: true }).isISO8601().toDate(), - query('min_amount').optional({ nullable: true }).isFloat().toFloat(), - query('max_amount').optional({ nullable: true }).isFloat().toFloat(), - ]; - } - - /** - * Categorize as expense validation schema. - */ - public get categorizeAsExpenseValidationSchema() { - return [ - check('expense_account_id').exists(), - check('date').isISO8601().exists(), - check('reference_no').optional(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - ]; - } - - /** - * Categorize cashflow tranasction validation schema. - */ - public get categorizeCashflowTransactionValidationSchema() { - return [ - check('uncategorized_transaction_ids').exists().isArray({ min: 1 }), - check('date').exists().isISO8601().toDate(), - check('credit_account_id').exists().isInt().toInt(), - check('transaction_number').optional(), - check('transaction_type').exists(), - check('reference_no').optional(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - check('description').optional(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - ]; - } - - /** - * New cashflow transaction validation schema. - */ - public get newTransactionValidationSchema() { - return [ - check('date').exists().isISO8601().toDate(), - check('reference_no').optional({ nullable: true }).trim(), - check('description') - .optional({ nullable: true }) - .isLength({ min: 3 }) - .trim(), - check('transaction_type').exists(), - - check('amount').exists().isFloat().toFloat(), - check('cashflow_account_id').exists().isInt().toInt(), - check('credit_account_id').exists().isInt().toInt(), - - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - check('publish').default(false).isBoolean().toBoolean(), - ]; - } - - /** - * Creates a new cashflow transaction. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private newCashflowTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, userId } = req; - const ownerContributionDTO = this.matchedBodyData(req); - - try { - const cashflowTransaction = - await this.cashflowApplication.createTransaction( - tenantId, - ownerContributionDTO, - userId - ); - return res.status(200).send({ - id: cashflowTransaction.id, - message: 'New cashflow transaction has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Revert the categorized cashflow transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private revertCategorizedCashflowTransaction = async ( - req: Request<{ id: number }>, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: cashflowTransactionId } = req.params; - - try { - const data = await this.cashflowApplication.uncategorizeTransaction( - tenantId, - cashflowTransactionId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Uncategorize the given transactions in bulk. - * @param {Request<{}>} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private uncategorizeBulkTransactions = async ( - req: Request<{}>, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { ids: uncategorizedTransactionIds } = this.matchedBodyData(req); - - try { - await this.cashflowApplication.uncategorizeTransactions( - tenantId, - uncategorizedTransactionIds - ); - return res.status(200).send({ - message: 'The given transactions have been uncategorized successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Categorize the cashflow transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private categorizeCashflowTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const matchedObject = this.matchedBodyData(req); - const categorizeDTO = omit(matchedObject, [ - 'uncategorizedTransactionIds', - ]) as ICategorizeCashflowTransactioDTO; - - const uncategorizedTransactionIds = - matchedObject.uncategorizedTransactionIds; - - try { - await this.cashflowApplication.categorizeTransaction( - tenantId, - uncategorizedTransactionIds, - categorizeDTO - ); - return res.status(200).send({ - message: 'The cashflow transaction has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Categorize the transaction as expense transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private categorizesCashflowTransactionAsExpense = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: cashflowTransactionId } = req.params; - const cashflowTransaction = this.matchedBodyData(req); - - try { - await this.cashflowApplication.categorizeAsExpense( - tenantId, - cashflowTransactionId, - cashflowTransaction - ); - return res.status(200).send({ - message: 'The cashflow transaction has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the uncategorized cashflow transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public getUncategorizedCashflowTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: transactionId } = req.params; - - try { - const data = await this.cashflowApplication.getUncategorizedTransaction( - tenantId, - transactionId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the uncategorized cashflow transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public getUncategorizedCashflowTransactions = async ( - req: Request<{ id: number }>, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: accountId } = req.params; - const query = this.matchedQueryData(req); - - try { - const data = await this.cashflowApplication.getUncategorizedTransactions( - tenantId, - accountId, - query - ); - - return res.status(200).send(data); - } catch (error) { - next(error); - } - }; - - /** - * Handle the service errors. - * @param error - * @param {Request} req - * @param {res - * @param next - * @returns - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'CASHFLOW_ACCOUNTS_IDS_NOT_FOUND') { - return res.boom.badRequest('Cashflow accounts ids not found.', { - errors: [{ type: 'CASHFLOW_ACCOUNTS_IDS_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'CREDIT_ACCOUNTS_IDS_NOT_FOUND') { - return res.boom.badRequest('Credit accounts ids not found.', { - errors: [{ type: 'CREDIT_ACCOUNTS_IDS_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'CREDIT_ACCOUNTS_HAS_INVALID_TYPE') { - return res.boom.badRequest('Cashflow .', { - errors: [{ type: 'CREDIT_ACCOUNTS_HAS_INVALID_TYPE', code: 300 }], - }); - } - if (error.errorType === 'CASHFLOW_ACCOUNTS_HAS_INVALID_TYPE') { - return res.boom.badRequest( - 'Cashflow accounts should be cash or bank type.', - { - errors: [{ type: 'CASHFLOW_ACCOUNTS_HAS_INVALID_TYPE', code: 300 }], - } - ); - } - if (error.errorType === 'CASHFLOW_TRANSACTION_NOT_FOUND') { - return res.boom.badRequest('Cashflow transaction not found.', { - errors: [{ type: 'CASHFLOW_TRANSACTION_NOT_FOUND', code: 500 }], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'UNCATEGORIZED_TRANSACTION_TYPE_INVALID') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'UNCATEGORIZED_TRANSACTION_TYPE_INVALID', - code: 4100, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Contacts/Contacts.ts b/packages/server/src/api/controllers/Contacts/Contacts.ts deleted file mode 100644 index 6d5bf19ec..000000000 --- a/packages/server/src/api/controllers/Contacts/Contacts.ts +++ /dev/null @@ -1,379 +0,0 @@ -import { check, param, query, body, ValidationChain } from 'express-validator'; -import { Router, Request, Response, NextFunction } from 'express'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import BaseController from '@/api/controllers/BaseController'; -import ContactsService from '@/services/Contacts/ContactsService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; - -@Service() -export default class ContactsController extends BaseController { - @Inject() - contactsService: ContactsService; - - @Inject() - dynamicListService: DynamicListingService; - - /** - * Express router. - */ - router() { - const router = Router(); - - router.get( - '/auto-complete', - [...this.autocompleteQuerySchema], - this.validationResult, - this.asyncMiddleware(this.autocompleteContacts.bind(this)), - this.dynamicListService.handlerErrorsToResponse, - ); - router.get( - '/:id', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getContact.bind(this)), - ); - router.post( - '/:id/inactivate', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.inactivateContact.bind(this)), - this.handlerServiceErrors, - ); - router.post( - '/:id/activate', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.activateContact.bind(this)), - this.handlerServiceErrors, - ); - return router; - } - - /** - * Auto-complete list query validation schema. - */ - get autocompleteQuerySchema() { - return [ - query('column_sort_by').optional().trim(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('stringified_filter_roles').optional().isJSON(), - query('limit').optional().isNumeric().toInt(), - ]; - } - - /** - * Retrieve details of the given contact. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async getContact(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: contactId } = req.params; - - try { - const contact = await this.contactsService.getContact( - tenantId, - contactId, - ); - return res.status(200).send({ - customer: this.transfromToResponse(contact), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve auto-complete contacts list. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - */ - async autocompleteContacts(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = { - filterRoles: [], - sortOrder: 'asc', - columnSortBy: 'display_name', - limit: 10, - ...this.matchedQueryData(req), - }; - try { - const contacts = await this.contactsService.autocompleteContacts( - tenantId, - filter, - ); - return res.status(200).send({ contacts }); - } catch (error) { - next(error); - } - } - - /** - * @returns {ValidationChain[]} - */ - get contactDTOSchema(): ValidationChain[] { - return [ - check('salutation') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('first_name') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('last_name') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('company_name') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - - check('display_name') - .exists() - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - - check('email') - .optional({ nullable: true }) - .isString() - .isEmail() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('website') - .optional({ nullable: true }) - .isString() - .trim() - .isURL() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('work_phone') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('personal_phone') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - - check('billing_address_1') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_2') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_city') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_country') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_email') - .optional({ nullable: true }) - .isString() - .isEmail() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_postcode') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_phone') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('billing_address_state') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - - check('shipping_address_1') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_2') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_city') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_country') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_email') - .optional({ nullable: true }) - .isString() - .isEmail() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_postcode') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_phone') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('shipping_address_state') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - - check('note') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('active').optional().isBoolean().toBoolean(), - ]; - } - - /** - * Contact new DTO schema. - * @returns {ValidationChain[]} - */ - get contactNewDTOSchema(): ValidationChain[] { - return [ - check('opening_balance') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.DECIMAL_13_3 }) - .toInt(), - check('opening_balance_exchange_rate') - .default(1) - .isFloat({ gt: 0 }) - .toFloat(), - body('opening_balance_at') - .if(body('opening_balance').exists()) - .exists() - .isISO8601(), - check('opening_balance_branch_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - ]; - } - - /** - * Contact edit DTO schema. - * @returns {ValidationChain[]} - */ - get contactEditDTOSchema(): ValidationChain[] { - return []; - } - - /** - * @returns {ValidationChain[]} - */ - get specificContactSchema(): ValidationChain[] { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Activates the given contact. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async activateContact(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: contactId } = req.params; - - try { - await this.contactsService.activateContact(tenantId, contactId); - - return res.status(200).send({ - id: contactId, - message: 'The given contact activated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Inactivate the given contact. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async inactivateContact(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: contactId } = req.params; - - try { - await this.contactsService.inactivateContact(tenantId, contactId); - - return res.status(200).send({ - id: contactId, - message: 'The given contact inactivated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction, - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CONTACT.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'CONTACT_ALREADY_ACTIVE') { - return res.boom.badRequest(null, { - errors: [{ type: 'CONTACT_ALREADY_ACTIVE', code: 700 }], - }); - } - if (error.errorType === 'CONTACT_ALREADY_INACTIVE') { - return res.boom.badRequest(null, { - errors: [{ type: 'CONTACT_ALREADY_INACTIVE', code: 800 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Contacts/Customers.ts b/packages/server/src/api/controllers/Contacts/Customers.ts deleted file mode 100644 index 19edc3817..000000000 --- a/packages/server/src/api/controllers/Contacts/Customers.ts +++ /dev/null @@ -1,344 +0,0 @@ -import { Request, Response, Router, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import { check, query } from 'express-validator'; -import ContactsController from '@/api/controllers/Contacts/Contacts'; -import CustomersService from '@/services/Contacts/CustomersService'; -import { ServiceError } from '@/exceptions'; -import { - ICustomerNewDTO, - ICustomerEditDTO, - AbilitySubject, - CustomerAction, -} from '@/interfaces'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { CustomersApplication } from '@/services/Contacts/Customers/CustomersApplication'; - -@Service() -export default class CustomersController extends ContactsController { - @Inject() - private customersApplication: CustomersApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Express router. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(CustomerAction.Create, AbilitySubject.Customer), - [ - ...this.contactDTOSchema, - ...this.contactNewDTOSchema, - ...this.customerDTOSchema, - ...this.createCustomerDTOSchema, - ], - this.validationResult, - asyncMiddleware(this.newCustomer.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id/opening_balance', - CheckPolicies(CustomerAction.Edit, AbilitySubject.Customer), - [ - ...this.specificContactSchema, - check('opening_balance').exists().isNumeric().toFloat(), - check('opening_balance_at').optional().isISO8601(), - check('opening_balance_exchange_rate') - .default(1) - .isFloat({ gt: 0 }) - .toFloat(), - check('opening_balance_branch_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - ], - this.validationResult, - asyncMiddleware(this.editOpeningBalanceCustomer.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id', - CheckPolicies(CustomerAction.Edit, AbilitySubject.Customer), - [ - ...this.contactDTOSchema, - ...this.contactEditDTOSchema, - ...this.customerDTOSchema, - ], - this.validationResult, - asyncMiddleware(this.editCustomer.bind(this)), - this.handlerServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(CustomerAction.Delete, AbilitySubject.Customer), - [...this.specificContactSchema], - this.validationResult, - asyncMiddleware(this.deleteCustomer.bind(this)), - this.handlerServiceErrors - ); - router.get( - '/', - CheckPolicies(CustomerAction.View, AbilitySubject.Customer), - [...this.validateListQuerySchema], - this.validationResult, - asyncMiddleware(this.getCustomersList.bind(this)), - this.dynamicListService.handlerErrorsToResponse - ); - router.get( - '/:id', - CheckPolicies(CustomerAction.View, AbilitySubject.Customer), - [...this.specificContactSchema], - this.validationResult, - asyncMiddleware(this.getCustomer.bind(this)), - this.handlerServiceErrors - ); - return router; - } - - /** - * Customer DTO schema. - */ - get customerDTOSchema() { - return [ - check('customer_type').exists().isIn(['business', 'individual']).trim(), - ]; - } - - /** - * Create customer DTO schema. - */ - get createCustomerDTOSchema() { - return [ - check('currency_code') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: 3 }), - ]; - } - - /** - * List param query schema. - */ - get validateListQuerySchema() { - return [ - query('column_sort_by').optional().trim(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('view_slug').optional().isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - - query('inactive_mode').optional().isBoolean().toBoolean(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Creates a new customer. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async newCustomer(req: Request, res: Response, next: NextFunction) { - const contactDTO: ICustomerNewDTO = this.matchedBodyData(req); - const { tenantId, user } = req; - - try { - const contact = await this.customersApplication.createCustomer( - tenantId, - contactDTO - ); - return res.status(200).send({ - id: contact.id, - message: 'The customer has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edits the given customer details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async editCustomer(req: Request, res: Response, next: NextFunction) { - const contactDTO: ICustomerEditDTO = this.matchedBodyData(req); - const { tenantId, user } = req; - const { id: contactId } = req.params; - - try { - await this.customersApplication.editCustomer( - tenantId, - contactId, - contactDTO, - user - ); - - return res.status(200).send({ - id: contactId, - message: 'The customer has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Changes the opening balance of the given customer. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async editOpeningBalanceCustomer( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: customerId } = req.params; - const openingBalanceEditDTO = this.matchedBodyData(req); - - try { - await this.customersApplication.editOpeningBalance( - tenantId, - customerId, - openingBalanceEditDTO - ); - return res.status(200).send({ - id: customerId, - message: - 'The opening balance of the given customer has been changed successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve details of the given customer id. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async getCustomer(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: contactId } = req.params; - - try { - const customer = await this.customersApplication.getCustomer( - tenantId, - contactId, - user - ); - - return res.status(200).send({ - customer: this.transfromToResponse(customer), - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given customer from the storage. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async deleteCustomer(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: contactId } = req.params; - - try { - await this.customersApplication.deleteCustomer(tenantId, contactId, user); - - return res.status(200).send({ - id: contactId, - message: 'The customer has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve customers paginated and filterable list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async getCustomersList(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - const filter = { - inactiveMode: false, - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - - try { - const { customers, pagination, filterMeta } = - await this.customersApplication.getCustomers(tenantId, filter); - - return res.status(200).send({ - customers: this.transfromToResponse(customers), - pagination: this.transfromToResponse(pagination), - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'contacts_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMERS.NOT.FOUND', code: 200 }], - }); - } - if (error.errorType === 'OPENING_BALANCE_DATE_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'OPENING_BALANCE_DATE_REQUIRED', code: 500 }], - }); - } - if (error.errorType === 'CUSTOMER_HAS_TRANSACTIONS') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_HAS_TRANSACTIONS', code: 600 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Contacts/Vendors.ts b/packages/server/src/api/controllers/Contacts/Vendors.ts deleted file mode 100644 index 78c5c6fb4..000000000 --- a/packages/server/src/api/controllers/Contacts/Vendors.ts +++ /dev/null @@ -1,329 +0,0 @@ -import { Request, Response, Router, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import { body, query, ValidationChain, check } from 'express-validator'; - -import ContactsController from '@/api/controllers/Contacts/Contacts'; -import { ServiceError } from '@/exceptions'; -import { - IVendorNewDTO, - IVendorEditDTO, - IVendorsFilter, - AbilitySubject, - VendorAction, -} from '@/interfaces'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { VendorsApplication } from '@/services/Contacts/Vendors/VendorsApplication'; - -@Service() -export default class VendorsController extends ContactsController { - @Inject() - private vendorsApplication: VendorsApplication; - - /** - * Express router. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(VendorAction.Create, AbilitySubject.Vendor), - [ - ...this.contactDTOSchema, - ...this.contactNewDTOSchema, - ...this.vendorDTOSchema, - ], - this.validationResult, - asyncMiddleware(this.newVendor.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id/opening_balance', - CheckPolicies(VendorAction.Edit, AbilitySubject.Vendor), - [ - ...this.specificContactSchema, - check('opening_balance').exists().isNumeric().toFloat(), - check('opening_balance_at').optional().isISO8601(), - check('opening_balance_exchange_rate') - .default(1) - .isFloat({ gt: 0 }) - .toFloat(), - check('opening_balance_branch_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - ], - this.validationResult, - asyncMiddleware(this.editOpeningBalanceVendor.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id', - CheckPolicies(VendorAction.Edit, AbilitySubject.Vendor), - [ - ...this.contactDTOSchema, - ...this.contactEditDTOSchema, - ...this.vendorDTOSchema, - ], - this.validationResult, - asyncMiddleware(this.editVendor.bind(this)), - this.handlerServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(VendorAction.Delete, AbilitySubject.Vendor), - [...this.specificContactSchema], - this.validationResult, - asyncMiddleware(this.deleteVendor.bind(this)), - this.handlerServiceErrors - ); - router.get( - '/:id', - CheckPolicies(VendorAction.View, AbilitySubject.Vendor), - [...this.specificContactSchema], - this.validationResult, - asyncMiddleware(this.getVendor.bind(this)), - this.handlerServiceErrors - ); - router.get( - '/', - CheckPolicies(VendorAction.View, AbilitySubject.Vendor), - [...this.vendorsListSchema], - this.validationResult, - asyncMiddleware(this.getVendorsList.bind(this)) - ); - return router; - } - - /** - * Vendor DTO schema. - * @returns {ValidationChain[]} - */ - get vendorDTOSchema(): ValidationChain[] { - return [ - check('currency_code') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ min: 3, max: 3 }), - ]; - } - - /** - * Vendors datatable list validation schema. - * @returns {ValidationChain[]} - */ - get vendorsListSchema() { - return [ - query('view_slug').optional().isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('inactive_mode').optional().isBoolean().toBoolean(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Creates a new vendor. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async newVendor(req: Request, res: Response, next: NextFunction) { - const contactDTO: IVendorNewDTO = this.matchedBodyData(req); - const { tenantId, user } = req; - - try { - const vendor = await this.vendorsApplication.createVendor( - tenantId, - contactDTO - ); - return res.status(200).send({ - id: vendor.id, - message: 'The vendor has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edits the given vendor details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async editVendor(req: Request, res: Response, next: NextFunction) { - const contactDTO: IVendorEditDTO = this.matchedBodyData(req); - const { tenantId, user } = req; - const { id: contactId } = req.params; - - try { - await this.vendorsApplication.editVendor( - tenantId, - contactId, - contactDTO, - user - ); - - return res.status(200).send({ - id: contactId, - message: 'The vendor has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Changes the opening balance of the given vendor. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async editOpeningBalanceVendor( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: vendorId } = req.params; - const editOpeningBalanceDTO = this.matchedBodyData(req); - - try { - await this.vendorsApplication.editOpeningBalance( - tenantId, - vendorId, - editOpeningBalanceDTO - ); - return res.status(200).send({ - id: vendorId, - message: - 'The opening balance of the given vendor has been changed successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given vendor from the storage. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async deleteVendor(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: contactId } = req.params; - - try { - await this.vendorsApplication.deleteVendor(tenantId, contactId, user); - - return res.status(200).send({ - id: contactId, - message: 'The vendor has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve details of the given vendor id. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async getVendor(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: vendorId } = req.params; - - try { - const vendor = await this.vendorsApplication.getVendor( - tenantId, - vendorId, - user - ); - return res.status(200).send(this.transfromToResponse({ vendor })); - } catch (error) { - next(error); - } - } - - /** - * Retrieve vendors datatable list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async getVendorsList(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - const vendorsFilter: IVendorsFilter = { - inactiveMode: false, - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - - try { - const { vendors, pagination, filterMeta } = - await this.vendorsApplication.getVendors(tenantId, vendorsFilter); - - return res.status(200).send({ - vendors: this.transfromToResponse(vendors), - pagination: this.transfromToResponse(pagination), - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - } - - /** - * Handle service errors. - * @param {Error} error - - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private handlerServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'contacts_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDORS.NOT.FOUND', code: 200 }], - }); - } - if (error.errorType === 'OPENING_BALANCE_DATE_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'OPENING_BALANCE_DATE_REQUIRED', code: 500 }], - }); - } - if (error.errorType === 'VENDOR_HAS_TRANSACTIONS') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR_HAS_TRANSACTIONS', code: 600 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Currencies.ts b/packages/server/src/api/controllers/Currencies.ts deleted file mode 100644 index e73a09572..000000000 --- a/packages/server/src/api/controllers/Currencies.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query, ValidationChain } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from './BaseController'; -import CurrenciesService from '@/services/Currencies/CurrenciesService'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; - -@Service() -export default class CurrenciesController extends BaseController { - @Inject() - currenciesService: CurrenciesService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - [...this.listSchema], - this.validationResult, - asyncMiddleware(this.all.bind(this)) - ); - router.post( - '/', - [...this.currencyDTOSchemaValidation], - this.validationResult, - asyncMiddleware(this.newCurrency.bind(this)), - this.handlerServiceError - ); - router.post( - '/:id', - [...this.currencyIdParamSchema, ...this.currencyEditDTOSchemaValidation], - this.validationResult, - asyncMiddleware(this.editCurrency.bind(this)), - this.handlerServiceError - ); - router.delete( - '/:currency_code', - [...this.currencyParamSchema], - this.validationResult, - asyncMiddleware(this.deleteCurrency.bind(this)), - this.handlerServiceError - ); - return router; - } - - get currencyDTOSchemaValidation(): ValidationChain[] { - return [ - check('currency_name').exists().trim(), - check('currency_code').exists().trim(), - check('currency_sign').exists().trim(), - ]; - } - - get currencyEditDTOSchemaValidation(): ValidationChain[] { - return [ - check('currency_name').exists().trim(), - check('currency_sign').exists().trim(), - ]; - } - - get currencyIdParamSchema(): ValidationChain[] { - return [param('id').exists().isNumeric().toInt()]; - } - - get currencyParamSchema(): ValidationChain[] { - return [param('currency_code').exists().trim()]; - } - - get listSchema(): ValidationChain[] { - return [ - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - ]; - } - - /** - * Retrieve all registered currency details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async all(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - try { - const currencies = await this.currenciesService.listCurrencies(tenantId); - - return res.status(200).send({ - currencies: this.transfromToResponse(currencies), - }); - } catch (error) { - next(error); - } - } - - /** - * Creates a new currency on the storage. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async newCurrency(req: Request, res: Response, next: Function) { - const { tenantId } = req; - const currencyDTO = this.matchedBodyData(req); - - try { - await this.currenciesService.newCurrency(tenantId, currencyDTO); - - return res.status(200).send({ - currency_code: currencyDTO.currencyCode, - message: 'The currency has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edits details of the given currency. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async deleteCurrency(req: Request, res: Response, next: Function) { - const { tenantId } = req; - const { currency_code: currencyCode } = req.params; - - try { - await this.currenciesService.deleteCurrency(tenantId, currencyCode); - return res.status(200).send({ - currency_code: currencyCode, - message: 'The currency has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the currency. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async editCurrency(req: Request, res: Response, next: Function) { - const { tenantId } = req; - const { id: currencyId } = req.params; - const editCurrencyDTO = this.matchedBodyData(req); - - try { - const currency = await this.currenciesService.editCurrency( - tenantId, - currencyId, - editCurrencyDTO - ); - return res.status(200).send({ - currency_code: currency.currencyCode, - message: 'The currency has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Handles currencies service error. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - handlerServiceError( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'currency_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CURRENCY_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'currency_code_exists') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'CURRENCY_CODE_EXISTS', - message: 'The given currency code is already exists.', - code: 200, - }, - ], - }); - } - if (error.errorType === 'CANNOT_DELETE_BASE_CURRENCY') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'CANNOT_DELETE_BASE_CURRENCY', - code: 300, - message: 'Cannot delete the base currency.', - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Dashboard/index.ts b/packages/server/src/api/controllers/Dashboard/index.ts deleted file mode 100644 index 47f3a5396..000000000 --- a/packages/server/src/api/controllers/Dashboard/index.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import DashboardService from '@/services/Dashboard/DashboardService'; - -@Service() -export default class DashboardMetaController { - @Inject() - private dashboardService: DashboardService; - - /** - * Constructor router. - * @returns - */ - public router() { - const router = Router(); - - router.get('/boot', this.getDashboardBoot); - - return router; - } - - /** - * Retrieve the dashboard boot meta. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private getDashboardBoot = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const authorizedUser = req.user; - const { tenantId } = req; - - try { - const meta = await this.dashboardService.getBootMeta( - tenantId, - authorizedUser - ); - - return res.status(200).send({ meta }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/ExchangeRates.ts b/packages/server/src/api/controllers/ExchangeRates.ts deleted file mode 100644 index 63c476bf9..000000000 --- a/packages/server/src/api/controllers/ExchangeRates.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query, oneOf } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from './BaseController'; -import { ServiceError } from '@/exceptions'; -import { EchangeRateErrors } from '@/lib/ExchangeRate/types'; -import { ExchangeRateApplication } from '@/services/ExchangeRates/ExchangeRateApplication'; - -@Service() -export default class ExchangeRatesController extends BaseController { - @Inject() - private exchangeRatesApp: ExchangeRateApplication; - - /** - * Constructor method. - */ - router() { - const router = Router(); - - router.get( - '/latest', - [ - oneOf([ - query('to_currency').exists().isString().isISO4217(), - query('from_currency').exists().isString().isISO4217(), - ]), - ], - this.validationResult, - asyncMiddleware(this.latestExchangeRate.bind(this)), - this.handleServiceError - ); - return router; - } - - /** - * Retrieve exchange rates. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async latestExchangeRate( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const exchangeRateQuery = this.matchedQueryData(req); - - try { - const exchangeRate = await this.exchangeRatesApp.latest( - tenantId, - exchangeRateQuery - ); - return res.status(200).send(exchangeRate); - } catch (error) { - next(error); - } - } - - /** - * Handle service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceError( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (EchangeRateErrors.EX_RATE_INVALID_BASE_CURRENCY === error.errorType) { - return res.status(400).send({ - errors: [ - { - type: EchangeRateErrors.EX_RATE_INVALID_BASE_CURRENCY, - code: 100, - message: 'The given base currency is invalid.', - }, - ], - }); - } else if ( - EchangeRateErrors.EX_RATE_SERVICE_NOT_ALLOWED === error.errorType - ) { - return res.status(400).send({ - errors: [ - { - type: EchangeRateErrors.EX_RATE_SERVICE_NOT_ALLOWED, - code: 200, - message: 'The service is not allowed', - }, - ], - }); - } else if ( - EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED === error.errorType - ) { - return res.status(400).send({ - errors: [ - { - type: EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED, - code: 300, - message: 'The API key is required', - }, - ], - }); - } else if (EchangeRateErrors.EX_RATE_LIMIT_EXCEEDED === error.errorType) { - return res.status(400).send({ - errors: [ - { - type: EchangeRateErrors.EX_RATE_LIMIT_EXCEEDED, - code: 400, - message: 'The API rate limit has been exceeded', - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Expenses/Expenses.ts b/packages/server/src/api/controllers/Expenses/Expenses.ts deleted file mode 100644 index 29a633096..000000000 --- a/packages/server/src/api/controllers/Expenses/Expenses.ts +++ /dev/null @@ -1,466 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { check, param, query } from 'express-validator'; -import { Router, Request, Response, NextFunction } from 'express'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { - AbilitySubject, - ExpenseAction, - IExpenseCreateDTO, - IExpenseEditDTO, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ExpensesApplication } from '@/services/Expenses/ExpensesApplication'; - -@Service() -export class ExpensesController extends BaseController { - @Inject() - private expensesApplication: ExpensesApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Express router. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(ExpenseAction.Create, AbilitySubject.Expense), - [...this.expenseDTOSchema], - this.validationResult, - asyncMiddleware(this.newExpense.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:id/publish', - CheckPolicies(ExpenseAction.Edit, AbilitySubject.Expense), - [...this.expenseParamSchema], - this.validationResult, - asyncMiddleware(this.publishExpense.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:id', - CheckPolicies(ExpenseAction.Edit, AbilitySubject.Expense), - [...this.editExpenseDTOSchema, ...this.expenseParamSchema], - this.validationResult, - asyncMiddleware(this.editExpense.bind(this)), - this.catchServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(ExpenseAction.Delete, AbilitySubject.Expense), - [...this.expenseParamSchema], - this.validationResult, - asyncMiddleware(this.deleteExpense.bind(this)), - this.catchServiceErrors - ); - router.get( - '/', - CheckPolicies(ExpenseAction.View, AbilitySubject.Expense), - [...this.expensesListSchema], - this.validationResult, - asyncMiddleware(this.getExpensesList.bind(this)), - this.dynamicListService.handlerErrorsToResponse, - this.catchServiceErrors - ); - router.get( - '/:id', - CheckPolicies(ExpenseAction.View, AbilitySubject.Expense), - [this.expenseParamSchema], - this.validationResult, - asyncMiddleware(this.getExpense.bind(this)), - this.catchServiceErrors - ); - return router; - } - - /** - * Expense DTO schema. - */ - private get expenseDTOSchema() { - return [ - check('reference_no') - .optional({ nullable: true }) - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('payment_date').exists().isISO8601().toDate(), - check('payment_account_id') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('description') - .optional({ nullable: true }) - .isString() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('currency_code').optional().isString().isLength({ max: 3 }), - check('exchange_rate').optional({ nullable: true }).isNumeric().toFloat(), - check('publish').optional().isBoolean().toBoolean(), - check('payee_id').optional({ nullable: true }).isNumeric().toInt(), - - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('categories').exists().isArray({ min: 1 }), - check('categories.*.index') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('categories.*.expense_account_id') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('categories.*.amount') - .optional({ nullable: true }) - .isFloat({ max: DATATYPES_LENGTH.DECIMAL_13_3 }) // 13, 3 - .toFloat(), - check('categories.*.description') - .optional() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('categories.*.landed_cost').optional().isBoolean().toBoolean(), - check('categories.*.project_id') - .optional({ nullable: true }) - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - ]; - } - - /** - * Edit expense validation schema. - */ - get editExpenseDTOSchema() { - return [ - check('reference_no') - .optional({ nullable: true }) - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('payment_date').exists().isISO8601().toDate(), - check('payment_account_id') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('description') - .optional({ nullable: true }) - .isString() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('currency_code').optional().isString().isLength({ max: 3 }), - check('exchange_rate').optional({ nullable: true }).isNumeric().toFloat(), - check('publish').optional().isBoolean().toBoolean(), - check('payee_id').optional({ nullable: true }).isNumeric().toInt(), - - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('categories').exists().isArray({ min: 1 }), - check('categories.*.id').optional().isNumeric().toInt(), - check('categories.*.index') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('categories.*.expense_account_id') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('categories.*.amount') - .optional({ nullable: true }) - .isFloat({ max: DATATYPES_LENGTH.DECIMAL_13_3 }) // 13, 3 - .toFloat(), - check('categories.*.description') - .optional() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('categories.*.landed_cost').optional().isBoolean().toBoolean(), - check('categories.*.project_id') - .optional({ nullable: true }) - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - ]; - } - - /** - * Expense param validation schema. - */ - get expenseParamSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Expenses list validation schema. - */ - get expensesListSchema() { - return [ - query('view_slug').optional({ nullable: true }).isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Creates a new expense on - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async newExpense(req: Request, res: Response, next: NextFunction) { - const expenseDTO: IExpenseCreateDTO = this.matchedBodyData(req); - const { tenantId, user } = req; - - try { - const expense = await this.expensesApplication.createExpense( - tenantId, - expenseDTO, - user - ); - return res.status(200).send({ - id: expense.id, - message: 'The expense has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edits details of the given expense. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async editExpense(req: Request, res: Response, next: NextFunction) { - const { id: expenseId } = req.params; - const expenseDTO: IExpenseEditDTO = this.matchedBodyData(req); - const { tenantId, user } = req; - - try { - await this.expensesApplication.editExpense( - tenantId, - expenseId, - expenseDTO, - user - ); - return res.status(200).send({ - id: expenseId, - message: 'The expense has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given expense. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async deleteExpense(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: expenseId } = req.params; - - try { - await this.expensesApplication.deleteExpense(tenantId, expenseId, user); - - return res.status(200).send({ - id: expenseId, - message: 'The expense has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Publishs the given expense. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async publishExpense( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: expenseId } = req.params; - - try { - await this.expensesApplication.publishExpense(tenantId, expenseId, user); - - return res.status(200).send({ - id: expenseId, - message: 'The expense has been published successfully', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve expneses list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getExpensesList( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - - try { - const { expenses, pagination, filterMeta } = - await this.expensesApplication.getExpenses(tenantId, filter); - - return res.status(200).send({ - expenses: this.transfromToResponse(expenses), - pagination: this.transfromToResponse(pagination), - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve expense details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getExpense(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: expenseId } = req.params; - - try { - const expense = await this.expensesApplication.getExpense( - tenantId, - expenseId - ); - return res.status(200).send(this.transfromToResponse({ expense })); - } catch (error) { - next(error); - } - } - - /** - * Transform service errors to api response errors. - * @param {Response} res - * @param {ServiceError} error - */ - private catchServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'expense_not_found') { - return res.boom.badRequest('Expense not found.', { - errors: [{ type: 'EXPENSE_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'EXPENSES_NOT_FOUND') { - return res.boom.badRequest('Expenses not found.', { - errors: [{ type: 'EXPENSES_NOT_FOUND', code: 110 }], - }); - } - if (error.errorType === 'total_amount_equals_zero') { - return res.boom.badRequest('Expense total should not equal zero.', { - errors: [{ type: 'TOTAL.AMOUNT.EQUALS.ZERO', code: 200 }], - }); - } - if (error.errorType === 'payment_account_not_found') { - return res.boom.badRequest('Payment account not found.', { - errors: [{ type: 'PAYMENT.ACCOUNT.NOT.FOUND', code: 300 }], - }); - } - if (error.errorType === 'some_expenses_not_found') { - return res.boom.badRequest('Some expense accounts not found.', { - errors: [{ type: 'SOME.EXPENSE.ACCOUNTS.NOT.FOUND', code: 400 }], - }); - } - if (error.errorType === 'payment_account_has_invalid_type') { - return res.boom.badRequest('Payment account has invalid type.', { - errors: [{ type: 'PAYMENT.ACCOUNT.HAS.INVALID.TYPE', code: 500 }], - }); - } - if (error.errorType === 'expenses_account_has_invalid_type') { - return res.boom.badRequest(null, { - errors: [{ type: 'EXPENSES.ACCOUNT.HAS.INVALID.TYPE', code: 600 }], - }); - } - if (error.errorType === 'expense_already_published') { - return res.boom.badRequest(null, { - errors: [{ type: 'EXPENSE_ALREADY_PUBLISHED', code: 700 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CONTACT_NOT_FOUND', code: 800 }], - }); - } - if (error.errorType === 'EXPENSE_HAS_ASSOCIATED_LANDED_COST') { - return res.status(400).send({ - errors: [{ type: 'EXPENSE_HAS_ASSOCIATED_LANDED_COST', code: 900 }], - }); - } - if (error.errorType === 'ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED') { - return res.status(400).send({ - errors: [ - { type: 'ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED', code: 1000 }, - ], - }); - } - if ( - error.errorType === 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES' - ) { - return res.status(400).send({ - errors: [ - { - type: 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES', - code: 1100, - }, - ], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Expenses/index.ts b/packages/server/src/api/controllers/Expenses/index.ts deleted file mode 100644 index 11744dd28..000000000 --- a/packages/server/src/api/controllers/Expenses/index.ts +++ /dev/null @@ -1,15 +0,0 @@ - -import { Router } from 'express'; -import { Container, Service } from 'typedi'; -import { ExpensesController } from './Expenses'; - -@Service() -export default class ExpensesBaseController { - router() { - const router = Router(); - - router.use('/', Container.get(ExpensesController).router()); - - return router; - } -} diff --git a/packages/server/src/api/controllers/Export/ExportController.ts b/packages/server/src/api/controllers/Export/ExportController.ts deleted file mode 100644 index 7ba493453..000000000 --- a/packages/server/src/api/controllers/Export/ExportController.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { ServiceError } from '@/exceptions'; -import { ExportApplication } from '@/services/Export/ExportApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { convertAcceptFormatToFormat } from './_utils'; - -@Service() -export class ExportController extends BaseController { - @Inject() - private exportResourceApp: ExportApplication; - - /** - * Router constructor method. - */ - public router() { - const router = Router(); - - router.get( - '/', - [ - query('resource').exists(), - query('format').isIn(['csv', 'xlsx']).optional(), - ], - this.validationResult, - this.export.bind(this), - ); - return router; - } - - /** - * Imports xlsx/csv to the given resource type. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async export(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const query = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - const applicationFormat = convertAcceptFormatToFormat(acceptType); - - const data = await this.exportResourceApp.export( - tenantId, - query.resource, - applicationFormat - ); - // Retrieves the csv format. - if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(data); - // Retrieves the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(data); - // - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': data.length, - }); - res.send(data); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Export/_utils.ts b/packages/server/src/api/controllers/Export/_utils.ts deleted file mode 100644 index 30758c72e..000000000 --- a/packages/server/src/api/controllers/Export/_utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { ExportFormat } from '@/services/Export/common'; - -export const convertAcceptFormatToFormat = (accept: string): ExportFormat => { - switch (accept) { - case ACCEPT_TYPE.APPLICATION_CSV: - return ExportFormat.Csv; - case ACCEPT_TYPE.APPLICATION_PDF: - return ExportFormat.Pdf; - case ACCEPT_TYPE.APPLICATION_XLSX: - return ExportFormat.Xlsx; - } -}; diff --git a/packages/server/src/api/controllers/FinancialStatements.ts b/packages/server/src/api/controllers/FinancialStatements.ts deleted file mode 100644 index 15b7900f8..000000000 --- a/packages/server/src/api/controllers/FinancialStatements.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Router } from 'express'; -import { Container, Service } from 'typedi'; - -import BalanceSheetController from './FinancialStatements/BalanceSheet'; -import TrialBalanceSheetController from './FinancialStatements/TrialBalanceSheet'; -import GeneralLedgerController from './FinancialStatements/GeneralLedger'; -import JournalSheetController from './FinancialStatements/JournalSheet'; -import ProfitLossController from './FinancialStatements/ProfitLossSheet'; -import ARAgingSummary from './FinancialStatements/ARAgingSummary'; -import APAgingSummary from './FinancialStatements/APAgingSummary'; -import PurchasesByItemsController from './FinancialStatements/PurchasesByItem'; -import SalesByItemsController from './FinancialStatements/SalesByItems'; -import InventoryValuationController from './FinancialStatements/InventoryValuationSheet'; -import CustomerBalanceSummaryController from './FinancialStatements/CustomerBalanceSummary'; -import VendorBalanceSummaryController from './FinancialStatements/VendorBalanceSummary'; -import TransactionsByCustomers from './FinancialStatements/TransactionsByCustomers'; -import TransactionsByVendors from './FinancialStatements/TransactionsByVendors'; -import CashFlowStatementController from './FinancialStatements/CashFlow/CashFlow'; -import InventoryDetailsController from './FinancialStatements/InventoryDetails'; -import TransactionsByReferenceController from './FinancialStatements/TransactionsByReference'; -import CashflowAccountTransactions from './FinancialStatements/CashflowAccountTransactions'; -import ProjectProfitabilityController from './FinancialStatements/ProjectProfitabilitySummary'; -import SalesTaxLiabilitySummary from './FinancialStatements/SalesTaxLiabilitySummary'; - -@Service() -export default class FinancialStatementsService { - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.use( - '/balance_sheet', - Container.get(BalanceSheetController).router() - ); - router.use( - '/profit_loss_sheet', - Container.get(ProfitLossController).router() - ); - router.use( - '/general_ledger', - Container.get(GeneralLedgerController).router() - ); - router.use( - '/trial_balance_sheet', - Container.get(TrialBalanceSheetController).router() - ); - router.use('/journal', Container.get(JournalSheetController).router()); - router.use( - '/receivable_aging_summary', - Container.get(ARAgingSummary).router() - ); - router.use( - '/payable_aging_summary', - Container.get(APAgingSummary).router() - ); - router.use( - '/purchases-by-items', - Container.get(PurchasesByItemsController).router() - ); - router.use( - '/sales-by-items', - Container.get(SalesByItemsController).router() - ); - router.use( - '/inventory-valuation', - Container.get(InventoryValuationController).router() - ); - router.use( - '/customer-balance-summary', - Container.get(CustomerBalanceSummaryController).router() - ); - router.use( - '/vendor-balance-summary', - Container.get(VendorBalanceSummaryController).router() - ); - router.use( - '/transactions-by-customers', - Container.get(TransactionsByCustomers).router() - ); - router.use( - '/transactions-by-vendors', - Container.get(TransactionsByVendors).router() - ); - router.use( - '/cash-flow', - Container.get(CashFlowStatementController).router() - ); - router.use( - '/inventory-item-details', - Container.get(InventoryDetailsController).router() - ); - router.use( - '/transactions-by-reference', - Container.get(TransactionsByReferenceController).router() - ); - router.use( - '/cashflow-account-transactions', - Container.get(CashflowAccountTransactions).router() - ); - router.use( - '/project-profitability-summary', - Container.get(ProjectProfitabilityController).router() - ); - router.use( - '/sales-tax-liability-summary', - Container.get(SalesTaxLiabilitySummary).router() - ); - return router; - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts b/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts deleted file mode 100644 index d87873a2b..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import { Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { APAgingSummaryApplication } from '@/services/FinancialStatements/AgingSummary/APAgingSummaryApplication'; - -export default class APAgingSummaryReportController extends BaseFinancialReportController { - @Inject() - private APAgingSummaryApp: APAgingSummaryApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_AP_AGING_SUMMARY, AbilitySubject.Report), - this.validationSchema, - asyncMiddleware(this.payableAgingSummary.bind(this)) - ); - return router; - } - - /** - * Validation schema. - * @returns {ValidationChain[]} - */ - private get validationSchema() { - return [ - ...this.sheetNumberFormatValidationSchema, - query('as_date').optional().isISO8601(), - - query('aging_days_before').default(30).isInt({ max: 500 }).toInt(), - query('aging_periods').default(3).isInt({ max: 12 }).toInt(), - - query('vendors_ids').optional().isArray({ min: 1 }), - query('vendors_ids.*').isInt({ min: 1 }).toInt(), - - query('none_zero').default(true).isBoolean().toBoolean(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieves payable aging summary report. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async payableAgingSummary( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF - ]); - // Retrieves the json table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.APAgingSummaryApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const csv = await this.APAgingSummaryApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(csv); - // Retrieves the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.APAgingSummaryApp.xlsx(tenantId, filter); - - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.APAgingSummaryApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Retrieves the json format. - } else { - const sheet = await this.APAgingSummaryApp.sheet(tenantId, filter); - - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts b/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts deleted file mode 100644 index 86b4b920a..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response } from 'express'; -import { query } from 'express-validator'; -import ARAgingSummaryService from '@/services/FinancialStatements/AgingSummary/ARAgingSummaryService'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ARAgingSummaryApplication } from '@/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class ARAgingSummaryReportController extends BaseFinancialReportController { - @Inject() - private ARAgingSummaryApp: ARAgingSummaryApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_AR_AGING_SUMMARY, AbilitySubject.Report), - this.validationSchema, - this.validationResult, - this.asyncMiddleware(this.receivableAgingSummary.bind(this)) - ); - return router; - } - - /** - * AR aging summary validation roles. - */ - private get validationSchema() { - return [ - ...this.sheetNumberFormatValidationSchema, - - query('as_date').optional().isISO8601(), - - query('aging_days_before').default(30).isInt({ max: 500 }).toInt(), - query('aging_periods').default(3).isInt({ max: 12 }).toInt(), - - query('customers_ids').optional().isArray({ min: 1 }), - query('customers_ids.*').isInt({ min: 1 }).toInt(), - - query('none_zero').default(true).isBoolean().toBoolean(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve AR aging summary report. - * @param {Request} req - * @param {Response} res - */ - private async receivableAgingSummary(req: Request, res: Response) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF - ]); - // Retrieves the xlsx format. - if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.ARAgingSummaryApp.xlsx(tenantId, filter); - - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the table format. - } else if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.ARAgingSummaryApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.ARAgingSummaryApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.ARAgingSummaryApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Retrieves the json format. - } else { - const sheet = await this.ARAgingSummaryApp.sheet(tenantId, filter); - - return res.status(200).send(sheet); - } - } catch (error) { - console.log(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts b/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts deleted file mode 100644 index fda717a38..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import { castArray } from 'lodash'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { BalanceSheetApplication } from '@/services/FinancialStatements/BalanceSheet/BalanceSheetApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class BalanceSheetStatementController extends BaseFinancialReportController { - @Inject() - private balanceSheetApp: BalanceSheetApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_BALANCE_SHEET, AbilitySubject.Report), - this.balanceSheetValidationSchema, - this.validationResult, - asyncMiddleware(this.balanceSheet.bind(this)) - ); - return router; - } - - /** - * Balance sheet validation schecma. - * @returns {ValidationChain[]} - */ - private get balanceSheetValidationSchema(): ValidationChain[] { - return [ - ...this.sheetNumberFormatValidationSchema, - query('accounting_method').optional().isIn(['cash', 'accrual']), - - query('from_date').optional(), - query('to_date').optional(), - - query('display_columns_type').optional().isIn(['date_periods', 'total']), - query('display_columns_by') - .optional({ nullable: true, checkFalsy: true }) - .isIn(['year', 'month', 'week', 'day', 'quarter']), - - query('account_ids').isArray().optional(), - query('account_ids.*').isNumeric().toInt(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Percentage of column/row. - query('percentage_of_column').optional().isBoolean().toBoolean(), - query('percentage_of_row').optional().isBoolean().toBoolean(), - - // Camparsion periods periods. - query('previous_period').optional().isBoolean().toBoolean(), - query('previous_period_amount_change').optional().isBoolean().toBoolean(), - query('previous_period_percentage_change') - .optional() - .isBoolean() - .toBoolean(), - // Camparsion periods periods. - query('previous_year').optional().isBoolean().toBoolean(), - query('previous_year_amount_change').optional().isBoolean().toBoolean(), - query('previous_year_percentage_change') - .optional() - .isBoolean() - .toBoolean(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the balance sheet. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async balanceSheet(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - let filter = this.matchedQueryData(req); - - filter = { - ...filter, - accountsIds: castArray(filter.accountsIds), - }; - try { - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - // Retrieves the json table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE == acceptType) { - const table = await this.balanceSheetApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.balanceSheetApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.balanceSheetApp.xlsx(tenantId, filter); - - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.balanceSheetApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - res.send(pdfContent); - } else { - const sheet = await this.balanceSheetApp.sheet(tenantId, filter); - - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/BaseFinancialReportController.ts b/packages/server/src/api/controllers/FinancialStatements/BaseFinancialReportController.ts deleted file mode 100644 index 4437c4bf3..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/BaseFinancialReportController.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { query } from 'express-validator'; -import BaseController from '../BaseController'; - -export default class BaseFinancialReportController extends BaseController { - get sheetNumberFormatValidationSchema() { - return [ - query('number_format.precision') - .optional() - .isInt({ min: 0, max: 5 }) - .toInt(), - query('number_format.divide_on_1000').optional().isBoolean().toBoolean(), - query('number_format.show_zero').optional().isBoolean().toBoolean(), - query('number_format.format_money') - .optional() - .isIn(['total', 'always', 'none']) - .trim(), - query('number_format.negative_format') - .optional() - .isIn(['parentheses', 'mines']) - .trim(), - ]; - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts b/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts deleted file mode 100644 index bc24b5379..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { query } from 'express-validator'; -import { - NextFunction, - Router, - Request, - Response, - ValidationChain, -} from 'express'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { CashflowSheetApplication } from '@/services/FinancialStatements/CashFlow/CashflowSheetApplication'; - -@Service() -export default class CashFlowController extends BaseFinancialReportController { - @Inject() - private cashflowSheetApp: CashflowSheetApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_CASHFLOW, AbilitySubject.Report), - this.cashflowValidationSchema, - this.validationResult, - this.asyncMiddleware(this.cashFlow.bind(this)) - ); - return router; - } - - /** - * Balance sheet validation schecma. - * @returns {ValidationChain[]} - */ - private get cashflowValidationSchema(): ValidationChain[] { - return [ - ...this.sheetNumberFormatValidationSchema, - query('from_date').optional(), - query('to_date').optional(), - - query('display_columns_type').optional().isIn(['date_periods', 'total']), - query('display_columns_by') - .optional({ nullable: true, checkFalsy: true }) - .isIn(['year', 'month', 'week', 'day', 'quarter']), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the cash flow statment. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public async cashFlow(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = { - ...this.matchedQueryData(req), - }; - - try { - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF - ]); - // Retrieves the json table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.cashflowSheetApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.cashflowSheetApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.status(200).send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.cashflowSheetApp.xlsx(tenantId, filter); - - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.cashflowSheetApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Retrieves the json format. - } else { - const cashflow = await this.cashflowSheetApp.sheet(tenantId, filter); - - return res.status(200).send(cashflow); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/CashflowAccountTransactions/index.ts b/packages/server/src/api/controllers/FinancialStatements/CashflowAccountTransactions/index.ts deleted file mode 100644 index b65c450cf..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/CashflowAccountTransactions/index.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { query } from 'express-validator'; -import { - NextFunction, - Router, - Request, - Response, - ValidationChain, -} from 'express'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import { - AbilitySubject, - ICashFlowStatementDOO, - ReportsAction, -} from '@/interfaces'; -import CashFlowTable from '@/services/FinancialStatements/CashFlow/CashFlowTable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import CashflowAccountTransactionsService from '@/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsService'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; - -@Service() -export default class CashFlowAccountTransactionsController extends BaseFinancialReportController { - @Inject() - tenancy: HasTenancyService; - - @Inject() - cashflowAccountTransactions: CashflowAccountTransactionsService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_CASHFLOW_ACCOUNT_TRANSACTION, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - this.asyncMiddleware(this.cashFlow), - this.catchServiceErrors - ); - return router; - } - - /** - * Cashflow account transactions validation schecma. - * @returns {ValidationChain[]} - */ - get validationSchema(): ValidationChain[] { - return [ - query('account_id').exists().isInt().toInt(), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - ]; - } - - /** - * Retrieve the cashflow account transactions statment to json response. - * @param {ICashFlowStatement} cashFlow - - */ - private transformJsonResponse(casahflowAccountTransactions) { - const { transactions, pagination } = casahflowAccountTransactions; - - return { - transactions: this.transfromToResponse(transactions), - pagination: this.transfromToResponse(pagination), - }; - } - - /** - * Transformes the report statement to table rows. - * @param {ITransactionsByVendorsStatement} statement - - */ - private transformToTableRows( - cashFlowDOO: ICashFlowStatementDOO, - tenantId: number - ) { - const i18n = this.tenancy.i18n(tenantId); - const cashFlowTable = new CashFlowTable(cashFlowDOO, i18n); - - return { - table: { - data: cashFlowTable.tableRows(), - columns: cashFlowTable.tableColumns(), - }, - query: this.transfromToResponse(cashFlowDOO.query), - meta: this.transfromToResponse(cashFlowDOO.meta), - }; - } - - /** - * Retrieve the cash flow statment. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private cashFlow = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const query = this.matchedQueryData(req); - - try { - const cashFlowAccountTransactions = - await this.cashflowAccountTransactions.cashflowAccountTransactions( - tenantId, - query - ); - - const accept = this.accepts(req); - const acceptType = accept.types(['json', 'application/json+table']); - - switch (acceptType) { - // case 'application/json+table': - // return res - // .status(200) - // .send(this.transformToTableRows(cashFlow, tenantId)); - case 'json': - default: - return res - .status(200) - .send(this.transformJsonResponse(cashFlowAccountTransactions)); - } - } catch (error) { - next(error); - } - }; - - /** - * Catches the service errors. - * @param {Error} error - Error. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @param {NextFunction} next - - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'ACCOUNT_ID_HAS_INVALID_TYPE') { - return res.boom.badRequest( - 'The given account id should be cash, bank or credit card type.', - { - errors: [{ type: 'ACCOUNT_ID_HAS_INVALID_TYPE', code: 200 }], - } - ); - } - if (error.errorType === 'account_not_found') { - return res.boom.notFound('The given account not found.', { - errors: [{ type: 'ACCOUNT.NOT.FOUND', code: 100 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/CustomerBalanceSummary/index.ts b/packages/server/src/api/controllers/FinancialStatements/CustomerBalanceSummary/index.ts deleted file mode 100644 index e69fcdc1c..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/CustomerBalanceSummary/index.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import { Inject } from 'typedi'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { CustomerBalanceSummaryApplication } from '@/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication'; - -export default class CustomerBalanceSummaryReportController extends BaseFinancialReportController { - @Inject() - private customerBalanceSummaryApp: CustomerBalanceSummaryApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_CUSTOMERS_SUMMARY_BALANCE, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.customerBalanceSummary.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - private get validationSchema() { - return [ - ...this.sheetNumberFormatValidationSchema, - - // As date. - query('as_date').optional().isISO8601(), - - // Percentages. - query('percentage_column').optional().isBoolean().toBoolean(), - - // Filters none-zero or none-transactions. - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Customers ids. - query('customers_ids').optional().isArray({ min: 1 }), - query('customers_ids.*').exists().isInt().toInt(), - ]; - } - - /** - * Retrieve payable aging summary report. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async customerBalanceSummary( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - - // Retrieves the xlsx format. - if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.customerBalanceSummaryApp.xlsx( - tenantId, - filter - ); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.customerBalanceSummaryApp.csv( - tenantId, - filter - ); - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the json table format. - } else if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.customerBalanceSummaryApp.table( - tenantId, - filter - ); - return res.status(200).send(table); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const buffer = await this.customerBalanceSummaryApp.pdf( - tenantId, - filter - ); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': buffer.length, - }); - return res.send(buffer); - // Retrieves the json format. - } else { - const sheet = await this.customerBalanceSummaryApp.sheet( - tenantId, - filter - ); - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/GeneralLedger.ts b/packages/server/src/api/controllers/FinancialStatements/GeneralLedger.ts deleted file mode 100644 index 188178a01..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/GeneralLedger.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { GeneralLedgerApplication } from '@/services/FinancialStatements/GeneralLedger/GeneralLedgerApplication'; - -@Service() -export default class GeneralLedgerReportController extends BaseFinancialReportController { - @Inject() - private generalLedgerApplication: GeneralLedgerApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_GENERAL_LEDGET, AbilitySubject.Report), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.generalLedger.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - private get validationSchema(): ValidationChain[] { - return [ - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - - query('basis').optional(), - - query('number_format.no_cents').optional().isBoolean().toBoolean(), - query('number_format.divide_1000').optional().isBoolean().toBoolean(), - - query('none_transactions').default(true).isBoolean().toBoolean(), - - query('accounts_ids').optional().isArray({ min: 1 }), - query('accounts_ids.*').isInt().toInt(), - - query('orderBy').optional().isIn(['created_at', 'name', 'code']), - query('order').optional().isIn(['desc', 'asc']), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the general ledger financial statement. - * @param {Request} req - - * @param {Response} res - - */ - private async generalLedger(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - // Retrieves the table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.generalLedgerApplication.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.generalLedgerApplication.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.generalLedgerApplication.xlsx(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.xlsx'); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.generalLedgerApplication.pdf( - tenantId, - filter - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Retrieves the json format. - } else { - const sheet = await this.generalLedgerApplication.sheet(tenantId, filter); - return res.status(200).send(sheet); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/InventoryDetails/index.ts b/packages/server/src/api/controllers/FinancialStatements/InventoryDetails/index.ts deleted file mode 100644 index 580be59b1..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/InventoryDetails/index.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { query } from 'express-validator'; -import { - NextFunction, - Router, - Request, - Response, - ValidationChain, -} from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import { InventortyDetailsApplication } from '@/services/FinancialStatements/InventoryDetails/InventoryDetailsApplication'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class InventoryDetailsController extends BaseController { - @Inject() - private inventoryItemDetailsApp: InventortyDetailsApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_INVENTORY_ITEM_DETAILS, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - this.asyncMiddleware(this.inventoryDetails.bind(this)) - ); - return router; - } - - /** - * Balance sheet validation schecma. - * @returns {ValidationChain[]} - */ - private get validationSchema(): ValidationChain[] { - return [ - query('number_format.precision') - .optional() - .isInt({ min: 0, max: 5 }) - .toInt(), - query('number_format.divide_on_1000').optional().isBoolean().toBoolean(), - query('number_format.negative_format') - .optional() - .isIn(['parentheses', 'mines']) - .trim(), - query('from_date').optional(), - query('to_date').optional(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - query('items_ids').optional().isArray(), - query('items_ids.*').optional().isInt().toInt(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - - // Filtering by warehouses. - query('warehouses_ids').optional().toArray().isArray({ min: 1 }), - query('warehouses_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the inventory item details sheet. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private async inventoryDetails( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - ...this.matchedQueryData(req), - }; - - try { - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - // Retrieves the csv format. - if (acceptType === ACCEPT_TYPE.APPLICATION_CSV) { - const buffer = await this.inventoryItemDetailsApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the xlsx format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_XLSX) { - const buffer = await this.inventoryItemDetailsApp.xlsx( - tenantId, - filter - ); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the json table format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_JSON_TABLE) { - const table = await this.inventoryItemDetailsApp.table( - tenantId, - filter - ); - return res.status(200).send(table); - // Retrieves the pdf format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { - const buffer = await this.inventoryItemDetailsApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': buffer.length, - }); - return res.send(buffer); - } else { - const sheet = await this.inventoryItemDetailsApp.sheet( - tenantId, - filter - ); - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/InventoryValuationSheet.ts b/packages/server/src/api/controllers/FinancialStatements/InventoryValuationSheet.ts deleted file mode 100644 index b31a911a2..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/InventoryValuationSheet.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { InventoryValuationSheetApplication } from '@/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class InventoryValuationReportController extends BaseFinancialReportController { - @Inject() - private inventoryValuationApp: InventoryValuationSheetApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_INVENTORY_VALUATION_SUMMARY, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.inventoryValuation.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - get validationSchema(): ValidationChain[] { - return [ - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - - query('items_ids').optional().isArray(), - query('items_ids.*').optional().isInt().toInt(), - - query('number_format.no_cents').optional().isBoolean().toBoolean(), - query('number_format.divide_1000').optional().isBoolean().toBoolean(), - - query('none_transactions').default(true).isBoolean().toBoolean(), - query('none_zero').default(false).isBoolean().toBoolean(), - query('only_active').default(false).isBoolean().toBoolean(), - - query('orderBy').optional().isIn(['created_at', 'name', 'code']), - query('order').optional().isIn(['desc', 'asc']), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - - // Filtering by warehouses. - query('warehouses_ids').optional().toArray().isArray({ min: 1 }), - query('warehouses_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the general ledger financial statement. - * @param {Request} req - - * @param {Response} res - - */ - async inventoryValuation(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - - // Retrieves the json table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.inventoryValuationApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV == acceptType) { - const buffer = await this.inventoryValuationApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the xslx buffer format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.inventoryValuationApp.xlsx(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.xlsx'); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.inventoryValuationApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.status(200).send(pdfContent); - // Retrieves the json format. - } else { - const { data, query, meta } = await this.inventoryValuationApp.sheet( - tenantId, - filter - ); - return res.status(200).send({ meta, data, query }); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts b/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts deleted file mode 100644 index b06d37449..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { castArray } from 'lodash'; -import { query, oneOf } from 'express-validator'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { JournalSheetApplication } from '@/services/FinancialStatements/JournalSheet/JournalSheetApplication'; - -@Service() -export default class JournalSheetController extends BaseFinancialReportController { - @Inject() - private journalSheetApp: JournalSheetApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_JOURNAL, AbilitySubject.Report), - this.journalValidationSchema, - this.validationResult, - this.asyncMiddleware(this.journal.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - get journalValidationSchema() { - return [ - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - query('transaction_type').optional().trim(), - query('transaction_id').optional().isInt().toInt(), - oneOf( - [ - query('account_ids').optional().isArray({ min: 1 }), - query('account_ids.*').optional().isNumeric().toInt(), - ], - [query('account_ids').optional().isNumeric().toInt()] - ), - query('from_range').optional().isNumeric().toInt(), - query('to_range').optional().isNumeric().toInt(), - - query('number_format.no_cents').optional().isBoolean().toBoolean(), - query('number_format.divide_1000').optional().isBoolean().toBoolean(), - ]; - } - - /** - * Retrieve the ledger report of the given account. - * @param {Request} req - - * @param {Response} res - - */ - private async journal(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - let filter = this.matchedQueryData(req); - - filter = { - ...filter, - accountsIds: castArray(filter.accountsIds), - }; - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - - // Retrieves the json table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.journalSheetApp.table(tenantId, filter); - return res.status(200).send(table); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.journalSheetApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.journalSheetApp.xlsx(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.xlsx'); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the json format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.journalSheetApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - res.send(pdfContent); - } else { - const sheet = await this.journalSheetApp.sheet(tenantId, filter); - - return res.status(200).send(sheet); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts b/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts deleted file mode 100644 index 995df07b4..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { ProfitLossSheetApplication } from '@/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication'; -@Service() -export default class ProfitLossSheetController extends BaseFinancialReportController { - @Inject() - private profitLossSheetApp: ProfitLossSheetApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_PROFIT_LOSS, AbilitySubject.Report), - this.validationSchema, - this.validationResult, - this.asyncMiddleware(this.profitLossSheet.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - private get validationSchema(): ValidationChain[] { - return [ - ...this.sheetNumberFormatValidationSchema, - query('basis').optional(), - - query('from_date').optional().isISO8601().toDate(), - query('to_date').optional().isISO8601().toDate(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - query('accounts_ids').isArray().optional(), - query('accounts_ids.*').isNumeric().toInt(), - - query('display_columns_type').optional().isIn(['total', 'date_periods']), - query('display_columns_by') - .optional({ nullable: true, checkFalsy: true }) - .isIn(['year', 'month', 'week', 'day', 'quarter']), - - // Percentage options. - query('percentage_column').optional().isBoolean().toBoolean(), - query('percentage_row').optional().isBoolean().toBoolean(), - query('percentage_expense').optional().isBoolean().toBoolean(), - query('percentage_income').optional().isBoolean().toBoolean(), - - // Camparsion periods periods. - query('previous_period').optional().isBoolean().toBoolean(), - query('previous_period_amount_change').optional().isBoolean().toBoolean(), - query('previous_period_percentage_change') - .optional() - .isBoolean() - .toBoolean(), - // Camparsion periods periods. - query('previous_year').optional().isBoolean().toBoolean(), - query('previous_year_amount_change').optional().isBoolean().toBoolean(), - query('previous_year_percentage_change') - .optional() - .isBoolean() - .toBoolean(), - - // Filtering by branches. - query('branches_ids').optional().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve profit/loss financial statement. - * @param {Request} req - - * @param {Response} res - - */ - private async profitLossSheet( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - try { - // Retrieves the csv format. - if (acceptType === ACCEPT_TYPE.APPLICATION_CSV) { - const sheet = await this.profitLossSheetApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(sheet); - // Retrieves the json table format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_JSON_TABLE) { - const table = await this.profitLossSheetApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the xlsx format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_XLSX) { - const sheet = await this.profitLossSheetApp.xlsx(tenantId, filter); - - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(sheet); - // Retrieves the json format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { - const pdfContent = await this.profitLossSheetApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - } else { - const sheet = await this.profitLossSheetApp.sheet(tenantId, filter); - - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/ProjectProfitabilitySummary/index.ts b/packages/server/src/api/controllers/FinancialStatements/ProjectProfitabilitySummary/index.ts deleted file mode 100644 index 26795fc9a..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/ProjectProfitabilitySummary/index.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { query } from 'express-validator'; -import { - NextFunction, - Router, - Request, - Response, - ValidationChain, -} from 'express'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import { - ICashFlowStatementDOO, - AbilitySubject, - ReportsAction, - IProjectProfitabilitySummaryPOJO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ProjectProfitabilitySummaryTable } from '@/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryTable'; -import { ProjectProfitabilitySummaryService } from '@/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryService'; - -@Service() -export default class ProjectProfitabilityController extends BaseFinancialReportController { - @Inject() - private projectProfitabilityService: ProjectProfitabilitySummaryService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_PROJECT_PROFITABILITY_SUMMARY, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - this.asyncMiddleware(this.projectProfitabilitySummary.bind(this)) - ); - return router; - } - - /** - * Balance sheet validation schecma. - * @returns {ValidationChain[]} - */ - get validationSchema(): ValidationChain[] { - return [ - ...this.sheetNumberFormatValidationSchema, - query('from_date').optional(), - query('to_date').optional(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Filtering by projects. - query('products_ids').optional().toArray().isArray({ min: 1 }), - query('products_ids.*').isNumeric().toInt(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the cashflow statment to json response. - * @param {ICashFlowStatement} cashFlow - - */ - private transformJsonResponse(projectProfitabilityPOJO: IProjectProfitabilitySummaryPOJO) { - const { data, query, meta } = projectProfitabilityPOJO; - - return { - data: this.transfromToResponse(data), - query: this.transfromToResponse(query), - meta: this.transfromToResponse(meta), - }; - } - - /** - * Transformes the report statement to table rows. - * @param {ITransactionsByVendorsStatement} statement - - */ - private transformToTableRows( - projectProfitabilityPOJO: IProjectProfitabilitySummaryPOJO, - tenantId: number - ) { - const i18n = this.tenancy.i18n(tenantId); - const projectProfitabilityTable = new ProjectProfitabilitySummaryTable( - projectProfitabilityPOJO.data, - i18n - ); - - return { - table: { - data: projectProfitabilityTable.tableData(), - columns: projectProfitabilityTable.tableColumns(), - }, - query: this.transfromToResponse(projectProfitabilityPOJO.query), - // meta: this.transfromToResponse(cashFlowDOO.meta), - }; - } - - /** - * Retrieve the cash flow statment. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - async projectProfitabilitySummary( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - ...this.matchedQueryData(req), - }; - - try { - const projectProfitability = - await this.projectProfitabilityService.projectProfitabilitySummary( - tenantId, - filter - ); - const accept = this.accepts(req); - const acceptType = accept.types(['json', 'application/json+table']); - - switch (acceptType) { - case 'application/json+table': - return res - .status(200) - .send(this.transformToTableRows(projectProfitability, tenantId)); - case 'json': - default: - return res - .status(200) - .send(this.transformJsonResponse(projectProfitability)); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/PurchasesByItem.ts b/packages/server/src/api/controllers/FinancialStatements/PurchasesByItem.ts deleted file mode 100644 index 2c92bdc97..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/PurchasesByItem.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { PurchasesByItemsService } from '@/services/FinancialStatements/PurchasesByItems/PurchasesByItemsService'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { PurcahsesByItemsApplication } from '@/services/FinancialStatements/PurchasesByItems/PurchasesByItemsApplication'; - -@Service() -export default class PurchasesByItemReportController extends BaseFinancialReportController { - @Inject() - private purchasesByItemsApp: PurcahsesByItemsApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_PURCHASES_BY_ITEMS, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.purchasesByItems.bind(this)) - ); - return router; - } - - /** - * Validation schema. - * @return {ValidationChain[]} - */ - get validationSchema(): ValidationChain[] { - return [ - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - - // Filter items. - query('number_format.no_cents').optional().isBoolean().toBoolean(), - query('number_format.divide_1000').optional().isBoolean().toBoolean(), - - // Filters items. - query('none_transactions').optional().isBoolean().toBoolean(), - query('only_active').optional().isBoolean().toBoolean(), - - // Specific items. - query('items_ids').optional().isArray(), - query('items_ids.*').optional().isInt().toInt(), - - query('orderBy').optional().isIn(['created_at', 'name', 'code']), - query('order').optional().isIn(['desc', 'asc']), - ]; - } - - /** - * Retrieve the general ledger financial statement. - * @param {Request} req - - * @param {Response} res - - */ - public async purchasesByItems(req: Request, res: Response) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - // JSON table response format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.purchasesByItemsApp.table(tenantId, filter); - - return res.status(200).send(table); - // CSV response format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.purchasesByItemsApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Xlsx response format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.purchasesByItemsApp.xlsx(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.xlsx'); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // PDF response format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.purchasesByItemsApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Json response format. - } else { - const sheet = await this.purchasesByItemsApp.sheet(tenantId, filter); - - return res.status(200).send(sheet); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts b/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts deleted file mode 100644 index 28ab611c0..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain, ValidationSchema } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { SalesByItemsApplication } from '@/services/FinancialStatements/SalesByItems/SalesByItemsApplication'; - -@Service() -export default class SalesByItemsReportController extends BaseFinancialReportController { - @Inject() - private salesByItemsApp: SalesByItemsApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ReportsAction.READ_SALES_BY_ITEMS, AbilitySubject.Report), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.salesByItems.bind(this)) - ); - return router; - } - - /** - * Validation schema. - * @returns {ValidationChain[]} - */ - private get validationSchema(): ValidationChain[] { - return [ - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - - // Specific items. - query('items_ids').optional().isArray(), - query('items_ids.*').optional().isInt().toInt(), - - // Number format. - query('number_format.no_cents').optional().isBoolean().toBoolean(), - query('number_format.divide_1000').optional().isBoolean().toBoolean(), - - // Filters items. - query('none_transactions').default(true).isBoolean().toBoolean(), - query('only_active').default(false).isBoolean().toBoolean(), - - // Order by. - query('orderBy').optional().isIn(['created_at', 'name', 'code']), - query('order').optional().isIn(['desc', 'asc']), - ]; - } - - /** - * Retrieve the general ledger financial statement. - * @param {Request} req - - * @param {Response} res - - */ - private async salesByItems(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - // Retrieves the csv format. - if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.salesByItemsApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the json table format. - } else if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.salesByItemsApp.table(tenantId, filter); - - return res.status(200).send(table); - // Retrieves the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = this.salesByItemsApp.xlsx(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.xlsx'); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the json format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.salesByItemsApp.pdf(tenantId, filter); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - } else { - const sheet = await this.salesByItemsApp.sheet(tenantId, filter); - return res.status(200).send(sheet); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts b/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts deleted file mode 100644 index 42a96aab2..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { SalesTaxLiabilitySummaryApplication } from '@/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -export default class SalesTaxLiabilitySummary extends BaseFinancialReportController { - @Inject() - private salesTaxLiabilitySummaryApp: SalesTaxLiabilitySummaryApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_SALES_TAX_LIABILITY_SUMMARY, - AbilitySubject.Report - ), - this.validationSchema, - asyncMiddleware(this.salesTaxLiabilitySummary.bind(this)) - ); - return router; - } - - /** - * Validation schema. - * @returns {ValidationChain[]} - */ - private get validationSchema() { - return [ - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - ]; - } - - /* - * Retrieves the sales tax liability summary. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async salesTaxLiabilitySummary( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - - // Retrieves the json table format. - if (acceptType === ACCEPT_TYPE.APPLICATION_JSON_TABLE) { - const table = await this.salesTaxLiabilitySummaryApp.table( - tenantId, - filter - ); - return res.status(200).send(table); - // Retrieves the xlsx format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_XLSX) { - const buffer = await this.salesTaxLiabilitySummaryApp.xlsx( - tenantId, - filter - ); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves the csv format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_CSV) { - const buffer = await this.salesTaxLiabilitySummaryApp.csv( - tenantId, - filter - ); - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves the json format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { - const pdfContent = await this.salesTaxLiabilitySummaryApp.pdf( - tenantId, - filter - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.status(200).send(pdfContent); - } else { - const sheet = await this.salesTaxLiabilitySummaryApp.sheet( - tenantId, - filter - ); - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/TransactionsByCustomers/index.ts b/packages/server/src/api/controllers/FinancialStatements/TransactionsByCustomers/index.ts deleted file mode 100644 index c10eeea16..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/TransactionsByCustomers/index.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { TransactionsByCustomerApplication } from '@/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class TransactionsByCustomersReportController extends BaseFinancialReportController { - @Inject() - private transactionsByCustomersApp: TransactionsByCustomerApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_CUSTOMERS_TRANSACTIONS, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.transactionsByCustomers.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - private get validationSchema() { - return [ - ...this.sheetNumberFormatValidationSchema, - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Customers ids. - query('customers_ids').optional().isArray({ min: 1 }), - query('customers_ids.*').exists().isInt().toInt(), - ]; - } - - /** - * Retrieve payable aging summary report. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async transactionsByCustomers( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - try { - // Retrieves the json table format. - if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.transactionsByCustomersApp.table( - tenantId, - filter - ); - return res.status(200).send(table); - // Retrieve the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const csv = await this.transactionsByCustomersApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(csv); - // Retrieve the xlsx format. - } else if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.transactionsByCustomersApp.xlsx( - tenantId, - filter - ); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieve the json format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.transactionsByCustomersApp.pdf( - tenantId, - filter - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - } else { - const sheet = await this.transactionsByCustomersApp.sheet( - tenantId, - filter - ); - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/TransactionsByReference/index.ts b/packages/server/src/api/controllers/FinancialStatements/TransactionsByReference/index.ts deleted file mode 100644 index db679253c..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/TransactionsByReference/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import TransactionsByReferenceService from '@/services/FinancialStatements/TransactionsByReference'; -import { ITransactionsByReferenceTransaction } from '@/interfaces'; -@Service() -export default class TransactionsByReferenceController extends BaseController { - @Inject() - private transactionsByReferenceService: TransactionsByReferenceService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - this.validationSchema, - this.validationResult, - this.asyncMiddleware(this.transactionsByReference.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - get validationSchema(): ValidationChain[] { - return [ - query('reference_id').exists().isInt(), - query('reference_type').exists().isString(), - - query('number_format.precision') - .optional() - .isInt({ min: 0, max: 5 }) - .toInt(), - query('number_format.divide_on_1000').optional().isBoolean().toBoolean(), - query('number_format.negative_format') - .optional() - .isIn(['parentheses', 'mines']) - .trim(), - ]; - } - - /** - * Retrieve transactions by the given reference type and id. - * @param {Request} req - Request object. - * @param {Response} res - Response. - * @param {NextFunction} next - * @returns - */ - public async transactionsByReference( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const data = - await this.transactionsByReferenceService.getTransactionsByReference( - tenantId, - filter - ); - - return res - .status(200) - .send(this.transformToJsonResponse(data.transactions)); - } catch (error) { - next(error); - } - } - - /** - * Transformes the given report transaction to json response. - * @param transactions - * @returns - */ - private transformToJsonResponse( - transactions: ITransactionsByReferenceTransaction[] - ) { - return { - transactions: this.transfromToResponse(transactions), - }; - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/TransactionsByVendors/index.ts b/packages/server/src/api/controllers/FinancialStatements/TransactionsByVendors/index.ts deleted file mode 100644 index c437892f4..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/TransactionsByVendors/index.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import { Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { TransactionsByVendorApplication } from '@/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorApplication'; - -export default class TransactionsByVendorsReportController extends BaseFinancialReportController { - @Inject() - private transactionsByVendorsApp: TransactionsByVendorApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_VENDORS_TRANSACTIONS, - AbilitySubject.Report - ), - this.validationSchema, - this.validationResult, - asyncMiddleware(this.transactionsByVendors.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - private get validationSchema(): ValidationChain[] { - return [ - ...this.sheetNumberFormatValidationSchema, - - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Vendors ids. - query('vendors_ids').optional().isArray({ min: 1 }), - query('vendors_ids.*').exists().isInt().toInt(), - ]; - } - - /** - * Retrieve payable aging summary report. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async transactionsByVendors( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - - // Retrieves the xlsx format. - if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { - const buffer = await this.transactionsByVendorsApp.xlsx( - tenantId, - filter - ); - res.setHeader('Content-Type', 'application/vnd.openxmlformats'); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=report.xlsx' - ); - return res.send(buffer); - // Retrieves the csv format. - } else if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { - const buffer = await this.transactionsByVendorsApp.csv( - tenantId, - filter - ); - res.setHeader('Content-Type', 'text/csv'); - res.setHeader('Content-Disposition', 'attachment; filename=report.csv'); - return res.send(buffer); - // Retrieves the json table format. - } else if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { - const table = await this.transactionsByVendorsApp.table( - tenantId, - filter - ); - return res.status(200).send(table); - // Retrieves the pdf format. - } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const pdfContent = await this.transactionsByVendorsApp.pdf( - tenantId, - filter - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Retrieves the json format. - } else { - const sheet = await this.transactionsByVendorsApp.sheet( - tenantId, - filter - ); - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts b/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts deleted file mode 100644 index b92e355a2..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { query, ValidationChain } from 'express-validator'; -import { castArray } from 'lodash'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from './BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { TrialBalanceSheetApplication } from '@/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class TrialBalanceSheetController extends BaseFinancialReportController { - @Inject() - private trialBalanceSheetApp: TrialBalanceSheetApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_TRIAL_BALANCE_SHEET, - AbilitySubject.Report - ), - this.trialBalanceSheetValidationSchema, - this.validationResult, - asyncMiddleware(this.trialBalanceSheet.bind(this)) - ); - return router; - } - - /** - * Validation schema. - * @return {ValidationChain[]} - */ - private get trialBalanceSheetValidationSchema(): ValidationChain[] { - return [ - ...this.sheetNumberFormatValidationSchema, - query('basis').optional(), - query('from_date').optional().isISO8601(), - query('to_date').optional().isISO8601(), - query('account_ids').isArray().optional(), - query('account_ids.*').isNumeric().toInt(), - query('basis').optional(), - - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - query('only_active').optional().isBoolean().toBoolean(), - - // Filtering by branches. - query('branches_ids').optional().toArray().isArray({ min: 1 }), - query('branches_ids.*').isNumeric().toInt(), - ]; - } - - /** - * Retrieve the trial balance sheet. - */ - private async trialBalanceSheet( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - let filter = this.matchedQueryData(req); - - filter = { - ...filter, - accountsIds: castArray(filter.accountsIds), - }; - try { - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - // Retrieves in json table format. - if (acceptType === ACCEPT_TYPE.APPLICATION_JSON_TABLE) { - const { table, meta, query } = await this.trialBalanceSheetApp.table( - tenantId, - filter - ); - return res.status(200).send({ table, meta, query }); - // Retrieves in xlsx format - } else if (acceptType === ACCEPT_TYPE.APPLICATION_XLSX) { - const buffer = await this.trialBalanceSheetApp.xlsx(tenantId, filter); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader( - 'Content-Type', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ); - return res.send(buffer); - // Retrieves in csv format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_CSV) { - const buffer = await this.trialBalanceSheetApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - // Retrieves in pdf format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { - const pdfContent = await this.trialBalanceSheetApp.pdf( - tenantId, - filter - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - res.send(pdfContent); - // Retrieves in json format. - } else { - const { data, query, meta } = await this.trialBalanceSheetApp.sheet( - tenantId, - filter - ); - return res.status(200).send({ data, query, meta }); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts b/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts deleted file mode 100644 index f1e26a0ed..000000000 --- a/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import { Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseFinancialReportController from '../BaseFinancialReportController'; -import { AbilitySubject, ReportsAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { VendorBalanceSummaryApplication } from '@/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication'; - -export default class VendorBalanceSummaryReportController extends BaseFinancialReportController { - @Inject() - private vendorBalanceSummaryApp: VendorBalanceSummaryApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get( - '/', - CheckPolicies( - ReportsAction.READ_VENDORS_SUMMARY_BALANCE, - AbilitySubject.Report - ), - this.validationSchema, - asyncMiddleware(this.vendorBalanceSummary.bind(this)) - ); - return router; - } - - /** - * Validation schema. - */ - private get validationSchema() { - return [ - ...this.sheetNumberFormatValidationSchema, - query('as_date').optional().isISO8601(), - - // Percentage columns. - query('percentage_column').optional().isBoolean().toBoolean(), - - // Filters none-zero or none-transactions. - query('none_zero').optional().isBoolean().toBoolean(), - query('none_transactions').optional().isBoolean().toBoolean(), - - // Vendors ids. - query('vendors_ids').optional().isArray({ min: 1 }), - query('vendors_ids.*').exists().isInt().toInt(), - ]; - } - - /** - * Retrieve vendors balance summary. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - public async vendorBalanceSummary( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = this.matchedQueryData(req); - - try { - const accept = this.accepts(req); - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_JSON_TABLE, - ACCEPT_TYPE.APPLICATION_CSV, - ACCEPT_TYPE.APPLICATION_XLSX, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - - // Retrieves the csv format. - if (acceptType === ACCEPT_TYPE.APPLICATION_CSV) { - const buffer = await this.vendorBalanceSummaryApp.csv(tenantId, filter); - - res.setHeader('Content-Disposition', 'attachment; filename=output.csv'); - res.setHeader('Content-Type', 'text/csv'); - - return res.send(buffer); - } else if (acceptType === ACCEPT_TYPE.APPLICATION_XLSX) { - const buffer = await this.vendorBalanceSummaryApp.xlsx( - tenantId, - filter - ); - res.setHeader( - 'Content-Disposition', - 'attachment; filename=output.xlsx' - ); - res.setHeader('Content-Type', 'application/vnd.openxmlformats'); - return res.send(buffer); - // Retrieves the json table format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_JSON_TABLE) { - const table = await this.vendorBalanceSummaryApp.table( - tenantId, - filter - ); - return res.status(200).send(table); - // Retrieves the pdf format. - } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { - const pdfContent = await this.vendorBalanceSummaryApp.pdf( - tenantId, - filter - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - }); - return res.send(pdfContent); - // Retrieves the json format. - } else { - const sheet = await this.vendorBalanceSummaryApp.sheet( - tenantId, - filter - ); - return res.status(200).send(sheet); - } - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Import/ImportController.ts b/packages/server/src/api/controllers/Import/ImportController.ts deleted file mode 100644 index 17b60bc95..000000000 --- a/packages/server/src/api/controllers/Import/ImportController.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { body, param, query } from 'express-validator'; -import { defaultTo } from 'lodash'; -import BaseController from '@/api/controllers/BaseController'; -import { ServiceError } from '@/exceptions'; -import { ImportResourceApplication } from '@/services/Import/ImportResourceApplication'; -import { uploadImportFile } from './_utils'; -import { parseJsonSafe } from '@/utils/parse-json-safe'; - -@Service() -export class ImportController extends BaseController { - @Inject() - private importResourceApp: ImportResourceApplication; - - /** - * Router constructor method. - */ - public router() { - const router = Router(); - - router.post( - '/file', - uploadImportFile.single('file'), - this.importValidationSchema, - this.validationResult, - this.asyncMiddleware(this.fileUpload.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:import_id/import', - this.asyncMiddleware(this.import.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:import_id/mapping', - [ - param('import_id').exists().isString(), - body('mapping').exists().isArray({ min: 1 }), - body('mapping.*.group').optional(), - body('mapping.*.from').exists(), - body('mapping.*.to').exists(), - ], - this.validationResult, - this.asyncMiddleware(this.mapping.bind(this)), - this.catchServiceErrors - ); - router.get( - '/sample', - [query('resource').exists(), query('format').optional()], - this.validationResult, - this.downloadImportSample.bind(this), - this.catchServiceErrors - ); - router.get( - '/:import_id', - this.asyncMiddleware(this.getImportFileMeta.bind(this)), - this.catchServiceErrors - ); - router.get( - '/:import_id/preview', - this.asyncMiddleware(this.preview.bind(this)), - this.catchServiceErrors - ); - return router; - } - - /** - * Import validation schema. - * @returns {ValidationSchema[]} - */ - private get importValidationSchema() { - return [body('resource').exists(), body('params').optional()]; - } - - /** - * Imports xlsx/csv to the given resource type. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async fileUpload(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const body = this.matchedBodyData(req); - const params = defaultTo(parseJsonSafe(body.params), {}); - - try { - const data = await this.importResourceApp.import( - tenantId, - body.resource, - req.file.filename, - params - ); - return res.status(200).send(data); - } catch (error) { - next(error); - } - } - - /** - * Maps the columns of the imported file. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async mapping(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { import_id: importId } = req.params; - const body = this.matchedBodyData(req); - - try { - const mapping = await this.importResourceApp.mapping( - tenantId, - importId, - body?.mapping - ); - return res.status(200).send(mapping); - } catch (error) { - next(error); - } - } - - /** - * Preview the imported file before actual importing. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async preview(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { import_id: importId } = req.params; - - try { - const preview = await this.importResourceApp.preview(tenantId, importId); - - return res.status(200).send(preview); - } catch (error) { - next(error); - } - } - - /** - * Importing the imported file to the application storage. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async import(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { import_id: importId } = req.params; - - try { - const result = await this.importResourceApp.process(tenantId, importId); - - return res.status(200).send(result); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the csv/xlsx sample sheet of the given resource name. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async downloadImportSample( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { format, resource } = this.matchedQueryData(req); - - try { - const result = this.importResourceApp.sample(tenantId, resource, format); - - return res.status(200).send(result); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the import file meta. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getImportFileMeta( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { import_id: importId } = req.params; - - try { - const result = await this.importResourceApp.importMeta( - tenantId, - importId - ); - return res.status(200).send(result); - } catch (error) { - next(error); - } - } - - /** - * Transforms service errors to response. - * @param {Error} - * @param {Request} req - * @param {Response} res - * @param {ServiceError} error - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'INVALID_MAP_ATTRS') { - return res.status(400).send({ - errors: [{ type: 'INVALID_MAP_ATTRS' }], - }); - } - if (error.errorType === 'DUPLICATED_FROM_MAP_ATTR') { - return res.status(400).send({ - errors: [{ type: 'DUPLICATED_FROM_MAP_ATTR' }], - }); - } - if (error.errorType === 'DUPLICATED_TO_MAP_ATTR') { - return res.status(400).send({ - errors: [{ type: 'DUPLICATED_TO_MAP_ATTR' }], - }); - } - if (error.errorType === 'IMPORTED_FILE_EXTENSION_INVALID') { - return res.status(400).send({ - errors: [{ type: 'IMPORTED_FILE_EXTENSION_INVALID' }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Import/_utils.ts b/packages/server/src/api/controllers/Import/_utils.ts deleted file mode 100644 index 5629a55c6..000000000 --- a/packages/server/src/api/controllers/Import/_utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -import Multer from 'multer'; -import { ServiceError } from '@/exceptions'; -import { getImportsStoragePath } from '@/services/Import/_utils'; - -export function allowSheetExtensions(req, file, cb) { - if ( - file.mimetype !== 'text/csv' && - file.mimetype !== 'application/vnd.ms-excel' && - file.mimetype !== - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ) { - cb(new ServiceError('IMPORTED_FILE_EXTENSION_INVALID')); - return; - } - cb(null, true); -} - -const storage = Multer.diskStorage({ - destination: function (req, file, cb) { - const path = getImportsStoragePath(); - cb(null, path); - }, - filename: function (req, file, cb) { - // Add the creation timestamp to clean up temp files later. - const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); - cb(null, uniqueSuffix); - }, -}); - -export const uploadImportFile = Multer({ - storage, - limits: { fileSize: 5 * 1024 * 1024 }, - fileFilter: allowSheetExtensions, -}); diff --git a/packages/server/src/api/controllers/Inventory/InventortyItemsCosts.ts b/packages/server/src/api/controllers/Inventory/InventortyItemsCosts.ts deleted file mode 100644 index 36a3c6408..000000000 --- a/packages/server/src/api/controllers/Inventory/InventortyItemsCosts.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { query } from 'express-validator'; -import BaseController from '../BaseController'; -import { InventoryCostApplication } from '@/services/Inventory/InventoryCostApplication'; - -@Service() -export class InventoryItemsCostController extends BaseController { - @Inject() - private inventoryItemCost: InventoryCostApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/items-cost', - [ - query('date').exists().isISO8601().toDate(), - - query('items_ids').exists().isArray({ min: 1 }), - query('items_ids.*').exists().isInt().toInt(), - ], - this.validationResult, - this.asyncMiddleware(this.getItemsCosts) - ); - return router; - } - - /** - * Retrieves the given items costs. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public getItemsCosts = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const itemsCostQueryDTO = this.matchedQueryData(req); - - try { - const costs = await this.inventoryItemCost.getItemsInventoryValuationList( - tenantId, - itemsCostQueryDTO.itemsIds, - itemsCostQueryDTO.date - ); - return res.status(200).send({ costs }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Inventory/InventoryAdjustments.ts b/packages/server/src/api/controllers/Inventory/InventoryAdjustments.ts deleted file mode 100644 index 8fc41cada..000000000 --- a/packages/server/src/api/controllers/Inventory/InventoryAdjustments.ts +++ /dev/null @@ -1,345 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { check, query, param } from 'express-validator'; -import { ServiceError } from '@/exceptions'; -import BaseController from '../BaseController'; -import InventoryAdjustmentService from '@/services/Inventory/InventoryAdjustmentService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { AbilitySubject, InventoryAdjustmentAction } from '@/interfaces'; -import CheckPolicies from '../../middleware/CheckPolicies'; - -@Service() -export default class InventoryAdjustmentsController extends BaseController { - @Inject() - inventoryAdjustmentService: InventoryAdjustmentService; - - @Inject() - dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/:id/publish', - CheckPolicies( - InventoryAdjustmentAction.EDIT, - AbilitySubject.InventoryAdjustment - ), - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.publishInventoryAdjustment.bind(this)), - this.handleServiceErrors - ); - router.delete( - '/:id', - CheckPolicies( - InventoryAdjustmentAction.DELETE, - AbilitySubject.InventoryAdjustment - ), - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteInventoryAdjustment.bind(this)), - this.handleServiceErrors - ); - router.post( - '/quick', - CheckPolicies( - InventoryAdjustmentAction.CREATE, - AbilitySubject.InventoryAdjustment - ), - this.validatateQuickAdjustment, - this.validationResult, - this.asyncMiddleware(this.createQuickInventoryAdjustment.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id', - CheckPolicies( - InventoryAdjustmentAction.VIEW, - AbilitySubject.InventoryAdjustment - ), - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getInventoryAdjustment.bind(this)), - this.handleServiceErrors - ); - router.get( - '/', - CheckPolicies( - InventoryAdjustmentAction.VIEW, - AbilitySubject.InventoryAdjustment - ), - [...this.validateListQuerySchema], - this.validationResult, - this.asyncMiddleware(this.getInventoryAdjustments.bind(this)), - this.dynamicListService.handlerErrorsToResponse, - this.handleServiceErrors - ); - return router; - } - - /** - * Validate list query schema - */ - get validateListQuerySchema() { - return [ - query('column_sort_by').optional().trim(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('stringified_filter_roles').optional().isJSON(), - ]; - } - - /** - * Quick inventory adjustment validation schema. - */ - get validatateQuickAdjustment() { - return [ - check('date').exists().isISO8601(), - check('type') - .exists() - .isIn(['increment', 'decrement', 'value_adjustment']), - check('reference_no').exists(), - check('adjustment_account_id').exists().isInt().toInt(), - check('reason').exists().isString().exists(), - check('description').optional().isString(), - check('item_id').exists().isInt().toInt(), - check('quantity') - .if(check('type').exists().isIn(['increment', 'decrement'])) - .exists() - .isInt() - .toInt(), - check('cost') - .if(check('type').exists().isIn(['increment'])) - .exists() - .isFloat() - .toInt(), - check('publish').default(false).isBoolean().toBoolean(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - ]; - } - - /** - * Creates a quick inventory adjustment. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async createQuickInventoryAdjustment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const quickInventoryAdjustment = this.matchedBodyData(req); - - try { - const inventoryAdjustment = - await this.inventoryAdjustmentService.createQuickAdjustment( - tenantId, - quickInventoryAdjustment, - user - ); - - return res.status(200).send({ - id: inventoryAdjustment.id, - message: 'The inventory adjustment has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given inventory adjustment transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async deleteInventoryAdjustment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: adjustmentId } = req.params; - - try { - await this.inventoryAdjustmentService.deleteInventoryAdjustment( - tenantId, - adjustmentId - ); - return res.status(200).send({ - id: adjustmentId, - message: 'The inventory adjustment has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Publish the given inventory adjustment transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async publishInventoryAdjustment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: adjustmentId } = req.params; - - try { - await this.inventoryAdjustmentService.publishInventoryAdjustment( - tenantId, - adjustmentId - ); - return res.status(200).send({ - id: adjustmentId, - message: 'The inventory adjustment has been published successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the specific inventory adjustment transaction of the given id. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async getInventoryAdjustment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: adjustmentId } = req.params; - - try { - const inventoryAdjustment = - await this.inventoryAdjustmentService.getInventoryAdjustment( - tenantId, - adjustmentId - ); - - return res.status(200).send({ - data: this.transfromToResponse(inventoryAdjustment), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the inventory adjustments paginated list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async getInventoryAdjustments( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - page: 1, - pageSize: 12, - columnSortBy: 'created_at', - sortOrder: 'desc', - filterRoles: [], - ...this.matchedQueryData(req), - }; - - try { - const { pagination, inventoryAdjustments } = - await this.inventoryAdjustmentService.getInventoryAdjustments( - tenantId, - filter - ); - - return res.status(200).send({ - inventoy_adjustments: inventoryAdjustments, - pagination: this.transfromToResponse(pagination), - }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'INVENTORY_ADJUSTMENT_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'INVENTORY_ADJUSTMENT.NOT.FOUND', - code: 100, - message: 'The inventory adjustment not found.', - }, - ], - }); - } - if (error.errorType === 'NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ITEM.NOT.FOUND', code: 140 }], - }); - } - if (error.errorType === 'account_not_found') { - return res.boom.notFound('The given account not found.', { - errors: [{ type: 'ACCOUNT.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'ITEM_SHOULD_BE_INVENTORY_TYPE') { - return res.boom.badRequest( - 'You could not make adjustment on item has no inventory type.', - { errors: [{ type: 'ITEM_SHOULD_BE_INVENTORY_TYPE', code: 300 }] } - ); - } - if (error.errorType === 'INVENTORY_ADJUSTMENT_ALREADY_PUBLISHED') { - return res.boom.badRequest('', { - errors: [ - { type: 'INVENTORY_ADJUSTMENT_ALREADY_PUBLISHED', code: 400 }, - ], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4900, - data: { ...error.payload }, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/InviteUsers.ts b/packages/server/src/api/controllers/InviteUsers.ts deleted file mode 100644 index b17e1ec02..000000000 --- a/packages/server/src/api/controllers/InviteUsers.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { check, body, param } from 'express-validator'; -import { IInviteUserInput } from '@/interfaces'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { ServiceError } from '@/exceptions'; -import BaseController from './BaseController'; -import InviteTenantUserService from '@/services/InviteUsers/TenantInviteUser'; -import AcceptInviteUserService from '@/services/InviteUsers/AcceptInviteUser'; - -@Service() -export default class InviteUsersController extends BaseController { - @Inject() - private inviteUsersService: InviteTenantUserService; - - @Inject() - private acceptInviteService: AcceptInviteUserService; - - /** - * Routes that require authentication. - */ - authRouter() { - const router = Router(); - - router.post( - '/send', - [ - body('email').exists().trim(), - body('role_id').exists().isNumeric().toInt(), - ], - this.validationResult, - asyncMiddleware(this.sendInvite.bind(this)), - this.handleServicesError - ); - router.post( - '/resend/:userId', - [param('userId').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.resendInvite.bind(this)), - this.handleServicesError - ); - return router; - } - - /** - * Routes that non-required authentication. - */ - nonAuthRouter() { - const router = Router(); - - router.post( - '/accept/:token', - [...this.inviteUserDTO], - this.validationResult, - asyncMiddleware(this.accept.bind(this)), - this.handleServicesError - ); - router.get( - '/invited/:token', - [param('token').exists().trim()], - this.validationResult, - asyncMiddleware(this.invited.bind(this)), - this.handleServicesError - ); - - return router; - } - - /** - * Invite DTO schema validation. - * @returns {ValidationChain[]} - */ - private get inviteUserDTO() { - return [ - check('first_name').exists().trim(), - check('last_name').exists().trim(), - check('password').exists().trim().isLength({ min: 5 }), - param('token').exists().trim(), - ]; - } - - /** - * Invite a user to the authorized user organization. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - private async sendInvite(req: Request, res: Response, next: Function) { - const sendInviteDTO = this.matchedBodyData(req); - const { tenantId } = req; - const { user } = req; - - try { - await this.inviteUsersService.sendInvite(tenantId, sendInviteDTO, user); - - return res.status(200).send({ - type: 'success', - code: 'INVITE.SENT.SUCCESSFULLY', - message: 'The invite has been sent to the given email.', - }); - } catch (error) { - next(error); - } - } - - /** - * Resend the user invite. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - private async resendInvite(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { userId } = req.params; - - try { - await this.inviteUsersService.resendInvite(tenantId, userId, user); - - return res.status(200).send({ - type: 'success', - code: 'INVITE.RESEND.SUCCESSFULLY', - message: 'The invite has been sent to the given email.', - }); - } catch (error) { - next(error); - } - } - - /** - * Accept the inviation. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async accept(req: Request, res: Response, next: Function) { - const inviteUserInput: IInviteUserInput = this.matchedBodyData(req, { - locations: ['body'], - includeOptionals: true, - }); - const { token } = req.params; - - try { - await this.acceptInviteService.acceptInvite(token, inviteUserInput); - - return res.status(200).send({ - type: 'success', - code: 'USER.INVITE.ACCEPTED', - message: 'User invite has been accepted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Check if the invite token is valid. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async invited(req: Request, res: Response, next: Function) { - const { token } = req.params; - - try { - const { inviteToken, orgName } = - await this.acceptInviteService.checkInvite(token); - - return res.status(200).send({ - inviteToken: inviteToken.token, - email: inviteToken.email, - organizationName: orgName, - }); - } catch (error) { - next(error); - } - } - - /** - * Handles the service error. - */ - private handleServicesError( - error, - req: Request, - res: Response, - next: Function - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'EMAIL_EXISTS') { - return res.status(400).send({ - errors: [ - { - type: 'EMAIL.ALREADY.EXISTS', - code: 100, - message: 'Email already exists in the users.', - }, - ], - }); - } - if (error.errorType === 'EMAIL_ALREADY_INVITED') { - return res.status(400).send({ - errors: [ - { - type: 'EMAIL.ALREADY.INVITED', - code: 200, - message: 'Email already invited.', - }, - ], - }); - } - if (error.errorType === 'INVITE_TOKEN_INVALID') { - return res.status(400).send({ - errors: [ - { - type: 'INVITE.TOKEN.INVALID', - code: 300, - message: 'Invite token is invalid, please try another one.', - }, - ], - }); - } - if (error.errorType === 'PHONE_NUMBER_EXISTS') { - return res.status(400).send({ - errors: [ - { - type: 'PHONE_NUMBER.EXISTS', - code: 400, - message: - 'Phone number is already invited, please try another unique one.', - }, - ], - }); - } - if (error.errorType === 'USER_RECENTLY_INVITED') { - return res.status(400).send({ - errors: [ - { - type: 'USER_RECENTLY_INVITED', - code: 500, - message: - 'This person was recently invited. No need to invite them again just yet.', - }, - ], - }); - } - if (error.errorType === 'ROLE_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'ROLE_NOT_FOUND', - code: 600, - message: 'The given user role is not found.', - }, - ], - }); - } - if (error.errorType === 'USER_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'USER_NOT_FOUND', - code: 700, - message: 'The given user is not found.', - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/ItemCategories.ts b/packages/server/src/api/controllers/ItemCategories.ts deleted file mode 100644 index 0e1349d86..000000000 --- a/packages/server/src/api/controllers/ItemCategories.ts +++ /dev/null @@ -1,306 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import ItemCategoriesService from '@/services/ItemCategories/ItemCategoriesService'; -import { Inject, Service } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { IItemCategoryOTD } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import BaseController from '@/api/controllers/BaseController'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; - -@Service() -export default class ItemsCategoriesController extends BaseController { - @Inject() - itemCategoriesService: ItemCategoriesService; - - @Inject() - dynamicListService: DynamicListingService; - - /** - * Router constructor method. - */ - router() { - const router = Router(); - - router.post( - '/:id', - [ - ...this.categoryValidationSchema, - ...this.specificCategoryValidationSchema, - ], - this.validationResult, - asyncMiddleware(this.editCategory.bind(this)), - this.handlerServiceError - ); - router.post( - '/', - [...this.categoryValidationSchema], - this.validationResult, - asyncMiddleware(this.newCategory.bind(this)), - this.handlerServiceError - ); - router.delete( - '/:id', - [...this.specificCategoryValidationSchema], - this.validationResult, - asyncMiddleware(this.deleteItem.bind(this)), - this.handlerServiceError - ); - router.get( - '/:id', - [...this.specificCategoryValidationSchema], - this.validationResult, - asyncMiddleware(this.getCategory.bind(this)), - this.handlerServiceError - ); - router.get( - '/', - [...this.categoriesListValidationSchema], - this.validationResult, - asyncMiddleware(this.getList.bind(this)), - this.handlerServiceError, - this.dynamicListService.handlerErrorsToResponse - ); - return router; - } - - /** - * Item category validation schema. - */ - get categoryValidationSchema() { - return [ - check('name') - .exists() - .trim() - .isLength({ min: 0, max: DATATYPES_LENGTH.STRING }), - check('description') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('sell_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('cost_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('inventory_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - ]; - } - - /** - * Validate items categories schema. - */ - get categoriesListValidationSchema() { - return [ - query('column_sort_by').optional().trim(), - query('sort_order').optional().trim().isIn(['desc', 'asc']), - query('stringified_filter_roles').optional().isJSON(), - ]; - } - - /** - * Validate specific item category schema. - */ - get specificCategoryValidationSchema() { - return [param('id').exists().toInt()]; - } - - /** - * Creates a new item category. - * @param {Request} req - * @param {Response} res - */ - async newCategory(req: Request, res: Response, next: NextFunction) { - const { user, tenantId } = req; - const itemCategoryOTD: IItemCategoryOTD = this.matchedBodyData(req); - - try { - const itemCategory = await this.itemCategoriesService.newItemCategory( - tenantId, - itemCategoryOTD, - user - ); - return res.status(200).send({ - id: itemCategory.id, - message: 'The item category has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit details of the given category item. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - async editCategory(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: itemCategoryId } = req.params; - const itemCategoryOTD: IItemCategoryOTD = this.matchedBodyData(req); - - try { - await this.itemCategoriesService.editItemCategory( - tenantId, - itemCategoryId, - itemCategoryOTD, - user - ); - return res.status(200).send({ - id: itemCategoryId, - message: 'The item category has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Delete the give item category. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - async deleteItem(req: Request, res: Response, next: NextFunction) { - const { id: itemCategoryId } = req.params; - const { tenantId, user } = req; - - try { - await this.itemCategoriesService.deleteItemCategory( - tenantId, - itemCategoryId, - user - ); - return res.status(200).send({ - id: itemCategoryId, - message: 'The item category has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the list of items. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - async getList(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - - const itemCategoriesFilter = { - sortOrder: 'asc', - columnSortBy: 'created_at', - ...this.matchedQueryData(req), - }; - - try { - const { itemCategories, filterMeta } = - await this.itemCategoriesService.getItemCategoriesList( - tenantId, - itemCategoriesFilter, - user - ); - return res.status(200).send({ - item_categories: itemCategories, - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve details of the given category. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - async getCategory(req: Request, res: Response, next: NextFunction) { - const itemCategoryId: number = req.params.id; - const { tenantId, user } = req; - - try { - const itemCategory = await this.itemCategoriesService.getItemCategory( - tenantId, - itemCategoryId, - user - ); - return res.status(200).send({ category: itemCategory }); - } catch (error) { - next(error); - } - } - - /** - * Handles service error. - * @param {Error} error - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - */ - handlerServiceError( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'CATEGORY_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEM_CATEGORY_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'ITEM_CATEGORIES_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEM_CATEGORIES_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'CATEGORY_NAME_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'CATEGORY_NAME_EXISTS', code: 300 }], - }); - } - if (error.errorType === 'COST_ACCOUNT_NOT_FOUMD') { - return res.boom.badRequest(null, { - errors: [{ type: 'COST.ACCOUNT.NOT.FOUND', code: 400 }], - }); - } - if (error.errorType === 'COST_ACCOUNT_NOT_COGS') { - return res.boom.badRequest(null, { - errors: [{ type: 'COST.ACCOUNT.NOT.COGS.TYPE', code: 500 }], - }); - } - if (error.errorType === 'SELL_ACCOUNT_NOT_INCOME') { - return res.boom.badRequest(null, { - errors: [{ type: 'SELL.ACCOUNT.NOT.FOUND', code: 600 }], - }); - } - if (error.errorType === 'SELL_ACCOUNT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'SELL.ACCOUNT.NOT.INCOME.TYPE', code: 700 }], - }); - } - if (error.errorType === 'INVENTORY_ACCOUNT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'INVENTORY.ACCOUNT.NOT.FOUND', code: 800 }], - }); - } - if (error.errorType === 'INVENTORY_ACCOUNT_NOT_INVENTORY') { - return res.boom.badRequest(null, { - errors: [{ type: 'INVENTORY.ACCOUNT.NOT.CURRENT.ASSET', code: 900 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Items/Items.ts b/packages/server/src/api/controllers/Items/Items.ts deleted file mode 100644 index 814358fd2..000000000 --- a/packages/server/src/api/controllers/Items/Items.ts +++ /dev/null @@ -1,536 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query, ValidationChain } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ServiceError } from '@/exceptions'; -import { IItemDTO, ItemAction, AbilitySubject } from '@/interfaces'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; -import CheckAbilities from '@/api/middleware/CheckPolicies'; -import { ItemsApplication } from '@/services/Items/ItemsApplication'; - -@Service() -export default class ItemsController extends BaseController { - @Inject() - private itemsApplication: ItemsApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckAbilities(ItemAction.CREATE, AbilitySubject.Item), - this.validateItemSchema, - this.validationResult, - this.asyncMiddleware(this.newItem.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id/activate', - CheckAbilities(ItemAction.EDIT, AbilitySubject.Item), - this.validateSpecificItemSchema, - this.validationResult, - this.asyncMiddleware(this.activateItem.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id/inactivate', - CheckAbilities(ItemAction.EDIT, AbilitySubject.Item), - [...this.validateSpecificItemSchema], - this.validationResult, - this.asyncMiddleware(this.inactivateItem.bind(this)), - this.handlerServiceErrors - ); - router.post( - '/:id', - CheckAbilities(ItemAction.EDIT, AbilitySubject.Item), - [...this.validateItemSchema, ...this.validateSpecificItemSchema], - this.validationResult, - this.asyncMiddleware(this.editItem.bind(this)), - this.handlerServiceErrors - ); - router.delete( - '/:id', - CheckAbilities(ItemAction.DELETE, AbilitySubject.Item), - [...this.validateSpecificItemSchema], - this.validationResult, - this.asyncMiddleware(this.deleteItem.bind(this)), - this.handlerServiceErrors - ); - router.get( - '/:id', - CheckAbilities(ItemAction.VIEW, AbilitySubject.Item), - [...this.validateSpecificItemSchema], - this.validationResult, - this.asyncMiddleware(this.getItem.bind(this)), - this.handlerServiceErrors - ); - router.get( - '/', - CheckAbilities(ItemAction.VIEW, AbilitySubject.Item), - [...this.validateListQuerySchema], - this.validationResult, - this.asyncMiddleware(this.getItemsList.bind(this)), - this.dynamicListService.handlerErrorsToResponse, - this.handlerServiceErrors - ); - return router; - } - - /** - * Validate item schema. - */ - get validateItemSchema(): ValidationChain[] { - return [ - check('name') - .exists() - .isString() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('type') - .exists() - .isString() - .trim() - .isIn(['service', 'non-inventory', 'inventory']), - check('code') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - // Purchase attributes. - check('purchasable').optional().isBoolean().toBoolean(), - check('cost_price') - .optional({ nullable: true }) - .isFloat({ min: 0, max: DATATYPES_LENGTH.DECIMAL_13_3 }) - .toFloat() - .if(check('purchasable').equals('true')) - .exists(), - check('cost_account_id').if(check('purchasable').equals('true')).exists(), - check('cost_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - // Sell attributes. - check('sellable').optional().isBoolean().toBoolean(), - check('sell_price') - .optional({ nullable: true }) - .isFloat({ min: 0, max: DATATYPES_LENGTH.DECIMAL_13_3 }) - .toFloat() - .if(check('sellable').equals('true')) - .exists(), - check('sell_account_id').if(check('sellable').equals('true')).exists(), - check('sell_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('inventory_account_id') - .if(check('type').equals('inventory')) - .exists(), - check('inventory_account_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('sell_description') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('purchase_description') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('sell_tax_rate_id').optional({ nullable: true }).isInt().toInt(), - check('purchase_tax_rate_id') - .optional({ nullable: true }) - .isInt() - .toInt(), - check('category_id') - .optional({ nullable: true }) - .isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('note') - .optional() - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('active').optional().isBoolean().toBoolean(), - - check('media_ids').optional().isArray(), - check('media_ids.*').exists().isNumeric().toInt(), - ]; - } - - /** - * Validate specific item params schema. - * @return {ValidationChain[]} - */ - get validateSpecificItemSchema(): ValidationChain[] { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Validate list query schema. - */ - private get validateListQuerySchema() { - return [ - query('column_sort_by').optional().trim(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('view_slug').optional({ nullable: true }).isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - - query('inactive_mode').optional().isBoolean().toBoolean(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Stores the given item details to the storage. - * @param {Request} req - * @param {Response} res - */ - private async newItem(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const itemDTO: IItemDTO = this.matchedBodyData(req); - - try { - const storedItem = await this.itemsApplication.createItem( - tenantId, - itemDTO - ); - - return res.status(200).send({ - id: storedItem.id, - message: 'The item has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Updates the given item details on the storage. - * @param {Request} req - * @param {Response} res - */ - private async editItem(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const itemId: number = req.params.id; - const item: IItemDTO = this.matchedBodyData(req); - - try { - await this.itemsApplication.editItem(tenantId, itemId, item); - - return res.status(200).send({ - id: itemId, - message: 'The item has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Activates the given item. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async activateItem(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const itemId: number = req.params.id; - - try { - await this.itemsApplication.activateItem(tenantId, itemId); - - return res.status(200).send({ - id: itemId, - message: 'The item has been activated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Inactivates the given item. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async inactivateItem( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const itemId: number = req.params.id; - - try { - await this.itemsApplication.inactivateItem(tenantId, itemId); - - return res.status(200).send({ - id: itemId, - message: 'The item has been inactivated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given item from the storage. - * @param {Request} req - * @param {Response} res - */ - private async deleteItem(req: Request, res: Response, next: NextFunction) { - const itemId: number = req.params.id; - const { tenantId } = req; - - try { - await this.itemsApplication.deleteItem(tenantId, itemId); - - return res.status(200).send({ - id: itemId, - message: 'The item has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve details the given item id. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async getItem(req: Request, res: Response, next: NextFunction) { - const itemId: number = req.params.id; - const { tenantId } = req; - - try { - const item = await this.itemsApplication.getItem(tenantId, itemId); - - return res.status(200).send({ - item: this.transfromToResponse(item), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve items datatable list. - * @param {Request} req - * @param {Response} res - */ - private async getItemsList(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - const filter = { - sortOrder: 'DESC', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - inactiveMode: false, - ...this.matchedQueryData(req), - }; - - try { - const { items, pagination, filterMeta } = - await this.itemsApplication.getItems(tenantId, filter); - - return res.status(200).send({ - items: this.transfromToResponse(items), - pagination: this.transfromToResponse(pagination), - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ITEM.NOT.FOUND', code: 140 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ITEMS_NOT_FOUND', code: 130 }], - }); - } - if (error.errorType === 'ITEM_CATEOGRY_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ITEM_CATEGORY.NOT.FOUND', code: 140 }], - }); - } - if (error.errorType === 'ITEM_NAME_EXISTS') { - return res.status(400).send({ - errors: [{ type: 'ITEM.NAME.ALREADY.EXISTS', code: 210 }], - }); - } - if (error.errorType === 'COST_ACCOUNT_NOT_FOUMD') { - return res.status(400).send({ - errors: [{ type: 'COST.ACCOUNT.NOT.FOUND', code: 120 }], - }); - } - if (error.errorType === 'COST_ACCOUNT_NOT_COGS') { - return res.status(400).send({ - errors: [{ type: 'COST.ACCOUNT.NOT.COGS.TYPE', code: 220 }], - }); - } - if (error.errorType === 'SELL_ACCOUNT_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'SELL.ACCOUNT.NOT.FOUND', code: 130 }], - }); - } - if (error.errorType === 'SELL_ACCOUNT_NOT_INCOME') { - return res.status(400).send({ - errors: [{ type: 'SELL.ACCOUNT.NOT.INCOME.TYPE', code: 230 }], - }); - } - if (error.errorType === 'COST_ACCOUNT_NOT_FOUMD') { - return res.status(400).send({ - errors: [{ type: 'COST.ACCOUNT.NOT.FOUND', code: 120 }], - }); - } - if (error.errorType === 'COST_ACCOUNT_NOT_COGS') { - return res.status(400).send({ - errors: [{ type: 'COST.ACCOUNT.NOT.COGS.TYPE', code: 220 }], - }); - } - if (error.errorType === 'SELL_ACCOUNT_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'SELL.ACCOUNT.NOT.FOUND', code: 130 }], - }); - } - if (error.errorType === 'INVENTORY_ACCOUNT_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'INVENTORY.ACCOUNT.NOT.FOUND', code: 200 }], - }); - } - if (error.errorType === 'SELL_ACCOUNT_NOT_INCOME') { - return res.status(400).send({ - errors: [{ type: 'SELL.ACCOUNT.NOT.INCOME.TYPE', code: 230 }], - }); - } - if (error.errorType === 'INVENTORY_ACCOUNT_NOT_INVENTORY') { - return res.status(400).send({ - errors: [{ type: 'INVENTORY.ACCOUNT.NOT.INVENTORY.TYPE', code: 300 }], - }); - } - if (error.errorType === 'ITEMS_HAVE_ASSOCIATED_TRANSACTIONS') { - return res.status(400).send({ - errors: [{ type: 'ITEMS_HAVE_ASSOCIATED_TRANSACTIONS', code: 310 }], - }); - } - if (error.errorType === 'ITEM_HAS_ASSOCIATED_TRANSACTINS') { - return res.status(400).send({ - errors: [{ type: 'ITEM_HAS_ASSOCIATED_TRANSACTINS', code: 320 }], - }); - } - if (error.errorType === 'ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT') { - return res.status(400).send({ - errors: [ - { type: 'ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT', code: 330 }, - ], - }); - } - if (error.errorType === 'ITEM_CANNOT_CHANGE_INVENTORY_TYPE') { - return res.status(400).send({ - errors: [ - { - type: 'ITEM_CANNOT_CHANGE_INVENTORY_TYPE', - message: 'Cannot change inventory item type', - code: 340, - }, - ], - }); - } - if (error.errorType === 'TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS') { - return res.status(400).send({ - errors: [ - { - type: 'TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS', - message: - 'Cannot change item type to inventory with item has associated transactions.', - code: 350, - }, - ], - }); - } - if (error.errorType === 'INVENTORY_ACCOUNT_CANNOT_MODIFIED') { - return res.status(400).send({ - errors: [ - { - type: 'INVENTORY_ACCOUNT_CANNOT_MODIFIED', - message: - 'Cannot change item inventory account while the item has transactions.', - code: 360, - }, - ], - }); - } - if (error.errorType === 'ITEM_HAS_ASSOCIATED_TRANSACTIONS') { - return res.status(400).send({ - errors: [ - { - type: 'ITEM_HAS_ASSOCIATED_TRANSACTIONS', - code: 370, - message: - 'Could not delete item that has associated transactions.', - }, - ], - }); - } - if (error.errorType === 'PURCHASE_TAX_RATE_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'PURCHASE_TAX_RATE_NOT_FOUND', - message: 'Purchase tax rate has not found.', - code: 410, - }, - ], - }); - } - if (error.errorType === 'SELL_TAX_RATE_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'SELL_TAX_RATE_NOT_FOUND', - message: 'Sell tax rate is not found.', - code: 420, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Items/ItemsTransactions.ts b/packages/server/src/api/controllers/Items/ItemsTransactions.ts deleted file mode 100644 index 53086c0c7..000000000 --- a/packages/server/src/api/controllers/Items/ItemsTransactions.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Inject, Service } from 'typedi'; -import ItemTransactionsService from '@/services/Items/ItemTransactionsService'; -import BaseController from '../BaseController'; - -@Service() -export default class ItemTransactionsController extends BaseController { - @Inject() - itemTransactionsService: ItemTransactionsService; - - router() { - const router = Router(); - - router.get( - '/:id/transactions/invoices', - this.asyncMiddleware(this.getItemInvoicesTransactions) - ); - router.get( - '/:id/transactions/bills', - this.asyncMiddleware(this.getItemBillTransactions) - ); - router.get( - '/:id/transactions/estimates', - this.asyncMiddleware(this.getItemEstimateTransactions) - ); - router.get( - '/:id/transactions/receipts', - this.asyncMiddleware(this.getItemReceiptTransactions) - ); - return router; - } - - /** - * Retrieve item associated invoices transactions. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - public getItemInvoicesTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - try { - const transactions = - await this.itemTransactionsService.getItemInvoicesTransactions( - tenantId, - invoiceId - ); - - return res.status(200).send({ data: transactions }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve item associated bills transactions. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - public getItemBillTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: billId } = req.params; - - try { - const transactions = - await this.itemTransactionsService.getItemBillTransactions( - tenantId, - billId - ); - return res.status(200).send({ data: transactions }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve item associated estimates transactions. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - public getItemEstimateTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: estimateId } = req.params; - - try { - const transactions = - await this.itemTransactionsService.getItemEstimateTransactions( - tenantId, - estimateId - ); - return res.status(200).send({ data: transactions }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - */ - public getItemReceiptTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: receiptId } = req.params; - - try { - const transactions = - await this.itemTransactionsService.getItemReceiptTransactions( - tenantId, - receiptId - ); - return res.status(200).send({ data: transactions }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Items/index.ts b/packages/server/src/api/controllers/Items/index.ts deleted file mode 100644 index a64e598eb..000000000 --- a/packages/server/src/api/controllers/Items/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Container, Service } from 'typedi'; -import ItemsController from './Items'; - -import ItemTransactionsController from './ItemsTransactions'; - -@Service() -export default class ItemsBaseController { - public router() { - const router = Router(); - - router.use('/', Container.get(ItemsController).router()); - router.use('/', Container.get(ItemTransactionsController).router()); - - return router; - } -} diff --git a/packages/server/src/api/controllers/Jobs.ts b/packages/server/src/api/controllers/Jobs.ts deleted file mode 100644 index 08786fdea..000000000 --- a/packages/server/src/api/controllers/Jobs.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import { ServiceError } from '@/exceptions'; -import JobsService from '@/services/Jobs/JobsService'; - -@Service() -export default class ItemsController extends BaseController { - @Inject() - jobsService: JobsService; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.get('/:id', this.getJob, this.handlerServiceErrors); - - return router; - } - - /** - * Retrieve job details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getJob = async (req: Request, res: Response, next: NextFunction) => { - const { id } = req.params; - - try { - const job = await this.jobsService.getJob(id); - - return res.status(200).send({ - job: this.transfromToResponse(job), - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors = ( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) => { - if (error instanceof ServiceError) { - } - next(error); - }; -} diff --git a/packages/server/src/api/controllers/ManualJournals.ts b/packages/server/src/api/controllers/ManualJournals.ts deleted file mode 100644 index c04a85821..000000000 --- a/packages/server/src/api/controllers/ManualJournals.ts +++ /dev/null @@ -1,476 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { ServiceError } from '@/exceptions'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { DATATYPES_LENGTH } from '@/data/DataTypes'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, ManualJournalAction } from '@/interfaces'; -import { ManualJournalsApplication } from '@/services/ManualJournals/ManualJournalsApplication'; - -@Service() -export default class ManualJournalsController extends BaseController { - @Inject() - private manualJournalsApplication: ManualJournalsApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - CheckPolicies(ManualJournalAction.View, AbilitySubject.ManualJournal), - [...this.manualJournalsListSchema], - this.validationResult, - asyncMiddleware(this.getManualJournalsList), - this.dynamicListService.handlerErrorsToResponse, - this.catchServiceErrors - ); - router.get( - '/:id', - CheckPolicies(ManualJournalAction.View, AbilitySubject.ManualJournal), - asyncMiddleware(this.getManualJournal), - this.catchServiceErrors - ); - router.post( - '/:id/publish', - CheckPolicies(ManualJournalAction.Edit, AbilitySubject.ManualJournal), - [...this.manualJournalParamSchema], - this.validationResult, - asyncMiddleware(this.publishManualJournal), - this.catchServiceErrors - ); - router.post( - '/:id', - CheckPolicies(ManualJournalAction.Edit, AbilitySubject.ManualJournal), - [...this.manualJournalValidationSchema, ...this.manualJournalParamSchema], - this.validationResult, - asyncMiddleware(this.editManualJournal), - this.catchServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(ManualJournalAction.Delete, AbilitySubject.ManualJournal), - [...this.manualJournalParamSchema], - this.validationResult, - asyncMiddleware(this.deleteManualJournal), - this.catchServiceErrors - ); - router.post( - '/', - CheckPolicies(ManualJournalAction.Create, AbilitySubject.ManualJournal), - [...this.manualJournalValidationSchema], - this.validationResult, - asyncMiddleware(this.makeJournalEntries), - this.catchServiceErrors - ); - return router; - } - - /** - * Specific manual journal id param validation schema. - */ - private get manualJournalParamSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Manual journal DTO schema. - */ - private get manualJournalValidationSchema() { - return [ - check('date').exists().isISO8601(), - check('currency_code').optional(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('journal_number') - .optional() - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('journal_type') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('reference') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('description') - .optional({ nullable: true }) - .isString() - .trim() - .isLength({ max: DATATYPES_LENGTH.TEXT }), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - check('publish').optional().isBoolean().toBoolean(), - check('entries').isArray({ min: 2 }), - check('entries.*.index') - .exists() - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('entries.*.credit') - .optional({ nullable: true }) - .isFloat({ min: 0, max: DATATYPES_LENGTH.DECIMAL_13_3 }) - .toFloat(), - check('entries.*.debit') - .optional({ nullable: true }) - .isFloat({ min: 0, max: DATATYPES_LENGTH.DECIMAL_13_3 }) - .toFloat(), - check('entries.*.account_id') - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('entries.*.note') - .optional({ nullable: true }) - .isString() - .isLength({ max: DATATYPES_LENGTH.STRING }), - check('entries.*.contact_id') - .optional({ nullable: true }) - .isInt({ max: DATATYPES_LENGTH.INT_10 }) - .toInt(), - check('entries.*.branch_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - check('entries.*.project_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - ]; - } - - /** - * Manual journals list validation schema. - */ - private get manualJournalsListSchema() { - return [ - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('custom_view_id').optional().isNumeric().toInt(), - - query('column_sort_by').optional().trim(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('stringified_filter_roles').optional().isJSON(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Make manual journal. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private makeJournalEntries = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - const manualJournalDTO = this.matchedBodyData(req); - - try { - const { manualJournal } = - await this.manualJournalsApplication.createManualJournal( - tenantId, - manualJournalDTO, - user - ); - return res.status(200).send({ - id: manualJournal.id, - message: 'The manual journal has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Edit the given manual journal. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private editManualJournal = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - const { id: manualJournalId } = req.params; - const manualJournalDTO = this.matchedBodyData(req); - - try { - const { manualJournal } = - await this.manualJournalsApplication.editManualJournal( - tenantId, - manualJournalId, - manualJournalDTO, - user - ); - return res.status(200).send({ - id: manualJournal.id, - message: 'The manual journal has been edited successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the given manual journal details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getManualJournal = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: manualJournalId } = req.params; - - try { - const manualJournal = - await this.manualJournalsApplication.getManualJournal( - tenantId, - manualJournalId - ); - return res.status(200).send({ - manual_journal: this.transfromToResponse(manualJournal), - }); - } catch (error) { - next(error); - } - }; - - /** - * Publish the given manual journal. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private publishManualJournal = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: manualJournalId } = req.params; - - try { - await this.manualJournalsApplication.publishManualJournal( - tenantId, - manualJournalId - ); - return res.status(200).send({ - id: manualJournalId, - message: 'The manual journal has been published successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Delete the given manual journal. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private deleteManualJournal = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - const { id: manualJournalId } = req.params; - - try { - await this.manualJournalsApplication.deleteManualJournal( - tenantId, - manualJournalId - ); - return res.status(200).send({ - id: manualJournalId, - message: 'Manual journal has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve manual journals list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getManualJournalsList = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - try { - const { manualJournals, pagination, filterMeta } = - await this.manualJournalsApplication.getManualJournals( - tenantId, - filter - ); - - return res.status(200).send({ - manual_journals: this.transfromToResponse(manualJournals), - pagination: this.transfromToResponse(pagination), - filter_meta: this.transfromToResponse(filterMeta), - }); - } catch (error) { - next(error); - } - }; - - /** - * Catches all service errors. - * @param error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - catchServiceErrors = ( - error, - req: Request, - res: Response, - next: NextFunction - ) => { - if (error instanceof ServiceError) { - if (error.errorType === 'manual_journal_not_found') { - res.boom.badRequest('Manual journal not found.', { - errors: [{ type: 'MANUAL.JOURNAL.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'credit_debit_not_equal_zero') { - return res.boom.badRequest( - 'Credit and debit should not be equal zero.', - { - errors: [ - { - type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', - code: 200, - }, - ], - } - ); - } - if (error.errorType === 'credit_debit_not_equal') { - return res.boom.badRequest('Credit and debit should be equal.', { - errors: [{ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 300 }], - }); - } - if (error.errorType === 'accounts_ids_not_found') { - return res.boom.badRequest( - 'Journal entries some of accounts ids not exists.', - { errors: [{ type: 'ACCOUNTS.IDS.NOT.FOUND', code: 400 }] } - ); - } - if (error.errorType === 'journal_number_exists') { - return res.boom.badRequest('Journal number should be unique.', { - errors: [{ type: 'JOURNAL.NUMBER.ALREADY.EXISTS', code: 500 }], - }); - } - if (error.errorType === 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT') { - return res.boom.badRequest('', { - errors: [ - { - type: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT', - code: 600, - meta: this.transfromToResponse(error.payload), - }, - ], - }); - } - if (error.errorType === 'CONTACTS_SHOULD_ASSIGN_WITH_VALID_ACCOUNT') { - return res.boom.badRequest('', { - errors: [ - { - type: 'CONTACTS_SHOULD_ASSIGN_WITH_VALID_ACCOUNT', - code: 700, - meta: this.transfromToResponse(error.payload), - }, - ], - }); - } - if (error.errorType === 'contacts_not_found') { - return res.boom.badRequest('', { - errors: [{ type: 'CONTACTS_NOT_FOUND', code: 800 }], - }); - } - if (error.errorType === 'MANUAL_JOURNAL_ALREADY_PUBLISHED') { - return res.boom.badRequest('', { - errors: [{ type: 'MANUAL_JOURNAL_ALREADY_PUBLISHED', code: 900 }], - }); - } - if (error.errorType === 'MANUAL_JOURNAL_NO_REQUIRED') { - return res.boom.badRequest('', { - errors: [ - { - type: 'MANUAL_JOURNAL_NO_REQUIRED', - message: 'The manual journal number required.', - code: 1000, - }, - ], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if ( - error.errorType === 'COULD_NOT_ASSIGN_DIFFERENT_CURRENCY_TO_ACCOUNTS' - ) { - return res.boom.badRequest(null, { - errors: [ - { - type: 'COULD_NOT_ASSIGN_DIFFERENT_CURRENCY_TO_ACCOUNTS', - code: 1100, - }, - ], - }); - } - if (error.errorType === 'MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID') { - return res.boom.badRequest(null, { - errors: [ - { type: 'MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID', code: 1200 }, - ], - }); - } - } - next(error); - }; -} diff --git a/packages/server/src/api/controllers/Media.ts b/packages/server/src/api/controllers/Media.ts deleted file mode 100644 index 16b578c0d..000000000 --- a/packages/server/src/api/controllers/Media.ts +++ /dev/null @@ -1,211 +0,0 @@ - -import { Router, Request, Response, NextFunction } from 'express'; -import { - param, - query, - check, -} from 'express-validator'; -import { camelCase, upperFirst } from 'lodash'; -import { Inject, Service } from 'typedi'; -import { IMediaLinkDTO } from '@/interfaces'; -import fs from 'fs'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from './BaseController'; -import MediaService from '@/services/Media/MediaService'; -import { ServiceError } from '@/exceptions'; - -const fsPromises = fs.promises; - -@Service() -export default class MediaController extends BaseController { - @Inject() - mediaService: MediaService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post('/upload', [ - ...this.uploadValidationSchema, - ], - this.validationResult, - asyncMiddleware(this.uploadMedia.bind(this)), - this.handlerServiceErrors, - ); - router.post('/:id/link', [ - ...this.mediaIdParamSchema, - ...this.linkValidationSchema, - ], - this.validationResult, - asyncMiddleware(this.linkMedia.bind(this)), - this.handlerServiceErrors, - ); - router.delete('/', [ - ...this.deleteValidationSchema, - ], - this.validationResult, - asyncMiddleware(this.deleteMedia.bind(this)), - this.handlerServiceErrors, - ); - router.get('/:id', [ - ...this.mediaIdParamSchema, - ], - this.validationResult, - asyncMiddleware(this.getMedia.bind(this)), - this.handlerServiceErrors, - ); - return router; - } - - get uploadValidationSchema() { - return [ - check('model_name').optional().trim(), - check('model_id').optional().isNumeric(), - ]; - } - - get linkValidationSchema() { - return [ - check('model_name').exists().trim(), - check('model_id').exists().isNumeric().toInt(), - ] - } - - get deleteValidationSchema() { - return [ - query('ids').exists().isArray(), - query('ids.*').exists().isNumeric().toInt(), - ]; - } - - get mediaIdParamSchema() { - return [ - param('id').exists().isNumeric().toInt(), - ]; - } - - /** - * Retrieve all or the given attachment ids. - * @param {Request} req - - * @param {Response} req - - * @param {NextFunction} req - - */ - async getMedia(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: mediaId } = req.params; - - try { - const media = await this.mediaService.getMedia(tenantId, mediaId); - return res.status(200).send({ media }); - } catch (error) { - next(error); - } - } - - /** - * Uploads media. - * @param {Request} req - - * @param {Response} req - - * @param {NextFunction} req - - */ - async uploadMedia(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { attachment } = req.files - - const linkMediaDTO: IMediaLinkDTO = this.matchedBodyData(req); - const modelName = linkMediaDTO.modelName - ? upperFirst(camelCase(linkMediaDTO.modelName)) : ''; - - try { - const media = await this.mediaService.upload(tenantId, attachment, modelName, linkMediaDTO.modelId); - return res.status(200).send({ media_id: media.id }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given attachment ids from file system and database. - * @param {Request} req - - * @param {Response} req - - * @param {NextFunction} req - - */ - async deleteMedia(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { ids: mediaIds } = req.query; - - try { - await this.mediaService.deleteMedia(tenantId, mediaIds); - return res.status(200).send({ - media_ids: mediaIds - }); - } catch (error) { - next(error); - } - } - - /** - * Links the given media to the specific resource model. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async linkMedia(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: mediaId } = req.params; - const linkMediaDTO: IMediaLinkDTO = this.matchedBodyData(req); - const modelName = upperFirst(camelCase(linkMediaDTO.modelName)); - - try { - await this.mediaService.linkMedia(tenantId, mediaId, linkMediaDTO.modelId, modelName); - return res.status(200).send({ media_id: mediaId }); - } catch (error) { - next(error); - } - } - - /** - * Handler service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - handlerServiceErrors(error, req: Request, res: Response, next: NextFunction) { - if (error instanceof ServiceError) { - if (error.errorType === 'MINETYPE_NOT_SUPPORTED') { - return res.boom.badRequest(null, { - errors: [{ type: 'MINETYPE_NOT_SUPPORTED', code: 100, }] - }); - } - if (error.errorType === 'MEDIA_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'MEDIA_NOT_FOUND', code: 200 }] - }); - } - if (error.errorType === 'MODEL_NAME_HAS_NO_MEDIA') { - return res.boom.badRequest(null, { - errors: [{ type: 'MODEL_NAME_HAS_NO_MEDIA', code: 300 }] - }); - } - if (error.errorType === 'MODEL_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'MODEL_ID_NOT_FOUND', code: 400 }] - }); - } - if (error.errorType === 'MEDIA_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'MEDIA_IDS_NOT_FOUND', code: 500 }], - }); - } - if (error.errorType === 'MEDIA_LINK_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'MEDIA_LINK_EXISTS', code: 600 }], - }); - } - } - next(error); - } -}; diff --git a/packages/server/src/api/controllers/Miscellaneous/index.ts b/packages/server/src/api/controllers/Miscellaneous/index.ts deleted file mode 100644 index 9d8e5367b..000000000 --- a/packages/server/src/api/controllers/Miscellaneous/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import MiscService from '@/services/Miscellaneous/MiscService'; -import DateFormatsService from '@/services/Miscellaneous/DateFormats'; - -@Service() -export default class MiscController extends BaseController { - @Inject() - dateFormatsService: DateFormatsService; - - /** - * Express router. - */ - router() { - const router = Router(); - - router.get( - '/date_formats', - this.validationResult, - this.asyncMiddleware(this.dateFormats.bind(this)) - ); - return router; - } - - /** - * Retrieve date formats options. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - dateFormats(req: Request, res: Response, next: NextFunction) { - try { - const dateFormats = this.dateFormatsService.getDateFormats(); - - return res.status(200).send({ data: dateFormats }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts b/packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts deleted file mode 100644 index 1a92c18f8..000000000 --- a/packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import { body } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { OneClickDemoApplication } from '@/services/OneClickDemo/OneClickDemoApplication'; -import config from '@/config'; -@Service() -export class OneClickDemoController extends BaseController { - @Inject() - private oneClickDemoApp: OneClickDemoApplication; - - /** - * Router constructor method. - */ - router() { - const router = Router(); - - // Protects the endpoints if the feature is not enabled. - const protectMiddleware = ( - req: Request, - res: Response, - next: NextFunction - ) => { - // Add your protection logic here - if (config.oneClickDemoAccounts) { - next(); - } else { - res.status(403).send({ message: 'Forbidden' }); - } - }; - router.post( - '/one_click', - protectMiddleware, - asyncMiddleware(this.oneClickDemo.bind(this)) - ); - router.post( - '/one_click_signin', - [body('demo_id').exists()], - this.validationResult, - protectMiddleware, - asyncMiddleware(this.oneClickSignIn.bind(this)) - ); - return router; - } - - /** - * One-click demo application. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async oneClickDemo(req: Request, res: Response, next: NextFunction) { - try { - const data = await this.oneClickDemoApp.createOneClick(); - - return res.status(200).send({ - data, - message: 'The one-click demo has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Sign-in to one-click demo account. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async oneClickSignIn( - req: Request, - res: Response, - next: NextFunction - ) { - const { demoId } = this.matchedBodyData(req); - - try { - const data = await this.oneClickDemoApp.autoSignIn(demoId); - - return res.status(200).send(data); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Organization.ts b/packages/server/src/api/controllers/Organization.ts deleted file mode 100644 index 9e01c8da2..000000000 --- a/packages/server/src/api/controllers/Organization.ts +++ /dev/null @@ -1,225 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment-timezone'; -import { Router, Request, Response, NextFunction } from 'express'; -import { check, ValidationChain } from 'express-validator'; - -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import JWTAuth from '@/api/middleware/jwtAuth'; -import TenancyMiddleware from '@/api/middleware/TenancyMiddleware'; -import SubscriptionMiddleware from '@/api/middleware/SubscriptionMiddleware'; -import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser'; -import OrganizationService from '@/services/Organization/OrganizationService'; -import { MONTHS, ACCEPTED_LOCALES } from '@/services/Organization/constants'; -import { DATE_FORMATS } from '@/services/Miscellaneous/DateFormats/constants'; - -import { ServiceError } from '@/exceptions'; -import BaseController from '@/api/controllers/BaseController'; - -@Service() -export default class OrganizationController extends BaseController { - @Inject() - private organizationService: OrganizationService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - // Should before build tenant database the user be authorized and - // most important than that, should be subscribed to any plan. - router.use(JWTAuth); - router.use(AttachCurrentTenantUser); - router.use(TenancyMiddleware); - - router.use('/build', SubscriptionMiddleware('main')); - router.post( - '/build', - this.buildOrganizationValidationSchema, - this.validationResult, - asyncMiddleware(this.build.bind(this)), - this.handleServiceErrors.bind(this) - ); - router.put( - '/', - this.updateOrganizationValidationSchema, - this.validationResult, - this.asyncMiddleware(this.updateOrganization.bind(this)), - this.handleServiceErrors.bind(this) - ); - router.get( - '/', - asyncMiddleware(this.currentOrganization.bind(this)), - this.handleServiceErrors.bind(this) - ); - return router; - } - - /** - * Build organization validation schema. - * @returns {ValidationChain[]} - */ - private get buildOrganizationValidationSchema(): ValidationChain[] { - return [ - check('name').exists().trim(), - check('industry').optional({ nullable: true }).isString().trim(), - check('location').exists().isString().isISO31661Alpha2(), - check('base_currency').exists().isISO4217(), - check('timezone').exists().isIn(moment.tz.names()), - check('fiscal_year').exists().isIn(MONTHS), - check('language').exists().isString().isIn(ACCEPTED_LOCALES), - check('date_format').optional().isIn(DATE_FORMATS), - ]; - } - - /** - * Update organization validation schema. - * @returns {ValidationChain[]} - */ - private get updateOrganizationValidationSchema(): ValidationChain[] { - return [ - // # Profile - check('name').optional().trim(), - check('industry').optional({ nullable: true }).isString().trim(), - check('location').optional().isString().isISO31661Alpha2(), - check('base_currency').optional().isISO4217(), - check('timezone').optional().isIn(moment.tz.names()), - check('fiscal_year').optional().isIn(MONTHS), - check('language').optional().isString().isIn(ACCEPTED_LOCALES), - check('date_format').optional().isIn(DATE_FORMATS), - - // # Address - check('address.address_1').optional().isString().trim(), - check('address.address_2').optional().isString().trim(), - check('address.postal_code').optional().isString().trim(), - check('address.city').optional().isString().trim(), - check('address.state_province').optional().isString().trim(), - check('address.phone').optional().isString().trim(), - - // # Branding - check('primary_color').optional({ nullable: true }).isHexColor().trim(), - check('logo_key').optional({ nullable: true }).isString().trim(), - - check('tax_number').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Builds tenant database and migrate database schema. - * @param {Request} req - Express request. - * @param {Response} res - Express response. - * @param {NextFunction} next - */ - private async build(req: Request, res: Response, next: Function) { - const { tenantId, user } = req; - const buildDTO = this.matchedBodyData(req); - - try { - const result = await this.organizationService.buildRunJob( - tenantId, - buildDTO, - user - ); - return res.status(200).send({ - type: 'success', - code: 'ORGANIZATION.DATABASE.INITIALIZED', - message: 'The organization database has been initialized.', - data: result, - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the current organization of the associated authenticated user. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async currentOrganization( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const organization = await this.organizationService.currentOrganization( - tenantId - ); - return res.status(200).send({ - organization: this.transfromToResponse(organization), - }); - } catch (error) { - next(error); - } - } - - /** - * Update the organization information. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - private async updateOrganization( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const tenantDTO = this.matchedBodyData(req, { includeOptionals: false }); - - try { - await this.organizationService.updateOrganization(tenantId, tenantDTO); - - return res.status(200).send( - this.transfromToResponse({ - tenantId, - message: 'Organization information has been updated successfully.', - }) - ); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'tenant_not_found') { - return res.status(400).send({ - errors: [{ type: 'TENANT.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'TENANT_ALREADY_BUILT') { - return res.status(400).send({ - errors: [{ type: 'TENANT_ALREADY_BUILT', code: 200 }], - }); - } - if (error.errorType === 'TENANT_IS_BUILDING') { - return res.status(400).send({ - errors: [{ type: 'TENANT_IS_BUILDING', code: 300 }], - }); - } - if (error.errorType === 'BASE_CURRENCY_MUTATE_LOCKED') { - return res.status(400).send({ - errors: [{ type: 'BASE_CURRENCY_MUTATE_LOCKED', code: 400 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/OrganizationDashboard.ts b/packages/server/src/api/controllers/OrganizationDashboard.ts deleted file mode 100644 index 6b38b8e0b..000000000 --- a/packages/server/src/api/controllers/OrganizationDashboard.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import BaseController from '@/api/controllers/BaseController'; -import OrganizationService from '../../services/Organization/OrganizationService'; -import OrganizationUpgrade from '../../services/Organization/OrganizationUpgrade'; -import { ServiceError } from '../../exceptions'; - -@Service() -export default class OrganizationDashboardController extends BaseController { - @Inject() - organizationService: OrganizationService; - - @Inject() - organizationUpgrade: OrganizationUpgrade; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/base_currency_mutate', - this.baseCurrencyMutateAbility.bind(this) - ); - router.post( - '/upgrade', - this.validationResult, - this.asyncMiddleware(this.upgradeOrganization), - this.handleServiceErrors - ); - return router; - } - - /** - * Detarmines whether the current authed organization to able to change its currency/. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response|void} - */ - private async baseCurrencyMutateAbility( - req: Request, - res: Response, - next: Function - ): Promise { - const { tenantId } = req; - - try { - const abilities = - await this.organizationService.mutateBaseCurrencyAbility(tenantId); - - return res.status(200).send({ abilities }); - } catch (error) { - next(error); - } - } - - /** - * Upgrade the authenticated organization. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - * @returns {Response} - */ - public upgradeOrganization = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - // Upgrade organization database. - const { jobId } = await this.organizationUpgrade.upgrade(tenantId); - - return res.status(200).send({ - job_id: jobId, - message: 'The organization has been upgraded successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Handle service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - private handleServiceErrors = ( - error, - req: Request, - res: Response, - next: NextFunction - ) => { - if (error instanceof ServiceError) { - if (error.errorType === 'TENANT_DATABASE_UPGRADED') { - return res.status(400).send({ - errors: [ - { - type: 'TENANT_DATABASE_UPGRADED', - message: 'Organization database is already upgraded.', - }, - ], - }); - } - if (error.errorType === 'TENANT_UPGRADE_IS_RUNNING') { - return res.status(200).send({ - errors: [ - { - type: 'TENANT_UPGRADE_IS_RUNNING', - message: 'Organization database upgrade is running.', - }, - ], - }); - } - } - next(error); - }; -} diff --git a/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts b/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts deleted file mode 100644 index 8d02eaffa..000000000 --- a/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { body, param } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { PaymentServicesApplication } from '@/services/PaymentServices/PaymentServicesApplication'; - -@Service() -export class PaymentServicesController extends BaseController { - @Inject() - private paymentServicesApp: PaymentServicesApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - asyncMiddleware(this.getPaymentServicesSpecificInvoice.bind(this)) - ); - router.get('/state', this.getPaymentMethodsState.bind(this)); - router.get('/:paymentServiceId', this.getPaymentService.bind(this)); - router.post( - '/:paymentMethodId', - [ - param('paymentMethodId').exists(), - - body('name').optional().isString(), - body('options.bank_account_id').optional().isNumeric(), - body('options.clearing_account_id').optional().isNumeric(), - ], - this.validationResult, - asyncMiddleware(this.updatePaymentMethod.bind(this)) - ); - router.delete( - '/:paymentMethodId', - [param('paymentMethodId').exists()], - this.validationResult, - this.deletePaymentMethod.bind(this) - ); - - return router; - } - - /** - * Retrieve accounts types list. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @return {Promise} - */ - private async getPaymentServicesSpecificInvoice( - req: Request<{ invoiceId: number }>, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const paymentServices = - await this.paymentServicesApp.getPaymentServicesForInvoice(tenantId); - - return res.status(200).send({ paymentServices }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves a specific payment service. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @param {NextFunction} next - Next function. - * @return {Promise} - */ - private async getPaymentService( - req: Request<{ paymentServiceId: number }>, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { paymentServiceId } = req.params; - - try { - const paymentService = await this.paymentServicesApp.getPaymentService( - tenantId, - paymentServiceId - ); - - return res.status(200).send({ data: paymentService }); - } catch (error) { - next(error); - } - } - - /** - * Edits the given payment method settings. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @return {Promise} - */ - private async updatePaymentMethod( - req: Request<{ paymentMethodId: number }>, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { paymentMethodId } = req.params; - const updatePaymentMethodDTO = this.matchedBodyData(req); - - try { - await this.paymentServicesApp.editPaymentMethod( - tenantId, - paymentMethodId, - updatePaymentMethodDTO - ); - return res.status(200).send({ - id: paymentMethodId, - message: 'The given payment method has been updated.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the payment state providing state. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @param {NextFunction} next - Next function. - * @return {Promise} - */ - private async getPaymentMethodsState( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const paymentMethodsState = - await this.paymentServicesApp.getPaymentMethodsState(tenantId); - - return res.status(200).send({ data: paymentMethodsState }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given payment method. - * @param {Request<{ paymentMethodId: number }>} req - Request. - * @param {Response} res - Response. - * @param {NextFunction} next - Next function. - * @return {Promise} - */ - private async deletePaymentMethod( - req: Request<{ paymentMethodId: number }>, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { paymentMethodId } = req.params; - - try { - await this.paymentServicesApp.deletePaymentMethod( - tenantId, - paymentMethodId - ); - return res.status(204).send({ - id: paymentMethodId, - message: 'The payment method has been deleted.', - }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/PdfTemplates/PdfTemplatesController.ts b/packages/server/src/api/controllers/PdfTemplates/PdfTemplatesController.ts deleted file mode 100644 index f78be6650..000000000 --- a/packages/server/src/api/controllers/PdfTemplates/PdfTemplatesController.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import BaseController from '@/api/controllers/BaseController'; -import { PdfTemplateApplication } from '@/services/PdfTemplate/PdfTemplateApplication'; - -@Service() -export class PdfTemplatesController extends BaseController { - @Inject() - public pdfTemplateApplication: PdfTemplateApplication; - - /** - * Router constructor method. - */ - public router() { - const router = Router(); - - router.delete( - '/:template_id', - [param('template_id').exists().isInt().toInt()], - this.validationResult, - this.deletePdfTemplate.bind(this) - ); - router.post( - '/:template_id', - [ - param('template_id').exists().isInt().toInt(), - check('template_name').exists(), - check('attributes').exists(), - ], - this.validationResult, - this.editPdfTemplate.bind(this) - ); - router.get('/state', this.getOrganizationBrandingState.bind(this)); - router.get( - '/', - [query('resource').optional()], - this.validationResult, - this.getPdfTemplates.bind(this) - ); - router.get( - '/:template_id', - [param('template_id').exists().isInt().toInt()], - this.validationResult, - this.getPdfTemplate.bind(this) - ); - router.post( - '/', - [ - check('template_name').exists(), - check('resource').exists(), - check('attributes').exists(), - ], - this.validationResult, - this.createPdfInvoiceTemplate.bind(this) - ); - router.post( - '/:template_id/assign_default', - [param('template_id').exists().isInt().toInt()], - this.validationResult, - this.assginPdfTemplateAsDefault.bind(this) - ); - return router; - } - - async createPdfInvoiceTemplate( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { templateName, resource, attributes } = this.matchedBodyData(req); - - try { - const result = await this.pdfTemplateApplication.createPdfTemplate( - tenantId, - templateName, - resource, - attributes - ); - return res.status(201).send({ - id: result.id, - message: 'The PDF template has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - async editPdfTemplate(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { template_id: templateId } = req.params; - const editTemplateDTO = this.matchedBodyData(req); - - try { - const result = await this.pdfTemplateApplication.editPdfTemplate( - tenantId, - Number(templateId), - editTemplateDTO - ); - return res.status(200).send({ - id: result.id, - message: 'The PDF template has been updated successfully.', - }); - } catch (error) { - next(error); - } - } - - async deletePdfTemplate(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { template_id: templateId } = req.params; - - try { - await this.pdfTemplateApplication.deletePdfTemplate( - tenantId, - Number(templateId) - ); - return res.status(204).send({ - id: templateId, - message: 'The PDF template has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - async getPdfTemplate(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { template_id: templateId } = req.params; - - try { - const template = await this.pdfTemplateApplication.getPdfTemplate( - tenantId, - Number(templateId) - ); - return res.status(200).send(template); - } catch (error) { - next(error); - } - } - - async getPdfTemplates(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const query = this.matchedQueryData(req); - - try { - const templates = await this.pdfTemplateApplication.getPdfTemplates( - tenantId, - query - ); - return res.status(200).send(templates); - } catch (error) { - next(error); - } - } - - async assginPdfTemplateAsDefault( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { template_id: templateId } = req.params; - - try { - await this.pdfTemplateApplication.assignPdfTemplateAsDefault( - tenantId, - Number(templateId) - ); - return res.status(204).send({ - id: templateId, - message: 'The given pdf template has been assigned as default template', - }); - } catch (error) { - next(error); - } - } - async getOrganizationBrandingState( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const data = - await this.pdfTemplateApplication.getPdfTemplateBrandingState(tenantId); - - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Ping.ts b/packages/server/src/api/controllers/Ping.ts deleted file mode 100644 index df199d8c2..000000000 --- a/packages/server/src/api/controllers/Ping.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Router, Request, Response } from 'express'; - -export default class Ping { - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/', - this.ping, - ); - return router; - } - - /** - * Handle the ping request. - * @param {Request} req - * @param {Response} res - */ - async ping(req: Request, res: Response) - { - return res.status(200).send({ - server: true, - }); - } -} \ No newline at end of file diff --git a/packages/server/src/api/controllers/Projects/Projects.ts b/packages/server/src/api/controllers/Projects/Projects.ts deleted file mode 100644 index 6953e322d..000000000 --- a/packages/server/src/api/controllers/Projects/Projects.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { AbilitySubject, IProjectStatus, ProjectAction } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ProjectsApplication } from '@/services/Projects/Projects/ProjectsApplication'; - -@Service() -export class ProjectsController extends BaseController { - @Inject() - private projectsApplication: ProjectsApplication; - - /** - * Router constructor method. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(ProjectAction.CREATE, AbilitySubject.Project), - [ - check('contact_id').exists(), - check('name').exists().trim(), - check('deadline').exists().isISO8601(), - check('cost_estimate').exists().isDecimal(), - ], - this.validationResult, - asyncMiddleware(this.createProject.bind(this)) - ); - router.post( - '/:id', - CheckPolicies(ProjectAction.EDIT, AbilitySubject.Project), - [ - param('id').exists().isInt().toInt(), - check('contact_id').exists(), - check('name').exists().trim(), - check('deadline').exists().isISO8601(), - check('cost_estimate').exists().isDecimal(), - ], - this.validationResult, - asyncMiddleware(this.editProject.bind(this)) - ); - router.patch( - '/:projectId/status', - CheckPolicies(ProjectAction.EDIT, AbilitySubject.Project), - [ - param('projectId').exists().isInt().toInt(), - check('status') - .exists() - .isIn([IProjectStatus.InProgress, IProjectStatus.Closed]), - ], - this.validationResult, - asyncMiddleware(this.editProject.bind(this)) - ); - router.get( - '/:id', - CheckPolicies(ProjectAction.VIEW, AbilitySubject.Project), - [param('id').exists().isInt().toInt()], - this.validationResult, - asyncMiddleware(this.getProject.bind(this)) - ); - router.get( - '/:projectId/billable/entries', - CheckPolicies(ProjectAction.VIEW, AbilitySubject.Project), - [ - param('projectId').exists().isInt().toInt(), - query('billable_type').optional().toArray(), - query('to_date').optional().isISO8601(), - ], - this.validationResult, - asyncMiddleware(this.projectBillableEntries.bind(this)) - ); - router.get( - '/', - CheckPolicies(ProjectAction.VIEW, AbilitySubject.Project), - [], - this.validationResult, - asyncMiddleware(this.getProjects.bind(this)) - ); - router.delete( - '/:id', - CheckPolicies(ProjectAction.DELETE, AbilitySubject.Project), - [param('id').exists().isInt().toInt()], - this.validationResult, - asyncMiddleware(this.deleteProject.bind(this)) - ); - return router; - } - - /** - * Creates a new project. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async createProject(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const projectDTO = this.matchedBodyData(req); - - try { - const account = await this.projectsApplication.createProject( - tenantId, - projectDTO - ); - return res.status(200).send({ - id: account.id, - message: 'The project has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit project details. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async editProject(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { projectId } = req.params; - - const editProjectDTO = this.matchedBodyData(req); - - try { - const account = await this.projectsApplication.editProjectStatus( - tenantId, - projectId, - editProjectDTO.status - ); - return res.status(200).send({ - id: account.id, - message: 'The project has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Get details of the given account. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async getProject(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: projectId } = req.params; - - try { - const project = await this.projectsApplication.getProject( - tenantId, - projectId - ); - return res.status(200).send({ project }); - } catch (error) { - next(error); - } - } - - /** - * Delete the given account. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async deleteProject(req: Request, res: Response, next: NextFunction) { - const { id: accountId } = req.params; - const { tenantId } = req; - - try { - await this.projectsApplication.deleteProject(tenantId, accountId); - - return res.status(200).send({ - id: accountId, - message: 'The deleted project has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve accounts datatable list. - * @param {Request} req - * @param {Response} res - * @param {Response} - */ - private async getProjects(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - // Filter query. - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - inactiveMode: false, - ...this.matchedQueryData(req), - }; - - try { - const projects = await this.projectsApplication.getProjects( - tenantId, - filter - ); - return res.status(200).send({ - projects, - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the given billable entries of the given project. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private projectBillableEntries = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { projectId } = req.params; - const query = this.matchedQueryData(req); - - try { - const billableEntries = - await this.projectsApplication.getProjectBillableEntries( - tenantId, - projectId, - query - ); - return res.status(200).send({ - billableEntries, - }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Projects/Tasks.ts b/packages/server/src/api/controllers/Projects/Tasks.ts deleted file mode 100644 index 4c6551b18..000000000 --- a/packages/server/src/api/controllers/Projects/Tasks.ts +++ /dev/null @@ -1,211 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { AbilitySubject, AccountAction } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { TasksApplication } from '@/services/Projects/Tasks/TasksApplication'; -import { ProjectTaskChargeType } from '@/services/Projects/Tasks/constants'; - -@Service() -export class ProjectTasksController extends BaseController { - @Inject() - private tasksApplication: TasksApplication; - - /** - * Router constructor method. - */ - router() { - const router = Router(); - - router.post( - '/projects/:projectId/tasks', - CheckPolicies(AccountAction.CREATE, AbilitySubject.Project), - [ - check('name').exists(), - check('charge_type') - .exists() - .trim() - .toUpperCase() - .isIn(Object.values(ProjectTaskChargeType)), - check('rate').exists(), - check('estimate_hours').exists(), - ], - this.validationResult, - asyncMiddleware(this.createTask.bind(this)), - this.catchServiceErrors - ); - router.post( - '/tasks/:taskId', - CheckPolicies(AccountAction.EDIT, AbilitySubject.Project), - [ - param('taskId').exists().isInt().toInt(), - check('name').exists(), - check('charge_type').exists().trim(), - check('rate').exists(), - check('estimate_hours').exists(), - ], - this.validationResult, - asyncMiddleware(this.editTask.bind(this)), - this.catchServiceErrors - ); - router.get( - '/tasks/:taskId', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Project), - [param('taskId').exists().isInt().toInt()], - this.validationResult, - asyncMiddleware(this.getTask.bind(this)), - this.catchServiceErrors - ); - router.get( - '/projects/:projectId/tasks', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Project), - [param('projectId').exists().isInt().toInt()], - this.validationResult, - asyncMiddleware(this.getTasks.bind(this)), - this.catchServiceErrors - ); - router.delete( - '/tasks/:taskId', - CheckPolicies(AccountAction.DELETE, AbilitySubject.Project), - [param('taskId').exists().isInt().toInt()], - this.validationResult, - asyncMiddleware(this.deleteTask.bind(this)), - this.catchServiceErrors - ); - return router; - } - - /** - * Creates a new project. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async createTask(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { projectId } = req.params; - const taskDTO = this.matchedBodyData(req); - - try { - const task = await this.tasksApplication.createTask( - tenantId, - projectId, - taskDTO - ); - return res.status(200).send({ - id: task.id, - message: 'The task has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit project details. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async editTask(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { taskId } = req.params; - - const editTaskDTO = this.matchedBodyData(req); - - try { - const task = await this.tasksApplication.editTask( - tenantId, - taskId, - editTaskDTO - ); - return res.status(200).send({ - id: task.id, - message: 'The task has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Get details of the given task. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async getTask(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { taskId } = req.params; - - try { - const task = await this.tasksApplication.getTask(tenantId, taskId); - - return res.status(200).send({ task }); - } catch (error) { - next(error); - } - } - - /** - * Delete the given task. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async deleteTask(req: Request, res: Response, next: NextFunction) { - const { taskId } = req.params; - const { tenantId } = req; - - try { - await this.tasksApplication.deleteTask(tenantId, taskId); - - return res.status(200).send({ - id: taskId, - message: 'The deleted task has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve accounts datatable list. - * @param {Request} req - * @param {Response} res - * @param {Response} - */ - public async getTasks(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { projectId } = req.params; - - try { - const tasks = await this.tasksApplication.getTasks(tenantId, projectId); - - return res.status(200).send({ tasks }); - } catch (error) { - next(error); - } - } - - /** - * Transforms service errors to response. - * @param {Error} - * @param {Request} req - * @param {Response} res - * @param {ServiceError} error - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Projects/Times.ts b/packages/server/src/api/controllers/Projects/Times.ts deleted file mode 100644 index a74edcf48..000000000 --- a/packages/server/src/api/controllers/Projects/Times.ts +++ /dev/null @@ -1,253 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import { AbilitySubject, AccountAction } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { TimesApplication } from '@/services/Projects/Times/TimesApplication'; - -@Service() -export class ProjectTimesController extends BaseController { - @Inject() - private timesApplication: TimesApplication; - - /** - * Router constructor method. - */ - router() { - const router = Router(); - - router.post( - '/projects/tasks/:taskId/times', - CheckPolicies(AccountAction.CREATE, AbilitySubject.Project), - [ - param('taskId').exists().isInt().toInt(), - check('duration').exists().isDecimal(), - check('description').exists().trim(), - check('date').exists().isISO8601(), - ], - this.validationResult, - asyncMiddleware(this.createTime.bind(this)), - this.catchServiceErrors - ); - router.post( - '/projects/times/:timeId', - CheckPolicies(AccountAction.EDIT, AbilitySubject.Project), - [ - param('timeId').exists().isInt().toInt(), - check('duration').exists().isDecimal(), - check('description').exists().trim(), - check('date').exists().isISO8601(), - ], - this.validationResult, - asyncMiddleware(this.editTime.bind(this)), - this.catchServiceErrors - ); - router.get( - '/projects/times/:timeId', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Project), - [ - param('timeId').exists().isInt().toInt(), - ], - this.validationResult, - asyncMiddleware(this.getTime.bind(this)), - this.catchServiceErrors - ); - router.get( - '/projects/:projectId/times', - CheckPolicies(AccountAction.VIEW, AbilitySubject.Project), - [ - param('projectId').exists().isInt().toInt(), - ], - this.validationResult, - asyncMiddleware(this.getTimeline.bind(this)), - this.catchServiceErrors - ); - router.delete( - '/projects/times/:timeId', - CheckPolicies(AccountAction.DELETE, AbilitySubject.Project), - [ - param('timeId').exists().isInt().toInt(), - ], - this.validationResult, - asyncMiddleware(this.deleteTime.bind(this)), - this.catchServiceErrors - ); - return router; - } - - /** - * Project create DTO Schema validation. - */ - get createTimeDTOSchema() { - return []; - } - - /** - * Project edit DTO Schema validation. - */ - get editProjectDTOSchema() { - return [ - check('contact_id').exists(), - check('name').exists().trim(), - check('deadline').exists({ nullable: true }).isISO8601(), - check('cost_estimate').exists().isDecimal(), - ]; - } - - get accountParamSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Accounts list validation schema. - */ - get accountsListSchema() { - return [ - query('view_slug').optional({ nullable: true }).isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('inactive_mode').optional().isBoolean().toBoolean(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Creates a new project. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - async createTime(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { taskId } = req.params; - const taskDTO = this.matchedBodyData(req); - - try { - const task = await this.timesApplication.createTime( - tenantId, - taskId, - taskDTO - ); - return res.status(200).send({ - id: task.id, - message: 'The time entry has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit project details. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async editTime(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { timeId } = req.params; - - const editTaskDTO = this.matchedBodyData(req); - - try { - const task = await this.timesApplication.editTime( - tenantId, - timeId, - editTaskDTO - ); - return res.status(200).send({ - id: task.id, - message: 'The task has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Get details of the given task. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async getTime(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { timeId } = req.params; - - try { - const timeEntry = await this.timesApplication.getTime(tenantId, timeId); - - return res.status(200).send({ timeEntry }); - } catch (error) { - next(error); - } - } - - /** - * Delete the given task. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - async deleteTime(req: Request, res: Response, next: NextFunction) { - const { timeId } = req.params; - const { tenantId } = req; - - try { - await this.timesApplication.deleteTime(tenantId, timeId); - - return res.status(200).send({ - id: timeId, - message: 'The deleted task has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve accounts datatable list. - * @param {Request} req - * @param {Response} res - * @param {Response} - */ - public async getTimeline(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { projectId } = req.params; - - try { - const timeline = await this.timesApplication.getTimeline( - tenantId, - projectId - ); - - return res.status(200).send({ timeline }); - } catch (error) { - next(error); - } - } - - /** - * Transforms service errors to response. - * @param {Error} - * @param {Request} req - * @param {Response} res - * @param {ServiceError} error - */ - private catchServiceErrors( - error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Purchases/Bills.ts b/packages/server/src/api/controllers/Purchases/Bills.ts deleted file mode 100644 index ec901247e..000000000 --- a/packages/server/src/api/controllers/Purchases/Bills.ts +++ /dev/null @@ -1,599 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { - AbilitySubject, - BillAction, - DiscountType, - IBillDTO, - IBillEditDTO, -} from '@/interfaces'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { BillsApplication } from '@/services/Purchases/Bills/BillsApplication'; - -@Service() -export default class BillsController extends BaseController { - @Inject() - private billsApplication: BillsApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(BillAction.Create, AbilitySubject.Bill), - [...this.billValidationSchema], - this.validationResult, - asyncMiddleware(this.newBill.bind(this)), - this.handleServiceError - ); - router.post( - '/:id/open', - CheckPolicies(BillAction.Edit, AbilitySubject.Bill), - [...this.specificBillValidationSchema], - this.validationResult, - asyncMiddleware(this.openBill.bind(this)), - this.handleServiceError - ); - router.post( - '/:id', - CheckPolicies(BillAction.Edit, AbilitySubject.Bill), - [...this.billEditValidationSchema, ...this.specificBillValidationSchema], - this.validationResult, - asyncMiddleware(this.editBill.bind(this)), - this.handleServiceError - ); - router.get( - '/due', - CheckPolicies(BillAction.View, AbilitySubject.Bill), - [...this.dueBillsListingValidationSchema], - this.validationResult, - asyncMiddleware(this.getDueBills.bind(this)), - this.handleServiceError - ); - router.get( - '/:id', - CheckPolicies(BillAction.View, AbilitySubject.Bill), - [...this.specificBillValidationSchema], - this.validationResult, - asyncMiddleware(this.getBill.bind(this)), - this.handleServiceError - ); - router.get( - '/:id/payment-transactions', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getBillPaymentsTransactions), - this.handleServiceError - ); - router.get( - '/', - CheckPolicies(BillAction.View, AbilitySubject.Bill), - [...this.billsListingValidationSchema], - this.validationResult, - asyncMiddleware(this.billsList.bind(this)), - this.handleServiceError, - this.dynamicListService.handlerErrorsToResponse - ); - router.delete( - '/:id', - CheckPolicies(BillAction.Delete, AbilitySubject.Bill), - [...this.specificBillValidationSchema], - this.validationResult, - asyncMiddleware(this.deleteBill.bind(this)), - this.handleServiceError - ); - return router; - } - - /** - * Common validation schema. - */ - private get billValidationSchema() { - return [ - check('bill_number').exists().trim(), - check('reference_no').optional().trim(), - check('bill_date').exists().isISO8601(), - check('due_date').optional().isISO8601(), - - check('vendor_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - check('project_id').optional({ nullable: true }).isNumeric().toInt(), - - check('note').optional().trim(), - check('open').default(false).isBoolean().toBoolean(), - - check('is_inclusive_tax').default(false).isBoolean().toBoolean(), - - check('entries').isArray({ min: 1 }), - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.landed_cost') - .optional({ nullable: true }) - .isBoolean() - .toBoolean(), - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - check('entries.*.tax_code') - .optional({ nullable: true }) - .trim() - .isString(), - check('entries.*.tax_rate_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - // Attachments - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // # Discount - check('discount_type') - .default(DiscountType.Amount) - .isIn([DiscountType.Amount, DiscountType.Percentage]), - check('discount').optional({ nullable: true }).isDecimal().toFloat(), - - // # Adjustment - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Common validation schema. - */ - private get billEditValidationSchema() { - return [ - check('bill_number').optional().trim(), - check('reference_no').optional().trim(), - check('bill_date').exists().isISO8601(), - check('due_date').optional().isISO8601(), - - check('vendor_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - check('project_id').optional({ nullable: true }).isNumeric().toInt(), - - check('note').optional().trim(), - check('open').default(false).isBoolean().toBoolean(), - - check('entries').isArray({ min: 1 }), - - check('entries.*.id').optional().isNumeric().toInt(), - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.landed_cost') - .optional({ nullable: true }) - .isBoolean() - .toBoolean(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // # Discount - check('discount_type') - .default(DiscountType.Amount) - .isIn([DiscountType.Amount, DiscountType.Percentage]), - check('discount').optional({ nullable: true }).isDecimal().toFloat(), - - // # Adjustment - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Bill validation schema. - */ - private get specificBillValidationSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Bills list validation schema. - */ - private get billsListingValidationSchema() { - return [ - query('view_slug').optional().isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - private get dueBillsListingValidationSchema() { - return [ - query('vendor_id').optional().trim(), - query('payment_made_id').optional().trim(), - ]; - } - - /** - * Creates a new bill and records journal transactions. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - private async newBill(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const billDTO: IBillDTO = this.matchedBodyData(req); - - try { - const storedBill = await this.billsApplication.createBill( - tenantId, - billDTO, - user - ); - return res.status(200).send({ - id: storedBill.id, - message: 'The bill has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit bill details with associated entries and rewrites journal transactions. - * @param {Request} req - * @param {Response} res - */ - private async editBill(req: Request, res: Response, next: NextFunction) { - const { id: billId } = req.params; - const { tenantId, user } = req; - const billDTO: IBillEditDTO = this.matchedBodyData(req); - - try { - await this.billsApplication.editBill(tenantId, billId, billDTO, user); - - return res.status(200).send({ - id: billId, - message: 'The bill has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Open the given bill. - * @param {Request} req - - * @param {Response} res - - */ - private async openBill(req: Request, res: Response, next: NextFunction) { - const { id: billId } = req.params; - const { tenantId } = req; - - try { - await this.billsApplication.openBill(tenantId, billId); - - return res.status(200).send({ - id: billId, - message: 'The bill has been opened successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the given bill details with associated item entries. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async getBill(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { id: billId } = req.params; - - try { - const bill = await this.billsApplication.getBill(tenantId, billId); - - return res.status(200).send({ bill }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given bill with associated entries and journal transactions. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - private async deleteBill(req: Request, res: Response, next: NextFunction) { - const billId = req.params.id; - const { tenantId } = req; - - try { - await this.billsApplication.deleteBill(tenantId, billId); - - return res.status(200).send({ - id: billId, - message: 'The given bill deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Listing bills with pagination meta. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - private async billsList(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = { - page: 1, - pageSize: 12, - sortOrder: 'desc', - columnSortBy: 'created_at', - ...this.matchedQueryData(req), - }; - - try { - const billsWithPagination = await this.billsApplication.getBills( - tenantId, - filter - ); - return res.status(200).send(billsWithPagination); - } catch (error) { - next(error); - } - } - - /** - * Listing all due bills of the given vendor. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getDueBills(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { vendorId } = this.matchedQueryData(req); - - try { - const bills = await this.billsApplication.getDueBills(tenantId, vendorId); - - return res.status(200).send({ bills }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve payments transactions of specific bill. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getBillPaymentsTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: billId } = req.params; - - try { - const billPayments = await this.billsApplication.getBillPayments( - tenantId, - billId - ); - return res.status(200).send({ - data: billPayments, - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceError( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'BILL_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'BILL_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'BILL_NUMBER_EXISTS') { - return res.status(400).send({ - errors: [{ type: 'BILL.NUMBER.EXISTS', code: 500 }], - }); - } - if (error.errorType === 'BILL_VENDOR_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'BILL_VENDOR_NOT_FOUND', code: 600 }], - }); - } - if (error.errorType === 'BILL_ITEMS_NOT_PURCHASABLE') { - return res.status(400).send({ - errors: [{ type: 'BILL_ITEMS_NOT_PURCHASABLE', code: 700 }], - }); - } - if (error.errorType === 'NOT_PURCHASE_ABLE_ITEMS') { - return res.status(400).send({ - errors: [{ type: 'NOT_PURCHASE_ABLE_ITEMS', code: 800 }], - }); - } - if (error.errorType === 'BILL_ITEMS_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ITEMS.IDS.NOT.FOUND', code: 400 }], - }); - } - if (error.errorType === 'BILL_ENTRIES_IDS_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'BILL_ENTRIES_IDS_NOT_FOUND', code: 900 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS_NOT_FOUND', code: 1000 }], - }); - } - if (error.errorType === 'BILL_ALREADY_OPEN') { - return res.boom.badRequest(null, { - errors: [{ type: 'BILL_ALREADY_OPEN', code: 1100 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'VENDOR_NOT_FOUND', - message: 'Vendor not found.', - code: 1200, - }, - ], - }); - } - if (error.errorType === 'BILL_HAS_ASSOCIATED_PAYMENT_ENTRIES') { - return res.status(400).send({ - errors: [ - { - type: 'BILL_HAS_ASSOCIATED_PAYMENT_ENTRIES', - message: - 'Cannot delete bill that has associated payment transactions.', - code: 1200, - }, - ], - }); - } - if (error.errorType === 'BILL_HAS_ASSOCIATED_LANDED_COSTS') { - return res.status(400).send({ - errors: [ - { - type: 'BILL_HAS_ASSOCIATED_LANDED_COSTS', - message: - 'Cannot delete bill that has associated landed cost transactions.', - code: 1300, - }, - ], - }); - } - if (error.errorType === 'ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED') { - return res.status(400).send({ - errors: [ - { - type: 'ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED', - code: 1400, - message: - 'Bill entries that have landed cost type can not be deleted.', - }, - ], - }); - } - if ( - error.errorType === 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES' - ) { - return res.status(400).send({ - errors: [ - { - type: 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES', - code: 1500, - }, - ], - }); - } - if (error.errorType === 'LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS') { - return res.status(400).send({ - errors: [ - { - type: 'LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS', - message: - 'Landed cost entries should be only with inventory items.', - code: 1600, - }, - ], - }); - } - if (error.errorType === 'BILL_HAS_APPLIED_TO_VENDOR_CREDIT') { - return res.status(400).send({ - errors: [{ type: 'BILL_HAS_APPLIED_TO_VENDOR_CREDIT', code: 1700 }], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND', code: 1800 }], - }); - } - if (error.errorType === 'ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND', code: 1900 }], - }); - } - if (error.errorType === 'BILL_AMOUNT_SMALLER_THAN_PAID_AMOUNT') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'BILL_AMOUNT_SMALLER_THAN_PAID_AMOUNT', - code: 2000, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Purchases/BillsPayments.ts b/packages/server/src/api/controllers/Purchases/BillsPayments.ts deleted file mode 100644 index b02f3d530..000000000 --- a/packages/server/src/api/controllers/Purchases/BillsPayments.ts +++ /dev/null @@ -1,469 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import { check, param, query, ValidationChain } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { ServiceError } from '@/exceptions'; -import BaseController from '@/api/controllers/BaseController'; -import { BillPaymentsApplication } from '@/services/Purchases/BillPayments/BillPaymentsApplication'; -import BillPaymentsPages from '@/services/Purchases/BillPayments/BillPaymentsPages'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, IPaymentMadeAction } from '@/interfaces'; - -/** - * Bills payments controller. - * @service - */ -@Service() -export default class BillsPayments extends BaseController { - @Inject() - private billPaymentsApplication: BillPaymentsApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private billPaymentsPages: BillPaymentsPages; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(IPaymentMadeAction.Create, AbilitySubject.PaymentMade), - [...this.billPaymentSchemaValidation], - this.validationResult, - asyncMiddleware(this.createBillPayment.bind(this)), - this.handleServiceError - ); - router.post( - '/:id', - CheckPolicies(IPaymentMadeAction.Edit, AbilitySubject.PaymentMade), - [ - ...this.billPaymentSchemaValidation, - ...this.specificBillPaymentValidateSchema, - ], - this.validationResult, - asyncMiddleware(this.editBillPayment.bind(this)), - this.handleServiceError - ); - router.delete( - '/:id', - CheckPolicies(IPaymentMadeAction.Delete, AbilitySubject.PaymentMade), - [...this.specificBillPaymentValidateSchema], - this.validationResult, - asyncMiddleware(this.deleteBillPayment.bind(this)), - this.handleServiceError - ); - router.get( - '/new-page/entries', - CheckPolicies(IPaymentMadeAction.View, AbilitySubject.PaymentMade), - [query('vendor_id').exists()], - this.validationResult, - asyncMiddleware(this.getBillPaymentNewPageEntries.bind(this)), - this.handleServiceError - ); - router.get( - '/:id/edit-page', - CheckPolicies(IPaymentMadeAction.View, AbilitySubject.PaymentMade), - this.specificBillPaymentValidateSchema, - this.validationResult, - asyncMiddleware(this.getBillPaymentEditPage.bind(this)), - this.handleServiceError - ); - router.get( - '/:id/bills', - CheckPolicies(IPaymentMadeAction.View, AbilitySubject.PaymentMade), - this.specificBillPaymentValidateSchema, - this.validationResult, - asyncMiddleware(this.getPaymentBills.bind(this)), - this.handleServiceError - ); - router.get( - '/:id', - CheckPolicies(IPaymentMadeAction.View, AbilitySubject.PaymentMade), - this.specificBillPaymentValidateSchema, - this.validationResult, - asyncMiddleware(this.getBillPayment.bind(this)), - this.handleServiceError - ); - router.get( - '/', - CheckPolicies(IPaymentMadeAction.View, AbilitySubject.PaymentMade), - this.listingValidationSchema, - this.validationResult, - asyncMiddleware(this.getBillsPayments.bind(this)), - this.handleServiceError, - this.dynamicListService.handlerErrorsToResponse - ); - return router; - } - - /** - * Bill payments schema validation. - * @return {ValidationChain[]} - */ - private get billPaymentSchemaValidation(): ValidationChain[] { - return [ - check('vendor_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('amount').exists().isNumeric().toFloat(), - check('payment_account_id').exists().isNumeric().toInt(), - check('payment_number').optional({ nullable: true }).trim(), - check('payment_date').exists(), - check('statement').optional().trim(), - check('reference').optional().trim(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').exists().isArray(), - check('entries.*.index').optional().isNumeric().toInt(), - check('entries.*.bill_id').exists().isNumeric().toInt(), - check('entries.*.payment_amount').exists().isNumeric().toFloat(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - ]; - } - - /** - * Specific bill payment schema validation. - * @returns {ValidationChain[]} - */ - private get specificBillPaymentValidateSchema(): ValidationChain[] { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Bills payment list validation schema. - * @returns {ValidationChain[]} - */ - private get listingValidationSchema(): ValidationChain[] { - return [ - query('custom_view_id').optional().isNumeric().toInt(), - query('stringified_filter_roles').optional().isJSON(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Retrieve bill payment new page entries. - * @param {Request} req - - * @param {Response} res - - */ - private async getBillPaymentNewPageEntries(req: Request, res: Response) { - const { tenantId } = req; - const { vendorId } = this.matchedQueryData(req); - - const entries = await this.billPaymentsPages.getNewPageEntries( - tenantId, - vendorId - ); - return res.status(200).send({ entries }); - } - - /** - * Retrieve the bill payment edit page details. - * @param {Request} req - * @param {Response} res - */ - private async getBillPaymentEditPage( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - - try { - const billPaymentsWithEditEntries = - await this.billPaymentsPages.getBillPaymentEditPage( - tenantId, - paymentReceiveId - ); - return res.status(200).send(billPaymentsWithEditEntries); - } catch (error) { - next(error); - } - } - - /** - * Creates a bill payment. - * @async - * @param {Request} req - * @param {Response} res - * @param {Response} res - */ - private async createBillPayment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const billPaymentDTO = this.matchedBodyData(req); - - try { - const billPayment = await this.billPaymentsApplication.createBillPayment( - tenantId, - billPaymentDTO - ); - return res.status(200).send({ - id: billPayment.id, - message: 'Payment made has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edits the given bill payment details. - * @param {Request} req - * @param {Response} res - */ - private async editBillPayment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const billPaymentDTO = this.matchedBodyData(req); - const { id: billPaymentId } = req.params; - - try { - const paymentMade = await this.billPaymentsApplication.editBillPayment( - tenantId, - billPaymentId, - billPaymentDTO - ); - return res.status(200).send({ - id: paymentMade.id, - message: 'Payment made has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the bill payment and revert the journal - * transactions with accounts balance. - * @param {Request} req - - * @param {Response} res - - * @return {Response} res - - */ - private async deleteBillPayment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: billPaymentId } = req.params; - - try { - await this.billPaymentsApplication.deleteBillPayment( - tenantId, - billPaymentId - ); - - return res.status(200).send({ - id: billPaymentId, - message: 'Payment made has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the bill payment. - * @param {Request} req - * @param {Response} res - */ - private async getBillPayment( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: billPaymentId } = req.params; - - try { - const billPayment = await this.billPaymentsApplication.getBillPayment( - tenantId, - billPaymentId - ); - return res.status(200).send({ billPayment }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve associated bills for the given payment made. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getPaymentBills( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: billPaymentId } = req.params; - - try { - const bills = await this.billPaymentsApplication.getPaymentBills( - tenantId, - billPaymentId - ); - return res.status(200).send({ bills }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve bills payments listing with pagination metadata. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - private async getBillsPayments( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const billPaymentsFilter = { - page: 1, - pageSize: 12, - filterRoles: [], - sortOrder: 'desc', - columnSortBy: 'created_at', - ...this.matchedQueryData(req), - }; - - try { - const billPaymentsWithPagination = - await this.billPaymentsApplication.getBillPayments( - tenantId, - billPaymentsFilter - ); - return res.status(200).send(billPaymentsWithPagination); - } catch (error) { - next(error); - } - } - - /** - * Handle service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceError( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'PAYMENT_MADE_NOT_FOUND') { - return res.status(404).send({ - message: 'Payment made not found.', - errors: [{ type: 'BILL_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'VENDOR_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'BILL.PAYMENT.VENDOR.NOT.FOUND', code: 200 }], - }); - } - if (error.errorType === 'PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE') { - return res.status(400).send({ - errors: [ - { type: 'PAYMENT_ACCOUNT.NOT.CURRENT_ASSET.TYPE', code: 300 }, - ], - }); - } - if (error.errorType === 'BILL_PAYMENT_NUMBER_NOT_UNQIUE') { - return res.status(400).send({ - errors: [{ type: 'PAYMENT.NUMBER.NOT.UNIQUE', code: 400 }], - }); - } - if (error.errorType === 'PAYMENT_ACCOUNT_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'PAYMENT.ACCOUNT.NOT.FOUND', code: 500 }], - }); - } - if (error.errorType === 'PAYMENT_ACCOUNT_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'PAYMENT.ACCOUNT.NOT.FOUND', code: 600 }], - }); - } - if (error.errorType === '') { - return res.status(400).send({ - errors: [{ type: 'BILLS.IDS.NOT.EXISTS', code: 700 }], - }); - } - if (error.errorType === 'BILL_PAYMENT_ENTRIES_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ENTEIES.IDS.NOT.FOUND', code: 800 }], - }); - } - if (error.errorType === 'INVALID_BILL_PAYMENT_AMOUNT') { - return res.status(400).send({ - errors: [{ type: 'INVALID_BILL_PAYMENT_AMOUNT', code: 900 }], - }); - } - if (error.errorType === 'BILL_ENTRIES_IDS_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'BILLS_NOT_FOUND', code: 1000 }], - }); - } - if (error.errorType === 'PAYMENT_NUMBER_SHOULD_NOT_MODIFY') { - return res.status(400).send({ - errors: [{ type: 'PAYMENT_NUMBER_SHOULD_NOT_MODIFY', code: 1100 }], - }); - } - if (error.errorType === 'BILLS_NOT_OPENED_YET') { - return res.status(400).send({ - errors: [ - { - type: 'BILLS_NOT_OPENED_YET', - message: 'The given bills are not opened yet.', - code: 1200, - }, - ], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'WITHDRAWAL_ACCOUNT_CURRENCY_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'WITHDRAWAL_ACCOUNT_CURRENCY_INVALID', code: 1300 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Purchases/LandedCost.ts b/packages/server/src/api/controllers/Purchases/LandedCost.ts deleted file mode 100644 index 4cb086d6f..000000000 --- a/packages/server/src/api/controllers/Purchases/LandedCost.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import BillAllocatedCostTransactions from '@/services/Purchases/LandedCost/BillAllocatedLandedCostTransactions'; -import BaseController from '../BaseController'; -import AllocateLandedCost from '@/services/Purchases/LandedCost/AllocateLandedCost'; -import RevertAllocatedLandedCost from '@/services/Purchases/LandedCost/RevertAllocatedLandedCost'; -import LandedCostTranasctions from '@/services/Purchases/LandedCost/LandedCostTransactions'; - -@Service() -export default class BillAllocateLandedCost extends BaseController { - @Inject() - allocateLandedCost: AllocateLandedCost; - - @Inject() - billAllocatedCostTransactions: BillAllocatedCostTransactions; - - @Inject() - revertAllocatedLandedCost: RevertAllocatedLandedCost; - - @Inject() - landedCostTranasctions: LandedCostTranasctions; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/bills/:billId/allocate', - [ - check('transaction_id').exists().isInt(), - check('transaction_type').exists().isIn(['Expense', 'Bill']), - check('transaction_entry_id').exists().isInt(), - - check('allocation_method').exists().isIn(['value', 'quantity']), - check('description').optional({ nullable: true }), - - check('items').isArray({ min: 1 }), - check('items.*.entry_id').isInt(), - check('items.*.cost').isDecimal(), - ], - this.validationResult, - this.calculateLandedCost, - this.handleServiceErrors - ); - router.delete( - '/:allocatedLandedCostId', - [param('allocatedLandedCostId').exists().isInt()], - this.validationResult, - this.deleteAllocatedLandedCost, - this.handleServiceErrors - ); - router.get( - '/transactions', - [query('transaction_type').exists().isIn(['Expense', 'Bill'])], - this.validationResult, - this.getLandedCostTransactions, - this.handleServiceErrors - ); - router.get( - '/bills/:billId/transactions', - [param('billId').exists()], - this.validationResult, - this.getBillLandedCostTransactions, - this.handleServiceErrors - ); - return router; - } - - /** - * Retrieve the landed cost transactions of the given query. - * @param {Request} req - Request - * @param {Response} res - Response. - * @param {NextFunction} next - Next function. - */ - private getLandedCostTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const query = this.matchedQueryData(req); - - try { - const transactions = - await this.landedCostTranasctions.getLandedCostTransactions( - tenantId, - query - ); - - return res.status(200).send({ transactions }); - } catch (error) { - next(error); - } - }; - - /** - * Allocate landed cost. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public calculateLandedCost = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { billId: purchaseInvoiceId } = req.params; - const landedCostDTO = this.matchedBodyData(req); - - try { - const billLandedCost = await this.allocateLandedCost.allocateLandedCost( - tenantId, - landedCostDTO, - purchaseInvoiceId - ); - return res.status(200).send({ - id: billLandedCost.id, - message: 'The items cost are located successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the allocated landed cost. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public deleteAllocatedLandedCost = async ( - req: Request, - res: Response, - next: NextFunction - ): Promise => { - const { tenantId } = req; - const { allocatedLandedCostId } = req.params; - - try { - await this.revertAllocatedLandedCost.deleteAllocatedLandedCost( - tenantId, - allocatedLandedCostId - ); - - return res.status(200).send({ - id: allocatedLandedCostId, - message: 'The allocated landed cost are delete successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the list unlocated landed costs. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public listLandedCosts = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const query = this.matchedQueryData(req); - const { tenantId } = req; - - try { - const transactions = - await this.landedCostTranasctions.getLandedCostTransactions( - tenantId, - query - ); - - return res.status(200).send({ transactions }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the bill landed cost transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public getBillLandedCostTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ): Promise => { - const { tenantId } = req; - const { billId } = req.params; - - try { - const transactions = - await this.billAllocatedCostTransactions.getBillLandedCostTransactions( - tenantId, - billId - ); - - return res.status(200).send({ - billId, - transactions: this.transfromToResponse(transactions), - }); - } catch (error) { - next(error); - } - }; - - /** - * Handle service errors. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @param {Error} error - */ - public handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'BILL_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'BILL_NOT_FOUND', - message: 'The give bill id not found.', - code: 100, - }, - ], - }); - } - if (error.errorType === 'LANDED_COST_TRANSACTION_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'LANDED_COST_TRANSACTION_NOT_FOUND', - message: 'The given landed cost transaction id not found.', - code: 200, - }, - ], - }); - } - if (error.errorType === 'LANDED_COST_ENTRY_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'LANDED_COST_ENTRY_NOT_FOUND', - message: 'The given landed cost tranasction entry id not found.', - code: 300, - }, - ], - }); - } - if (error.errorType === 'COST_AMOUNT_BIGGER_THAN_UNALLOCATED_AMOUNT') { - return res.status(400).send({ - errors: [ - { - type: 'COST_AMOUNT_BIGGER_THAN_UNALLOCATED_AMOUNT', - code: 400, - }, - ], - }); - } - if (error.errorType === 'LANDED_COST_ITEMS_IDS_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'LANDED_COST_ITEMS_IDS_NOT_FOUND', - message: 'The given entries ids of purchase invoice not found.', - code: 500, - }, - ], - }); - } - if (error.errorType === 'BILL_LANDED_COST_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'BILL_LANDED_COST_NOT_FOUND', - message: 'The given bill located landed cost not found.', - code: 600, - }, - ], - }); - } - if (error.errorType === 'COST_TRASNACTION_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'COST_TRASNACTION_NOT_FOUND', code: 500 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Purchases/VendorCredit.ts b/packages/server/src/api/controllers/Purchases/VendorCredit.ts deleted file mode 100644 index dd8bdae7d..000000000 --- a/packages/server/src/api/controllers/Purchases/VendorCredit.ts +++ /dev/null @@ -1,680 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import { - AbilitySubject, - DiscountType, - IVendorCreditCreateDTO, - IVendorCreditEditDTO, - VendorCreditAction, -} from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import CreateVendorCredit from '@/services/Purchases/VendorCredits/CreateVendorCredit'; -import EditVendorCredit from '@/services/Purchases/VendorCredits/EditVendorCredit'; -import DeleteVendorCredit from '@/services/Purchases/VendorCredits/DeleteVendorCredit'; -import GetVendorCredit from '@/services/Purchases/VendorCredits/GetVendorCredit'; -import ListVendorCredits from '@/services/Purchases/VendorCredits/ListVendorCredits'; -import CreateRefundVendorCredit from '@/services/Purchases/VendorCredits/RefundVendorCredits/CreateRefundVendorCredit'; -import DeleteRefundVendorCredit from '@/services/Purchases/VendorCredits/RefundVendorCredits/DeleteRefundVendorCredit'; -import ListVendorCreditRefunds from '@/services/Purchases/VendorCredits/RefundVendorCredits/ListRefundVendorCredits'; -import OpenVendorCredit from '@/services/Purchases/VendorCredits/OpenVendorCredit'; -import GetRefundVendorCredit from '@/services/Purchases/VendorCredits/RefundVendorCredits/GetRefundVendorCredit'; - -@Service() -export default class VendorCreditController extends BaseController { - @Inject() - createVendorCreditService: CreateVendorCredit; - - @Inject() - editVendorCreditService: EditVendorCredit; - - @Inject() - deleteVendorCreditService: DeleteVendorCredit; - - @Inject() - getVendorCreditService: GetVendorCredit; - - @Inject() - listCreditNotesService: ListVendorCredits; - - @Inject() - tenancy: TenancyService; - - @Inject() - dynamicListService: DynamicListingService; - - @Inject() - createRefundCredit: CreateRefundVendorCredit; - - @Inject() - deleteRefundCredit: DeleteRefundVendorCredit; - - @Inject() - listRefundCredit: ListVendorCreditRefunds; - - @Inject() - openVendorCreditService: OpenVendorCredit; - - @Inject() - getRefundCredit: GetRefundVendorCredit; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(VendorCreditAction.Create, AbilitySubject.VendorCredit), - this.vendorCreditCreateDTOSchema, - this.validationResult, - this.asyncMiddleware(this.newVendorCredit), - this.handleServiceError - ); - router.post( - '/:id', - CheckPolicies(VendorCreditAction.Edit, AbilitySubject.VendorCredit), - this.vendorCreditEditDTOSchema, - this.validationResult, - this.asyncMiddleware(this.editVendorCredit), - this.handleServiceError - ); - router.get( - '/:id', - CheckPolicies(VendorCreditAction.View, AbilitySubject.VendorCredit), - [], - this.validationResult, - this.asyncMiddleware(this.getVendorCredit), - this.handleServiceError - ); - router.get( - '/', - CheckPolicies(VendorCreditAction.View, AbilitySubject.VendorCredit), - this.billsListingValidationSchema, - this.validationResult, - this.asyncMiddleware(this.getVendorCreditsList), - this.handleServiceError, - this.dynamicListService.handlerErrorsToResponse - ); - router.delete( - '/:id', - CheckPolicies(VendorCreditAction.Delete, AbilitySubject.VendorCredit), - this.deleteDTOValidationSchema, - this.validationResult, - this.asyncMiddleware(this.deleteVendorCredit), - this.handleServiceError - ); - router.post( - '/:id/open', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.openVendorCreditTransaction), - this.handleServiceError - ); - router.get( - '/:id/refund', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.vendorCreditRefundTransactions), - this.handleServiceError - ); - router.post( - '/:id/refund', - CheckPolicies(VendorCreditAction.Refund, AbilitySubject.VendorCredit), - this.vendorCreditRefundValidationSchema, - this.validationResult, - this.asyncMiddleware(this.refundVendorCredit), - this.handleServiceError - ); - router.get( - '/refunds/:refundId', - this.getRefundCreditTransactionSchema, - this.validationResult, - this.asyncMiddleware(this.getRefundCreditTransaction), - this.handleServiceError - ); - router.delete( - '/refunds/:refundId', - CheckPolicies(VendorCreditAction.Refund, AbilitySubject.VendorCredit), - this.deleteRefundVendorCreditSchema, - this.validationResult, - this.asyncMiddleware(this.deleteRefundVendorCredit), - this.handleServiceError - ); - return router; - } - - /** - * Common validation schema. - */ - get vendorCreditCreateDTOSchema() { - return [ - check('vendor_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('vendor_credit_number').optional({ nullable: true }).trim(), - check('reference_no').optional().trim(), - check('vendor_credit_date').exists().isISO8601().toDate(), - check('note').optional().trim(), - check('open').default(false).isBoolean().toBoolean(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').isArray({ min: 1 }), - - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // Discount. - check('discount').optional({ nullable: true }).isNumeric().toFloat(), - check('discount_type') - .optional({ nullable: true }) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - // Adjustment. - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Common validation schema. - */ - get vendorCreditEditDTOSchema() { - return [ - param('id').exists().isNumeric().toInt(), - - check('vendor_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('vendor_credit_number').optional({ nullable: true }).trim(), - check('reference_no').optional().trim(), - check('vendor_credit_date').exists().isISO8601().toDate(), - check('note').optional().trim(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').isArray({ min: 1 }), - check('entries.*.id').optional().isNumeric().toInt(), - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // Discount. - check('discount').optional({ nullable: true }).isNumeric().toFloat(), - check('discount_type') - .optional({ nullable: true }) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - // Adjustment. - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Bills list validation schema. - */ - get billsListingValidationSchema() { - return [ - query('view_slug').optional().isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * - */ - get deleteDTOValidationSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - get getRefundCreditTransactionSchema() { - return [param('refundId').exists().isNumeric().toInt()]; - } - - get deleteRefundVendorCreditSchema() { - return []; - } - - /** - * Refund vendor credit validation schema. - */ - get vendorCreditRefundValidationSchema() { - return [ - check('deposit_account_id').exists().isNumeric().toInt(), - check('description').exists(), - - check('amount').exists().isNumeric().toFloat(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('reference_no').optional(), - check('date').exists().isISO8601().toDate(), - - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - ]; - } - - /** - * Creates a new bill and records journal transactions. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - private newVendorCredit = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - const vendorCreditCreateDTO: IVendorCreditCreateDTO = - this.matchedBodyData(req); - - try { - const vendorCredit = await this.createVendorCreditService.newVendorCredit( - tenantId, - vendorCreditCreateDTO - ); - - return res.status(200).send({ - id: vendorCredit.id, - message: 'The vendor credit has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Edit bill details with associated entries and rewrites journal transactions. - * @param {Request} req - * @param {Response} res - */ - private editVendorCredit = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { id: vendorCreditId } = req.params; - const { tenantId, user } = req; - const vendorCreditEditDTO: IVendorCreditEditDTO = this.matchedBodyData(req); - - try { - await this.editVendorCreditService.editVendorCredit( - tenantId, - vendorCreditId, - vendorCreditEditDTO - ); - - return res.status(200).send({ - id: vendorCreditId, - message: 'The vendor credit has been edited successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the given bill details with associated item entries. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private getVendorCredit = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: billId } = req.params; - - try { - const data = await this.getVendorCreditService.getVendorCredit( - tenantId, - billId - ); - - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the given bill with associated entries and journal transactions. - * @param {Request} req - - * @param {Response} res - - * @return {Response} - */ - private deleteVendorCredit = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const vendorCreditId = req.params.id; - const { tenantId } = req; - - try { - await this.deleteVendorCreditService.deleteVendorCredit( - tenantId, - vendorCreditId - ); - - return res.status(200).send({ - id: vendorCreditId, - message: 'The given vendor credit has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve vendor credits list. - * @param req - * @param res - * @param next - * @returns - */ - private getVendorCreditsList = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - - try { - const { vendorCredits, pagination, filterMeta } = - await this.listCreditNotesService.getVendorCredits(tenantId, filter); - - return res.status(200).send({ vendorCredits, pagination, filterMeta }); - } catch (error) { - next(error); - } - }; - - /** - * Refunds vendor credit. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - private refundVendorCredit = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const refundDTO = this.matchedBodyData(req); - const { id: vendorCreditId } = req.params; - const { tenantId } = req; - - try { - const refundVendorCredit = await this.createRefundCredit.createRefund( - tenantId, - vendorCreditId, - refundDTO - ); - - return res.status(200).send({ - id: refundVendorCredit.id, - message: 'The vendor credit refund has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes refund vendor credit transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private deleteRefundVendorCredit = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { refundId: vendorCreditId } = req.params; - const { tenantId } = req; - - try { - await this.deleteRefundCredit.deleteRefundVendorCreditRefund( - tenantId, - vendorCreditId - ); - - return res.status(200).send({ - id: vendorCreditId, - message: 'The vendor credit refund has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve refunds transactions associated to vendor credit transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private vendorCreditRefundTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { id: vendorCreditId } = req.params; - const { tenantId } = req; - - try { - const transactions = await this.listRefundCredit.getVendorCreditRefunds( - tenantId, - vendorCreditId - ); - return res.status(200).send({ data: transactions }); - } catch (error) { - next(error); - } - }; - - /** - * Open vendor credit transaction. - * @param {Error} error - * @param {Request} req - * @param {Response} res - */ - private openVendorCreditTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { id: vendorCreditId } = req.params; - const { tenantId } = req; - - try { - await this.openVendorCreditService.openVendorCredit( - tenantId, - vendorCreditId - ); - - return res.status(200).send({ - id: vendorCreditId, - message: 'The vendor credit has been opened successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - * @returns - */ - private getRefundCreditTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { refundId } = req.params; - const { tenantId } = req; - - try { - const refundCredit = - await this.getRefundCredit.getRefundCreditTransaction( - tenantId, - refundId - ); - return res.status(200).send({ refundCredit }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceError( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'ENTRIES_ITEMS_IDS_NOT_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_ITEMS_IDS_NOT_EXISTS', code: 100 }], - }); - } - if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_IDS_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS_NOT_FOUND', code: 400 }], - }); - } - if (error.errorType === 'VENDOR_CREDIT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR_CREDIT_NOT_FOUND', code: 500 }], - }); - } - if (error.errorType === 'DEPOSIT_ACCOUNT_INVALID_TYPE') { - return res.boom.badRequest(null, { - errors: [{ type: 'DEPOSIT_ACCOUNT_INVALID_TYPE', code: 600 }], - }); - } - if (error.errorType === 'REFUND_VENDOR_CREDIT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'REFUND_VENDOR_CREDIT_NOT_FOUND', code: 700 }], - }); - } - if (error.errorType === 'VENDOR_CREDIT_HAS_NO_CREDITS_REMAINING') { - return res.boom.badRequest(null, { - errors: [ - { type: 'VENDOR_CREDIT_HAS_NO_CREDITS_REMAINING', code: 800 }, - ], - }); - } - if (error.errorType === 'VENDOR_CREDIT_ALREADY_OPENED') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR_CREDIT_ALREADY_OPENED', code: 900 }], - }); - } - if (error.errorType === 'VENDOR_CREDIT_HAS_APPLIED_BILLS') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR_CREDIT_HAS_APPLIED_BILLS', code: 1000 }], - }); - } - if (error.errorType === 'VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS') { - return res.boom.badRequest(null, { - errors: [ - { type: 'VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS', code: 1200 }, - ], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Purchases/VendorCreditApplyToBills.ts b/packages/server/src/api/controllers/Purchases/VendorCreditApplyToBills.ts deleted file mode 100644 index b6276f911..000000000 --- a/packages/server/src/api/controllers/Purchases/VendorCreditApplyToBills.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { param, check } from 'express-validator'; -import BaseController from '../BaseController'; -import ApplyVendorCreditToBills from '@/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditToBills'; -import DeleteApplyVendorCreditToBill from '@/services/Purchases/VendorCredits/ApplyVendorCreditToBills/DeleteApplyVendorCreditToBill'; -import { ServiceError } from '@/exceptions'; -import GetAppliedBillsToVendorCredit from '@/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetAppliedBillsToVendorCredit'; -import GetVendorCreditToApplyBills from '@/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetVendorCreditToApplyBills'; - -@Service() -export default class VendorCreditApplyToBills extends BaseController { - @Inject() - applyVendorCreditToBillsService: ApplyVendorCreditToBills; - - @Inject() - deleteAppliedCreditToBillsService: DeleteApplyVendorCreditToBill; - - @Inject() - getAppliedBillsToCreditService: GetAppliedBillsToVendorCredit; - - @Inject() - getCreditToApplyBillsService: GetVendorCreditToApplyBills; - - /** - * - * @returns - */ - router() { - const router = Router(); - - router.post( - '/:id/apply-to-bills', - [ - param('id').exists().isNumeric().toInt(), - - check('entries').isArray({ min: 1 }), - check('entries.*.bill_id').exists().isInt().toInt(), - check('entries.*.amount').exists().isNumeric().toFloat(), - ], - this.validationResult, - this.asyncMiddleware(this.applyVendorCreditToBills), - this.handleServiceErrors - ); - router.delete( - '/applied-to-bills/:applyId', - [param('applyId').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteApplyCreditToBill), - this.handleServiceErrors - ); - router.get( - '/:id/apply-to-bills', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getVendorCreditAssociatedBillsToApply), - this.handleServiceErrors - ); - router.get( - '/:id/applied-bills', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getVendorCreditAppliedBills), - this.handleServiceErrors - ); - return router; - } - - /** - * Apply vendor credit to the given bills. - * @param {Request} - * @param {Response} - * @param {NextFunction} - */ - public applyVendorCreditToBills = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: vendorCreditId } = req.params; - const applyCreditToBillsDTO = this.matchedBodyData(req); - - try { - await this.applyVendorCreditToBillsService.applyVendorCreditToBills( - tenantId, - vendorCreditId, - applyCreditToBillsDTO - ); - return res.status(200).send({ - id: vendorCreditId, - message: - 'The vendor credit has been applied to the given bills successfully', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes vendor credit applied to bill transaction. - * @param {Request} - * @param {Response} - * @param {NextFunction} - */ - public deleteApplyCreditToBill = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { applyId } = req.params; - - try { - await this.deleteAppliedCreditToBillsService.deleteApplyVendorCreditToBills( - tenantId, - applyId - ); - return res.status(200).send({ - id: applyId, - message: - 'The applied vendor credit to bill has been deleted successfully', - }); - } catch (error) { - next(error); - } - }; - - /** - * - */ - public getVendorCreditAssociatedBillsToApply = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: vendorCreditId } = req.params; - - try { - const bills = - await this.getCreditToApplyBillsService.getCreditToApplyBills( - tenantId, - vendorCreditId - ); - return res.status(200).send({ data: bills }); - } catch (error) { - next(error); - } - }; - - /** - * - */ - public getVendorCreditAppliedBills = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: vendorCreditId } = req.params; - - try { - const appliedBills = - await this.getAppliedBillsToCreditService.getAppliedBills( - tenantId, - vendorCreditId - ); - return res.status(200).send({ data: appliedBills }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param next - */ - handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'VENDOR_CREDIT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'VENDOR_CREDIT_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'BILL_ENTRIES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'BILL_ENTRIES_IDS_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'BILLS_NOT_OPENED_YET') { - return res.boom.badRequest(null, { - errors: [{ type: 'BILLS_NOT_OPENED_YET', code: 300 }], - }); - } - if (error.errorType === 'BILLS_HAS_NO_REMAINING_AMOUNT') { - return res.boom.badRequest(null, { - errors: [{ type: 'BILLS_HAS_NO_REMAINING_AMOUNT', code: 400 }], - }); - } - if (error.errorType === 'VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT') { - return res.boom.badRequest(null, { - errors: [ - { type: 'VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT', code: 500 }, - ], - }); - } - if (error.errorType === 'VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [ - { type: 'VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND', code: 600 }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Purchases/index.ts b/packages/server/src/api/controllers/Purchases/index.ts deleted file mode 100644 index 3cb7a278f..000000000 --- a/packages/server/src/api/controllers/Purchases/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Router } from 'express'; -import { Container, Service } from 'typedi'; -import Bills from '@/api/controllers/Purchases/Bills'; -import BillPayments from '@/api/controllers/Purchases/BillsPayments'; -import BillAllocateLandedCost from './LandedCost'; -import VendorCredit from './VendorCredit'; -import VendorCreditApplyToBills from './VendorCreditApplyToBills'; - -@Service() -export default class PurchasesController { - router() { - const router = Router(); - - router.use('/bills', Container.get(Bills).router()); - router.use('/bill_payments', Container.get(BillPayments).router()); - router.use('/landed-cost', Container.get(BillAllocateLandedCost).router()); - router.use('/vendor-credit', Container.get(VendorCredit).router()); - router.use( - '/vendor-credit', - Container.get(VendorCreditApplyToBills).router() - ); - - return router; - } -} diff --git a/packages/server/src/api/controllers/Resources.ts b/packages/server/src/api/controllers/Resources.ts deleted file mode 100644 index c22038087..000000000 --- a/packages/server/src/api/controllers/Resources.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { param } from 'express-validator'; -import BaseController from './BaseController'; -import { ServiceError } from '@/exceptions'; -import ResourceService from '@/services/Resource/ResourceService'; - -@Service() -export default class ResourceController extends BaseController { - @Inject() - resourcesService: ResourceService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/:resource_model/meta', - [param('resource_model').exists().trim()], - this.asyncMiddleware(this.resourceMeta.bind(this)), - this.handleServiceErrors - ); - return router; - } - - /** - * Retrieve resource model meta. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - * @returns {Response} - */ - public resourceMeta = ( - req: Request, - res: Response, - next: NextFunction - ): Response => { - const { tenantId } = req; - const { resource_model: resourceModel } = req.params; - - try { - const resourceMeta = this.resourcesService.getResourceMeta( - tenantId, - resourceModel - ); - return res.status(200).send({ - resource_meta: this.transfromToResponse(resourceMeta), - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'RESOURCE_MODEL_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'RESOURCE.MODEL.NOT.FOUND', code: 100 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Roles/PermissionsSchema.ts b/packages/server/src/api/controllers/Roles/PermissionsSchema.ts deleted file mode 100644 index b09df1555..000000000 --- a/packages/server/src/api/controllers/Roles/PermissionsSchema.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import RolePermissionsSchema from '@/services/Roles/RolePermissionsSchema'; -import { Service, Inject } from 'typedi'; -import BaseController from '../BaseController'; - -@Service() -export default class RolePermissionsSchemaController extends BaseController { - @Inject() - rolePermissionSchema: RolePermissionsSchema; - - router() { - const router = Router(); - - router.get('/permissions/schema', this.getPermissionsSchema); - - return router; - } - - /** - * Retrieve the role permissions schema. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getPermissionsSchema = ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const permissionsSchema = - this.rolePermissionSchema.getRolePermissionsSchema(tenantId); - - return res.status(200).send({ data: permissionsSchema }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Roles/Roles.ts b/packages/server/src/api/controllers/Roles/Roles.ts deleted file mode 100644 index 297b10902..000000000 --- a/packages/server/src/api/controllers/Roles/Roles.ts +++ /dev/null @@ -1,254 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query, ValidationChain } from 'express-validator'; -import BaseController from '../BaseController'; -import { Service, Inject } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import RolesService from '@/services/Roles/RolesService'; - -@Service() -export default class RolesController extends BaseController { - @Inject() - rolesService: RolesService; - - router() { - const router = Router(); - - router.post( - '/', - [ - check('role_name').exists().trim(), - check('role_description').optional(), - check('permissions').exists().isArray({ min: 1 }), - check('permissions.*.subject').exists().trim(), - check('permissions.*.ability').exists().trim(), - check('permissions.*.value').exists().isBoolean().toBoolean(), - ], - this.validationResult, - this.asyncMiddleware(this.createRole), - this.handleServiceErrors - ); - router.post( - '/:id', - [ - check('role_name').exists().trim(), - check('role_description').optional(), - check('permissions').isArray({ min: 1 }), - check('permissions.*.permission_id'), - check('permissions.*.subject').exists().trim(), - check('permissions.*.ability').exists().trim(), - check('permissions.*.value').exists().isBoolean().toBoolean(), - ], - this.validationResult, - this.asyncMiddleware(this.editRole), - this.handleServiceErrors - ); - router.delete( - '/:id', - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteRole), - this.handleServiceErrors - ); - router.get( - '/:id', - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.getRole), - this.handleServiceErrors - ); - router.get( - '/', - [], - this.validationResult, - this.asyncMiddleware(this.listRoles), - this.handleServiceErrors - ); - return router; - } - - /** - * Creates a new role on the authenticated tenant. - * @param req - * @param res - * @param next - */ - private createRole = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const newRoleDTO = this.matchedBodyData(req); - - try { - const role = await this.rolesService.createRole(tenantId, newRoleDTO); - - return res.status(200).send({ - data: { roleId: role.id }, - message: 'The role has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the given role from the storage. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private deleteRole = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: roleId } = req.params; - - try { - const role = await this.rolesService.deleteRole(tenantId, roleId); - - return res.status(200).send({ - data: { roleId }, - message: 'The given role has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Edits the given role details on the storage. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private editRole = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: roleId } = req.params; - const editRoleDTO = this.matchedBodyData(req); - - try { - const role = await this.rolesService.editRole(tenantId, roleId, editRoleDTO); - - return res.status(200).send({ - data: { roleId }, - message: 'The given role hsa been updated successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the roles list. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private listRoles = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const roles = await this.rolesService.listRoles(tenantId); - - return res.status(200).send({ - roles, - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the specific role details. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private getRole = async (req: Request, res: Response, next: NextFunction) => { - const { tenantId } = req; - const { id: roleId } = req.params; - - try { - const role = await this.rolesService.getRole(tenantId, roleId); - - return res.status(200).send({ - role, - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles the service errors. - * @param error - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private handleServiceErrors = ( - error, - req: Request, - res: Response, - next: NextFunction - ) => { - if (error instanceof ServiceError) { - if (error.errorType === 'ROLE_PREFINED') { - return res.status(400).send({ - errors: [ - { - type: 'ROLE_PREFINED', - message: 'Role is predefined, you cannot modify predefined roles', - code: 100, - }, - ], - }); - } - if (error.errorType === 'ROLE_NOT_FOUND') { - return res.status(400).send({ - errors: [ - { - type: 'ROLE_NOT_FOUND', - message: 'Role is not found', - code: 200, - }, - ], - }); - } - if (error.errorType === 'INVALIDATE_PERMISSIONS') { - return res.status(400).send({ - errors: [ - { - type: 'INVALIDATE_PERMISSIONS', - message: 'The submit role has invalid permissions.', - code: 300, - }, - ], - }); - } - if (error.errorType === 'CANNT_DELETE_ROLE_ASSOCIATED_TO_USERS') { - return res.status(400).send({ - errors: [ - { - type: 'CANNOT_DELETE_ROLE_ASSOCIATED_TO_USERS', - message: 'Cannot delete role associated to users.', - code: 400 - }, - ], - }); - } - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Roles/index.ts b/packages/server/src/api/controllers/Roles/index.ts deleted file mode 100644 index f13918979..000000000 --- a/packages/server/src/api/controllers/Roles/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; - -import BaseController from '../BaseController'; -import { Container, Service, Inject } from 'typedi'; - -import RolesService from '@/services/Roles/RolesService'; -import PermissionsSchema from './PermissionsSchema'; -import RolesController from './Roles'; -@Service() -export default class RolesBaseController extends BaseController { - @Inject() - rolesService: RolesService; - - router() { - const router = Router(); - - router.use('/', Container.get(PermissionsSchema).router()); - router.use('/', Container.get(RolesController).router()); - - return router; - } -} diff --git a/packages/server/src/api/controllers/Sales/CreditNoteApplyToBills.ts b/packages/server/src/api/controllers/Sales/CreditNoteApplyToBills.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/src/api/controllers/Sales/CreditNotes.ts b/packages/server/src/api/controllers/Sales/CreditNotes.ts deleted file mode 100644 index fa1a90b27..000000000 --- a/packages/server/src/api/controllers/Sales/CreditNotes.ts +++ /dev/null @@ -1,883 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { check, param, query, ValidationChain } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import { - AbilitySubject, - CreditNoteAction, - DiscountType, - ICreditNoteEditDTO, - ICreditNoteNewDTO, -} from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import CreateCreditNote from '@/services/CreditNotes/CreateCreditNote'; -import EditCreditNote from '@/services/CreditNotes/EditCreditNote'; -import DeleteCreditNote from '@/services/CreditNotes/DeleteCreditNote'; -import GetCreditNote from '@/services/CreditNotes/GetCreditNote'; -import ListCreditNotes from '@/services/CreditNotes/ListCreditNotes'; -import DeleteRefundCreditNote from '@/services/CreditNotes/DeleteRefundCreditNote'; -import ListCreditNoteRefunds from '@/services/CreditNotes/ListCreditNoteRefunds'; -import OpenCreditNote from '@/services/CreditNotes/OpenCreditNote'; -import CreateRefundCreditNote from '@/services/CreditNotes/CreateRefundCreditNote'; -import CreditNoteApplyToInvoices from '@/services/CreditNotes/CreditNoteApplyToInvoices'; -import DeletreCreditNoteApplyToInvoices from '@/services/CreditNotes/DeleteCreditNoteApplyToInvoices'; -import GetCreditNoteAssociatedInvoicesToApply from '@/services/CreditNotes/GetCreditNoteAssociatedInvoicesToApply'; -import GetCreditNoteAssociatedAppliedInvoices from '@/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices'; -import GetRefundCreditTransaction from '@/services/CreditNotes/GetRefundCreditNoteTransaction'; -import GetCreditNotePdf from '../../../services/CreditNotes/GetCreditNotePdf'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; -import { GetCreditNoteState } from '@/services/CreditNotes/GetCreditNoteState'; -/** - * Credit notes controller. - * @service - */ -@Service() -export default class PaymentReceivesController extends BaseController { - @Inject() - createCreditNoteService: CreateCreditNote; - - @Inject() - editCreditNoteService: EditCreditNote; - - @Inject() - deleteCreditNoteService: DeleteCreditNote; - - @Inject() - getCreditNoteService: GetCreditNote; - - @Inject() - listCreditNotesService: ListCreditNotes; - - @Inject() - dynamicListService: DynamicListingService; - - @Inject() - createCreditNoteRefund: CreateRefundCreditNote; - - @Inject() - deleteRefundCredit: DeleteRefundCreditNote; - - @Inject() - listCreditRefunds: ListCreditNoteRefunds; - - @Inject() - openCreditNote: OpenCreditNote; - - @Inject() - applyCreditNoteToInvoicesService: CreditNoteApplyToInvoices; - - @Inject() - deleteApplyCreditToInvoicesService: DeletreCreditNoteApplyToInvoices; - - @Inject() - getCreditAssociatedInvoicesToApply: GetCreditNoteAssociatedInvoicesToApply; - - @Inject() - getCreditAssociatedAppliedInvoices: GetCreditNoteAssociatedAppliedInvoices; - - @Inject() - getRefundCreditService: GetRefundCreditTransaction; - - @Inject() - creditNotePdf: GetCreditNotePdf; - - @Inject() - getCreditNoteStateService: GetCreditNoteState; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - // Edit credit note. - router.post( - '/:id', - CheckPolicies(CreditNoteAction.Edit, AbilitySubject.CreditNote), - this.editCreditNoteDTOShema, - this.validationResult, - this.asyncMiddleware(this.editCreditNote), - this.handleServiceErrors - ); - // New credit note. - router.post( - '/', - CheckPolicies(CreditNoteAction.Create, AbilitySubject.CreditNote), - [...this.newCreditNoteDTOSchema], - this.validationResult, - this.asyncMiddleware(this.newCreditNote), - this.handleServiceErrors - ); - router.get( - '/state', - CheckPolicies(CreditNoteAction.View, AbilitySubject.CreditNote), - this.asyncMiddleware(this.getCreditNoteState.bind(this)), - this.handleServiceErrors - ); - // Get specific credit note. - router.get( - '/:id', - CheckPolicies(CreditNoteAction.View, AbilitySubject.CreditNote), - this.getCreditNoteSchema, - this.asyncMiddleware(this.getCreditNote), - this.handleServiceErrors - ); - // Get credit note list. - router.get( - '/', - CheckPolicies(CreditNoteAction.View, AbilitySubject.CreditNote), - this.validatePaymentReceiveList, - this.validationResult, - this.asyncMiddleware(this.getCreditNotesList), - this.handleServiceErrors, - this.dynamicListService.handlerErrorsToResponse - ); - // Get specific credit note. - router.delete( - '/:id', - CheckPolicies(CreditNoteAction.Delete, AbilitySubject.CreditNote), - this.deleteCreditNoteSchema, - this.validationResult, - this.asyncMiddleware(this.deleteCreditNote), - this.handleServiceErrors - ); - router.post( - '/:id/open', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.openCreditNoteTransaction), - this.handleServiceErrors - ); - router.get( - '/:id/refund', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.creditNoteRefundTransactions), - this.handleServiceErrors - ); - router.post( - '/:id/refund', - CheckPolicies(CreditNoteAction.Refund, AbilitySubject.CreditNote), - this.creditNoteRefundSchema, - this.validationResult, - this.asyncMiddleware(this.refundCreditNote), - this.handleServiceErrors - ); - router.post( - '/:id/apply-to-invoices', - this.creditNoteApplyToInvoices, - this.validationResult, - this.asyncMiddleware(this.applyCreditNoteToInvoices), - this.handleServiceErrors - ); - router.delete( - '/refunds/:refundId', - this.deleteRefundCreditSchema, - this.validationResult, - this.asyncMiddleware(this.deleteCreditNoteRefund), - this.handleServiceErrors - ); - router.get( - '/refunds/:refundId', - this.getRefundCreditTransactionSchema, - this.validationResult, - this.asyncMiddleware(this.getRefundCreditTransaction), - this.handleServiceErrors - ); - router.delete( - '/applied-to-invoices/:applyId', - [param('applyId').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteApplyCreditToInvoices), - this.handleServiceErrors - ); - router.get( - '/:id/apply-to-invoices', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getCreditNoteInvoicesToApply), - this.handleServiceErrors - ); - router.get( - '/:id/applied-invoices', - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.getCreditNoteAppliedInvoices), - this.handleServiceErrors - ); - return router; - } - - /** - * Payment receive schema. - * @return {Array} - */ - get creditNoteDTOSchema(): ValidationChain[] { - return [ - check('customer_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('credit_note_date').exists().isISO8601().toDate(), - check('reference_no').optional(), - check('credit_note_number').optional({ nullable: true }).trim(), - check('note').optional().trim(), - check('terms_conditions').optional().trim(), - check('open').default(false).isBoolean().toBoolean(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').isArray({ min: 1 }), - - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - // Attachments. - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // Pdf template id. - check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(), - - // Discount. - check('discount').optional({ nullable: true }).isNumeric().toFloat(), - check('discount_type') - .optional({ nullable: true }) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - // Adjustment. - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Payment receive list validation schema. - */ - get validatePaymentReceiveList(): ValidationChain[] { - return [ - query('stringified_filter_roles').optional().isJSON(), - - query('view_slug').optional({ nullable: true }).isString().trim(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Validate payment receive parameters. - */ - get deleteCreditNoteSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * New credit note DTO validation schema. - * @return {Array} - */ - get newCreditNoteDTOSchema() { - return [...this.creditNoteDTOSchema]; - } - - /** - * Geet credit note validation schema. - */ - get getCreditNoteSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Edit credit note DTO validation schema. - */ - get editCreditNoteDTOShema() { - return [ - param('id').exists().isNumeric().toInt(), - ...this.creditNoteDTOSchema, - ]; - } - - get creditNoteRefundSchema() { - return [ - check('from_account_id').exists().isNumeric().toInt(), - check('description').optional(), - - check('amount').exists().isNumeric().toFloat(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('reference_no').optional(), - check('date').exists().isISO8601().toDate(), - - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - ]; - } - - get creditNoteApplyToInvoices() { - return [ - check('entries').isArray({ min: 1 }), - check('entries.*.invoice_id').exists().isInt().toInt(), - check('entries.*.amount').exists().isNumeric().toFloat(), - ]; - } - - get deleteRefundCreditSchema() { - return [check('refundId').exists().isNumeric().toInt()]; - } - - get getRefundCreditTransactionSchema() { - return [check('refundId').exists().isNumeric().toInt()]; - } - - /** - * Records payment receive to the given customer with associated invoices. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private newCreditNote = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - const creditNoteDTO: ICreditNoteNewDTO = this.matchedBodyData(req); - - try { - const creditNote = await this.createCreditNoteService.newCreditNote( - tenantId, - creditNoteDTO - ); - return res.status(200).send({ - id: creditNote.id, - message: 'The credit note has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Edit the given payment receive. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private editCreditNote = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: creditNoteId } = req.params; - - const creditNoteDTO: ICreditNoteEditDTO = this.matchedBodyData(req); - - try { - await this.editCreditNoteService.editCreditNote( - tenantId, - creditNoteId, - creditNoteDTO - ); - return res.status(200).send({ - id: creditNoteId, - message: 'The credit note has been edited successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Delets the given payment receive id. - * @param {Request} req - * @param {Response} res - */ - private deleteCreditNote = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId, user } = req; - const { id: creditNoteId } = req.params; - - try { - await this.deleteCreditNoteService.deleteCreditNote( - tenantId, - creditNoteId - ); - return res.status(200).send({ - id: creditNoteId, - message: 'The credit note has been deleted successfully', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve payment receive list with pagination metadata. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private getCreditNotesList = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - - try { - const { creditNotes, pagination, filterMeta } = - await this.listCreditNotesService.getCreditNotesList(tenantId, filter); - - return res.status(200).send({ creditNotes, pagination, filterMeta }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the credit note details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getCreditNote = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: creditNoteId } = req.params; - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_PDF, - ]); - if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const [pdfContent, filename] = await this.creditNotePdf.getCreditNotePdf( - tenantId, - creditNoteId - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - 'Content-Disposition': `attachment; filename="${filename}"`, - }); - res.send(pdfContent); - } else { - const creditNote = await this.getCreditNoteService.getCreditNote( - tenantId, - creditNoteId - ); - return res.status(200).send({ creditNote }); - } - }; - - /** - * Refunds the credit note. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - private refundCreditNote = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: creditNoteId } = req.params; - const creditNoteRefundDTO = this.matchedBodyData(req); - - try { - const creditNoteRefund = - await this.createCreditNoteRefund.createCreditNoteRefund( - tenantId, - creditNoteId, - creditNoteRefundDTO - ); - return res.status(200).send({ - id: creditNoteRefund.id, - message: - 'The customer credit note refund has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Apply credit note to the given invoices. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private applyCreditNoteToInvoices = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: creditNoteId } = req.params; - const applyCreditNoteToInvoicesDTO = this.matchedBodyData(req); - - try { - await this.applyCreditNoteToInvoicesService.applyCreditNoteToInvoices( - tenantId, - creditNoteId, - applyCreditNoteToInvoicesDTO - ); - return res.status(200).send({ - id: creditNoteId, - message: - 'The credit note has been applied the given invoices successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the credit note refund transaction. - * @param req - * @param res - * @param next - * @returns - */ - private deleteCreditNoteRefund = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { refundId: creditRefundId } = req.params; - - try { - await this.deleteRefundCredit.deleteCreditNoteRefund( - tenantId, - creditRefundId - ); - return res.status(200).send({ - id: creditRefundId, - message: 'The credit note refund has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve get refund credit note transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private getRefundCreditTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { refundId: creditRefundId } = req.params; - - try { - const refundCredit = - await this.getRefundCreditService.getRefundCreditTransaction( - tenantId, - creditRefundId - ); - return res.status(200).send({ refundCredit }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve refund transactions associated to the given credit note. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private creditNoteRefundTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { id: creditNoteId } = req.params; - const { tenantId } = req; - - try { - const transactions = await this.listCreditRefunds.getCreditNoteRefunds( - tenantId, - creditNoteId - ); - return res.status(200).send({ data: transactions }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - * @returns - */ - private openCreditNoteTransaction = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { id: creditNoteId } = req.params; - const { tenantId } = req; - - try { - const creditNote = await this.openCreditNote.openCreditNote( - tenantId, - creditNoteId - ); - return res.status(200).send({ - message: 'The credit note has been opened successfully', - id: creditNote.id, - }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - * @returns - */ - private deleteApplyCreditToInvoices = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { applyId: creditAppliedToInvoicesId } = req.params; - - try { - await this.deleteApplyCreditToInvoicesService.deleteApplyCreditNoteToInvoices( - tenantId, - creditAppliedToInvoicesId - ); - return res.status(200).send({ - id: creditAppliedToInvoicesId, - message: - 'The applied credit to invoices has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the credit note associated invoices to apply. - * @param req - * @param res - * @param next - */ - private getCreditNoteInvoicesToApply = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: creditNoteId } = req.params; - - try { - const saleInvoices = - await this.getCreditAssociatedInvoicesToApply.getCreditAssociatedInvoicesToApply( - tenantId, - creditNoteId - ); - return res.status(200).send({ data: saleInvoices }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - * @returns - */ - private getCreditNoteAppliedInvoices = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: creditNoteId } = req.params; - - try { - const appliedInvoices = - await this.getCreditAssociatedAppliedInvoices.getCreditAssociatedAppliedInvoices( - tenantId, - creditNoteId - ); - return res.status(200).send({ data: appliedInvoices }); - } catch (error) { - next(error); - } - }; - - private getCreditNoteState = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const data = await this.getCreditNoteStateService.getCreditNoteState( - tenantId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param next - */ - handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'ENTRIES_ITEMS_IDS_NOT_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_ITEMS_IDS_NOT_EXISTS', code: 100 }], - }); - } - if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_IDS_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS_NOT_FOUND', code: 400 }], - }); - } - if (error.errorType === 'CREDIT_NOTE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'CREDIT_NOTE_NOT_FOUND', code: 500 }], - }); - } - if (error.errorType === 'CREDIT_NOTE_ALREADY_OPENED') { - return res.boom.badRequest(null, { - errors: [{ type: 'CREDIT_NOTE_ALREADY_OPENED', code: 600 }], - }); - } - if ( - error.errorType === 'INVOICES_IDS_NOT_FOUND' || - error.errorType === 'INVOICES_NOT_DELIVERED_YET' - ) { - return res.boom.badRequest(null, { - errors: [{ type: 'APPLIED_INVOICES_IDS_NOT_FOUND', code: 700 }], - }); - } - if (error.errorType === 'CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT') { - return res.boom.badRequest(null, { - errors: [{ type: 'CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT', code: 800 }], - }); - } - if (error.errorType === 'CREDIT_NOTE_APPLY_TO_INVOICES_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [ - { type: 'CREDIT_NOTE_APPLY_TO_INVOICES_NOT_FOUND', code: 900 }, - ], - }); - } - if (error.errorType === 'INVOICES_HAS_NO_REMAINING_AMOUNT') { - return res.boom.badRequest(null, { - errors: [{ type: 'INVOICES_HAS_NO_REMAINING_AMOUNT', code: 1000 }], - }); - } - if (error.errorType === 'CREDIT_NOTE_HAS_REFUNDS_TRANSACTIONS') { - return res.boom.badRequest(null, { - errors: [ - { type: 'CREDIT_NOTE_HAS_REFUNDS_TRANSACTIONS', code: 1100 }, - ], - }); - } - if (error.errorType === 'CREDIT_NOTE_HAS_APPLIED_INVOICES') { - return res.boom.badRequest(null, { - errors: [{ type: 'CREDIT_NOTE_HAS_APPLIED_INVOICES', code: 1200 }], - }); - } - if (error.errorType === 'REFUND_CREDIT_NOTE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'REFUND_CREDIT_NOTE_NOT_FOUND', code: 1300 }], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4900, - data: { ...error.payload }, - }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Sales/PaymentReceives.ts b/packages/server/src/api/controllers/Sales/PaymentReceives.ts deleted file mode 100644 index f61768629..000000000 --- a/packages/server/src/api/controllers/Sales/PaymentReceives.ts +++ /dev/null @@ -1,754 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { body, check, param, query, ValidationChain } from 'express-validator'; -import { - AbilitySubject, - IPaymentReceiveDTO, - PaymentReceiveAction, - PaymentReceiveMailOptsDTO, -} from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import PaymentsReceivedPages from '@/services/Sales/PaymentReceived/PaymentsReceivedPages'; -import { PaymentReceivesApplication } from '@/services/Sales/PaymentReceived/PaymentReceivedApplication'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { ServiceError } from '@/exceptions'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class PaymentReceivesController extends BaseController { - @Inject() - private paymentReceiveApplication: PaymentReceivesApplication; - - @Inject() - private PaymentsReceivedPages: PaymentsReceivedPages; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/:id', - CheckPolicies(PaymentReceiveAction.Edit, AbilitySubject.PaymentReceive), - this.editPaymentReceiveValidation, - this.validationResult, - asyncMiddleware(this.editPaymentReceive.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/notify-by-sms', - CheckPolicies( - PaymentReceiveAction.NotifyBySms, - AbilitySubject.PaymentReceive - ), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.paymentReceiveNotifyBySms), - this.handleServiceErrors - ); - router.get( - '/:id/sms-details', - CheckPolicies( - PaymentReceiveAction.NotifyBySms, - AbilitySubject.PaymentReceive - ), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.paymentReceiveSmsDetails), - this.handleServiceErrors - ); - router.post( - '/', - CheckPolicies(PaymentReceiveAction.Create, AbilitySubject.PaymentReceive), - [...this.newPaymentReceiveValidation], - this.validationResult, - asyncMiddleware(this.newPaymentReceive.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id/edit-page', - CheckPolicies(PaymentReceiveAction.Edit, AbilitySubject.PaymentReceive), - this.paymentReceiveValidation, - this.validationResult, - asyncMiddleware(this.getPaymentReceiveEditPage.bind(this)), - this.handleServiceErrors - ); - router.get( - '/new-page/entries', - CheckPolicies(PaymentReceiveAction.View, AbilitySubject.PaymentReceive), - [query('customer_id').exists().isNumeric().toInt()], - this.validationResult, - asyncMiddleware(this.getPaymentReceiveNewPageEntries.bind(this)), - this.getPaymentReceiveNewPageEntries.bind(this) - ); - router.get( - '/:id/invoices', - CheckPolicies(PaymentReceiveAction.View, AbilitySubject.PaymentReceive), - this.paymentReceiveValidation, - this.validationResult, - asyncMiddleware(this.getPaymentReceiveInvoices.bind(this)), - this.handleServiceErrors - ); - router.get( - '/state', - CheckPolicies(PaymentReceiveAction.View, AbilitySubject.PaymentReceive), - this.getPaymentReceivedState.bind(this), - this.handleServiceErrors - ); - router.get( - '/:id', - CheckPolicies(PaymentReceiveAction.View, AbilitySubject.PaymentReceive), - this.paymentReceiveValidation, - this.asyncMiddleware(this.getPaymentReceive.bind(this)), - this.handleServiceErrors - ); - router.get( - '/', - CheckPolicies(PaymentReceiveAction.View, AbilitySubject.PaymentReceive), - this.validatePaymentReceiveList, - this.validationResult, - asyncMiddleware(this.getPaymentReceiveList.bind(this)), - this.handleServiceErrors, - this.dynamicListService.handlerErrorsToResponse - ); - router.delete( - '/:id', - CheckPolicies(PaymentReceiveAction.Delete, AbilitySubject.PaymentReceive), - this.paymentReceiveValidation, - this.validationResult, - asyncMiddleware(this.deletePaymentReceive.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/mail', - [ - ...this.paymentReceiveValidation, - body('subject').isString().optional(), - - body('from').isString().optional(), - - body('to').isArray().exists(), - body('to.*').isString().isEmail().optional(), - - body('cc').isArray().optional({ nullable: true }), - body('cc.*').isString().isEmail().optional(), - - body('bcc').isArray().optional({ nullable: true }), - body('bcc.*').isString().isEmail().optional(), - - body('attach_invoice').optional().isBoolean().toBoolean(), - ], - this.sendPaymentReceiveByMail.bind(this), - this.handleServiceErrors - ); - router.get( - '/:id/mail', - [...this.paymentReceiveValidation], - asyncMiddleware(this.getPaymentDefaultMail.bind(this)), - this.handleServiceErrors - ); - return router; - } - - /** - * Payment receive schema. - * @return {Array} - */ - private get paymentReceiveSchema(): ValidationChain[] { - return [ - check('customer_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('amount').exists().isNumeric().toFloat(), - check('payment_date').exists(), - check('reference_no').optional(), - check('deposit_account_id').exists().isNumeric().toInt(), - check('payment_receive_no').optional({ nullable: true }).trim(), - check('statement').optional().trim(), - - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').isArray({}), - check('entries.*.id').optional({ nullable: true }).isNumeric().toInt(), - check('entries.*.index').optional().isNumeric().toInt(), - check('entries.*.invoice_id').exists().isNumeric().toInt(), - check('entries.*.payment_amount').exists().isNumeric().toFloat(), - - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // Pdf template id. - check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(), - ]; - } - - /** - * Payment receive list validation schema. - */ - private get validatePaymentReceiveList(): ValidationChain[] { - return [ - query('stringified_filter_roles').optional().isJSON(), - query('view_slug').optional({ nullable: true }).isString().trim(), - - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Validate payment receive parameters. - */ - private get paymentReceiveValidation() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * New payment receive validation schema. - * @return {Array} - */ - private get newPaymentReceiveValidation() { - return [...this.paymentReceiveSchema]; - } - - /** - * Edit payment receive validation. - */ - private get editPaymentReceiveValidation() { - return [ - param('id').exists().isNumeric().toInt(), - ...this.paymentReceiveSchema, - ]; - } - - /** - * Records payment receive to the given customer with associated invoices. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async newPaymentReceive( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const paymentReceive: IPaymentReceiveDTO = this.matchedBodyData(req); - - try { - const storedPaymentReceive = - await this.paymentReceiveApplication.createPaymentReceived( - tenantId, - paymentReceive, - user - ); - return res.status(200).send({ - id: storedPaymentReceive.id, - message: 'The payment receive has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit the given payment receive. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async editPaymentReceive( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: paymentReceiveId } = req.params; - - const paymentReceive: IPaymentReceiveDTO = this.matchedBodyData(req); - - try { - await this.paymentReceiveApplication.editPaymentReceive( - tenantId, - paymentReceiveId, - paymentReceive, - user - ); - return res.status(200).send({ - id: paymentReceiveId, - message: 'The payment receive has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Delets the given payment receive id. - * @param {Request} req - * @param {Response} res - */ - private async deletePaymentReceive( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: paymentReceiveId } = req.params; - - try { - await this.paymentReceiveApplication.deletePaymentReceive( - tenantId, - paymentReceiveId, - user - ); - return res.status(200).send({ - id: paymentReceiveId, - message: 'The payment receive has been deleted successfully', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve sale invoices that associated with the given payment receive. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getPaymentReceiveInvoices( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - - try { - const saleInvoices = - await this.paymentReceiveApplication.getPaymentReceiveInvoices( - tenantId, - paymentReceiveId - ); - - return res.status(200).send(this.transfromToResponse({ saleInvoices })); - } catch (error) { - next(error); - } - } - - /** - * Retrieve payment receive list with pagination metadata. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - private async getPaymentReceiveList( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - - try { - const paymentsReceivedWithPagination = - await this.paymentReceiveApplication.getPaymentReceives( - tenantId, - filter - ); - return res.status(200).send(paymentsReceivedWithPagination); - } catch (error) { - next(error); - } - } - - /** - * Retrieve payment receive new page receivable entries. - * @param {Request} req - Request. - * @param {Response} res - Response. - */ - private async getPaymentReceiveNewPageEntries( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { customerId } = this.matchedQueryData(req); - - try { - const entries = await this.PaymentsReceivedPages.getNewPageEntries( - tenantId, - customerId - ); - return res.status(200).send({ - entries: this.transfromToResponse(entries), - }); - } catch (error) { - next(error); - } - } - - /** - * - * @async - * @param {Request} req - - * @param {Response} res - - */ - private async getPaymentReceivedState( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const data = await this.paymentReceiveApplication.getPaymentReceivedState( - tenantId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the given payment receive details. - * @async - * @param {Request} req - - * @param {Response} res - - */ - private async getPaymentReceiveEditPage( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: paymentReceiveId } = req.params; - - try { - const { paymentReceive, entries } = - await this.PaymentsReceivedPages.getPaymentReceiveEditPage( - tenantId, - paymentReceiveId, - user - ); - - return res.status(200).send({ - payment_receive: this.transfromToResponse({ ...paymentReceive }), - entries: this.transfromToResponse([...entries]), - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the payment receive details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getPaymentReceive( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_PDF, - ACCEPT_TYPE.APPLICATION_TEXT_HTML, - ]); - // Responds pdf format. - if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const [pdfContent, filename] = - await this.paymentReceiveApplication.getPaymentReceivePdf( - tenantId, - paymentReceiveId - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - 'Content-Disposition': `attachment; filename="${filename}"`, - }); - res.send(pdfContent); - // Responds html format. - } else if (ACCEPT_TYPE.APPLICATION_TEXT_HTML === acceptType) { - const htmlContent = - await this.paymentReceiveApplication.getPaymentReceivedHtml( - tenantId, - paymentReceiveId - ); - return res.status(200).send({ htmlContent }); - // Responds json format. - } else { - const paymentReceive = - await this.paymentReceiveApplication.getPaymentReceive( - tenantId, - paymentReceiveId - ); - return res.status(200).send({ - payment_receive: paymentReceive, - }); - } - } - - /** - * Payment receive notfiy customer by sms. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public paymentReceiveNotifyBySms = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - - try { - const paymentReceive = - await this.paymentReceiveApplication.notifyPaymentBySms( - tenantId, - paymentReceiveId - ); - return res.status(200).send({ - id: paymentReceive.id, - message: 'The payment notification has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the sms details of the given payment receive. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public paymentReceiveSmsDetails = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - - try { - const smsDetails = - await this.paymentReceiveApplication.getPaymentSmsDetails( - tenantId, - paymentReceiveId - ); - return res.status(200).send({ - data: smsDetails, - }); - } catch (error) { - next(error); - } - }; - - /** - * Sends mail invoice of the given sale invoice. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public sendPaymentReceiveByMail = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - const paymentMailDTO: PaymentReceiveMailOptsDTO = this.matchedBodyData( - req, - { - includeOptionals: false, - } - ); - - try { - await this.paymentReceiveApplication.notifyPaymentByMail( - tenantId, - paymentReceiveId, - paymentMailDTO - ); - return res.status(200).send({ - code: 200, - message: 'The payment notification has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the default mail options of the given payment transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public getPaymentDefaultMail = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: paymentReceiveId } = req.params; - - try { - const data = await this.paymentReceiveApplication.getPaymentMailOptions( - tenantId, - paymentReceiveId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'DEPOSIT_ACCOUNT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'DEPOSIT.ACCOUNT.NOT.EXISTS', code: 300 }], - }); - } - if (error.errorType === 'PAYMENT_RECEIVE_NO_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'PAYMENT_RECEIVE_NO_EXISTS', code: 300 }], - }); - } - if (error.errorType === 'PAYMENT_RECEIVE_NOT_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'PAYMENT_RECEIVE_NOT_EXISTS', code: 300 }], - }); - } - if (error.errorType === 'DEPOSIT_ACCOUNT_INVALID_TYPE') { - return res.boom.badRequest(null, { - errors: [{ type: 'DEPOSIT_ACCOUNT_INVALID_TYPE', code: 300 }], - }); - } - if (error.errorType === 'INVALID_PAYMENT_AMOUNT_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'INVALID_PAYMENT_AMOUNT', code: 300 }], - }); - } - if (error.errorType === 'INVOICES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'INVOICES_IDS_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'ENTRIES_IDS_NOT_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_IDS_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'INVALID_PAYMENT_AMOUNT') { - return res.boom.badRequest(null, { - errors: [{ type: 'INVALID_PAYMENT_AMOUNT', code: 1000 }], - }); - } - if (error.errorType === 'INVOICES_NOT_DELIVERED_YET') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'INVOICES_NOT_DELIVERED_YET', - code: 200, - data: { - not_delivered_invoices_ids: - error.payload.notDeliveredInvoices.map( - (invoice) => invoice.id - ), - }, - }, - ], - }); - } - if (error.errorType === 'PAYMENT_RECEIVE_NO_IS_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'PAYMENT_RECEIVE_NO_IS_REQUIRED', code: 1100 }], - }); - } - if (error.errorType === 'PAYMENT_CUSTOMER_SHOULD_NOT_UPDATE') { - return res.boom.badRequest(null, { - errors: [{ type: 'PAYMENT_CUSTOMER_SHOULD_NOT_UPDATE', code: 1200 }], - }); - } - if (error.errorType === 'PAYMENT_RECEIVE_NO_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'PAYMENT_RECEIVE_NO_REQUIRED', code: 1300 }], - }); - } - if (error.errorType === 'CUSTOMER_HAS_NO_PHONE_NUMBER') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_HAS_NO_PHONE_NUMBER', code: 1800 }], - }); - } - if (error.errorType === 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID', code: 1900 }], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'PAYMENT_ACCOUNT_CURRENCY_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'PAYMENT_ACCOUNT_CURRENCY_INVALID', code: 2000 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Sales/SalesEstimates.ts b/packages/server/src/api/controllers/Sales/SalesEstimates.ts deleted file mode 100644 index 1c784a1f0..000000000 --- a/packages/server/src/api/controllers/Sales/SalesEstimates.ts +++ /dev/null @@ -1,733 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { body, check, param, query } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import { - AbilitySubject, - DiscountType, - ISaleEstimateDTO, - SaleEstimateAction, - SaleEstimateMailOptionsDTO, -} from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ServiceError } from '@/exceptions'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { SaleEstimatesApplication } from '@/services/Sales/Estimates/SaleEstimatesApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class SalesEstimatesController extends BaseController { - @Inject() - private saleEstimatesApplication: SaleEstimatesApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(SaleEstimateAction.Create, AbilitySubject.SaleEstimate), - [...this.estimateValidationSchema], - this.validationResult, - asyncMiddleware(this.newEstimate.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/deliver', - CheckPolicies(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate), - [...this.validateSpecificEstimateSchema], - this.validationResult, - asyncMiddleware(this.deliverSaleEstimate.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/approve', - CheckPolicies(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate), - [...this.validateSpecificEstimateSchema], - this.validationResult, - asyncMiddleware(this.approveSaleEstimate.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/reject', - CheckPolicies(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate), - [...this.validateSpecificEstimateSchema], - this.validationResult, - asyncMiddleware(this.rejectSaleEstimate.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id/sms-details', - CheckPolicies( - SaleEstimateAction.NotifyBySms, - AbilitySubject.SaleEstimate - ), - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.saleEstimateSmsDetails), - this.handleServiceErrors - ); - router.post( - '/:id/notify-by-sms', - CheckPolicies( - SaleEstimateAction.NotifyBySms, - AbilitySubject.SaleEstimate - ), - [param('id').exists().isNumeric().toInt()], - this.validationResult, - this.asyncMiddleware(this.saleEstimateNotifyBySms), - this.handleServiceErrors - ); - router.post( - '/:id', - CheckPolicies(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate), - [ - ...this.validateSpecificEstimateSchema, - ...this.estimateValidationSchema, - ], - this.validationResult, - asyncMiddleware(this.editEstimate.bind(this)), - this.handleServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(SaleEstimateAction.Delete, AbilitySubject.SaleEstimate), - [this.validateSpecificEstimateSchema], - this.validationResult, - asyncMiddleware(this.deleteEstimate.bind(this)), - this.handleServiceErrors - ); - router.get( - '/state', - CheckPolicies(SaleEstimateAction.View, AbilitySubject.SaleEstimate), - this.getSaleEstimateState.bind(this), - this.handleServiceErrors - ); - router.get( - '/:id', - CheckPolicies(SaleEstimateAction.View, AbilitySubject.SaleEstimate), - this.validateSpecificEstimateSchema, - this.validationResult, - asyncMiddleware(this.getEstimate.bind(this)), - this.handleServiceErrors - ); - router.get( - '/', - CheckPolicies(SaleEstimateAction.View, AbilitySubject.SaleEstimate), - this.validateEstimateListSchema, - this.validationResult, - asyncMiddleware(this.getEstimates.bind(this)), - this.handleServiceErrors, - this.dynamicListService.handlerErrorsToResponse - ); - router.post( - '/:id/mail', - [ - ...this.validateSpecificEstimateSchema, - body('subject').isString().optional(), - - body('from').isString().optional(), - - body('to').isArray().exists(), - body('to.*').isString().isEmail().optional(), - - body('cc').isArray().optional({ nullable: true }), - body('cc.*').isString().isEmail().optional(), - - body('bcc').isArray().optional({ nullable: true }), - body('bcc.*').isString().isEmail().optional(), - - body('body').isString().optional(), - body('attach_invoice').optional().isBoolean().toBoolean(), - ], - this.validationResult, - asyncMiddleware(this.sendSaleEstimateMail.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id/mail/state', - [...this.validateSpecificEstimateSchema], - this.validationResult, - asyncMiddleware(this.getSaleEstimateMailState.bind(this)), - this.handleServiceErrors - ); - return router; - } - - /** - * Estimate validation schema. - */ - private get estimateValidationSchema() { - return [ - check('customer_id').exists().isNumeric().toInt(), - check('estimate_date').exists().isISO8601().toDate(), - check('expiration_date').exists().isISO8601().toDate(), - check('reference').optional(), - check('estimate_number').optional().trim(), - check('delivered').default(false).isBoolean().toBoolean(), - - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').exists().isArray({ min: 1 }), - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - check('note').optional().trim(), - check('terms_conditions').optional().trim(), - check('send_to_email').optional().trim(), - - // # Attachments - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // # Pdf template id. - check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(), - - // # Discount - check('discount').optional({ nullable: true }).isNumeric().toFloat(), - check('discount_type') - .default(DiscountType.Amount) - .isIn([DiscountType.Amount, DiscountType.Percentage]), - - // # Adjustment - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Specific sale estimate validation schema. - */ - private get validateSpecificEstimateSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Sales estimates list validation schema. - */ - private get validateEstimateListSchema() { - return [ - query('view_slug').optional().isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Handle create a new estimate with associated entries. - * @param {Request} req - - * @param {Response} res - - * @return {Response} res - - */ - private async newEstimate(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const estimateDTO: ISaleEstimateDTO = this.matchedBodyData(req); - - try { - const storedEstimate = - await this.saleEstimatesApplication.createSaleEstimate( - tenantId, - estimateDTO - ); - - return res.status(200).send({ - id: storedEstimate.id, - message: 'The sale estimate has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Handle update estimate details with associated entries. - * @param {Request} req - * @param {Response} res - */ - private async editEstimate(req: Request, res: Response, next: NextFunction) { - const { id: estimateId } = req.params; - const { tenantId } = req; - const estimateDTO: ISaleEstimateDTO = this.matchedBodyData(req); - - try { - // Update estimate with associated estimate entries. - await this.saleEstimatesApplication.editSaleEstimate( - tenantId, - estimateId, - estimateDTO - ); - return res.status(200).send({ - id: estimateId, - message: 'The sale estimate has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given estimate with associated entries. - * @param {Request} req - * @param {Response} res - */ - private async deleteEstimate( - req: Request, - res: Response, - next: NextFunction - ) { - const { id: estimateId } = req.params; - const { tenantId } = req; - - try { - await this.saleEstimatesApplication.deleteSaleEstimate( - tenantId, - estimateId - ); - return res.status(200).send({ - id: estimateId, - message: 'The sale estimate has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deliver the given sale estimate. - * @param {Request} req - * @param {Response} res - */ - private async deliverSaleEstimate( - req: Request, - res: Response, - next: NextFunction - ) { - const { id: estimateId } = req.params; - const { tenantId } = req; - - try { - await this.saleEstimatesApplication.deliverSaleEstimate( - tenantId, - estimateId - ); - return res.status(200).send({ - id: estimateId, - message: 'The sale estimate has been delivered successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Marks the sale estimate as approved. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async approveSaleEstimate( - req: Request, - res: Response, - next: NextFunction - ) { - const { id: estimateId } = req.params; - const { tenantId } = req; - - try { - await this.saleEstimatesApplication.approveSaleEstimate( - tenantId, - estimateId - ); - return res.status(200).send({ - id: estimateId, - message: 'The sale estimate has been approved successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Marks the sale estimate as rejected. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async rejectSaleEstimate( - req: Request, - res: Response, - next: NextFunction - ) { - const { id: estimateId } = req.params; - const { tenantId } = req; - - try { - await this.saleEstimatesApplication.rejectSaleEstimate( - tenantId, - estimateId - ); - return res.status(200).send({ - id: estimateId, - message: 'The sale estimate has been rejected successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the given estimate with associated entries. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getEstimate(req: Request, res: Response, next: NextFunction) { - const { id: estimateId } = req.params; - const { tenantId } = req; - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_PDF, - ACCEPT_TYPE.APPLICATION_TEXT_HTML, - ]); - // Retrieves estimate in pdf format. - if (ACCEPT_TYPE.APPLICATION_PDF == acceptType) { - const [pdfContent, filename] = - await this.saleEstimatesApplication.getSaleEstimatePdf( - tenantId, - estimateId - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - 'Content-Disposition': `attachment; filename="${filename}"`, - }); - res.send(pdfContent); - // Retrieves estimates in json format. - } else if (ACCEPT_TYPE.APPLICATION_TEXT_HTML === acceptType) { - const htmlContent = - await this.saleEstimatesApplication.getSaleEstimateHtml( - tenantId, - estimateId - ); - return res.status(200).send({ htmlContent }); - } else if (ACCEPT_TYPE.APPLICATION_JSON) { - const estimate = await this.saleEstimatesApplication.getSaleEstimate( - tenantId, - estimateId - ); - return res.status(200).send({ estimate }); - } - } - - /** - * Retrieve estimates with pagination metadata. - * @param {Request} req - * @param {Response} res - */ - private async getEstimates(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - try { - const salesEstimatesWithPagination = - await this.saleEstimatesApplication.getSaleEstimates(tenantId, filter); - - return res.status(200).send(salesEstimatesWithPagination); - } catch (error) { - next(error); - } - } - - private saleEstimateNotifyBySms = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: estimateId } = req.params; - - try { - const saleEstimate = - await this.saleEstimatesApplication.notifySaleEstimateBySms( - tenantId, - estimateId - ); - return res.status(200).send({ - id: saleEstimate.id, - message: - 'The sale estimate sms notification has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the sale estimate sms notification message details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private saleEstimateSmsDetails = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: estimateId } = req.params; - - try { - const estimateSmsDetails = - await this.saleEstimatesApplication.getSaleEstimateSmsDetails( - tenantId, - estimateId - ); - return res.status(200).send({ - data: estimateSmsDetails, - }); - } catch (error) { - next(error); - } - }; - - /** - * Send the sale estimate mail. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private sendSaleEstimateMail = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - const saleEstimateDTO: SaleEstimateMailOptionsDTO = this.matchedBodyData( - req, - { - includeOptionals: false, - } - ); - try { - await this.saleEstimatesApplication.sendSaleEstimateMail( - tenantId, - invoiceId, - saleEstimateDTO - ); - return res.status(200).send({ - code: 200, - message: 'The sale estimate mail has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the default mail options of the given sale estimate. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getSaleEstimateMailState = async ( - req: Request<{ id: number }>, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: estimateId } = req.params; - - try { - const data = await this.saleEstimatesApplication.getSaleEstimateMailState( - tenantId, - estimateId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - private getSaleEstimateState = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const data = await this.saleEstimatesApplication.getSaleEstimateState( - tenantId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 100 }], - }); - } - if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES.IDS.NOT.EXISTS', code: 200 }], - }); - } - if (error.errorType === 'ITEMS_IDS_NOT_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 300 }], - }); - } - if (error.errorType === 'NOT_PURCHASE_ABLE_ITEMS') { - return res.boom.badRequest(null, { - errors: [{ type: 'NOT_PURCHASABLE_ITEMS', code: 400 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_ESTIMATE_NOT_FOUND', code: 500 }], - }); - } - if (error.errorType === 'CUSTOMER_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 600 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_NUMBER_EXISTANCE') { - return res.boom.badRequest(null, { - errors: [{ type: 'ESTIMATE.NUMBER.IS.NOT.UNQIUE', code: 700 }], - }); - } - if (error.errorType === 'NOT_SELL_ABLE_ITEMS') { - return res.boom.badRequest(null, { - errors: [{ type: 'NOT_SELL_ABLE_ITEMS', code: 800 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_ALREADY_APPROVED') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 1000 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_NOT_DELIVERED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_ESTIMATE_NOT_DELIVERED', code: 1100 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_ALREADY_REJECTED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_ESTIMATE_ALREADY_REJECTED', code: 1200 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 1300 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_NO_IS_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_ESTIMATE_NO_IS_REQUIRED', code: 1400 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_CONVERTED_TO_INVOICE') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_ESTIMATE_CONVERTED_TO_INVOICE', code: 1500 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_ALREADY_DELIVERED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_ESTIMATE_ALREADY_DELIVERED', code: 1600 }], - }); - } - if (error.errorType === 'CUSTOMER_HAS_NO_PHONE_NUMBER') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_HAS_NO_PHONE_NUMBER', code: 1800 }], - }); - } - if (error.errorType === 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID', code: 1900 }], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'WAREHOUSE_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'WAREHOUSE_ID_NOT_FOUND', code: 5000 }], - }); - } - if (error.errorType === 'BRANCH_ID_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'BRANCH_ID_REQUIRED', code: 5100 }], - }); - } - if (error.errorType === 'BRANCH_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'BRANCH_ID_NOT_FOUND', code: 5300 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Sales/SalesInvoices.ts b/packages/server/src/api/controllers/Sales/SalesInvoices.ts deleted file mode 100644 index dbe7679df..000000000 --- a/packages/server/src/api/controllers/Sales/SalesInvoices.ts +++ /dev/null @@ -1,987 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { body, check, param, query } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import BaseController from '../BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ServiceError } from '@/exceptions'; -import { - ISaleInvoiceDTO, - ISaleInvoiceCreateDTO, - SaleInvoiceAction, - AbilitySubject, - SendInvoiceMailDTO, - DiscountType, -} from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { SaleInvoiceApplication } from '@/services/Sales/Invoices/SaleInvoicesApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class SaleInvoicesController extends BaseController { - @Inject() - private saleInvoiceApplication: SaleInvoiceApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(SaleInvoiceAction.Create, AbilitySubject.SaleInvoice), - [ - ...this.saleInvoiceValidationSchema, - check('from_estimate_id').optional().isNumeric().toInt(), - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - ], - this.validationResult, - asyncMiddleware(this.newSaleInvoice.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/deliver', - CheckPolicies(SaleInvoiceAction.Edit, AbilitySubject.SaleInvoice), - [...this.specificSaleInvoiceValidation], - this.validationResult, - asyncMiddleware(this.deliverSaleInvoice.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/writeoff', - CheckPolicies(SaleInvoiceAction.Writeoff, AbilitySubject.SaleInvoice), - [ - param('id').exists().isInt().toInt(), - - check('expense_account_id').exists().isInt().toInt(), - check('reason').exists().trim(), - ], - this.validationResult, - this.asyncMiddleware(this.writeoffSaleInvoice), - this.handleServiceErrors - ); - router.post( - '/:id/writeoff/cancel', - CheckPolicies(SaleInvoiceAction.Writeoff, AbilitySubject.SaleInvoice), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.cancelWrittenoffSaleInvoice), - this.handleServiceErrors - ); - router.post( - '/:id/notify-by-sms', - CheckPolicies(SaleInvoiceAction.NotifyBySms, AbilitySubject.SaleInvoice), - [ - param('id').exists().isInt().toInt(), - check('notification_key').exists().isIn(['details', 'reminder']), - ], - this.validationResult, - this.asyncMiddleware(this.saleInvoiceNotifyBySms), - this.handleServiceErrors - ); - router.get( - '/:id/sms-details', - CheckPolicies(SaleInvoiceAction.NotifyBySms, AbilitySubject.SaleInvoice), - [ - param('id').exists().isInt().toInt(), - query('notification_key').exists().isIn(['details', 'reminder']), - ], - this.validationResult, - this.asyncMiddleware(this.saleInvoiceSmsDetails), - this.handleServiceErrors - ); - router.post( - '/:id', - CheckPolicies(SaleInvoiceAction.Edit, AbilitySubject.SaleInvoice), - [ - ...this.saleInvoiceValidationSchema, - ...this.specificSaleInvoiceValidation, - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - ], - this.validationResult, - asyncMiddleware(this.editSaleInvoice.bind(this)), - this.handleServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(SaleInvoiceAction.Delete, AbilitySubject.SaleInvoice), - this.specificSaleInvoiceValidation, - this.validationResult, - asyncMiddleware(this.deleteSaleInvoice.bind(this)), - this.handleServiceErrors - ); - router.get( - '/payable', - CheckPolicies(SaleInvoiceAction.View, AbilitySubject.SaleInvoice), - [...this.dueSalesInvoicesListValidationSchema], - this.validationResult, - asyncMiddleware(this.getPayableInvoices.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id/payment-transactions', - [param('id').exists().isString()], - this.validationResult, - this.asyncMiddleware(this.getInvoicePaymentTransactions), - this.handleServiceErrors - ); - router.get( - '/state', - CheckPolicies(SaleInvoiceAction.View, AbilitySubject.SaleInvoice), - asyncMiddleware(this.getSaleInvoiceState.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id', - CheckPolicies(SaleInvoiceAction.View, AbilitySubject.SaleInvoice), - this.specificSaleInvoiceValidation, - this.validationResult, - asyncMiddleware(this.getSaleInvoice.bind(this)), - this.handleServiceErrors - ); - - router.get( - '/', - CheckPolicies(SaleInvoiceAction.View, AbilitySubject.SaleInvoice), - this.saleInvoiceListValidationSchema, - this.validationResult, - asyncMiddleware(this.getSalesInvoices.bind(this)), - this.handleServiceErrors, - this.dynamicListService.handlerErrorsToResponse - ); - router.get( - '/:id/mail-reminder', - this.specificSaleInvoiceValidation, - this.validationResult, - asyncMiddleware(this.getSaleInvoiceMailReminder.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/mail-reminder', - [ - ...this.specificSaleInvoiceValidation, - body('subject').isString().optional(), - body('from').isString().optional(), - body('to').isString().optional(), - body('body').isString().optional(), - body('attach_invoice').optional().isBoolean().toBoolean(), - ], - this.validationResult, - asyncMiddleware(this.sendSaleInvoiceMailReminder.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/mail', - [ - ...this.specificSaleInvoiceValidation, - - body('subject').isString().optional({ nullable: true }), - body('message').isString().optional({ nullable: true }), - - body('from').isString().optional(), - - body('to').isArray().exists(), - body('to.*').isString().isEmail().optional(), - - body('cc').isArray().optional({ nullable: true }), - body('cc.*').isString().isEmail().optional(), - - body('bcc').isArray().optional({ nullable: true }), - body('bcc.*').isString().isEmail().optional(), - - body('attach_invoice').optional().isBoolean().toBoolean(), - ], - this.validationResult, - asyncMiddleware(this.sendSaleInvoiceMail.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id/mail/state', - [...this.specificSaleInvoiceValidation], - this.validationResult, - asyncMiddleware(this.getSaleInvoiceMail.bind(this)), - this.handleServiceErrors - ); - return router; - } - - /** - * Sale invoice validation schema. - */ - private get saleInvoiceValidationSchema() { - return [ - check('customer_id').exists().isNumeric().toInt(), - check('invoice_date').exists().isISO8601().toDate(), - check('due_date').exists().isISO8601().toDate(), - check('invoice_no').optional().trim(), - check('reference_no').optional().trim(), - check('delivered').default(false).isBoolean().toBoolean(), - - check('invoice_message').optional().trim(), - check('terms_conditions').optional().trim(), - - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - check('project_id').optional({ nullable: true }).isNumeric().toInt(), - - check('is_inclusive_tax').optional().isBoolean().toBoolean(), - - check('entries').exists().isArray({ min: 1 }), - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.tax_code') - .optional({ nullable: true }) - .trim() - .isString(), - check('entries.*.tax_rate_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - check('entries.*.project_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - check('entries.*.project_ref_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - check('entries.*.project_ref_type') - .optional({ nullable: true }) - .isString() - .toUpperCase() - .isIn(['TASK', 'BILL', 'EXPENSE']), - check('entries.*.project_ref_invoiced_amount') - .optional({ nullable: true }) - .isNumeric() - .toFloat(), - - // Pdf template id. - check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(), - - // Payment methods. - check('payment_methods').optional({ nullable: true }).isArray(), - check('payment_methods.*.payment_integration_id').exists().toInt(), - check('payment_methods.*.enable').exists().isBoolean(), - - // Discount - check('discount').optional({ nullable: true }).isNumeric().toFloat(), - check('discount_type') - .optional({ nullable: true }) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - // Adjustments - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Specific sale invoice validation schema. - */ - private get specificSaleInvoiceValidation() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * Sales invoices list validation schema. - */ - private get saleInvoiceListValidationSchema() { - return [ - query('view_slug').optional({ nullable: true }).isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Due sale invoice list validation schema. - */ - private get dueSalesInvoicesListValidationSchema() { - return [query('customer_id').optional().isNumeric().toInt()]; - } - - /** - * Creates a new sale invoice. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - private async newSaleInvoice( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const saleInvoiceDTO: ISaleInvoiceCreateDTO = this.matchedBodyData(req); - - try { - // Creates a new sale invoice with associated entries. - const storedSaleInvoice = - await this.saleInvoiceApplication.createSaleInvoice( - tenantId, - saleInvoiceDTO, - user - ); - return res.status(200).send({ - id: storedSaleInvoice.id, - message: 'The sale invoice has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit sale invoice details. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - private async editSaleInvoice( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: saleInvoiceId } = req.params; - const saleInvoiceOTD: ISaleInvoiceDTO = this.matchedBodyData(req); - - try { - // Update the given sale invoice details. - await this.saleInvoiceApplication.editSaleInvoice( - tenantId, - saleInvoiceId, - saleInvoiceOTD, - user - ); - return res.status(200).send({ - id: saleInvoiceId, - message: 'The sale invoice has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deliver the given sale invoice. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private async deliverSaleInvoice( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId, user } = req; - const { id: saleInvoiceId } = req.params; - - try { - await this.saleInvoiceApplication.deliverSaleInvoice( - tenantId, - saleInvoiceId, - user - ); - return res.status(200).send({ - id: saleInvoiceId, - message: 'The given sale invoice has been delivered successfully', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the sale invoice with associated entries and journal transactions. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - private async deleteSaleInvoice( - req: Request, - res: Response, - next: NextFunction - ) { - const { id: saleInvoiceId } = req.params; - const { tenantId, user } = req; - - try { - // Deletes the sale invoice with associated entries and journal transaction. - await this.saleInvoiceApplication.deleteSaleInvoice( - tenantId, - saleInvoiceId, - user - ); - return res.status(200).send({ - id: saleInvoiceId, - message: 'The sale invoice has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the sale invoice with associated entries. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - */ - private async getSaleInvoice(req: Request, res: Response) { - const { id: saleInvoiceId } = req.params; - const { tenantId, user } = req; - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_PDF, - ACCEPT_TYPE.APPLICATION_TEXT_HTML, - ]); - // Retrieves invoice in PDF format. - if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { - const [pdfContent, filename] = - await this.saleInvoiceApplication.saleInvoicePdf( - tenantId, - saleInvoiceId - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - 'Content-Disposition': `attachment; filename="${filename}"`, - }); - res.send(pdfContent); - // Retrieves invoice in html json format. - } else if (ACCEPT_TYPE.APPLICATION_TEXT_HTML === acceptType) { - const htmlContent = await this.saleInvoiceApplication.saleInvoiceHtml( - tenantId, - saleInvoiceId - ); - return res.status(200).send({ htmlContent }); - } else { - const saleInvoice = await this.saleInvoiceApplication.getSaleInvoice( - tenantId, - saleInvoiceId, - user - ); - return res.status(200).send({ saleInvoice }); - } - } - - private async getSaleInvoiceState( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const data = await this.saleInvoiceApplication.getSaleInvoiceState( - tenantId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve paginated sales invoices with custom view metadata. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - public async getSalesInvoices( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - try { - const salesInvoicesWithPagination = - await this.saleInvoiceApplication.getSaleInvoices(tenantId, filter); - - return res.status(200).send(salesInvoicesWithPagination); - } catch (error) { - next(error); - } - } - - /** - * Retrieve due sales invoices. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - * @return {Response|void} - */ - public async getPayableInvoices( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { customerId } = this.matchedQueryData(req); - - try { - const salesInvoices = - await this.saleInvoiceApplication.getReceivableSaleInvoices( - tenantId, - customerId - ); - return res.status(200).send({ salesInvoices }); - } catch (error) { - next(error); - } - } - - /** - * Written-off sale invoice. - * @param {Request} req - * @param {Response} res - * @param next - */ - public writeoffSaleInvoice = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - const writeoffDTO = this.matchedBodyData(req); - - try { - const saleInvoice = await this.saleInvoiceApplication.writeOff( - tenantId, - invoiceId, - writeoffDTO - ); - return res.status(200).send({ - id: saleInvoice.id, - message: 'The given sale invoice has been written-off successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Cancel the written-off sale invoice. - * @param {Request} req - * @param {Response} res - * @param next - */ - public cancelWrittenoffSaleInvoice = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - try { - const saleInvoice = await this.saleInvoiceApplication.cancelWrittenoff( - tenantId, - invoiceId - ); - return res.status(200).send({ - id: saleInvoice.id, - message: - 'The given sale invoice has been canceled write-off successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Sale invoice notfiy customer by sms. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public saleInvoiceNotifyBySms = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - const invoiceNotifySmsDTO = this.matchedBodyData(req); - - try { - const saleInvoice = - await this.saleInvoiceApplication.notifySaleInvoiceBySms( - tenantId, - invoiceId, - invoiceNotifySmsDTO.notificationKey - ); - return res.status(200).send({ - id: saleInvoice.id, - message: - 'The sale invoice sms notification has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Sale invoice SMS details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public saleInvoiceSmsDetails = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - const smsDetailsDTO = this.matchedQueryData(req); - - try { - const invoiceSmsDetails = - await this.saleInvoiceApplication.getSaleInvoiceSmsDetails( - tenantId, - invoiceId, - smsDetailsDTO - ); - return res.status(200).send({ - data: invoiceSmsDetails, - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the invoice payment transactions. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - public getInvoicePaymentTransactions = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - try { - const invoicePayments = - await this.saleInvoiceApplication.getInvoicePayments( - tenantId, - invoiceId - ); - - return res.status(200).send({ - data: invoicePayments, - }); - } catch (error) { - next(error); - } - }; - - /** - * Sends mail invoice of the given sale invoice. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async sendSaleInvoiceMail( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: invoiceId } = req.params; - const invoiceMailDTO: SendInvoiceMailDTO = this.matchedBodyData(req, { - includeOptionals: false, - }); - - try { - await this.saleInvoiceApplication.sendSaleInvoiceMail( - tenantId, - invoiceId, - invoiceMailDTO - ); - return res.status(200).send({ - code: 200, - message: 'The sale invoice mail has been sent successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retreivers the sale invoice reminder options. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async getSaleInvoiceMailReminder( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - try { - const data = await this.saleInvoiceApplication.getSaleInvoiceMailReminder( - tenantId, - invoiceId - ); - return res.status(200).send(data); - } catch (error) { - next(error); - } - } - - /** - * Sends mail invoice of the given sale invoice. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async sendSaleInvoiceMailReminder( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: invoiceId } = req.params; - const invoiceMailDTO: SendInvoiceMailDTO = this.matchedBodyData(req, { - includeOptionals: false, - }); - try { - await this.saleInvoiceApplication.sendSaleInvoiceMailReminder( - tenantId, - invoiceId, - invoiceMailDTO - ); - return res.status(200).send({ - code: 200, - message: 'The sale invoice mail reminder has been sent successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the mail state of the given sale invoice. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async getSaleInvoiceMail( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: invoiceId } = req.params; - - try { - const data = await this.saleInvoiceApplication.getSaleInvoiceMailState( - tenantId, - invoiceId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'INVOICE_NUMBER_NOT_UNIQUE') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE.INVOICE.NUMBER.IS.EXISTS', code: 100 }], - }); - } - if (error.errorType === 'SALE_INVOICE_NOT_FOUND') { - return res.status(404).send({ - errors: [{ type: 'SALE.INVOICE.NOT.FOUND', code: 200 }], - }); - } - if (error.errorType === 'ENTRIES_ITEMS_IDS_NOT_EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_ITEMS_IDS_NOT_EXISTS', code: 300 }], - }); - } - if (error.errorType === 'NOT_SELLABLE_ITEMS') { - return res.boom.badRequest(null, { - errors: [{ type: 'NOT_SELLABLE_ITEMS', code: 400 }], - }); - } - if (error.errorType === 'SALE_INVOICE_NO_NOT_UNIQUE') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_INVOICE_NO_NOT_UNIQUE', code: 500 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS_NOT_FOUND', code: 600 }], - }); - } - if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_IDS_NOT_FOUND', code: 700 }], - }); - } - if (error.errorType === 'NOT_SELL_ABLE_ITEMS') { - return res.boom.badRequest(null, { - errors: [{ type: 'NOT_SELL_ABLE_ITEMS', code: 800 }], - }); - } - if (error.errorType === 'contact_not_found') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 900 }], - }); - } - if (error.errorType === 'SALE_INVOICE_ALREADY_DELIVERED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_INVOICE_ALREADY_DELIVERED', code: 1000 }], - }); - } - if (error.errorType === 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES') { - return res.boom.badRequest(null, { - errors: [ - { type: 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES', code: 1100 }, - ], - }); - } - if (error.errorType === 'SALE_ESTIMATE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'FROM_SALE_ESTIMATE_NOT_FOUND', code: 1200 }], - }); - } - if (error.errorType === 'SALE_ESTIMATE_CONVERTED_TO_INVOICE') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'SALE_ESTIMATE_IS_ALREADY_CONVERTED_TO_INVOICE', - code: 1300, - }, - ], - }); - } - if (error.errorType === 'INVOICE_AMOUNT_SMALLER_THAN_PAYMENT_AMOUNT') { - return res.boom.badRequest(null, { - errors: [ - { type: 'INVOICE_AMOUNT_SMALLER_THAN_PAYMENT_AMOUNT', code: 1400 }, - ], - }); - } - if (error.errorType === 'SALE_INVOICE_NO_IS_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_INVOICE_NO_IS_REQUIRED', code: 1500 }], - }); - } - if (error.errorType === 'SALE_INVOICE_NOT_WRITTEN_OFF') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_INVOICE_NOT_WRITTEN_OFF', code: 1600 }], - }); - } - if (error.errorType === 'SALE_INVOICE_ALREADY_WRITTEN_OFF') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_INVOICE_ALREADY_WRITTEN_OFF', code: 1700 }], - }); - } - if (error.errorType === 'CUSTOMER_HAS_NO_PHONE_NUMBER') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_HAS_NO_PHONE_NUMBER', code: 1800 }], - }); - } - if (error.errorType === 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID', code: 1800 }], - }); - } - if (error.errorType === 'SALE_INVOICE_HAS_APPLIED_TO_CREDIT_NOTES') { - return res.boom.badRequest(null, { - errors: [ - { type: 'SALE_INVOICE_HAS_APPLIED_TO_CREDIT_NOTES', code: 1900 }, - ], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4900, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND', code: 5000 }], - }); - } - if (error.errorType === 'ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND', code: 5100 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Sales/SalesReceipts.ts b/packages/server/src/api/controllers/Sales/SalesReceipts.ts deleted file mode 100644 index 47e03d03f..000000000 --- a/packages/server/src/api/controllers/Sales/SalesReceipts.ts +++ /dev/null @@ -1,666 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { body, check, param, query } from 'express-validator'; -import { Inject, Service } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '../BaseController'; -import { - ISaleReceiptDTO, - SaleReceiptMailOpts, - SaleReceiptMailOptsDTO, -} from '@/interfaces/SaleReceipt'; -import { ServiceError } from '@/exceptions'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, DiscountType, SaleReceiptAction } from '@/interfaces'; -import { SaleReceiptApplication } from '@/services/Sales/Receipts/SaleReceiptApplication'; -import { ACCEPT_TYPE } from '@/interfaces/Http'; - -@Service() -export default class SalesReceiptsController extends BaseController { - @Inject() - private saleReceiptsApplication: SaleReceiptApplication; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/:id/close', - CheckPolicies(SaleReceiptAction.Edit, AbilitySubject.SaleReceipt), - [...this.specificReceiptValidationSchema], - this.validationResult, - asyncMiddleware(this.closeSaleReceipt.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/notify-by-sms', - CheckPolicies(SaleReceiptAction.NotifyBySms, AbilitySubject.SaleReceipt), - [param('id').exists().isInt().toInt()], - this.asyncMiddleware(this.saleReceiptNotifyBySms), - this.handleServiceErrors - ); - router.get( - '/:id/sms-details', - CheckPolicies(SaleReceiptAction.NotifyBySms, AbilitySubject.SaleReceipt), - [param('id').exists().isInt().toInt()], - this.saleReceiptSmsDetails, - this.handleServiceErrors - ); - router.post( - '/:id/mail', - [ - ...this.specificReceiptValidationSchema, - body('subject').isString().optional(), - - body('from').isString().optional(), - - body('to').isArray().exists(), - body('to.*').isString().isEmail().optional(), - - body('cc').isArray().optional({ nullable: true }), - body('cc.*').isString().isEmail().optional(), - - body('bcc').isArray().optional({ nullable: true }), - body('bcc.*').isString().isEmail().optional(), - - body('body').isString().optional(), - body('attach_receipt').optional().isBoolean().toBoolean(), - ], - this.validationResult, - asyncMiddleware(this.sendSaleReceiptMail.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id/mail', - [...this.specificReceiptValidationSchema], - this.validationResult, - asyncMiddleware(this.getSaleReceiptMail.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id', - CheckPolicies(SaleReceiptAction.Edit, AbilitySubject.SaleReceipt), - [ - ...this.specificReceiptValidationSchema, - ...this.salesReceiptsValidationSchema, - ], - this.validationResult, - asyncMiddleware(this.editSaleReceipt.bind(this)), - this.handleServiceErrors - ); - router.post( - '/', - CheckPolicies(SaleReceiptAction.Create, AbilitySubject.SaleReceipt), - this.salesReceiptsValidationSchema, - this.validationResult, - asyncMiddleware(this.newSaleReceipt.bind(this)), - this.handleServiceErrors - ); - router.delete( - '/:id', - CheckPolicies(SaleReceiptAction.Delete, AbilitySubject.SaleReceipt), - this.specificReceiptValidationSchema, - this.validationResult, - asyncMiddleware(this.deleteSaleReceipt.bind(this)), - this.handleServiceErrors - ); - router.get( - '/', - CheckPolicies(SaleReceiptAction.View, AbilitySubject.SaleReceipt), - this.listSalesReceiptsValidationSchema, - this.validationResult, - asyncMiddleware(this.getSalesReceipts.bind(this)), - this.handleServiceErrors, - this.dynamicListService.handlerErrorsToResponse - ); - router.get( - '/state', - CheckPolicies(SaleReceiptAction.View, AbilitySubject.SaleReceipt), - asyncMiddleware(this.getSaleReceiptState.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id', - CheckPolicies(SaleReceiptAction.View, AbilitySubject.SaleReceipt), - [...this.specificReceiptValidationSchema], - this.validationResult, - asyncMiddleware(this.getSaleReceipt.bind(this)), - this.handleServiceErrors - ); - return router; - } - - /** - * Sales receipt validation schema. - * @return {Array} - */ - private get salesReceiptsValidationSchema() { - return [ - check('customer_id').exists().isNumeric().toInt(), - check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(), - - check('deposit_account_id').exists().isNumeric().toInt(), - check('receipt_date').exists().isISO8601(), - check('receipt_number').optional().trim(), - check('reference_no').optional().trim(), - check('closed').default(false).isBoolean().toBoolean(), - - check('warehouse_id').optional({ nullable: true }).isNumeric().toInt(), - check('branch_id').optional({ nullable: true }).isNumeric().toInt(), - - check('entries').exists().isArray({ min: 1 }), - - check('entries.*.id').optional({ nullable: true }).isNumeric().toInt(), - check('entries.*.index').exists().isNumeric().toInt(), - check('entries.*.item_id').exists().isNumeric().toInt(), - check('entries.*.quantity').exists().isNumeric().toFloat(), - check('entries.*.rate').exists().isNumeric().toFloat(), - check('entries.*.discount') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - check('entries.*.discount_type') - .default(DiscountType.Percentage) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - check('entries.*.description').optional({ nullable: true }).trim(), - check('entries.*.warehouse_id') - .optional({ nullable: true }) - .isNumeric() - .toInt(), - - check('receipt_message').optional().trim(), - - check('statement').optional().trim(), - check('attachments').isArray().optional(), - check('attachments.*.key').exists().isString(), - - // # Pdf template - check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(), - - // # Discount - check('discount').optional({ nullable: true }).isNumeric().toFloat(), - check('discount_type') - .optional({ nullable: true }) - .isString() - .isIn([DiscountType.Percentage, DiscountType.Amount]), - - // # Adjustment - check('adjustment').optional({ nullable: true }).isNumeric().toFloat(), - ]; - } - - /** - * Specific sale receipt validation schema. - */ - private get specificReceiptValidationSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - /** - * List sales receipts validation schema. - */ - private get listSalesReceiptsValidationSchema() { - return [ - query('view_slug').optional().isString().trim(), - query('stringified_filter_roles').optional().isJSON(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - query('search_keyword').optional({ nullable: true }).isString().trim(), - ]; - } - - /** - * Creates a new receipt. - * @param {Request} req - * @param {Response} res - */ - private async newSaleReceipt( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const saleReceiptDTO: ISaleReceiptDTO = this.matchedBodyData(req); - - try { - // Store the given sale receipt details with associated entries. - const storedSaleReceipt = - await this.saleReceiptsApplication.createSaleReceipt( - tenantId, - saleReceiptDTO - ); - return res.status(200).send({ - id: storedSaleReceipt.id, - message: 'Sale receipt has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the sale receipt with associated entries and journal transactions. - * @param {Request} req - * @param {Response} res - */ - private async deleteSaleReceipt( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: saleReceiptId } = req.params; - - try { - // Deletes the sale receipt. - await this.saleReceiptsApplication.deleteSaleReceipt( - tenantId, - saleReceiptId - ); - return res.status(200).send({ - id: saleReceiptId, - message: 'Sale receipt has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Edit the sale receipt details with associated entries and re-write - * journal transaction on the same date. - * @param {Request} req - - * @param {Response} res - - */ - private async editSaleReceipt( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: saleReceiptId } = req.params; - const saleReceipt = this.matchedBodyData(req); - - try { - // Update the given sale receipt details. - await this.saleReceiptsApplication.editSaleReceipt( - tenantId, - saleReceiptId, - saleReceipt - ); - return res.status(200).send({ - id: saleReceiptId, - message: 'Sale receipt has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Marks the given the sale receipt as closed. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async closeSaleReceipt( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { id: saleReceiptId } = req.params; - - try { - // Update the given sale receipt details. - await this.saleReceiptsApplication.closeSaleReceipt( - tenantId, - saleReceiptId - ); - return res.status(200).send({ - id: saleReceiptId, - message: 'Sale receipt has been closed successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Listing sales receipts. - * @param {Request} req - * @param {Response} res - */ - private async getSalesReceipts( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const filter = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - try { - const salesReceiptsWithPagination = - await this.saleReceiptsApplication.getSaleReceipts(tenantId, filter); - - return res.status(200).send(salesReceiptsWithPagination); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the sale receipt with associated entries. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async getSaleReceipt(req: Request, res: Response) { - const { id: saleReceiptId } = req.params; - const { tenantId } = req; - - const accept = this.accepts(req); - - const acceptType = accept.types([ - ACCEPT_TYPE.APPLICATION_JSON, - ACCEPT_TYPE.APPLICATION_PDF, - ACCEPT_TYPE.APPLICATION_TEXT_HTML, - ]); - // Retrieves receipt in pdf format. - if (ACCEPT_TYPE.APPLICATION_PDF == acceptType) { - const [pdfContent, filename] = - await this.saleReceiptsApplication.getSaleReceiptPdf( - tenantId, - saleReceiptId - ); - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - 'Content-Disposition': `attachment; filename="${filename}"`, - }); - res.send(pdfContent); - // Retrieves receipt in json format. - } else if (ACCEPT_TYPE.APPLICATION_TEXT_HTML === acceptType) { - const htmlContent = await this.saleReceiptsApplication.getSaleReceiptHtml( - tenantId, - saleReceiptId - ); - res.send({ htmlContent }); - } else { - const saleReceipt = await this.saleReceiptsApplication.getSaleReceipt( - tenantId, - saleReceiptId - ); - return res.status(200).send({ saleReceipt }); - } - } - - /** - * - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async getSaleReceiptState( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - // Retrieves receipt in pdf format. - try { - const data = await this.saleReceiptsApplication.getSaleReceiptState( - tenantId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } - - /** - * Sale receipt notification via SMS. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public saleReceiptNotifyBySms = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: receiptId } = req.params; - - try { - const saleReceipt = - await this.saleReceiptsApplication.saleReceiptNotifyBySms( - tenantId, - receiptId - ); - return res.status(200).send({ - id: saleReceipt.id, - message: - 'The sale receipt notification via sms has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Sale receipt sms details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public saleReceiptSmsDetails = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: receiptId } = req.params; - - try { - const smsDetails = - await this.saleReceiptsApplication.getSaleReceiptSmsDetails( - tenantId, - receiptId - ); - return res.status(200).send({ - data: smsDetails, - }); - } catch (error) { - next(error); - } - }; - - /** - * Sends mail notification of the given sale receipt. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public sendSaleReceiptMail = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: receiptId } = req.params; - const receiptMailDTO: SaleReceiptMailOptsDTO = this.matchedBodyData(req, { - includeOptionals: false, - }); - - try { - await this.saleReceiptsApplication.sendSaleReceiptMail( - tenantId, - receiptId, - receiptMailDTO - ); - return res.status(200).send({ - code: 200, - message: - 'The sale receipt notification via sms has been sent successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves the default mail options of the given sale receipt. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public getSaleReceiptMail = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: receiptId } = req.params; - - try { - const data = await this.saleReceiptsApplication.getSaleReceiptMailState( - tenantId, - receiptId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'SALE_RECEIPT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_RECEIPT_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'DEPOSIT_ACCOUNT_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'DEPOSIT_ACCOUNT_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'DEPOSIT_ACCOUNT_NOT_CURRENT_ASSET') { - return res.boom.badRequest(null, { - errors: [{ type: 'DEPOSIT_ACCOUNT_NOT_CURRENT_ASSET', code: 300 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ITEMS_NOT_FOUND', code: 400 }], - }); - } - if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'ENTRIES_IDS_NOT_FOUND', code: 500 }], - }); - } - if (error.errorType === 'NOT_SELL_ABLE_ITEMS') { - return res.boom.badRequest(null, { - errors: [{ type: 'NOT_SELL_ABLE_ITEMS', code: 600 }], - }); - } - if (error.errorType === 'SALE.RECEIPT.NOT.FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE.RECEIPT.NOT.FOUND', code: 700 }], - }); - } - if (error.errorType === 'DEPOSIT.ACCOUNT.NOT.EXISTS') { - return res.boom.badRequest(null, { - errors: [{ type: 'DEPOSIT.ACCOUNT.NOT.EXISTS', code: 800 }], - }); - } - if (error.errorType === 'SALE_RECEIPT_NUMBER_NOT_UNIQUE') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_RECEIPT_NUMBER_NOT_UNIQUE', code: 900 }], - }); - } - if (error.errorType === 'SALE_RECEIPT_IS_ALREADY_CLOSED') { - return res.boom.badRequest(null, { - errors: [{ type: 'SALE_RECEIPT_IS_ALREADY_CLOSED', code: 1000 }], - }); - } - if (error.errorType === 'SALE_RECEIPT_NO_IS_REQUIRED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'SALE_RECEIPT_NO_IS_REQUIRED', - message: 'The sale receipt number is required.', - code: 1100, - }, - ], - }); - } - if (error.errorType === 'CUSTOMER_HAS_NO_PHONE_NUMBER') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_HAS_NO_PHONE_NUMBER', code: 1800 }], - }); - } - if (error.errorType === 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID') { - return res.boom.badRequest(null, { - errors: [{ type: 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID', code: 1900 }], - }); - } - if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'TRANSACTIONS_DATE_LOCKED', - code: 4000, - data: { ...error.payload }, - }, - ], - }); - } - if (error.errorType === 'WAREHOUSE_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'WAREHOUSE_ID_NOT_FOUND', code: 5000 }], - }); - } - if (error.errorType === 'BRANCH_ID_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'BRANCH_ID_REQUIRED', code: 5100 }], - }); - } - if (error.errorType === 'BRANCH_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'BRANCH_ID_NOT_FOUND', code: 5300 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Sales/index.ts b/packages/server/src/api/controllers/Sales/index.ts deleted file mode 100644 index 2e3c987f2..000000000 --- a/packages/server/src/api/controllers/Sales/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Router } from 'express'; -import { Container, Service } from 'typedi'; -import SalesInvoices from './SalesInvoices' -import SalesEstimates from './SalesEstimates'; -import SalesReceipts from './SalesReceipts'; -import CreditNotes from './CreditNotes'; -import PaymentReceives from './PaymentReceives'; -@Service() -export default class SalesController { - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.use('/invoices', Container.get(SalesInvoices).router()); - router.use('/estimates', Container.get(SalesEstimates).router()); - router.use('/receipts', Container.get(SalesReceipts).router()); - router.use('/payment_receives', Container.get(PaymentReceives).router()); - router.use('/credit_notes', Container.get(CreditNotes).router()) - - return router; - } -} \ No newline at end of file diff --git a/packages/server/src/api/controllers/Settings/EasySmsIntegration.ts b/packages/server/src/api/controllers/Settings/EasySmsIntegration.ts deleted file mode 100644 index d62f34b0f..000000000 --- a/packages/server/src/api/controllers/Settings/EasySmsIntegration.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, NextFunction, Response } from 'express'; -import { check } from 'express-validator'; -import { Request } from 'express-validator/src/base'; -import EasySmsIntegration from '@/services/SmsIntegration/EasySmsIntegration'; -import BaseController from '../BaseController'; - -@Service() -export default class EasySmsIntegrationController extends BaseController { - @Inject() - easySmsIntegrationService: EasySmsIntegration; - - /** - * Controller router. - */ - public router = () => { - const router = Router(); - - router.post( - '/easysms/integrate', - [check('token').exists()], - this.integrationEasySms - ); - router.post( - '/easysms/disconnect', - this.disconnectEasysms - ) - router.get('/easysms', this.getIntegrationMeta); - - return router; - }; - - /** - * Easysms integration API. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - private integrationEasySms = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const easysmsIntegrateDTO = this.matchedBodyData(req); - - try { - await this.easySmsIntegrationService.integrate( - tenantId, - easysmsIntegrateDTO - ); - return res.status(200).send({ - message: - 'The system has been integrated with Easysms sms gateway successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the Easysms integration meta. - * @param req - * @param res - * @param next - * @returns - */ - private getIntegrationMeta = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const data = await this.easySmsIntegrationService.getIntegrationMeta( - tenantId - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - * @returns - */ - private disconnectEasysms = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - await this.easySmsIntegrationService.disconnect( - tenantId, - ); - return res.status(200).send({ - message: 'The sms gateway integration has been disconnected successfully.', - }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Settings/Settings.ts b/packages/server/src/api/controllers/Settings/Settings.ts deleted file mode 100644 index b776bdcf9..000000000 --- a/packages/server/src/api/controllers/Settings/Settings.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response } from 'express'; -import { body, query } from 'express-validator'; -import { pick } from 'lodash'; -import { IOptionDTO, IOptionsDTO } from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { AbilitySubject, PreferencesAction } from '@/interfaces'; -import SettingsService from '@/services/Settings/SettingsService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; - -@Service() -export default class SettingsController extends BaseController { - @Inject() - settingsService: SettingsService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/', - CheckPolicies(PreferencesAction.Mutate, AbilitySubject.Preferences), - this.saveSettingsValidationSchema, - this.validationResult, - asyncMiddleware(this.saveSettings.bind(this)) - ); - router.get( - '/', - this.getSettingsSchema, - this.validationResult, - asyncMiddleware(this.getSettings.bind(this)) - ); - return router; - } - - /** - * Save settings validation schema. - */ - private get saveSettingsValidationSchema() { - return [ - body('options').isArray({ min: 1 }), - body('options.*.key').exists().trim().isLength({ min: 1 }), - body('options.*.value').exists().trim(), - body('options.*.group').exists().trim().isLength({ min: 1 }), - ]; - } - - /** - * Retrieve the application options from the storage. - */ - private get getSettingsSchema() { - return [query('key').optional().trim(), query('group').optional().trim()]; - } - - /** - * Saves the given options to the storage. - * @param {Request} req - - * @param {Response} res - - */ - public async saveSettings(req: Request, res: Response, next) { - const { tenantId } = req; - const optionsDTO: IOptionsDTO = this.matchedBodyData(req); - const { settings } = req; - - const errorReasons: { type: string; code: number; keys: [] }[] = []; - const notDefinedOptions = this.settingsService.validateNotDefinedSettings( - tenantId, - optionsDTO.options - ); - - if (notDefinedOptions.length) { - errorReasons.push({ - type: 'OPTIONS.KEY.NOT.DEFINED', - code: 200, - keys: notDefinedOptions.map((o) => ({ ...pick(o, ['key', 'group']) })), - }); - } - if (errorReasons.length) { - return res.status(400).send({ errors: errorReasons }); - } - optionsDTO.options.forEach((option: IOptionDTO) => { - settings.set({ ...option }); - }); - try { - await settings.save(); - - return res.status(200).send({ - type: 'success', - code: 'OPTIONS.SAVED.SUCCESSFULLY', - message: 'Options have been saved successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve settings. - * @param {Request} req - * @param {Response} res - */ - public getSettings(req: Request, res: Response) { - const { settings } = req; - const allSettings = settings.all(); - - return res.status(200).send({ settings: allSettings }); - } -} diff --git a/packages/server/src/api/controllers/Settings/SmsNotificationsSettings.ts b/packages/server/src/api/controllers/Settings/SmsNotificationsSettings.ts deleted file mode 100644 index 40d396ce1..000000000 --- a/packages/server/src/api/controllers/Settings/SmsNotificationsSettings.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { check, oneOf, param } from 'express-validator'; -import { Router, Response, Request, NextFunction } from 'express'; - -import SmsNotificationsSettingsService from '@/services/Settings/SmsNotificationsSettings'; -import BaseController from '../BaseController'; - -import { ServiceError } from '@/exceptions'; -import { - AbilitySubject, - PreferencesAction, - IEditSmsNotificationDTO, -} from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; - -@Service() -export default class SettingsController extends BaseController { - @Inject() - smsNotificationsSettings: SmsNotificationsSettingsService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/sms-notifications', - [], - this.validationResult, - this.asyncMiddleware(this.smsNotifications), - this.handleServiceErrors - ); - router.get( - '/sms-notification/:notification_key', - [param('notification_key').exists().isString()], - this.validationResult, - this.asyncMiddleware(this.smsNotification), - this.handleServiceErrors - ); - router.post( - '/sms-notification', - CheckPolicies(PreferencesAction.Mutate, AbilitySubject.Preferences), - [ - check('notification_key').exists(), - oneOf([ - check('message_text').exists(), - check('is_notification_enabled').exists().isBoolean().toBoolean(), - ]), - ], - this.validationResult, - this.asyncMiddleware(this.updateSmsNotification), - this.handleServiceErrors - ); - return router; - } - - /** - * Retrieve the sms notifications. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private smsNotifications = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const notifications = - await this.smsNotificationsSettings.smsNotificationsList(tenantId); - - return res.status(200).send({ notifications }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve the sms notification details from the given notification key. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private smsNotification = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { notification_key: notificationKey } = req.params; - - try { - const notification = - await this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - notificationKey - ); - - return res.status(200).send({ notification }); - } catch (error) { - next(error); - } - }; - - /** - * Update the given sms notification key. - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private updateSmsNotification = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const editDTO: IEditSmsNotificationDTO = this.matchedBodyData(req); - - try { - await this.smsNotificationsSettings.editSmsNotificationMessage( - tenantId, - editDTO - ); - return res.status(200).send({ - message: 'Sms notification settings has been updated successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors = ( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) => { - if (error instanceof ServiceError) { - if (error.errorType === 'SMS_NOTIFICATION_KEY_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'SMS_NOTIFICATION_KEY_NOT_FOUND', code: 1000 }], - }); - } - if (error.errorType === 'UNSUPPORTED_SMS_MESSAGE_VARIABLES') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'UNSUPPORTED_SMS_MESSAGE_VARIABLES', - code: 1100, - data: { ...error.payload }, - }, - ], - }); - } - } - next(error); - }; -} diff --git a/packages/server/src/api/controllers/Settings/index.ts b/packages/server/src/api/controllers/Settings/index.ts deleted file mode 100644 index 6a625bf76..000000000 --- a/packages/server/src/api/controllers/Settings/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Router } from 'express'; -import { Container, Service } from 'typedi'; -import SmsNotificationSettings from './SmsNotificationsSettings'; -import Settings from './Settings'; -import EasySmsIntegrationController from './EasySmsIntegration'; -import { AbilitySubject, PreferencesAction } from '@/interfaces'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; - -@Service() -export default class SettingsController { - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.use('/', Container.get(EasySmsIntegrationController).router()); - router.use('/', Container.get(SmsNotificationSettings).router()); - router.use('/', Container.get(Settings).router()); - - return router; - } -} diff --git a/packages/server/src/api/controllers/ShareLink/PublicSharableLinkController.ts b/packages/server/src/api/controllers/ShareLink/PublicSharableLinkController.ts deleted file mode 100644 index aae07abe7..000000000 --- a/packages/server/src/api/controllers/ShareLink/PublicSharableLinkController.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { PaymentLinksApplication } from '@/services/PaymentLinks/PaymentLinksApplication'; - -@Service() -export class PublicSharableLinkController extends BaseController { - @Inject() - private paymentLinkApp: PaymentLinksApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/:paymentLinkId/invoice', - [param('paymentLinkId').exists()], - this.validationResult, - this.getPaymentLinkPublicMeta.bind(this), - this.validationResult - ); - router.get( - '/:paymentLinkId/invoice/pdf', - [param('paymentLinkId').exists()], - this.validationResult, - this.getPaymentLinkInvoicePdf.bind(this), - this.validationResult - ); - router.post( - '/:paymentLinkId/stripe_checkout_session', - [param('paymentLinkId').exists()], - this.validationResult, - this.createInvoicePaymentLinkCheckoutSession.bind(this) - ); - return router; - } - - /** - * Retrieves the payment link public meta. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - public async getPaymentLinkPublicMeta( - req: Request<{ paymentLinkId: string }>, - res: Response, - next: NextFunction - ) { - const { paymentLinkId } = req.params; - - try { - const data = await this.paymentLinkApp.getInvoicePaymentLink( - paymentLinkId - ); - - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - } - - /** - * Creates a Stripe checkout session for the given payment link id. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - public async createInvoicePaymentLinkCheckoutSession( - req: Request<{ paymentLinkId: string }>, - res: Response, - next: NextFunction - ) { - const { paymentLinkId } = req.params; - - try { - const session = - await this.paymentLinkApp.createInvoicePaymentCheckoutSession( - paymentLinkId - ); - return res.status(200).send(session); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the sale invoice pdf of the given payment link. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async getPaymentLinkInvoicePdf( - req: Request<{ paymentLinkId: string }>, - res: Response, - next: NextFunction - ) { - const { paymentLinkId } = req.params; - - try { - const [pdfContent, filename] = - await this.paymentLinkApp.getPaymentLinkInvoicePdf(paymentLinkId); - - res.set({ - 'Content-Type': 'application/pdf', - 'Content-Length': pdfContent.length, - 'Content-Disposition': `attachment; filename="${filename}"`, - }); - res.send(pdfContent); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/ShareLink/ShareLinkController.ts b/packages/server/src/api/controllers/ShareLink/ShareLinkController.ts deleted file mode 100644 index a06e7bb06..000000000 --- a/packages/server/src/api/controllers/ShareLink/ShareLinkController.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { body } from 'express-validator'; -import { AbilitySubject, PaymentReceiveAction } from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { GenerateShareLink } from '@/services/Sales/Invoices/GenerateeInvoicePaymentLink'; - -@Service() -export class ShareLinkController extends BaseController { - @Inject() - private generateShareLinkService: GenerateShareLink; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.post( - '/payment-links/generate', - CheckPolicies(PaymentReceiveAction.Edit, AbilitySubject.PaymentReceive), - [ - body('transaction_type').exists(), - body('transaction_id').exists().isNumeric().toInt(), - body('publicity').optional(), - body('expiry_date').optional({ nullable: true }), - ], - this.validationResult, - asyncMiddleware(this.generateShareLink.bind(this)) - ); - return router; - } - - /** - * Generates sharable link for the given transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async generateShareLink( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { transactionType, transactionId, publicity, expiryDate } = - this.matchedBodyData(req); - - try { - const link = await this.generateShareLinkService.generatePaymentLink( - tenantId, - transactionId, - publicity, - expiryDate - ); - res.status(200).json({ link }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/StripeIntegration/StripeIntegrationController.ts b/packages/server/src/api/controllers/StripeIntegration/StripeIntegrationController.ts deleted file mode 100644 index bd992a77e..000000000 --- a/packages/server/src/api/controllers/StripeIntegration/StripeIntegrationController.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { NextFunction, Request, Response, Router } from 'express'; -import { body } from 'express-validator'; -import { Service, Inject } from 'typedi'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { StripePaymentApplication } from '@/services/StripePayment/StripePaymentApplication'; -import BaseController from '../BaseController'; - -@Service() -export class StripeIntegrationController extends BaseController { - @Inject() - private stripePaymentApp: StripePaymentApplication; - - public router() { - const router = Router(); - - router.get('/link', this.getStripeConnectLink.bind(this)); - router.post( - '/callback', - [body('code').exists()], - this.validationResult, - this.exchangeOAuth.bind(this) - ); - router.post('/account', asyncMiddleware(this.createAccount.bind(this))); - router.post( - '/account_link', - [body('stripe_account_id').exists()], - this.validationResult, - asyncMiddleware(this.createAccountLink.bind(this)) - ); - return router; - } - - /** - * Retrieves Stripe OAuth2 connect link. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - public async getStripeConnectLink( - req: Request, - res: Response, - next: NextFunction - ) { - try { - const authorizationUri = this.stripePaymentApp.getStripeConnectLink(); - - return res.status(200).send({ url: authorizationUri }); - } catch (error) { - next(error); - } - } - - /** - * Exchanges the given Stripe authorization code to Stripe user id and access token. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - public async exchangeOAuth(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { code } = this.matchedBodyData(req); - - try { - await this.stripePaymentApp.exchangeStripeOAuthToken(tenantId, code); - - return res.status(200).send({}); - } catch (error) { - next(error); - } - } - - /** - * Creates a new Stripe account. - * @param {Request} req - The Express request object. - * @param {Response} res - The Express response object. - * @param {NextFunction} next - The Express next middleware function. - * @returns {Promise} - */ - public async createAccount(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - try { - const accountId = await this.stripePaymentApp.createStripeAccount( - tenantId - ); - return res.status(201).json({ - accountId, - message: 'The Stripe account has been created successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Creates a new Stripe account session. - * @param {Request} req - The Express request object. - * @param {Response} res - The Express response object. - * @param {NextFunction} next - The Express next middleware function. - * @returns {Promise} - */ - public async createAccountLink( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { stripeAccountId } = this.matchedBodyData(req); - - try { - const clientSecret = await this.stripePaymentApp.createAccountLink( - tenantId, - stripeAccountId - ); - return res.status(200).json({ clientSecret }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/StripeIntegration/StripeWebhooksController.ts b/packages/server/src/api/controllers/StripeIntegration/StripeWebhooksController.ts deleted file mode 100644 index fbe4098de..000000000 --- a/packages/server/src/api/controllers/StripeIntegration/StripeWebhooksController.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { NextFunction, Request, Response, Router } from 'express'; -import { Inject, Service } from 'typedi'; -import bodyParser from 'body-parser'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { StripeWebhookEventPayload } from '@/interfaces/StripePayment'; -import { StripePaymentService } from '@/services/StripePayment/StripePaymentService'; -import events from '@/subscribers/events'; -import config from '@/config'; - -@Service() -export class StripeWebhooksController { - @Inject() - private stripePaymentService: StripePaymentService; - - @Inject() - private eventPublisher: EventPublisher; - - public router() { - const router = Router(); - - router.post( - '/stripe', - bodyParser.raw({ type: 'application/json' }), - this.handleWebhook.bind(this) - ); - return router; - } - - /** - * Handles incoming Stripe webhook events. - * Verifies the webhook signature, processes the event based on its type, - * and triggers appropriate actions or events in the system. - * - * @param {Request} req - The Express request object containing the webhook payload. - * @param {Response} res - The Express response object. - * @param {NextFunction} next - The Express next middleware function. - */ - private async handleWebhook(req: Request, res: Response, next: NextFunction) { - try { - let event = req.body; - const sig = req.headers['stripe-signature']; - - // Verify webhook signature and extract the event. - // See https://stripe.com/docs/webhooks#verify-events for more information. - try { - event = this.stripePaymentService.stripe.webhooks.constructEvent( - req.rawBody, - sig, - config.stripePayment.webhooksSecret - ); - } catch (err) { - return res.status(400).send(`Webhook Error: ${err.message}`); - } - // Handle the event based on its type - switch (event.type) { - case 'checkout.session.completed': - // Triggers `onStripeCheckoutSessionCompleted` event. - this.eventPublisher.emitAsync( - events.stripeWebhooks.onCheckoutSessionCompleted, - { - event, - } as StripeWebhookEventPayload - ); - break; - case 'account.updated': - this.eventPublisher.emitAsync( - events.stripeWebhooks.onAccountUpdated, - { - event, - } as StripeWebhookEventPayload - ); - break; - // Add more cases as needed - default: - console.log(`Unhandled event type ${event.type}`); - } - - res.status(200).json({ received: true }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Subscription/SubscriptionController.ts b/packages/server/src/api/controllers/Subscription/SubscriptionController.ts deleted file mode 100644 index 4c51b776a..000000000 --- a/packages/server/src/api/controllers/Subscription/SubscriptionController.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import { body } from 'express-validator'; -import JWTAuth from '@/api/middleware/jwtAuth'; -import TenancyMiddleware from '@/api/middleware/TenancyMiddleware'; -import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser'; -import SubscriptionService from '@/services/Subscription/SubscriptionService'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '../BaseController'; -import { LemonSqueezyService } from '@/services/Subscription/LemonSqueezyService'; -import { SubscriptionApplication } from '@/services/Subscription/SubscriptionApplication'; - -@Service() -export class SubscriptionController extends BaseController { - @Inject() - private subscriptionService: SubscriptionService; - - @Inject() - private lemonSqueezyService: LemonSqueezyService; - - @Inject() - private subscriptionApp: SubscriptionApplication; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.use(JWTAuth); - router.use(AttachCurrentTenantUser); - router.use(TenancyMiddleware); - - router.post( - '/lemon/checkout_url', - [body('variantId').exists().trim()], - this.validationResult, - this.getCheckoutUrl.bind(this) - ); - router.post('/cancel', asyncMiddleware(this.cancelSubscription.bind(this))); - router.post('/resume', asyncMiddleware(this.resumeSubscription.bind(this))); - router.post( - '/change', - [body('variant_id').exists().trim()], - this.validationResult, - asyncMiddleware(this.changeSubscriptionPlan.bind(this)) - ); - router.get('/', asyncMiddleware(this.getSubscriptions.bind(this))); - - return router; - } - - /** - * Retrieve all subscriptions of the authenticated user's tenant. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getSubscriptions( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - const subscriptions = await this.subscriptionService.getSubscriptions( - tenantId - ); - return res.status(200).send({ subscriptions }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the LemonSqueezy checkout url. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private async getCheckoutUrl( - req: Request, - res: Response, - next: NextFunction - ) { - const { variantId } = this.matchedBodyData(req); - const { user } = req; - - try { - const checkout = await this.lemonSqueezyService.getCheckout( - variantId, - user - ); - return res.status(200).send(checkout); - } catch (error) { - next(error); - } - } - - /** - * Cancels the subscription of the current organization. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async cancelSubscription( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - await this.subscriptionApp.cancelSubscription(tenantId); - - return res.status(200).send({ - status: 200, - message: 'The organization subscription has been canceled.', - }); - } catch (error) { - next(error); - } - } - - /** - * Resumes the subscription of the current organization. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - private async resumeSubscription( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - - try { - await this.subscriptionApp.resumeSubscription(tenantId); - - return res.status(200).send({ - status: 200, - message: 'The organization subscription has been resumed.', - }); - } catch (error) { - next(error); - } - } - - /** - * Changes the main subscription plan of the current organization. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Promise} - */ - public async changeSubscriptionPlan( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const body = this.matchedBodyData(req); - - try { - await this.subscriptionApp.changeSubscriptionPlan( - tenantId, - body.variantId - ); - return res.status(200).send({ - message: 'The subscription plan has been changed.', - }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/controllers/Subscription/index.ts b/packages/server/src/api/controllers/Subscription/index.ts deleted file mode 100644 index 67ff37623..000000000 --- a/packages/server/src/api/controllers/Subscription/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SubscriptionController'; \ No newline at end of file diff --git a/packages/server/src/api/controllers/TaxRates/TaxRates.ts b/packages/server/src/api/controllers/TaxRates/TaxRates.ts deleted file mode 100644 index f60c7e0e2..000000000 --- a/packages/server/src/api/controllers/TaxRates/TaxRates.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, Response } from 'express'; -import { body, param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import { TaxRatesApplication } from '@/services/TaxRates/TaxRatesApplication'; -import CheckAbilities from '@/api/middleware/CheckPolicies'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from '@/services/TaxRates/constants'; -import { AbilitySubject, TaxRateAction } from '@/interfaces'; - -@Service() -export class TaxRatesController extends BaseController { - @Inject() - private taxRatesApplication: TaxRatesApplication; - - /** - * Router constructor. - */ - public router() { - const router = Router(); - - router.post( - '/', - CheckAbilities(TaxRateAction.CREATE, AbilitySubject.TaxRate), - this.taxRateValidationSchema, - this.validationResult, - asyncMiddleware(this.createTaxRate.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id', - CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate), - [param('id').exists().toInt(), ...this.taxRateValidationSchema], - this.validationResult, - asyncMiddleware(this.editTaxRate.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/active', - CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate), - [param('id').exists().toInt()], - this.validationResult, - asyncMiddleware(this.activateTaxRate.bind(this)), - this.handleServiceErrors - ); - router.post( - '/:id/inactive', - CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate), - [param('id').exists().toInt()], - this.validationResult, - asyncMiddleware(this.inactivateTaxRate.bind(this)), - this.handleServiceErrors - ); - router.delete( - '/:id', - CheckAbilities(TaxRateAction.DELETE, AbilitySubject.TaxRate), - [param('id').exists().toInt()], - this.validationResult, - asyncMiddleware(this.deleteTaxRate.bind(this)), - this.handleServiceErrors - ); - router.get( - '/:id', - CheckAbilities(TaxRateAction.VIEW, AbilitySubject.TaxRate), - [param('id').exists().toInt()], - this.validationResult, - asyncMiddleware(this.getTaxRate.bind(this)), - this.handleServiceErrors - ); - router.get( - '/', - CheckAbilities(TaxRateAction.VIEW, AbilitySubject.TaxRate), - this.validationResult, - asyncMiddleware(this.getTaxRates.bind(this)), - this.handleServiceErrors - ); - return router; - } - - /** - * Tax rate validation schema. - */ - private get taxRateValidationSchema() { - return [ - body('name').exists(), - body('code').exists().isString(), - body('rate').exists().isNumeric().toFloat(), - body('description').optional().trim().isString(), - body('is_non_recoverable').optional().isBoolean().default(false), - body('is_compound').optional().isBoolean().default(false), - body('active').optional().isBoolean().default(false), - ]; - } - - /** - * Creates a new tax rate. - * @param {Request} req - - * @param {Response} res - - */ - public async createTaxRate(req: Request, res: Response, next) { - const { tenantId } = req; - const createTaxRateDTO = this.matchedBodyData(req); - - try { - const taxRate = await this.taxRatesApplication.createTaxRate( - tenantId, - createTaxRateDTO - ); - return res.status(200).send({ - data: taxRate, - }); - } catch (error) { - next(error); - } - } - - /** - * Edits the given tax rate. - * @param {Request} req - - * @param {Response} res - - */ - public async editTaxRate(req: Request, res: Response, next) { - const { tenantId } = req; - const editTaxRateDTO = this.matchedBodyData(req); - const { id: taxRateId } = req.params; - - try { - const taxRate = await this.taxRatesApplication.editTaxRate( - tenantId, - taxRateId, - editTaxRateDTO - ); - return res.status(200).send({ - data: taxRate, - }); - } catch (error) { - next(error); - } - } - - /** - * Deletes the given tax rate. - * @param {Request} req - - * @param {Response} res - - */ - public async deleteTaxRate(req: Request, res: Response, next) { - const { tenantId } = req; - const { id: taxRateId } = req.params; - - try { - await this.taxRatesApplication.deleteTaxRate(tenantId, taxRateId); - - return res.status(200).send({ - code: 200, - message: 'The tax rate has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the given tax rate. - * @param {Request} req - - * @param {Response} res - - */ - public async getTaxRate(req: Request, res: Response, next) { - const { tenantId } = req; - const { id: taxRateId } = req.params; - - try { - const taxRate = await this.taxRatesApplication.getTaxRate( - tenantId, - taxRateId - ); - return res.status(200).send({ data: taxRate }); - } catch (error) { - next(error); - } - } - - /** - * Retrieves the tax rates list. - * @param {Request} req - - * @param {Response} res - - */ - public async getTaxRates(req: Request, res: Response, next) { - const { tenantId } = req; - - try { - const taxRates = await this.taxRatesApplication.getTaxRates(tenantId); - - return res.status(200).send({ data: taxRates }); - } catch (error) { - next(error); - } - } - - /** - * Inactivates the given tax rate. - * @param req - * @param res - * @param next - * @returns - */ - public async inactivateTaxRate(req: Request, res: Response, next) { - const { tenantId } = req; - const { id: taxRateId } = req.params; - - try { - await this.taxRatesApplication.inactivateTaxRate(tenantId, taxRateId); - - return res.status(200).send({ - id: taxRateId, - message: 'The given tax rate has been inactivated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Inactivates the given tax rate. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns - */ - public async activateTaxRate(req: Request, res: Response, next) { - const { tenantId } = req; - const { id: taxRateId } = req.params; - - try { - await this.taxRatesApplication.activateTaxRate(tenantId, taxRateId); - - return res.status(200).send({ - id: taxRateId, - message: 'The given tax rate has been activated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handleServiceErrors(error: Error, req: Request, res: Response, next) { - if (error instanceof ServiceError) { - if (error.errorType === ERRORS.TAX_CODE_NOT_UNIQUE) { - return res.boom.badRequest(null, { - errors: [{ type: ERRORS.TAX_CODE_NOT_UNIQUE, code: 100 }], - }); - } - if (error.errorType === ERRORS.TAX_RATE_NOT_FOUND) { - return res.boom.badRequest(null, { - errors: [{ type: ERRORS.TAX_RATE_NOT_FOUND, code: 200 }], - }); - } - if (error.errorType === ERRORS.TAX_RATE_ALREADY_INACTIVE) { - return res.boom.badRequest(null, { - errors: [{ type: ERRORS.TAX_RATE_ALREADY_INACTIVE, code: 300 }], - }); - } - if (error.errorType === ERRORS.TAX_RATE_ALREADY_ACTIVE) { - return res.boom.badRequest(null, { - errors: [{ type: ERRORS.TAX_RATE_ALREADY_ACTIVE, code: 400 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/TransactionsLocking/index.ts b/packages/server/src/api/controllers/TransactionsLocking/index.ts deleted file mode 100644 index 300c4e81e..000000000 --- a/packages/server/src/api/controllers/TransactionsLocking/index.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { check, param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import TransactionsLockingService from '@/services/TransactionsLocking/CommandTransactionsLockingService'; -import CheckPolicies from '@/api/middleware/CheckPolicies'; -import { AbilitySubject, AccountAction } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import QueryTransactionsLocking from '@/services/TransactionsLocking/QueryTransactionsLocking'; - -@Service() -export default class TransactionsLockingController extends BaseController { - @Inject() - private transactionsLockingService: TransactionsLockingService; - - @Inject() - private queryTransactionsLocking: QueryTransactionsLocking; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.put( - '/lock', - CheckPolicies(AccountAction.TransactionsLocking, AbilitySubject.Account), - [ - check('module') - .exists() - .isIn(['all', 'sales', 'purchases', 'financial']), - check('lock_to_date').exists().isISO8601().toDate(), - check('reason').exists().trim(), - ], - this.validationResult, - this.asyncMiddleware(this.commandTransactionsLocking), - this.handleServiceErrors - ); - router.put( - '/cancel-lock', - CheckPolicies(AccountAction.TransactionsLocking, AbilitySubject.Account), - [check('module').exists(), check('reason').exists().trim()], - this.validationResult, - this.asyncMiddleware(this.cancelTransactionsLocking), - this.handleServiceErrors - ); - router.put( - '/unlock-partial', - CheckPolicies(AccountAction.TransactionsLocking, AbilitySubject.Account), - [ - check('module').exists(), - check('unlock_from_date').exists().isISO8601().toDate(), - check('unlock_to_date').exists().isISO8601().toDate(), - check('reason').exists().trim(), - ], - this.validationResult, - this.asyncMiddleware(this.unlockTransactionsLockingBetweenPeriod), - this.handleServiceErrors - ); - router.put( - '/cancel-unlock-partial', - CheckPolicies(AccountAction.TransactionsLocking, AbilitySubject.Account), - [ - check('module').exists(), - check('reason').optional({ nullable: true }).trim(), - ], - this.validationResult, - this.asyncMiddleware(this.cancelPartialUnlocking), - this.handleServiceErrors - ); - router.get( - '/', - this.validationResult, - this.asyncMiddleware(this.getTransactionLockingMetaList), - this.handleServiceErrors - ); - router.get( - '/:module', - [param('module').exists()], - this.validationResult, - this.asyncMiddleware(this.getTransactionLockingMeta), - this.handleServiceErrors - ); - return router; - } - - /** - * Retrieve accounts types list. - * @param {Request} req - Request. - * @param {Response} res - Response. - * @return {Response} - */ - private commandTransactionsLocking = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { module, ...allTransactionsDTO } = this.matchedBodyData(req); - - try { - const transactionMeta = - await this.transactionsLockingService.commandTransactionsLocking( - tenantId, - module, - allTransactionsDTO - ); - return res.status(200).send({ - message: 'All transactions locking has been submit successfully.', - data: transactionMeta, - }); - } catch (error) { - next(error); - } - }; - - /** - * Unlock transactions locking between the given periods. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private unlockTransactionsLockingBetweenPeriod = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { module, ...unlockDTO } = this.matchedBodyData(req); - - try { - const transactionMeta = - await this.transactionsLockingService.unlockTransactionsLockingPartially( - tenantId, - module, - unlockDTO - ); - return res.status(200).send({ - message: - 'Transactions locking haas been unlocked partially successfully.', - data: transactionMeta, - }); - } catch (error) { - next(error); - } - }; - - /** - * Cancel full transactions locking of the given module. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private cancelTransactionsLocking = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { module, ...cancelLockingDTO } = this.matchedBodyData(req); - - try { - const data = - await this.transactionsLockingService.cancelTransactionLocking( - tenantId, - module, - cancelLockingDTO - ); - return res.status(200).send({ - message: 'Transactions locking has been canceled successfully.', - data, - }); - } catch (error) { - next(error); - } - }; - - /** - * Cancel transaction partial unlocking. - * @param req - * @param res - * @param next - * @returns - */ - private cancelPartialUnlocking = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { module } = this.matchedBodyData(req); - - try { - const transactionMeta = - await this.transactionsLockingService.cancelPartialTransactionsUnlock( - tenantId, - module - ); - return res.status(200).send({ - message: - 'Partial transaction unlocking has been canceled successfully.', - data: transactionMeta, - }); - } catch (error) { - next(error); - } - }; - - private getTransactionLockingMeta = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { module } = req.params; - const { tenantId } = req; - - try { - const data = - await this.queryTransactionsLocking.getTransactionsLockingModuleMeta( - tenantId, - module - ); - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieve transactions locking meta list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private getTransactionLockingMetaList = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { module } = req.params; - const { tenantId } = req; - - try { - const data = - await this.queryTransactionsLocking.getTransactionsLockingList( - tenantId - ); - - return res.status(200).send({ data }); - } catch (error) { - next(error); - } - }; - - /** - * Handle the service errors. - * @param {Error} error - - * @param {Request} req - - * @param {Response} res - - * @param {NextFunction} next - - */ - private handleServiceErrors = ( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) => { - if (error instanceof ServiceError) { - if (error.errorType === 'TRANSACTION_LOCKING_ALL') { - return res.boom.badRequest(null, { - errors: [{ type: 'TRANSACTION_LOCKING_ALL', code: 100 }], - }); - } - if (error.errorType === 'TRANSACTIONS_LOCKING_MODULE_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [ - { type: 'TRANSACTIONS_LOCKING_MODULE_NOT_FOUND', code: 100 }, - ], - }); - } - } - next(error); - }; -} diff --git a/packages/server/src/api/controllers/TransactionsLocking/utils.ts b/packages/server/src/api/controllers/TransactionsLocking/utils.ts deleted file mode 100644 index 5f518daed..000000000 --- a/packages/server/src/api/controllers/TransactionsLocking/utils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { chain, mapKeys } from 'lodash'; - -export const getTransactionsLockingSettingsSchema = (modules: string[]) => { - const moduleSchema = { - active: { type: 'boolean' }, - lock_to_date: { type: 'date' }, - unlock_from_date: { type: 'date' }, - unlock_to_date: { type: 'date' }, - lock_reason: { type: 'string' }, - unlock_reason: { type: 'string' }, - }; - return chain(modules) - .map((module: string) => { - return mapKeys(moduleSchema, (value, key: string) => `${module}.${key}`); - }) - .flattenDeep() - .reduce((result, value) => { - return { - ...result, - ...value, - }; - }, {}) - .value(); -}; diff --git a/packages/server/src/api/controllers/Users.ts b/packages/server/src/api/controllers/Users.ts deleted file mode 100644 index 39f438cdb..000000000 --- a/packages/server/src/api/controllers/Users.ts +++ /dev/null @@ -1,289 +0,0 @@ -import { Router, Request, Response, NextFunction } from 'express'; -import { Service, Inject } from 'typedi'; -import { check, query, param } from 'express-validator'; -import JWTAuth from '@/api/middleware/jwtAuth'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import BaseController from '@/api/controllers/BaseController'; -import UsersService from '@/services/Users/UsersService'; -import TenancyMiddleware from '@/api/middleware/TenancyMiddleware'; -import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser'; -import { ServiceError, ServiceErrors } from '@/exceptions'; -import { IEditUserDTO, ISystemUserDTO } from '@/interfaces'; - -@Service() -export default class UsersController extends BaseController { - @Inject() - usersService: UsersService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.use(JWTAuth); - router.use(AttachCurrentTenantUser); - router.use(TenancyMiddleware); - - router.put( - '/:id/inactivate', - [...this.specificUserSchema], - this.validationResult, - asyncMiddleware(this.inactivateUser.bind(this)), - this.catchServiceErrors - ); - router.put( - '/:id/activate', - [...this.specificUserSchema], - this.validationResult, - asyncMiddleware(this.activateUser.bind(this)), - this.catchServiceErrors - ); - router.post( - '/:id', - [ - param('id').exists().isNumeric().toInt(), - - check('first_name').exists(), - check('last_name').exists(), - check('email').exists().isEmail(), - check('role_id').exists().isNumeric().toInt(), - ], - this.validationResult, - asyncMiddleware(this.editUser.bind(this)), - this.catchServiceErrors - ); - router.get( - '/', - this.listUsersSchema, - this.validationResult, - asyncMiddleware(this.listUsers.bind(this)) - ); - router.get( - '/:id', - [...this.specificUserSchema], - this.validationResult, - asyncMiddleware(this.getUser.bind(this)), - this.catchServiceErrors - ); - router.delete( - '/:id', - [...this.specificUserSchema], - this.validationResult, - asyncMiddleware(this.deleteUser.bind(this)), - this.catchServiceErrors - ); - return router; - } - - /** - * User DTO Schema. - */ - get userDTOSchema() { - return []; - } - - get specificUserSchema() { - return [param('id').exists().isNumeric().toInt()]; - } - - get listUsersSchema() { - return [ - query('page_size').optional().isNumeric().toInt(), - query('page').optional().isNumeric().toInt(), - ]; - } - - /** - * Edit details of the given user. - * @param {Request} req - * @param {Response} res - * @return {Response|void} - */ - async editUser(req: Request, res: Response, next: NextFunction) { - const editUserDTO: IEditUserDTO = this.matchedBodyData(req); - const { tenantId, user: authorizedUser } = req; - const { id: userId } = req.params; - - try { - await this.usersService.editUser( - tenantId, - userId, - editUserDTO, - authorizedUser - ); - return res.status(200).send({ - id: userId, - message: 'The user has been edited successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Soft deleting the given user. - * @param {Request} req - * @param {Response} res - * @return {Response|void} - */ - async deleteUser(req: Request, res: Response, next: Function) { - const { id } = req.params; - const { tenantId } = req; - - try { - await this.usersService.deleteUser(tenantId, id); - - return res.status(200).send({ - id, - message: 'The user has been deleted successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve user details of the given user id. - * @param {Request} req - * @param {Response} res - * @return {Response|void} - */ - async getUser(req: Request, res: Response, next: NextFunction) { - const { id: userId } = req.params; - const { tenantId } = req; - - try { - const user = await this.usersService.getUser(tenantId, userId); - - return res.status(200).send({ user }); - } catch (error) { - next(error); - } - } - - /** - * Retrieve the list of users. - * @param {Request} req - * @param {Response} res - * @return {Response|void} - */ - async listUsers(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - try { - const users = await this.usersService.getList(tenantId); - - return res.status(200).send({ users }); - } catch (error) { - next(error); - } - } - - /** - * Activate the given user. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async activateUser(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: userId } = req.params; - - try { - await this.usersService.activateUser(tenantId, userId, user); - - return res.status(200).send({ - id: userId, - message: 'The user has been activated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Inactivate the given user. - * @param {Request} req - * @param {Response} res - * @return {Response|void} - */ - async inactivateUser(req: Request, res: Response, next: NextFunction) { - const { tenantId, user } = req; - const { id: userId } = req.params; - - try { - await this.usersService.inactivateUser(tenantId, userId, user); - - return res.status(200).send({ - id: userId, - message: 'The user has been inactivated successfully.', - }); - } catch (error) { - next(error); - } - } - - /** - * Catches all users service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private catchServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'USER_NOT_FOUND') { - return res.boom.badRequest('User not found.', { - errors: [{ type: 'USER.NOT.FOUND', code: 100 }], - }); - } - if (error.errorType === 'USER_ALREADY_ACTIVE') { - return res.boom.badRequest('User is already active.', { - errors: [{ type: 'USER.ALREADY.ACTIVE', code: 200 }], - }); - } - if (error.errorType === 'USER_ALREADY_INACTIVE') { - return res.boom.badRequest('User is already inactive.', { - errors: [{ type: 'USER.ALREADY.INACTIVE', code: 200 }], - }); - } - if (error.errorType === 'USER_SAME_THE_AUTHORIZED_USER') { - return res.boom.badRequest( - 'You could not activate/inactivate the same authorized user.', - { - errors: [ - { type: 'CANNOT.TOGGLE.ACTIVATE.AUTHORIZED.USER', code: 300 }, - ], - } - ); - } - if (error.errorType === 'CANNOT_DELETE_LAST_USER') { - return res.boom.badRequest( - 'Cannot delete last user in the organization.', - { errors: [{ type: 'CANNOT_DELETE_LAST_USER', code: 400 }] } - ); - } - if (error.errorType === 'EMAIL_ALREADY_EXISTS') { - return res.boom.badRequest('Exmail is already exists.', { - errors: [{ type: 'EMAIL_ALREADY_EXISTS', code: 500 }], - }); - } - if (error.errorType === 'PHONE_NUMBER_ALREADY_EXIST') { - return res.boom.badRequest('Phone number is already exists.', { - errors: [{ type: 'PHONE_NUMBER_ALREADY_EXIST', code: 600 }], - }); - } - if (error.errorType === 'CANNOT_AUTHORIZED_USER_MUTATE_ROLE') { - return res.boom.badRequest('Cannout mutate authorized user role.', { - errors: [{ type: 'CANNOT_AUTHORIZED_USER_MUTATE_ROLE', code: 700 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Views.ts b/packages/server/src/api/controllers/Views.ts deleted file mode 100644 index b21b63751..000000000 --- a/packages/server/src/api/controllers/Views.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Router, Request, NextFunction, Response } from 'express'; -import { check, param } from 'express-validator'; -import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import ViewsService from '@/services/Views/ViewsService'; -import BaseController from '@/api/controllers/BaseController'; -import { IViewDTO, IViewEditDTO } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; - -@Service() -export default class ViewsController extends BaseController { - @Inject() - viewsService: ViewsService; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.get( - '/resource/:resource_model', - [...this.viewsListSchemaValidation], - this.validationResult, - asyncMiddleware(this.listResourceViews.bind(this)), - this.handlerServiceErrors - ); - return router; - } - - /** - * Custom views list validation schema. - */ - get viewsListSchemaValidation() { - return [param('resource_model').exists().trim()]; - } - - /** - * List all views that associated with the given resource. - * @param {Request} req - Request object. - * @param {Response} res - Response object. - * @param {NextFunction} next - Next function. - */ - async listResourceViews(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - const { resource_model: resourceModel } = req.params; - - try { - const views = await this.viewsService.listResourceViews( - tenantId, - resourceModel - ); - return res.status(200).send({ - views: this.transfromToResponse(views, ['name', 'columns.label'], req), - }); - } catch (error) { - next(error); - } - } - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'VIEW_NAME_NOT_UNIQUE') { - return res.boom.badRequest(null, { - errors: [{ type: 'VIEW_NAME_NOT_UNIQUE', code: 110 }], - }); - } - if (error.errorType === 'RESOURCE_MODEL_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'RESOURCE_MODEL_NOT_FOUND', code: 150 }], - }); - } - if (error.errorType === 'INVALID_LOGIC_EXPRESSION') { - return res.boom.badRequest(null, { - errors: [{ type: 'VIEW.ROLES.LOGIC.EXPRESSION.INVALID', code: 400 }], - }); - } - if (error.errorType === '') { - return res.boom.badRequest(null, { - errors: [{ type: 'RESOURCE_FIELDS_NOT_EXIST', code: 100 }], - }); - } - if (error.errorType === '') { - return res.boom.badRequest(null, { - errors: [{ type: 'COLUMNS_NOT_EXIST', code: 200 }], - }); - } - if (error.errorType === 'VIEW_NOT_FOUND') { - return res.boom.notFound(null, { - errors: [{ type: 'VIEW_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'VIEW_PREDEFINED') { - return res.boom.badRequest(null, { - errors: [{ type: 'PREDEFINED_VIEW', code: 200 }], - }); - } - if (error.errorType === 'RESOURCE_FIELDS_KEYS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'RESOURCE_FIELDS_KEYS_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'RESOURCE_COLUMNS_KEYS_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'RESOURCE_COLUMNS_KEYS_NOT_FOUND', code: 310 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Warehouses/WarehouseTransfers.ts b/packages/server/src/api/controllers/Warehouses/WarehouseTransfers.ts deleted file mode 100644 index de7385786..000000000 --- a/packages/server/src/api/controllers/Warehouses/WarehouseTransfers.ts +++ /dev/null @@ -1,407 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Request, Response, Router, NextFunction } from 'express'; -import { query, check, param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { WarehouseTransferApplication } from '@/services/Warehouses/WarehousesTransfers/WarehouseTransferApplication'; -import { - Features, - ICreateWarehouseTransferDTO, - IEditWarehouseTransferDTO, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { FeatureActivationGuard } from '@/api/middleware/FeatureActivationGuard'; - -@Service() -export class WarehousesTransfers extends BaseController { - @Inject() - private warehouseTransferApplication: WarehouseTransferApplication; - - /** - * - */ - router() { - const router = Router(); - - router.post( - '/', - FeatureActivationGuard(Features.WAREHOUSES), - [ - check('from_warehouse_id').exists().isInt().toInt(), - check('to_warehouse_id').exists().isInt().toInt(), - - check('date').exists().isISO8601(), - check('transaction_number').optional(), - - check('transfer_initiated').default(false).isBoolean().toBoolean(), - check('transfer_delivered').default(false).isBoolean().toBoolean(), - - check('entries').exists().isArray({ min: 1 }), - check('entries.*.index').exists(), - check('entries.*.item_id').exists(), - check('entries.*.description').optional(), - check('entries.*.quantity').exists().isInt().toInt(), - check('entries.*.cost').optional().isDecimal().toFloat(), - ], - this.validationResult, - this.asyncMiddleware(this.createWarehouseTransfer), - this.handlerServiceErrors - ); - router.post( - '/:id', - FeatureActivationGuard(Features.WAREHOUSES), - [ - param('id').exists().isInt().toInt(), - - check('from_warehouse_id').exists().isInt().toInt(), - check('to_warehouse_id').exists().isInt().toInt(), - - check('date').exists().isISO8601(), - check('transaction_number').optional(), - - check('transfer_initiated').default(false).isBoolean().toBoolean(), - check('transfer_delivered').default(false).isBoolean().toBoolean(), - - check('entries').exists().isArray({ min: 1 }), - check('entries.*.id').optional().isInt().toInt(), - check('entries.*.index').exists(), - check('entries.*.item_id').exists().isInt().toInt(), - check('entries.*.description').optional(), - check('entries.*.quantity').exists().isInt({ min: 1 }).toInt(), - check('entries.*.cost').optional().isDecimal().toFloat(), - ], - this.validationResult, - this.asyncMiddleware(this.editWarehouseTransfer), - this.handlerServiceErrors - ); - router.put( - '/:id/initiate', - FeatureActivationGuard(Features.WAREHOUSES), - [param('id').exists().isInt().toInt()], - this.asyncMiddleware(this.initiateTransfer), - this.handlerServiceErrors - ); - router.put( - '/:id/transferred', - FeatureActivationGuard(Features.WAREHOUSES), - [param('id').exists().isInt().toInt()], - this.asyncMiddleware(this.deliverTransfer), - this.handlerServiceErrors - ); - router.get( - '/', - FeatureActivationGuard(Features.WAREHOUSES), - [ - query('view_slug').optional({ nullable: true }).isString().trim(), - - query('stringified_filter_roles').optional().isJSON(), - query('column_sort_by').optional(), - query('sort_order').optional().isIn(['desc', 'asc']), - - query('page').optional().isNumeric().toInt(), - query('page_size').optional().isNumeric().toInt(), - - query('search_keyword').optional({ nullable: true }).isString().trim(), - ], - this.validationResult, - this.asyncMiddleware(this.getWarehousesTransfers), - this.handlerServiceErrors - ); - router.get( - '/:id', - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.getWarehouseTransfer), - this.handlerServiceErrors - ); - router.delete( - '/:id', - FeatureActivationGuard(Features.WAREHOUSES), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteWarehouseTransfer), - this.handlerServiceErrors - ); - return router; - } - - /** - * Creates a new warehouse transfer transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private createWarehouseTransfer = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const createWareouseTransfer: ICreateWarehouseTransferDTO = - this.matchedBodyData(req); - - try { - const warehouse = - await this.warehouseTransferApplication.createWarehouseTransfer( - tenantId, - createWareouseTransfer - ); - return res.status(200).send({ - id: warehouse.id, - message: - 'The warehouse transfer transaction has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Edits warehouse transfer transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private editWarehouseTransfer = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseTransferId } = req.params; - const editWarehouseTransferDTO: IEditWarehouseTransferDTO = - this.matchedBodyData(req); - - try { - const warehouseTransfer = - await this.warehouseTransferApplication.editWarehouseTransfer( - tenantId, - warehouseTransferId, - editWarehouseTransferDTO - ); - return res.status(200).send({ - id: warehouseTransfer.id, - message: - 'The warehouse transfer transaction has been edited successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the given warehouse transfer transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private deleteWarehouseTransfer = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseTransferId } = req.params; - - try { - await this.warehouseTransferApplication.deleteWarehouseTransfer( - tenantId, - warehouseTransferId - ); - return res.status(200).send({ - message: - 'The warehouse transfer transaction has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves warehouse transfer transaction details. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private getWarehouseTransfer = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseTransferId } = req.params; - - try { - const warehouseTransfer = - await this.warehouseTransferApplication.getWarehouseTransfer( - tenantId, - warehouseTransferId - ); - return res.status(200).send({ data: warehouseTransfer }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves specific warehouse transfer transaction. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private getWarehousesTransfers = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const filterDTO = { - sortOrder: 'desc', - columnSortBy: 'created_at', - page: 1, - pageSize: 12, - ...this.matchedQueryData(req), - }; - try { - const { warehousesTransfers, pagination, filter } = - await this.warehouseTransferApplication.getWarehousesTransfers( - tenantId, - filterDTO - ); - - return res.status(200).send({ - data: warehousesTransfers, - pagination, - filter, - }); - } catch (error) { - next(error); - } - }; - - /** - * Initiates the warehouse transfer. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private initiateTransfer = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseTransferId } = req.params; - - try { - await this.warehouseTransferApplication.initiateWarehouseTransfer( - tenantId, - warehouseTransferId - ); - return res.status(200).send({ - id: warehouseTransferId, - message: 'The given warehouse transfer has been initialized.', - }); - } catch (error) { - next(error); - } - }; - - /** - * marks the given warehouse transfer as transferred. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - private deliverTransfer = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseTransferId } = req.params; - - try { - await this.warehouseTransferApplication.transferredWarehouseTransfer( - tenantId, - warehouseTransferId - ); - return res.status(200).send({ - id: warehouseTransferId, - message: 'The given warehouse transfer has been delivered.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'WAREHOUSES_TRANSFER_SHOULD_NOT_BE_SAME') { - return res.status(400).send({ - errors: [ - { type: 'WAREHOUSES_TRANSFER_SHOULD_NOT_BE_SAME', code: 100 }, - ], - }); - } - if (error.errorType === 'FROM_WAREHOUSE_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'FROM_WAREHOUSE_NOT_FOUND', code: 200 }], - }); - } - if (error.errorType === 'TO_WAREHOUSE_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'TO_WAREHOUSE_NOT_FOUND', code: 300 }], - }); - } - if (error.errorType === 'ITEMS_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'ITEMS_NOT_FOUND', code: 400 }], - }); - } - if (error.errorType === 'WAREHOUSE_TRANSFER_ITEMS_SHOULD_BE_INVENTORY') { - return res.status(400).send({ - errors: [ - { type: 'WAREHOUSE_TRANSFER_ITEMS_SHOULD_BE_INVENTORY', code: 500 }, - ], - }); - } - if (error.errorType === 'WAREHOUSE_TRANSFER_ALREADY_TRANSFERRED') { - return res.status(400).send({ - errors: [ - { type: 'WAREHOUSE_TRANSFER_ALREADY_TRANSFERRED', code: 600 }, - ], - }); - } - if (error.errorType === 'WAREHOUSE_TRANSFER_ALREADY_INITIATED') { - return res.status(400).send({ - errors: [{ type: 'WAREHOUSE_TRANSFER_ALREADY_INITIATED', code: 700 }], - }); - } - if (error.errorType === 'WAREHOUSE_TRANSFER_NOT_INITIATED') { - return res.status(400).send({ - errors: [{ type: 'WAREHOUSE_TRANSFER_NOT_INITIATED', code: 800 }], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Warehouses/WarehousesItem.ts b/packages/server/src/api/controllers/Warehouses/WarehousesItem.ts deleted file mode 100644 index 73aded86c..000000000 --- a/packages/server/src/api/controllers/Warehouses/WarehousesItem.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Router, Request, Response, NextFunction } from 'express'; -import { param } from 'express-validator'; - -import { Features } from '@/interfaces'; -import BaseController from '@/api/controllers/BaseController'; -import { FeatureActivationGuard } from '@/api/middleware/FeatureActivationGuard'; -import { WarehousesApplication } from '@/services/Warehouses/WarehousesApplication'; - -@Service() -export class WarehousesItemController extends BaseController { - @Inject() - warehousesApplication: WarehousesApplication; - - router() { - const router = Router(); - - router.get( - '/items/:id/warehouses', - FeatureActivationGuard(Features.WAREHOUSES), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.getItemWarehouses - ); - return router; - } - - getItemWarehouses = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseId } = req.params; - - try { - const itemWarehouses = await this.warehousesApplication.getItemWarehouses( - tenantId, - warehouseId - ); - - return res.status(200).send({ itemWarehouses }); - } catch (error) { - next(error); - } - }; -} diff --git a/packages/server/src/api/controllers/Warehouses/index.ts b/packages/server/src/api/controllers/Warehouses/index.ts deleted file mode 100644 index c704f44e0..000000000 --- a/packages/server/src/api/controllers/Warehouses/index.ts +++ /dev/null @@ -1,337 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { Request, Response, Router, NextFunction } from 'express'; -import { check, param } from 'express-validator'; -import BaseController from '@/api/controllers/BaseController'; -import { WarehousesApplication } from '@/services/Warehouses/WarehousesApplication'; -import { Features, ICreateWarehouseDTO, IEditWarehouseDTO } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { FeatureActivationGuard } from '@/api/middleware/FeatureActivationGuard'; - -@Service() -export class WarehousesController extends BaseController { - @Inject() - private warehouseApplication: WarehousesApplication; - - /** - * - * @returns - */ - public router() { - const router = Router(); - - router.post( - '/activate', - [], - this.validationResult, - this.asyncMiddleware(this.activateWarehouses), - this.handlerServiceErrors - ); - router.post( - '/', - FeatureActivationGuard(Features.WAREHOUSES), - [ - check('name').exists(), - check('code').optional({ nullable: true }), - - check('address').optional({ nullable: true }), - check('city').optional({ nullable: true }), - check('country').optional({ nullable: true }), - - check('phone_number').optional({ nullable: true }), - check('email').optional({ nullable: true }).isEmail(), - check('website').optional({ nullable: true }).isURL(), - ], - this.validationResult, - this.asyncMiddleware(this.createWarehouse), - this.handlerServiceErrors - ); - router.post( - '/:id', - FeatureActivationGuard(Features.WAREHOUSES), - [ - check('id').exists().isInt().toInt(), - check('name').exists(), - check('code').optional({ nullable: true }), - - check('address').optional({ nullable: true }), - check('city').optional({ nullable: true }), - check('country').optional({ nullable: true }), - - check('phone_number').optional({ nullable: true }), - check('email').optional({ nullable: true }).isEmail(), - check('website').optional({ nullable: true }).isURL(), - ], - this.validationResult, - this.asyncMiddleware(this.editWarehouse), - this.handlerServiceErrors - ); - router.post( - '/:id/mark-primary', - FeatureActivationGuard(Features.WAREHOUSES), - [check('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.markPrimaryWarehouse) - ); - router.delete( - '/:id', - FeatureActivationGuard(Features.WAREHOUSES), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.deleteWarehouse), - this.handlerServiceErrors - ); - router.get( - '/:id', - FeatureActivationGuard(Features.WAREHOUSES), - [param('id').exists().isInt().toInt()], - this.validationResult, - this.asyncMiddleware(this.getWarehouse), - this.handlerServiceErrors - ); - router.get( - '/', - FeatureActivationGuard(Features.WAREHOUSES), - [], - this.validationResult, - this.asyncMiddleware(this.getWarehouses), - this.handlerServiceErrors - ); - return router; - } - - /** - * Creates a new warehouse. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public createWarehouse = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const createWarehouseDTO: ICreateWarehouseDTO = this.matchedBodyData(req); - - try { - const warehouse = await this.warehouseApplication.createWarehouse( - tenantId, - createWarehouseDTO - ); - return res.status(200).send({ - id: warehouse.id, - message: 'The warehouse has been created successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Deletes the given warehouse. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public editWarehouse = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseId } = req.params; - const editWarehouseDTO: IEditWarehouseDTO = this.matchedBodyData(req); - - try { - const warehouse = await this.warehouseApplication.editWarehouse( - tenantId, - warehouseId, - editWarehouseDTO - ); - - return res.status(200).send({ - id: warehouse.id, - message: 'The warehouse has been edited successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * - * @param req - * @param res - * @param next - * @returns - */ - public deleteWarehouse = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseId } = req.params; - - try { - await this.warehouseApplication.deleteWarehouse(tenantId, warehouseId); - - return res.status(200).send({ - message: 'The warehouse has been deleted successfully.', - }); - } catch (error) { - next(error); - } - }; - /** - * Retrieves specific warehouse. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public getWarehouse = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseId } = req.params; - - try { - const warehouse = await this.warehouseApplication.getWarehouse( - tenantId, - warehouseId - ); - return res.status(200).send({ warehouse }); - } catch (error) { - next(error); - } - }; - - /** - * Retrieves warehouses list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public getWarehouses = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - const warehouses = await this.warehouseApplication.getWarehouses( - tenantId - ); - return res.status(200).send({ warehouses }); - } catch (error) { - next(error); - } - }; - - /** - * Activates multi-warehouses feature. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public activateWarehouses = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - - try { - await this.warehouseApplication.activateWarehouses(tenantId); - - return res.status(200).send({ - message: 'The multi-warehouses has been activated successfully.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Marks the given warehouse as primary. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @returns {Response} - */ - public markPrimaryWarehouse = async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { tenantId } = req; - const { id: warehouseId } = req.params; - - try { - const warehouse = await this.warehouseApplication.markWarehousePrimary( - tenantId, - warehouseId - ); - return res.status(200).send({ - id: warehouse.id, - message: 'The given warehouse has been marked as primary.', - }); - } catch (error) { - next(error); - } - }; - - /** - * Handles service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - private handlerServiceErrors( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'WAREHOUSE_NOT_FOUND') { - return res.status(400).send({ - errors: [{ type: 'WAREHOUSE_NOT_FOUND', code: 100 }], - }); - } - if (error.errorType === 'MUTLI_WAREHOUSES_ALREADY_ACTIVATED') { - return res.status(400).send({ - errors: [{ type: 'MUTLI_WAREHOUSES_ALREADY_ACTIVATED', code: 200 }], - }); - } - if (error.errorType === 'COULD_NOT_DELETE_ONLY_WAERHOUSE') { - return res.status(400).send({ - errors: [{ type: 'COULD_NOT_DELETE_ONLY_WAERHOUSE', code: 300 }], - }); - } - if (error.errorType === 'WAREHOUSE_CODE_NOT_UNIQUE') { - return res.status(400).send({ - errors: [{ type: 'WAREHOUSE_CODE_NOT_UNIQUE', code: 400 }], - }); - } - if (error.errorType === 'WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS') { - return res.status(400).send({ - errors: [ - { type: 'WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS', code: 500 }, - ], - }); - } - } - next(error); - } -} diff --git a/packages/server/src/api/controllers/Webhooks/Webhooks.ts b/packages/server/src/api/controllers/Webhooks/Webhooks.ts deleted file mode 100644 index 1659f0a9d..000000000 --- a/packages/server/src/api/controllers/Webhooks/Webhooks.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { NextFunction, Router, Request, Response } from 'express'; -import Container, { Inject, Service } from 'typedi'; -import { PlaidApplication } from '@/services/Banking/Plaid/PlaidApplication'; -import BaseController from '../BaseController'; -import { LemonSqueezyWebhooks } from '@/services/Subscription/LemonSqueezyWebhooks'; -import { PlaidWebhookTenantBootMiddleware } from '@/services/Banking/Plaid/PlaidWebhookTenantBootMiddleware'; -import { StripeWebhooksController } from '../StripeIntegration/StripeWebhooksController'; - -@Service() -export class Webhooks extends BaseController { - @Inject() - private plaidApp: PlaidApplication; - - @Inject() - private lemonWebhooksService: LemonSqueezyWebhooks; - - /** - * Router constructor. - */ - router() { - const router = Router(); - - router.use('/plaid', PlaidWebhookTenantBootMiddleware); - router.post('/plaid', this.plaidWebhooks.bind(this)); - - router.post('/lemon', this.lemonWebhooks.bind(this)); - - router.use(Container.get(StripeWebhooksController).router()); - - return router; - } - - /** - * Listens to Lemon Squeezy webhooks events. - * @param {Request} req - * @param {Response} res - * @returns {Response} - */ - public async lemonWebhooks(req: Request, res: Response, next: NextFunction) { - const data = req.body; - const signature = req.headers['x-signature'] as string ?? ''; - const rawBody = req.rawBody; - - try { - await this.lemonWebhooksService.handlePostWebhook( - rawBody, - data, - signature - ); - return res.status(200).send(); - } catch (error) { - next(error); - } - } - - /** - * Listens to Plaid webhooks. - * @param {Request} req - * @param {Response} res - * @returns {Response} - */ - public async plaidWebhooks(req: Request, res: Response, next: NextFunction) { - const { tenantId } = req; - - try { - const { - webhook_type: webhookType, - webhook_code: webhookCode, - item_id: plaidItemId, - } = req.body; - - await this.plaidApp.webhooks( - tenantId, - plaidItemId, - webhookType, - webhookCode - ); - return res.status(200).send({ code: 200, message: 'ok' }); - } catch (error) { - next(error); - } - } -} diff --git a/packages/server/src/api/exceptions/GlobalErrorException.ts b/packages/server/src/api/exceptions/GlobalErrorException.ts deleted file mode 100644 index 85f433437..000000000 --- a/packages/server/src/api/exceptions/GlobalErrorException.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; - -/** - * Global error handler. - * @param {Error} err - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ -export function GlobalErrorException( - err: Error, - req: Request, - res: Response, - next: NextFunction -) { - console.error(err.stack); - - res.status(500); - res.boom.badImplementation('', { stack: err.stack }); -} diff --git a/packages/server/src/api/exceptions/ObjectionErrorException.ts b/packages/server/src/api/exceptions/ObjectionErrorException.ts deleted file mode 100644 index 31ddc64e9..000000000 --- a/packages/server/src/api/exceptions/ObjectionErrorException.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { - ValidationError, - NotFoundError, - DBError, - UniqueViolationError, - NotNullViolationError, - ForeignKeyViolationError, - CheckViolationError, - DataError, -} from 'objection'; - -/** - * Handles the Objection error exception. - * @param {Error} err - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ -export function ObjectionErrorException( - err: Error, - req: Request, - res: Response, - next: NextFunction -) { - if (err instanceof ValidationError) { - switch (err.type) { - case 'ModelValidation': - return res.status(400).send({ - message: err.message, - type: err.type, - data: err.data, - }); - case 'RelationExpression': - return res.status(400).send({ - message: err.message, - type: 'RelationExpression', - data: {}, - }); - - case 'UnallowedRelation': - return res.status(400).send({ - message: err.message, - type: err.type, - data: {}, - }); - - case 'InvalidGraph': - return res.status(400).send({ - message: err.message, - type: err.type, - data: {}, - }); - - default: - return res.status(400).send({ - message: err.message, - type: 'UnknownValidationError', - data: {}, - }); - } - } else if (err instanceof NotFoundError) { - return res.status(404).send({ - message: err.message, - type: 'NotFound', - data: {}, - }); - } else if (err instanceof UniqueViolationError) { - return res.status(409).send({ - message: err.message, - type: 'UniqueViolation', - data: { - columns: err.columns, - table: err.table, - constraint: err.constraint, - }, - }); - } else if (err instanceof NotNullViolationError) { - return res.status(400).send({ - message: err.message, - type: 'NotNullViolation', - data: { - column: err.column, - table: err.table, - }, - }); - } else if (err instanceof ForeignKeyViolationError) { - return res.status(409).send({ - message: err.message, - type: 'ForeignKeyViolation', - data: { - table: err.table, - constraint: err.constraint, - }, - }); - } else if (err instanceof CheckViolationError) { - return res.status(400).send({ - message: err.message, - type: 'CheckViolation', - data: { - table: err.table, - constraint: err.constraint, - }, - }); - } else if (err instanceof DataError) { - return res.status(400).send({ - message: err.message, - type: 'InvalidData', - data: {}, - }); - } else if (err instanceof DBError) { - return res.status(500).send({ - message: err.message, - type: 'UnknownDatabaseError', - data: {}, - }); - } else { - next(err); - } -} diff --git a/packages/server/src/api/exceptions/ServiceErrorException.ts b/packages/server/src/api/exceptions/ServiceErrorException.ts deleted file mode 100644 index fd1990e59..000000000 --- a/packages/server/src/api/exceptions/ServiceErrorException.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NextFunction, Request, Response } from 'express'; -import { ServiceError } from '@/exceptions'; - -/** - * Handles service error exception. - * @param {Error | ServiceError} err - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ -export function ServiceErrorException( - err: Error | ServiceError, - req: Request, - res: Response, - next: NextFunction -) { - if (err instanceof ServiceError) { - res.boom.badRequest('', { - errors: [{ type: err.errorType, message: err.message }], - type: 'ServiceError', - }); - } else { - next(err); - } -} diff --git a/packages/server/src/api/index.ts b/packages/server/src/api/index.ts deleted file mode 100644 index c1a890587..000000000 --- a/packages/server/src/api/index.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Router } from 'express'; -import { Container } from 'typedi'; - -// Middlewares -import JWTAuth from '@/api/middleware/jwtAuth'; -import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser'; -import SubscriptionMiddleware from '@/api/middleware/SubscriptionMiddleware'; -import TenancyMiddleware from '@/api/middleware/TenancyMiddleware'; -import EnsureTenantIsInitialized from '@/api/middleware/EnsureTenantIsInitialized'; -import SettingsMiddleware from '@/api/middleware/SettingsMiddleware'; -import I18nMiddleware from '@/api/middleware/I18nMiddleware'; -import I18nAuthenticatedMiddlware from '@/api/middleware/I18nAuthenticatedMiddlware'; -import EnsureTenantIsSeeded from '@/api/middleware/EnsureTenantIsSeeded'; - -// Routes -import Authentication from '@/api/controllers/Authentication'; -import InviteUsers from '@/api/controllers/InviteUsers'; -import Organization from '@/api/controllers/Organization'; -import Account from '@/api/controllers/Account'; -import Users from '@/api/controllers/Users'; -import Items from '@/api/controllers/Items'; -import ItemCategories from '@/api/controllers/ItemCategories'; -import Accounts from '@/api/controllers/Accounts'; -import AccountTypes from '@/api/controllers/AccountTypes'; -import Views from '@/api/controllers/Views'; -import ManualJournals from '@/api/controllers/ManualJournals'; -import FinancialStatements from '@/api/controllers/FinancialStatements'; -import Expenses from '@/api/controllers/Expenses'; -import Settings from '@/api/controllers/Settings'; -import Currencies from '@/api/controllers/Currencies'; -import Contacts from '@/api/controllers/Contacts/Contacts'; -import Customers from '@/api/controllers/Contacts/Customers'; -import Vendors from '@/api/controllers/Contacts/Vendors'; -import Sales from '@/api/controllers/Sales'; -import Purchases from '@/api/controllers/Purchases'; -import Resources from './controllers/Resources'; -import ExchangeRates from '@/api/controllers/ExchangeRates'; -import Media from '@/api/controllers/Media'; -import Ping from '@/api/controllers/Ping'; -import { SubscriptionController } from '@/api/controllers/Subscription'; -import InventoryAdjustments from '@/api/controllers/Inventory/InventoryAdjustments'; -import asyncRenderMiddleware from './middleware/AsyncRenderMiddleware'; -import Jobs from './controllers/Jobs'; -import Miscellaneous from '@/api/controllers/Miscellaneous'; -import OrganizationDashboard from '@/api/controllers/OrganizationDashboard'; -import CashflowController from './controllers/Cashflow/CashflowController'; -import AuthorizationMiddleware from './middleware/AuthorizationMiddleware'; -import RolesController from './controllers/Roles'; -import TransactionsLocking from './controllers/TransactionsLocking'; -import DashboardController from './controllers/Dashboard'; -import { BranchesController } from './controllers/Branches'; -import { WarehousesController } from './controllers/Warehouses'; -import { WarehousesTransfers } from './controllers/Warehouses/WarehouseTransfers'; -import { WarehousesItemController } from './controllers/Warehouses/WarehousesItem'; -import { BranchIntegrationErrorsMiddleware } from '@/services/Branches/BranchIntegrationErrorsMiddleware'; -import { InventoryItemsCostController } from './controllers/Inventory/InventortyItemsCosts'; -import { ProjectsController } from './controllers/Projects/Projects'; -import { ProjectTasksController } from './controllers/Projects/Tasks'; -import { ProjectTimesController } from './controllers/Projects/Times'; -import { TaxRatesController } from './controllers/TaxRates/TaxRates'; -import { ImportController } from './controllers/Import/ImportController'; -import { BankingController } from './controllers/Banking/BankingController'; -import { Webhooks } from './controllers/Webhooks/Webhooks'; -import { ExportController } from './controllers/Export/ExportController'; -import { AttachmentsController } from './controllers/Attachments/AttachmentsController'; -import { OneClickDemoController } from './controllers/OneClickDemo/OneClickDemoController'; -import { StripeIntegrationController } from './controllers/StripeIntegration/StripeIntegrationController'; -import { ShareLinkController } from './controllers/ShareLink/ShareLinkController'; -import { PublicSharableLinkController } from './controllers/ShareLink/PublicSharableLinkController'; -import { PdfTemplatesController } from './controllers/PdfTemplates/PdfTemplatesController'; -import { PaymentServicesController } from './controllers/PaymentServices/PaymentServicesController'; - -export default () => { - const app = Router(); - - // - Global routes. - // --------------------------- - app.use(asyncRenderMiddleware); - app.use(I18nMiddleware); - - app.use('/auth', Container.get(Authentication).router()); - app.use('/invite', Container.get(InviteUsers).nonAuthRouter()); - app.use('/subscription', Container.get(SubscriptionController).router()); - app.use('/organization', Container.get(Organization).router()); - app.use('/ping', Container.get(Ping).router()); - app.use('/jobs', Container.get(Jobs).router()); - app.use('/account', Container.get(Account).router()); - app.use('/webhooks', Container.get(Webhooks).router()); - app.use('/demo', Container.get(OneClickDemoController).router()); - app.use( - '/payment-links', - Container.get(PublicSharableLinkController).router() - ); - - // - Dashboard routes. - // --------------------------- - const dashboard = Router(); - - dashboard.use(JWTAuth); - dashboard.use(AttachCurrentTenantUser); - dashboard.use(TenancyMiddleware); - dashboard.use(SubscriptionMiddleware('main')); - dashboard.use(EnsureTenantIsInitialized); - dashboard.use(SettingsMiddleware); - dashboard.use(I18nAuthenticatedMiddlware); - dashboard.use(EnsureTenantIsSeeded); - dashboard.use(AuthorizationMiddleware); - - dashboard.use('/organization', Container.get(OrganizationDashboard).router()); - dashboard.use('/users', Container.get(Users).router()); - dashboard.use('/invite', Container.get(InviteUsers).authRouter()); - dashboard.use('/currencies', Container.get(Currencies).router()); - dashboard.use('/settings', Container.get(Settings).router()); - dashboard.use('/accounts', Container.get(Accounts).router()); - dashboard.use('/account_types', Container.get(AccountTypes).router()); - dashboard.use('/manual-journals', Container.get(ManualJournals).router()); - dashboard.use('/views', Container.get(Views).router()); - dashboard.use('/items', Container.get(Items).router()); - dashboard.use('/item_categories', Container.get(ItemCategories).router()); - dashboard.use('/expenses', Container.get(Expenses).router()); - dashboard.use( - '/financial_statements', - Container.get(FinancialStatements).router() - ); - dashboard.use('/contacts', Container.get(Contacts).router()); - dashboard.use('/customers', Container.get(Customers).router()); - dashboard.use('/vendors', Container.get(Vendors).router()); - dashboard.use('/sales', Container.get(Sales).router()); - dashboard.use('/purchases', Container.get(Purchases).router()); - dashboard.use('/resources', Container.get(Resources).router()); - dashboard.use('/exchange_rates', Container.get(ExchangeRates).router()); - dashboard.use('/media', Container.get(Media).router()); - dashboard.use( - '/inventory_adjustments', - Container.get(InventoryAdjustments).router() - ); - dashboard.use( - '/inventory', - Container.get(InventoryItemsCostController).router() - ); - dashboard.use('/cashflow', Container.get(CashflowController).router()); - dashboard.use('/banking', Container.get(BankingController).router()); - dashboard.use('/roles', Container.get(RolesController).router()); - dashboard.use( - '/transactions-locking', - Container.get(TransactionsLocking).router() - ); - dashboard.use('/branches', Container.get(BranchesController).router()); - dashboard.use( - '/warehouses/transfers', - Container.get(WarehousesTransfers).router() - ); - dashboard.use('/warehouses', Container.get(WarehousesController).router()); - dashboard.use('/projects', Container.get(ProjectsController).router()); - dashboard.use('/tax-rates', Container.get(TaxRatesController).router()); - dashboard.use('/import', Container.get(ImportController).router()); - dashboard.use('/export', Container.get(ExportController).router()); - dashboard.use('/attachments', Container.get(AttachmentsController).router()); - dashboard.use( - '/stripe_integration', - Container.get(StripeIntegrationController).router() - ); - dashboard.use( - '/pdf-templates', - Container.get(PdfTemplatesController).router() - ); - dashboard.use( - '/payment-services', - Container.get(PaymentServicesController).router() - ); - dashboard.use('/', Container.get(ProjectTasksController).router()); - dashboard.use('/', Container.get(ProjectTimesController).router()); - dashboard.use('/', Container.get(WarehousesItemController).router()); - dashboard.use('/', Container.get(ShareLinkController).router()); - - dashboard.use('/dashboard', Container.get(DashboardController).router()); - dashboard.use('/', Container.get(Miscellaneous).router()); - - app.use('/', dashboard); - - app.use(BranchIntegrationErrorsMiddleware); - - return app; -}; diff --git a/packages/server/src/api/middleware/AsyncRenderMiddleware.ts b/packages/server/src/api/middleware/AsyncRenderMiddleware.ts deleted file mode 100644 index 5bd6e736a..000000000 --- a/packages/server/src/api/middleware/AsyncRenderMiddleware.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Request, Response } from 'express'; - -const asyncRender = (app) => (path: string, attributes = {}) => - new Promise((resolve, reject) => { - app.render(path, attributes, (error, data) => { - if (error) { reject(error); } - - resolve(data); - }); - }); - -/** - * Injects `asyncRender` method to response object. - * @param {Request} req Express req Object - * @param {Response} res Express res Object - * @param {NextFunction} next Express next Function - */ -const asyncRenderMiddleware = (req: Request, res: Response, next: Function) => { - res.asyncRender = asyncRender(req.app); - next(); -}; - -export default asyncRenderMiddleware; diff --git a/packages/server/src/api/middleware/AttachCurrentTenantUser.ts b/packages/server/src/api/middleware/AttachCurrentTenantUser.ts deleted file mode 100644 index 0ba44f689..000000000 --- a/packages/server/src/api/middleware/AttachCurrentTenantUser.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response } from 'express'; - -/** - * Attach user to req.currentUser - * @param {Request} req Express req Object - * @param {Response} res Express res Object - * @param {NextFunction} next Express next Function - */ -const attachCurrentUser = async (req: Request, res: Response, next: Function) => { - const Logger = Container.get('logger'); - const { systemUserRepository } = Container.get('repositories'); - - try { - Logger.info('[attach_user_middleware] finding system user by id.'); - const user = await systemUserRepository.findOneById(req.token.id); - - if (!user) { - Logger.info('[attach_user_middleware] the system user not found.'); - return res.boom.unauthorized(); - } - if (!user.active) { - Logger.info('[attach_user_middleware] the system user not found.'); - return res.boom.badRequest( - 'The authorized user is inactivated.', - { errors: [{ type: 'USER_INACTIVE', code: 100, }] }, - ); - } - // Delete password property from user object. - Reflect.deleteProperty(user, 'password'); - req.user = user; - return next(); - } catch (e) { - Logger.error('[attach_user_middleware] error attaching user to req: %o', e); - return next(e); - } -}; - -export default attachCurrentUser; diff --git a/packages/server/src/api/middleware/AuthorizationMiddleware.ts b/packages/server/src/api/middleware/AuthorizationMiddleware.ts deleted file mode 100644 index 9b0c2d90b..000000000 --- a/packages/server/src/api/middleware/AuthorizationMiddleware.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { Container } from 'typedi'; -import { Ability } from '@casl/ability'; -import LruCache from 'lru-cache'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { IRole, IRolePremission, ISystemUser } from '@/interfaces'; - -// store abilities of 1000 most active users -export const ABILITIES_CACHE = new LruCache(1000); - -/** - * Retrieve ability for the given role. - * @param {} role - * @returns - */ -function getAbilityForRole(role) { - const rules = getAbilitiesRolesConds(role); - return new Ability(rules); -} - -/** - * Retrieve abilities of the given role. - * @param {IRole} role - * @returns {} - */ -function getAbilitiesRolesConds(role: IRole) { - switch (role.slug) { - case 'admin': // predefined role. - return getSuperAdminRules(); - default: - return getRulesFromRolePermissions(role.permissions || []); - } -} - -/** - * Retrieve the super admin rules. - * @returns {} - */ -function getSuperAdminRules() { - return [{ action: 'manage', subject: 'all' }]; -} - -/** - * Retrieve CASL rules from role permissions. - * @param {IRolePremission[]} permissions - - * @returns {} - */ -function getRulesFromRolePermissions(permissions: IRolePremission[]) { - return permissions - .filter((permission: IRolePremission) => permission.value) - .map((permission: IRolePremission) => { - return { - action: permission.ability, - subject: permission.subject, - }; - }); -} - -/** - * Retrieve ability for user. - * @param {ISystemUser} user - * @param {number} tenantId - * @returns {} - */ -async function getAbilityForUser(user: ISystemUser, tenantId: number) { - const tenancy = Container.get(HasTenancyService); - const { User } = tenancy.models(tenantId); - - const tenantUser = await User.query() - .findOne('systemUserId', user.id) - .withGraphFetched('role.permissions'); - - return getAbilityForRole(tenantUser.role); -} - -/** - * - * @param {Request} request - - * @param {Response} response - - * @param {NextFunction} next - - */ -export default async (req: Request, res: Response, next: NextFunction) => { - const { tenantId, user } = req; - - if (ABILITIES_CACHE.has(req.user.id)) { - req.ability = ABILITIES_CACHE.get(req.user.id); - } else { - req.ability = await getAbilityForUser(req.user, tenantId); - ABILITIES_CACHE.set(req.user.id, req.ability); - } - next(); -}; diff --git a/packages/server/src/api/middleware/CheckPolicies.ts b/packages/server/src/api/middleware/CheckPolicies.ts deleted file mode 100644 index 3649f0aa8..000000000 --- a/packages/server/src/api/middleware/CheckPolicies.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { ForbiddenError } from '@casl/ability'; - -/** - * - */ -export default (ability: string, subject: string) => - (req: Request, res: Response, next: NextFunction) => { - try { - ForbiddenError.from(req.ability).throwUnlessCan(ability, subject); - } catch (error) { - return res.status(403).send({ - type: 'USER_PERMISSIONS_FORBIDDEN', - message: `You are not allowed to ${error.action} on ${error.subjectType}`, - }); - } - next(); - }; diff --git a/packages/server/src/api/middleware/ConvertEmptyStringsToNull.ts b/packages/server/src/api/middleware/ConvertEmptyStringsToNull.ts deleted file mode 100644 index aa7b41690..000000000 --- a/packages/server/src/api/middleware/ConvertEmptyStringsToNull.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import deepMap from 'deep-map'; -import { convertEmptyStringToNull } from 'utils'; - -function convertEmptyStringsToNull(data) { - return deepMap(data, (value) => convertEmptyStringToNull(value)); -} - -export default (req: Request, res: Response, next: NextFunction) => { - const transfomedBody = convertEmptyStringsToNull(req.body); - req.body = transfomedBody; - next(); -}; \ No newline at end of file diff --git a/packages/server/src/api/middleware/EnsureTenantIsInitialized.ts b/packages/server/src/api/middleware/EnsureTenantIsInitialized.ts deleted file mode 100644 index 2f546cb01..000000000 --- a/packages/server/src/api/middleware/EnsureTenantIsInitialized.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response } from 'express'; - - -export default (req: Request, res: Response, next: Function) => { - const Logger = Container.get('logger'); - - if (!req.tenant) { - Logger.info('[ensure_tenant_intialized_middleware] no tenant model.'); - throw new Error('Should load this middleware after `TenancyMiddleware`.'); - } - if (!req.tenant.initializedAt) { - Logger.info('[ensure_tenant_initialized_middleware] tenant database not initalized.'); - - return res.boom.badRequest( - 'Tenant database is not migrated with application schema yut.', - { errors: [{ type: 'TENANT.DATABASE.NOT.INITALIZED' }] }, - ); - } - next(); -}; \ No newline at end of file diff --git a/packages/server/src/api/middleware/EnsureTenantIsSeeded.ts b/packages/server/src/api/middleware/EnsureTenantIsSeeded.ts deleted file mode 100644 index 69f92c76a..000000000 --- a/packages/server/src/api/middleware/EnsureTenantIsSeeded.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response } from 'express'; - -export default (req: Request, res: Response, next: Function) => { - const Logger = Container.get('logger'); - - if (!req.tenant) { - Logger.info('[ensure_tenant_intialized_middleware] no tenant model.'); - throw new Error('Should load this middleware after `TenancyMiddleware`.'); - } - if (!req.tenant.seededAt) { - Logger.info( - '[ensure_tenant_initialized_middleware] tenant databae not seeded.' - ); - return res.boom.badRequest( - 'Tenant database is not seeded with initial data yet.', - { errors: [{ type: 'TENANT.DATABASE.NOT.SEED' }] } - ); - } - next(); -}; diff --git a/packages/server/src/api/middleware/FeatureActivationGuard.ts b/packages/server/src/api/middleware/FeatureActivationGuard.ts deleted file mode 100644 index 1455ac913..000000000 --- a/packages/server/src/api/middleware/FeatureActivationGuard.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Request, Response } from 'express'; -import { Features } from '@/interfaces'; - -export const FeatureActivationGuard = - (feature: Features) => (req: Request, res: Response, next: Function) => { - const { settings } = req; - - const isActivated = settings.get({ group: 'features', key: feature }); - - if (!isActivated) { - return res.status(400).send({ - errors: [ - { type: 'FEATURE_NOT_ACTIVATED', code: 20, payload: { feature } }, - ], - }); - } - next(); - }; diff --git a/packages/server/src/api/middleware/I18nAuthenticatedMiddlware.ts b/packages/server/src/api/middleware/I18nAuthenticatedMiddlware.ts deleted file mode 100644 index 19a26458c..000000000 --- a/packages/server/src/api/middleware/I18nAuthenticatedMiddlware.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { injectI18nUtils } from './TenantDependencyInjection'; - -/** - * I18n from organization settings. - */ -export default (req: Request, res: Response, next: NextFunction) => { - const Logger = Container.get('logger'); - const I18n = Container.get('i18n'); - - const { tenantId, tenant } = req; - - if (!req.user) { - throw new Error('Should load this middleware after `JWTAuth`.'); - } - if (!req.settings) { - throw new Error('Should load this middleware after `SettingsMiddleware`.'); - } - // Get the organization language from settings. - const { language } = tenant.metadata; - - if (language) { - I18n.setLocale(req, language); - } - Logger.info('[i18n_authenticated_middleware] set locale language to i18n.', { - language, - user: req.user, - }); - const tenantServices = Container.get(HasTenancyService); - const tenantContainer = tenantServices.tenantContainer(tenantId); - - tenantContainer.set('i18n', injectI18nUtils(req)); - - next(); -}; diff --git a/packages/server/src/api/middleware/I18nMiddleware.ts b/packages/server/src/api/middleware/I18nMiddleware.ts deleted file mode 100644 index 81f0e8551..000000000 --- a/packages/server/src/api/middleware/I18nMiddleware.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; -import { lowerCase } from 'lodash'; - -/** - * Set the language from request `accept-language` header -* or default application language. - */ -export default (req: Request, res: Response, next: NextFunction) => { - const Logger = Container.get('logger'); - const I18n = Container.get('i18n'); - - // Parses the accepted language from request object. - const language = lowerCase(req.headers['accept-language']) || 'en'; - - Logger.info('[i18n_middleware] set locale language to i18n.', { - language, - user: req.user, - }); - // Initialise the global localization. - I18n.init(req, res, next); -}; diff --git a/packages/server/src/api/middleware/JSONResponseTransformer.ts b/packages/server/src/api/middleware/JSONResponseTransformer.ts deleted file mode 100644 index a68bc699a..000000000 --- a/packages/server/src/api/middleware/JSONResponseTransformer.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { snakeCase } from 'lodash'; -import { mapKeysDeep } from 'utils'; - -/** - * Express middleware for intercepting and transforming json responses - * - * @param {function} [condition] - takes the req and res and returns a boolean indicating whether to run the transform on this response - * @param {function} transform - takes an object passed to res.json and returns a replacement object - * @return {function} the middleware - */ -export function JSONResponseTransformer(transform: Function) { - const replaceJson = (res) => { - var origJson = res.json; - - res.json = function (val) { - const json = JSON.parse(JSON.stringify(val)); - - return origJson.call(res, transform(json)); - }; - }; - - return function (req, res, next) { - replaceJson(res); - next(); - }; -} - -/** - * Transformes the given response keys to snake case. - * @param response - * @returns - */ -export const snakecaseResponseTransformer = (response) => { - return mapKeysDeep(response, (value, key) => { - return snakeCase(key); - }); -}; diff --git a/packages/server/src/api/middleware/LoggerMiddleware.ts b/packages/server/src/api/middleware/LoggerMiddleware.ts deleted file mode 100644 index e57952cd3..000000000 --- a/packages/server/src/api/middleware/LoggerMiddleware.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NextFunction, Request } from 'express'; -import { Container } from 'typedi'; - -function loggerMiddleware(request: Request, response: Response, next: NextFunction) { - const Logger = Container.get('logger'); - - Logger.info(`[routes] ${request.method} ${request.path}`); - next(); -} - -export default loggerMiddleware; diff --git a/packages/server/src/api/middleware/LoginThrottlerMiddleware.ts b/packages/server/src/api/middleware/LoginThrottlerMiddleware.ts deleted file mode 100644 index 60d437387..000000000 --- a/packages/server/src/api/middleware/LoginThrottlerMiddleware.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; -import config from '@/config'; - -const MAX_CONSECUTIVE_FAILS = config.throttler.login.points; - -export default async (req: Request, res: Response, next: NextFunction) => { - const { crediential } = req.body; - const loginThrottler = Container.get('rateLimiter.login'); - - // Retrieve the rate limiter response of the given crediential. - const emailRateRes = await loginThrottler.get(crediential); - - if (emailRateRes !== null && emailRateRes.consumedPoints >= MAX_CONSECUTIVE_FAILS) { - const retrySecs = Math.round(emailRateRes.msBeforeNext / 1000) || 1; - - res.set('Retry-After', retrySecs); - res.status(429).send({ - errors: [{ type: 'LOGIN_TO_MANY_ATTEMPTS', code: 400 }], - }); - } else { - next(); - } -} \ No newline at end of file diff --git a/packages/server/src/api/middleware/RateLimiterMiddleware.ts b/packages/server/src/api/middleware/RateLimiterMiddleware.ts deleted file mode 100644 index 69a79f7e9..000000000 --- a/packages/server/src/api/middleware/RateLimiterMiddleware.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; - -/** - * Rate limiter middleware. - */ -export default (req: Request, res: Response, next: NextFunction) => { - const requestRateLimiter = Container.get('rateLimiter.request'); - - requestRateLimiter.attempt(req.ip).then(() => { - next(); - }) - .catch(() => { - res.status(429).send('Too Many Requests'); - }); -} \ No newline at end of file diff --git a/packages/server/src/api/middleware/SettingsMiddleware.ts b/packages/server/src/api/middleware/SettingsMiddleware.ts deleted file mode 100644 index 010971381..000000000 --- a/packages/server/src/api/middleware/SettingsMiddleware.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; -import SettingsStore from '@/services/Settings/SettingsStore'; - -export default async (req: Request, res: Response, next: NextFunction) => { - const { tenantId } = req.user; - - const settings = await initializeTenantSettings(tenantId); - req.settings = settings; - - res.on('finish', async () => { - await settings.save(); - }); - next(); -} - - -export const initializeTenantSettings = async (tenantId: number) => { - const tenantContainer = Container.of(`tenant-${tenantId}`); - - if (tenantContainer && !tenantContainer.has('settings')) { - const { settingRepository } = tenantContainer.get('repositories'); - - const settings = new SettingsStore(settingRepository); - tenantContainer.set('settings', settings); - } - const settings = tenantContainer.get('settings'); - - await settings.load(); - - return settings; -} \ No newline at end of file diff --git a/packages/server/src/api/middleware/SubscriptionMiddleware.ts b/packages/server/src/api/middleware/SubscriptionMiddleware.ts deleted file mode 100644 index 8c764f47e..000000000 --- a/packages/server/src/api/middleware/SubscriptionMiddleware.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; - -const SupportedMethods = ['POST', 'PUT']; - -export default (subscriptionSlug = 'main') => - async (req: Request, res: Response, next: NextFunction) => { - const { tenant, tenantId } = req; - const { subscriptionRepository } = Container.get('repositories'); - - if (!tenant) { - throw new Error('Should load `TenancyMiddlware` before this middleware.'); - } - const subscription = await subscriptionRepository.getBySlugInTenant( - subscriptionSlug, - tenantId - ); - // Validate in case there is no any already subscription. - if (!subscription) { - return res.boom.badRequest('Tenant has no subscription.', { - errors: [{ type: 'TENANT.HAS.NO.SUBSCRIPTION' }], - }); - } - const isMethodSupported = SupportedMethods.includes(req.method); - const isSubscriptionInactive = subscription.inactive(); - - if (isMethodSupported && isSubscriptionInactive) { - return res.boom.badRequest(null, { - errors: [{ type: 'ORGANIZATION.SUBSCRIPTION.INACTIVE' }], - }); - } - next(); - }; diff --git a/packages/server/src/api/middleware/TenancyMiddleware.ts b/packages/server/src/api/middleware/TenancyMiddleware.ts deleted file mode 100644 index 5e9f4e1ac..000000000 --- a/packages/server/src/api/middleware/TenancyMiddleware.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Container } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; -import tenantDependencyInjection from '@/api/middleware/TenantDependencyInjection'; -import { Tenant } from '@/system/models'; - -export default async (req: Request, res: Response, next: NextFunction) => { - const Logger = Container.get('logger'); - const organizationId = - req.headers['organization-id'] || req.query.organization; - - const notFoundOrganization = () => { - Logger.info('[tenancy_middleware] organization id not found.'); - return res.boom.unauthorized('Organization identication not found.', { - errors: [{ type: 'ORGANIZATION.ID.NOT.FOUND', code: 100 }], - }); - }; - // In case the given organization not found. - if (!organizationId) { - return notFoundOrganization(); - } - const tenant = await Tenant.query() - .findOne({ organizationId }) - .withGraphFetched('metadata'); - - // When the given organization id not found on the system storage. - if (!tenant) { - return notFoundOrganization(); - } - // When user tenant not match the given organization id. - if (tenant.id !== req.user.tenantId) { - Logger.info('[tenancy_middleware] authorized user not match org. tenant.'); - return res.boom.unauthorized(); - } - tenantDependencyInjection(req, tenant); - next(); -}; diff --git a/packages/server/src/api/middleware/TenantDependencyInjection.ts b/packages/server/src/api/middleware/TenantDependencyInjection.ts deleted file mode 100644 index 8447db780..000000000 --- a/packages/server/src/api/middleware/TenantDependencyInjection.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Container } from 'typedi'; -import { ITenant } from '@/interfaces'; -import { Request } from 'express'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import TenantsManagerService from '@/services/Tenancy/TenantsManager'; -import rtlDetect from 'rtl-detect'; -import { Tenant } from '@/system/models'; - -export default (req: Request, tenant: ITenant) => { - const { id: tenantId, organizationId } = tenant; - - const tenantServices = Container.get(TenancyService); - const tenantsManager = Container.get(TenantsManagerService); - - // Initialize the knex instance. - tenantsManager.setupKnexInstance(tenant); - - const tenantContainer = tenantServices.tenantContainer(tenantId); - - tenantContainer.set('i18n', injectI18nUtils()); - - const knexInstance = tenantServices.knex(tenantId); - const models = tenantServices.models(tenantId); - const repositories = tenantServices.repositories(tenantId); - const cacheInstance = tenantServices.cache(tenantId); - - req.knex = knexInstance; - req.organizationId = organizationId; - req.tenant = tenant; - req.tenantId = tenant.id; - req.models = models; - req.repositories = repositories; - req.cache = cacheInstance; -}; - -export const injectI18nUtils = (req) => { - const globalI18n = Container.get('i18n'); - const locale = globalI18n.getLocale(); - const direction = rtlDetect.getLangDir(locale); - - return { - locale, - __: globalI18n.__, - direction, - isRtl: direction === 'rtl', - isLtr: direction === 'ltr', - }; -}; - -export const initalizeTenantServices = async (tenantId: number) => { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata') - .throwIfNotFound(); - - const tenantServices = Container.get(TenancyService); - const tenantsManager = Container.get(TenantsManagerService); - - // Initialize the knex instance. - tenantsManager.setupKnexInstance(tenant); - - const tenantContainer = tenantServices.tenantContainer(tenantId); - tenantContainer.set('i18n', injectI18nUtils()); - - tenantServices.knex(tenantId); - tenantServices.models(tenantId); - tenantServices.repositories(tenantId); - tenantServices.cache(tenantId); -}; diff --git a/packages/server/src/api/middleware/asyncMiddleware.ts b/packages/server/src/api/middleware/asyncMiddleware.ts deleted file mode 100644 index e0c6e0256..000000000 --- a/packages/server/src/api/middleware/asyncMiddleware.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { Container } from 'typedi'; - -export default ( - fn: (rq: Request, rs: Response, next?: NextFunction) => {}) => - (req: Request, res: Response, next: NextFunction) => { - const Logger = Container.get('logger'); - - Promise.resolve(fn(req, res, next)) - .catch((error) => { - Logger.error('[async_middleware] error.', { error }); - next(error); - }); -}; \ No newline at end of file diff --git a/packages/server/src/api/middleware/jwtAuth.ts b/packages/server/src/api/middleware/jwtAuth.ts deleted file mode 100644 index 0c101c246..000000000 --- a/packages/server/src/api/middleware/jwtAuth.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { Container } from 'typedi'; -import jwt from 'jsonwebtoken'; -import config from '@/config'; - -const authMiddleware = (req: Request, res: Response, next: NextFunction) => { - const Logger = Container.get('logger'); - const token = req.headers['x-access-token'] || req.query.token; - - const onError = () => { - Logger.info('[auth_middleware] jwt verify error.'); - res.boom.unauthorized(); - }; - const onSuccess = (decoded) => { - req.token = decoded; - Logger.info('[auth_middleware] jwt verify success.'); - next(); - }; - if (!token) { return onError(); } - - const verify = new Promise((resolve, reject) => { - jwt.verify(token, config.jwtSecret, async (error, decoded) => { - if (error) { - reject(error); - } else { - resolve(decoded); - } - }); - }); - verify.then(onSuccess).catch(onError); -}; -export default authMiddleware; diff --git a/packages/server/src/before.ts b/packages/server/src/before.ts deleted file mode 100644 index 305fca840..000000000 --- a/packages/server/src/before.ts +++ /dev/null @@ -1,12 +0,0 @@ -import path from 'path'; -import moment from 'moment'; - -global.__root_dir = path.join(__dirname, '..'); -global.__resources_dir = path.join(global.__root_dir, 'resources'); -global.__locales_dir = path.join(global.__resources_dir, 'locales'); -global.__views_dir = path.join(global.__root_dir, 'views'); -global.__storage_dir = path.join(global.__root_dir, 'storage'); - -moment.prototype.toMySqlDateTime = function () { - return this.format('YYYY-MM-DD HH:mm:ss'); -}; diff --git a/packages/server/src/collection/BudgetEntriesSet.ts b/packages/server/src/collection/BudgetEntriesSet.ts deleted file mode 100644 index 1be8c34b8..000000000 --- a/packages/server/src/collection/BudgetEntriesSet.ts +++ /dev/null @@ -1,76 +0,0 @@ - - -export default class BudgetEntriesSet { - - constructor() { - this.accounts = {}; - this.totalSummary = {} - this.orderSize = null; - } - - setZeroPlaceholder() { - if (!this.orderSize) { return; } - - Object.values(this.accounts).forEach((account) => { - - for (let i = 0; i <= this.orderSize.length; i++) { - if (typeof account[i] === 'undefined') { - account[i] = { amount: 0 }; - } - } - }); - } - - static from(accounts, configs) { - const collection = new this(configs); - - accounts.forEach((entry) => { - if (typeof this.accounts[entry.accountId] === 'undefined') { - collection.accounts[entry.accountId] = {}; - } - if (entry.order) { - collection.accounts[entry.accountId][entry.order] = entry; - } - }); - return collection; - } - - toArray() { - const output = []; - - Object.key(this.accounts).forEach((accountId) => { - const entries = this.accounts[accountId]; - output.push({ - account_id: accountId, - entries: [ - ...Object.key(entries).map((order) => { - const entry = entries[order]; - return { - order, - amount: entry.amount, - }; - }), - ], - }); - }); - } - - calcTotalSummary() { - const totalSummary = {}; - - for (let i = 0; i < this.orderSize.length; i++) { - Object.value(this.accounts).forEach((account) => { - if (typeof totalSummary[i] !== 'undefined') { - totalSummary[i] = { amount: 0, order: i }; - } - totalSummary[i].amount += account[i].amount; - }); - } - this.totalSummary = totalSummary; - } - - toArrayTotalSummary() { - return Object.values(this.totalSummary); - } - -} diff --git a/packages/server/src/collection/Cachable.ts b/packages/server/src/collection/Cachable.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/src/collection/Metable.ts b/packages/server/src/collection/Metable.ts deleted file mode 100644 index 80f6a9e7e..000000000 --- a/packages/server/src/collection/Metable.ts +++ /dev/null @@ -1,279 +0,0 @@ - - -export default { - METADATA_GROUP: 'default', - KEY_COLUMN: 'key', - VALUE_COLUMN: 'value', - TYPE_COLUMN: 'type', - - extraColumns: [], - metadata: [], - shouldReload: true, - extraMetadataQuery: () => {}, - - /** - * Set the value column key to query from. - * @param {String} name - - */ - setKeyColumnName(name) { - this.KEY_COLUMN = name; - }, - - /** - * Set the key column name to query from. - * @param {String} name - - */ - setValueColumnName(name) { - this.VALUE_COLUMN = name; - }, - - /** - * Set extra columns to be added to the rows. - * @param {Array} columns - - */ - setExtraColumns(columns) { - this.extraColumns = columns; - }, - - /** - * Metadata database query. - * @param {Object} query - - * @param {String} groupName - - */ - whereQuery(query, key) { - const groupName = this.METADATA_GROUP; - - if (groupName) { - query.where('group', groupName); - } - if (key) { - if (Array.isArray(key)) { - query.whereIn('key', key); - } else { - query.where('key', key); - } - } - }, - - /** - * Loads the metadata from the storage. - * @param {String|Array} key - - * @param {Boolean} force - - */ - async load(force = false) { - if (this.shouldReload || force) { - const metadataCollection = await this.query((query) => { - this.whereQuery(query); - this.extraMetadataQuery(query); - }).fetchAll(); - - this.shouldReload = false; - this.metadata = []; - - const metadataArray = this.mapMetadataCollection(metadataCollection); - metadataArray.forEach((metadata) => { this.metadata.push(metadata); }); - } - }, - - /** - * Fetches all the metadata that associate with the current group. - */ - async allMeta(force = false) { - await this.load(force); - return this.metadata; - }, - - /** - * Find the given metadata key. - * @param {String} key - - * @return {object} - Metadata object. - */ - findMeta(key) { - return this.metadata.find((meta) => meta.key === key); - }, - - /** - * Fetch the metadata of the current group. - * @param {*} key - - */ - async getMeta(key, defaultValue, force = false) { - await this.load(force); - - const metadata = this.findMeta(key); - return metadata ? metadata.value : defaultValue || false; - }, - - /** - * Markes the metadata to should be deleted. - * @param {String} key - - */ - async removeMeta(key) { - await this.load(); - const metadata = this.findMeta(key); - - if (metadata) { - metadata.markAsDeleted = true; - } - this.shouldReload = true; - - - /** - * Remove all meta data of the given group. - * @param {*} group - */ - removeAllMeta(group = 'default') { - this.metdata.map((meta) => ({ - ...(meta.group !== group) ? { markAsDeleted: true } : {}, - ...meta, - })); - this.shouldReload = true; - }, - - /** - * Set the meta data to the stack. - * @param {String} key - - * @param {String} value - - */ - async setMeta(key, value, payload) { - if (Array.isArray(key)) { - const metadata = key; - metadata.forEach((meta) => { - this.setMeta(meta.key, meta.value); - }); - return; - } - - await this.load(); - const metadata = this.findMeta(key); - - if (metadata) { - metadata.value = value; - metadata.markAsUpdated = true; - } else { - this.metadata.push({ - value, key, ...payload, markAsInserted: true, - }); - } - }, - - /** - * Saved the modified metadata. - */ - async saveMeta() { - const inserted = this.metadata.filter((m) => (m.markAsInserted === true)); - const updated = this.metadata.filter((m) => (m.markAsUpdated === true)); - const deleted = this.metadata.filter((m) => (m.markAsDeleted === true)); - - const metadataDeletedKeys = deleted.map((m) => m.key); - const metadataInserted = inserted.map((m) => this.mapMetadata(m, 'format')); - const metadataUpdated = updated.map((m) => this.mapMetadata(m, 'format')); - - const batchUpdate = (collection) => knex.transaction((trx) => { - const queries = collection.map((tuple) => { - const query = knex(this.tableName); - this.whereQuery(query, tuple.key); - this.extraMetadataQuery(query); - return query.update(tuple).transacting(trx); - }); - return Promise.all(queries).then(trx.commit).catch(trx.rollback); - }); - - await Promise.all([ - knex.insert(metadataInserted).into(this.tableName), - batchUpdate(metadataUpdated), - metadataDeletedKeys.length > 0 - ? this.query('whereIn', this.KEY_COLUMN, metadataDeletedKeys).destroy({ - require: true, - }) : null, - ]); - this.shouldReload = true; - }, - - /** - * Purge all the cached metadata in the memory. - */ - purgeMetadata() { - this.metadata = []; - this.shouldReload = true; - }, - - /** - * Parses the metadata value. - * @param {String} value - - * @param {String} valueType - - */ - parseMetaValue(value, valueType) { - let parsedValue; - - switch (valueType) { - case 'integer': - parsedValue = parseInt(value, 10); - break; - case 'float': - parsedValue = parseFloat(value); - break; - case 'boolean': - parsedValue = Boolean(value); - break; - case 'json': - parsedValue = JSON.parse(parsedValue); - break; - default: - parsedValue = value; - break; - } - return parsedValue; - }, - - /** - * Format the metadata before saving to the database. - * @param {String|Number|Boolean} value - - * @param {String} valueType - - * @return {String|Number|Boolean} - - */ - formatMetaValue(value, valueType) { - let parsedValue; - - switch (valueType) { - case 'number': - parsedValue = `${value}`; - break; - case 'boolean': - parsedValue = value ? '1' : '0'; - break; - case 'json': - parsedValue = JSON.stringify(parsedValue); - break; - default: - parsedValue = value; - break; - } - return parsedValue; - }, - - mapMetadata(attr, parseType = 'parse') { - return { - key: attr[this.KEY_COLUMN], - value: (parseType === 'parse') - ? this.parseMetaValue( - attr[this.VALUE_COLUMN], - this.TYPE_COLUMN ? attr[this.TYPE_COLUMN] : false, - ) - : this.formatMetaValue( - attr[this.VALUE_COLUMN], - this.TYPE_COLUMN ? attr[this.TYPE_COLUMN] : false, - ), - ...this.extraColumns.map((extraCol) => ({ - [extraCol]: attr[extraCol] || null, - })), - }; - }, - - /** - * Parse the metadata collection. - * @param {Array} collection - - */ - mapMetadataCollection(collection, parseType = 'parse') { - return collection.map((model) => this.mapMetadata(model.attributes, parseType)); - }, -}; diff --git a/packages/server/src/collection/NestedSet/index.ts b/packages/server/src/collection/NestedSet/index.ts deleted file mode 100644 index e7480e900..000000000 --- a/packages/server/src/collection/NestedSet/index.ts +++ /dev/null @@ -1,116 +0,0 @@ - -export default class NestedSet { - /** - * Constructor method. - * @param {Object} options - - */ - constructor(items, options) { - this.options = { - parentId: 'parent_id', - id: 'id', - ...options, - }; - this.items = items || []; - this.tree = this.linkChildren(); - } - - setItems(items) { - this.items = items; - this.tree = this.linkChildren(); - } - - /** - * Link nodes children. - */ - linkChildren() { - if (this.items.length <= 0) return false; - - const map = {}; - this.items.forEach((item) => { - map[item.id] = item; - map[item.id].children = {}; - }); - - this.items.forEach((item) => { - const parentNodeId = item[this.options.parentId]; - if (parentNodeId) { - map[parentNodeId].children[item.id] = item; - } - }); - return map; - } - - toArray() { - const stack = []; - const treeNodes = this.items.map((i) => ({ ...i })); - - const walk = (nodes) => { - nodes.forEach((node) => { - if (!node[this.options.parentId]) { - stack.push(node); - } - if (node.children) { - const childrenNodes = Object.values(node.children) - .map((i) => ({ ...i })); - - node.children = childrenNodes; - walk(childrenNodes); - } - }); - }; - walk(treeNodes); - return stack; - } - - getTree() { - return this.tree; - } - - getElementById(id) { - return this.tree[id] || null - } - - getParents(id) { - const item = this.getElementById(id); - const parents = []; - let index = 0; - - const walk = (_item) => { - if (!item) return; - - if (index) { - parents.push(_item); - } - if (_item[this.options.parentId]) { - const parentItem = this.getElementById(_item[this.options.parentId]); - - index++; - walk(parentItem); - } - }; - walk(item); - return parents; - } - - toFlattenArray(nodeMapper) { - const flattenTree = []; - - const traversal = (nodes, parentNode) => { - nodes.forEach((node) => { - let nodeMapped = node; - - if (typeof nodeMapper === 'function') { - nodeMapped = nodeMapper(nodeMapped, parentNode); - } - flattenTree.push(nodeMapped); - - if (node.children && node.children.length > 0) { - traversal(node.children, node); - } - }); - }; - traversal(this.collection); - - return flattenTree; - } -} diff --git a/packages/server/src/collection/ResourceFieldMetadataCollection.ts b/packages/server/src/collection/ResourceFieldMetadataCollection.ts deleted file mode 100644 index 5d53dc17f..000000000 --- a/packages/server/src/collection/ResourceFieldMetadataCollection.ts +++ /dev/null @@ -1,14 +0,0 @@ -import MetableCollection from '@/lib/Metable/MetableCollection'; -import ResourceFieldMetadata from 'models/ResourceFieldMetadata'; - -export default class ResourceFieldMetadataCollection extends MetableCollection { - /** - * Constructor method. - */ - constructor() { - super(); - - this.setModel(ResourceFieldMetadata); - this.extraColumns = ['resource_id', 'resource_item_id']; - } -} diff --git a/packages/server/src/collection/SoftDeleteQueryBuilder.ts b/packages/server/src/collection/SoftDeleteQueryBuilder.ts deleted file mode 100644 index 2bd15fe30..000000000 --- a/packages/server/src/collection/SoftDeleteQueryBuilder.ts +++ /dev/null @@ -1,73 +0,0 @@ -import moment from 'moment'; -import { Model } from 'objection'; - -const options = { - columnName: 'deleted_at', - deletedValue: moment().format('YYYY-MM-DD HH:mm:ss'), - notDeletedValue: null, -}; - -export default class SoftDeleteQueryBuilder extends Model.QueryBuilder { - constructor(...args) { - super(...args); - - this.onBuild((builder) => { - if (builder.isFind() || builder.isDelete() || builder.isUpdate()) { - builder.whereNotDeleted(); - } - }); - } - - /** - * override the normal delete function with one that patches the row's "deleted" column - */ - delete() { - this.context({ - softDelete: true, - }); - const patch = {}; - patch[options.columnName] = options.deletedValue; - return this.patch(patch); - } - - /** - * Provide a way to actually delete the row if necessary - */ - hardDelete() { - return super.delete(); - } - - /** - * Provide a way to undo the delete - */ - undelete() { - this.context({ - undelete: true, - }); - const patch = {}; - patch[options.columnName] = options.notDeletedValue; - return this.patch(patch); - } - - /** - * Provide a way to filter to ONLY deleted records without having to remember the column name - */ - whereDeleted() { - const prefix = this.modelClass().tableName; - - // this if is for backwards compatibility, to protect those that used a nullable `deleted` field - if (options.deletedValue === true) { - return this.where(`${prefix}.${options.columnName}`, options.deletedValue); - } - // qualify the column name - return this.whereNot(`${prefix}.${options.columnName}`, options.notDeletedValue); - } - - // provide a way to filter out deleted records without having to remember the column name - whereNotDeleted() { - const prefix = this.modelClass().tableName; - - // qualify the column name - return this.where(`${prefix}.${options.columnName}`, options.notDeletedValue); - } -} diff --git a/packages/server/src/commands/bigcapital.ts b/packages/server/src/commands/bigcapital.ts deleted file mode 100644 index 7e9b6cc88..000000000 --- a/packages/server/src/commands/bigcapital.ts +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env node -import commander from 'commander'; -import color from 'colorette'; -import argv from 'getopts'; -import Knex from 'knex'; -import { knexSnakeCaseMappers } from 'objection'; -import { PromisePool } from '@supercharge/promise-pool'; -import '../before'; -import config from '../config'; - -function initSystemKnex() { - return Knex({ - client: config.system.db_client, - connection: { - host: config.system.db_host, - user: config.system.db_user, - password: config.system.db_password, - database: config.system.db_name, - charset: 'utf8', - }, - migrations: { - directory: config.system.migrations_dir, - }, - seeds: { - directory: config.system.seeds_dir, - }, - pool: { min: 0, max: 7 }, - ...knexSnakeCaseMappers({ upperCase: true }), - }); -} - -function initTenantKnex(organizationId: string = '') { - return Knex({ - client: config.tenant.db_client, - connection: { - host: config.tenant.db_host, - user: config.tenant.db_user, - password: config.tenant.db_password, - database: `${config.tenant.db_name_prefix}${organizationId}`, - charset: config.tenant.charset, - }, - migrations: { - directory: config.tenant.migrations_dir, - }, - seeds: { - directory: config.tenant.seeds_dir, - }, - pool: { min: 0, max: 5 }, - ...knexSnakeCaseMappers({ upperCase: true }), - }); -} -function exit(text) { - if (text instanceof Error) { - console.error( - color.red(`${text.detail ? `${text.detail}\n` : ''}${text.stack}`) - ); - } else { - console.error(color.red(text)); - } - process.exit(1); -} - -function success(text) { - console.log(text); - process.exit(0); -} -function log(text) { - console.log(text); -} - -function getAllSystemTenants(knex) { - return knex('tenants'); -} - -function getAllInitializedTenants(knex) { - return knex('tenants').whereNotNull('initializedAt'); -} - -const MIGRATION_CONCURRENCY = 10; - -// module.exports = { -// log, -// success, -// exit, -// initSystemKnex, -// }; - -// - bigcapital system:migrate:latest -// - bigcapital system:migrate:rollback -// - bigcapital tenants:migrate:latest -// - bigcapital tenants:migrate:latest --tenant_id=XXX -// - bigcapital tenants:migrate:rollback -// - bigcapital tenants:migrate:rollback --tenant_id=XXX -// - bigcapital tenants:migrate:make -// - bigcapital system:migrate:make -// - bigcapital tenants:list -// - bigcapital tenants:list --all - -commander - .command('system:migrate:rollback') - .description('Migrate the system database of the application.') - .action(async () => { - try { - const sysKnex = await initSystemKnex(); - const [batchNo, _log] = await sysKnex.migrate.rollback(); - - if (_log.length === 0) { - success(color.cyan('Already at the base migration')); - } - success( - color.green(`Batch ${batchNo} rolled back: ${_log.length} migrations`) + - (argv.verbose ? `\n${color.cyan(_log.join('\n'))}` : '') - ); - } catch (error) { - exit(error); - } - }); - -commander - .command('system:migrate:latest') - .description('Migrate latest mgiration of the system database.') - .action(async () => { - try { - const sysKnex = await initSystemKnex(); - const [batchNo, log] = await sysKnex.migrate.latest(); - - if (log.length === 0) { - success(color.cyan('Already up to date')); - } - success( - color.green(`Batch ${batchNo} run: ${log.length} migrations`) + - (argv.verbose ? `\n${color.cyan(log.join('\n'))}` : '') - ); - } catch (error) { - exit(error); - } - }); - -commander - .command('system:migrate:make ') - .description('Created a named migration file to the system database.') - .action(async (name) => { - const sysKnex = await initSystemKnex(); - - sysKnex.migrate - .make(name) - .then((name) => { - success(color.green(`Created Migration: ${name}`)); - }) - .catch(exit); - }); - -commander - .command('tenants:list') - .description('Retrieve a list of all system tenants databases.') - .option('-a, --all', 'All tenants even are not initialized.') - .action(async (cmd) => { - try { - const sysKnex = await initSystemKnex(); - const tenants = cmd?.all - ? await getAllSystemTenants(sysKnex) - : await getAllInitializedTenants(sysKnex); - - tenants.forEach((tenant) => { - const dbName = `${config.tenant.db_name_prefix}${tenant.organizationId}`; - console.log( - `ID: ${tenant.id} | Organization ID: ${tenant.organizationId} | DB Name: ${dbName}` - ); - }); - } catch (error) { - exit(error); - } - success('---'); - }); - -commander - .command('tenants:migrate:make ') - .description('Created a named migration file to the tenants database.') - .action(async (name) => { - const sysKnex = await initTenantKnex(); - - sysKnex.migrate - .make(name) - .then((name) => { - success(color.green(`Created Migration: ${name}`)); - }) - .catch(exit); - }); - -commander - .command('tenants:migrate:latest') - .description('Migrate all tenants or the given tenant id.') - .option( - '-t, --tenant_id [tenant_id]', - 'Which organization id do you migrate.' - ) - .action(async (cmd) => { - try { - const sysKnex = await initSystemKnex(); - const tenants = await getAllInitializedTenants(sysKnex); - const tenantsOrgsIds = tenants.map((tenant) => tenant.organizationId); - - if (cmd.tenant_id && tenantsOrgsIds.indexOf(cmd.tenant_id) === -1) { - exit(`The given tenant id ${cmd.tenant_id} is not exists.`); - } - // Validate the tenant id exist first of all. - const migrateTenant = async (organizationId) => { - try { - const tenantKnex = await initTenantKnex(organizationId); - const [batchNo, _log] = await tenantKnex.migrate.latest(); - - const tenantDb = `${config.tenant.db_name_prefix}${organizationId}`; - - if (_log.length === 0) { - log(color.cyan('Already up to date')); - } - log( - color.green( - `Tenant ${tenantDb} > Batch ${batchNo} run: ${_log.length} migrations` - ) + (argv.verbose ? `\n${color.cyan(log.join('\n'))}` : '') - ); - log('-------------------'); - } catch (error) { - log(error); - } - }; - if (!cmd.tenant_id) { - await PromisePool.withConcurrency(MIGRATION_CONCURRENCY) - .for(tenants) - .process((tenant, index, pool) => { - return migrateTenant(tenant.organizationId); - }) - .then(() => { - success('All tenants are migrated.'); - }); - } else { - await migrateTenant(cmd.tenant_id); - } - } catch (error) { - exit(error); - } - }); - -commander - .command('tenants:migrate:rollback') - .description('Rollback the last batch of tenants migrations.') - .option( - '-t, --tenant_id [tenant_id]', - 'Which organization id do you migrate.' - ) - .action(async (cmd) => { - try { - const sysKnex = await initSystemKnex(); - const tenants = await getAllInitializedTenants(sysKnex); - const tenantsOrgsIds = tenants.map((tenant) => tenant.organizationId); - - if (cmd.tenant_id && tenantsOrgsIds.indexOf(cmd.tenant_id) === -1) { - exit(`The given tenant id ${cmd.tenant_id} is not exists.`); - } - - const migrateTenant = async (organizationId: string) => { - try { - const tenantKnex = await initTenantKnex(organizationId); - const [batchNo, _log] = await tenantKnex.migrate.rollback(); - const tenantDb = `${config.tenant.db_name_prefix}${organizationId}`; - - if (_log.length === 0) { - log(color.cyan('Already at the base migration')); - } - log( - color.green( - `Tenant: ${tenantDb} > Batch ${batchNo} rolled back: ${_log.length} migrations` - ) + (argv.verbose ? `\n${color.cyan(_log.join('\n'))}` : '') - ); - log('---------------'); - } catch (error) { - exit(error); - } - }; - - if (!cmd.tenant_id) { - await PromisePool.withConcurrency(MIGRATION_CONCURRENCY) - .for(tenants) - .process((tenant, index, pool) => { - return migrateTenant(tenant.organizationId); - }) - .then(() => { - success('All tenants are rollbacked.'); - }); - } else { - await migrateTenant(cmd.tenant_id); - } - } catch (error) { - exit(error); - } - }); diff --git a/packages/server/src/commands/index.ts b/packages/server/src/commands/index.ts deleted file mode 100644 index 627eeb658..000000000 --- a/packages/server/src/commands/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import commander from 'commander'; -import './bigcapital'; - -commander.parse(); diff --git a/packages/server-nest/src/common/config/gotenberg.ts b/packages/server/src/common/config/gotenberg.ts similarity index 100% rename from packages/server-nest/src/common/config/gotenberg.ts rename to packages/server/src/common/config/gotenberg.ts diff --git a/packages/server-nest/src/common/config/index.ts b/packages/server/src/common/config/index.ts similarity index 100% rename from packages/server-nest/src/common/config/index.ts rename to packages/server/src/common/config/index.ts diff --git a/packages/server-nest/src/common/config/inventory.ts b/packages/server/src/common/config/inventory.ts similarity index 100% rename from packages/server-nest/src/common/config/inventory.ts rename to packages/server/src/common/config/inventory.ts diff --git a/packages/server-nest/src/common/config/jwt.ts b/packages/server/src/common/config/jwt.ts similarity index 100% rename from packages/server-nest/src/common/config/jwt.ts rename to packages/server/src/common/config/jwt.ts diff --git a/packages/server-nest/src/common/config/lemonsqueezy.ts b/packages/server/src/common/config/lemonsqueezy.ts similarity index 100% rename from packages/server-nest/src/common/config/lemonsqueezy.ts rename to packages/server/src/common/config/lemonsqueezy.ts diff --git a/packages/server-nest/src/common/config/loops.ts b/packages/server/src/common/config/loops.ts similarity index 100% rename from packages/server-nest/src/common/config/loops.ts rename to packages/server/src/common/config/loops.ts diff --git a/packages/server-nest/src/common/config/mail.ts b/packages/server/src/common/config/mail.ts similarity index 100% rename from packages/server-nest/src/common/config/mail.ts rename to packages/server/src/common/config/mail.ts diff --git a/packages/server-nest/src/common/config/open-exchange.ts b/packages/server/src/common/config/open-exchange.ts similarity index 100% rename from packages/server-nest/src/common/config/open-exchange.ts rename to packages/server/src/common/config/open-exchange.ts diff --git a/packages/server-nest/src/common/config/plaid.ts b/packages/server/src/common/config/plaid.ts similarity index 100% rename from packages/server-nest/src/common/config/plaid.ts rename to packages/server/src/common/config/plaid.ts diff --git a/packages/server-nest/src/common/config/posthog.ts b/packages/server/src/common/config/posthog.ts similarity index 100% rename from packages/server-nest/src/common/config/posthog.ts rename to packages/server/src/common/config/posthog.ts diff --git a/packages/server-nest/src/common/config/redis.ts b/packages/server/src/common/config/redis.ts similarity index 100% rename from packages/server-nest/src/common/config/redis.ts rename to packages/server/src/common/config/redis.ts diff --git a/packages/server-nest/src/common/config/s3.ts b/packages/server/src/common/config/s3.ts similarity index 100% rename from packages/server-nest/src/common/config/s3.ts rename to packages/server/src/common/config/s3.ts diff --git a/packages/server-nest/src/common/config/signup-confirmation.ts b/packages/server/src/common/config/signup-confirmation.ts similarity index 100% rename from packages/server-nest/src/common/config/signup-confirmation.ts rename to packages/server/src/common/config/signup-confirmation.ts diff --git a/packages/server-nest/src/common/config/signup-restrictions.ts b/packages/server/src/common/config/signup-restrictions.ts similarity index 100% rename from packages/server-nest/src/common/config/signup-restrictions.ts rename to packages/server/src/common/config/signup-restrictions.ts diff --git a/packages/server-nest/src/common/config/signup.ts b/packages/server/src/common/config/signup.ts similarity index 100% rename from packages/server-nest/src/common/config/signup.ts rename to packages/server/src/common/config/signup.ts diff --git a/packages/server-nest/src/common/config/stripe-payment.ts b/packages/server/src/common/config/stripe-payment.ts similarity index 100% rename from packages/server-nest/src/common/config/stripe-payment.ts rename to packages/server/src/common/config/stripe-payment.ts diff --git a/packages/server-nest/src/common/config/system-database.ts b/packages/server/src/common/config/system-database.ts similarity index 100% rename from packages/server-nest/src/common/config/system-database.ts rename to packages/server/src/common/config/system-database.ts diff --git a/packages/server-nest/src/common/config/tenant-database.ts b/packages/server/src/common/config/tenant-database.ts similarity index 100% rename from packages/server-nest/src/common/config/tenant-database.ts rename to packages/server/src/common/config/tenant-database.ts diff --git a/packages/server-nest/src/common/constants/files.constants.ts b/packages/server/src/common/constants/files.constants.ts similarity index 100% rename from packages/server-nest/src/common/constants/files.constants.ts rename to packages/server/src/common/constants/files.constants.ts diff --git a/packages/server-nest/src/common/constants/multer.constants.ts b/packages/server/src/common/constants/multer.constants.ts similarity index 100% rename from packages/server-nest/src/common/constants/multer.constants.ts rename to packages/server/src/common/constants/multer.constants.ts diff --git a/packages/server-nest/src/common/constants/multer.utils.ts b/packages/server/src/common/constants/multer.utils.ts similarity index 100% rename from packages/server-nest/src/common/constants/multer.utils.ts rename to packages/server/src/common/constants/multer.utils.ts diff --git a/packages/server-nest/src/common/events/events.ts b/packages/server/src/common/events/events.ts similarity index 100% rename from packages/server-nest/src/common/events/events.ts rename to packages/server/src/common/events/events.ts diff --git a/packages/server-nest/src/common/exceptions/ModelEntityNotFound.ts b/packages/server/src/common/exceptions/ModelEntityNotFound.ts similarity index 100% rename from packages/server-nest/src/common/exceptions/ModelEntityNotFound.ts rename to packages/server/src/common/exceptions/ModelEntityNotFound.ts diff --git a/packages/server-nest/src/common/filters/service-error.filter.ts b/packages/server/src/common/filters/service-error.filter.ts similarity index 100% rename from packages/server-nest/src/common/filters/service-error.filter.ts rename to packages/server/src/common/filters/service-error.filter.ts diff --git a/packages/server-nest/src/common/interceptors/file.interceptor.ts b/packages/server/src/common/interceptors/file.interceptor.ts similarity index 100% rename from packages/server-nest/src/common/interceptors/file.interceptor.ts rename to packages/server/src/common/interceptors/file.interceptor.ts diff --git a/packages/server-nest/src/common/interceptors/serialize.interceptor.ts b/packages/server/src/common/interceptors/serialize.interceptor.ts similarity index 100% rename from packages/server-nest/src/common/interceptors/serialize.interceptor.ts rename to packages/server/src/common/interceptors/serialize.interceptor.ts diff --git a/packages/server-nest/src/common/pipes/ClassValidation.pipe.ts b/packages/server/src/common/pipes/ClassValidation.pipe.ts similarity index 100% rename from packages/server-nest/src/common/pipes/ClassValidation.pipe.ts rename to packages/server/src/common/pipes/ClassValidation.pipe.ts diff --git a/packages/server-nest/src/common/pipes/ZodValidation.pipe.ts b/packages/server/src/common/pipes/ZodValidation.pipe.ts similarity index 100% rename from packages/server-nest/src/common/pipes/ZodValidation.pipe.ts rename to packages/server/src/common/pipes/ZodValidation.pipe.ts diff --git a/packages/server-nest/src/common/repository/CachableRepository.ts b/packages/server/src/common/repository/CachableRepository.ts similarity index 100% rename from packages/server-nest/src/common/repository/CachableRepository.ts rename to packages/server/src/common/repository/CachableRepository.ts diff --git a/packages/server-nest/src/common/repository/EntityRepository.ts b/packages/server/src/common/repository/EntityRepository.ts similarity index 100% rename from packages/server-nest/src/common/repository/EntityRepository.ts rename to packages/server/src/common/repository/EntityRepository.ts diff --git a/packages/server-nest/src/common/repository/TenantRepository.ts b/packages/server/src/common/repository/TenantRepository.ts similarity index 100% rename from packages/server-nest/src/common/repository/TenantRepository.ts rename to packages/server/src/common/repository/TenantRepository.ts diff --git a/packages/server-nest/src/common/types/Constructor.ts b/packages/server/src/common/types/Constructor.ts similarity index 100% rename from packages/server-nest/src/common/types/Constructor.ts rename to packages/server/src/common/types/Constructor.ts diff --git a/packages/server-nest/src/common/types/Date.ts b/packages/server/src/common/types/Date.ts similarity index 100% rename from packages/server-nest/src/common/types/Date.ts rename to packages/server/src/common/types/Date.ts diff --git a/packages/server-nest/src/common/types/Discount.ts b/packages/server/src/common/types/Discount.ts similarity index 100% rename from packages/server-nest/src/common/types/Discount.ts rename to packages/server/src/common/types/Discount.ts diff --git a/packages/server-nest/src/common/types/Features.ts b/packages/server/src/common/types/Features.ts similarity index 100% rename from packages/server-nest/src/common/types/Features.ts rename to packages/server/src/common/types/Features.ts diff --git a/packages/server/src/config/index.ts b/packages/server/src/config/index.ts deleted file mode 100644 index c7c8061ee..000000000 --- a/packages/server/src/config/index.ts +++ /dev/null @@ -1,275 +0,0 @@ -import dotenv from 'dotenv'; -import path from 'path'; -import { defaultTo, toInteger } from 'lodash'; -import { castCommaListEnvVarToArray, parseBoolean } from '@/utils'; - -dotenv.config(); - -const API_RATE_LIMIT = process.env.API_RATE_LIMIT?.split(',') || []; - -module.exports = { - /** - * Your favorite port - */ - port: parseInt(process.env.PORT, 10), - - /** - * System database configuration. - */ - system: { - db_client: process.env.SYSTEM_DB_CLIENT || process.env.DB_CLIENT || 'mysql', - db_host: process.env.SYSTEM_DB_HOST || process.env.DB_HOST, - db_user: process.env.SYSTEM_DB_USER || process.env.DB_USER, - db_password: process.env.SYSTEM_DB_PASSWORD || process.env.DB_PASSWORD, - db_name: process.env.SYSTEM_DB_NAME, - charset: process.env.SYSTEM_DB_CHARSET || process.env.DB_CHARSET, - migrations_dir: path.join(global.__root_dir, './src/system/migrations'), - seeds_dir: path.join(global.__root_dir, './src/system/seeds'), - }, - - /** - * Tenant database configuration. - */ - tenant: { - db_client: process.env.TENANT_DB_CLIENT || process.env.DB_CLIENT || 'mysql', - db_name_prefix: process.env.TENANT_DB_NAME_PERFIX || 'bigcapital_tenant_', - db_host: process.env.TENANT_DB_HOST || process.env.DB_HOST, - db_user: process.env.TENANT_DB_USER || process.env.DB_USER, - db_password: process.env.TENANT_DB_PASSWORD || process.env.DB_PASSWORD, - charset: process.env.TENANT_DB_CHARSET || process.env.DB_CHARSET, - migrations_dir: path.join(global.__root_dir, './src/database/migrations'), - seeds_dir: path.join(global.__root_dir, './src/database/seeds/core'), - }, - - /** - * Databases manager config. - */ - manager: { - superUser: process.env.SYSTEM_DB_USER || process.env.DB_USER, - superPassword: process.env.SYSTEM_DB_PASSWORD || process.env.DB_PASSWORD, - }, - - /** - * Mail. - */ - mail: { - host: process.env.MAIL_HOST, - port: process.env.MAIL_PORT, - secure: parseBoolean(defaultTo(process.env.MAIL_SECURE, false), false), - username: process.env.MAIL_USERNAME, - password: process.env.MAIL_PASSWORD, - from: process.env.MAIL_FROM_ADDRESS, - }, - - /** - * Mongo DB. - */ - mongoDb: { - /** - * That long string from mlab - */ - databaseURL: process.env.MONGODB_DATABASE_URL, - }, - - /** - * Agenda - */ - agenda: { - dbCollection: process.env.AGENDA_DB_COLLECTION, - pooltime: process.env.AGENDA_POOL_TIME, - concurrency: parseInt(process.env.AGENDA_CONCURRENCY, 10), - }, - - /** - * Agendash. - */ - agendash: { - user: process.env.AGENDASH_AUTH_USER, - password: process.env.AGENDASH_AUTH_PASSWORD, - }, - - /** - * Easy SMS gateway. - */ - easySMSGateway: { - api_key: process.env.EASY_SMS_TOKEN, - }, - - /** - * JWT secret. - */ - jwtSecret: process.env.JWT_SECRET, - - /** - * - */ - resetPasswordSeconds: 600, - - /** - * Application base URL. - */ - baseURL: process.env.BASE_URL, - - /** - * General API prefix. - */ - api: { - prefix: '/api', - }, - - /** - * Redis storage configuration. - */ - redis: { - port: 6379, - }, - - /** - * Throttler configuration. - */ - throttler: { - login: { - points: 5, - duration: 60 * 60 * 24 * 1, // Store number for 90 days since first fail - blockDuration: 60 * 15, - }, - requests: { - points: API_RATE_LIMIT[0] ? toInteger(API_RATE_LIMIT[0]) : 120, - duration: API_RATE_LIMIT[1] ? toInteger(API_RATE_LIMIT[1]) : 60, - blockDuration: API_RATE_LIMIT[2] ? toInteger(API_RATE_LIMIT[2]) : 60 * 10, - }, - }, - - /** - * Sign-up restrictions - */ - signupRestrictions: { - disabled: parseBoolean(process.env.SIGNUP_DISABLED, false), - allowedDomains: castCommaListEnvVarToArray( - process.env.SIGNUP_ALLOWED_DOMAINS - ), - allowedEmails: castCommaListEnvVarToArray( - process.env.SIGNUP_ALLOWED_EMAILS - ), - }, - - /** - * Sign-up email confirmation - */ - signupConfirmation: { - enabled: parseBoolean( - process.env.SIGNUP_EMAIL_CONFIRMATION, - false - ), - }, - - /** - * Puppeteer remote browserless connection. - */ - puppeteer: { - browserWSEndpoint: process.env.BROWSER_WS_ENDPOINT, - }, - - scheduleComputeItemCost: 'in 5 seconds', - - /** - * Latest tenant database batch number. - * - * Should increment the batch number once you create a new migrations or seeds - * to application detarmines to upgrade. - */ - databaseBatch: 4, - - /** - * Exchange rate. - */ - exchangeRate: { - service: 'open-exchange-rate', - openExchangeRate: { - appId: process.env.OPEN_EXCHANGE_RATE_APP_ID, - }, - }, - - /** - * Bank Synchronization. - */ - bankSync: { - enabled: parseBoolean(defaultTo(process.env.BANKING_CONNECT, false), false), - provider: 'plaid', - }, - - /** - * Plaid. - */ - plaid: { - env: process.env.PLAID_ENV || 'sandbox', - clientId: process.env.PLAID_CLIENT_ID, - secret: process.env.PLAID_SECRET, - linkWebhook: process.env.PLAID_LINK_WEBHOOK, - }, - - /** - * Lemon Squeezy. - */ - lemonSqueezy: { - key: process.env.LEMONSQUEEZY_API_KEY, - storeId: process.env.LEMONSQUEEZY_STORE_ID, - webhookSecret: process.env.LEMONSQUEEZY_WEBHOOK_SECRET, - redirectTo: `${process.env.BASE_URL}/setup`, - }, - - /** - * Bigcapital (Cloud). - * NOTE: DO NOT CHANGE THIS OPTION OR ADD THIS ENV VAR. - */ - hostedOnBigcapitalCloud: parseBoolean( - defaultTo(process.env.HOSTED_ON_BIGCAPITAL_CLOUD, false), - false - ), - - /** - * S3 for documents. - */ - s3: { - region: process.env.S3_REGION, - accessKeyId: process.env.S3_ACCESS_KEY_ID, - secretAccessKey: process.env.S3_SECRET_ACCESS_KEY, - endpoint: process.env.S3_ENDPOINT, - bucket: process.env.S3_BUCKET || 'bigcapital-documents', - forcePathStyle: parseBoolean( - defaultTo(process.env.S3_FORCE_PATH_STYLE, false), - false - ), - }, - - loops: { - apiKey: process.env.LOOPS_API_KEY, - }, - - /** - * One-click demo accounts. - */ - oneClickDemoAccounts: { - enable: parseBoolean(process.env.ONE_CLICK_DEMO_ACCOUNTS, false), - demoUrl: process.env.ONE_CLICK_DEMO_ACCOUNTS_URL || '', - }, - - /** - * PostHog - */ - posthog: { - apiKey: process.env.POSTHOG_API_KEY, - host: process.env.POSTHOG_HOST, - }, - - /** - * Stripe Payment Integration. - */ - stripePayment: { - secretKey: process.env.STRIPE_PAYMENT_SECRET_KEY || '', - publishableKey: process.env.STRIPE_PAYMENT_PUBLISHABLE_KEY || '', - clientId: process.env.STRIPE_PAYMENT_CLIENT_ID || '', - redirectTo: process.env.STRIPE_PAYMENT_REDIRECT_URL || '', - webhooksSecret: process.env.STRIPE_PAYMENT_WEBHOOKS_SECRET || '', - }, -}; diff --git a/packages/server/src/config/knexConfig.ts b/packages/server/src/config/knexConfig.ts deleted file mode 100644 index 2d7631e9b..000000000 --- a/packages/server/src/config/knexConfig.ts +++ /dev/null @@ -1,59 +0,0 @@ -import config from '@/config'; -import { ITenant } from '@/interfaces'; - -export const tenantKnexConfig = (tenant: ITenant) => { - const { organizationId, id } = tenant; - - return { - client: config.tenant.db_client, - connection: { - host: config.tenant.db_host, - user: config.tenant.db_user, - password: config.tenant.db_password, - database: `${config.tenant.db_name_prefix}${organizationId}`, - charset: config.tenant.charset, - }, - migrations: { - directory: config.tenant.migrations_dir, - }, - seeds: { - tableName: 'bigcapital_seeds', - directory: config.tenant.seeds_dir, - }, - pool: { min: 0, max: 5 }, - userParams: { - tenantId: id, - organizationId - } - }; -}; - -export const systemKnexConfig = { - client: config.system.db_client, - connection: { - host: config.system.db_host, - user: config.system.db_user, - password: config.system.db_password, - database: config.system.db_name, - charset: 'utf8', - }, - migrations: { - directory: config.system.migrations_dir, - }, - seeds: { - directory: config.system.seeds_dir, - }, - pool: { min: 0, max: 7 }, -}; - -export const systemDbManager = { - collate: [], - superUser: config.manager.superUser, - superPassword: config.manager.superPassword, -}; - -export const tenantSeedConfig = (tenant: ITenant) => { - return { - directory: config.tenant.seeds_dir, - }; -} \ No newline at end of file diff --git a/packages/server/src/config/smsNotifications.ts b/packages/server/src/config/smsNotifications.ts deleted file mode 100644 index d63705b7e..000000000 --- a/packages/server/src/config/smsNotifications.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { ISmsNotificationDefined, SMS_NOTIFICATION_KEY } from '@/interfaces'; - -export default [ - { - notificationLabel: 'sms_notification.invoice_details.label', - notificationDescription: 'sms_notification.invoice_details.description', - key: SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS, - module: 'sale-invoice', - moduleFormatted: 'module.sale_invoices.label', - allowedVariables: [ - { - variable: 'InvoiceNumber', - description: 'sms_notification.invoice.var.invoice_number', - }, - { - variable: 'ReferenceNumber', - description: 'sms_notification.invoice.var.reference_number', - }, - { - variable: 'CustomerName', - description: 'sms_notification.invoice.var.customer_name', - }, - { - variable: 'DueAmount', - description: 'sms_notification.invoice.var.due_amount', - }, - { - variable: 'DueDate', - description: 'sms_notification.invoice.var.due_date', - }, - { - variable: 'Amount', - description: 'sms_notification.invoice.var.amount', - }, - { - variable: 'CompanyName', - description: 'sms_notification.invoice.var.company_name', - }, - ], - defaultSmsMessage: 'sms_notification.invoice_details.default_message', - defaultIsNotificationEnabled: true, - }, - { - notificationLabel: 'sms_notification.invoice_reminder.label', - notificationDescription: 'sms_notification.invoice_reminder.description', - key: SMS_NOTIFICATION_KEY.SALE_INVOICE_REMINDER, - module: 'sale-invoice', - moduleFormatted: 'module.sale_invoices.label', - allowedVariables: [ - { - variable: 'InvoiceNumber', - description: 'sms_notification.invoice.var.invoice_number', - }, - { - variable: 'ReferenceNumber', - description: 'sms_notification.invoice.var.reference_number', - }, - { - variable: 'CustomerName', - description: 'sms_notification.invoice.var.customer_name', - }, - { - variable: 'DueAmount', - description: 'sms_notification.invoice.var.due_amount', - }, - { - variable: 'DueDate', - description: 'sms_notification.invoice.var.due_date', - }, - { - variable: 'Amount', - description: 'sms_notification.invoice.var.amount', - }, - { - variable: 'CompanyName', - description: 'sms_notification.invoice.var.company_name', - }, - ], - defaultSmsMessage: 'sms_notification.invoice_reminder.default_message', - defaultIsNotificationEnabled: true, - }, - { - notificationLabel: 'sms_notification.receipt_details.label', - notificationDescription: 'sms_notification.receipt_details.description', - key: SMS_NOTIFICATION_KEY.SALE_RECEIPT_DETAILS, - module: 'sale-receipt', - moduleFormatted: 'module.sale_receipts.label', - allowedVariables: [ - { - variable: 'CustomerName', - description: 'sms_notification.receipt.var.customer_name', - }, - { - variable: 'ReceiptNumber', - description: 'sms_notification.receipt.var.receipt_number', - }, - { - variable: 'ReferenceNumber', - description: 'sms_notification.receipt.var.reference_number', - }, - { - variable: 'Amount', - description: 'sms_notification.receipt.var.amount', - }, - { - variable: 'CompanyName', - description: 'sms_notification.receipt.var.company_name', - }, - ], - defaultSmsMessage: 'sms_notification.receipt_details.default_message', - }, - { - notificationLabel: 'sms_notification.sale_estimate_details.label', - notificationDescription: 'sms_notification.estimate_details.description', - key: SMS_NOTIFICATION_KEY.SALE_ESTIMATE_DETAILS, - module: 'sale-estimate', - moduleFormatted: 'module.sale_estimates.label', - allowedVariables: [ - { - variable: 'EstimateNumber', - description: 'sms_notification.estimate.var.estimate_number', - }, - { - variable: 'EstimateDate', - description: 'sms_notification.estimate.var.estimate_date', - }, - { - variable: 'ExpirationDate', - description: 'sms_notification.estimate.var.expiration_date' - }, - { - variable: 'ReferenceNumber', - description: 'sms_notification.estimate.var.reference_number', - }, - { - variable: 'CustomerName', - description: 'sms_notification.estimate.var.customer_name', - }, - { - variable: 'Amount', - description: 'sms_notification.estimate.var.amount', - }, - { - variable: 'CompanyName', - description: 'sms_notification.estimate.var.company_name', - }, - ], - defaultSmsMessage: 'sms_notification.estimate.default_message', - }, - { - notificationLabel: 'sms_notification.payment_receive_details.label', - notificationDescription: 'sms_notification.payment_receive.description', - key: SMS_NOTIFICATION_KEY.PAYMENT_RECEIVE_DETAILS, - module: 'payment-receive', - moduleFormatted: 'module.payment_receives.label', - allowedVariables: [ - { - variable: 'PaymentNumber', - description: 'sms_notification.payment.var.payment_number', - }, - { - variable: 'ReferenceNumber', - description: 'sms_notification.payment.var.reference_number', - }, - { - variable: 'CustomerName', - description: 'sms_notification.payment.var.customer_name', - }, - { - variable: 'Amount', - description: 'sms_notification.payment.var.amount', - }, - { - variable: 'InvoiceNumber', - description: 'sms_notification.payment.var.invoice_number', - }, - { - variable: 'CompanyName', - description: 'sms_notification.payment.company_name', - }, - ], - defaultSmsMessage: 'sms_notification.payment_receive.default_message', - defaultIsNotificationEnabled: true, - }, - { - notificationLabel: 'sms_notification.customer_balance.label', - notificationDescription: 'sms_notification.customer_balance.description', - key: SMS_NOTIFICATION_KEY.CUSTOMER_BALANCE, - module: 'customer', - moduleFormatted: 'module.customers.label', - defaultSmsMessage: 'sms_notification.customer_balance.default_message', - allowedVariables: [ - { - variable: 'CustomerName', - description: 'sms_notification.customer.var.customer_name', - }, - { - variable: 'Balance', - description: 'sms_notification.customer.var.balance', - }, - { - variable: 'CompanyName', - description: 'sms_notification.customer.var.company_name', - }, - ], - }, -] as ISmsNotificationDefined[]; diff --git a/packages/server-nest/src/constants/accept-type.ts b/packages/server/src/constants/accept-type.ts similarity index 100% rename from packages/server-nest/src/constants/accept-type.ts rename to packages/server/src/constants/accept-type.ts diff --git a/packages/server-nest/src/constants/accounts.ts b/packages/server/src/constants/accounts.ts similarity index 100% rename from packages/server-nest/src/constants/accounts.ts rename to packages/server/src/constants/accounts.ts diff --git a/packages/server-nest/src/constants/data-types.ts b/packages/server/src/constants/data-types.ts similarity index 100% rename from packages/server-nest/src/constants/data-types.ts rename to packages/server/src/constants/data-types.ts diff --git a/packages/server/src/constants/event-tracker.ts b/packages/server/src/constants/event-tracker.ts deleted file mode 100644 index 12a89d6bd..000000000 --- a/packages/server/src/constants/event-tracker.ts +++ /dev/null @@ -1,130 +0,0 @@ -export const SALE_INVOICE_CREATED = 'Sale invoice created'; -export const SALE_INVOICE_EDITED = 'Sale invoice edited'; -export const SALE_INVOICE_DELETED = 'Sale invoice deleted'; -export const SALE_INVOICE_MAIL_DELIVERED = 'Sale invoice mail delivered'; -export const SALE_INVOICE_VIEWED = 'Sale invoice viewed'; -export const SALE_INVOICE_PDF_VIEWED = 'Sale invoice PDF viewed'; -export const SALE_INVOICE_MAIL_SENT = 'Sale invoice mail sent'; -export const SALE_INVOICE_MAIL_REMINDER_SENT = - 'Sale invoice reminder mail sent'; - -export const SALE_ESTIMATE_CREATED = 'Sale estimate created'; -export const SALE_ESTIMATE_EDITED = 'Sale estimate edited'; -export const SALE_ESTIMATE_DELETED = 'Sale estimate deleted'; -export const SALE_ESTIMATE_PDF_VIEWED = 'Sale estimate PDF viewed'; -export const SALE_ESTIMATE_VIEWED = 'Sale estimate viewed'; -export const SALE_ESTIMATE_MAIL_SENT = 'Sale estimate mail sent'; - -export const PAYMENT_RECEIVED_CREATED = 'Payment received created'; -export const PAYMENT_RECEIVED_EDITED = 'payment received edited'; -export const PAYMENT_RECEIVED_DELETED = 'Payment received deleted'; -export const PAYMENT_RECEIVED_PDF_VIEWED = 'Payment received PDF viewed'; -export const PAYMENT_RECEIVED_MAIL_SENT = 'Payment received mail sent'; - -export const SALE_RECEIPT_PDF_VIEWED = 'Sale credit PDF viewed'; -export const SALE_RECEIPT_MAIL_SENT = 'Sale credit mail sent'; - -export const CREDIT_NOTE_PDF_VIEWED = 'Credit note PDF viewed'; -export const CREDIT_NOTE_MAIL_SENT = 'Credit note mail sent'; - -export const BILL_CREATED = 'Bill created'; -export const BILL_EDITED = 'Bill edited'; -export const BILL_DELETED = 'Bill deleted'; - -export const PAYMENT_MADE_CREATED = 'Payment made created'; -export const PAYMENT_MADE_EDITED = 'Payment made edited'; -export const PAYMENT_MADE_DELETED = 'Payment made deleted'; - -export const EXPENSE_CREATED = 'Expense created'; -export const EXPENSE_EDITED = 'Expense edited'; -export const EXPENSE_DELETED = 'Expense deleted'; - -export const ACCOUNT_CREATED = 'Account created'; -export const ACCOUNT_EDITED = 'Account Edited'; -export const ACCOUNT_DELETED = 'Account deleted'; -export const ACCOUNT_VIEWED = 'Account viewed'; - -export const ITEM_EVENT_CREATED = 'Item created'; -export const ITEM_EVENT_EDITED = 'Item edited'; -export const ITEM_EVENT_DELETED = 'Item deleted'; -export const ITEM_EVENT_VIEWED = 'Item viewed'; - -export const AUTH_SIGNED_UP = 'Auth Signed-up'; -export const AUTH_RESET_PASSWORD = 'Auth reset password'; - -export const SUBSCRIPTION_CANCELLED = 'Subscription cancelled'; -export const SUBSCRIPTION_RESUMED = 'Subscription resumed'; -export const SUBSCRIPTION_PLAN_CHANGED = 'Subscription plan changed'; -export const SUBSCRIPTION_PAYMENT_SUCCEED = 'Subscription payment succeed'; -export const SUBSCRIPTION_PAYMENT_FAILED = 'Subscription payment failed'; - -export const CUSTOMER_CREATED = 'Customer created'; -export const CUSTOMER_EDITED = 'Customer edited'; -export const CUSTOMER_DELETED = 'Customer deleted'; - -export const VENDOR_CREATED = 'Vendor created'; -export const VENDOR_EDITED = 'Vendor edited'; -export const VENDOR_DELETED = 'Vendor deleted'; - -export const TRANSACTIONS_LOCKING_LOCKED = 'Transactions locking locked'; -export const TRANSACTIONS_LOCKING_LOCKING_CANCELLED = - 'Transactions locking cancelled'; -export const TRANSACTIONS_LOCKING_PARTIALLY_UNLOCKED = - 'Transactions locking partially unlocked'; -export const TRANSACTIONS_LOCKING_PARTIALLY_UNLOCK_CANCELLED = - 'Transactions locking partially unlock cancelled'; - -export const BANK_TRANSACTION_MATCHED = 'Bank transaction matching deleted'; -export const BANK_TRANSACTION_EXCLUDED = 'Bank transaction excluded'; -export const BANK_TRANSACTION_CATEGORIZED = 'Bank transaction categorized'; -export const BANK_TRANSACTION_UNCATEGORIZED = 'Bank transaction uncategorized'; -export const BANK_ACCOUNT_DISCONNECTED = 'Bank account disconnected'; - -export const MANUAL_JOURNAL_CREATED = 'Manual journal created'; -export const MANUAL_JOURNAL_EDITED = 'Manual journal edited'; -export const MANUAL_JOURNAL_DELETED = 'Manual journal deleted'; -export const MANUAL_JOURNAL_PUBLISHED = 'Manual journal published'; - -export const BANK_RULE_CREATED = 'Bank rule created'; -export const BANK_RULE_EDITED = 'Bank rule edited'; -export const BANK_RULE_DELETED = 'Bank rule deleted'; - -export const PDF_TEMPLATE_CREATED = 'PDF template created'; -export const PDF_TEMPLATE_EDITED = 'PDF template edited'; -export const PDF_TEMPLATE_DELETED = 'PDF template deleted'; -export const PDF_TEMPLATE_ASSIGNED_DEFAULT = 'PDF template assigned as default'; - -export const PAYMENT_METHOD_EDITED = 'Payment method edited'; -export const PAYMENT_METHOD_DELETED = 'Payment method deleted'; - -export const INVOICE_PAYMENT_LINK_GENERATED = 'Invoice payment link generated'; - -export const STRIPE_INTEGRAION_CONNECTED = - 'Stripe integration oauth2 connected'; - -// # Event Groups -export const ACCOUNT_GROUP = 'Account'; -export const ITEM_GROUP = 'Item'; -export const AUTH_GROUP = 'Auth'; -export const SALE_GROUP = 'Sale'; -export const PAYMENT_GROUP = 'Payment'; -export const BILL_GROUP = 'Bill'; -export const EXPENSE_GROUP = 'Expense'; - -// # Reports -export const BALANCE_SHEET_VIEWED = 'Balance sheet viewed'; -export const TRIAL_BALANCE_SHEET_VIEWED = 'Trial balance sheet viewed'; -export const PROFIT_LOSS_SHEET_VIEWED = 'Profit loss sheet viewed'; -export const CASHFLOW_STATEMENT_VIEWED = 'Cashflow statement viewed'; -export const GENERAL_LEDGER_VIEWED = 'General ledger viewed'; -export const JOURNAL_VIEWED = 'Journal viewed'; -export const RECEIVABLE_AGING_VIEWED = 'Receivable aging viewed'; -export const PAYABLE_AGING_VIEWED = 'Payable aging viewed'; -export const CUSTOMER_BALANCE_SUMMARY_VIEWED = - 'Customer balance summary viewed'; -export const VENDOR_BALANCE_SUMMARY_VIEWED = 'Vendor balance summary viewed'; -export const INVENTORY_VALUATION_VIEWED = 'Inventory valuation viewed'; -export const CUSTOMER_TRANSACTIONS_VIEWED = 'Customer transactions viewed'; -export const VENDOR_TRANSACTIONS_VIEWED = 'Vendor transactions viewed'; -export const SALES_BY_ITEM_VIEWED = 'Sales by item viewed'; -export const PURCHASES_BY_ITEM_VIEWED = 'Purchases by item viewed'; diff --git a/packages/server-nest/src/constants/metable-options.ts b/packages/server/src/constants/metable-options.ts similarity index 100% rename from packages/server-nest/src/constants/metable-options.ts rename to packages/server/src/constants/metable-options.ts diff --git a/packages/server/src/data/AccountTypes.ts b/packages/server/src/data/AccountTypes.ts deleted file mode 100644 index b6055e852..000000000 --- a/packages/server/src/data/AccountTypes.ts +++ /dev/null @@ -1,230 +0,0 @@ -export const ACCOUNT_TYPE = { - CASH: 'cash', - BANK: 'bank', - ACCOUNTS_RECEIVABLE: 'accounts-receivable', - INVENTORY: 'inventory', - OTHER_CURRENT_ASSET: 'other-current-asset', - FIXED_ASSET: 'fixed-asset', - NON_CURRENT_ASSET: 'none-current-asset', - - ACCOUNTS_PAYABLE: 'accounts-payable', - CREDIT_CARD: 'credit-card', - TAX_PAYABLE: 'tax-payable', - OTHER_CURRENT_LIABILITY: 'other-current-liability', - LOGN_TERM_LIABILITY: 'long-term-liability', - NON_CURRENT_LIABILITY: 'non-current-liability', - - EQUITY: 'equity', - INCOME: 'income', - OTHER_INCOME: 'other-income', - COST_OF_GOODS_SOLD: 'cost-of-goods-sold', - EXPENSE: 'expense', - OTHER_EXPENSE: 'other-expense', -}; - -export const ACCOUNT_PARENT_TYPE = { - CURRENT_ASSET: 'current-asset', - FIXED_ASSET: 'fixed-asset', - NON_CURRENT_ASSET: 'non-current-asset', - - CURRENT_LIABILITY: 'current-liability', - LOGN_TERM_LIABILITY: 'long-term-liability', - NON_CURRENT_LIABILITY: 'non-current-liability', - - EQUITY: 'equity', - EXPENSE: 'expense', - INCOME: 'income', -}; - -export const ACCOUNT_ROOT_TYPE = { - ASSET: 'asset', - LIABILITY: 'liability', - EQUITY: 'equity', - EXPENSE: 'expense', - INCOME: 'income', -}; - -export const ACCOUNT_NORMAL = { - CREDIT: 'credit', - DEBIT: 'debit', -}; -export const ACCOUNT_TYPES = [ - { - label: 'Cash', - key: ACCOUNT_TYPE.CASH, - normal: ACCOUNT_NORMAL.DEBIT, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_ASSET, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - multiCurrency: true, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Bank', - key: ACCOUNT_TYPE.BANK, - normal: ACCOUNT_NORMAL.DEBIT, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_ASSET, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - multiCurrency: true, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Accounts Receivable', - key: ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_ASSET, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Inventory', - key: ACCOUNT_TYPE.INVENTORY, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_ASSET, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Other Current Asset', - key: ACCOUNT_TYPE.OTHER_CURRENT_ASSET, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_ASSET, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Fixed Asset', - key: ACCOUNT_TYPE.FIXED_ASSET, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - parentType: ACCOUNT_PARENT_TYPE.FIXED_ASSET, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Non-Current Asset', - key: ACCOUNT_TYPE.NON_CURRENT_ASSET, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.ASSET, - parentType: ACCOUNT_PARENT_TYPE.FIXED_ASSET, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Accounts Payable', - key: ACCOUNT_TYPE.ACCOUNTS_PAYABLE, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.LIABILITY, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_LIABILITY, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Credit Card', - key: ACCOUNT_TYPE.CREDIT_CARD, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.LIABILITY, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_LIABILITY, - multiCurrency: true, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Tax Payable', - key: ACCOUNT_TYPE.TAX_PAYABLE, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.LIABILITY, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_LIABILITY, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Other Current Liability', - key: ACCOUNT_TYPE.OTHER_CURRENT_LIABILITY, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.LIABILITY, - parentType: ACCOUNT_PARENT_TYPE.CURRENT_LIABILITY, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Long Term Liability', - key: ACCOUNT_TYPE.LOGN_TERM_LIABILITY, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.LIABILITY, - parentType: ACCOUNT_PARENT_TYPE.LOGN_TERM_LIABILITY, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Non-Current Liability', - key: ACCOUNT_TYPE.NON_CURRENT_LIABILITY, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.LIABILITY, - parentType: ACCOUNT_PARENT_TYPE.NON_CURRENT_LIABILITY, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Equity', - key: ACCOUNT_TYPE.EQUITY, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.EQUITY, - parentType: ACCOUNT_PARENT_TYPE.EQUITY, - balanceSheet: true, - incomeSheet: false, - }, - { - label: 'Income', - key: ACCOUNT_TYPE.INCOME, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.INCOME, - parentType: ACCOUNT_PARENT_TYPE.INCOME, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Other Income', - key: ACCOUNT_TYPE.OTHER_INCOME, - normal: ACCOUNT_NORMAL.CREDIT, - rootType: ACCOUNT_ROOT_TYPE.INCOME, - parentType: ACCOUNT_PARENT_TYPE.INCOME, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Cost of Goods Sold', - key: ACCOUNT_TYPE.COST_OF_GOODS_SOLD, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.EXPENSE, - parentType: ACCOUNT_PARENT_TYPE.EXPENSE, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Expense', - key: ACCOUNT_TYPE.EXPENSE, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.EXPENSE, - parentType: ACCOUNT_PARENT_TYPE.EXPENSE, - balanceSheet: false, - incomeSheet: true, - }, - { - label: 'Other Expense', - key: ACCOUNT_TYPE.OTHER_EXPENSE, - normal: ACCOUNT_NORMAL.DEBIT, - rootType: ACCOUNT_ROOT_TYPE.EXPENSE, - parentType: ACCOUNT_PARENT_TYPE.EXPENSE, - balanceSheet: false, - incomeSheet: true, - }, -]; - -export const getAccountsSupportsMultiCurrency = () => { - return ACCOUNT_TYPES.filter((account) => account.multiCurrency); -}; diff --git a/packages/server/src/data/BalanceSheetStructure.ts b/packages/server/src/data/BalanceSheetStructure.ts deleted file mode 100644 index dc9b215d5..000000000 --- a/packages/server/src/data/BalanceSheetStructure.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { IBalanceSheetStructureSection } from '@/interfaces'; -import { - ACCOUNT_TYPE -} from '@/data/AccountTypes'; - -const balanceSheetStructure: IBalanceSheetStructureSection[] = [ - { - name: 'Assets', - sectionType: 'assets', - type: 'section', - children: [ - { - name: 'Current Asset', - sectionType: 'assets', - type: 'section', - children: [ - { - name: 'Cash and cash equivalents', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.CASH, ACCOUNT_TYPE.BANK], - }, - { - name: 'Accounts Receivable', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE], - }, - { - name: 'Inventories', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.INVENTORY], - }, - { - name: 'Other current assets', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.OTHER_CURRENT_ASSET], - }, - ], - alwaysShow: true, - }, - { - name: 'Fixed Asset', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.FIXED_ASSET], - }, - { - name: 'Non-Current Assets', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.NON_CURRENT_ASSET], - } - ], - alwaysShow: true, - }, - { - name: 'Liabilities and Equity', - sectionType: 'liabilities_equity', - type: 'section', - children: [ - { - name: 'Liabilities', - sectionType: 'liability', - type: 'section', - children: [ - { - name: 'Current Liabilties', - type: 'accounts_section', - accountsTypes: [ - ACCOUNT_TYPE.ACCOUNTS_PAYABLE, - ACCOUNT_TYPE.TAX_PAYABLE, - ACCOUNT_TYPE.CREDIT_CARD, - ACCOUNT_TYPE.OTHER_CURRENT_LIABILITY, - ], - }, - { - name: 'Long-Term Liabilities', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.LOGN_TERM_LIABILITY], - }, - { - name: 'Non-Current Liabilities', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.NON_CURRENT_LIABILITY], - } - ], - }, - { - name: 'Equity', - sectionType: 'equity', - type: 'accounts_section', - accountsTypes: [ACCOUNT_TYPE.EQUITY], - }, - ], - alwaysShow: true, - }, -]; - -export default balanceSheetStructure; \ No newline at end of file diff --git a/packages/server/src/data/DataTypes.ts b/packages/server/src/data/DataTypes.ts deleted file mode 100644 index d5ab1086f..000000000 --- a/packages/server/src/data/DataTypes.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export const DATATYPES_LENGTH = { - STRING: 255, - TEXT: 65535, - INT_10: 4294967295, - DECIMAL_13_3: 9999999999.999, - DECIMAL_15_5: 999999999999.999, -}; diff --git a/packages/server/src/data/ResourceFieldsKeys.ts b/packages/server/src/data/ResourceFieldsKeys.ts deleted file mode 100644 index 8504d3fdf..000000000 --- a/packages/server/src/data/ResourceFieldsKeys.ts +++ /dev/null @@ -1,205 +0,0 @@ -/* eslint-disable quote-props */ - -export default { - // Expenses. - expense: { - payment_date: { - column: 'payment_date', - }, - payment_account: { - column: 'payment_account_id', - relation: 'accounts.id', - }, - amount: { - column: 'total_amount', - }, - currency_code: { - column: 'currency_code', - }, - reference_no: { - column: 'reference_no' - }, - description: { - column: 'description', - }, - published: { - column: 'published', - }, - user: { - column: 'user_id', - relation: 'users.id', - relationColumn: 'users.id', - }, - }, - - // Accounts - Account: { - name: { - column: 'name', - }, - type: { - column: 'account_type_id', - relation: 'account_types.id', - relationColumn: 'account_types.key', - }, - description: { - column: 'description', - }, - code: { - column: 'code', - }, - root_type: { - column: 'account_type_id', - relation: 'account_types.id', - relationColumn: 'account_types.root_type', - }, - created_at: { - column: 'created_at', - columnType: 'date', - }, - active: { - column: 'active', - }, - balance: { - column: 'amount', - columnType: 'number' - }, - currency: { - column: 'currency_code', - }, - normal: { - column: 'account_type_id', - relation: 'account_types.id', - relationColumn: 'account_types.normal' - }, - }, - - // Items - item: { - type: { - column: 'type', - }, - name: { - column: 'name', - }, - sellable: { - column: 'sellable', - }, - purchasable: { - column: 'purchasable', - }, - sell_price: { - column: 'sell_price' - }, - cost_price: { - column: 'cost_price', - }, - currency_code: { - column: 'currency_code', - }, - cost_account: { - column: 'cost_account_id', - relation: 'accounts.id', - }, - sell_account: { - column: 'sell_account_id', - relation: 'accounts.id', - }, - inventory_account: { - column: 'inventory_account_id', - relation: 'accounts.id', - }, - sell_description: { - column: 'sell_description', - }, - purchase_description: { - column: 'purchase_description', - }, - quantity_on_hand: { - column: 'quantity_on_hand', - }, - note: { - column: 'note', - }, - category: { - column: 'category_id', - relation: 'categories.id', - }, - user: { - column: 'user_id', - relation: 'users.id', - relationColumn: 'users.id', - }, - created_at: { - column: 'created_at', - } - }, - - // Item category. - item_category: { - name: { - column: 'name', - }, - description: { - column: 'description', - }, - parent_category_id: { - column: 'parent_category_id', - relation: 'items_categories.id', - relationColumn: 'items_categories.id', - }, - user: { - column: 'user_id', - relation: 'users.id', - relationColumn: 'users.id', - }, - cost_account: { - column: 'cost_account_id', - relation: 'accounts.id', - }, - sell_account: { - column: 'sell_account_id', - relation: 'accounts.id', - }, - inventory_account: { - column: 'inventory_account_id', - relation: 'accounts.id', - }, - cost_method: { - column: 'cost_method', - }, - }, - - // Manual Journals - manual_journal: { - date: { - column: 'date', - }, - journal_number: { - column: 'journal_number', - }, - reference: { - column: 'reference', - }, - status: { - column: 'status', - }, - amount: { - column: 'amount', - }, - description: { - column: 'description', - }, - user: { - column: 'user_id', - relation: 'users.id', - relationColumn: 'users.id', - }, - journal_type: { - column: 'journal_type', - }, - created_at: { - column: 'created_at', - }, - } -}; diff --git a/packages/server/src/data/TransactionTypes.ts b/packages/server/src/data/TransactionTypes.ts deleted file mode 100755 index bdf407d32..000000000 --- a/packages/server/src/data/TransactionTypes.ts +++ /dev/null @@ -1,35 +0,0 @@ -export const CashflowTransactionTypes = { - OtherIncome: 'Other income', - OtherExpense: 'Other expense', - OwnerDrawing: 'Owner drawing', - OwnerContribution: 'Owner contribution', - TransferToAccount: 'Transfer to account', - TransferFromAccount: 'Transfer from account', -}; - -export const TransactionTypes = { - SaleInvoice: 'Sale invoice', - SaleReceipt: 'Sale receipt', - PaymentReceive: 'Payment received', - Bill: 'Bill', - BillPayment: 'Payment made', - VendorOpeningBalance: 'Vendor opening balance', - CustomerOpeningBalance: 'Customer opening balance', - InventoryAdjustment: 'Inventory adjustment', - ManualJournal: 'Manual journal', - Journal: 'Manual journal', - Expense: 'Expense', - OwnerContribution: 'Owner contribution', - TransferToAccount: 'Transfer to account', - TransferFromAccount: 'Transfer from account', - OtherIncome: 'Other income', - OtherExpense: 'Other expense', - OwnerDrawing: 'Owner drawing', - InvoiceWriteOff: 'Invoice write-off', - CreditNote: 'transaction_type.credit_note', - VendorCredit: 'transaction_type.vendor_credit', - RefundCreditNote: 'transaction_type.refund_credit_note', - RefundVendorCredit: 'transaction_type.refund_vendor_credit', - LandedCost: 'transaction_type.landed_cost', - CashflowTransaction: CashflowTransactionTypes, -}; diff --git a/packages/server/src/data/options.ts b/packages/server/src/data/options.ts deleted file mode 100644 index 2c0377fda..000000000 --- a/packages/server/src/data/options.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { getTransactionsLockingSettingsSchema } from '@/api/controllers/TransactionsLocking/utils'; - -export default { - organization: { - name: { - type: 'string', - }, - base_currency: { - type: 'string', - }, - industry: { - type: 'string', - }, - location: { - type: 'string', - }, - fiscal_year: { - type: 'string', - }, - financial_date_start: { - type: 'string', - }, - language: { - type: 'string', - }, - time_zone: { - type: 'string', - }, - date_format: { - type: 'string', - }, - accounting_basis: { - type: 'string', - }, - }, - manual_journals: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - }, - bill_payments: { - withdrawal_account: { - type: 'number', - }, - }, - sales_estimates: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - customer_notes: { - type: 'string', - }, - terms_conditions: { - type: 'string', - }, - }, - sales_receipts: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - preferred_deposit_account: { - type: 'number', - }, - receipt_message: { - type: 'string', - }, - terms_conditions: { - type: 'string', - }, - }, - sales_invoices: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - customer_notes: { - type: 'string', - }, - terms_conditions: { - type: 'string', - }, - }, - payment_receives: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - preferred_deposit_account: { - type: 'number', - }, - preferred_advance_deposit: { - type: 'number', - }, - }, - items: { - preferred_sell_account: { - type: 'number', - }, - preferred_cost_account: { - type: 'number', - }, - preferred_inventory_account: { - type: 'number', - }, - }, - expenses: { - preferred_payment_account: { - type: 'number', - }, - }, - inventory: { - cost_compute_running: { - type: 'boolean', - }, - }, - accounts: { - account_code_required: { - type: 'boolean', - }, - account_code_unique: { - type: 'boolean', - }, - }, - cashflow: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - }, - credit_note: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - customer_notes: { - type: 'string', - }, - terms_conditions: { - type: 'string', - }, - }, - vendor_credit: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - }, - warehouse_transfers: { - next_number: { - type: 'string', - }, - number_prefix: { - type: 'string', - }, - auto_increment: { - type: 'boolean', - }, - }, - 'sms-notification': { - 'sms-notification-enable.sale-invoice-details': { - type: 'boolean', - }, - 'sms-notification-enable.sale-invoice-reminder': { - type: 'boolean', - }, - 'sms-notification-enable.sale-estimate-details': { - type: 'boolean', - }, - 'sms-notification-enable.sale-receipt-details': { - type: 'boolean', - }, - 'sms-notification-enable.payment-receive-details': { - type: 'boolean', - }, - 'sms-notification-enable.customer-balance': { - type: 'boolean', - }, - }, - 'transactions-locking': { - 'locking-type': { - type: 'string', - }, - ...getTransactionsLockingSettingsSchema([ - 'all', - 'sales', - 'purchases', - 'financial', - ]), - }, - features: { - 'multi-warehouses': { - type: 'boolean', - }, - 'multi-branches': { - type: 'boolean', - }, - }, -}; diff --git a/packages/server/src/database/factories/index.js b/packages/server/src/database/factories/index.js deleted file mode 100644 index 641db7470..000000000 --- a/packages/server/src/database/factories/index.js +++ /dev/null @@ -1,390 +0,0 @@ -import KnexFactory from '@/lib/KnexFactory'; -import faker from 'faker'; -import { hashPassword } from 'utils'; - - -export default (tenantDb) => { - const factory = new KnexFactory(tenantDb); - - factory.define('user', 'users', async () => { - // const hashedPassword = await hashPassword('admin'); - - return { - first_name: faker.name.firstName(), - last_name: faker.name.lastName(), - email: faker.internet.email(), - phone_number: faker.phone.phoneNumberFormat().replace('-', ''), - active: 1, - // password: hashedPassword, - }; - }); - - factory.define('password_reset', 'password_resets', async () => { - return { - user_id: null, - token: faker.lorem.slug, - }; - }); - - factory.define('account_type', 'account_types', async () => ({ - name: faker.lorem.words(2), - normal: 'debit', - })); - - factory.define('account_balance', 'account_balances', async () => { - const account = await factory.create('account'); - - return { - account_id: account.id, - amount: faker.random.number(), - currency_code: 'USD', - }; - }); - - factory.define('account', 'accounts', async () => { - const accountType = await factory.create('account_type'); - return { - name: faker.lorem.word(), - code: faker.random.number(), - account_type_id: accountType.id, - description: faker.lorem.paragraph(), - }; - }); - - factory.define('account_transaction', 'accounts_transactions', async () => { - const account = await factory.create('account'); - const user = await factory.create('user'); - - return { - account_id: account.id, - credit: faker.random.number(), - debit: 0, - user_id: user.id, - }; - }); - - factory.define('manual_journal', 'manual_journals', async () => { - const user = await factory.create('user'); - - return { - journal_number: faker.random.number(), - transaction_type: '', - amount: faker.random.number(), - date: faker.date.future, - status: 1, - user_id: user.id, - }; - }); - - factory.define('item_category', 'items_categories', () => ({ - name: faker.name.firstName(), - description: faker.lorem.text(), - parent_category_id: null, - })); - - factory.define('item_metadata', 'items_metadata', async () => { - const item = await factory.create('item'); - - return { - key: faker.lorem.slug(), - value: faker.lorem.word(), - item_id: item.id, - }; - }); - - factory.define('item', 'items', async () => { - const category = await factory.create('item_category'); - const costAccount = await factory.create('account'); - const sellAccount = await factory.create('account'); - const inventoryAccount = await factory.create('account'); - - return { - name: faker.lorem.word(), - note: faker.lorem.paragraph(), - cost_price: faker.random.number(), - sell_price: faker.random.number(), - cost_account_id: costAccount.id, - sell_account_id: sellAccount.id, - inventory_account_id: inventoryAccount.id, - category_id: category.id, - }; - }); - - factory.define('setting', 'settings', async () => { - const user = await factory.create('user'); - return { - key: faker.lorem.slug(), - user_id: user.id, - type: 'string', - value: faker.lorem.words(), - group: 'default', - }; - }); - - factory.define('role', 'roles', async () => ({ - name: faker.lorem.word(), - description: faker.lorem.words(), - predefined: false, - })); - - factory.define('user_has_role', 'user_has_roles', async () => { - const user = await factory.create('user'); - const role = await factory.create('role'); - - return { - user_id: user.id, - role_id: role.id, - }; - }); - - factory.define('permission', 'permissions', async () => { - const permissions = ['create', 'edit', 'delete', 'view', 'owner']; - const randomPermission = permissions[Math.floor(Math.random() * permissions.length)]; - - return { - name: randomPermission, - }; - }); - - factory.define('role_has_permission', 'role_has_permissions', async () => { - const permission = await factory.create('permission'); - const role = await factory.create('role'); - const resource = await factory.create('resource'); - - return { - role_id: role.id, - permission_id: permission.id, - resource_id: resource.id, - }; - }); - - factory.define('resource', 'resources', () => ({ - name: faker.lorem.word(), - })); - - factory.define('view', 'views', async () => { - const resource = await factory.create('resource'); - return { - name: faker.lorem.word(), - resource_id: resource.id, - predefined: false, - }; - }); - - factory.define('resource_field', 'resource_fields', async () => { - const resource = await factory.create('resource'); - const dataTypes = ['select', 'date', 'text']; - - return { - label_name: faker.lorem.words(), - key: faker.lorem.slug(), - data_type: dataTypes[Math.floor(Math.random() * dataTypes.length)], - help_text: faker.lorem.words(), - default: faker.lorem.word(), - resource_id: resource.id, - active: true, - columnable: true, - predefined: false, - }; - }); - - factory.define('resource_custom_field_metadata', 'resource_custom_fields_metadata', async () => { - const resource = await factory.create('resource'); - - return { - resource_id: resource.id, - resource_item_id: 1, - key: faker.lorem.words(), - value: faker.lorem.words(), - }; - }); - - factory.define('view_role', 'view_roles', async () => { - const view = await factory.create('view'); - const field = await factory.create('resource_field'); - - return { - view_id: view.id, - index: faker.random.number(), - field_id: field.id, - value: '', - comparator: '', - }; - }); - - factory.define('view_column', 'view_has_columns', async () => { - const view = await factory.create('view'); - const field = await factory.create('resource_field'); - - return { - field_id: field.id, - view_id: view.id, - // index: 1, - }; - }); - - factory.define('expense', 'expenses_transactions', async () => { - const paymentAccount = await factory.create('account'); - const expenseAccount = await factory.create('account'); - const user = await factory.create('user'); - - return { - total_amount: faker.random.number(), - currency_code: 'USD', - description: '', - reference_no: faker.random.number(), - payment_account_id: paymentAccount.id, - published: true, - user_id: user.id, - }; - }); - - factory.define('expense_category', 'expense_transaction_categories', async () => { - const expense = await factory.create('expense'); - - return { - expense_account_id: expense.id, - description: '', - amount: faker.random.number(), - expense_id: expense.id, - }; - }); - - factory.define('option', 'options', async () => { - return { - key: faker.lorem.slug(), - value: faker.lorem.slug(), - group: faker.lorem.slug(), - }; - }); - - factory.define('currency', 'currencies', async () => { - return { - currency_name: faker.lorem.slug(), - currency_code: 'USD', - }; - }); - - factory.define('exchange_rate', 'exchange_rates', async () => { - return { - date: '2020-02-02', - currency_code: 'USD', - exchange_rate: faker.random.number(), - }; - }); - - factory.define('budget', 'budgets', async () => { - return { - name: faker.lorem.slug(), - fiscal_year: '2020', - period: 'month', - account_types: 'profit_loss', - }; - }); - - factory.define('budget_entry', 'budget_entries', async () => { - const budget = await factory.create('budget'); - const account = await factory.create('account'); - - return { - account_id: account.id, - budget_id: budget.id, - amount: 1000, - order: 1, - }; - }); - - factory.define('customer', 'customers', async () => { - return { - customer_type: 'business', - }; - }); - - factory.define('vendor', 'vendors', async () => { - return { - customer_type: 'business', - }; - }); - - factory.define('sale_estimate', 'sales_estimates', async () => { - const customer = await factory.create('customer'); - - return { - customer_id: customer.id, - estimate_date: faker.date.past, - expiration_date: faker.date.future, - reference: '', - estimate_number: faker.random.number, - note: '', - terms_conditions: '', - }; - }); - - factory.define('sale_estimate_entry', 'sales_estimate_entries', async () => { - const estimate = await factory.create('sale_estimate'); - const item = await factory.create('item'); - - return { - estimate_id: estimate.id, - item_id: item.id, - description: '', - discount: faker.random.number, - quantity: faker.random.number, - rate: faker.random.number, - }; - }); - - factory.define('sale_receipt', 'sales_receipts', async () => { - const depositAccount = await factory.create('account'); - const customer = await factory.create('customer'); - - return { - deposit_account_id: depositAccount.id, - customer_id: customer.id, - reference_no: faker.random.number, - receipt_date: faker.date.past, - }; - }); - - factory.define('sale_receipt_entry', 'sales_receipt_entries', async () => { - const saleReceipt = await factory.create('sale_receipt'); - const item = await factory.create('item'); - - return { - sale_receipt_id: saleReceipt.id, - item_id: item.id, - rate: faker.random.number, - quantity: faker.random.number, - }; - }); - - factory.define('sale_invoice', 'sales_invoices', async () => { - - return { - - }; - }); - - factory.define('sale_invoice_entry', 'sales_invoices_entries', async () => { - return { - - }; - }); - - factory.define('payment_receive', 'payment_receives', async () => { - - }); - - factory.define('payment_receive_entry', 'payment_receives_entries', async () => { - - }); - - - factory.define('bill', 'bills', async () => { - return { - - } - }); - - return factory; -} diff --git a/packages/server/src/database/factories/system.js b/packages/server/src/database/factories/system.js deleted file mode 100644 index ccde0f943..000000000 --- a/packages/server/src/database/factories/system.js +++ /dev/null @@ -1,16 +0,0 @@ -import KnexFactory from '@/lib/KnexFactory'; -import systemDb from '@/database/knex'; -import faker from 'faker'; - -export default () => { - const factory = new KnexFactory(systemDb); - - factory.define('password_reset', 'password_resets', async () => { - return { - email: faker.lorem.email, - token: faker.lorem.slug, - }; - }); - - return factory; -}; \ No newline at end of file diff --git a/packages/server/src/database/migrations/20190822214303_create_accounts_table.js b/packages/server/src/database/migrations/20190822214303_create_accounts_table.js deleted file mode 100644 index 81abcaf26..000000000 --- a/packages/server/src/database/migrations/20190822214303_create_accounts_table.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('accounts', (table) => { - table.increments('id').comment('Auto-generated id'); - table.string('name').index(); - table.string('slug'); - table.string('account_type').index(); - table.integer('parent_account_id').unsigned().references('id').inTable('accounts'); - table.string('code', 10).index(); - table.text('description'); - table.boolean('active').defaultTo(true).index(); - table.integer('index').unsigned(); - table.boolean('predefined').defaultTo(false).index(); - table.decimal('amount', 15, 5); - table.string('currency_code', 3).index(); - table.timestamps(); - }).raw('ALTER TABLE `ACCOUNTS` AUTO_INCREMENT = 1000'); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('accounts'); diff --git a/packages/server-nest/src/database/migrations/20190822214303_create_accounts_table.ts b/packages/server/src/database/migrations/20190822214303_create_accounts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214303_create_accounts_table.ts rename to packages/server/src/database/migrations/20190822214303_create_accounts_table.ts diff --git a/packages/server/src/database/migrations/20190822214304_create_items_categories_table.js b/packages/server/src/database/migrations/20190822214304_create_items_categories_table.js deleted file mode 100644 index 2fe1ec9ef..000000000 --- a/packages/server/src/database/migrations/20190822214304_create_items_categories_table.js +++ /dev/null @@ -1,19 +0,0 @@ - -exports.up = function (knex) { - return knex.schema.createTable('items_categories', (table) => { - table.increments(); - table.string('name').index(); - - table.text('description'); - table.integer('user_id').unsigned().index(); - - table.integer('cost_account_id').unsigned().references('id').inTable('accounts'); - table.integer('sell_account_id').unsigned().references('id').inTable('accounts'); - table.integer('inventory_account_id').unsigned().references('id').inTable('accounts'); - - table.string('cost_method'); - table.timestamps(); - }); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('items_categories'); diff --git a/packages/server-nest/src/database/migrations/20190822214304_create_items_categories_table.ts b/packages/server/src/database/migrations/20190822214304_create_items_categories_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214304_create_items_categories_table.ts rename to packages/server/src/database/migrations/20190822214304_create_items_categories_table.ts diff --git a/packages/server/src/database/migrations/20190822214306_create_items_table.js b/packages/server/src/database/migrations/20190822214306_create_items_table.js deleted file mode 100644 index 16ac1ed66..000000000 --- a/packages/server/src/database/migrations/20190822214306_create_items_table.js +++ /dev/null @@ -1,30 +0,0 @@ - -exports.up = function (knex) { - return knex.schema.createTable('items', (table) => { - table.increments(); - table.string('name').index(); - table.string('type').index(); - table.string('code'); - table.boolean('sellable').index(); - table.boolean('purchasable').index(); - table.decimal('sell_price', 13, 3).unsigned(); - table.decimal('cost_price', 13, 3).unsigned(); - table.string('currency_code', 3); - table.string('picture_uri'); - table.integer('cost_account_id').nullable().unsigned().references('id').inTable('accounts'); - table.integer('sell_account_id').nullable().unsigned().references('id').inTable('accounts'); - table.integer('inventory_account_id').unsigned().references('id').inTable('accounts'); - table.text('sell_description').nullable(); - table.text('purchase_description').nullable(); - table.integer('quantity_on_hand'); - table.boolean('landed_cost').nullable(); - - table.text('note').nullable(); - table.boolean('active'); - table.integer('category_id').unsigned().index().references('id').inTable('items_categories'); - table.integer('user_id').unsigned().index(); - table.timestamps(); - }).raw('ALTER TABLE `ITEMS` AUTO_INCREMENT = 1000'); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('items'); diff --git a/packages/server-nest/src/database/migrations/20190822214306_create_items_table.ts b/packages/server/src/database/migrations/20190822214306_create_items_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214306_create_items_table.ts rename to packages/server/src/database/migrations/20190822214306_create_items_table.ts diff --git a/packages/server/src/database/migrations/20190822214903_create_views_table.js b/packages/server/src/database/migrations/20190822214903_create_views_table.js deleted file mode 100644 index eb3929c47..000000000 --- a/packages/server/src/database/migrations/20190822214903_create_views_table.js +++ /dev/null @@ -1,15 +0,0 @@ - -exports.up = function (knex) { - return knex.schema.createTable('views', (table) => { - table.increments(); - table.string('name').index(); - table.string('slug').index(); - table.boolean('predefined'); - table.string('resource_model').index(); - table.boolean('favourite'); - table.string('roles_logic_expression'); - table.timestamps(); - }).raw('ALTER TABLE `VIEWS` AUTO_INCREMENT = 1000'); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('views'); diff --git a/packages/server-nest/src/database/migrations/20190822214903_create_views_table.ts b/packages/server/src/database/migrations/20190822214903_create_views_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214903_create_views_table.ts rename to packages/server/src/database/migrations/20190822214903_create_views_table.ts diff --git a/packages/server/src/database/migrations/20190822214904_create_settings_table.js b/packages/server/src/database/migrations/20190822214904_create_settings_table.js deleted file mode 100644 index 65f3f4fdc..000000000 --- a/packages/server/src/database/migrations/20190822214904_create_settings_table.js +++ /dev/null @@ -1,13 +0,0 @@ - -exports.up = function (knex) { - return knex.schema.createTable('settings', (table) => { - table.increments(); - table.integer('user_id').unsigned().index(); - table.string('group').index(); - table.string('type'); - table.string('key').index(); - table.string('value'); - }).raw('ALTER TABLE `SETTINGS` AUTO_INCREMENT = 2000'); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('settings'); diff --git a/packages/server-nest/src/database/migrations/20190822214904_create_settings_table.ts b/packages/server/src/database/migrations/20190822214904_create_settings_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214904_create_settings_table.ts rename to packages/server/src/database/migrations/20190822214904_create_settings_table.ts diff --git a/packages/server/src/database/migrations/20190822214905_create_views_columns.js b/packages/server/src/database/migrations/20190822214905_create_views_columns.js deleted file mode 100644 index 4fc76e399..000000000 --- a/packages/server/src/database/migrations/20190822214905_create_views_columns.js +++ /dev/null @@ -1,11 +0,0 @@ - -exports.up = function (knex) { - return knex.schema.createTable('view_has_columns', (table) => { - table.increments(); - table.integer('view_id').unsigned().index().references('id').inTable('views'); - table.string('field_key'); - table.integer('index').unsigned(); - }).raw('ALTER TABLE `ITEMS_CATEGORIES` AUTO_INCREMENT = 1000'); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('view_has_columns'); diff --git a/packages/server-nest/src/database/migrations/20190822214905_create_views_columns.ts b/packages/server/src/database/migrations/20190822214905_create_views_columns.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214905_create_views_columns.ts rename to packages/server/src/database/migrations/20190822214905_create_views_columns.ts diff --git a/packages/server/src/database/migrations/20190822214905_create_views_roles_table.js b/packages/server/src/database/migrations/20190822214905_create_views_roles_table.js deleted file mode 100644 index 4167514c3..000000000 --- a/packages/server/src/database/migrations/20190822214905_create_views_roles_table.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .createTable('view_roles', (table) => { - table.increments(); - table.integer('index'); - table.string('field_key').index(); - table.string('comparator'); - table.string('value'); - table - .integer('view_id') - .unsigned() - .index() - .references('id') - .inTable('views'); - }) - .raw('ALTER TABLE `VIEW_ROLES` AUTO_INCREMENT = 1000'); -}; - -exports.down = (knex) => knex.schema.dropTableIfExists('view_roles'); diff --git a/packages/server-nest/src/database/migrations/20190822214905_create_views_roles_table.ts b/packages/server/src/database/migrations/20190822214905_create_views_roles_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20190822214905_create_views_roles_table.ts rename to packages/server/src/database/migrations/20190822214905_create_views_roles_table.ts diff --git a/packages/server/src/database/migrations/20200104232644_create_contacts_table.js b/packages/server/src/database/migrations/20200104232644_create_contacts_table.js deleted file mode 100644 index 09e0accde..000000000 --- a/packages/server/src/database/migrations/20200104232644_create_contacts_table.js +++ /dev/null @@ -1,54 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('contacts', table => { - table.increments(); - - table.string('contact_service'); - table.string('contact_type'); - - table.decimal('balance', 13, 3).defaultTo(0); - table.string('currency_code', 3); - - table.decimal('opening_balance', 13, 3).defaultTo(0); - table.date('opening_balance_at'); - - table.string('salutation').nullable(); - table.string('first_name').nullable(); - table.string('last_name').nullable(); - table.string('company_name').nullable(); - - table.string('display_name'); - - table.string('email').nullable(); - table.string('work_phone').nullable(); - table.string('personal_phone').nullable(); - table.string('website').nullable(); - - table.string('billing_address_1').nullable(); - table.string('billing_address_2').nullable(); - table.string('billing_address_city').nullable(); - table.string('billing_address_country').nullable(); - table.string('billing_address_email').nullable(); - table.string('billing_address_postcode').nullable(); - table.string('billing_address_phone').nullable(); - table.string('billing_address_state').nullable(), - - table.string('shipping_address_1').nullable(); - table.string('shipping_address_2').nullable(); - table.string('shipping_address_city').nullable(); - table.string('shipping_address_country').nullable(); - table.string('shipping_address_email').nullable(); - table.string('shipping_address_postcode').nullable(); - table.string('shipping_address_phone').nullable(); - table.string('shipping_address_state').nullable(); - - table.text('note'); - table.boolean('active').defaultTo(true); - - table.timestamps(); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('contacts'); -}; diff --git a/packages/server-nest/src/database/migrations/20200104232644_create_contacts_table.ts b/packages/server/src/database/migrations/20200104232644_create_contacts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200104232644_create_contacts_table.ts rename to packages/server/src/database/migrations/20200104232644_create_contacts_table.ts diff --git a/packages/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js b/packages/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js deleted file mode 100644 index 50fe6d396..000000000 --- a/packages/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js +++ /dev/null @@ -1,36 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .createTable('accounts_transactions', (table) => { - table.increments(); - table.decimal('credit', 13, 3); - table.decimal('debit', 13, 3); - table.string('transaction_type').index(); - table.string('reference_type').index(); - table.integer('reference_id').index(); - table - .integer('account_id') - .unsigned() - .index() - .references('id') - .inTable('accounts'); - table.string('contact_type').nullable().index(); - table.integer('contact_id').unsigned().nullable().index(); - table.string('transaction_number').nullable().index(); - table.string('reference_number').nullable().index(); - table.integer('item_id').unsigned().nullable().index(); - table.integer('item_quantity').unsigned().nullable().index(), - table.string('note'); - table.integer('user_id').unsigned().index(); - - table.integer('index_group').unsigned().index(); - table.integer('index').unsigned().index(); - - table.date('date').index(); - table.datetime('created_at').index(); - }) - .raw('ALTER TABLE `ACCOUNTS_TRANSACTIONS` AUTO_INCREMENT = 1000'); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('accounts_transactions'); -}; diff --git a/packages/server-nest/src/database/migrations/20200104232647_create_accounts_transactions_table.ts b/packages/server/src/database/migrations/20200104232647_create_accounts_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200104232647_create_accounts_transactions_table.ts rename to packages/server/src/database/migrations/20200104232647_create_accounts_transactions_table.ts diff --git a/packages/server/src/database/migrations/20200105014405_create_expenses_table.js b/packages/server/src/database/migrations/20200105014405_create_expenses_table.js deleted file mode 100644 index 169856f33..000000000 --- a/packages/server/src/database/migrations/20200105014405_create_expenses_table.js +++ /dev/null @@ -1,29 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .createTable('expenses_transactions', (table) => { - table.increments(); - table.string('currency_code', 3); - table.text('description'); - table - .integer('payment_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.integer('payee_id').unsigned().references('id').inTable('contacts'); - table.string('reference_no'); - - table.decimal('total_amount', 13, 3); - table.decimal('landed_cost_amount', 13, 3).defaultTo(0); - table.decimal('allocated_cost_amount', 13, 3).defaultTo(0); - - table.date('published_at').index(); - table.integer('user_id').unsigned().index(); - table.date('payment_date').index(); - table.timestamps(); - }) - .raw('ALTER TABLE `EXPENSES_TRANSACTIONS` AUTO_INCREMENT = 1000'); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('expenses'); -}; diff --git a/packages/server-nest/src/database/migrations/20200105014405_create_expenses_table.ts b/packages/server/src/database/migrations/20200105014405_create_expenses_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200105014405_create_expenses_table.ts rename to packages/server/src/database/migrations/20200105014405_create_expenses_table.ts diff --git a/packages/server/src/database/migrations/20200105195823_create_manual_journals_table.js b/packages/server/src/database/migrations/20200105195823_create_manual_journals_table.js deleted file mode 100644 index 8c2714648..000000000 --- a/packages/server/src/database/migrations/20200105195823_create_manual_journals_table.js +++ /dev/null @@ -1,21 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('manual_journals', (table) => { - table.increments(); - table.string('journal_number').index(); - table.string('reference').index(); - table.string('journal_type').index(); - table.decimal('amount', 13, 3); - table.string('currency_code', 3); - table.date('date').index(); - table.string('description'); - table.date('published_at').index(); - table.string('attachment_file'); - table.integer('user_id').unsigned().index(); - table.timestamps(); - }).raw('ALTER TABLE `MANUAL_JOURNALS` AUTO_INCREMENT = 1000'); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('manual_journals'); -}; diff --git a/packages/server-nest/src/database/migrations/20200105195823_create_manual_journals_table.ts b/packages/server/src/database/migrations/20200105195823_create_manual_journals_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200105195823_create_manual_journals_table.ts rename to packages/server/src/database/migrations/20200105195823_create_manual_journals_table.ts diff --git a/packages/server/src/database/migrations/20200105195825_create_manual_journals_entries_table.js b/packages/server/src/database/migrations/20200105195825_create_manual_journals_entries_table.js deleted file mode 100644 index ecf22cf4c..000000000 --- a/packages/server/src/database/migrations/20200105195825_create_manual_journals_entries_table.js +++ /dev/null @@ -1,17 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('manual_journals_entries', (table) => { - table.increments(); - table.decimal('credit', 13, 3); - table.decimal('debit', 13, 3); - table.integer('index').unsigned(); - table.integer('account_id').unsigned().index().references('id').inTable('accounts'); - table.integer('contact_id').unsigned().nullable().index(); - table.string('note'); - table.integer('manual_journal_id').unsigned().index().references('id').inTable('manual_journals'); - }).raw('ALTER TABLE `MANUAL_JOURNALS_ENTRIES` AUTO_INCREMENT = 1000'); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('manual_journals_entries'); -}; diff --git a/packages/server-nest/src/database/migrations/20200105195825_create_manual_journals_entries_table.ts b/packages/server/src/database/migrations/20200105195825_create_manual_journals_entries_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200105195825_create_manual_journals_entries_table.ts rename to packages/server/src/database/migrations/20200105195825_create_manual_journals_entries_table.ts diff --git a/packages/server/src/database/migrations/20200419171451_create_currencies_table.js b/packages/server/src/database/migrations/20200419171451_create_currencies_table.js deleted file mode 100644 index 4d06717b9..000000000 --- a/packages/server/src/database/migrations/20200419171451_create_currencies_table.js +++ /dev/null @@ -1,14 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('currencies', table => { - table.increments(); - table.string('currency_name').index(); - table.string('currency_code', 4).index(); - table.string('currency_sign').index(); - table.timestamps(); - }).raw('ALTER TABLE `CURRENCIES` AUTO_INCREMENT = 1000'); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('currencies'); -}; diff --git a/packages/server-nest/src/database/migrations/20200419171451_create_currencies_table.ts b/packages/server/src/database/migrations/20200419171451_create_currencies_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200419171451_create_currencies_table.ts rename to packages/server/src/database/migrations/20200419171451_create_currencies_table.ts diff --git a/packages/server/src/database/migrations/20200419191832_create_exchange_rates_table.js b/packages/server/src/database/migrations/20200419191832_create_exchange_rates_table.js deleted file mode 100644 index 99db76530..000000000 --- a/packages/server/src/database/migrations/20200419191832_create_exchange_rates_table.js +++ /dev/null @@ -1,14 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('exchange_rates', table => { - table.increments(); - table.string('currency_code', 4).index(); - table.decimal('exchange_rate'); - table.date('date').index(); - table.timestamps(); - }).raw('ALTER TABLE `EXCHANGE_RATES` AUTO_INCREMENT = 1000'); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('exchange_rates'); -}; diff --git a/packages/server-nest/src/database/migrations/20200419191832_create_exchange_rates_table.ts b/packages/server/src/database/migrations/20200419191832_create_exchange_rates_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200419191832_create_exchange_rates_table.ts rename to packages/server/src/database/migrations/20200419191832_create_exchange_rates_table.ts diff --git a/packages/server/src/database/migrations/20200423201600_create_media_table.js b/packages/server/src/database/migrations/20200423201600_create_media_table.js deleted file mode 100644 index 64ffc3940..000000000 --- a/packages/server/src/database/migrations/20200423201600_create_media_table.js +++ /dev/null @@ -1,12 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('media', (table) => { - table.increments(); - table.string('attachment_file'); - table.timestamps(); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('media'); -}; diff --git a/packages/server-nest/src/database/migrations/20200423201600_create_media_table.ts b/packages/server/src/database/migrations/20200423201600_create_media_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200423201600_create_media_table.ts rename to packages/server/src/database/migrations/20200423201600_create_media_table.ts diff --git a/packages/server/src/database/migrations/20200503032011_create_media_links_table.js b/packages/server/src/database/migrations/20200503032011_create_media_links_table.js deleted file mode 100644 index 31d26be4b..000000000 --- a/packages/server/src/database/migrations/20200503032011_create_media_links_table.js +++ /dev/null @@ -1,13 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('media_links', table => { - table.increments(); - table.string('model_name').index(); - table.integer('media_id').unsigned().references('id').inTable('media'); - table.integer('model_id').unsigned().index(); - }) -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('media_links'); -}; diff --git a/packages/server-nest/src/database/migrations/20200503032011_create_media_links_table.ts b/packages/server/src/database/migrations/20200503032011_create_media_links_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200503032011_create_media_links_table.ts rename to packages/server/src/database/migrations/20200503032011_create_media_links_table.ts diff --git a/packages/server/src/database/migrations/20200606113848_create_expense_transactions_categories_table.js b/packages/server/src/database/migrations/20200606113848_create_expense_transactions_categories_table.js deleted file mode 100644 index a1bc88052..000000000 --- a/packages/server/src/database/migrations/20200606113848_create_expense_transactions_categories_table.js +++ /dev/null @@ -1,29 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .createTable('expense_transaction_categories', (table) => { - table.increments(); - table - .integer('expense_account_id') - .unsigned() - .index() - .references('id') - .inTable('accounts'); - table.integer('index').unsigned(); - table.text('description'); - table.decimal('amount', 13, 3); - table.decimal('allocated_cost_amount', 13, 3).defaultTo(0); - table.boolean('landed_cost').defaultTo(false); - table - .integer('expense_id') - .unsigned() - .index() - .references('id') - .inTable('expenses_transactions'); - table.timestamps(); - }) - .raw('ALTER TABLE `EXPENSE_TRANSACTION_CATEGORIES` AUTO_INCREMENT = 1000'); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('expense_transaction_categories'); -}; diff --git a/packages/server-nest/src/database/migrations/20200606113848_create_expense_transactions_categories_table.ts b/packages/server/src/database/migrations/20200606113848_create_expense_transactions_categories_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200606113848_create_expense_transactions_categories_table.ts rename to packages/server/src/database/migrations/20200606113848_create_expense_transactions_categories_table.ts diff --git a/packages/server/src/database/migrations/20200713192127_create_sales_estimates_table.js b/packages/server/src/database/migrations/20200713192127_create_sales_estimates_table.js deleted file mode 100644 index 06f8f1c91..000000000 --- a/packages/server/src/database/migrations/20200713192127_create_sales_estimates_table.js +++ /dev/null @@ -1,35 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('sales_estimates', (table) => { - table.increments(); - table.decimal('amount', 13, 3); - table.string('currency_code', 3); - table - .integer('customer_id') - .unsigned() - .index() - .references('id') - .inTable('contacts'); - table.date('estimate_date').index(); - table.date('expiration_date').index(); - table.string('reference'); - table.string('estimate_number').index(); - table.text('note'); - table.text('terms_conditions'); - table.text('send_to_email'); - - table.date('delivered_at').index(); - table.date('approved_at').index(); - table.date('rejected_at').index(); - - table.integer('user_id').unsigned().index(); - - table.integer('converted_to_invoice_id').unsigned(); - table.date('converted_to_invoice_at'); - - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('sales_estimates'); -}; diff --git a/packages/server-nest/src/database/migrations/20200713192127_create_sales_estimates_table.ts b/packages/server/src/database/migrations/20200713192127_create_sales_estimates_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200713192127_create_sales_estimates_table.ts rename to packages/server/src/database/migrations/20200713192127_create_sales_estimates_table.ts diff --git a/packages/server/src/database/migrations/20200713213303_create_sales_receipt_table.js b/packages/server/src/database/migrations/20200713213303_create_sales_receipt_table.js deleted file mode 100644 index c1f093312..000000000 --- a/packages/server/src/database/migrations/20200713213303_create_sales_receipt_table.js +++ /dev/null @@ -1,22 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('sales_receipts', table => { - table.increments(); - table.decimal('amount', 13, 3); - table.string('currency_code', 3); - table.integer('deposit_account_id').unsigned().index().references('id').inTable('accounts'); - table.integer('customer_id').unsigned().index().references('id').inTable('contacts'); - table.date('receipt_date').index(); - table.string('receipt_number').index(); - table.string('reference_no').index(); - table.string('send_to_email'); - table.text('receipt_message'); - table.text('statement'); - table.date('closed_at').index(); - table.timestamps(); - }) -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('sales_receipts'); -}; diff --git a/packages/server-nest/src/database/migrations/20200713213303_create_sales_receipt_table.ts b/packages/server/src/database/migrations/20200713213303_create_sales_receipt_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200713213303_create_sales_receipt_table.ts rename to packages/server/src/database/migrations/20200713213303_create_sales_receipt_table.ts diff --git a/packages/server/src/database/migrations/20200715193633_create_sale_invoices_table.js b/packages/server/src/database/migrations/20200715193633_create_sale_invoices_table.js deleted file mode 100644 index 87c26f58c..000000000 --- a/packages/server/src/database/migrations/20200715193633_create_sale_invoices_table.js +++ /dev/null @@ -1,34 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('sales_invoices', (table) => { - table.increments(); - table - .integer('customer_id') - .unsigned() - .index() - .references('id') - .inTable('contacts'); - - table.date('invoice_date').index(); - table.date('due_date'); - table.string('invoice_no').index(); - table.string('reference_no'); - - table.text('invoice_message'); - table.text('terms_conditions'); - - table.decimal('balance', 13, 3); - table.decimal('payment_amount', 13, 3); - table.string('currency_code', 3); - table.decimal('credited_amount', 13, 3).defaultTo(0); - - table.string('inv_lot_number').index(); - - table.date('delivered_at').index(); - table.integer('user_id').unsigned(); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('sales_invoices'); -}; diff --git a/packages/server-nest/src/database/migrations/20200715193633_create_sale_invoices_table.ts b/packages/server/src/database/migrations/20200715193633_create_sale_invoices_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200715193633_create_sale_invoices_table.ts rename to packages/server/src/database/migrations/20200715193633_create_sale_invoices_table.ts diff --git a/packages/server/src/database/migrations/20200715194514_create_payment_receives_table.js b/packages/server/src/database/migrations/20200715194514_create_payment_receives_table.js deleted file mode 100644 index c9a73ba13..000000000 --- a/packages/server/src/database/migrations/20200715194514_create_payment_receives_table.js +++ /dev/null @@ -1,30 +0,0 @@ -const { knexSnakeCaseMappers } = require('objection'); - -exports.up = function (knex) { - return knex.schema.createTable('payment_receives', (table) => { - table.increments(); - table - .integer('customer_id') - .unsigned() - .index() - .references('id') - .inTable('contacts'); - table.date('payment_date').index(); - table.decimal('amount', 13, 3).defaultTo(0); - table.string('currency_code', 3); - table.string('reference_no').index(); - table - .integer('deposit_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.string('payment_receive_no').nullable(); - table.text('statement'); - table.integer('user_id').unsigned().index(); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('payment_receives'); -}; diff --git a/packages/server-nest/src/database/migrations/20200715194514_create_payment_receives_table.ts b/packages/server/src/database/migrations/20200715194514_create_payment_receives_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200715194514_create_payment_receives_table.ts rename to packages/server/src/database/migrations/20200715194514_create_payment_receives_table.ts diff --git a/packages/server/src/database/migrations/20200718161031_create_payment_receives_entries_table.js b/packages/server/src/database/migrations/20200718161031_create_payment_receives_entries_table.js deleted file mode 100644 index d4c68a270..000000000 --- a/packages/server/src/database/migrations/20200718161031_create_payment_receives_entries_table.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('payment_receives_entries', (table) => { - table.increments(); - table - .integer('payment_receive_id') - .unsigned() - .index() - .references('id') - .inTable('payment_receives'); - table - .integer('invoice_id') - .unsigned() - .index() - .references('id') - .inTable('sales_invoices'); - table.decimal('payment_amount', 13, 3).unsigned(); - table.integer('index').unsigned(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('payment_receives_entries'); -}; diff --git a/packages/server-nest/src/database/migrations/20200718161031_create_payment_receives_entries_table.ts b/packages/server/src/database/migrations/20200718161031_create_payment_receives_entries_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200718161031_create_payment_receives_entries_table.ts rename to packages/server/src/database/migrations/20200718161031_create_payment_receives_entries_table.ts diff --git a/packages/server/src/database/migrations/20200719152005_create_bills_table.js b/packages/server/src/database/migrations/20200719152005_create_bills_table.js deleted file mode 100644 index cac0e04cd..000000000 --- a/packages/server/src/database/migrations/20200719152005_create_bills_table.js +++ /dev/null @@ -1,31 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('bills', (table) => { - table.increments(); - table - .integer('vendor_id') - .unsigned() - .index() - .references('id') - .inTable('contacts'); - table.string('bill_number'); - table.date('bill_date').index(); - table.date('due_date').index(); - table.string('reference_no').index(); - table.string('status').index(); - table.text('note'); - table.decimal('amount', 13, 3).defaultTo(0); - table.string('currency_code'); - table.decimal('payment_amount', 13, 3).defaultTo(0); - table.decimal('landed_cost_amount', 13, 3).defaultTo(0); - table.decimal('allocated_cost_amount', 13, 3).defaultTo(0); - table.decimal('credited_amount', 13, 3).defaultTo(0); - table.string('inv_lot_number').index(); - table.date('opened_at').index(); - table.integer('user_id').unsigned(); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('bills'); -}; diff --git a/packages/server-nest/src/database/migrations/20200719152005_create_bills_table.ts b/packages/server/src/database/migrations/20200719152005_create_bills_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200719152005_create_bills_table.ts rename to packages/server/src/database/migrations/20200719152005_create_bills_table.ts diff --git a/packages/server/src/database/migrations/20200719153909_create_bills_payments_table.js b/packages/server/src/database/migrations/20200719153909_create_bills_payments_table.js deleted file mode 100644 index 568302f3e..000000000 --- a/packages/server/src/database/migrations/20200719153909_create_bills_payments_table.js +++ /dev/null @@ -1,21 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('bills_payments', table => { - table.increments(); - table.integer('vendor_id').unsigned().index().references('id').inTable('contacts'); - table.decimal('amount', 13, 3).defaultTo(0); - table.string('currency_code'); - table.integer('payment_account_id').unsigned().references('id').inTable('accounts'); - table.string('payment_number').nullable().index(); - table.date('payment_date').index(); - table.string('payment_method'); - table.string('reference'); - table.integer('user_id').unsigned().index(); - table.text('statement'); - table.timestamps(); - }); -}; - -exports.down = function(knex) { - -}; diff --git a/packages/server-nest/src/database/migrations/20200719153909_create_bills_payments_table.ts b/packages/server/src/database/migrations/20200719153909_create_bills_payments_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200719153909_create_bills_payments_table.ts rename to packages/server/src/database/migrations/20200719153909_create_bills_payments_table.ts diff --git a/packages/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js b/packages/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js deleted file mode 100644 index bf8de6184..000000000 --- a/packages/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js +++ /dev/null @@ -1,24 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('inventory_transactions', (table) => { - table.increments('id'); - table.date('date').index(); - table.string('direction').index(); - table - .integer('item_id') - .unsigned() - .index() - .references('id') - .inTable('items'); - table.integer('quantity').unsigned(); - table.decimal('rate', 13, 3).unsigned(); - - table.string('transaction_type').index(); - table.integer('transaction_id').unsigned().index(); - - table.integer('entry_id').unsigned().index(); - table.integer('cost_account_id').unsigned(); - table.timestamps(); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20200722164251_create_inventory_transactions_table.ts b/packages/server/src/database/migrations/20200722164251_create_inventory_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200722164251_create_inventory_transactions_table.ts rename to packages/server/src/database/migrations/20200722164251_create_inventory_transactions_table.ts diff --git a/packages/server/src/database/migrations/20200722164252_create_landed_cost_table.js b/packages/server/src/database/migrations/20200722164252_create_landed_cost_table.js deleted file mode 100644 index f315e1bde..000000000 --- a/packages/server/src/database/migrations/20200722164252_create_landed_cost_table.js +++ /dev/null @@ -1,21 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('bill_located_costs', (table) => { - table.increments(); - - table.decimal('amount', 13, 3).unsigned(); - - table.integer('fromTransactionId').unsigned(); - table.string('fromTransactionType'); - table.integer('fromTransactionEntryId').unsigned(); - - table.string('allocationMethod'); - table.integer('costAccountId').unsigned(); - table.text('description'); - - table.integer('billId').unsigned(); - - table.timestamps(); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20200722164252_create_landed_cost_table.ts b/packages/server/src/database/migrations/20200722164252_create_landed_cost_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200722164252_create_landed_cost_table.ts rename to packages/server/src/database/migrations/20200722164252_create_landed_cost_table.ts diff --git a/packages/server/src/database/migrations/20200722164253_create_landed_cost_entries_table.js b/packages/server/src/database/migrations/20200722164253_create_landed_cost_entries_table.js deleted file mode 100644 index 96cdc5d77..000000000 --- a/packages/server/src/database/migrations/20200722164253_create_landed_cost_entries_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('bill_located_cost_entries', (table) => { - table.increments(); - - table.decimal('cost', 13, 3).unsigned(); - table.integer('entry_id').unsigned(); - table.integer('bill_located_cost_id').unsigned(); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20200722164253_create_landed_cost_entries_table.ts b/packages/server/src/database/migrations/20200722164253_create_landed_cost_entries_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200722164253_create_landed_cost_entries_table.ts rename to packages/server/src/database/migrations/20200722164253_create_landed_cost_entries_table.ts diff --git a/packages/server/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.js b/packages/server/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.js deleted file mode 100644 index 15f348a17..000000000 --- a/packages/server/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('inventory_transaction_meta', (table) => { - table.increments('id'); - table.string('transaction_number'); - table.text('description'); - table.integer('inventory_transaction_id').unsigned(); - }); - }; - - exports.down = function (knex) {}; - \ No newline at end of file diff --git a/packages/server-nest/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.ts b/packages/server/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.ts rename to packages/server/src/database/migrations/20200722164255_create_inventory_transaction_meta_table.ts diff --git a/packages/server/src/database/migrations/20200722173423_create_items_entries_table.js b/packages/server/src/database/migrations/20200722173423_create_items_entries_table.js deleted file mode 100644 index b480540de..000000000 --- a/packages/server/src/database/migrations/20200722173423_create_items_entries_table.js +++ /dev/null @@ -1,39 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('items_entries', (table) => { - table.increments(); - table.string('reference_type').index(); - table.string('reference_id').index(); - - table.integer('index').unsigned(); - table - .integer('item_id') - .unsigned() - .index() - .references('id') - .inTable('items'); - table.text('description'); - table.integer('discount').unsigned(); - table.integer('quantity').unsigned(); - table.integer('rate').unsigned(); - - table - .integer('sell_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table - .integer('cost_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - - table.boolean('landed_cost').defaultTo(false); - table.decimal('allocated_cost_amount', 13, 3).defaultTo(0); - - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('items_entries'); -}; diff --git a/packages/server-nest/src/database/migrations/20200722173423_create_items_entries_table.ts b/packages/server/src/database/migrations/20200722173423_create_items_entries_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200722173423_create_items_entries_table.ts rename to packages/server/src/database/migrations/20200722173423_create_items_entries_table.ts diff --git a/packages/server/src/database/migrations/20200728161617_create_bill_payments_entries.js b/packages/server/src/database/migrations/20200728161617_create_bill_payments_entries.js deleted file mode 100644 index d08ac23bb..000000000 --- a/packages/server/src/database/migrations/20200728161617_create_bill_payments_entries.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('bills_payments_entries', (table) => { - table.increments(); - table - .integer('bill_payment_id') - .unsigned() - .index() - .references('id') - .inTable('bills_payments'); - table - .integer('bill_id') - .unsigned() - .index() - .references('id') - .inTable('bills'); - table.decimal('payment_amount', 13, 3).unsigned(); - table.integer('index').unsigned(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('bills_payments_entries'); -}; diff --git a/packages/server-nest/src/database/migrations/20200728161617_create_bill_payments_entries.ts b/packages/server/src/database/migrations/20200728161617_create_bill_payments_entries.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200728161617_create_bill_payments_entries.ts rename to packages/server/src/database/migrations/20200728161617_create_bill_payments_entries.ts diff --git a/packages/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js b/packages/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js deleted file mode 100644 index d490cbcc7..000000000 --- a/packages/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js +++ /dev/null @@ -1,26 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('inventory_cost_lot_tracker', (table) => { - table.increments(); - table.date('date').index(); - table.string('direction').index(); - - table.integer('item_id').unsigned().index(); - table.integer('quantity').unsigned().index(); - table.decimal('rate', 13, 3); - table.integer('remaining'); - table.decimal('cost', 13, 3); - - table.string('transaction_type').index(); - table.integer('transaction_id').unsigned().index(); - - table.integer('entry_id').unsigned().index(); - table.integer('cost_account_id').unsigned(); - table.integer('inventory_transaction_id').unsigned().index(); - - table.datetime('created_at').index(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('inventory_cost_lot_tracker'); -}; diff --git a/packages/server-nest/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.ts b/packages/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.ts rename to packages/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.ts diff --git a/packages/server/src/database/migrations/20200810121809_create_inventory_adjustments_table.js b/packages/server/src/database/migrations/20200810121809_create_inventory_adjustments_table.js deleted file mode 100644 index 4774fcd23..000000000 --- a/packages/server/src/database/migrations/20200810121809_create_inventory_adjustments_table.js +++ /dev/null @@ -1,19 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('inventory_adjustments', table => { - table.increments(); - table.date('date').index(); - table.string('type').index(); - table.integer('adjustment_account_id').unsigned().references('id').inTable('accounts'); - table.string('reason'); - table.string('reference_no').index(); - table.string('description'); - table.integer('user_id').unsigned(); - table.date('published_at'); - table.timestamps(); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('inventory_adjustments'); -}; diff --git a/packages/server-nest/src/database/migrations/20200810121809_create_inventory_adjustments_table.ts b/packages/server/src/database/migrations/20200810121809_create_inventory_adjustments_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200810121809_create_inventory_adjustments_table.ts rename to packages/server/src/database/migrations/20200810121809_create_inventory_adjustments_table.ts diff --git a/packages/server/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.js b/packages/server/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.js deleted file mode 100644 index c40f877e2..000000000 --- a/packages/server/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.js +++ /dev/null @@ -1,25 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('inventory_adjustments_entries', (table) => { - table.increments(); - table - .integer('adjustment_id') - .unsigned() - .index() - .references('id') - .inTable('inventory_adjustments'); - table.integer('index').unsigned(); - table - .integer('item_id') - .unsigned() - .index() - .references('id') - .inTable('items'); - table.integer('quantity'); - table.decimal('cost', 13, 3).unsigned(); - table.decimal('value', 13, 3).unsigned(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('inventory_adjustments_entries'); -}; diff --git a/packages/server-nest/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.ts b/packages/server/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.ts rename to packages/server/src/database/migrations/20200810121810_create_inventory_adjustments_entries_table.ts diff --git a/packages/server/src/database/migrations/20200810121910_create_cashflow_transactions_table.js b/packages/server/src/database/migrations/20200810121910_create_cashflow_transactions_table.js deleted file mode 100644 index 22914346a..000000000 --- a/packages/server/src/database/migrations/20200810121910_create_cashflow_transactions_table.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('cashflow_transactions', (table) => { - table.increments(); - table.date('date').index(); - table.decimal('amount', 13, 3); - table.string('reference_no').index(); - table.string('transaction_type').index(); - table.string('transaction_number').index(); - table.string('description'); - table.date('published_at').index(); - table.integer('user_id').unsigned().index(); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('cashflow_transactions'); -}; diff --git a/packages/server-nest/src/database/migrations/20200810121910_create_cashflow_transactions_table.ts b/packages/server/src/database/migrations/20200810121910_create_cashflow_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20200810121910_create_cashflow_transactions_table.ts rename to packages/server/src/database/migrations/20200810121910_create_cashflow_transactions_table.ts diff --git a/packages/server/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.js b/packages/server/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.js deleted file mode 100644 index 79a47e690..000000000 --- a/packages/server/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('cashflow_transaction_lines', (table) => { - table.increments(); - table.integer('cashflow_transaction_id').unsigned(); - table - .integer('cashflow_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table - .integer('credit_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.decimal('amount', 13, 3); - table.integer('index').unsigned(); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('cashflow_transaction_lines'); -}; diff --git a/packages/server-nest/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.ts b/packages/server/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.ts rename to packages/server/src/database/migrations/20210810121910_create_cashflow_transaction_lines_table.ts diff --git a/packages/server/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.js b/packages/server/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.js deleted file mode 100644 index 8ce84a105..000000000 --- a/packages/server/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('sales_invoices', (table) => { - table.decimal('writtenoff_amount', 13, 3); - table.date('writtenoff_at').index(); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('sales_invoices', (table) => { - table.dropColumn('writtenoff_amount'); - table.dropColumn('writtenoff_at'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.ts b/packages/server/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.ts rename to packages/server/src/database/migrations/20210910121910_add_invoices_writtenoff_columns.ts diff --git a/packages/server/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.js b/packages/server/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.js deleted file mode 100644 index 7594fae97..000000000 --- a/packages/server/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('accounts_transactions', (table) => { - table.boolean('costable'); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('accounts_transactions', (table) => { - table.dropColumn('costable'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.ts b/packages/server/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.ts rename to packages/server/src/database/migrations/20211012121910_add_costable_column_to_account_transactions.ts diff --git a/packages/server/src/database/migrations/20211014121910_add_roles_table.js b/packages/server/src/database/migrations/20211014121910_add_roles_table.js deleted file mode 100644 index e9d8a0775..000000000 --- a/packages/server/src/database/migrations/20211014121910_add_roles_table.js +++ /dev/null @@ -1,21 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .createTable('roles', (table) => { - table.increments('id'); - table.string('name', 255).notNullable(); - table.string('slug'); - table.text('description'); - table.boolean('predefined'); - }) - .createTable('role_permissions', (table) => { - table.increments('id'); - table.integer('role_id').unsigned().references('id').inTable('roles'); - table.string('subject'); - table.string('ability'); - table.boolean('value'); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTable('roles').dropTable('role_permissions'); -}; diff --git a/packages/server-nest/src/database/migrations/20211014121910_add_roles_table.ts b/packages/server/src/database/migrations/20211014121910_add_roles_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211014121910_add_roles_table.ts rename to packages/server/src/database/migrations/20211014121910_add_roles_table.ts diff --git a/packages/server/src/database/migrations/20211112121920_create_users_table.js b/packages/server/src/database/migrations/20211112121920_create_users_table.js deleted file mode 100644 index a5df01941..000000000 --- a/packages/server/src/database/migrations/20211112121920_create_users_table.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('users', (table) => { - table.increments(); - table.string('first_name'); - table.string('last_name'); - table.string('email').index(); - table.string('phone_number').index(); - table.boolean('active').index(); - table.integer('role_id').unsigned().references('id').inTable('roles'); - table.integer('system_user_id').unsigned(); - table.dateTime('invited_at').index(); - table.dateTime('invite_accepted_at').index(); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('users'); -}; diff --git a/packages/server-nest/src/database/migrations/20211112121920_create_users_table.ts b/packages/server/src/database/migrations/20211112121920_create_users_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211112121920_create_users_table.ts rename to packages/server/src/database/migrations/20211112121920_create_users_table.ts diff --git a/packages/server/src/database/migrations/20211122121920_create_credit_notes_table.js b/packages/server/src/database/migrations/20211122121920_create_credit_notes_table.js deleted file mode 100644 index 07aa28a65..000000000 --- a/packages/server/src/database/migrations/20211122121920_create_credit_notes_table.js +++ /dev/null @@ -1,28 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('credit_notes', (table) => { - table.increments(); - table - .integer('customer_id') - .unsigned() - .references('id') - .inTable('contacts'); - table.date('credit_note_date'); - table.string('credit_note_number'); - table.string('reference_no'); - table.decimal('amount', 13, 3); - - table.decimal('refunded_amount', 13, 3).defaultTo(0); - table.decimal('invoices_amount', 13, 3).defaultTo(0); - - table.string('currency_code', 3); - table.text('note'); - table.text('terms_conditions'); - table.date('opened_at').index(); - table.integer('user_id').unsigned().references('id').inTable('users'); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('credit_notescredit_notes'); -}; diff --git a/packages/server-nest/src/database/migrations/20211122121920_create_credit_notes_table.ts b/packages/server/src/database/migrations/20211122121920_create_credit_notes_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211122121920_create_credit_notes_table.ts rename to packages/server/src/database/migrations/20211122121920_create_credit_notes_table.ts diff --git a/packages/server/src/database/migrations/20211122121920_create_vendor_credits_table.js b/packages/server/src/database/migrations/20211122121920_create_vendor_credits_table.js deleted file mode 100644 index 0e4e361f8..000000000 --- a/packages/server/src/database/migrations/20211122121920_create_vendor_credits_table.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('vendor_credits', (table) => { - table.increments(); - table.integer('vendor_id').unsigned().references('id').inTable('contacts'); - table.decimal('amount', 13, 3); - table.string('currency_code', 3); - table.date('vendor_credit_date'); - table.string('vendor_credit_number'); - table.string('reference_no'); - - table.decimal('refunded_amount', 13, 3).defaultTo(0); - table.decimal('invoiced_amount', 13, 3).defaultTo(0); - - table.text('note'); - table.date('opened_at').index(); - table.integer('user_id').unsigned().references('id').inTable('users'); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('vendor_credits'); -}; diff --git a/packages/server-nest/src/database/migrations/20211122121920_create_vendor_credits_table.ts b/packages/server/src/database/migrations/20211122121920_create_vendor_credits_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211122121920_create_vendor_credits_table.ts rename to packages/server/src/database/migrations/20211122121920_create_vendor_credits_table.ts diff --git a/packages/server/src/database/migrations/20211123121920_create_refund_transactions_table.js b/packages/server/src/database/migrations/20211123121920_create_refund_transactions_table.js deleted file mode 100644 index 233657be2..000000000 --- a/packages/server/src/database/migrations/20211123121920_create_refund_transactions_table.js +++ /dev/null @@ -1,45 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .createTable('refund_credit_note_transactions', (table) => { - table.increments(); - table.date('date'); - table - .integer('credit_note_id') - .unsigned() - .references('id') - .inTable('credit_notes'); - table.decimal('amount', 13, 3); - table.string('currency_code', 3); - table.string('reference_no'); - table - .integer('from_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.text('description'); - table.timestamps(); - }) - .createTable('refund_vendor_credit_transactions', (table) => { - table.increments(); - table.date('date'); - table - .integer('vendor_credit_id') - .unsigned() - .references('id') - .inTable('vendor_credits'); - table.decimal('amount', 13, 3); - table.string('currency_code', 3); - table.string('reference_no'); - table - .integer('deposit_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.text('description'); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('refund_transactions'); -}; diff --git a/packages/server-nest/src/database/migrations/20211123121920_create_refund_transactions_table.ts b/packages/server/src/database/migrations/20211123121920_create_refund_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211123121920_create_refund_transactions_table.ts rename to packages/server/src/database/migrations/20211123121920_create_refund_transactions_table.ts diff --git a/packages/server/src/database/migrations/20211124121920_create_credit_note_applies_invoices.js b/packages/server/src/database/migrations/20211124121920_create_credit_note_applies_invoices.js deleted file mode 100644 index 678a52bf2..000000000 --- a/packages/server/src/database/migrations/20211124121920_create_credit_note_applies_invoices.js +++ /dev/null @@ -1,35 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .createTable('credit_note_applied_invoice', (table) => { - table.increments(); - table.decimal('amount', 13, 3); - table - .integer('credit_note_id') - .unsigned() - .references('id') - .inTable('credit_notes'); - table - .integer('invoice_id') - .unsigned() - .references('id') - .inTable('sales_invoices'); - table.timestamps(); - }) - .createTable('vendor_credit_applied_bill', (table) => { - table.increments(); - table.decimal('amount', 13, 3); - table - .integer('vendor_credit_id') - .unsigned() - .references('id') - .inTable('vendor_credits'); - table.integer('bill_id').unsigned().references('id').inTable('bills'); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema - .dropTableIfExists('vendor_credit_applied_bill') - .dropTableIfExists('credit_note_applied_invoice'); -}; diff --git a/packages/server-nest/src/database/migrations/20211124121920_create_credit_note_applies_invoices.ts b/packages/server/src/database/migrations/20211124121920_create_credit_note_applies_invoices.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20211124121920_create_credit_note_applies_invoices.ts rename to packages/server/src/database/migrations/20211124121920_create_credit_note_applies_invoices.ts diff --git a/packages/server/src/database/migrations/20220124121920_create_branches_table.js b/packages/server/src/database/migrations/20220124121920_create_branches_table.js deleted file mode 100644 index de2b75261..000000000 --- a/packages/server/src/database/migrations/20220124121920_create_branches_table.js +++ /dev/null @@ -1,24 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('branches', (table) => { - table.increments(); - - table.string('name'); - table.string('code'); - - table.string('address'); - table.string('city'); - table.string('country'); - - table.string('phone_number'); - table.string('email'); - table.string('website'); - - table.boolean('primary'); - - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('branches'); -}; diff --git a/packages/server-nest/src/database/migrations/20220124121920_create_branches_table.ts b/packages/server/src/database/migrations/20220124121920_create_branches_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220124121920_create_branches_table.ts rename to packages/server/src/database/migrations/20220124121920_create_branches_table.ts diff --git a/packages/server/src/database/migrations/20220124121920_create_warehouses_table.js b/packages/server/src/database/migrations/20220124121920_create_warehouses_table.js deleted file mode 100644 index b6617857e..000000000 --- a/packages/server/src/database/migrations/20220124121920_create_warehouses_table.js +++ /dev/null @@ -1,59 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .createTable('warehouses', (table) => { - table.increments(); - table.string('name'); - table.string('code'); - - table.string('address'); - table.string('city'); - table.string('country'); - - table.string('phone_number'); - table.string('email'); - table.string('website'); - - table.boolean('primary'); - - table.timestamps(); - }) - .createTable('warehouses_transfers', (table) => { - table.increments(); - table.date('date'); - table - .integer('to_warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - table - .integer('from_warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - table.string('transaction_number'); - - table.date('transfer_initiated_at'); - table.date('transfer_delivered_at'); - - table.timestamps(); - }) - .createTable('warehouses_transfers_entries', (table) => { - table.increments(); - table.integer('index'); - table - .integer('warehouse_transfer_id') - .unsigned() - .references('id') - .inTable('warehouses_transfers'); - table.integer('item_id').unsigned().references('id').inTable('items'); - table.string('description'); - table.integer('quantity'); - table.decimal('cost'); - }); -}; - -exports.down = (knex) => { - return knex.schema - .dropTableIfExists('vendor_credit_applied_bill') - .dropTableIfExists('credit_note_applied_invoice'); -}; diff --git a/packages/server-nest/src/database/migrations/20220124121920_create_warehouses_table.ts b/packages/server/src/database/migrations/20220124121920_create_warehouses_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220124121920_create_warehouses_table.ts rename to packages/server/src/database/migrations/20220124121920_create_warehouses_table.ts diff --git a/packages/server/src/database/migrations/20220125021920_create_items_warehouses_quantity.js b/packages/server/src/database/migrations/20220125021920_create_items_warehouses_quantity.js deleted file mode 100644 index 899db5e2b..000000000 --- a/packages/server/src/database/migrations/20220125021920_create_items_warehouses_quantity.js +++ /dev/null @@ -1,16 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('items_warehouses_quantity', (table) => { - table.integer('item_id').unsigned().references('id').inTable('items'); - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - - table.integer('quantity_on_hand'); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('items_warehouses_quantity'); -}; diff --git a/packages/server-nest/src/database/migrations/20220125021920_create_items_warehouses_quantity.ts b/packages/server/src/database/migrations/20220125021920_create_items_warehouses_quantity.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220125021920_create_items_warehouses_quantity.ts rename to packages/server/src/database/migrations/20220125021920_create_items_warehouses_quantity.ts diff --git a/packages/server/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.js b/packages/server/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.js deleted file mode 100644 index ba7ab26c1..000000000 --- a/packages/server/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.js +++ /dev/null @@ -1,86 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .table('accounts_transactions', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('manual_journals', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('manual_journals_entries', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('expenses_transactions', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches') - .after('user_id'); - }) - .table('cashflow_transactions', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches') - .after('user_id'); - }) - .table('contacts', (table) => { - table - .integer('opening_balance_branch_id') - .unsigned() - .references('id') - .inTable('branches') - .after('opening_balance_at'); - }) - .table('refund_credit_note_transactions', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches') - .after('description'); - }) - .table('refund_vendor_credit_transactions', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches') - .after('description'); - }); -}; - -exports.down = (knex) => { - return knex.schema - .table('accounts_transactions', (table) => { - table.dropColumn('branch_id'); - }) - .table('manual_journals', (table) => { - table.dropColumn('branch_id'); - }) - .table('manual_journals_entries', (table) => { - table.dropColumn('branch_id'); - }) - .table('cashflow_transactions', (table) => { - table.dropColumn('branch_id'); - }) - .table('refund_credit_note_transactions', (table) => { - table.dropColumn('branch_id'); - }) - .table('refund_vendor_credit_transactions', (table) => { - table.dropColumn('branch_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.ts b/packages/server/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.ts rename to packages/server/src/database/migrations/20220125121920_add_branch_column_to_accounts_transactions.ts diff --git a/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.js b/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.js deleted file mode 100644 index 7ce87115c..000000000 --- a/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.js +++ /dev/null @@ -1,65 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .table('bills', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('bills_payments', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('vendor_credits', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - }) - .table('inventory_adjustments', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - }); -}; - -exports.down = (knex) => { - return knex.schema - .table('bills', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }) - .table('bills_payments', (table) => { - table.dropColumn('branch_id'); - }) - .table('vendor_credits', (table) => { - table.dropColumn('branch_id'); - table.dropColumn('warehouse_id'); - }) - .table('inventory_adjustments', (table) => { - table.dropColumn('branch_id'); - table.dropColumn('warehouse_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.ts b/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.ts rename to packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_purchases.ts diff --git a/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.js b/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.js deleted file mode 100644 index b209040e4..000000000 --- a/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.js +++ /dev/null @@ -1,84 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .table('sales_invoices', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('sales_estimates', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('sales_receipts', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('payment_receives', (table) => { - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('credit_notes', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }); -}; - -exports.down = (knex) => { - return knex.schema - .table('sales_invoices', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }) - .table('sales_estimates', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }) - .table('sales_receipts', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }) - .table('payment_receives', (table) => { - table.dropColumn('branch_id'); - }) - .table('credit_notes', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.ts b/packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.ts rename to packages/server/src/database/migrations/20220125121920_add_branch_warehouse_columns_to_sales.ts diff --git a/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.js b/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.js deleted file mode 100644 index 622961f22..000000000 --- a/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.js +++ /dev/null @@ -1,40 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .table('inventory_transactions', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }) - .table('inventory_cost_lot_tracker', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - - table - .integer('branch_id') - .unsigned() - .references('id') - .inTable('branches'); - }); -}; - -exports.down = (knex) => { - return knex.schema - .table('inventory_transactions', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }) - .table('inventory_cost_lot_tracker', (table) => { - table.dropColumn('warehouse_id'); - table.dropColumn('branch_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.ts b/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.ts rename to packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_inventory_transactions.ts diff --git a/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.js b/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.js deleted file mode 100644 index bac471bfe..000000000 --- a/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('items_entries', (table) => { - table - .integer('warehouse_id') - .unsigned() - .references('id') - .inTable('warehouses'); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('items_entries', (table) => { - table.dropColumn('warehouse_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.ts b/packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.ts rename to packages/server/src/database/migrations/20220125121920_add_warehouse_column_to_items_entries.ts diff --git a/packages/server/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.js b/packages/server/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.js deleted file mode 100644 index 86c7836dc..000000000 --- a/packages/server/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.js +++ /dev/null @@ -1,114 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .table('sales_invoices', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('sales_estimates', (table) => { - table.decimal('exchange_rate', 13, 9); - }) - .table('sales_receipts', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('payment_receives', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('bills', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('bills_payments', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('credit_notes', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('vendor_credits', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('accounts_transactions', (table) => { - table.string('currency_code', 3).after('debit'); - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('manual_journals', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('cashflow_transactions', (table) => { - table.string('currency_code', 3).after('amount'); - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('expenses_transactions', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('refund_credit_note_transactions', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('refund_vendor_credit_transactions', (table) => { - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('bill_located_costs', (table) => { - table.string('currency_code', 3).after('amount'); - table.decimal('exchange_rate', 13, 9).after('currency_code'); - }) - .table('contacts', (table) => { - table - .decimal('opening_balance_exchange_rate', 13, 9) - .after('opening_balance_at'); - }) - .table('items', (table) => { - table.dropColumn('currency_code'); - }); -}; - -exports.down = (knex) => { - return knex.schema - .table('sales_invoices', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('sales_estimates', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('sales_receipts', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('payment_receives', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('bills', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('bills_payments', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('credit_notes', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('vendor_credits', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('accounts_transactions', (table) => { - table.dropColumn('currency_code'); - table.dropColumn('exchange_rate'); - }) - .table('manual_journals', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('cashflow_transactions', (table) => { - table.dropColumn('currency_code'); - table.dropColumn('exchange_rate'); - }) - .table('expenses_transactions', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('refund_credit_note_transactions', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('refund_vendor_credit_transactions', (table) => { - table.dropColumn('exchange_rate'); - }) - .table('bill_located_costs', (table) => { - table.dropColumn('currency_code'); - table.dropColumn('exchange_rate'); - }) - .table('contacts', (table) => { - table.dropColumn('opening_balance_exchange_rate'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.ts b/packages/server/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.ts rename to packages/server/src/database/migrations/20220128121920_add_exchange_rate_to_transactions.ts diff --git a/packages/server/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.js b/packages/server/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.js deleted file mode 100644 index 4f496cd11..000000000 --- a/packages/server/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('sales_invoices', (table) => { - table - .integer('writtenoff_expense_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('sales_invoices', (table) => { - table.dropColumn('writtenoff_expense_account_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.ts b/packages/server/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.ts rename to packages/server/src/database/migrations/20220129121920_add_writtenoff_expense_account_to_invoices.ts diff --git a/packages/server/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.js b/packages/server/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.js deleted file mode 100644 index 117086ef0..000000000 --- a/packages/server/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .raw( - 'ALTER TABLE CONTACTS CHANGE SHIPPING_ADDRESS_1 SHIPPING_ADDRESS1 VARCHAR(255)' - ) - .raw( - 'ALTER TABLE CONTACTS CHANGE SHIPPING_ADDRESS_2 SHIPPING_ADDRESS2 VARCHAR(255)' - ) - .raw( - 'ALTER TABLE CONTACTS CHANGE BILLING_ADDRESS_1 BILLING_ADDRESS1 VARCHAR(255)' - ) - .raw( - 'ALTER TABLE CONTACTS CHANGE BILLING_ADDRESS_2 BILLING_ADDRESS2 VARCHAR(255)' - ); -}; - -exports.down = (knex) => { - return knex.schema.table('contacts', (table) => {}); -}; diff --git a/packages/server-nest/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.ts b/packages/server/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.ts rename to packages/server/src/database/migrations/20220229121920_rename_contacts_shipping_billing_addresses.ts diff --git a/packages/server/src/database/migrations/20220329121920_add_cashflow_credit_account.js b/packages/server/src/database/migrations/20220329121920_add_cashflow_credit_account.js deleted file mode 100644 index 4bc18796f..000000000 --- a/packages/server/src/database/migrations/20220329121920_add_cashflow_credit_account.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('cashflow_transactions', (table) => { - table - .integer('cashflow_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table - .integer('credit_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('cashflow_transactions', () => {}); -}; diff --git a/packages/server-nest/src/database/migrations/20220329121920_add_cashflow_credit_account.ts b/packages/server/src/database/migrations/20220329121920_add_cashflow_credit_account.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20220329121920_add_cashflow_credit_account.ts rename to packages/server/src/database/migrations/20220329121920_add_cashflow_credit_account.ts diff --git a/packages/server/src/database/migrations/20230405232607_drop_phone_number_from_users.js b/packages/server/src/database/migrations/20230405232607_drop_phone_number_from_users.js deleted file mode 100644 index 9ab142779..000000000 --- a/packages/server/src/database/migrations/20230405232607_drop_phone_number_from_users.js +++ /dev/null @@ -1,9 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('users', (table) => { - table.dropColumn('phone_number'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('users', (table) => {}); -}; diff --git a/packages/server-nest/src/database/migrations/20230405232607_drop_phone_number_from_users.ts b/packages/server/src/database/migrations/20230405232607_drop_phone_number_from_users.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20230405232607_drop_phone_number_from_users.ts rename to packages/server/src/database/migrations/20230405232607_drop_phone_number_from_users.ts diff --git a/packages/server/src/database/migrations/20230810191606_create_tax_rates.js b/packages/server/src/database/migrations/20230810191606_create_tax_rates.js deleted file mode 100644 index 881a9db31..000000000 --- a/packages/server/src/database/migrations/20230810191606_create_tax_rates.js +++ /dev/null @@ -1,52 +0,0 @@ -exports.up = (knex) => { - return knex.schema - .createTable('tax_rates', (table) => { - table.increments(); - table.string('name'); - table.string('code'); - table.decimal('rate'); - table.string('description'); - table.boolean('is_non_recoverable').defaultTo(false); - table.boolean('is_compound').defaultTo(false); - table.boolean('active').defaultTo(false); - table.date('deleted_at'); - table.timestamps(); - }) - .table('items_entries', (table) => { - table.boolean('is_inclusive_tax').defaultTo(false); - table - .integer('tax_rate_id') - .unsigned() - .references('id') - .inTable('tax_rates'); - table.decimal('tax_rate').unsigned(); - }) - .table('sales_invoices', (table) => { - table.boolean('is_inclusive_tax').defaultTo(false); - table.decimal('tax_amount_withheld'); - }) - .createTable('tax_rate_transactions', (table) => { - table.increments('id'); - table - .integer('tax_rate_id') - .unsigned() - .references('id') - .inTable('tax_rates'); - table.string('reference_type'); - table.integer('reference_id'); - table.decimal('rate').unsigned(); - table.integer('tax_account_id').unsigned(); - }) - .table('accounts_transactions', (table) => { - table - .integer('tax_rate_id') - .unsigned() - .references('id') - .inTable('tax_rates'); - table.decimal('tax_rate').unsigned(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('tax_rates'); -}; diff --git a/packages/server-nest/src/database/migrations/20230810191606_create_tax_rates.ts b/packages/server/src/database/migrations/20230810191606_create_tax_rates.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20230810191606_create_tax_rates.ts rename to packages/server/src/database/migrations/20230810191606_create_tax_rates.ts diff --git a/packages/server/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.js b/packages/server/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.js deleted file mode 100644 index f61655877..000000000 --- a/packages/server/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.js +++ /dev/null @@ -1,10 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('bills', (table) => { - table.boolean('is_inclusive_tax').defaultTo(false); - table.decimal('tax_amount_withheld'); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('bills', () => {}); -}; diff --git a/packages/server-nest/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.ts b/packages/server/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.ts rename to packages/server/src/database/migrations/20231004012644_add_tax_amount_withheld_to_bills_table.ts diff --git a/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js b/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js deleted file mode 100644 index 51b842df2..000000000 --- a/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.up = (knex) => { - return knex.schema.table('items', (table) => { - table - .integer('sell_tax_rate_id') - .unsigned() - .references('id') - .inTable('tax_rates'); - table - .integer('purchase_tax_rate_id') - .unsigned() - .references('id') - .inTable('tax_rates'); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('tax_rates'); -}; diff --git a/packages/server-nest/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.ts b/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.ts rename to packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.ts diff --git a/packages/server/src/database/migrations/20231108170207_create_storage_table.js b/packages/server/src/database/migrations/20231108170207_create_storage_table.js deleted file mode 100644 index 0bf9e8ef9..000000000 --- a/packages/server/src/database/migrations/20231108170207_create_storage_table.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('storage', (table) => { - table.increments('id').primary(); - table.string('key').notNullable(); - table.string('path').notNullable(); - table.string('extension').notNullable(); - table.integer('expire_in'); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('storage'); -}; \ No newline at end of file diff --git a/packages/server-nest/src/database/migrations/20231108170207_create_storage_table.ts b/packages/server/src/database/migrations/20231108170207_create_storage_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20231108170207_create_storage_table.ts rename to packages/server/src/database/migrations/20231108170207_create_storage_table.ts diff --git a/packages/server/src/database/migrations/20231202124014_change_item_entries_rate_to_float.js b/packages/server/src/database/migrations/20231202124014_change_item_entries_rate_to_float.js deleted file mode 100644 index 802440045..000000000 --- a/packages/server/src/database/migrations/20231202124014_change_item_entries_rate_to_float.js +++ /dev/null @@ -1,9 +0,0 @@ -exports.up = function (knex) { - return knex.schema.alterTable('items_entries', (table) => { - table.decimal('rate', 15, 5).alter(); - }); -}; - -exports.down = function (knex) { - return knex.table('items_entries', (table) => {}); -}; diff --git a/packages/server-nest/src/database/migrations/20231202124014_change_item_entries_rate_to_float.ts b/packages/server/src/database/migrations/20231202124014_change_item_entries_rate_to_float.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20231202124014_change_item_entries_rate_to_float.ts rename to packages/server/src/database/migrations/20231202124014_change_item_entries_rate_to_float.ts diff --git a/packages/server/src/database/migrations/20240201160214_create_plaid_items_Table.js b/packages/server/src/database/migrations/20240201160214_create_plaid_items_Table.js deleted file mode 100644 index 089283290..000000000 --- a/packages/server/src/database/migrations/20240201160214_create_plaid_items_Table.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('plaid_items', (table) => { - table.increments('id'); - table.integer('tenant_id').unsigned(); - table.string('plaid_item_id'); - table.string('plaid_institution_id'); - table.string('plaid_access_token'); - table.string('last_cursor'); - table.string('status'); - table.timestamps(); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20240201160214_create_plaid_items_Table.ts b/packages/server/src/database/migrations/20240201160214_create_plaid_items_Table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240201160214_create_plaid_items_Table.ts rename to packages/server/src/database/migrations/20240201160214_create_plaid_items_Table.ts diff --git a/packages/server/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.js b/packages/server/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.js deleted file mode 100644 index 901f08987..000000000 --- a/packages/server/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.js +++ /dev/null @@ -1,9 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('accounts', (table) => { - table.string('plaid_account_id'); - table.string('account_mask').nullable(); - table.decimal('bank_balance', 15, 5); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.ts b/packages/server/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.ts rename to packages/server/src/database/migrations/20240201235818_add_plaid_account_id_to_accounts_table.ts diff --git a/packages/server/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.js b/packages/server/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.js deleted file mode 100644 index 3c88cd589..000000000 --- a/packages/server/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.js +++ /dev/null @@ -1,7 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('cashflow_transactions', (table) => { - table.string('plaid_transaction_id'); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.ts b/packages/server/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.ts rename to packages/server/src/database/migrations/20240204180554_add_plaid_transaction_id_to_cashflow_transaction.ts diff --git a/packages/server/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.js b/packages/server/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.js deleted file mode 100644 index 29a596772..000000000 --- a/packages/server/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.js +++ /dev/null @@ -1,28 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable( - 'uncategorized_cashflow_transactions', - (table) => { - table.increments('id'); - table.date('date').index(); - table.decimal('amount'); - table.string('currency_code'); - table.string('reference_no').index(); - table.string('payee'); - table - .integer('account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.string('description'); - table.string('categorize_ref_type'); - table.integer('categorize_ref_id').unsigned(); - table.boolean('categorized').defaultTo(false); - table.string('plaid_transaction_id'); - table.timestamps(); - } - ); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('uncategorized_cashflow_transactions'); -}; diff --git a/packages/server-nest/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.ts b/packages/server/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.ts rename to packages/server/src/database/migrations/20240228183404_create_uncateogrized_cashflow_transactions_table.ts diff --git a/packages/server/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.js b/packages/server/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.js deleted file mode 100644 index 06d05f521..000000000 --- a/packages/server/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.js +++ /dev/null @@ -1,10 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('accounts', (table) => { - table.integer('uncategorized_transactions').defaultTo(0); - table.boolean('is_system_account').defaultTo(true); - table.boolean('is_feeds_active').defaultTo(false); - table.datetime('last_feeds_updated_at').nullable(); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.ts b/packages/server/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.ts rename to packages/server/src/database/migrations/20240304153926_add_uncategorized_transactions_column_to_accounts_table.ts diff --git a/packages/server/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.js b/packages/server/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.js deleted file mode 100644 index 01b93bea5..000000000 --- a/packages/server/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('cashflow_transactions', (table) => { - table - .integer('uncategorized_transaction_id') - .unsigned() - .references('id') - .inTable('uncategorized_cashflow_transactions'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('cashflow_transactions', (table) => { - table.dropColumn('uncategorized_transaction_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.ts b/packages/server/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.ts rename to packages/server/src/database/migrations/20240308122047_add_uncategorized_transaction_id_to_cashflow_transactions.ts diff --git a/packages/server/src/database/migrations/20240604153938_drop_storage_table.js b/packages/server/src/database/migrations/20240604153938_drop_storage_table.js deleted file mode 100644 index f84c6abd0..000000000 --- a/packages/server/src/database/migrations/20240604153938_drop_storage_table.js +++ /dev/null @@ -1,5 +0,0 @@ -exports.up = function (knex) { - return knex.schema.dropTableIfExists('storage'); -}; - -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20240604153938_drop_storage_table.ts b/packages/server/src/database/migrations/20240604153938_drop_storage_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240604153938_drop_storage_table.ts rename to packages/server/src/database/migrations/20240604153938_drop_storage_table.ts diff --git a/packages/server/src/database/migrations/20240604153951_create_documents_table.js b/packages/server/src/database/migrations/20240604153951_create_documents_table.js deleted file mode 100644 index 44e2f269c..000000000 --- a/packages/server/src/database/migrations/20240604153951_create_documents_table.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('documents', (table) => { - table.increments('id').primary(); - table.string('key').notNullable(); - table.string('mime_type').notNullable(); - table.integer('size').unsigned(); - table.string('origin_name'); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('documents'); -}; diff --git a/packages/server-nest/src/database/migrations/20240604153951_create_documents_table.ts b/packages/server/src/database/migrations/20240604153951_create_documents_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240604153951_create_documents_table.ts rename to packages/server/src/database/migrations/20240604153951_create_documents_table.ts diff --git a/packages/server/src/database/migrations/20240604154005_create_documents_links_table.js b/packages/server/src/database/migrations/20240604154005_create_documents_links_table.js deleted file mode 100644 index 7cdb91429..000000000 --- a/packages/server/src/database/migrations/20240604154005_create_documents_links_table.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('document_links', (table) => { - table.increments('id').primary(); - table.string('model_ref').notNullable(); - table.string('model_id').notNullable(); - table.integer('document_id').unsigned(); - table.datetime('expires_at').nullable(); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('document_links'); -}; diff --git a/packages/server-nest/src/database/migrations/20240604154005_create_documents_links_table.ts b/packages/server/src/database/migrations/20240604154005_create_documents_links_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240604154005_create_documents_links_table.ts rename to packages/server/src/database/migrations/20240604154005_create_documents_links_table.ts diff --git a/packages/server/src/database/migrations/20240618100137_create_bank_rules_table.js b/packages/server/src/database/migrations/20240618100137_create_bank_rules_table.js deleted file mode 100644 index c11ce89f2..000000000 --- a/packages/server/src/database/migrations/20240618100137_create_bank_rules_table.js +++ /dev/null @@ -1,45 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .createTable('bank_rules', (table) => { - table.increments('id').primary(); - table.string('name'); - table.integer('order').unsigned(); - - table - .integer('apply_if_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.string('apply_if_transaction_type'); - - table.string('assign_category'); - table - .integer('assign_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.string('assign_payee'); - table.string('assign_memo'); - - table.string('conditions_type'); - - table.timestamps(); - }) - .createTable('bank_rule_conditions', (table) => { - table.increments('id').primary(); - table - .integer('rule_id') - .unsigned() - .references('id') - .inTable('bank_rules'); - table.string('field'); - table.string('comparator'); - table.string('value'); - }); -}; - -exports.down = function (knex) { - return knex.schema - .dropTableIfExists('bank_rules') - .dropTableIfExists('bank_rule_conditions'); -}; diff --git a/packages/server-nest/src/database/migrations/20240618100137_create_bank_rules_table.ts b/packages/server/src/database/migrations/20240618100137_create_bank_rules_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240618100137_create_bank_rules_table.ts rename to packages/server/src/database/migrations/20240618100137_create_bank_rules_table.ts diff --git a/packages/server/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.js b/packages/server/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.js deleted file mode 100644 index fbb8e7734..000000000 --- a/packages/server/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.js +++ /dev/null @@ -1,31 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('recognized_bank_transactions', (table) => { - table.increments('id'); - table - .integer('uncategorized_transaction_id') - .unsigned() - .references('id') - .inTable('uncategorized_cashflow_transactions') - .withKeyName('recognizedBankTransactionsUncategorizedTransIdForeign'); - table - .integer('bank_rule_id') - .unsigned() - .references('id') - .inTable('bank_rules'); - - table.string('assigned_category'); - table - .integer('assigned_account_id') - .unsigned() - .references('id') - .inTable('accounts'); - table.string('assigned_payee'); - table.string('assigned_memo'); - - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('recognized_bank_transactions'); -}; diff --git a/packages/server-nest/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.ts b/packages/server/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.ts rename to packages/server/src/database/migrations/20240618171553_create_recognized_bank_transactions_table.ts diff --git a/packages/server/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.js b/packages/server/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.js deleted file mode 100644 index 64c1e5450..000000000 --- a/packages/server/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.js +++ /dev/null @@ -1,16 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table - .integer('recognized_transaction_id') - .unsigned() - .references('id') - .inTable('recognized_bank_transactions') - .withKeyName('uncategorizedCashflowTransRecognizedTranIdForeign'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.dropColumn('recognized_transaction_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.ts b/packages/server/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.ts rename to packages/server/src/database/migrations/20240618175241_add_recognized_transaction_id_to_uncategorized_transactins_table.ts diff --git a/packages/server/src/database/migrations/20240619133733_create_matched_bank_transactions_table.js b/packages/server/src/database/migrations/20240619133733_create_matched_bank_transactions_table.js deleted file mode 100644 index f804ad7c7..000000000 --- a/packages/server/src/database/migrations/20240619133733_create_matched_bank_transactions_table.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('matched_bank_transactions', (table) => { - table.increments('id'); - table - .integer('uncategorized_transaction_id') - .unsigned() - .references('id') - .inTable('uncategorized_cashflow_transactions'); - table.string('reference_type'); - table.integer('reference_id').unsigned(); - table.decimal('amount'); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('matched_bank_transactions'); -}; diff --git a/packages/server-nest/src/database/migrations/20240619133733_create_matched_bank_transactions_table.ts b/packages/server/src/database/migrations/20240619133733_create_matched_bank_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240619133733_create_matched_bank_transactions_table.ts rename to packages/server/src/database/migrations/20240619133733_create_matched_bank_transactions_table.ts diff --git a/packages/server/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.js b/packages/server/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.js deleted file mode 100644 index f27351438..000000000 --- a/packages/server/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.datetime('excluded_at'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.dropColumn('excluded_at'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.ts b/packages/server/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.ts rename to packages/server/src/database/migrations/20240620111308_add_excluded_column_to_uncategorized_cashflow_transactions_table.ts diff --git a/packages/server/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.js b/packages/server/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.js deleted file mode 100644 index 7641da878..000000000 --- a/packages/server/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.string('batch'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.dropColumn('batch'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.ts b/packages/server/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.ts rename to packages/server/src/database/migrations/20240623154149_add_batch_column_to_uncategorized_cashflow_transactions_table.ts diff --git a/packages/server/src/database/migrations/20240704064858_change_settings_value_to_text.js b/packages/server/src/database/migrations/20240704064858_change_settings_value_to_text.js deleted file mode 100644 index 985947276..000000000 --- a/packages/server/src/database/migrations/20240704064858_change_settings_value_to_text.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('settings', (table) => { - table.text('value').alter(); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('settings', (table) => { - table.string('value').alter(); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240704064858_change_settings_value_to_text.ts b/packages/server/src/database/migrations/20240704064858_change_settings_value_to_text.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240704064858_change_settings_value_to_text.ts rename to packages/server/src/database/migrations/20240704064858_change_settings_value_to_text.ts diff --git a/packages/server/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.js b/packages/server/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.js deleted file mode 100644 index cc8a52e8c..000000000 --- a/packages/server/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.js +++ /dev/null @@ -1,60 +0,0 @@ -exports.up = function (knex) { - return knex('accounts_transactions') - .whereIn('referenceType', [ - 'OtherIncome', - 'OtherExpense', - 'OwnerDrawing', - 'OwnerContribution', - 'TransferToAccount', - 'TransferFromAccount', - ]) - .update({ - transactionType: knex.raw(` - CASE - WHEN REFERENCE_TYPE = 'OtherIncome' THEN 'OtherIncome' - WHEN REFERENCE_TYPE = 'OtherExpense' THEN 'OtherExpense' - WHEN REFERENCE_TYPE = 'OwnerDrawing' THEN 'OwnerDrawing' - WHEN REFERENCE_TYPE = 'OwnerContribution' THEN 'OwnerContribution' - WHEN REFERENCE_TYPE = 'TransferToAccount' THEN 'TransferToAccount' - WHEN REFERENCE_TYPE = 'TransferFromAccount' THEN 'TransferFromAccount' - END - `), - referenceType: knex.raw(` - CASE - WHEN REFERENCE_TYPE IN ('OtherIncome', 'OtherExpense', 'OwnerDrawing', 'OwnerContribution', 'TransferToAccount', 'TransferFromAccount') THEN 'CashflowTransaction' - ELSE REFERENCE_TYPE - END - `), - }); -}; - -exports.down = function (knex) { - return knex('accounts_transactions') - .whereIn('transactionType', [ - 'OtherIncome', - 'OtherExpense', - 'OwnerDrawing', - 'OwnerContribution', - 'TransferToAccount', - 'TransferFromAccount', - ]) - .update({ - referenceType: knex.raw(` - CASE - WHEN TRANSACTION_TYPE = 'OtherIncome' THEN 'OtherIncome' - WHEN TRANSACTION_TYPE = 'OtherExpense' THEN 'OtherExpense' - WHEN TRANSACTION_TYPE = 'OwnerDrawing' THEN 'OwnerDrawing' - WHEN TRANSACTION_TYPE = 'OwnerContribution' THEN 'OwnerContribution' - WHEN TRANSACTION_TYPE = 'TransferToAccount' THEN 'TransferToAccount' - WHEN TRANSACTION_TYPE = 'TransferFromAccount' THEN 'TransferFromAccount' - ELSE REFERENCE_TYPE - END - `), - transactionType: knex.raw(` - CASE - WHEN TRANSACTION_TYPE IN ('OtherIncome', 'OtherExpense', 'OwnerDrawing', 'OwnerContribution', 'TransferToAccount', 'TransferFromAccount') THEN NULL - ELSE TRANSACTION_TYPE - END - `), - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.ts b/packages/server/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.ts rename to packages/server/src/database/migrations/20240709122347_move_cashflow_transaction_type_to_transaction_type_column.ts diff --git a/packages/server/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.js b/packages/server/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.js deleted file mode 100644 index ce084dca8..000000000 --- a/packages/server/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('accounts', (table) => { - table.string('plaid_item_id').nullable(); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('accounts', (table) => { - table.dropColumn('plaid_item_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.ts b/packages/server/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.ts rename to packages/server/src/database/migrations/20240716114732_add_plaid_item_id_to_accounts_table.ts diff --git a/packages/server/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.js b/packages/server/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.js deleted file mode 100644 index f65eb3ca0..000000000 --- a/packages/server/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .table('accounts', (table) => { - table - .boolean('is_syncing_owner') - .defaultTo(false) - .after('is_feeds_active'); - }) - .then(() => { - return knex('accounts') - .whereNotNull('plaid_item_id') - .orWhereNotNull('plaid_account_id') - .update('is_syncing_owner', true); - }); -}; - -exports.down = function (knex) { - table.dropColumn('is_syncing_owner'); -}; diff --git a/packages/server-nest/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.ts b/packages/server/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.ts rename to packages/server/src/database/migrations/20240729172403_add_is_syncing_owner_to_accounts_table.ts diff --git a/packages/server/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.js b/packages/server/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.js deleted file mode 100644 index e03346a5f..000000000 --- a/packages/server/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.js +++ /dev/null @@ -1,18 +0,0 @@ -// This migration changes the precision of the tax_amount_withheld column in the bills and sales_invoices tables from 8, 2 to 13, 2. -// This migration is necessary to allow tax_amount_withheld filed to store values bigger than 999,999.99. - -exports.up = function(knex) { - return knex.schema.alterTable('bills', function (table) { - table.decimal('tax_amount_withheld', 13, 2).alter(); - }).alterTable('sales_invoices', function (table) { - table.decimal('tax_amount_withheld', 13, 2).alter(); - }); -}; - -exports.down = function(knex) { - return knex.schema.alterTable('bills', function (table) { - table.decimal('tax_amount_withheld', 8, 2).alter(); - }).alterTable('sales_invoices', function (table) { - table.decimal('tax_amount_withheld', 8, 2).alter(); - }); -}; \ No newline at end of file diff --git a/packages/server-nest/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.ts b/packages/server/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.ts rename to packages/server/src/database/migrations/20240801130829_change_tax_amount_withheld_column_precision_in_bills_and_sales_invoices_tables.ts diff --git a/packages/server/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.js b/packages/server/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.js deleted file mode 100644 index 2947eb30b..000000000 --- a/packages/server/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('plaid_items', (table) => { - table.datetime('paused_at'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('plaid_items', (table) => { - table.dropColumn('paused_at'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.ts b/packages/server/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.ts rename to packages/server/src/database/migrations/20240804084709_create_paused_at_column_to_plaid_items_table.ts diff --git a/packages/server/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.js b/packages/server/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.js deleted file mode 100644 index 73713b98b..000000000 --- a/packages/server/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.boolean('pending').defaultTo(false); - table.string('pending_plaid_transaction_id').nullable(); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('uncategorized_cashflow_transactions', (table) => { - table.dropColumn('pending'); - table.dropColumn('pending_plaid_transaction_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.ts b/packages/server/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.ts rename to packages/server/src/database/migrations/20240811121028_add_pending_column_to_uncategorized_transactions_table.ts diff --git a/packages/server/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.js b/packages/server/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.js deleted file mode 100644 index 5a82f16bb..000000000 --- a/packages/server/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.table('payment_receives', (table) => { - table.string('stripe_pintent_id').nullable(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.table('payment_receives', (table) => { - table.dropColumn('stripe_pintent_id'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.ts b/packages/server/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.ts rename to packages/server/src/database/migrations/20240909101051_add_stripe_pintent_id_to_payments_received.ts diff --git a/packages/server/src/database/migrations/20240911112147_create_pdf_templates_table.js b/packages/server/src/database/migrations/20240911112147_create_pdf_templates_table.js deleted file mode 100644 index be880c262..000000000 --- a/packages/server/src/database/migrations/20240911112147_create_pdf_templates_table.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema - .createTable('pdf_templates', (table) => { - table.increments('id').primary(); - table.text('resource'); - table.text('template_name'); - table.json('attributes'); - table.boolean('predefined').defaultTo(false); - table.boolean('default').defaultTo(false); - table.timestamps(); - }) - .table('sales_invoices', (table) => { - table - .integer('pdf_template_id') - .unsigned() - .references('id') - .inTable('pdf_templates'); - }) - .table('sales_estimates', (table) => { - table - .integer('pdf_template_id') - .unsigned() - .references('id') - .inTable('pdf_templates'); - }) - .table('sales_receipts', (table) => { - table - .integer('pdf_template_id') - .unsigned() - .references('id') - .inTable('pdf_templates'); - }) - .table('credit_notes', (table) => { - table - .integer('pdf_template_id') - .unsigned() - .references('id') - .inTable('pdf_templates'); - }) - .table('payment_receives', (table) => { - table - .integer('pdf_template_id') - .unsigned() - .references('id') - .inTable('pdf_templates'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema - .table('payment_receives', (table) => { - table.dropColumn('pdf_template_id'); - }) - .table('credit_notes', (table) => { - table.dropColumn('pdf_template_id'); - }) - .table('sales_receipts', (table) => { - table.dropColumn('pdf_template_id'); - }) - .table('sales_estimates', (table) => { - table.dropColumn('pdf_template_id'); - }) - .table('sales_invoices', (table) => { - table.dropColumn('pdf_template_id'); - }) - .dropTableIfExists('pdf_templates'); -}; diff --git a/packages/server-nest/src/database/migrations/20240911112147_create_pdf_templates_table.ts b/packages/server/src/database/migrations/20240911112147_create_pdf_templates_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240911112147_create_pdf_templates_table.ts rename to packages/server/src/database/migrations/20240911112147_create_pdf_templates_table.ts diff --git a/packages/server/src/database/migrations/20240915155403_payment_integration.js b/packages/server/src/database/migrations/20240915155403_payment_integration.js deleted file mode 100644 index 01fac495c..000000000 --- a/packages/server/src/database/migrations/20240915155403_payment_integration.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.createTable('payment_integrations', (table) => { - table.increments('id'); - table.string('service'); - table.string('name'); - table.string('slug'); - table.boolean('payment_enabled').defaultTo(false); - table.boolean('payout_enabled').defaultTo(false); - table.string('account_id'); - table.json('options'); - table.timestamps(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.dropTableIfExists('payment_integrations'); -}; diff --git a/packages/server-nest/src/database/migrations/20240915155403_payment_integration.ts b/packages/server/src/database/migrations/20240915155403_payment_integration.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240915155403_payment_integration.ts rename to packages/server/src/database/migrations/20240915155403_payment_integration.ts diff --git a/packages/server/src/database/migrations/20240915163722_creat_transaction_payment_service_table.js b/packages/server/src/database/migrations/20240915163722_creat_transaction_payment_service_table.js deleted file mode 100644 index 17b7fceda..000000000 --- a/packages/server/src/database/migrations/20240915163722_creat_transaction_payment_service_table.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.createTable('transactions_payment_methods', (table) => { - table.increments('id'); - table.integer('reference_id').unsigned(); - table.string('reference_type'); - table - .integer('payment_integration_id') - .unsigned() - .index() - .references('id') - .inTable('payment_integrations'); - table.boolean('enable').defaultTo(false); - table.json('options').nullable(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.dropTableIfExists('transactions_payment_methods'); -}; diff --git a/packages/server-nest/src/database/migrations/20240915163722_creat_transaction_payment_service_table.ts b/packages/server/src/database/migrations/20240915163722_creat_transaction_payment_service_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240915163722_creat_transaction_payment_service_table.ts rename to packages/server/src/database/migrations/20240915163722_creat_transaction_payment_service_table.ts diff --git a/packages/server/src/database/migrations/20240915195024_seed_standard_pdf_templates.js b/packages/server/src/database/migrations/20240915195024_seed_standard_pdf_templates.js deleted file mode 100644 index 74c87bb14..000000000 --- a/packages/server/src/database/migrations/20240915195024_seed_standard_pdf_templates.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex('pdf_templates').insert([ - { - resource: 'SaleInvoice', - templateName: 'Standard Template', - predefined: true, - default: true, - }, - { - resource: 'SaleEstimate', - templateName: 'Standard Template', - predefined: true, - default: true, - }, - { - resource: 'SaleReceipt', - templateName: 'Standard Template', - predefined: true, - default: true, - }, - { - resource: 'CreditNote', - templateName: 'Standard Template', - predefined: true, - default: true, - }, - { - resource: 'PaymentReceive', - templateName: 'Standard Template', - predefined: true, - default: true, - }, - ]); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) {}; diff --git a/packages/server-nest/src/database/migrations/20240915195024_seed_standard_pdf_templates.ts b/packages/server/src/database/migrations/20240915195024_seed_standard_pdf_templates.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20240915195024_seed_standard_pdf_templates.ts rename to packages/server/src/database/migrations/20240915195024_seed_standard_pdf_templates.ts diff --git a/packages/server/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.js b/packages/server/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.js deleted file mode 100644 index dcc711ffc..000000000 --- a/packages/server/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema - .table('items_entries', (table) => { - table.decimal('quantity', 13, 3).alter(); - }) - .table('inventory_transactions', (table) => { - table.decimal('quantity', 13, 3).alter(); - }) - .table('inventory_cost_lot_tracker', (table) => { - table.decimal('quantity', 13, 3).alter(); - }) - .table('items', (table) => { - table.decimal('quantityOnHand', 13, 3).alter(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema - .table('items_entries', (table) => { - table.integer('quantity').alter(); - }) - .table('inventory_transactions', (table) => { - table.integer('quantity').alter(); - }) - .table('inventory_cost_lot_tracker', (table) => { - table.integer('quantity').alter(); - }) - .table('items', (table) => { - table.integer('quantityOnHand').alter(); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.ts b/packages/server/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.ts rename to packages/server/src/database/migrations/20241113113437_change_quantity_in_items_entries_to_decimal.ts diff --git a/packages/server/src/database/migrations/20241128080734_add_discount_to_invoices_table.js b/packages/server/src/database/migrations/20241128080734_add_discount_to_invoices_table.js deleted file mode 100644 index d65b00615..000000000 --- a/packages/server/src/database/migrations/20241128080734_add_discount_to_invoices_table.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.alterTable('sales_invoices', (table) => { - table.decimal('discount', 10, 2).nullable().after('credited_amount'); - table.string('discount_type').nullable().after('discount'); - table.decimal('adjustment', 10, 2).nullable().after('discount_type'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.alterTable('sale_invoices', (table) => { - table.dropColumn('discount'); - table.dropColumn('discount_type'); - table.dropColumn('adjustment'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241128080734_add_discount_to_invoices_table.ts b/packages/server/src/database/migrations/20241128080734_add_discount_to_invoices_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241128080734_add_discount_to_invoices_table.ts rename to packages/server/src/database/migrations/20241128080734_add_discount_to_invoices_table.ts diff --git a/packages/server/src/database/migrations/20241128081259_add_discount_to_estimates_table.js b/packages/server/src/database/migrations/20241128081259_add_discount_to_estimates_table.js deleted file mode 100644 index 748483f26..000000000 --- a/packages/server/src/database/migrations/20241128081259_add_discount_to_estimates_table.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function(knex) { - return knex.schema.alterTable('sales_estimates', (table) => { - table.decimal('discount', 10, 2).nullable().after('amount'); - table.string('discount_type').nullable().after('discount'); - - table.decimal('adjustment', 10, 2).nullable().after('discount_type'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function(knex) { - return knex.schema.alterTable('sales_estimates', (table) => { - table.dropColumn('discount'); - table.dropColumn('discount_type'); - table.dropColumn('adjustment'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241128081259_add_discount_to_estimates_table.ts b/packages/server/src/database/migrations/20241128081259_add_discount_to_estimates_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241128081259_add_discount_to_estimates_table.ts rename to packages/server/src/database/migrations/20241128081259_add_discount_to_estimates_table.ts diff --git a/packages/server/src/database/migrations/20241128084550_add_discount_to_receipts_table.js b/packages/server/src/database/migrations/20241128084550_add_discount_to_receipts_table.js deleted file mode 100644 index 8b46955cc..000000000 --- a/packages/server/src/database/migrations/20241128084550_add_discount_to_receipts_table.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function(knex) { - return knex.schema.alterTable('sales_receipts', (table) => { - table.decimal('discount', 10, 2).nullable().after('amount'); - table.string('discount_type').nullable().after('discount'); - - table.decimal('adjustment', 10, 2).nullable().after('discount_type'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function(knex) { - return knex.schema.alterTable('sales_receipts', (table) => { - table.dropColumn('discount'); - table.dropColumn('discount_type'); - table.dropColumn('adjustment'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241128084550_add_discount_to_receipts_table.ts b/packages/server/src/database/migrations/20241128084550_add_discount_to_receipts_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241128084550_add_discount_to_receipts_table.ts rename to packages/server/src/database/migrations/20241128084550_add_discount_to_receipts_table.ts diff --git a/packages/server/src/database/migrations/20241128085243_add_discount_to_bills_table.js b/packages/server/src/database/migrations/20241128085243_add_discount_to_bills_table.js deleted file mode 100644 index 9de24d9ab..000000000 --- a/packages/server/src/database/migrations/20241128085243_add_discount_to_bills_table.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function(knex) { - return knex.schema.alterTable('bills', (table) => { - // Discount. - table.decimal('discount', 10, 2).nullable().after('amount'); - table.string('discount_type').nullable().after('discount'); - - // Adjustment. - table.decimal('adjustment', 10, 2).nullable().after('discount_type'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function(knex) { - return knex.schema.alterTable('bills', (table) => { - table.dropColumn('discount'); - table.dropColumn('discount_type'); - table.dropColumn('adjustment'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241128085243_add_discount_to_bills_table.ts b/packages/server/src/database/migrations/20241128085243_add_discount_to_bills_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241128085243_add_discount_to_bills_table.ts rename to packages/server/src/database/migrations/20241128085243_add_discount_to_bills_table.ts diff --git a/packages/server/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.js b/packages/server/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.js deleted file mode 100644 index fcca5bfa4..000000000 --- a/packages/server/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function(knex) { - return knex.schema.alterTable('credit_notes', (table) => { - table.decimal('discount', 10, 2).nullable().after('exchange_rate'); - table.string('discount_type').nullable().after('discount'); - table.decimal('adjustment', 10, 2).nullable().after('discount_type'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function(knex) { - return knex.schema.alterTable('credit_notes', (table) => { - table.dropColumn('discount'); - table.dropColumn('discount_type'); - table.dropColumn('adjustment'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.ts b/packages/server/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.ts rename to packages/server/src/database/migrations/20241128090222_add_discount_to_credit_notes_table.ts diff --git a/packages/server/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.js b/packages/server/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.js deleted file mode 100644 index 706bad1f7..000000000 --- a/packages/server/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function(knex) { - return knex.schema.alterTable('vendor_credits', (table) => { - table.decimal('discount', 10, 2).nullable().after('amount'); - table.string('discount_type').nullable().after('discount'); - table.decimal('adjustment', 10, 2).nullable().after('discount_type'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function(knex) { - return knex.schema.alterTable('vendor_credits', (table) => { - table.dropColumn('discount'); - table.dropColumn('discount_type'); - table.dropColumn('adjustment'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.ts b/packages/server/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.ts rename to packages/server/src/database/migrations/20241128160604_add_discount_to_vendor_credits_table.ts diff --git a/packages/server/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.js b/packages/server/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.js deleted file mode 100644 index 292bdd8dc..000000000 --- a/packages/server/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.alterTable('items_entries', (table) => { - table.string('discount_type').defaultTo('percentage').after('discount'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.alterTable('items_entries', (table) => { - table.dropColumn('discount_type'); - }); -}; diff --git a/packages/server-nest/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.ts b/packages/server/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.ts similarity index 100% rename from packages/server-nest/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.ts rename to packages/server/src/database/migrations/20241211103019_add_discount_type_to_items_entries_table.ts diff --git a/packages/server/src/database/objection.ts b/packages/server/src/database/objection.ts deleted file mode 100644 index cf57361c4..000000000 --- a/packages/server/src/database/objection.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Model } from 'objection'; - -// Bind all Models to a knex instance. If you only have one database in -// your server this is all you have to do. For multi database systems, see -// the Model.bindKnex() method. -export default ({ knex }) => { - Model.knex(knex); -}; diff --git a/packages/server/src/database/seeds/core/20190423085242_seed_accounts.ts b/packages/server/src/database/seeds/core/20190423085242_seed_accounts.ts index 7fcbd0e5f..303a4281a 100644 --- a/packages/server/src/database/seeds/core/20190423085242_seed_accounts.ts +++ b/packages/server/src/database/seeds/core/20190423085242_seed_accounts.ts @@ -1,5 +1,5 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; -import AccountsData from '../data/accounts'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; +import { AccountsData } from '../data/accounts'; export default class SeedAccounts extends TenantSeeder { /** @@ -8,8 +8,8 @@ export default class SeedAccounts extends TenantSeeder { up(knex) { const data = AccountsData.map((account) => ({ ...account, - name: this.i18n.__(account.name), - description: this.i18n.__(account.description), + name: this.i18n.t(account.name), + description: account.description ? this.i18n.t(account.description) : '', currencyCode: this.tenant.metadata.baseCurrency, seededAt: new Date(), })); diff --git a/packages/server/src/database/seeds/core/20200810121809_seed_settings.ts b/packages/server/src/database/seeds/core/20200810121809_seed_settings.ts index 8e05b291d..70948f36c 100644 --- a/packages/server/src/database/seeds/core/20200810121809_seed_settings.ts +++ b/packages/server/src/database/seeds/core/20200810121809_seed_settings.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; export default class SeedSettings extends TenantSeeder { /** diff --git a/packages/server/src/database/seeds/core/20200810121909_seed_items_settings.ts b/packages/server/src/database/seeds/core/20200810121909_seed_items_settings.ts index 1950b4c75..b07e5c39e 100644 --- a/packages/server/src/database/seeds/core/20200810121909_seed_items_settings.ts +++ b/packages/server/src/database/seeds/core/20200810121909_seed_items_settings.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; export default class SeedSettings extends TenantSeeder { /** diff --git a/packages/server/src/database/seeds/core/20210810121909_seed_roles.ts b/packages/server/src/database/seeds/core/20210810121909_seed_roles.ts index 5bbca56b4..10ac1e49a 100644 --- a/packages/server/src/database/seeds/core/20210810121909_seed_roles.ts +++ b/packages/server/src/database/seeds/core/20210810121909_seed_roles.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; export default class SeedRolesAndPermissions extends TenantSeeder { /** diff --git a/packages/server/src/database/seeds/core/20210812121909_seed_roles_permissions.ts b/packages/server/src/database/seeds/core/20210812121909_seed_roles_permissions.ts index 041057387..b6493f1e6 100644 --- a/packages/server/src/database/seeds/core/20210812121909_seed_roles_permissions.ts +++ b/packages/server/src/database/seeds/core/20210812121909_seed_roles_permissions.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; export default class SeedRolesAndPermissions extends TenantSeeder { /** diff --git a/packages/server/src/database/seeds/core/20210912121909_seed_credit_settings.ts b/packages/server/src/database/seeds/core/20210912121909_seed_credit_settings.ts index 3c88a4c76..6defb942e 100644 --- a/packages/server/src/database/seeds/core/20210912121909_seed_credit_settings.ts +++ b/packages/server/src/database/seeds/core/20210912121909_seed_credit_settings.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; export default class SeedCustomerVendorCreditSettings extends TenantSeeder { /** diff --git a/packages/server/src/database/seeds/core/20230912121909_seed_tax_rates.ts b/packages/server/src/database/seeds/core/20230912121909_seed_tax_rates.ts index 10856e740..4a11fa4fc 100644 --- a/packages/server/src/database/seeds/core/20230912121909_seed_tax_rates.ts +++ b/packages/server/src/database/seeds/core/20230912121909_seed_tax_rates.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; import { InitialTaxRates } from '../data/TaxRates'; export default class SeedTaxRates extends TenantSeeder { diff --git a/packages/server/src/database/seeds/core/20230912121909_update_tax_payable_account.ts b/packages/server/src/database/seeds/core/20230912121909_update_tax_payable_account.ts index 469eef10e..352d2b0b3 100644 --- a/packages/server/src/database/seeds/core/20230912121909_update_tax_payable_account.ts +++ b/packages/server/src/database/seeds/core/20230912121909_update_tax_payable_account.ts @@ -1,4 +1,4 @@ -import { TenantSeeder } from '@/lib/Seeder/TenantSeeder'; +import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder'; import { InitialTaxRates } from '../data/TaxRates'; export default class UpdateTaxPayableAccount extends TenantSeeder { diff --git a/packages/server/src/database/seeds/data/accounts.js b/packages/server/src/database/seeds/data/accounts.js deleted file mode 100644 index 35430bbed..000000000 --- a/packages/server/src/database/seeds/data/accounts.js +++ /dev/null @@ -1,395 +0,0 @@ -export const OtherExpensesAccount = { - name: 'Other Expenses', - slug: 'other-expenses', - account_type: 'other-expense', - code: '40011', - description: '', - active: 1, - index: 1, - predefined: 1, -}; - -export const TaxPayableAccount = { - name: 'Tax Payable', - slug: 'tax-payable', - account_type: 'tax-payable', - code: '20006', - description: '', - active: 1, - index: 1, - predefined: 1, -}; - -export const UnearnedRevenueAccount = { - name: 'Unearned Revenue', - slug: 'unearned-revenue', - account_type: 'other-current-liability', - parent_account_id: null, - code: '50005', - active: true, - index: 1, - predefined: true, -}; - -export const PrepardExpenses = { - name: 'Prepaid Expenses', - slug: 'prepaid-expenses', - account_type: 'other-current-asset', - parent_account_id: null, - code: '100010', - active: true, - index: 1, - predefined: true, -}; - -export const StripeClearingAccount = { - name: 'Stripe Clearing', - slug: 'stripe-clearing', - account_type: 'other-current-asset', - parent_account_id: null, - code: '100020', - active: true, - index: 1, - predefined: true, -}; - -export const DiscountExpenseAccount = { - name: 'Discount', - slug: 'discount', - account_type: 'other-income', - code: '40008', - active: true, - index: 1, - predefined: true, -}; - -export const PurchaseDiscountAccount = { - name: 'Purchase Discount', - slug: 'purchase-discount', - account_type: 'other-expense', - code: '40009', - active: true, - index: 1, - predefined: true, -}; - -export const OtherChargesAccount = { - name: 'Other Charges', - slug: 'other-charges', - account_type: 'other-income', - code: '40010', - active: true, - index: 1, - predefined: true, -}; - -export default [ - { - name: 'Bank Account', - slug: 'bank-account', - account_type: 'bank', - code: '10001', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Saving Bank Account', - slug: 'saving-bank-account', - account_type: 'bank', - code: '10002', - description: '', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Undeposited Funds', - slug: 'undeposited-funds', - account_type: 'cash', - code: '10003', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Petty Cash', - slug: 'petty-cash', - account_type: 'cash', - code: '10004', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Computer Equipment', - slug: 'computer-equipment', - code: '10005', - account_type: 'fixed-asset', - predefined: 0, - parent_account_id: null, - index: 1, - active: 1, - description: '', - }, - { - name: 'Office Equipment', - slug: 'office-equipment', - code: '10006', - account_type: 'fixed-asset', - predefined: 0, - parent_account_id: null, - index: 1, - active: 1, - description: '', - }, - { - name: 'Accounts Receivable (A/R)', - slug: 'accounts-receivable', - account_type: 'accounts-receivable', - code: '10007', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Inventory Asset', - slug: 'inventory-asset', - code: '10008', - account_type: 'inventory', - predefined: 1, - parent_account_id: null, - index: 1, - active: 1, - description: - 'An account that holds valuation of products or goods that available for sale.', - }, - - // Libilities - { - name: 'Accounts Payable (A/P)', - slug: 'accounts-payable', - account_type: 'accounts-payable', - parent_account_id: null, - code: '20001', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Owner A Drawings', - slug: 'owner-drawings', - account_type: 'other-current-liability', - parent_account_id: null, - code: '20002', - description: 'Withdrawals by the owners.', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Loan', - slug: 'owner-drawings', - account_type: 'other-current-liability', - code: '20003', - description: 'Money that has been borrowed from a creditor.', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Opening Balance Liabilities', - slug: 'opening-balance-liabilities', - account_type: 'other-current-liability', - code: '20004', - description: - 'This account will hold the difference in the debits and credits entered during the opening balance..', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Revenue Received in Advance', - slug: 'revenue-received-in-advance', - account_type: 'other-current-liability', - parent_account_id: null, - code: '20005', - description: 'When customers pay in advance for products/services.', - active: 1, - index: 1, - predefined: 0, - }, - TaxPayableAccount, - - // Equity - { - name: 'Retained Earnings', - slug: 'retained-earnings', - account_type: 'equity', - code: '30001', - description: - 'Retained earnings tracks net income from previous fiscal years.', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Opening Balance Equity', - slug: 'opening-balance-equity', - account_type: 'equity', - code: '30002', - description: - 'When you enter opening balances to the accounts, the amounts enter in Opening balance equity. This ensures that you have a correct trial balance sheet for your company, without even specific the second credit or debit entry.', - active: 1, - index: 1, - predefined: 1, - }, - { - name: "Owner's Equity", - slug: 'owner-equity', - account_type: 'equity', - code: '30003', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: `Drawings`, - slug: 'drawings', - account_type: 'equity', - code: '30003', - description: - 'Goods purchased with the intention of selling these to customers', - active: 1, - index: 1, - predefined: 1, - }, - - // Expenses - OtherExpensesAccount, - { - name: 'Cost of Goods Sold', - slug: 'cost-of-goods-sold', - account_type: 'cost-of-goods-sold', - parent_account_id: null, - code: '40002', - description: 'Tracks the direct cost of the goods sold.', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Office expenses', - slug: 'office-expenses', - account_type: 'expense', - parent_account_id: null, - code: '40003', - description: '', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Rent', - slug: 'rent', - account_type: 'expense', - parent_account_id: null, - code: '40004', - description: '', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Exchange Gain or Loss', - slug: 'exchange-grain-loss', - account_type: 'other-expense', - parent_account_id: null, - code: '40005', - description: 'Tracks the gain and losses of the exchange differences.', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Bank Fees and Charges', - slug: 'bank-fees-and-charges', - account_type: 'expense', - parent_account_id: null, - code: '40006', - description: - 'Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.', - active: 1, - index: 1, - predefined: 0, - }, - { - name: 'Depreciation Expense', - slug: 'depreciation-expense', - account_type: 'expense', - parent_account_id: null, - code: '40007', - description: '', - active: 1, - index: 1, - predefined: 0, - }, - - // Income - { - name: 'Sales of Product Income', - slug: 'sales-of-product-income', - account_type: 'income', - predefined: 1, - parent_account_id: null, - code: '50001', - index: 1, - active: 1, - description: '', - }, - { - name: 'Sales of Service Income', - slug: 'sales-of-service-income', - account_type: 'income', - predefined: 0, - parent_account_id: null, - code: '50002', - index: 1, - active: 1, - description: '', - }, - { - name: 'Uncategorized Income', - slug: 'uncategorized-income', - account_type: 'income', - parent_account_id: null, - code: '50003', - description: '', - active: 1, - index: 1, - predefined: 1, - }, - { - name: 'Other Income', - slug: 'other-income', - account_type: 'other-income', - parent_account_id: null, - code: '50004', - description: - 'The income activities are not associated to the core business.', - active: 1, - index: 1, - predefined: 0, - }, - UnearnedRevenueAccount, - PrepardExpenses, - DiscountExpenseAccount, - PurchaseDiscountAccount, - OtherChargesAccount, -]; diff --git a/packages/server-nest/src/database/seeds/data/accounts.ts b/packages/server/src/database/seeds/data/accounts.ts similarity index 100% rename from packages/server-nest/src/database/seeds/data/accounts.ts rename to packages/server/src/database/seeds/data/accounts.ts diff --git a/packages/server/src/decorators/eventDispatcher.ts b/packages/server/src/decorators/eventDispatcher.ts deleted file mode 100644 index 4ac9a6d50..000000000 --- a/packages/server/src/decorators/eventDispatcher.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { EventDispatcher as EventDispatcherClass } from 'event-dispatch'; -import { Container } from 'typedi'; - -export function EventDispatcher() { - return (object: any, propertyName: string, index?: number): void => { - const eventDispatcher = new EventDispatcherClass(); - Container.registerHandler({ object, propertyName, index, value: () => eventDispatcher }); - }; -} - -export { EventDispatcher as EventDispatcherInterface } from 'event-dispatch'; diff --git a/packages/server/src/exceptions/HttpException.ts b/packages/server/src/exceptions/HttpException.ts deleted file mode 100644 index e0297d0e6..000000000 --- a/packages/server/src/exceptions/HttpException.ts +++ /dev/null @@ -1,9 +0,0 @@ -class HttpException extends Error { - public status: number; - public message: string; - constructor(status: number, message: string) { - super(message); - this.status = status; - this.message = message; - } -} diff --git a/packages/server/src/exceptions/ModelEntityNotFound.ts b/packages/server/src/exceptions/ModelEntityNotFound.ts deleted file mode 100644 index a7bd6dfe1..000000000 --- a/packages/server/src/exceptions/ModelEntityNotFound.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export default class ModelEntityNotFound extends Error { - - constructor(entityId, message?) { - message = message || `Entity with id ${entityId} does not exist`; - super(message); - } -} \ No newline at end of file diff --git a/packages/server/src/exceptions/NotAllowedChangeSubscriptionPlan.ts b/packages/server/src/exceptions/NotAllowedChangeSubscriptionPlan.ts deleted file mode 100644 index 3c5380259..000000000 --- a/packages/server/src/exceptions/NotAllowedChangeSubscriptionPlan.ts +++ /dev/null @@ -1,8 +0,0 @@ - - -export default class NotAllowedChangeSubscriptionPlan { - - constructor() { - this.name = "NotAllowedChangeSubscriptionPlan"; - } -} \ No newline at end of file diff --git a/packages/server/src/exceptions/ServiceError.ts b/packages/server/src/exceptions/ServiceError.ts deleted file mode 100644 index 2e3139805..000000000 --- a/packages/server/src/exceptions/ServiceError.ts +++ /dev/null @@ -1,14 +0,0 @@ - - -export default class ServiceError { - errorType: string; - message: string; - payload: any; - - constructor(errorType: string, message?: string, payload?: any) { - this.errorType = errorType; - this.message = message || null; - - this.payload = payload; - } -} \ No newline at end of file diff --git a/packages/server/src/exceptions/ServiceErrors.ts b/packages/server/src/exceptions/ServiceErrors.ts deleted file mode 100644 index 665b78676..000000000 --- a/packages/server/src/exceptions/ServiceErrors.ts +++ /dev/null @@ -1,15 +0,0 @@ -import ServiceError from './ServiceError'; - -export default class ServiceErrors { - errors: ServiceError[]; - - constructor(errors: ServiceError[]) { - this.errors = errors; - } - - hasType(errorType: string) { - return this.errors.some( - (error: ServiceError) => error.errorType === errorType - ); - } -} diff --git a/packages/server/src/exceptions/TenantAlreadyInitialized.ts b/packages/server/src/exceptions/TenantAlreadyInitialized.ts deleted file mode 100644 index 2c7a400f3..000000000 --- a/packages/server/src/exceptions/TenantAlreadyInitialized.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default class TenantAlreadyInitialized { - constructor() {} -} diff --git a/packages/server/src/exceptions/TenantAlreadySeeded.ts b/packages/server/src/exceptions/TenantAlreadySeeded.ts deleted file mode 100644 index 22ceacd23..000000000 --- a/packages/server/src/exceptions/TenantAlreadySeeded.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default class TenantAlreadySeeded { - constructor() {} -} diff --git a/packages/server/src/exceptions/TenantDBAlreadyExists.ts b/packages/server/src/exceptions/TenantDBAlreadyExists.ts deleted file mode 100644 index 72c51890d..000000000 --- a/packages/server/src/exceptions/TenantDBAlreadyExists.ts +++ /dev/null @@ -1,9 +0,0 @@ - - - - -export default class TenantDBAlreadyExists { - constructor() { - - } -} \ No newline at end of file diff --git a/packages/server/src/exceptions/TenantDatabaseNotBuilt.ts b/packages/server/src/exceptions/TenantDatabaseNotBuilt.ts deleted file mode 100644 index f186836ec..000000000 --- a/packages/server/src/exceptions/TenantDatabaseNotBuilt.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default class TenantDatabaseNotBuilt { - constructor() {} -} diff --git a/packages/server/src/exceptions/index.ts b/packages/server/src/exceptions/index.ts deleted file mode 100644 index f04873ba5..000000000 --- a/packages/server/src/exceptions/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import NotAllowedChangeSubscriptionPlan from './NotAllowedChangeSubscriptionPlan'; -import ServiceError from './ServiceError'; -import ServiceErrors from './ServiceErrors'; -import TenantAlreadyInitialized from './TenantAlreadyInitialized'; -import TenantAlreadySeeded from './TenantAlreadySeeded'; -import TenantDBAlreadyExists from './TenantDBAlreadyExists'; -import TenantDatabaseNotBuilt from './TenantDatabaseNotBuilt'; - -export { - NotAllowedChangeSubscriptionPlan, - ServiceError, - ServiceErrors, - TenantAlreadyInitialized, - TenantAlreadySeeded, - TenantDBAlreadyExists, - TenantDatabaseNotBuilt, -}; diff --git a/packages/server-nest/src/i18n/en/test.json b/packages/server/src/i18n/en/test.json similarity index 100% rename from packages/server-nest/src/i18n/en/test.json rename to packages/server/src/i18n/en/test.json diff --git a/packages/server-nest/src/interceptors/ExcludeNull.interceptor.ts b/packages/server/src/interceptors/ExcludeNull.interceptor.ts similarity index 100% rename from packages/server-nest/src/interceptors/ExcludeNull.interceptor.ts rename to packages/server/src/interceptors/ExcludeNull.interceptor.ts diff --git a/packages/server-nest/src/interceptors/global-prefix.interceptor.ts b/packages/server/src/interceptors/global-prefix.interceptor.ts similarity index 100% rename from packages/server-nest/src/interceptors/global-prefix.interceptor.ts rename to packages/server/src/interceptors/global-prefix.interceptor.ts diff --git a/packages/server-nest/src/interceptors/user-ip.interceptor.ts b/packages/server/src/interceptors/user-ip.interceptor.ts similarity index 100% rename from packages/server-nest/src/interceptors/user-ip.interceptor.ts rename to packages/server/src/interceptors/user-ip.interceptor.ts diff --git a/packages/server/src/interfaces/APAgingSummaryReport.ts b/packages/server/src/interfaces/APAgingSummaryReport.ts deleted file mode 100644 index 21ed036c7..000000000 --- a/packages/server/src/interfaces/APAgingSummaryReport.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - IAgingPeriod, - IAgingSummaryQuery, - IAgingSummaryTotal, - IAgingSummaryContact, - IAgingSummaryData, -} from './AgingReport'; -import { IFinancialSheetCommonMeta } from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface IAPAgingSummaryQuery extends IAgingSummaryQuery { - vendorsIds: number[]; -} - -export interface IAPAgingSummaryVendor extends IAgingSummaryContact { - vendorName: string; -} - -export interface IAPAgingSummaryTotal extends IAgingSummaryTotal {} - -export interface IAPAgingSummaryData extends IAgingSummaryData { - vendors: IAPAgingSummaryVendor[]; -} - -export type IAPAgingSummaryColumns = IAgingPeriod[]; - -export interface IARAgingSummaryMeta extends IFinancialSheetCommonMeta { - formattedAsDate: string; -} - -export interface IAPAgingSummaryMeta extends IFinancialSheetCommonMeta { - formattedAsDate: string; -} - -export interface IAPAgingSummaryTable extends IFinancialTable { - query: IAPAgingSummaryQuery; - meta: IAPAgingSummaryMeta; -} - -export interface IAPAgingSummarySheet { - data: IAPAgingSummaryData; - meta: IAPAgingSummaryMeta; - query: IAPAgingSummaryQuery; - columns: any; -} diff --git a/packages/server/src/interfaces/ARAgingSummaryReport.ts b/packages/server/src/interfaces/ARAgingSummaryReport.ts deleted file mode 100644 index b20753927..000000000 --- a/packages/server/src/interfaces/ARAgingSummaryReport.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - IAgingPeriod, - IAgingSummaryQuery, - IAgingSummaryTotal, - IAgingSummaryContact, - IAgingSummaryData, -} from './AgingReport'; -import { IFinancialTable } from './Table'; - -export interface IARAgingSummaryQuery extends IAgingSummaryQuery { - customersIds: number[]; -} - -export interface IARAgingSummaryCustomer extends IAgingSummaryContact { - customerName: string; -} - -export interface IARAgingSummaryTotal extends IAgingSummaryTotal {} - -export interface IARAgingSummaryData extends IAgingSummaryData { - customers: IARAgingSummaryCustomer[]; -} - -export type IARAgingSummaryColumns = IAgingPeriod[]; - -export interface IARAgingSummaryMeta { - organizationName: string; - baseCurrency: string; -} - -export interface IARAgingSummaryTable extends IFinancialTable { - meta: IARAgingSummaryMeta; - query: IARAgingSummaryQuery; -} - -export interface IARAgingSummarySheet { - data: IARAgingSummaryData; - meta: IARAgingSummaryMeta; - query: IARAgingSummaryQuery; - columns: IARAgingSummaryColumns; -} - diff --git a/packages/server/src/interfaces/Account.ts b/packages/server/src/interfaces/Account.ts index 03c002c7b..9fb905e3f 100644 --- a/packages/server/src/interfaces/Account.ts +++ b/packages/server/src/interfaces/Account.ts @@ -1,5 +1,4 @@ import { Knex } from 'knex'; -import { IDynamicListFilterDTO } from '@/interfaces/DynamicFilter'; export interface IAccountDTO { name: string; @@ -38,7 +37,7 @@ export interface IAccount { accountNormal: string; accountParentType: string; bankBalance: string; - plaidItemId: number | null + plaidItemId: number | null; lastFeedsUpdatedAt: Date; } @@ -97,7 +96,7 @@ export enum IAccountsStructureType { Flat = 'flat', } -export interface IAccountsFilter extends IDynamicListFilterDTO { +export interface IAccountsFilter { stringifiedFilterRoles?: string; onlyInactive: boolean; structure?: IAccountsStructureType; @@ -118,26 +117,22 @@ export interface IAccountsTypesService { } export interface IAccountEventCreatingPayload { - tenantId: number; accountDTO: any; trx: Knex.Transaction; } export interface IAccountEventCreatedPayload { - tenantId: number; account: IAccount; accountId: number; trx: Knex.Transaction; } export interface IAccountEventEditedPayload { - tenantId: number; account: IAccount; oldAccount: IAccount; trx: Knex.Transaction; } export interface IAccountEventDeletedPayload { - tenantId: number; accountId: number; oldAccount: IAccount; trx: Knex.Transaction; diff --git a/packages/server/src/interfaces/AgingReport.ts b/packages/server/src/interfaces/AgingReport.ts deleted file mode 100644 index dc2a0dd1b..000000000 --- a/packages/server/src/interfaces/AgingReport.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; - -export interface IAgingPeriodTotal extends IAgingPeriod { - total: IAgingAmount; -} - -export interface IAgingAmount { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface IAgingPeriod { - fromPeriod: Date | string; - toPeriod: Date | string; - beforeDays: number; - toDays: number; -} - -export interface IAgingSummaryContact { - current: IAgingAmount; - aging: IAgingPeriodTotal[]; - total: IAgingAmount; -} - -export interface IAgingSummaryQuery { - asDate: Date | string; - agingDaysBefore: number; - agingPeriods: number; - numberFormat: INumberFormatQuery; - branchesIds: number[]; - noneZero: boolean; -} - -export interface IAgingSummaryTotal { - current: IAgingAmount; - aging: IAgingPeriodTotal[]; - total: IAgingAmount; -} - -export interface IAgingSummaryData { - total: IAgingSummaryTotal; -} - -export interface IAgingSummaryMeta extends IFinancialSheetCommonMeta { - formattedAsDate: string; - formattedDateRange: string; -} diff --git a/packages/server/src/interfaces/Attachments.ts b/packages/server/src/interfaces/Attachments.ts deleted file mode 100644 index d1699ed12..000000000 --- a/packages/server/src/interfaces/Attachments.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface AttachmentLinkDTO { - key: string; -} diff --git a/packages/server/src/interfaces/Authentication.ts b/packages/server/src/interfaces/Authentication.ts deleted file mode 100644 index aee2d3521..000000000 --- a/packages/server/src/interfaces/Authentication.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ISystemUser } from './User'; -import { ITenant } from './Tenancy'; -import { SystemUser } from '@/system/models'; - -export interface IRegisterDTO { - firstName: string; - lastName: string; - email: string; - password: string; -} - -export interface ILoginDTO { - crediential: string; - password: string; -} - -export interface IPasswordReset { - id: number; - email: string; - token: string; - createdAt: Date; -} - -export interface IAuthenticationService { - signIn( - email: string, - password: string - ): Promise<{ user: ISystemUser; token: string; tenant: ITenant }>; - register(registerDTO: IRegisterDTO): Promise; - sendResetPassword(email: string): Promise; - resetPassword(token: string, password: string): Promise; -} - -export interface IAuthSigningInEventPayload { - email: string; - password: string; - user: ISystemUser; -} - -export interface IAuthSignedInEventPayload { - email: string; - password: string; - user: ISystemUser; -} - -export interface IAuthSigningUpEventPayload { - signupDTO: IRegisterDTO; -} - -export interface IAuthSignedUpEventPayload { - signupDTO: IRegisterDTO; - tenant: ITenant; - user: ISystemUser; -} - -export interface IAuthSignInPOJO { - user: ISystemUser; - token: string; - tenant: ITenant; -} - -export interface IAuthResetedPasswordEventPayload { - user: SystemUser; - token: string; - password: string; -} - -export interface IAuthSendingResetPassword { - user: ISystemUser; - token: string; -} -export interface IAuthSendedResetPassword { - user: ISystemUser; - token: string; -} - -export interface IAuthGetMetaPOJO { - signupDisabled: boolean; - oneClickDemo: { - enable: boolean; - demoUrl: string; - }; -} - -export interface IAuthSignUpVerifingEventPayload { - email: string; - verifyToken: string; - userId: number; -} - -export interface IAuthSignUpVerifiedEventPayload { - email: string; - verifyToken: string; - userId: number; -} diff --git a/packages/server/src/interfaces/BalanceSheet.ts b/packages/server/src/interfaces/BalanceSheet.ts deleted file mode 100644 index 567cb8764..000000000 --- a/packages/server/src/interfaces/BalanceSheet.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { - INumberFormatQuery, - IFormatNumberSettings, - IFinancialSheetBranchesQuery, - IFinancialSheetCommonMeta, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -// Balance sheet schema nodes types. -export enum BALANCE_SHEET_SCHEMA_NODE_TYPE { - AGGREGATE = 'AGGREGATE', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', - NET_INCOME = 'NET_INCOME', -} - -export enum BALANCE_SHEET_NODE_TYPE { - AGGREGATE = 'AGGREGATE', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', -} - -// Balance sheet schema nodes ids. -export enum BALANCE_SHEET_SCHEMA_NODE_ID { - ASSETS = 'ASSETS', - CURRENT_ASSETS = 'CURRENT_ASSETS', - CASH_EQUIVALENTS = 'CASH_EQUIVALENTS', - ACCOUNTS_RECEIVABLE = 'ACCOUNTS_RECEIVABLE', - NON_CURRENT_ASSET = 'NON_CURRENT_ASSET', - FIXED_ASSET = 'FIXED_ASSET', - OTHER_CURRENT_ASSET = 'OTHER_CURRENT_ASSET', - INVENTORY = 'INVENTORY', - LIABILITY_EQUITY = 'LIABILITY_EQUITY', - LIABILITY = 'LIABILITY', - CURRENT_LIABILITY = 'CURRENT_LIABILITY', - LOGN_TERM_LIABILITY = 'LOGN_TERM_LIABILITY', - NON_CURRENT_LIABILITY = 'NON_CURRENT_LIABILITY', - EQUITY = 'EQUITY', - NET_INCOME = 'NET_INCOME', -} - -// Balance sheet query. -export interface IBalanceSheetQuery extends IFinancialSheetBranchesQuery { - displayColumnsType: 'total' | 'date_periods'; - displayColumnsBy: string; - fromDate: Date; - toDate: Date; - numberFormat: INumberFormatQuery; - noneTransactions: boolean; - noneZero: boolean; - basis: 'cash' | 'accrual'; - accountIds: number[]; - - percentageOfColumn: boolean; - percentageOfRow: boolean; - - previousPeriod: boolean; - previousPeriodAmountChange: boolean; - previousPeriodPercentageChange: boolean; - - previousYear: boolean; - previousYearAmountChange: boolean; - previousYearPercentageChange: boolean; -} - -// Balance sheet meta. -export interface IBalanceSheetMeta extends IFinancialSheetCommonMeta { - formattedAsDate: string; - formattedDateRange: string; -} - -export interface IBalanceSheetFormatNumberSettings - extends IFormatNumberSettings { - type: string; -} - -// Balance sheet service. -export interface IBalanceSheetStatementService { - balanceSheet( - tenantId: number, - query: IBalanceSheetQuery - ): Promise; -} - -export type IBalanceSheetStatementData = IBalanceSheetDataNode[]; - -export interface IBalanceSheetDOO { - query: IBalanceSheetQuery; - data: IBalanceSheetStatementData; - meta: IBalanceSheetMeta; -} - -export interface IBalanceSheetCommonNode { - total: IBalanceSheetTotal; - horizontalTotals?: IBalanceSheetTotal[]; - - percentageRow?: IBalanceSheetPercentageAmount; - percentageColumn?: IBalanceSheetPercentageAmount; - - previousPeriod?: IBalanceSheetTotal; - previousPeriodChange?: IBalanceSheetTotal; - previousPeriodPercentage?: IBalanceSheetPercentageAmount; - - previousYear?: IBalanceSheetTotal; - previousYearChange?: IBalanceSheetTotal; - previousYearPercentage?: IBalanceSheetPercentageAmount; -} - -export interface IBalanceSheetAggregateNode extends IBalanceSheetCommonNode { - id: string; - name: string; - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE; - children?: IBalanceSheetDataNode[]; -} - -export interface IBalanceSheetTotal { - amount: number; - formattedAmount: string; - currencyCode: string; - date?: string | Date; -} - -export interface IBalanceSheetAccountsNode extends IBalanceSheetCommonNode { - id: number | string; - name: string; - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS; - children: IBalanceSheetAccountNode[]; -} - -export interface IBalanceSheetAccountNode extends IBalanceSheetCommonNode { - id: number; - index: number; - name: string; - code: string; - parentAccountId?: number; - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT; - children?: IBalanceSheetAccountNode[]; -} - -export interface IBalanceSheetNetIncomeNode extends IBalanceSheetCommonNode { - id: number; - name: string; - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME; -} - -export type IBalanceSheetDataNode = - | IBalanceSheetAggregateNode - | IBalanceSheetAccountNode - | IBalanceSheetAccountsNode - | IBalanceSheetNetIncomeNode; - -export interface IBalanceSheetPercentageAmount { - amount: number; - formattedAmount: string; -} - -export interface IBalanceSheetSchemaAggregateNode { - name: string; - id: string; - type: BALANCE_SHEET_SCHEMA_NODE_TYPE; - children: IBalanceSheetSchemaNode[]; - alwaysShow: boolean; -} - -export interface IBalanceSheetSchemaAccountNode { - name: string; - id: string; - type: BALANCE_SHEET_SCHEMA_NODE_TYPE; - accountsTypes: string[]; -} - -export interface IBalanceSheetSchemaNetIncomeNode { - id: string; - name: string; - type: BALANCE_SHEET_SCHEMA_NODE_TYPE; -} - -export type IBalanceSheetSchemaNode = - | IBalanceSheetSchemaAccountNode - | IBalanceSheetSchemaAggregateNode - | IBalanceSheetSchemaNetIncomeNode; - -export interface IBalanceSheetDatePeriods { - assocAccountNodeDatePeriods(node): any; - initDateRangeCollection(): void; -} - -export interface IBalanceSheetComparsions { - assocPreviousYearAccountNode(node); - hasPreviousPeriod(): boolean; - hasPreviousYear(): boolean; - assocPreviousPeriodAccountNode(node); -} - -export interface IBalanceSheetTotalPeriod extends IFinancialSheetTotalPeriod { - percentageRow?: IBalanceSheetPercentageAmount; - percentageColumn?: IBalanceSheetPercentageAmount; -} - -export interface IFinancialSheetTotalPeriod { - fromDate: any; - toDate: any; - total: any; -} - -export enum IFinancialDatePeriodsUnit { - Day = 'day', - Month = 'month', - Year = 'year', -} - -export enum IAccountTransactionsGroupBy { - Quarter = 'quarter', - Year = 'year', - Day = 'day', - Month = 'month', - Week = 'week', -} - -export interface IBalanceSheetTable extends IFinancialTable { - meta: IBalanceSheetMeta; - query: IBalanceSheetQuery; -} diff --git a/packages/server/src/interfaces/Bill.ts b/packages/server/src/interfaces/Bill.ts deleted file mode 100644 index 6e5391ee8..000000000 --- a/packages/server/src/interfaces/Bill.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { Knex } from 'knex'; -import { IDynamicListFilterDTO } from './DynamicFilter'; -import { IItemEntry, IItemEntryDTO } from './ItemEntry'; -import { IBillLandedCost } from './LandedCost'; -import { AttachmentLinkDTO } from './Attachments'; -import { DiscountType } from './SaleInvoice'; - -export interface IBillDTO { - vendorId: number; - billNumber: string; - billDate: Date; - dueDate: Date; - referenceNo: string; - status: string; - note: string; - amount: number; - paymentAmount: number; - exchangeRate?: number; - open: boolean; - entries: IItemEntryDTO[]; - branchId?: number; - warehouseId?: number; - projectId?: number; - isInclusiveTax?: boolean; - attachments?: AttachmentLinkDTO[]; - - // # Discount - discount?: number; - discountType?: DiscountType; - - // # Adjustment - adjustment?: number; -} - -export interface IBillEditDTO { - vendorId: number; - billNumber: string; - billDate: Date; - dueDate: Date; - referenceNo: string; - status: string; - note: string; - amount: number; - paymentAmount: number; - open: boolean; - entries: IItemEntryDTO[]; - - branchId?: number; - warehouseId?: number; - projectId?: number; - attachments?: AttachmentLinkDTO[]; -} - -export interface IBill { - id?: number; - - vendorId: number; - billNumber: string; - billDate: Date; - dueDate: Date; - referenceNo: string; - status: string; - note: string; - - amount: number; - allocatedCostAmount: number; - landedCostAmount: number; - unallocatedCostAmount: number; - - paymentAmount: number; - currencyCode: string; - exchangeRate: number; - - dueAmount: number; - overdueDays: number; - - billableAmount: number; - invoicedAmount: number; - - openedAt: Date | string; - - entries: IItemEntry[]; - - createdAt: Date; - updateAt: Date; - - isOpen: boolean; - - userId?: number; - branchId?: number; - projectId?: number; - - localAmount?: number; - locatedLandedCosts?: IBillLandedCost[]; - - amountLocal: number; - subtotal: number; - subtotalLocal: number; - subtotalExcludingTax: number; - taxAmountWithheld: number; - taxAmountWithheldLocal: number; - total: number; - totalLocal: number; -} - -export interface IBillsFilter extends IDynamicListFilterDTO { - stringifiedFilterRoles?: string; - page: number; - pageSize: number; - filterQuery?: (q: any) => void; -} - -export interface IBillsService { - validateVendorHasNoBills(tenantId: number, vendorId: number): Promise; -} - -export interface IBillCreatedPayload { - tenantId: number; - bill: IBill; - billDTO: IBillDTO; - billId: number; - trx: Knex.Transaction; -} - -export interface IBillCreatingPayload { - tenantId: number; - billDTO: IBillDTO; - trx: Knex.Transaction; -} - -export interface IBillEditingPayload { - tenantId: number; - oldBill: IBill; - billDTO: IBillEditDTO; - trx: Knex.Transaction; -} -export interface IBillEditedPayload { - tenantId: number; - billId: number; - oldBill: IBill; - bill: IBill; - billDTO: IBillDTO; - trx: Knex.Transaction; -} - -export interface IBIllEventDeletedPayload { - tenantId: number; - billId: number; - oldBill: IBill; - trx: Knex.Transaction; -} - -export interface IBillEventDeletingPayload { - tenantId: number; - oldBill: IBill; - trx: Knex.Transaction; -} -export enum BillAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - NotifyBySms = 'NotifyBySms', -} - -export interface IBillOpeningPayload { - trx: Knex.Transaction; - tenantId: number; - oldBill: IBill; -} - -export interface IBillOpenedPayload { - trx: Knex.Transaction; - bill: IBill; - oldBill: IBill; - tenantId: number; -} diff --git a/packages/server/src/interfaces/BillPayment.ts b/packages/server/src/interfaces/BillPayment.ts deleted file mode 100644 index 002bf867b..000000000 --- a/packages/server/src/interfaces/BillPayment.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Knex } from 'knex'; -import { IBill } from './Bill'; -import { AttachmentLinkDTO } from './Attachments'; - -export interface IBillPaymentEntry { - id?: number; - billPaymentId: number; - billId: number; - paymentAmount: number; - - bill?: IBill; -} - -export interface IBillPayment { - id?: number; - vendorId: number; - amount: number; - currencyCode: string; - reference: string; - paymentAccountId: number; - paymentNumber: string; - paymentDate: Date; - exchangeRate: number | null; - userId: number; - entries: IBillPaymentEntry[]; - statement: string; - createdAt: Date; - updatedAt: Date; - - localAmount?: number; - branchId?: number; -} - -export interface IBillPaymentEntryDTO { - billId: number; - paymentAmount: number; -} - -export interface IBillPaymentDTO { - vendorId: number; - paymentAccountId: number; - paymentNumber?: string; - paymentDate: Date; - exchangeRate?: number; - statement: string; - reference: string; - entries: IBillPaymentEntryDTO[]; - branchId?: number; - attachments?: AttachmentLinkDTO[]; -} - -export interface IBillReceivePageEntry { - billId: number; - entryType: string; - billNo: string; - dueAmount: number; - amount: number; - totalPaymentAmount: number; - paymentAmount: number; - currencyCode: string; - date: Date | string; -} - -export interface IBillPaymentsService { - validateVendorHasNoPayments(tenantId: number, vendorId): Promise; -} - -export interface IBillPaymentEventCreatedPayload { - tenantId: number; - billPayment: IBillPayment; - billPaymentDTO: IBillPaymentDTO; - billPaymentId: number; - trx: Knex.Transaction; -} - -export interface IBillPaymentCreatingPayload { - tenantId: number; - billPaymentDTO: IBillPaymentDTO; - trx: Knex.Transaction; -} - -export interface IBillPaymentEditingPayload { - tenantId: number; - billPaymentDTO: IBillPaymentDTO; - oldBillPayment: IBillPayment; - trx: Knex.Transaction; -} -export interface IBillPaymentEventEditedPayload { - tenantId: number; - billPaymentId: number; - billPayment: IBillPayment; - oldBillPayment: IBillPayment; - billPaymentDTO: IBillPaymentDTO; - trx: Knex.Transaction; -} - -export interface IBillPaymentEventDeletedPayload { - tenantId: number; - billPaymentId: number; - oldBillPayment: IBillPayment; - trx: Knex.Transaction; -} - -export interface IBillPaymentDeletingPayload { - tenantId: number; - oldBillPayment: IBillPayment; - trx: Knex.Transaction; -} - -export interface IBillPaymentPublishingPayload { - tenantId: number; - oldBillPayment: IBillPayment; - trx: Knex.Transaction; -} - -export enum IPaymentMadeAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', -} diff --git a/packages/server/src/interfaces/Branches.ts b/packages/server/src/interfaces/Branches.ts deleted file mode 100644 index 671de6563..000000000 --- a/packages/server/src/interfaces/Branches.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Knex } from 'knex'; - -export interface IBranch { - id?: number; -} - -export interface ICreateBranchDTO { - name: string; - code: string; - - primary?: boolean; -} -export interface IEditBranchDTO { - code: string; -} - -export interface IBranchCreatePayload { - tenantId: number; - createBranchDTO: ICreateBranchDTO; - trx: Knex.Transaction; -} -export interface IBranchCreatedPayload {} - -export interface IBranchEditPayload {} -export interface IBranchEditedPayload {} - -export interface IBranchDeletePayload {} -export interface IBranchDeletedPayload {} - -export interface IBranchesActivatePayload { - tenantId: number; - trx: Knex.Transaction; -} -export interface IBranchesActivatedPayload { - tenantId: number; - primaryBranch: IBranch; - trx: Knex.Transaction; -} - -export interface IBranchMarkAsPrimaryPayload { - tenantId: number; - oldBranch: IBranch; - trx: Knex.Transaction; -} -export interface IBranchMarkedAsPrimaryPayload { - tenantId: number; - oldBranch: IBranch; - markedBranch: IBranch; - trx: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/CashFlow.ts b/packages/server/src/interfaces/CashFlow.ts deleted file mode 100644 index 0b3298929..000000000 --- a/packages/server/src/interfaces/CashFlow.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { Knex } from 'knex'; -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IAccount } from './Account'; -import { ILedger } from './Ledger'; -import { IFinancialTable, ITableRow } from './Table'; - -export interface ICashFlowStatementQuery { - fromDate: Date | string; - toDate: Date | string; - displayColumnsBy: string; - displayColumnsType: string; - noneZero: boolean; - noneTransactions: boolean; - numberFormat: INumberFormatQuery; - basis: string; - - branchesIds?: number[]; -} - -export interface ICashFlowStatementTotal { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface ICashFlowStatementTotalPeriod { - fromDate: Date; - toDate: Date; - total: ICashFlowStatementTotal; -} - -export interface ICashFlowStatementCommonSection { - id: string; - label: string; - total: ICashFlowStatementTotal; - footerLabel?: string; -} - -export interface ICashFlowStatementAccountMeta { - id: number; - label: string; - code: string; - total: ICashFlowStatementTotal; - accountType: string; - adjustmentType: string; - sectionType: ICashFlowStatementSectionType.ACCOUNT; -} - -export enum ICashFlowStatementSectionType { - REGULAR = 'REGULAR', - AGGREGATE = 'AGGREGATE', - NET_INCOME = 'NET_INCOME', - ACCOUNT = 'ACCOUNT', - ACCOUNTS = 'ACCOUNTS', - TOTAL = 'TOTAL', - CASH_AT_BEGINNING = 'CASH_AT_BEGINNING', -} - -export interface ICashFlowStatementAccountSection - extends ICashFlowStatementCommonSection { - sectionType: ICashFlowStatementSectionType.ACCOUNTS; - children: ICashFlowStatementAccountMeta[]; - total: ICashFlowStatementTotal; -} - -export interface ICashFlowStatementNetIncomeSection - extends ICashFlowStatementCommonSection { - sectionType: ICashFlowStatementSectionType.NET_INCOME; -} - -export interface ICashFlowStatementTotalSection - extends ICashFlowStatementCommonSection { - sectionType: ICashFlowStatementSectionType.TOTAL; -} - -export interface ICashFlowStatementAggregateSection - extends ICashFlowStatementCommonSection { - sectionType: ICashFlowStatementSectionType.AGGREGATE; -} - -export interface ICashFlowCashBeginningNode - extends ICashFlowStatementCommonSection { - sectionType: ICashFlowStatementSectionType.CASH_AT_BEGINNING; -} - -export type ICashFlowStatementSection = - | ICashFlowStatementAccountSection - | ICashFlowStatementNetIncomeSection - | ICashFlowStatementTotalSection - | ICashFlowStatementCommonSection; - -export interface ICashFlowStatementColumn {} -export interface ICashFlowStatementMeta extends IFinancialSheetCommonMeta { - formattedToDate: string; - formattedFromDate: string; - formattedDateRange: string; -} - -export interface ICashFlowStatementDOO { - data: ICashFlowStatementData; - meta: ICashFlowStatementMeta; - query: ICashFlowStatementQuery; -} - -export interface ICashFlowStatementTable extends IFinancialTable { - meta: ICashFlowStatementMeta; - query: ICashFlowStatementQuery; -} - -export interface ICashFlowStatementService { - cashFlow( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise; -} - -// CASH FLOW SCHEMA TYPES. -// ----------------------------- -export interface ICashFlowSchemaCommonSection { - id: string; - label: string; - children: ICashFlowSchemaSection[]; - footerLabel?: string; -} - -export enum CASH_FLOW_ACCOUNT_RELATION { - MINES = 'mines', - PLUS = 'plus', -} - -export enum CASH_FLOW_SECTION_ID { - NET_INCOME = 'NET_INCOME', - OPERATING = 'OPERATING', - OPERATING_ACCOUNTS = 'OPERATING_ACCOUNTS', - INVESTMENT = 'INVESTMENT', - FINANCIAL = 'FINANCIAL', - - NET_OPERATING = 'NET_OPERATING', - NET_INVESTMENT = 'NET_INVESTMENT', - NET_FINANCIAL = 'NET_FINANCIAL', - - CASH_BEGINNING_PERIOD = 'CASH_BEGINNING_PERIOD', - CASH_END_PERIOD = 'CASH_END_PERIOD', - NET_CASH_INCREASE = 'NET_CASH_INCREASE', -} - -export interface ICashFlowSchemaAccountsSection - extends ICashFlowSchemaCommonSection { - sectionType: ICashFlowStatementSectionType.ACCOUNT; - accountsRelations: ICashFlowSchemaAccountRelation[]; -} - -export interface ICashFlowSchemaTotalSection - extends ICashFlowStatementCommonSection { - sectionType: ICashFlowStatementSectionType.TOTAL; - equation: string; -} - -export type ICashFlowSchemaSection = - | ICashFlowSchemaAccountsSection - | ICashFlowSchemaTotalSection - | ICashFlowSchemaCommonSection; - -export type ICashFlowStatementData = ICashFlowSchemaSection[]; - -export interface ICashFlowSchemaAccountRelation { - type: string; - direction: CASH_FLOW_ACCOUNT_RELATION.PLUS; -} - -export interface ICashFlowSchemaSectionAccounts - extends ICashFlowStatementCommonSection { - type: ICashFlowStatementSectionType.ACCOUNT; - accountsRelations: ICashFlowSchemaAccountRelation[]; -} - -export interface ICashFlowSchemaSectionTotal { - type: ICashFlowStatementSectionType.TOTAL; - totalEquation: string; -} - -export interface ICashFlowDatePeriod { - fromDate: ICashFlowDate; - toDate: ICashFlowDate; - total: ICashFlowStatementTotal; -} - -export interface ICashFlowDate { - formattedDate: string; - date: Date; -} - -export interface ICashFlowStatement { - /** - * Constructor method. - * @constructor - */ - constructor( - accounts: IAccount[], - ledger: ILedger, - cashLedger: ILedger, - netIncomeLedger: ILedger, - query: ICashFlowStatementQuery, - baseCurrency: string - ): void; - - reportData(): ICashFlowStatementData; -} - -export interface ICashFlowTable { - constructor(reportStatement: ICashFlowStatement): void; - tableRows(): ITableRow[]; -} - -export interface IDateRange { - fromDate: Date; - toDate: Date; -} - -export interface ICashflowTransactionSchema { - amount: number; - date: Date; - referenceNo?: string | null; - transactionNumber: string; - transactionType: string; - creditAccountId: number; - cashflowAccountId: number; - userId: number; - publishedAt?: Date | null; - branchId?: number; -} - -export interface ICashflowTransactionInput extends ICashflowTransactionSchema {} - -export interface ICategorizeCashflowTransactioDTO { - date: Date; - creditAccountId: number; - referenceNo: string; - transactionNumber: string; - transactionType: string; - exchangeRate: number; - description: string; - branchId: number; -} - -export interface IUncategorizedCashflowTransaction { - id?: number; - amount: number; - date: Date; - currencyCode: string; - accountId: number; - description: string; - referenceNo: string; - categorizeRefType: string; - categorizeRefId: number; - categorized: boolean; -} - -export interface CreateUncategorizedTransactionDTO { - date: Date | string; - accountId: number; - amount: number; - currencyCode: string; - payee?: string; - description?: string; - referenceNo?: string | null; - plaidTransactionId?: string | null; - pending?: boolean; - pendingPlaidTransactionId?: string | null; - batch?: string; -} - -export interface IUncategorizedTransactionCreatingEventPayload { - tenantId: number; - createUncategorizedTransactionDTO: CreateUncategorizedTransactionDTO; - trx: Knex.Transaction; -} - -export interface IUncategorizedTransactionCreatedEventPayload { - tenantId: number; - uncategorizedTransaction: any; - createUncategorizedTransactionDTO: CreateUncategorizedTransactionDTO; - trx: Knex.Transaction; -} - -export interface IPendingTransactionRemovingEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - pendingTransaction: IUncategorizedCashflowTransaction; - trx?: Knex.Transaction; -} - -export interface IPendingTransactionRemovedEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - pendingTransaction: IUncategorizedCashflowTransaction; - trx?: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/CashflowService.ts b/packages/server/src/interfaces/CashflowService.ts deleted file mode 100644 index 9c2a68909..000000000 --- a/packages/server/src/interfaces/CashflowService.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { Knex } from 'knex'; -import { IAccount } from './Account'; -import { IUncategorizedCashflowTransaction } from './CashFlow'; - -export interface ICashflowAccountTransactionsFilter { - page: number; - pageSize: number; -} - -export interface ICashflowAccountsFilter { - inactiveMode: boolean; - stringifiedFilterRoles?: string; - sortOrder: string; - columnSortBy: string; -} - -export interface ICashflowAccount { - id: number; - name: string; - balance: number; - formattedBalance: string; - accountType: string; -} - -interface ICashflowCommandLineDTO { - creditAccountId: number; - cashflowAccountId: number; - amount: number; - index: number; -} - -export interface ICashflowCommandDTO { - date: Date; - - transactionNumber: string; - referenceNo: string; - transactionType: string; - description: string; - - amount: number; - exchangeRate: number; - currencyCode: string; - - creditAccountId: number; - cashflowAccountId: number; - - publish: boolean; - branchId?: number; - plaidTransactionId?: string; -} - -export interface ICashflowNewCommandDTO extends ICashflowCommandDTO { - plaidAccountId?: string; - uncategorizedTransactionId?: number; -} - -export interface ICashflowTransaction { - id?: number; - date: Date; - - referenceNo: string; - description: string; - - transactionType: string; - transactionNumber: string; - - amount: number; - localAmount?: number; - currencyCode: string; - exchangeRate: number; - - publishedAt?: Date | null; - userId: number; - entries: ICashflowTransactionLine[]; - - creditAccountId: number; - cashflowAccountId: number; - - creditAccount?: IAccount; - cashflowAccount?: IAccount; - - branchId?: number; - isPublished: boolean; - - isCashDebit?: boolean; - isCashCredit?: boolean; - - uncategorizedTransactionId?: number; -} - -export interface ICashflowTransactionLine { - creditAccountId: number; - cashflowAccountId: number; - amount: number; - index: number; - - creditAccount?: IAccount; -} - -export enum CashflowDirection { - IN = 'in', - OUT = 'out', -} - -export interface ICommandCashflowCreatingPayload { - tenantId: number; - trx: Knex.Transaction; - newTransactionDTO: ICashflowNewCommandDTO; -} - -export interface ICommandCashflowCreatedPayload { - tenantId: number; - newTransactionDTO: ICashflowNewCommandDTO; - cashflowTransaction: ICashflowTransaction; - trx: Knex.Transaction; -} - -export interface ICommandCashflowDeletingPayload { - tenantId: number; - oldCashflowTransaction: ICashflowTransaction; - trx: Knex.Transaction; -} - -export interface ICommandCashflowDeletedPayload { - tenantId: number; - cashflowTransactionId: number; - oldCashflowTransaction: ICashflowTransaction; - trx: Knex.Transaction; -} - -export interface ICashflowTransactionCategorizedPayload { - tenantId: number; - uncategorizedTransactions: Array; - cashflowTransaction: ICashflowTransaction; - oldUncategorizedTransactions: Array; - categorizeDTO: any; - trx: Knex.Transaction; -} -export interface ICashflowTransactionUncategorizingPayload { - tenantId: number; - uncategorizedTransactionId: number; - oldUncategorizedTransactions: Array; - trx: Knex.Transaction; -} -export interface ICashflowTransactionUncategorizedPayload { - tenantId: number; - uncategorizedTransactionId: number; - uncategorizedTransactions: Array; - oldMainUncategorizedTransaction: IUncategorizedCashflowTransaction; - oldUncategorizedTransactions: Array; - trx: Knex.Transaction; -} - -export enum CashflowAction { - Create = 'Create', - Delete = 'Delete', - View = 'View', -} - -export interface CategorizeTransactionAsExpenseDTO { - expenseAccountId: number; - exchangeRate: number; - referenceNo: string; - description: string; - branchId?: number; -} - -export interface IGetUncategorizedTransactionsQuery { - page?: number; - pageSize?: number; - minDate?: Date; - maxDate?: Date; - minAmount?: number; - maxAmount?: number; -} - -export interface IGetRecognizedTransactionsQuery { - page?: number; - pageSize?: number; - accountId?: number; - minDate?: Date; - maxDate?: Date; - minAmount?: number; - maxAmount?: number; -} diff --git a/packages/server/src/interfaces/Contact.ts b/packages/server/src/interfaces/Contact.ts deleted file mode 100644 index 1b3b555ea..000000000 --- a/packages/server/src/interfaces/Contact.ts +++ /dev/null @@ -1,392 +0,0 @@ -import { ISystemUser } from '@/interfaces'; -import { Knex } from 'knex'; -import { IFilterRole } from './DynamicFilter'; - -export enum ContactService { - Customer = 'customer', - Vendor = 'vendor', -} - -// ---------------------------------- -export interface IContactAddress { - billingAddress1: string; - billingAddress2: string; - billingAddressCity: string; - billingAddressCountry: string; - billingAddressEmail: string; - billingAddressZipcode: string; - billingAddressPhone: string; - billingAddressState: string; - - shippingAddress1: string; - shippingAddress2: string; - shippingAddressCity: string; - shippingAddressCountry: string; - shippingAddressEmail: string; - shippingAddressZipcode: string; - shippingAddressPhone: string; - shippingAddressState: string; -} -export interface IContactAddressDTO { - billingAddress1?: string; - billingAddress2?: string; - billingAddressCity?: string; - billingAddressCountry?: string; - billingAddressEmail?: string; - billingAddressZipcode?: string; - billingAddressPhone?: string; - billingAddressState?: string; - - shippingAddress1?: string; - shippingAddress2?: string; - shippingAddressCity?: string; - shippingAddressCountry?: string; - shippingAddressEmail?: string; - shippingAddressZipcode?: string; - shippingAddressPhone?: string; - shippingAddressState?: string; -} -export interface IContact extends IContactAddress { - id?: number; - contactService: 'customer' | 'vendor'; - contactType: string; - - balance: number; - currencyCode: string; - - openingBalance: number; - openingBalanceExchangeRate: number; - localOpeningBalance?: number; - openingBalanceAt: Date; - openingBalanceBranchId: number; - - salutation: string; - firstName: string; - lastName: string; - companyName: string; - displayName: string; - - email: string; - website: string; - workPhone: string; - personalPhone: string; - - note: string; - active: boolean; -} -export interface IContactNewDTO { - contactType?: string; - - currencyCode?: string; - - openingBalance?: number; - openingBalanceAt?: string; - - salutation?: string; - firstName?: string; - lastName?: string; - companyName?: string; - displayName: string; - - website?: string; - email?: string; - workPhone?: string; - personalPhone?: string; - - note?: string; - active: boolean; -} -export interface IContactEditDTO { - contactType?: string; - - salutation?: string; - firstName?: string; - lastName?: string; - companyName?: string; - displayName: string; - - website?: string; - email?: string; - workPhone?: string; - personalPhone?: string; - - note?: string; - active: boolean; -} - -// Customer Interfaces. -// ---------------------------------- -export interface ICustomer extends IContact { - contactService: 'customer'; -} -export interface ICustomerNewDTO extends IContactAddressDTO { - customerType: string; - - currencyCode: string; - - openingBalance?: number; - openingBalanceAt?: string; - openingBalanceExchangeRate?: number; - openingBalanceBranchId?: number; - - salutation?: string; - firstName?: string; - lastName?: string; - companyName?: string; - displayName: string; - - website?: string; - email?: string; - workPhone?: string; - personalPhone?: string; - - note?: string; - active?: boolean; -} -export interface ICustomerEditDTO extends IContactAddressDTO { - customerType: string; - - salutation?: string; - firstName?: string; - lastName?: string; - companyName?: string; - displayName: string; - - website?: string; - email?: string; - workPhone?: string; - personalPhone?: string; - - note?: string; - active?: boolean; -} - -// Vendor Interfaces. -// ---------------------------------- -export interface IVendor extends IContact { - contactService: 'vendor'; -} -export interface IVendorNewDTO extends IContactAddressDTO { - currencyCode: string; - - openingBalance?: number; - openingBalanceAt?: string; - openingBalanceExchangeRate?: number; - openingBalanceBranchId?: number; - - salutation?: string; - firstName?: string; - lastName?: string; - companyName?: string; - displayName: string; - - website?: string; - email?: string; - workPhone?: string; - personalPhone?: string; - - note?: string; - active?: boolean; -} -export interface IVendorEditDTO extends IContactAddressDTO { - salutation?: string; - firstName?: string; - lastName?: string; - companyName?: string; - displayName?: string; - - website?: string; - email?: string; - workPhone?: string; - personalPhone?: string; - - note?: string; - active?: boolean; -} - -export interface IVendorsFilter extends IDynamicListFilter { - stringifiedFilterRoles?: string; - page?: number; - pageSize?: number; -} - -export interface ICustomersFilter extends IDynamicListFilter { - stringifiedFilterRoles?: string; - page?: number; - pageSize?: number; -} - -export interface IContactsAutoCompleteFilter { - limit: number; - keyword: string; - filterRoles?: IFilterRole[]; - columnSortBy: string; - sortOrder: string; -} - -export interface IContactAutoCompleteItem { - displayName: string; - contactService: string; -} -export interface ICustomerEventCreatedPayload { - tenantId: number; - customerId: number; - authorizedUser: ISystemUser; - customer: ICustomer; - trx: Knex.Transaction; -} -export interface ICustomerEventCreatingPayload { - tenantId: number; - customerDTO: ICustomerNewDTO; - trx: Knex.Transaction; -} -export interface ICustomerEventEditedPayload { - tenantId: number - customerId: number; - customer: ICustomer; - trx: Knex.Transaction; -} - -export interface ICustomerEventEditingPayload { - tenantId: number; - customerDTO: ICustomerEditDTO; - customerId: number; - trx: Knex.Transaction; -} - -export interface ICustomerDeletingPayload { - tenantId: number; - customerId: number; - oldCustomer: ICustomer; -} - -export interface ICustomerEventDeletedPayload { - tenantId: number; - customerId: number; - oldCustomer: ICustomer; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} -export interface IVendorEventCreatingPayload { - tenantId: number; - vendorDTO: IVendorNewDTO; - trx: Knex.Transaction; -} -export interface IVendorEventCreatedPayload { - tenantId: number; - vendorId: number; - vendor: IVendor; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export interface IVendorEventDeletingPayload { - tenantId: number; - vendorId: number; - oldVendor: IVendor; -} - -export interface IVendorEventDeletedPayload { - tenantId: number; - vendorId: number; - authorizedUser: ISystemUser; - oldVendor: IVendor; - trx: Knex.Transaction; -} -export interface IVendorEventEditingPayload { - trx: Knex.Transaction; - tenantId: number; - vendorDTO: IVendorEditDTO; -} -export interface IVendorEventEditedPayload { - tenantId: number; - vendorId: number; - vendor: IVendor; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export enum CustomerAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', -} - -export enum VendorAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', -} - -export interface ICustomerOpeningBalanceEditDTO { - openingBalance: number; - openingBalanceAt: Date | string; - openingBalanceExchangeRate: number; - openingBalanceBranchId?: number; -} - -export interface ICustomerOpeningBalanceEditingPayload { - tenantId: number; - oldCustomer: ICustomer; - openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO; - trx: Knex.Transaction; -} - -export interface ICustomerOpeningBalanceEditedPayload { - tenantId: number; - customer: ICustomer; - oldCustomer: ICustomer; - openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO; - trx: Knex.Transaction; -} - -export interface IVendorOpeningBalanceEditDTO { - openingBalance: number; - openingBalanceAt: Date | string; - openingBalanceExchangeRate: number; - openingBalanceBranchId?: number; -} - -export interface IVendorOpeningBalanceEditingPayload { - tenantId: number; - oldVendor: IVendor; - openingBalanceEditDTO: IVendorOpeningBalanceEditDTO; - trx: Knex.Transaction; -} - -export interface IVendorOpeningBalanceEditedPayload { - tenantId: number; - vendor: IVendor; - oldVendor: IVendor; - openingBalanceEditDTO: IVendorOpeningBalanceEditDTO; - trx: Knex.Transaction; -} - - -export interface ICustomerActivatingPayload { - tenantId: number; - trx: Knex.Transaction, - oldCustomer: IContact; -} - -export interface ICustomerActivatedPayload { - tenantId: number; - trx: Knex.Transaction, - oldCustomer: IContact; - customer: IContact; -} - -export interface IVendorActivatingPayload { - tenantId: number; - trx: Knex.Transaction, - oldVendor: IContact; -} - -export interface IVendorActivatedPayload { - tenantId: number; - trx: Knex.Transaction, - oldVendor: IContact; - vendor: IContact; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/ContactBalanceSummary.ts b/packages/server/src/interfaces/ContactBalanceSummary.ts deleted file mode 100644 index ddefabab1..000000000 --- a/packages/server/src/interfaces/ContactBalanceSummary.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { INumberFormatQuery } from './FinancialStatements'; - -export interface IContactBalanceSummaryQuery { - asDate: Date; - numberFormat: INumberFormatQuery; - percentageColumn: boolean; - noneTransactions: boolean; - noneZero: boolean; -} - -export interface IContactBalanceSummaryAmount { - amount: number; - formattedAmount: string; - currencyCode: string; -} -export interface IContactBalanceSummaryPercentage { - amount: number; - formattedAmount: string; -} - -export interface IContactBalanceSummaryContact { - total: IContactBalanceSummaryAmount; - percentageOfColumn?: IContactBalanceSummaryPercentage; -} - -export interface IContactBalanceSummaryTotal { - total: IContactBalanceSummaryAmount; - percentageOfColumn?: IContactBalanceSummaryPercentage; -} - -export interface ICustomerBalanceSummaryData { - customers: IContactBalanceSummaryContact[]; - total: IContactBalanceSummaryTotal; -} - -export interface ICustomerBalanceSummaryStatement { - data: ICustomerBalanceSummaryData; - columns: {}; - query: IContactBalanceSummaryQuery; -} - -export interface ICustomerBalanceSummaryService { - customerBalanceSummary( - tenantId: number, - query: IContactBalanceSummaryQuery - ): Promise; -} diff --git a/packages/server/src/interfaces/CreditNote.ts b/packages/server/src/interfaces/CreditNote.ts deleted file mode 100644 index 4f0944aaa..000000000 --- a/packages/server/src/interfaces/CreditNote.ts +++ /dev/null @@ -1,323 +0,0 @@ -import { Knex } from 'knex'; -import { DiscountType, IDynamicListFilter, IItemEntry } from '@/interfaces'; -import { ILedgerEntry } from './Ledger'; -import { AttachmentLinkDTO } from './Attachments'; - -export interface ICreditNoteEntryNewDTO { - index?: number; - itemId: number; - rate: number; - quantity: number; - discount: number; - description: string; - warehouseId?: number; -} -export interface ICreditNoteNewDTO { - customerId: number; - exchangeRate?: number; - creditNoteDate: Date; - creditNoteNumber: string; - note: string; - open: boolean; - entries: ICreditNoteEntryNewDTO[]; - branchId?: number; - warehouseId?: number; - attachments?: AttachmentLinkDTO[]; - discount?: number; - discountType?: DiscountType; - adjustment?: number; -} - -export interface ICreditNoteEditDTO { - customerId: number; - exchangeRate?: number; - creditNoteDate: Date; - creditNoteNumber: string; - note: string; - open: boolean; - entries: ICreditNoteEntryNewDTO[]; - branchId?: number; - warehouseId?: number; - attachments?: AttachmentLinkDTO[]; -} - -export interface ICreditNoteEntry extends IItemEntry {} - -export interface ICreditNote { - id?: number; - customerId: number; - amount: number; - refundedAmount: number; - currencyCode: string; - exchangeRate: number; - creditNoteDate: Date; - creditNoteNumber: string; - referenceNo?: string; - note?: string; - openedAt: Date | null; - entries: ICreditNoteEntry[]; - isOpen: boolean; - isClosed: boolean; - isDraft: boolean; - isPublished: boolean; - creditsRemaining: number; - localAmount?: number; - branchId?: number; - warehouseId: number; - createdAt?: Date; - termsConditions: string; - note: string; -} - -export enum CreditNoteAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - Refund = 'Refund', -} - -export interface ICreditNoteDeletingPayload { - tenantId: number; - oldCreditNote: ICreditNote; - trx: Knex.Transaction; -} - -export interface ICreditNoteDeletedPayload { - tenantId: number; - oldCreditNote: ICreditNote; - creditNoteId: number; - trx: Knex.Transaction; -} - -export interface ICreditNoteEditingPayload { - trx: Knex.Transaction; - oldCreditNote: ICreditNote; - creditNoteEditDTO: ICreditNoteEditDTO; - tenantId: number; -} - -export interface ICreditNoteEditedPayload { - trx: Knex.Transaction; - oldCreditNote: ICreditNote; - creditNoteId: number; - creditNote: ICreditNote; - creditNoteEditDTO: ICreditNoteEditDTO; - tenantId: number; -} - -export interface ICreditNoteCreatedPayload { - tenantId: number; - creditNoteDTO: ICreditNoteNewDTO; - creditNote: ICreditNote; - creditNoteId: number; - trx: Knex.Transaction; -} - -export interface ICreditNoteCreatingPayload { - tenantId: number; - creditNoteDTO: ICreditNoteNewDTO; - trx: Knex.Transaction; -} - -export interface ICreditNoteOpeningPayload { - tenantId: number; - creditNoteId: number; - oldCreditNote: ICreditNote; - trx: Knex.Transaction; -} - -export interface ICreditNoteOpenedPayload { - tenantId: number; - creditNote: ICreditNote; - creditNoteId: number; - oldCreditNote: ICreditNote; - trx: Knex.Transaction; -} - -export interface ICreditNotesQueryDTO { - filterQuery?: (query: any) => void; -} - -export interface ICreditNotesQueryDTO extends IDynamicListFilter { - page: number; - pageSize: number; - searchKeyword?: string; -} - -export interface ICreditNoteRefundDTO { - fromAccountId: number; - amount: number; - exchangeRate?: number; - referenceNo: string; - description: string; - date: Date; - branchId?: number; -} - -export interface ICreditNoteApplyInvoiceDTO { - entries: { invoiceId: number; amount: number }[]; -} - -export interface IRefundCreditNote { - id?: number | null; - date: Date; - referenceNo: string; - amount: number; - currencyCode: string; - exchangeRate: number; - fromAccountId: number; - description: string; - creditNoteId: number; - createdAt?: Date | null; - userId?: number; - branchId?: number; - - creditNote?: ICreditNote; -} - -export interface IRefundCreditNotePOJO { - formattedAmount: string; -} - -export interface IRefundCreditNoteDeletedPayload { - trx: Knex.Transaction; - refundCreditId: number; - oldRefundCredit: IRefundCreditNote; - tenantId: number; -} - -export interface IRefundCreditNoteDeletingPayload { - trx: Knex.Transaction; - refundCreditId: number; - oldRefundCredit: IRefundCreditNote; - tenantId: number; -} - -export interface IRefundCreditNoteCreatingPayload { - trx: Knex.Transaction; - creditNote: ICreditNote; - tenantId: number; - newCreditNoteDTO: ICreditNoteRefundDTO; -} - -export interface IRefundCreditNoteCreatedPayload { - trx: Knex.Transaction; - refundCreditNote: IRefundCreditNote; - creditNote: ICreditNote; - tenantId: number; -} - -export interface IRefundCreditNoteOpenedPayload { - tenantId: number; - creditNoteId: number; - oldCreditNote: ICreditNote; - trx: Knex.Transaction; -} - -export interface IApplyCreditToInvoiceEntryDTO { - amount: number; - invoiceId: number; -} - -export interface IApplyCreditToInvoicesDTO { - entries: IApplyCreditToInvoiceEntryDTO[]; -} - -export interface IApplyCreditToInvoicesCreatedPayload { - trx: Knex.Transaction; - creditNote: ICreditNote; - tenantId: number; - creditNoteAppliedInvoices: ICreditNoteAppliedToInvoice[]; -} -export interface IApplyCreditToInvoicesDeletedPayload { - trx: Knex.Transaction; - creditNote: ICreditNote; - creditNoteAppliedToInvoice: ICreditNoteAppliedToInvoice; - tenantId: number; -} - -export interface ICreditNoteAppliedToInvoice { - invoiceId: number; - amount: number; - creditNoteId: number; -} -export interface ICreditNoteAppliedToInvoiceModel { - amount: number; - entries: ICreditNoteAppliedToInvoice[]; -} - -export type ICreditNoteGLCommonEntry = Pick< - ILedgerEntry, - | 'date' - | 'userId' - | 'currencyCode' - | 'exchangeRate' - | 'transactionType' - | 'transactionId' - | 'transactionNumber' - | 'referenceNumber' - | 'createdAt' - | 'indexGroup' - | 'credit' - | 'debit' - | 'branchId' ->; - -export interface CreditNotePdfTemplateAttributes { - // # Primary color - primaryColor: string; - secondaryColor: string; - - // # Company logo - showCompanyLogo: boolean; - companyLogo: string; - - // # Company name - companyName: string; - - // # Customer Address - showCustomerAddress: boolean; - customerAddress: string; - - // # Company address - showCompanyAddress: boolean; - companyAddress: string; - billedToLabel: string; - - total: string; - totalLabel: string; - showTotal: boolean; - - subtotal: string; - subtotalLabel: string; - showSubtotal: boolean; - - showCustomerNote: boolean; - customerNote: string; - customerNoteLabel: string; - - showTermsConditions: boolean; - termsConditions: string; - termsConditionsLabel: string; - - lines: Array<{ - item: string; - description: string; - rate: string; - quantity: string; - total: string; - }>; - - showCreditNoteNumber: boolean; - creditNoteNumberLabel: string; - creditNoteNumebr: string; - - creditNoteDate: string; - showCreditNoteDate: boolean; - creditNoteDateLabel: string; -} - -export interface ICreditNoteState { - defaultTemplateId: number; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Currency.ts b/packages/server/src/interfaces/Currency.ts deleted file mode 100644 index 2bcfc5620..000000000 --- a/packages/server/src/interfaces/Currency.ts +++ /dev/null @@ -1,27 +0,0 @@ - - -export interface ICurrencyDTO { - currencyName: string, - currencyCode: string, - currencySign: string, -}; -export interface ICurrencyEditDTO { - currencyName: string, - currencySign: string, -} -export interface ICurrency { - id: number, - currencyName: string, - currencyCode: string, - currencySign: string, - createdAt: Date, - updatedAt: Date, -}; - -export interface ICurrenciesService { - newCurrency(tenantId: number, currencyDTO: ICurrencyDTO): Promise; - editCurrency(tenantId: number, currencyId: number, editCurrencyDTO: ICurrencyEditDTO): Promise; - - deleteCurrency(tenantId: number, currencyCode: string): Promise; - listCurrencies(tenantId: number): Promise; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/CustomerBalanceSummary.ts b/packages/server/src/interfaces/CustomerBalanceSummary.ts deleted file mode 100644 index c55452d98..000000000 --- a/packages/server/src/interfaces/CustomerBalanceSummary.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { - IContactBalanceSummaryQuery, - IContactBalanceSummaryAmount, - IContactBalanceSummaryPercentage, - IContactBalanceSummaryTotal, -} from './ContactBalanceSummary'; -import { IFinancialSheetCommonMeta } from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface ICustomerBalanceSummaryQuery - extends IContactBalanceSummaryQuery { - customersIds?: number[]; -} - -export interface ICustomerBalanceSummaryAmount - extends IContactBalanceSummaryAmount {} - -export interface ICustomerBalanceSummaryPercentage - extends IContactBalanceSummaryPercentage {} - -export interface ICustomerBalanceSummaryCustomer { - id: number; - customerName: string; - total: ICustomerBalanceSummaryAmount; - percentageOfColumn?: ICustomerBalanceSummaryPercentage; -} - -export interface ICustomerBalanceSummaryTotal - extends IContactBalanceSummaryTotal { - total: ICustomerBalanceSummaryAmount; - percentageOfColumn?: ICustomerBalanceSummaryPercentage; -} - -export interface ICustomerBalanceSummaryData { - customers: ICustomerBalanceSummaryCustomer[]; - total: ICustomerBalanceSummaryTotal; -} - -export interface ICustomerBalanceSummaryMeta extends IFinancialSheetCommonMeta { - formattedAsDate: string; - formattedDateRange: string; -} - -export interface ICustomerBalanceSummaryStatement { - data: ICustomerBalanceSummaryData; - query: ICustomerBalanceSummaryQuery; - meta: ICustomerBalanceSummaryMeta; -} - -export interface ICustomerBalanceSummaryService { - customerBalanceSummary( - tenantId: number, - query: ICustomerBalanceSummaryQuery - ): Promise; -} - -export interface ICustomerBalanceSummaryTable extends IFinancialTable { - query: ICustomerBalanceSummaryQuery; - meta: ICustomerBalanceSummaryMeta; -} diff --git a/packages/server/src/interfaces/DynamicFilter.ts b/packages/server/src/interfaces/DynamicFilter.ts deleted file mode 100644 index 674328fb9..000000000 --- a/packages/server/src/interfaces/DynamicFilter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IModel, ISortOrder } from "./Model"; - -export interface IDynamicFilter { - setModel(model: IModel): void; - buildQuery(): void; - getResponseMeta(); -} - -export interface IFilterRole { - fieldKey: string; - value: string; - condition?: string; - index?: number; - comparator?: string; -} -export interface IDynamicListFilter { - customViewId?: number; - filterRoles?: IFilterRole[]; - columnSortBy: ISortOrder; - sortOrder: string; - stringifiedFilterRoles: string; - searchKeyword?: string; -} - -export interface IDynamicListService { - dynamicList( - tenantId: number, - model: any, - filter: IDynamicListFilter - ): Promise; - handlerErrorsToResponse(error, req, res, next): void; -} - -// Search role. -export interface ISearchRole { - fieldKey: string; - comparator: string; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Entry.ts b/packages/server/src/interfaces/Entry.ts deleted file mode 100644 index 8d43449e7..000000000 --- a/packages/server/src/interfaces/Entry.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface ICommonEntry { - id?: number; - amount: number; -} - -export interface ICommonLandedCostEntry extends ICommonEntry { - landedCost: boolean; - allocatedCostAmount: number; -} - -export interface ICommonEntryDTO { - id?: number; - amount: number; -} - -export interface ICommonLandedCostEntryDTO extends ICommonEntryDTO { - landedCost?: boolean; -} diff --git a/packages/server/src/interfaces/ExchangeRate.ts b/packages/server/src/interfaces/ExchangeRate.ts deleted file mode 100644 index 45080fc0f..000000000 --- a/packages/server/src/interfaces/ExchangeRate.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface ExchangeRateLatestDTO { - toCurrency: string; - fromCurrency: string; -} - -export interface EchangeRateLatestPOJO { - baseCurrency: string; - toCurrency: string; - exchangeRate: number; -} diff --git a/packages/server/src/interfaces/Expenses.ts b/packages/server/src/interfaces/Expenses.ts deleted file mode 100644 index 36b3c3dec..000000000 --- a/packages/server/src/interfaces/Expenses.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { Knex } from 'knex'; -import { ISystemUser } from './User'; -import { IFilterRole } from './DynamicFilter'; -import { IAccount } from './Account'; -import { AttachmentLinkDTO } from './Attachments'; - -export interface IPaginationMeta { - total: number; - page: number; - pageSize: number; -} - -export interface IExpensesFilter { - page: number; - pageSize: number; - filterRoles?: IFilterRole[]; - columnSortBy: string; - sortOrder: string; - viewSlug?: string; - filterQuery?: (query: any) => void; -} - -export interface IExpense { - id: number; - totalAmount: number; - localAmount?: number; - currencyCode: string; - exchangeRate: number; - description?: string; - paymentAccountId: number; - peyeeId?: number; - referenceNo?: string; - publishedAt: Date | null; - userId: number; - paymentDate: Date; - payeeId: number; - landedCostAmount: number; - allocatedCostAmount: number; - unallocatedCostAmount: number; - categories?: IExpenseCategory[]; - isPublished: boolean; - - localLandedCostAmount?: number; - localAllocatedCostAmount?: number; - localUnallocatedCostAmount?: number; - - billableAmount: number; - invoicedAmount: number; - - branchId?: number; - - createdAt?: Date; -} - -export interface IExpenseCategory { - id?: number; - expenseAccountId: number; - index: number; - description: string; - expenseId: number; - amount: number; - - projectId?: number; - - allocatedCostAmount: number; - unallocatedCostAmount: number; - landedCost: boolean; - - expenseAccount?: IAccount; -} - -export interface IExpenseCommonDTO { - currencyCode: string; - exchangeRate?: number; - description?: string; - paymentAccountId: number; - peyeeId?: number; - referenceNo?: string; - publish: boolean; - userId: number; - paymentDate: Date; - payeeId: number; - categories: IExpenseCategoryDTO[]; - - branchId?: number; - attachments?: AttachmentLinkDTO[]; -} - -export interface IExpenseCreateDTO extends IExpenseCommonDTO {} -export interface IExpenseEditDTO extends IExpenseCommonDTO {} - -export interface IExpenseCategoryDTO { - id?: number; - expenseAccountId: number; - index: number; - amount: number; - description?: string; - expenseId: number; - landedCost?: boolean; - projectId?: number; -} - -export interface IExpensesService { - newExpense( - tenantid: number, - expenseDTO: IExpenseDTO, - authorizedUser: ISystemUser - ): Promise; - - editExpense( - tenantid: number, - expenseId: number, - expenseDTO: IExpenseDTO, - authorizedUser: ISystemUser - ): void; - - publishExpense( - tenantId: number, - expenseId: number, - authorizedUser: ISystemUser - ): Promise; - - deleteExpense( - tenantId: number, - expenseId: number, - authorizedUser: ISystemUser - ): Promise; - - getExpensesList( - tenantId: number, - expensesFilter: IExpensesFilter - ): Promise<{ - expenses: IExpense[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }>; - - getExpense(tenantId: number, expenseId: number): Promise; -} - -export interface IExpenseCreatingPayload { - trx: Knex.Transaction; - tenantId: number; - expenseDTO: IExpenseCreateDTO; -} - -export interface IExpenseEventEditingPayload { - tenantId: number; - oldExpense: IExpense; - expenseDTO: IExpenseEditDTO; - trx: Knex.Transaction; -} -export interface IExpenseCreatedPayload { - tenantId: number; - expenseId: number; - authorizedUser: ISystemUser; - expense: IExpense; - expenseDTO: IExpenseCreateDTO; - trx: Knex.Transaction; -} - -export interface IExpenseEventEditPayload { - tenantId: number; - expenseId: number; - expense: IExpense; - expenseDTO: IExpenseEditDTO; - authorizedUser: ISystemUser; - oldExpense: IExpense; - trx: Knex.Transaction; -} - -export interface IExpenseEventDeletePayload { - tenantId: number; - expenseId: number; - authorizedUser: ISystemUser; - oldExpense: IExpense; - trx: Knex.Transaction; -} - -export interface IExpenseDeletingPayload { - trx: Knex.Transaction; - tenantId: number; - oldExpense: IExpense; -} -export interface IExpenseEventPublishedPayload { - tenantId: number; - expenseId: number; - oldExpense: IExpense; - expense: IExpense; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export interface IExpensePublishingPayload { - trx: Knex.Transaction; - oldExpense: IExpense; - tenantId: number; -} -export enum ExpenseAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', -} diff --git a/packages/server/src/interfaces/Features.ts b/packages/server/src/interfaces/Features.ts deleted file mode 100644 index 05b5247d2..000000000 --- a/packages/server/src/interfaces/Features.ts +++ /dev/null @@ -1,16 +0,0 @@ -export enum Features { - WAREHOUSES = 'warehouses', - BRANCHES = 'branches', - BankSyncing = 'BankSyncing' -} - -export interface IFeatureAllItem { - name: string; - isAccessible: boolean; - defaultAccessible: boolean; -} - -export interface IFeatureConfiugration { - name: string; - defaultValue?: boolean; -} diff --git a/packages/server/src/interfaces/FinancialReports/CashflowAccountTransactions/index.ts b/packages/server/src/interfaces/FinancialReports/CashflowAccountTransactions/index.ts deleted file mode 100644 index 3372d73fd..000000000 --- a/packages/server/src/interfaces/FinancialReports/CashflowAccountTransactions/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { INumberFormatQuery } from '../../FinancialStatements'; - -export interface ICashflowAccountTransactionsQuery { - page: number; - pageSize: number; - accountId: number; - numberFormat: INumberFormatQuery; -} - -export interface ICashflowAccountTransaction { - withdrawal: number; - deposit: number; - runningBalance: number; - - formattedWithdrawal: string; - formattedDeposit: string; - formattedRunningBalance: string; - - transactionNumber: string; - referenceNumber: string; - - referenceId: number; - referenceType: string; - - formattedTransactionType: string; - - balance: number; - formattedBalance: string; - - date: Date; - formattedDate: string; - - status: string; - formattedStatus: string; - - uncategorizedTransactionId: number; -} diff --git a/packages/server/src/interfaces/FinancialStatements.ts b/packages/server/src/interfaces/FinancialStatements.ts deleted file mode 100644 index abf2468c6..000000000 --- a/packages/server/src/interfaces/FinancialStatements.ts +++ /dev/null @@ -1,54 +0,0 @@ -export interface INumberFormatQuery { - precision: number; - divideOn1000: boolean; - showZero: boolean; - formatMoney: 'total' | 'always' | 'none'; - negativeFormat: 'parentheses' | 'mines'; -} - -export interface IFormatNumberSettings { - precision?: number; - divideOn1000?: boolean; - excerptZero?: boolean; - negativeFormat?: 'parentheses' | 'mines'; - thousand?: string; - decimal?: string; - zeroSign?: string; - currencyCode?: string; - money?: boolean; -} - -export enum ReportsAction { - READ_BALANCE_SHEET = 'read-balance-sheet', - READ_TRIAL_BALANCE_SHEET = 'read-trial-balance-sheet', - READ_PROFIT_LOSS = 'read-profit-loss', - READ_JOURNAL = 'read-journal', - READ_GENERAL_LEDGET = 'read-general-ledger', - READ_CASHFLOW = 'read-cashflow', - READ_AR_AGING_SUMMARY = 'read-ar-aging-summary', - READ_AP_AGING_SUMMARY = 'read-ap-aging-summary', - READ_PURCHASES_BY_ITEMS = 'read-purchases-by-items', - READ_SALES_BY_ITEMS = 'read-sales-by-items', - READ_CUSTOMERS_TRANSACTIONS = 'read-customers-transactions', - READ_VENDORS_TRANSACTIONS = 'read-vendors-transactions', - READ_CUSTOMERS_SUMMARY_BALANCE = 'read-customers-summary-balance', - READ_VENDORS_SUMMARY_BALANCE = 'read-vendors-summary-balance', - READ_INVENTORY_VALUATION_SUMMARY = 'read-inventory-valuation-summary', - READ_INVENTORY_ITEM_DETAILS = 'read-inventory-item-details', - READ_CASHFLOW_ACCOUNT_TRANSACTION = 'read-cashflow-account-transactions', - READ_PROJECT_PROFITABILITY_SUMMARY = 'read-project-profitability-summary', - READ_SALES_TAX_LIABILITY_SUMMARY = 'read-sales-tax-liability-summary', -} - -export interface IFinancialSheetBranchesQuery { - branchesIds?: number[]; -} - -export interface IFinancialSheetCommonMeta { - organizationName: string; - baseCurrency: string; - dateFormat: string; - isCostComputeRunning: boolean; - sheetName: string; - -} diff --git a/packages/server/src/interfaces/GeneralLedgerSheet.ts b/packages/server/src/interfaces/GeneralLedgerSheet.ts deleted file mode 100644 index 68835a59e..000000000 --- a/packages/server/src/interfaces/GeneralLedgerSheet.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { IFinancialSheetCommonMeta } from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface IGeneralLedgerSheetQuery { - fromDate: Date | string; - toDate: Date | string; - basis: string; - numberFormat: { - noCents: boolean; - divideOn1000: boolean; - }; - noneTransactions: boolean; - accountsIds: number[]; - branchesIds?: number[]; -} - -export interface IGeneralLedgerSheetAccountTransaction { - id: number; - - amount: number; - runningBalance: number; - credit: number; - debit: number; - - formattedAmount: string; - formattedCredit: string; - formattedDebit: string; - formattedRunningBalance: string; - - currencyCode: string; - note?: string; - - transactionTypeFormatted: string; - transactionNumber: string; - - referenceId?: number; - referenceType?: string; - - date: Date | string; - dateFormatted: string; -} - -export interface IGeneralLedgerSheetAccountBalance { - date: Date | string; - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface IGeneralLedgerSheetAccount { - id: number; - name: string; - code: string; - index: number; - parentAccountId: number; - transactions: IGeneralLedgerSheetAccountTransaction[]; - openingBalance: IGeneralLedgerSheetAccountBalance; - closingBalance: IGeneralLedgerSheetAccountBalance; - closingBalanceSubaccounts?: IGeneralLedgerSheetAccountBalance; - children?: IGeneralLedgerSheetAccount[]; -} - -export type IGeneralLedgerSheetData = IGeneralLedgerSheetAccount[]; - -export interface IAccountTransaction { - id: number; - index: number; - draft: boolean; - note: string; - accountId: number; - transactionType: string; - referenceType: string; - referenceId: number; - contactId: number; - contactType: string; - credit: number; - debit: number; - date: string | Date; - createdAt: string | Date; - updatedAt: string | Date; -} - -export interface IGeneralLedgerMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} - -export interface IGeneralLedgerTableData extends IFinancialTable { - meta: IGeneralLedgerMeta; - query: IGeneralLedgerSheetQuery; -} diff --git a/packages/server/src/interfaces/Http.ts b/packages/server/src/interfaces/Http.ts deleted file mode 100644 index b956f8c3e..000000000 --- a/packages/server/src/interfaces/Http.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const ACCEPT_TYPE = { - APPLICATION_PDF: 'application/pdf', - APPLICATION_JSON: 'application/json', - APPLICATION_JSON_TABLE: 'application/json+table', - APPLICATION_XLSX: 'application/xlsx', - APPLICATION_CSV: 'application/csv', - APPLICATION_TEXT_HTML: 'application/json+html', -}; diff --git a/packages/server/src/interfaces/IInventoryValuationSheet.ts b/packages/server/src/interfaces/IInventoryValuationSheet.ts deleted file mode 100644 index a5bd5d051..000000000 --- a/packages/server/src/interfaces/IInventoryValuationSheet.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface IInventoryValuationReportQuery { - asDate: Date | string; - numberFormat: INumberFormatQuery; - noneTransactions: boolean; - noneZero: boolean; - onlyActive: boolean; - itemsIds: number[]; - - warehousesIds?: number[]; - branchesIds?: number[]; -} - -export interface IInventoryValuationSheetMeta - extends IFinancialSheetCommonMeta { - formattedAsDate: string; - formattedDateRange: string; -} - -export interface IInventoryValuationItem { - id: number; - name: string; - code: string; - valuation: number; - quantity: number; - average: number; - valuationFormatted: string; - quantityFormatted: string; - averageFormatted: string; - currencyCode: string; -} - -export interface IInventoryValuationTotal { - valuation: number; - quantity: number; - - valuationFormatted: string; - quantityFormatted: string; -} - -export type IInventoryValuationStatement = { - items: IInventoryValuationItem[]; - total: IInventoryValuationTotal; -}; -export type IInventoryValuationSheetData = IInventoryValuationStatement; - -export interface IInventoryValuationSheet { - data: IInventoryValuationStatement; - meta: IInventoryValuationSheetMeta; - query: IInventoryValuationReportQuery; -} - -export interface IInventoryValuationTable extends IFinancialTable { - meta: IInventoryValuationSheetMeta; - query: IInventoryValuationReportQuery; -} diff --git a/packages/server/src/interfaces/Import.ts b/packages/server/src/interfaces/Import.ts deleted file mode 100644 index cf25a79fb..000000000 --- a/packages/server/src/interfaces/Import.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ImportFilePreviewPOJO } from "@/services/Import/interfaces"; - - -export interface IImportFileCommitedEventPayload { - tenantId: number; - importId: string; - meta: ImportFilePreviewPOJO; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/InventoryAdjustment.ts b/packages/server/src/interfaces/InventoryAdjustment.ts deleted file mode 100644 index 07b234a4f..000000000 --- a/packages/server/src/interfaces/InventoryAdjustment.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Knex } from 'knex'; -import { IItem } from './Item'; - -type IAdjustmentTypes = 'increment' | 'decrement'; - -export interface IQuickInventoryAdjustmentDTO { - date: Date; - type: IAdjustmentTypes; - adjustmentAccountId: number; - reason: string; - description: string; - referenceNo: string; - itemId: number; - quantity: number; - cost: number; - publish: boolean; - - warehouseId?: number; - branchId?: number; -} - -export interface IInventoryAdjustment { - id?: number; - date: Date; - adjustmentAccountId: number; - reason: string; - description: string; - type: string; - referenceNo: string; - inventoryDirection?: 'IN' | 'OUT'; - entries: IInventoryAdjustmentEntry[]; - userId: number; - publishedAt?: Date | null; - createdAt?: Date; - isPublished: boolean; - - branchId?: number; - warehouseId?: number; -} - -export interface IInventoryAdjustmentEntry { - id?: number; - adjustmentId?: number; - index: number; - itemId: number; - quantity?: number; - cost?: number; - value?: number; - - item?: IItem; -} - -export interface IInventoryAdjustmentsFilter { - page: number; - pageSize: number; -} - -export interface IInventoryAdjustmentEventCreatedPayload { - tenantId: number; - inventoryAdjustment: IInventoryAdjustment; - inventoryAdjustmentId: number; - trx: Knex.Transaction; -} -export interface IInventoryAdjustmentCreatingPayload { - tenantId: number; - quickAdjustmentDTO: IQuickInventoryAdjustmentDTO; - trx: Knex.Transaction; -} - -export interface IInventoryAdjustmentEventPublishedPayload { - tenantId: number; - inventoryAdjustmentId: number; - inventoryAdjustment: IInventoryAdjustment; - trx: Knex.Transaction; -} - -export interface IInventoryAdjustmentPublishingPayload { - trx: Knex.Transaction; - tenantId: number; - oldInventoryAdjustment: IInventoryAdjustment; -} -export interface IInventoryAdjustmentEventDeletedPayload { - tenantId: number; - inventoryAdjustmentId: number; - oldInventoryAdjustment: IInventoryAdjustment; - trx: Knex.Transaction; -} - -export interface IInventoryAdjustmentDeletingPayload { - tenantId: number; - oldInventoryAdjustment: IInventoryAdjustment; - trx: Knex.Transaction; -} - -export enum InventoryAdjustmentAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} diff --git a/packages/server/src/interfaces/InventoryCost.ts b/packages/server/src/interfaces/InventoryCost.ts deleted file mode 100644 index c1049b078..000000000 --- a/packages/server/src/interfaces/InventoryCost.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Knex } from "knex"; - - - -export interface IInventoryItemCostMeta { - itemId: number; - valuation: number; - quantity: number; - average: number; -} - -export interface IInventoryCostLotsGLEntriesWriteEvent { - tenantId: number, - startingDate: Date, - trx: Knex.Transaction -} \ No newline at end of file diff --git a/packages/server/src/interfaces/InventoryCostMethod.ts b/packages/server/src/interfaces/InventoryCostMethod.ts deleted file mode 100644 index 104edc5e3..000000000 --- a/packages/server/src/interfaces/InventoryCostMethod.ts +++ /dev/null @@ -1,6 +0,0 @@ - - -interface IInventoryCostMethod { - computeItemsCost(fromDate: Date): void, - storeInventoryLotsCost(transactions: any[]): void, -} \ No newline at end of file diff --git a/packages/server/src/interfaces/InventoryDetails.ts b/packages/server/src/interfaces/InventoryDetails.ts deleted file mode 100644 index 8da644540..000000000 --- a/packages/server/src/interfaces/InventoryDetails.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface IInventoryDetailsQuery { - fromDate: Date | string; - toDate: Date | string; - numberFormat: INumberFormatQuery; - noneTransactions: boolean; - itemsIds: number[]; - - warehousesIds?: number[]; - branchesIds?: number[]; -} - -export interface IInventoryDetailsNumber { - number: number; - formattedNumber: string; -} - -export interface IInventoryDetailsMoney { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface IInventoryDetailsDate { - date: Date; - formattedDate: string; -} - -export interface IInventoryDetailsOpening { - nodeType: 'OPENING_ENTRY'; - date: IInventoryDetailsDate; - quantity: IInventoryDetailsNumber; - value: IInventoryDetailsNumber; -} - -export interface IInventoryDetailsClosing extends IInventoryDetailsOpening { - nodeType: 'CLOSING_ENTRY'; -} - -export interface IInventoryDetailsItem { - id: number; - nodeType: string; - name: string; - code: string; - children: ( - | IInventoryDetailsItemTransaction - | IInventoryDetailsOpening - | IInventoryDetailsClosing - )[]; -} - -export interface IInventoryDetailsItemTransaction { - nodeType: string; - date: IInventoryDetailsDate; - transactionType: string; - transactionNumber?: string; - - quantityMovement: IInventoryDetailsNumber; - valueMovement: IInventoryDetailsNumber; - - quantity: IInventoryDetailsNumber; - total: IInventoryDetailsNumber; - cost: IInventoryDetailsNumber; - value: IInventoryDetailsNumber; - profitMargin: IInventoryDetailsNumber; - - rate: IInventoryDetailsNumber; - - runningQuantity: IInventoryDetailsNumber; - runningValuation: IInventoryDetailsNumber; - - direction: string; -} - -export type IInventoryDetailsNode = - | IInventoryDetailsItem - | IInventoryDetailsItemTransaction; -export type IInventoryDetailsData = IInventoryDetailsItem[]; - -export interface IInventoryItemDetailMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDay: string; - formattedDateRange: string; -} - -export interface IInvetoryItemDetailDOO { - data: IInventoryDetailsData; - query: IInventoryDetailsQuery; - meta: IInventoryItemDetailMeta; -} - -export interface IInvetoryItemDetailsTable extends IFinancialTable { - query: IInventoryDetailsQuery; - meta: IInventoryItemDetailMeta; -} diff --git a/packages/server/src/interfaces/InventoryTransaction.ts b/packages/server/src/interfaces/InventoryTransaction.ts deleted file mode 100644 index b483e1c60..000000000 --- a/packages/server/src/interfaces/InventoryTransaction.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Knex } from 'knex'; -import { IItem } from './Item'; -import { ISaleInvoice } from './SaleInvoice'; -import { ISaleReceipt } from './SaleReceipt'; - -export type TInventoryTransactionDirection = 'IN' | 'OUT'; - -export interface IInventoryTransaction { - id?: number; - date: Date | string; - direction: TInventoryTransactionDirection; - itemId: number; - quantity: number | null; - rate: number; - transactionType: string; - transcationTypeFormatted?: string; - transactionId: number; - costAccountId?: number; - entryId: number; - meta?: IInventoryTransactionMeta; - costLotAggregated?: IInventoryCostLotAggregated; - createdAt?: Date; - updatedAt?: Date; - warehouseId?: number; -} - -export interface IInventoryTransactionMeta { - id?: number; - transactionNumber: string; - description: string; -} - -export interface IInventoryCostLotAggregated { - cost: number; - quantity: number; -} - -export interface IInventoryLotCost { - id?: number; - date: Date; - direction: string; - itemId: number; - quantity: number; - rate: number; - remaining: number; - cost: number; - transactionType: string; - transactionId: number; - costAccountId: number; - entryId: number; - createdAt: Date; - - exchangeRate: number; - currencyCode: string; - item?: IItem; - - invoice?: ISaleInvoice; - receipt?: ISaleReceipt; -} - -export interface IItemsQuantityChanges { - itemId: number; - balanceChange: number; -} - -export interface IInventoryTransactionsCreatedPayload { - tenantId: number; - inventoryTransactions: IInventoryTransaction[]; - trx: Knex.Transaction; -} - -export interface IInventoryTransactionsDeletedPayload { - tenantId: number; - oldInventoryTransactions: IInventoryTransaction[]; - transactionId: number; - transactionType: string; - trx: Knex.Transaction; -} - -export interface IInventoryItemCostScheduledPayload { - startingDate: Date | string; - itemId: number; - tenantId: number; -} - -export interface IComputeItemCostJobStartedPayload { - startingDate: Date | string; - itemId: number; - tenantId: number; -} -export interface IComputeItemCostJobCompletedPayload { - startingDate: Date | string; - itemId: number; - tenantId: number; -} diff --git a/packages/server/src/interfaces/Item.ts b/packages/server/src/interfaces/Item.ts index 9fdfa374d..63816bdff 100644 --- a/packages/server/src/interfaces/Item.ts +++ b/packages/server/src/interfaces/Item.ts @@ -1,6 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; import { Knex } from 'knex'; -import { AbilitySubject } from '@/interfaces'; -import { IFilterRole } from '@/interfaces/DynamicFilter'; +import { Item } from '@/modules/Items/models/Item'; +// import { AbilitySubject } from '@/interfaces'; +// import { IFilterRole } from '@/interfaces/DynamicFilter'; export interface IItem { id: number; @@ -37,92 +39,119 @@ export interface IItem { updatedAt: Date; } -export interface IItemDTO { +export class IItemDTO { + @ApiProperty() name: string; + + @ApiProperty() type: string; + + @ApiProperty() code: string; + @ApiProperty() sellable: boolean; + + @ApiProperty() purchasable: boolean; + @ApiProperty() costPrice: number; + + @ApiProperty() sellPrice: number; + @ApiProperty() currencyCode: string; + @ApiProperty() costAccountId: number; + + @ApiProperty() sellAccountId: number; + + @ApiProperty() inventoryAccountId: number; + @ApiProperty() sellDescription: string; + + @ApiProperty() purchaseDescription: string; + @ApiProperty() sellTaxRateId: number; + + @ApiProperty() purchaseTaxRateId: number; + @ApiProperty() quantityOnHand: number; + @ApiProperty() note: string; + + @ApiProperty() active: boolean; + @ApiProperty() categoryId: number; } export interface IItemCreateDTO extends IItemDTO {} export interface IItemEditDTO extends IItemDTO {} -export interface IItemsService { - getItem(tenantId: number, itemId: number): Promise; - deleteItem(tenantId: number, itemId: number): Promise; - editItem(tenantId: number, itemId: number, itemDTO: IItemDTO): Promise; - newItem(tenantId: number, itemDTO: IItemDTO): Promise; - itemsList( - tenantId: number, - itemsFilter: IItemsFilter - ): Promise<{ items: IItem[] }>; -} +// export interface IItemsService { +// getItem(tenantId: number, itemId: number): Promise; +// deleteItem(tenantId: number, itemId: number): Promise; +// editItem(tenantId: number, itemId: number, itemDTO: IItemDTO): Promise; +// newItem(tenantId: number, itemDTO: IItemDTO): Promise; +// itemsList( +// tenantId: number, +// itemsFilter: IItemsFilter, +// ): Promise<{ items: IItem[] }>; +// } -export interface IItemsFilter extends IDynamicListFilterDTO { - stringifiedFilterRoles?: string; - page: number; - pageSize: number; - inactiveMode: boolean; - viewSlug?: string; -} +// export interface IItemsFilter extends IDynamicListFilterDTO { +// stringifiedFilterRoles?: string; +// page: number; +// pageSize: number; +// inactiveMode: boolean; +// viewSlug?: string; +// } -export interface IItemsAutoCompleteFilter { - limit: number; - keyword: string; - filterRoles?: IFilterRole[]; - columnSortBy: string; - sortOrder: string; -} +// export interface IItemsAutoCompleteFilter { +// limit: number; +// keyword: string; +// filterRoles?: IFilterRole[]; +// columnSortBy: string; +// sortOrder: string; +// } export interface IItemEventCreatedPayload { - tenantId: number; - item: IItem; + // tenantId: number; + item: Item; itemId: number; trx: Knex.Transaction; } export interface IItemEventEditedPayload { - tenantId: number; - item: IItem; - oldItem: IItem; + item: Item; + oldItem: Item; itemId: number; trx: Knex.Transaction; } export interface IItemEventDeletingPayload { - tenantId: number; + // tenantId: number; trx: Knex.Transaction; - oldItem: IItem; + oldItem: Item; } export interface IItemEventDeletedPayload { - tenantId: number; - oldItem: IItem; + // tenantId: number; itemId: number; + oldItem: Item; trx: Knex.Transaction; } @@ -133,4 +162,4 @@ export enum ItemAction { VIEW = 'View', } -export type ItemAbility = [ItemAction, AbilitySubject.Item]; +// export type ItemAbility = [ItemAction, AbilitySubject.Item]; diff --git a/packages/server/src/interfaces/ItemCategory.ts b/packages/server/src/interfaces/ItemCategory.ts deleted file mode 100644 index 7113573e9..000000000 --- a/packages/server/src/interfaces/ItemCategory.ts +++ /dev/null @@ -1,87 +0,0 @@ -import Knex from 'knex'; -import { IDynamicListFilterDTO } from './DynamicFilter'; -import { ISystemUser } from './User'; - -export interface IItemCategory { - id: number; - name: string; - description?: string; - userId: number; - - costAccountId?: number; - sellAccountId?: number; - inventoryAccountId?: number; - - costMethod?: string; -} - -export interface IItemCategoryOTD { - name: string; - - description?: string; - userId: number; - - costAccountId?: number; - sellAccountId?: number; - inventoryAccountId?: number; - - costMethod?: string; -} - -export interface IItemCategoriesFilter extends IDynamicListFilterDTO { - stringifiedFilterRoles?: string; -} - -export interface IItemCategoriesService { - newItemCategory( - tenantId: number, - itemCategoryOTD: IItemCategoryOTD, - authorizedUser: ISystemUser - ): Promise; - editItemCategory( - tenantId: number, - itemCategoryId: number, - itemCategoryOTD: IItemCategoryOTD, - authorizedUser: ISystemUser - ): Promise; - - deleteItemCategory( - tenantId: number, - itemCategoryId: number, - authorizedUser: ISystemUser - ): Promise; - deleteItemCategories( - tenantId: number, - itemCategoriesIds: number[], - authorizedUser: ISystemUser - ): Promise; - - getItemCategory( - tenantId: number, - itemCategoryId: number, - authorizedUser: ISystemUser - ): Promise; - getItemCategoriesList( - tenantId: number, - itemCategoriesFilter: IItemCategoriesFilter, - authorizedUser: ISystemUser - ): Promise; -} - -export interface IItemCategoryCreatedPayload { - tenantId: number; - itemCategory: IItemCategory; - trx: Knex.Transaction; -} - -export interface IItemCategoryEditedPayload { - oldItemCategory: IItemCategory; - tenantId: number; - trx: Knex.Transaction; -} - -export interface IItemCategoryDeletedPayload { - tenantId: number; - itemCategoryId: number; - oldItemCategory: IItemCategory; -} diff --git a/packages/server/src/interfaces/ItemEntry.ts b/packages/server/src/interfaces/ItemEntry.ts deleted file mode 100644 index a2693ab5c..000000000 --- a/packages/server/src/interfaces/ItemEntry.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { IItem } from './Item'; -import { IBillLandedCostEntry } from './LandedCost'; - -export type IItemEntryTransactionType = 'SaleInvoice' | 'Bill' | 'SaleReceipt'; - -export interface IItemEntry { - id?: number; - - referenceType: string; - referenceId: number; - - index: number; - - itemId: number; - description: string; - discountType?: string; - discount: number; - quantity: number; - rate: number; - amount: number; - - total: number; - totalExcludingTax?: number; - - subtotalInclusingTax: number; - subtotalExcludingTax: number; - discountAmount: number; - - landedCost: number; - allocatedCostAmount: number; - unallocatedCostAmount: number; - - sellAccountId: number; - costAccountId: number; - - warehouseId: number; - projectId: number; - - projectRefId?: number; - projectRefType?: ProjectLinkRefType; - projectRefInvoicedAmount?: number; - - taxRateId: number | null; - taxRate: number; - taxAmount: number; - - item?: IItem; - - allocatedCostEntries?: IBillLandedCostEntry[]; -} - -export interface IItemEntryDTO { - id?: number; - index?: number; - itemId: number; - landedCost?: boolean; - warehouseId?: number; - - projectRefId?: number; - projectRefType?: ProjectLinkRefType; - projectRefInvoicedAmount?: number; - - taxRateId?: number; - taxCode?: string; -} - -export enum ProjectLinkRefType { - Task = 'TASK', - Bill = 'BILL', - Expense = 'EXPENSE', -} diff --git a/packages/server/src/interfaces/Jobs.ts b/packages/server/src/interfaces/Jobs.ts deleted file mode 100644 index 9c40bcd43..000000000 --- a/packages/server/src/interfaces/Jobs.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface IJobMeta { - id: string; - nextRunAt: Date; - lastModifiedBy: null | Date; - lockedAt: null | Date; - lastRunAt: null | Date; - failCount: number; - failedAt: null | Date; - lastFinishedAt: Date | null; - running: boolean; - queued: boolean; - completed: boolean; - failed: boolean; -} diff --git a/packages/server/src/interfaces/Journal.ts b/packages/server/src/interfaces/Journal.ts deleted file mode 100644 index b4020b296..000000000 --- a/packages/server/src/interfaces/Journal.ts +++ /dev/null @@ -1,55 +0,0 @@ -export interface IJournalEntry { - id: number; - index?: number; - - date: Date; - credit: number; - debit: number; - account: number; - referenceType: string; - referenceId: number; - - referenceTypeFormatted: string; - - itemId?: number; - transactionNumber?: string; - referenceNumber?: string; - - transactionType?: string; - note?: string; - userId?: number; - contactType?: string; - contactId?: number; - branchId: number; -} - -export interface IJournalPoster { - entries: IJournalEntry[]; - - credit(entry: IJournalEntry): void; - debit(entry: IJournalEntry): void; - - removeEntries(ids: number[]): void; - - saveEntries(): void; - saveBalance(): void; - deleteEntries(): void; - - getAccountBalance( - accountId: number, - closingDate?: Date | string, - dateType?: string - ): number; - getAccountEntries(accountId: number): IJournalEntry[]; -} - -export type TEntryType = 'credit' | 'debit'; - -export interface IAccountChange { - credit: number; - debit: number; -} - -export interface IAccountsChange { - [key: string]: IAccountChange; -} diff --git a/packages/server/src/interfaces/JournalReport.ts b/packages/server/src/interfaces/JournalReport.ts deleted file mode 100644 index 319bf526c..000000000 --- a/packages/server/src/interfaces/JournalReport.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { IFinancialSheetCommonMeta } from './FinancialStatements'; -import { IJournalEntry } from './Journal'; -import { IFinancialTable } from './Table'; - -export interface IJournalReportQuery { - fromDate: Date | string; - toDate: Date | string; - numberFormat: { - noCents: boolean; - divideOn1000: boolean; - }; - transactionType: string; - transactionId: string; - - accountsIds: number | number[]; - fromRange: number; - toRange: number; -} - -export interface IJournalReportEntriesGroup { - id: string; - date: Date; - dateFormatted: string; - entries: IJournalEntry[]; - currencyCode: string; - credit: number; - debit: number; - formattedCredit: string; - formattedDebit: string; -} - -export interface IJournalReport { - entries: IJournalReportEntriesGroup[]; -} - -export interface IJournalSheetMeta extends IFinancialSheetCommonMeta { - formattedDateRange: string; - formattedFromDate: string; - formattedToDate: string; -} - -export interface IJournalTable extends IFinancialTable { - query: IJournalReportQuery; - meta: IJournalSheetMeta; -} - -export type IJournalTableData = IJournalReportEntriesGroup[]; - -export interface IJournalSheet { - data: IJournalTableData; - query: IJournalReportQuery; - meta: IJournalSheetMeta; -} diff --git a/packages/server/src/interfaces/LandedCost.ts b/packages/server/src/interfaces/LandedCost.ts deleted file mode 100644 index 9653be8cc..000000000 --- a/packages/server/src/interfaces/LandedCost.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IBill } from '@/interfaces'; -import Knex from 'knex'; -import { IItemEntry } from './ItemEntry'; - -export interface IBillLandedCost { - id?: number; - - fromTransactionId: number; - fromTransactionType: string; - fromTransactionEntryId: number; - allocationMethod: string; - costAccountId: number; - description: string; - - amount: number; - localAmount?: number; - exchangeRate: number; - currencyCode: string; - - billId: number; - allocateEntries: IBillLandedCostEntry[] -} - -export interface IBillLandedCostEntry { - id?: number; - cost: number; - entryId: number; - billLocatedCostId: number; - - itemEntry?: IItemEntry; -} - -export interface ILandedCostItemDTO { - entryId: number; - cost: number; -} -export type ILandedCostType = 'Expense' | 'Bill'; - -export interface ILandedCostDTO { - transactionType: ILandedCostType; - transactionId: number; - transactionEntryId: number; - allocationMethod: string; - description: string; - items: ILandedCostItemDTO[]; -} - -export interface ILandedCostQueryDTO { - vendorId: number; - fromDate: Date; - toDate: Date; -} - -export interface IUnallocatedListCost { - costNumber: string; - costAmount: number; - unallocatedAmount: number; -} - -export interface ILandedCostTransactionsQueryDTO { - transactionType: string; - date: Date; -} - -export interface ILandedCostEntriesQueryDTO { - transactionType: string; - transactionId: number; -} - -export interface ILandedCostTransaction { - id: number; - name: string; - amount: number; - allocatedCostAmount: number; - unallocatedCostAmount: number; - currencyCode: string; - exchangeRate: number; - // formattedAllocatedCostAmount: string; - // formattedAmount: string; - // formattedUnallocatedCostAmount: string; - transactionType: string; - entries?: ILandedCostTransactionEntry[]; -} - -export interface ILandedCostTransactionEntry { - id: number; - name: string; - code: string; - amount: number; - unallocatedCostAmount: number; - allocatedCostAmount: number; - description: string; - costAccountId: number; -} - -export interface ILandedCostTransactionEntryDOJO - extends ILandedCostTransactionEntry { - formattedAmount: string; - formattedUnallocatedCostAmount: string; - formattedAllocatedCostAmount: string; -} -export interface ILandedCostTransactionDOJO extends ILandedCostTransaction { - formattedAmount: string; - formattedUnallocatedCostAmount: string; - formattedAllocatedCostAmount: string; -} - -interface ILandedCostEntry { - id: number; - landedCost?: boolean; -} - -export interface IBillLandedCostTransaction { - id: number; - fromTransactionId: number; - fromTransactionType: string; - fromTransactionEntryId: number; - - billId: number; - allocationMethod: string; - costAccountId: number; - description: string; - - amount: number; - localAmount?: number; - currencyCode: string; - exchangeRate: number; - - allocateEntries?: IBillLandedCostTransactionEntry[]; -} - -export interface IBillLandedCostTransactionEntry { - cost: number; - entryId: number; - billLocatedCostId: number; -} - -export interface IAllocatedLandedCostDeletedPayload { - tenantId: number; - oldBillLandedCost: IBillLandedCostTransaction; - billId: number; - trx: Knex.Transaction; -} - -export interface IAllocatedLandedCostCreatedPayload { - tenantId: number; - bill: IBill; - billLandedCostId: number; - billLandedCost: IBillLandedCostTransaction; - trx: Knex.Transaction; -} - -export interface IBillAssociatedLandedCostTransactions {} diff --git a/packages/server/src/interfaces/Ledger.ts b/packages/server/src/interfaces/Ledger.ts deleted file mode 100644 index 0c39eef4f..000000000 --- a/packages/server/src/interfaces/Ledger.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Knex } from 'knex'; -export interface ILedger { - entries: ILedgerEntry[]; - - getEntries(): ILedgerEntry[]; - - filter(cb: (entry: ILedgerEntry) => boolean): ILedger; - - whereAccountId(accountId: number): ILedger; - whereAccountsIds(accountsIds: number[]): ILedger; - whereContactId(contactId: number): ILedger; - whereFromDate(fromDate: Date | string): ILedger; - whereToDate(toDate: Date | string): ILedger; - whereCurrencyCode(currencyCode: string): ILedger; - whereBranch(branchId: number): ILedger; - whereItem(itemId: number): ILedger; - whereProject(projectId: number): ILedger; - - getClosingBalance(): number; - getForeignClosingBalance(): number; - getClosingDebit(): number; - getClosingCredit(): number; - - getContactsIds(): number[]; - getAccountsIds(): number[]; - - reverse(): ILedger; - isEmpty(): boolean; -} - -export interface ILedgerEntry { - credit: number; - debit: number; - currencyCode: string; - exchangeRate: number; - - accountId?: number; - accountNormal: string; - contactId?: number; - date: Date | string; - - transactionType: string; - transactionSubType?: string; - - transactionId: number; - - transactionNumber?: string; - - referenceNumber?: string; - index: number; - indexGroup?: number; - - note?: string; - - userId?: number; - itemId?: number; - branchId?: number; - projectId?: number; - - taxRateId?: number; - taxRate?: number; - - entryId?: number; - createdAt?: Date; - - costable?: boolean; -} - -export interface ISaveLedgerEntryQueuePayload { - tenantId: number; - entry: ILedgerEntry; - trx?: Knex.Transaction; -} - -export interface ISaveAccountsBalanceQueuePayload { - ledger: ILedger; - tenantId: number; - accountId: number; - trx?: Knex.Transaction; -} - -export interface ISaleContactsBalanceQueuePayload { - ledger: ILedger; - tenantId: number; - contactId: number; - trx?: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/License.ts b/packages/server/src/interfaces/License.ts deleted file mode 100644 index e58e9a6ea..000000000 --- a/packages/server/src/interfaces/License.ts +++ /dev/null @@ -1,25 +0,0 @@ - - -export interface ILicense { - id?: number, - licenseCode: string, - licensePeriod: number, - sent: boolean, - disabled: boolean, - used: boolean, -}; - -export interface ILicensesFilter { - active: boolean, - disabld: boolean, - used: boolean, - sent: boolean, -}; - -export interface ISendLicenseDTO { - phoneNumber: string, - email: string, - period: string, - periodInterval: string, - planSlug: string, -}; \ No newline at end of file diff --git a/packages/server/src/interfaces/Mailable.ts b/packages/server/src/interfaces/Mailable.ts deleted file mode 100644 index faae8437e..000000000 --- a/packages/server/src/interfaces/Mailable.ts +++ /dev/null @@ -1,44 +0,0 @@ -export type IMailAttachment = MailAttachmentPath | MailAttachmentContent; - -export interface MailAttachmentPath { - filename: string; - path: string; - cid: string; -} -export interface MailAttachmentContent { - filename: string; - content: Buffer; -} - -export interface IMailable { - constructor(view: string, data?: { [key: string]: string | number }); - send(): Promise; - build(): void; - setData(data: { [key: string]: string | number }): IMailable; - setTo(to: string): IMailable; - setFrom(from: string): IMailable; - setSubject(subject: string): IMailable; - setView(view: string): IMailable; - render(data?: { [key: string]: string | number }): string; - getViewContent(): string; -} - -export interface AddressItem { - label: string; - mail: string; - primary?: boolean; -} - -export interface CommonMailOptions { - from: Array; - subject: string; - message: string; - to: Array; - cc?: Array; - bcc?: Array; - formatArgs?: Record; - toOptions: Array; - fromOptions: Array; -} - -export interface CommonMailOptionsDTO extends Partial {} diff --git a/packages/server/src/interfaces/ManualJournal.ts b/packages/server/src/interfaces/ManualJournal.ts deleted file mode 100644 index 8cdc112f9..000000000 --- a/packages/server/src/interfaces/ManualJournal.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { Knex } from 'knex'; -import { IDynamicListFilterDTO } from './DynamicFilter'; -import { ISystemUser } from './User'; -import { IAccount } from './Account'; -import { AttachmentLinkDTO } from './Attachments'; - -export interface IManualJournal { - id?: number; - date: Date; - journalNumber: string; - journalType: string; - reference: string; - amount: number; - currencyCode: string; - exchangeRate: number | null; - publishedAt: Date | null; - description: string; - userId?: number; - entries: IManualJournalEntry[]; - createdAt?: Date; - updatedAt?: Date; - isPublished?: boolean; -} - -export interface IManualJournalEntry { - index: number; - credit: number; - debit: number; - accountId: number; - note: string; - contactId?: number; - account?: IAccount - - branchId?: number; - projectId?: number; -} - -export interface IManualJournalEntryDTO { - index: number; - credit: number; - debit: number; - accountId: number; - note: string; - contactId?: number; - branchId?: number - projectId?: number; -} - -export interface IManualJournalDTO { - date: Date; - currencyCode?: string; - exchangeRate?: number; - journalNumber: string; - journalType: string; - reference?: string; - description?: string; - publish?: boolean; - branchId?: number; - entries: IManualJournalEntryDTO[]; - attachments?: AttachmentLinkDTO[]; -} - -export interface IManualJournalsFilter extends IDynamicListFilterDTO { - stringifiedFilterRoles?: string; - page: number; - pageSize: number; -} - -export interface IManualJournalsService { - makeJournalEntries( - tenantId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser - ): Promise<{ manualJournal: IManualJournal }>; - - editJournalEntries( - tenantId: number, - manualJournalId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser - ): Promise<{ manualJournal: IManualJournal }>; - - deleteManualJournal(tenantId: number, manualJournalId: number): Promise; - - deleteManualJournals( - tenantId: number, - manualJournalsIds: number[] - ): Promise; - - publishManualJournals( - tenantId: number, - manualJournalsIds: number[] - ): Promise<{ - meta: { - alreadyPublished: number; - published: number; - total: number; - }; - }>; - - publishManualJournal( - tenantId: number, - manualJournalId: number - ): Promise; - - getManualJournals( - tenantId: number, - filter: IManualJournalsFilter - ): Promise<{ - manualJournals: IManualJournal; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }>; -} - -export interface IManualJournalEventPublishedPayload { - tenantId: number; - manualJournal: IManualJournal; - manualJournalId: number; - oldManualJournal: IManualJournal; - trx: Knex.Transaction; -} - -export interface IManualJournalPublishingPayload { - oldManualJournal: IManualJournal; - trx: Knex.Transaction; - tenantId: number; -} - -export interface IManualJournalEventDeletedPayload { - tenantId: number; - manualJournalId: number; - oldManualJournal: IManualJournal; - trx: Knex.Transaction; -} - -export interface IManualJournalDeletingPayload { - tenantId: number; - oldManualJournal: IManualJournal; - trx: Knex.Transaction; -} - -export interface IManualJournalEventEditedPayload { - tenantId: number; - manualJournal: IManualJournal; - oldManualJournal: IManualJournal; - manualJournalDTO: IManualJournalDTO; - trx: Knex.Transaction; -} -export interface IManualJournalEditingPayload { - tenantId: number; - oldManualJournal: IManualJournal; - manualJournalDTO: IManualJournalDTO; - trx: Knex.Transaction; -} - -export interface IManualJournalCreatingPayload { - tenantId: number; - manualJournalDTO: IManualJournalDTO; - trx: Knex.Transaction; -} - -export interface IManualJournalEventCreatedPayload { - tenantId: number; - manualJournal: IManualJournal; - manualJournalId: number; - manualJournalDTO: IManualJournalDTO; - trx: Knex.Transaction; -} - -export enum ManualJournalAction { - Create = 'Create', - View = 'View', - Edit = 'Edit', - Delete = 'Delete', -} diff --git a/packages/server/src/interfaces/Media.ts b/packages/server/src/interfaces/Media.ts deleted file mode 100644 index 6cd338583..000000000 --- a/packages/server/src/interfaces/Media.ts +++ /dev/null @@ -1,25 +0,0 @@ - - -export interface IMedia { - id?: number, - attachmentFile: string, - createdAt?: Date, -}; - -export interface IMediaLink { - mediaId: number, - modelName: string, - modelId: number, -}; - -export interface IMediaLinkDTO { - modelName: string, - modelId: number, -}; - -export interface IMediaService { - linkMedia(tenantId: number, mediaId: number, modelId?: number, modelName?: string): Promise; - getMedia(tenantId: number, mediaId: number): Promise; - deleteMedia(tenantId: number, mediaId: number | number[]): Promise; - upload(tenantId: number, attachment: any, modelName?: string, modelId?: number): Promise; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Metable.ts b/packages/server/src/interfaces/Metable.ts deleted file mode 100644 index 8a16d3055..000000000 --- a/packages/server/src/interfaces/Metable.ts +++ /dev/null @@ -1,28 +0,0 @@ - - -export interface IMetadata { - key: string, - value: string|boolean|number, - group: string, - _markAsDeleted?: boolean, - _markAsInserted?: boolean, - _markAsUpdated?: boolean, -}; - -export interface IMetaQuery { - key: string, - group?: string, -}; - -export interface IMetableStore { - find(query: string|IMetaQuery): IMetadata; - all(): IMetadata[]; - get(query: string|IMetaQuery, defaultValue: any): string|number|boolean; - remove(query: string|IMetaQuery): void; - removeAll(): void; - toArray(): IMetadata[]; -}; - -export interface IMetableStoreStorage { - save(): Promise; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Model.ts b/packages/server/src/interfaces/Model.ts index 59c75f8de..3230dddb3 100644 --- a/packages/server/src/interfaces/Model.ts +++ b/packages/server/src/interfaces/Model.ts @@ -39,6 +39,8 @@ export interface IModelMetaFieldCommon { order?: number; unique?: number; dataTransferObjectKey?: string; + filterCustomQuery?: Function; + sortCustomQuery?: Function; } export interface IModelMetaFieldText { @@ -122,7 +124,7 @@ export type IModelMetaCollectionField = IModelMetaCollectionFieldCommon & export type IModelMetaRelationField = IModelMetaRelationFieldCommon & IModelMetaRelationEnumerationField; -interface IModelPrintMeta{ +interface IModelPrintMeta { pageTitle: string; } @@ -140,8 +142,9 @@ export interface IModelMeta { print?: IModelPrintMeta; - fields: { [key: string]: IModelMetaField }; - columns: { [key: string]: IModelMetaColumn }; + fields: Record; + fields2: Record; + columns: Record; } // ---- @@ -151,7 +154,7 @@ export interface IModelMetaFieldCommon2 { importHint?: string; order?: number; unique?: number; - features?: Array + features?: Array; } export interface IModelMetaRelationField2 { diff --git a/packages/server/src/interfaces/Options.ts b/packages/server/src/interfaces/Options.ts deleted file mode 100644 index 51a4e7834..000000000 --- a/packages/server/src/interfaces/Options.ts +++ /dev/null @@ -1,11 +0,0 @@ - - -export interface IOptionDTO { - key: string, - value: string|number, - group: string, -}; - -export interface IOptionsDTO { - options: IOptionDTO[], -}; \ No newline at end of file diff --git a/packages/server/src/interfaces/Payment.ts b/packages/server/src/interfaces/Payment.ts deleted file mode 100644 index 4d5317319..000000000 --- a/packages/server/src/interfaces/Payment.ts +++ /dev/null @@ -1,20 +0,0 @@ - - -export interface IPaymentModel {} - -export interface ILicensePaymentModel extends IPaymentModel { - licenseCode: string; -} - -export interface IPaymentMethod { - makePayment(paymentModel: IPaymentModel): Promise; -} - -export interface ILicensePaymentMethod { - makePayment(paymentModel: ILicensePaymentModel): Promise; -} - -export interface IPaymentContext { - paymentMethod: IPaymentMethod; - makePayment(paymentModel: PaymentModel): Promise; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/PaymentReceive.ts b/packages/server/src/interfaces/PaymentReceive.ts deleted file mode 100644 index 695a3b17a..000000000 --- a/packages/server/src/interfaces/PaymentReceive.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { Knex } from 'knex'; -import { - CommonMailOptions, - CommonMailOptionsDTO, - ISystemUser, -} from '@/interfaces'; -import { ILedgerEntry } from './Ledger'; -import { ISaleInvoice } from './SaleInvoice'; -import { AttachmentLinkDTO } from './Attachments'; - -export interface IPaymentReceived { - id?: number; - customerId: number; - paymentDate: Date; - amount: number; - currencyCode: string; - exchangeRate: number; - referenceNo: string; - depositAccountId: number; - paymentReceiveNo: string; - statement: string; - entries: IPaymentReceivedEntry[]; - userId: number; - createdAt: Date; - updatedAt: Date; - localAmount?: number; - branchId?: number; - pdfTemplateId?: number; -} -export interface IPaymentReceivedCreateDTO { - customerId: number; - paymentDate: Date; - amount: number; - exchangeRate: number; - referenceNo: string; - depositAccountId: number; - paymentReceiveNo?: string; - statement: string; - entries: IPaymentReceivedEntryDTO[]; - - branchId?: number; - attachments?: AttachmentLinkDTO[]; -} - -export interface IPaymentReceivedEditDTO { - customerId: number; - paymentDate: Date; - amount: number; - exchangeRate: number; - referenceNo: string; - depositAccountId: number; - paymentReceiveNo?: string; - statement: string; - entries: IPaymentReceivedEntryDTO[]; - branchId?: number; - attachments?: AttachmentLinkDTO[]; -} - -export interface IPaymentReceivedEntry { - id?: number; - paymentReceiveId: number; - invoiceId: number; - paymentAmount: number; - - invoice?: ISaleInvoice; -} - -export interface IPaymentReceivedEntryDTO { - id?: number; - index?: number; - paymentReceiveId?: number; - invoiceId: number; - paymentAmount: number; -} - -export interface IPaymentsReceivedFilter extends IDynamicListFilterDTO { - stringifiedFilterRoles?: string; - filterQuery?: (trx: Knex.Transaction) => void; -} - -export interface IPaymentReceivePageEntry { - invoiceId: number; - entryType: string; - invoiceNo: string; - dueAmount: number; - amount: number; - totalPaymentAmount: number; - paymentAmount: number; - currencyCode: string; - date: Date | string; -} - -export interface IPaymentReceivedEditPage { - paymentReceive: IPaymentReceived; - entries: IPaymentReceivePageEntry[]; -} - -export interface IPaymentsReceivedService { - validateCustomerHasNoPayments( - tenantId: number, - customerId: number - ): Promise; -} - -export interface IPaymentReceivedSmsDetails { - customerName: string; - customerPhoneNumber: string; - smsMessage: string; -} - -export interface IPaymentReceivedCreatingPayload { - tenantId: number; - paymentReceiveDTO: IPaymentReceivedCreateDTO; - trx: Knex.Transaction; -} - -export interface IPaymentReceivedCreatedPayload { - tenantId: number; - paymentReceive: IPaymentReceived; - paymentReceiveId: number; - authorizedUser: ISystemUser; - paymentReceiveDTO: IPaymentReceivedCreateDTO; - trx: Knex.Transaction; -} - -export interface IPaymentReceivedEditedPayload { - tenantId: number; - paymentReceiveId: number; - paymentReceive: IPaymentReceived; - oldPaymentReceive: IPaymentReceived; - paymentReceiveDTO: IPaymentReceivedEditDTO; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export interface IPaymentReceivedEditingPayload { - tenantId: number; - oldPaymentReceive: IPaymentReceived; - paymentReceiveDTO: IPaymentReceivedEditDTO; - trx: Knex.Transaction; -} - -export interface IPaymentReceivedDeletingPayload { - tenantId: number; - oldPaymentReceive: IPaymentReceived; - trx: Knex.Transaction; -} -export interface IPaymentReceivedDeletedPayload { - tenantId: number; - paymentReceiveId: number; - oldPaymentReceive: IPaymentReceived; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export enum PaymentReceiveAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - NotifyBySms = 'NotifyBySms', -} - -export type IPaymentReceiveGLCommonEntry = Pick< - ILedgerEntry, - | 'debit' - | 'credit' - | 'currencyCode' - | 'exchangeRate' - | 'transactionId' - | 'transactionType' - | 'transactionNumber' - | 'referenceNumber' - | 'date' - | 'userId' - | 'createdAt' - | 'branchId' ->; - -export interface PaymentReceiveMailOpts extends CommonMailOptions { - attachPdf?: boolean; -} - -export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {} - -export interface PaymentReceiveMailPresendEvent { - tenantId: number; - paymentReceiveId: number; - messageOptions: PaymentReceiveMailOptsDTO; -} - -export interface PaymentReceivedPdfLineItem { - item: string; - description: string; - rate: string; - quantity: string; - total: string; -} - -export interface PaymentReceivedPdfTax { - label: string; - amount: string; -} - -export interface PaymentReceivedPdfTemplateAttributes { - primaryColor: string; - secondaryColor: string; - showCompanyLogo: boolean; - companyLogo: string; - companyName: string; - - // Customer Address - showCustomerAddress: boolean; - customerAddress: string; - - // Company address - showCompanyAddress: boolean; - companyAddress: string; - billedToLabel: string; - - total: string; - totalLabel: string; - showTotal: boolean; - - subtotal: string; - subtotalLabel: string; - showSubtotal: boolean; - - lines: Array<{ - invoiceNumber: string; - invoiceAmount: string; - paidAmount: string; - }>; - - showPaymentReceivedNumber: boolean; - paymentReceivedNumberLabel: string; - paymentReceivedNumebr: string; - - paymentReceivedDate: string; - showPaymentReceivedDate: boolean; - paymentReceivedDateLabel: string; -} - -export interface IPaymentReceivedState { - defaultTemplateId: number; -} diff --git a/packages/server/src/interfaces/Plaid.ts b/packages/server/src/interfaces/Plaid.ts deleted file mode 100644 index 6142dab93..000000000 --- a/packages/server/src/interfaces/Plaid.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Knex } from "knex"; - -export interface IPlaidItemCreatedEventPayload { - tenantId: number; - plaidAccessToken: string; - plaidItemId: string; - plaidInstitutionId: string; -} - -export interface PlaidItemDTO { - publicToken: string; - institutionId: string; -} - -export interface PlaidAccount { - account_id: string; - balances: { - available: number; - current: number; - iso_currency_code: string; - limit: null; - unofficial_currency_code: null; - }; - mask: string; - name: string; - official_name: string; - persistent_account_id: string; - subtype: string; - type: string; -} - -export interface PlaidTransaction { - date: string; - account_id: string; - amount: number; - authorized_date: string; - name: string; - category: string[]; - check_number: number | null; - iso_currency_code: string; - transaction_id: string; - transaction_type: string; - payment_meta: { reference_number: string | null; payee: string | null }; -} - -export interface PlaidFetchedTransactionsUpdates { - added: any[]; - modified: any[]; - removed: any[]; - accessToken: string; - cursor: string; -} - -export interface SyncAccountsTransactionsTask { - tenantId: number; - plaidAccountId: number; - plaidTransactions: PlaidTransaction[]; -} - -export interface IPlaidTransactionsSyncedEventPayload { - tenantId: number; - plaidAccountId: number; - batch: string; - trx?: Knex.Transaction -} diff --git a/packages/server/src/interfaces/Preferences.ts b/packages/server/src/interfaces/Preferences.ts deleted file mode 100644 index 0017d6458..000000000 --- a/packages/server/src/interfaces/Preferences.ts +++ /dev/null @@ -1,6 +0,0 @@ - - - -export enum PreferencesAction { - Mutate = 'Mutate' -} \ No newline at end of file diff --git a/packages/server/src/interfaces/ProfitLossSheet.ts b/packages/server/src/interfaces/ProfitLossSheet.ts deleted file mode 100644 index 64b787667..000000000 --- a/packages/server/src/interfaces/ProfitLossSheet.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { - IFinancialSheetBranchesQuery, - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export enum ProfitLossAggregateNodeId { - INCOME = 'INCOME', - COS = 'COST_OF_SALES', - GROSS_PROFIT = 'GROSS_PROFIT', - EXPENSES = 'EXPENSES', - OTHER_INCOME = 'OTHER_INCOME', - OTHER_EXPENSES = 'OTHER_EXPENSES', - OPERATING_PROFIT = 'OPERATING_PROFIT', - NET_OTHER_INCOME = 'NET_OTHER_INCOME', - NET_INCOME = 'NET_INCOME', - NET_OPERATING_INCOME = 'NET_OPERATING_INCOME', -} - -export enum ProfitLossNodeType { - EQUATION = 'EQUATION', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', - AGGREGATE = 'AGGREGATE', -} -interface FinancialDateMeta { - date: Date; - formattedDate: string; -} -export interface IFinancialNodeWithPreviousPeriod { - previousPeriodFromDate?: FinancialDateMeta; - previousPeriodToDate?: FinancialDateMeta; - - previousPeriod?: IProfitLossSheetTotal; - previousPeriodChange?: IProfitLossSheetTotal; - previousPeriodPercentage?: IProfitLossSheetPercentage; -} -export interface IFinancialNodeWithPreviousYear { - previousYearFromDate: FinancialDateMeta; - previousYearToDate: FinancialDateMeta; - - previousYear?: IProfitLossSheetTotal; - previousYearChange?: IProfitLossSheetTotal; - previousYearPercentage?: IProfitLossSheetPercentage; -} -export interface IFinancialCommonNode { - total: IProfitLossSheetTotal; -} -export interface IFinancialCommonHorizDatePeriodNode { - fromDate: FinancialDateMeta; - toDate: FinancialDateMeta; - total: IProfitLossSheetTotal; -} -export interface IProfitLossSheetQuery extends IFinancialSheetBranchesQuery { - basis: string; - fromDate: Date; - toDate: Date; - numberFormat: INumberFormatQuery; - noneZero: boolean; - noneTransactions: boolean; - accountsIds: number[]; - - displayColumnsType: 'total' | 'date_periods'; - displayColumnsBy: string; - - percentageColumn: boolean; - percentageRow: boolean; - - percentageIncome: boolean; - percentageExpense: boolean; - - previousPeriod: boolean; - previousPeriodAmountChange: boolean; - previousPeriodPercentageChange: boolean; - - previousYear: boolean; - previousYearAmountChange: boolean; - previousYearPercentageChange: boolean; -} - -export interface IProfitLossSheetTotal { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface IProfitLossSheetPercentage { - amount: number; - formattedAmount: string; -} - -export interface IProfitLossHorizontalDatePeriodNode - extends IFinancialNodeWithPreviousYear, - IFinancialNodeWithPreviousPeriod { - fromDate: FinancialDateMeta; - toDate: FinancialDateMeta; - - total: IProfitLossSheetTotal; - - percentageRow?: IProfitLossSheetPercentage; - percentageColumn?: IProfitLossSheetPercentage; -} - -export interface IProfitLossSheetCommonNode - extends IFinancialNodeWithPreviousYear, - IFinancialNodeWithPreviousPeriod { - id: ProfitLossAggregateNodeId; - name: string; - - children?: IProfitLossSheetNode[]; - - total: IProfitLossSheetTotal; - horizontalTotals?: IProfitLossHorizontalDatePeriodNode[]; - - percentageRow?: IProfitLossSheetPercentage; - percentageColumn?: IProfitLossSheetPercentage; -} -export interface IProfitLossSheetAccountNode - extends IProfitLossSheetCommonNode { - nodeType: ProfitLossNodeType.ACCOUNT; -} -export interface IProfitLossSheetEquationNode - extends IProfitLossSheetCommonNode { - nodeType: ProfitLossNodeType.EQUATION; -} - -export interface IProfitLossSheetAccountsNode - extends IProfitLossSheetCommonNode { - nodeType: ProfitLossNodeType.ACCOUNTS; -} - -export type IProfitLossSheetNode = - | IProfitLossSheetAccountsNode - | IProfitLossSheetEquationNode - | IProfitLossSheetAccountNode; - -export interface IProfitLossSheetMeta extends IFinancialSheetCommonMeta{ - formattedDateRange: string; - formattedFromDate: string; - formattedToDate: string; -} - -// ------------------------------------------------ -// # SCHEMA NODES -// ------------------------------------------------ -export interface IProfitLossCommonSchemaNode { - id: ProfitLossAggregateNodeId; - name: string; - nodeType: ProfitLossNodeType; - children?: IProfitLossSchemaNode[]; - alwaysShow?: boolean; -} - -export interface IProfitLossEquationSchemaNode - extends IProfitLossCommonSchemaNode { - nodeType: ProfitLossNodeType.EQUATION; - equation: string; -} - -export interface IProfitLossAccountsSchemaNode - extends IProfitLossCommonSchemaNode { - nodeType: ProfitLossNodeType.ACCOUNTS; - accountsTypes: string[]; -} - -export type IProfitLossSchemaNode = - | IProfitLossCommonSchemaNode - | IProfitLossAccountsSchemaNode - | IProfitLossEquationSchemaNode; - -// ------------------------------ -// # Table -// ------------------------------ - -export enum ProfitLossSheetRowType { - AGGREGATE = 'AGGREGATE', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', - TOTAL = 'TOTAL', -} - - -export interface IProfitLossSheetTable extends IFinancialTable{ - meta: IProfitLossSheetMeta; - query: IProfitLossSheetQuery; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Project.ts b/packages/server/src/interfaces/Project.ts deleted file mode 100644 index 231eb69a7..000000000 --- a/packages/server/src/interfaces/Project.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Knex } from 'knex'; - -export interface IProjectCommonDTO { - contactId: number; - name: string; - deadline: Date; - costEstimate: number; -} - -export interface IProject { - id?: number; - name: string; - contactId: number; - deadline: number; - costEstimate: number; - status: string; -} - -export interface IProjectCreateDTO extends IProjectCommonDTO {} -export interface IProjectEditDTO extends IProjectCommonDTO {} - -export interface IProjectCreatePOJO extends IProject {} -export interface IProjectEditPOJO extends IProject {} - -export interface IProjectGetPOJO { - costEstimate: number; - costEstimateFormatted: string; - - deadlineFormatted: string; - contactDisplayName: string; - statusFormatted: string; - - totalActualHours: number; - totalEstimateHours: number; - totalInvoicedHours: number; - totalBillableHours: number; - - totalActualHoursAmount: number; - totalActualHoursAmountFormatted: string; - - totalEstimateHoursAmount: number; - totalEstimateHoursAmountFormatted: string; - - totalInvoicedHoursAmount: number; - totalInvoicedHoursAmountFormatted: string; - - totalBillableHoursAmount: number; - totalBillableHoursAmountFormatted: string; - - totalExpenses: number; - totalExpensesFormatted: string; - - totalInvoicedExpenses: number; - totalInvoicedExpensesFormatted: string; - - totalBillableExpenses: number; - totalBillableExpensesFormatted: string; - - totalInvoiced: number; - totalInvoicedFormatted: string; - - totalBillable: number; - totalBillableFormatted: string; -} - -export interface IProjectCreateEventPayload { - tenantId: number; - projectDTO: IProjectCreateDTO; -} - -export interface IProjectCreatedEventPayload { - tenantId: number; - projectDTO: IProjectCreateDTO; - project: IProject; - trx: Knex.Transaction; -} - -export interface IProjectCreatingEventPayload { - tenantId: number; - projectDTO: IProjectCreateDTO; - trx: Knex.Transaction; -} - -export interface IProjectDeleteEventPayload { - tenantId: number; - projectId: number; -} - -export interface IProjectDeletingEventPayload { - tenantId: number; - oldProject: IProject; - trx: Knex.Transaction; -} - -export interface IProjectDeletedEventPayload - extends IProjectDeletingEventPayload {} - -export interface IProjectEditEventPayload { - tenantId: number; - oldProject: IProject; - projectDTO: IProjectEditDTO; -} -export interface IProjectEditingEventPayload { - tenantId: number; - oldProject: IProject; - projectDTO: IProjectEditDTO; - trx: Knex.Transaction; -} -export interface IProjectEditedEventPayload { - tenantId: number; - project: IProject; - oldProject: IProject; - projectDTO: IProjectEditDTO; - trx: Knex.Transaction; -} - -export enum IProjectStatus { - Closed = 'Closed', - InProgress = 'InProgress', -} - -export interface ProjectBillableEntriesQuery { - toDate?: Date; - billableType?: ProjectBillableType[]; -} - -export interface ProjectBillableEntry { - billableType: string; - billableId: number; - billableAmount: number; - billableCurrency: string; - billableTransactionNo: string; -} - -export enum ProjectBillableType { - Task = 'Task', - Expense = 'Expense', - Bill = 'Bill', -} - -export enum ProjectAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} - -export enum ProjectTaskAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} - -export enum ProjectTimeAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} diff --git a/packages/server/src/interfaces/ProjectProfitabilitySummary.ts b/packages/server/src/interfaces/ProjectProfitabilitySummary.ts deleted file mode 100644 index ed213a2c5..000000000 --- a/packages/server/src/interfaces/ProjectProfitabilitySummary.ts +++ /dev/null @@ -1,54 +0,0 @@ -export class ProjectProfitabilitySummaryQuery { - fromDate: Date; - toDate: Date; - projectsIds?: number[]; -} - -export interface IProjectProfitabilitySummaryTotal { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface IProjectProfitabilitySummaryProjectNode { - projectId: number; - projectName: string; - projectStatus: any; - - customerName: string; - customerId: number; - - income: IProjectProfitabilitySummaryTotal; - expenses: IProjectProfitabilitySummaryTotal; - - profit: IProjectProfitabilitySummaryTotal; -} - -export interface IProjectProfitabilitySummaryTotalNode { - income: IProjectProfitabilitySummaryTotal; - expenses: IProjectProfitabilitySummaryTotal; - - profit: IProjectProfitabilitySummaryTotal; -} - -export interface IProjectProfitabilitySummaryData { - projects: IProjectProfitabilitySummaryProjectNode[]; - total: IProjectProfitabilitySummaryTotalNode; -} - -export interface IProjectProfitabilitySummaryMeta { - organizationName: string; - baseCurrency: string; -} - -export interface IProjectProfitabilitySummaryPOJO { - data: IProjectProfitabilitySummaryData; - query: ProjectProfitabilitySummaryQuery; - meta: IProjectProfitabilitySummaryMeta; -} - - -export enum IProjectProfitabilitySummaryRowType { - TOTAL = 'TOTAL', - PROJECT = 'PROJECT' -} \ No newline at end of file diff --git a/packages/server/src/interfaces/PurchasesByItemsSheet.ts b/packages/server/src/interfaces/PurchasesByItemsSheet.ts deleted file mode 100644 index fcd1ee8d9..000000000 --- a/packages/server/src/interfaces/PurchasesByItemsSheet.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface IPurchasesByItemsReportQuery { - fromDate: Date | string; - toDate: Date | string; - itemsIds: number[]; - numberFormat: INumberFormatQuery; - noneTransactions: boolean; - onlyActive: boolean; -} - -export interface IPurchasesByItemsSheetMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} - -export interface IPurchasesByItemsItem { - id: number; - name: string; - code: string; - quantitySold: number; - soldCost: number; - averageSellPrice: number; - - quantitySoldFormatted: string; - soldCostFormatted: string; - averageSellPriceFormatted: string; - currencyCode: string; -} - -export interface IPurchasesByItemsTotal { - quantitySold: number; - soldCost: number; - quantitySoldFormatted: string; - soldCostFormatted: string; - currencyCode: string; -} - -export type IPurchasesByItemsSheetData = { - items: IPurchasesByItemsItem[]; - total: IPurchasesByItemsTotal; -}; - -export interface IPurchasesByItemsSheet { - data: IPurchasesByItemsSheetData; - query: IPurchasesByItemsReportQuery; - meta: IPurchasesByItemsSheetMeta; -} - -export interface IPurchasesByItemsTable extends IFinancialTable { - query: IPurchasesByItemsReportQuery; - meta: IPurchasesByItemsSheetMeta; -} diff --git a/packages/server/src/interfaces/Resource.ts b/packages/server/src/interfaces/Resource.ts deleted file mode 100644 index d193a94c7..000000000 --- a/packages/server/src/interfaces/Resource.ts +++ /dev/null @@ -1,22 +0,0 @@ - - -export interface IResource { - id: number, - key: string, -} - -export interface IResourceField { - labelName: string, - key: string, - dataType: string, - helpText?: string | null, - default?: string, - predefined: boolean, - active: boolean, - builtin: boolean, - columnable: boolean, - index: number, - dataResource: string, - resourceId: number, - options: any; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Roles.ts b/packages/server/src/interfaces/Roles.ts deleted file mode 100644 index f9d338268..000000000 --- a/packages/server/src/interfaces/Roles.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Knex } from 'knex'; -import { Ability, RawRuleOf, ForcedSubject } from '@casl/ability'; - -export const actions = [ - 'manage', - 'create', - 'read', - 'update', - 'delete', -] as const; -export const subjects = ['Article', 'all'] as const; - -export type Abilities = [ - typeof actions[number], - ( - | typeof subjects[number] - | ForcedSubject> - ) -]; - -export type AppAbility = Ability; - -export const createAbility = (rules: RawRuleOf[]) => - new Ability(rules); - -export interface IRoleDTO { - roleName: string; - roleDescription: string; - permissions: ICreateRolePermissionDTO[]; -} - -export interface IEditRoleDTO extends IRoleDTO { - permissions: IEditRolePermissionDTO[]; -} - -export interface IRolePermissionDTO { - subject: string; - ability: string; - value: boolean; -} - -export interface ICreateRolePermissionDTO extends IRolePermissionDTO {} -export interface IEditRolePermissionDTO extends IRolePermissionDTO { - permissionId: number; -} - -export interface ICreateRoleDTO extends IRoleDTO {} - -export interface ISubjectAbilitySchema { - key: string; - label: string; - default?: boolean; -} - -export interface ISubjectAbilitiesSchema { - subject: string; - subjectLabel: string; - description?: string; - abilities?: ISubjectAbilitySchema[]; - extraAbilities?: ISubjectAbilitySchema[]; -} - -export interface IRole { - id?: number; - name: string; - slug: string; - description: string; - predefined: boolean; - permissions?: IRolePremission[]; -} - -export interface IRolePremission { - id?: number; - roleId?: number; - subject: string; - ability: string; - value: boolean; -} - -export enum AbilitySubject { - Item = 'Item', - InventoryAdjustment = 'InventoryAdjustment', - Report = 'Report', - Account = 'Account', - SaleInvoice = 'SaleInvoice', - SaleEstimate = 'SaleEstimate', - SaleReceipt = 'SaleReceipt', - PaymentReceive = 'PaymentReceive', - Bill = 'Bill', - PaymentMade = 'PaymentMade', - Expense = 'Expense', - Customer = 'Customer', - Vendor = 'Vendor', - Cashflow = 'Cashflow', - ManualJournal = 'ManualJournal', - Preferences = 'Preferences', - CreditNote = 'CreditNode', - VendorCredit = 'VendorCredit', - Project = 'Project', - TaxRate = 'TaxRate' -} - -export interface IRoleCreatedPayload { - tenantId: number; - createRoleDTO: ICreateRoleDTO; - role: IRole; - trx: Knex.Transaction; -} - -export interface IRoleEditedPayload { - editRoleDTO: IEditRoleDTO; - oldRole: IRole; - role: IRole; - trx: Knex.Transaction; -} - -export interface IRoleDeletedPayload { - oldRole: IRole; - roleId: number; - tenantId: number; - trx: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/SaleEstimate.ts b/packages/server/src/interfaces/SaleEstimate.ts deleted file mode 100644 index 88ffcf51c..000000000 --- a/packages/server/src/interfaces/SaleEstimate.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { Knex } from 'knex'; -import { IItemEntry, IItemEntryDTO } from './ItemEntry'; -import { IDynamicListFilterDTO } from '@/interfaces/DynamicFilter'; -import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable'; -import { AttachmentLinkDTO } from './Attachments'; -import { DiscountType } from './SaleInvoice'; - -export interface ISaleEstimate { - id?: number; - amount: number; - currencyCode: string; - customerId: number; - estimateDate: Date; - estimateNumber: string; - reference: string; - note: string; - termsConditions: string; - userId: number; - entries: IItemEntry[]; - sendToEmail: string; - createdAt?: Date; - deliveredAt: string | Date; - isConvertedToInvoice: boolean; - isDelivered: boolean; - - branchId?: number; - warehouseId?: number; - - total?: number; - totalLocal?: number; - - discountAmount?: number; - discountPercentage?: number | null; - - adjustment?: number; -} -export interface ISaleEstimateDTO { - customerId: number; - exchangeRate?: number; - estimateDate?: Date; - reference?: string; - estimateNumber?: string; - entries: IItemEntryDTO[]; - note: string; - termsConditions: string; - sendToEmail: string; - delivered: boolean; - - branchId?: number; - warehouseId?: number; - attachments?: AttachmentLinkDTO[]; - - // # Discount - discount?: number; - discountType?: DiscountType; - - // # Adjustment - adjustment?: number; -} - -export interface ISalesEstimatesFilter extends IDynamicListFilterDTO { - stringifiedFilterRoles?: string; - filterQuery?: (q: any) => void; -} - -export interface ISalesEstimatesService { - validateCustomerHasNoEstimates( - tenantId: number, - customerId: number - ): Promise; -} - -export interface ISaleEstimateCreatedPayload { - tenantId: number; - saleEstimate: ISaleEstimate; - saleEstimateId: number; - saleEstimateDTO: ISaleEstimateDTO; - trx: Knex.Transaction; -} - -export interface ISaleEstimateCreatingPayload { - estimateDTO: ISaleEstimateDTO; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ISaleEstimateEditedPayload { - tenantId: number; - estimateId: number; - saleEstimate: ISaleEstimate; - oldSaleEstimate: ISaleEstimate; - estimateDTO: ISaleEstimateDTO; - trx: Knex.Transaction; -} - -export interface ISaleEstimateEditingPayload { - tenantId: number; - oldSaleEstimate: ISaleEstimate; - estimateDTO: ISaleEstimateDTO; - trx: Knex.Transaction; -} - -export interface ISaleEstimateDeletedPayload { - tenantId: number; - saleEstimateId: number; - oldSaleEstimate: ISaleEstimate; - trx: Knex.Transaction; -} - -export interface ISaleEstimateDeletingPayload { - tenantId: number; - oldSaleEstimate: ISaleEstimate; - trx: Knex.Transaction; -} - -export interface ISaleEstimateEventDeliveredPayload { - tenantId: number; - saleEstimate: ISaleEstimate; - trx: Knex.Transaction; -} - -export interface ISaleEstimateEventDeliveringPayload { - tenantId: number; - oldSaleEstimate: ISaleEstimate; - trx: Knex.Transaction; -} - -export enum SaleEstimateAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - NotifyBySms = 'NotifyBySms', -} - -export interface ISaleEstimateApprovingEvent { - tenantId: number; - oldSaleEstimate: ISaleEstimate; - trx: Knex.Transaction; -} - -export interface ISaleEstimateApprovedEvent { - tenantId: number; - oldSaleEstimate: ISaleEstimate; - saleEstimate: ISaleEstimate; - trx: Knex.Transaction; -} - -export interface SaleEstimateMailOptions extends CommonMailOptions { - attachEstimate?: boolean; -} - -export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO { - attachEstimate?: boolean; -} - -export interface ISaleEstimateMailPresendEvent { - tenantId: number; - saleEstimateId: number; - messageOptions: SaleEstimateMailOptionsDTO; -} - -export interface ISaleEstimateState { - defaultTemplateId: number; -} diff --git a/packages/server/src/interfaces/SaleInvoice.ts b/packages/server/src/interfaces/SaleInvoice.ts deleted file mode 100644 index b7f208ac0..000000000 --- a/packages/server/src/interfaces/SaleInvoice.ts +++ /dev/null @@ -1,391 +0,0 @@ -import { Knex } from 'knex'; -import { ISystemUser, IAccount, ITaxTransaction } from '@/interfaces'; -import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable'; -import { IDynamicListFilter } from '@/interfaces/DynamicFilter'; -import { IItemEntry, IItemEntryDTO } from './ItemEntry'; -import { AttachmentLinkDTO } from './Attachments'; - -export interface PaymentIntegrationTransactionLink { - id: number; - enable: true; - paymentIntegrationId: number; - referenceType: string; - referenceId: number; -} - -export interface PaymentIntegrationTransactionLinkEventPayload { - tenantId: number; - enable: true; - paymentIntegrationId: number; - referenceType: string; - referenceId: number; - saleInvoiceId: number; - trx?: Knex.Transaction; -} - -export interface PaymentIntegrationTransactionLinkDeleteEventPayload { - tenantId: number; - enable: true; - paymentIntegrationId: number; - referenceType: string; - referenceId: number; - oldSaleInvoiceId: number; - trx?: Knex.Transaction; -} - -export interface ISaleInvoice { - id: number; - amount: number; - amountLocal?: number; - paymentAmount: number; - currencyCode: string; - exchangeRate?: number; - invoiceDate: Date; - dueDate: Date; - dueAmount: number; - overdueDays: number; - customerId: number; - referenceNo: string; - invoiceNo: string; - isWrittenoff: boolean; - entries: IItemEntry[]; - deliveredAt: string | Date; - userId: number; - createdAt: Date; - isDelivered: boolean; - - warehouseId?: number; - branchId?: number; - projectId?: number; - - writtenoffAmount?: number; - writtenoffAmountLocal?: number; - writtenoffExpenseAccountId?: number; - writtenoffExpenseAccount?: IAccount; - - taxAmountWithheld: number; - taxAmountWithheldLocal: number; - taxes: ITaxTransaction[]; - - total: number; - totalLocal: number; - - subtotal: number; - subtotalLocal: number; - subtotalExludingTax: number; - - termsConditions: string; - invoiceMessage: string; - - pdfTemplateId?: number; - - paymentMethods?: Array; - - adjustment?: number; - adjustmentLocal?: number | null; - - discount?: number; - discountAmount?: number; - discountAmountLocal?: number | null; -} - -export enum DiscountType { - Percentage = 'percentage', - Amount = 'amount', -} - -export interface ISaleInvoiceDTO { - invoiceDate: Date; - dueDate: Date; - referenceNo: string; - invoiceNo: string; - customerId: number; - exchangeRate?: number; - invoiceMessage: string; - termsConditions: string; - isTaxExclusive: boolean; - entries: IItemEntryDTO[]; - delivered: boolean; - - warehouseId?: number | null; - projectId?: number; - branchId?: number | null; - - isInclusiveTax?: boolean; - - attachments?: AttachmentLinkDTO[]; - - // # Discount - discount?: number; - discountType?: DiscountType; - - // # Adjustments - adjustments?: string; -} - -export interface ISaleInvoiceCreateDTO extends ISaleInvoiceDTO { - fromEstimateId: number; -} - -export interface ISaleInvoiceEditDTO extends ISaleInvoiceDTO {} - -export interface ISalesInvoicesFilter extends IDynamicListFilter { - page: number; - pageSize: number; - searchKeyword?: string; - filterQuery?: (q: Knex.QueryBuilder) => void; -} - -export interface ISalesInvoicesService { - validateCustomerHasNoInvoices( - tenantId: number, - customerId: number - ): Promise; -} - -export interface ISaleInvoiceWriteoffDTO { - expenseAccountId: number; - date: Date; - reason: string; -} - -export type InvoiceNotificationType = 'details' | 'reminder'; - -export interface ISaleInvoiceCreatedPayload { - tenantId: number; - saleInvoice: ISaleInvoice; - saleInvoiceDTO: ISaleInvoiceCreateDTO; - saleInvoiceId: number; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceCreatingPaylaod { - tenantId: number; - saleInvoiceDTO: ISaleInvoiceCreateDTO; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceEditedPayload { - tenantId: number; - saleInvoice: ISaleInvoice; - oldSaleInvoice: ISaleInvoice; - saleInvoiceDTO: ISaleInvoiceEditDTO; - saleInvoiceId: number; - authorizedUser: ISystemUser; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceEditingPayload { - tenantId: number; - oldSaleInvoice: ISaleInvoice; - saleInvoiceDTO: ISaleInvoiceEditDTO; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceDeletePayload { - tenantId: number; - oldSaleInvoice: ISaleInvoice; - saleInvoiceId: number; -} - -export interface ISaleInvoiceDeletingPayload { - tenantId: number; - oldSaleInvoice: ISaleInvoice; - saleInvoiceId: number; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceDeletedPayload { - tenantId: number; - oldSaleInvoice: ISaleInvoice; - saleInvoiceId: number; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceWriteoffCreatePayload { - tenantId: number; - saleInvoiceId: number; - saleInvoice: ISaleInvoice; - writeoffDTO: ISaleInvoiceWriteoffDTO; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceWriteoffCreatedPayload { - tenantId: number; - saleInvoiceId: number; - saleInvoice: ISaleInvoice; - writeoffDTO: ISaleInvoiceCreatedPayload; -} - -export interface ISaleInvoiceWrittenOffCancelPayload { - tenantId: number; - saleInvoice: ISaleInvoice; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceWrittenOffCanceledPayload { - tenantId: number; - saleInvoice: ISaleInvoice; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceEventDeliveredPayload { - tenantId: number; - saleInvoiceId: number; - saleInvoice: ISaleInvoice; - trx: Knex.Transaction; -} - -export interface ISaleInvoiceDeliveringPayload { - tenantId: number; - oldSaleInvoice: ISaleInvoice; - trx: Knex.Transaction; -} - -export enum SaleInvoiceAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - Writeoff = 'Writeoff', - NotifyBySms = 'NotifyBySms', -} - -export interface SaleInvoiceMailOptions extends CommonMailOptions { - attachInvoice?: boolean; - formatArgs?: Record; -} - -export interface SaleInvoiceMailState extends SaleInvoiceMailOptions { - invoiceNo: string; - - invoiceDate: string; - invoiceDateFormatted: string; - - dueDate: string; - dueDateFormatted: string; - - total: number; - totalFormatted: string; - - subtotal: number; - subtotalFormatted: number; - - companyName: string; - companyLogoUri: string; - - customerName: string; - - // # Invoice entries - entries?: Array<{ label: string; total: string; quantity: string | number }>; -} - -export interface SendInvoiceMailDTO extends CommonMailOptionsDTO { - attachInvoice?: boolean; -} - -export interface ISaleInvoiceNotifyPayload { - tenantId: number; - saleInvoiceId: number; - messageDTO: SendInvoiceMailDTO; -} - -export interface ISaleInvoiceMailSend { - tenantId: number; - saleInvoiceId: number; - messageOptions: SendInvoiceMailDTO; - formattedMessageOptions: SaleInvoiceMailOptions; -} - -export interface ISaleInvoiceMailSent { - tenantId: number; - saleInvoiceId: number; - messageOptions: SendInvoiceMailDTO; -} - -// Invoice Pdf Document -export interface InvoicePdfLine { - item: string; - description: string; - rate: string; - quantity: string; - total: string; -} - -export interface InvoicePdfTax { - label: string; - amount: string; -} - -export interface InvoicePdfTemplateAttributes { - primaryColor: string; - secondaryColor: string; - - companyName: string; - - showCompanyLogo: boolean; - companyLogo: string; - - dueDate: string; - dueDateLabel: string; - showDueDate: boolean; - - dateIssue: string; - dateIssueLabel: string; - showDateIssue: boolean; - - invoiceNumberLabel: string; - invoiceNumber: string; - showInvoiceNumber: boolean; - - // Customer Address - showCustomerAddress: boolean; - customerAddress: string; - - // Company address - showCompanyAddress: boolean; - companyAddress: string; - billedToLabel: string; - - lineItemLabel: string; - lineDescriptionLabel: string; - lineRateLabel: string; - lineTotalLabel: string; - - totalLabel: string; - subtotalLabel: string; - discountLabel: string; - paymentMadeLabel: string; - - showTotal: boolean; - showSubtotal: boolean; - showDiscount: boolean; - showTaxes: boolean; - showPaymentMade: boolean; - - total: string; - subtotal: string; - discount: string; - paymentMade: string; - - // Due Amount - dueAmount: string; - showDueAmount: boolean; - dueAmountLabel: string; - - termsConditionsLabel: string; - showTermsConditions: boolean; - termsConditions: string; - - lines: InvoicePdfLine[]; - taxes: InvoicePdfTax[]; - - statementLabel: string; - showStatement: boolean; - statement: string; -} - -export interface ISaleInvocieState { - defaultTemplateId: number; -} diff --git a/packages/server/src/interfaces/SaleReceipt.ts b/packages/server/src/interfaces/SaleReceipt.ts deleted file mode 100644 index 8d854d46b..000000000 --- a/packages/server/src/interfaces/SaleReceipt.ts +++ /dev/null @@ -1,238 +0,0 @@ -import { Knex } from 'knex'; -import { IItemEntry } from './ItemEntry'; -import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable'; -import { AttachmentLinkDTO } from './Attachments'; -import { DiscountType } from './SaleInvoice'; - -export interface ISaleReceipt { - id?: number; - customerId: number; - depositAccountId: number; - receiptDate: Date; - sendToEmail: string; - referenceNo: string; - receiptMessage: string; - receiptNumber: string; - amount: number; - currencyCode: string; - exchangeRate: number; - statement: string; - closedAt: Date | string; - - createdAt: Date; - updatedAt: Date; - userId: number; - - branchId?: number; - warehouseId?: number; - - localAmount?: number; - entries?: IItemEntry[]; - - subtotal?: number; - subtotalLocal?: number; - - total?: number; - totalLocal?: number; - - discountAmount: number; - discountPercentage?: number | null; - - adjustment?: number; - adjustmentLocal?: number | null; - - discountAmountLocal?: number | null; -} - -export interface ISalesReceiptsFilter { - filterQuery?: (query: any) => void; -} - -export interface ISaleReceiptDTO { - customerId: number; - exchangeRate?: number; - depositAccountId: number; - receiptDate: Date; - sendToEmail: string; - referenceNo?: string; - receiptNumber?: string; - receiptMessage: string; - statement: string; - closed: boolean; - entries: any[]; - branchId?: number; - attachments?: AttachmentLinkDTO[]; - - discount?: number; - discountType?: DiscountType; - - adjustment?: number; -} - -export interface ISalesReceiptsService { - createSaleReceipt( - tenantId: number, - saleReceiptDTO: ISaleReceiptDTO - ): Promise; - - editSaleReceipt(tenantId: number, saleReceiptId: number): Promise; - - deleteSaleReceipt(tenantId: number, saleReceiptId: number): Promise; - - salesReceiptsList( - tennatid: number, - salesReceiptsFilter: ISalesReceiptsFilter - ): Promise<{ - salesReceipts: ISaleReceipt[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }>; - - validateCustomerHasNoReceipts( - tenantId: number, - customerId: number - ): Promise; -} - -export interface ISaleReceiptSmsDetails { - customerName: string; - customerPhoneNumber: string; - smsMessage: string; -} -export interface ISaleReceiptCreatingPayload { - saleReceiptDTO: ISaleReceiptDTO; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ISaleReceiptCreatedPayload { - tenantId: number; - saleReceipt: ISaleReceipt; - saleReceiptId: number; - saleReceiptDTO: ISaleReceiptDTO; - trx: Knex.Transaction; -} - -export interface ISaleReceiptEditedPayload { - tenantId: number; - oldSaleReceipt: number; - saleReceipt: ISaleReceipt; - saleReceiptId: number; - saleReceiptDTO: ISaleReceiptDTO; - trx: Knex.Transaction; -} - -export interface ISaleReceiptEditingPayload { - tenantId: number; - oldSaleReceipt: ISaleReceipt; - saleReceiptDTO: ISaleReceiptDTO; - trx: Knex.Transaction; -} -export interface ISaleReceiptEventClosedPayload { - tenantId: number; - saleReceiptId: number; - saleReceipt: ISaleReceipt; - trx: Knex.Transaction; -} - -export interface ISaleReceiptEventClosingPayload { - tenantId: number; - oldSaleReceipt: ISaleReceipt; - trx: Knex.Transaction; -} - -export interface ISaleReceiptEventDeletedPayload { - tenantId: number; - saleReceiptId: number; - oldSaleReceipt: ISaleReceipt; - trx: Knex.Transaction; -} - -export enum SaleReceiptAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - NotifyBySms = 'NotifyBySms', -} - -export interface ISaleReceiptDeletingPayload { - tenantId: number; - oldSaleReceipt: ISaleReceipt; - trx: Knex.Transaction; -} - -export interface SaleReceiptMailOpts extends CommonMailOptions { - attachReceipt: boolean; -} - -export interface SaleReceiptMailOptsDTO extends CommonMailOptionsDTO { - attachReceipt?: boolean; -} - -export interface ISaleReceiptMailPresend { - tenantId: number; - saleReceiptId: number; - messageOptions: SaleReceiptMailOptsDTO; -} - -export interface ISaleReceiptBrandingTemplateAttributes { - primaryColor: string; - secondaryColor: string; - showCompanyLogo: boolean; - companyLogo: string; - companyName: string; - - // Customer Address - showCustomerAddress: boolean; - customerAddress: string; - - // Company address - showCompanyAddress: boolean; - companyAddress: string; - billedToLabel: string; - - // Total - total: string; - totalLabel: string; - showTotal: boolean; - - // Subtotal - subtotal: string; - subtotalLabel: string; - showSubtotal: boolean; - - // Customer Note - showCustomerNote: boolean; - customerNote: string; - customerNoteLabel: string; - - // Terms & Conditions - showTermsConditions: boolean; - termsConditions: string; - termsConditionsLabel: string; - - // Lines - lines: Array<{ - item: string; - description: string; - rate: string; - quantity: string; - total: string; - }>; - - // Receipt Number - showReceiptNumber: boolean; - receiptNumberLabel: string; - receiptNumebr: string; - - // Receipt Date - receiptDate: string; - showReceiptDate: boolean; - receiptDateLabel: string; -} - - -export interface ISaleReceiptState { - defaultTemplateId: number; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/SalesByItemsSheet.ts b/packages/server/src/interfaces/SalesByItemsSheet.ts deleted file mode 100644 index 789ebae77..000000000 --- a/packages/server/src/interfaces/SalesByItemsSheet.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface ISalesByItemsReportQuery { - fromDate: Date | string; - toDate: Date | string; - itemsIds: number[]; - numberFormat: INumberFormatQuery; - noneTransactions: boolean; - onlyActive: boolean; -} - -export interface ISalesByItemsSheetMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} - -export interface ISalesByItemsItem { - id: number; - name: string; - code: string; - quantitySold: number; - soldCost: number; - averageSellPrice: number; - - quantitySoldFormatted: string; - soldCostFormatted: string; - averageSellPriceFormatted: string; - currencyCode: string; -} - -export interface ISalesByItemsTotal { - quantitySold: number; - soldCost: number; - quantitySoldFormatted: string; - soldCostFormatted: string; - currencyCode: string; -} - -export type ISalesByItemsSheetData = { - items: ISalesByItemsItem[]; - total: ISalesByItemsTotal; -}; - -export interface ISalesByItemsSheet { - data: ISalesByItemsSheetData; - query: ISalesByItemsReportQuery; - meta: ISalesByItemsSheetMeta; -} - -export interface ISalesByItemsTable extends IFinancialTable { - query: ISalesByItemsReportQuery; - meta: ISalesByItemsSheetMeta; -} diff --git a/packages/server/src/interfaces/SalesTaxLiabilitySummary.ts b/packages/server/src/interfaces/SalesTaxLiabilitySummary.ts deleted file mode 100644 index b37d8a384..000000000 --- a/packages/server/src/interfaces/SalesTaxLiabilitySummary.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { IFinancialSheetCommonMeta } from "./FinancialStatements"; -import { IFinancialTable } from "./Table"; - -export interface SalesTaxLiabilitySummaryQuery { - fromDate: Date; - toDate: Date; - basis: 'cash' | 'accrual'; -} - -export interface SalesTaxLiabilitySummaryAmount { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface SalesTaxLiabilitySummaryTotal { - taxableAmount: SalesTaxLiabilitySummaryAmount; - taxAmount: SalesTaxLiabilitySummaryAmount; - collectedTaxAmount: SalesTaxLiabilitySummaryAmount; -} - -export interface SalesTaxLiabilitySummaryRate { - id: number; - taxName: string; - taxableAmount: SalesTaxLiabilitySummaryAmount; - taxAmount: SalesTaxLiabilitySummaryAmount; - taxPercentage: any; - collectedTaxAmount: SalesTaxLiabilitySummaryAmount; -} - -export enum SalesTaxLiabilitySummaryTableRowType { - TaxRate = 'TaxRate', - Total = 'Total', -} - -export interface SalesTaxLiabilitySummaryReportData { - taxRates: SalesTaxLiabilitySummaryRate[]; - total: SalesTaxLiabilitySummaryTotal; -} - -export type SalesTaxLiabilitySummaryPayableById = Record< - string, - { taxRateId: number; credit: number; debit: number } ->; - -export type SalesTaxLiabilitySummarySalesById = Record< - string, - { taxRateId: number; credit: number; debit: number } ->; - -export interface SalesTaxLiabilitySummaryMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} - -export interface ISalesTaxLiabilitySummaryTable extends IFinancialTable { - query: SalesTaxLiabilitySummaryQuery; - meta: SalesTaxLiabilitySummaryMeta; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Setup.ts b/packages/server/src/interfaces/Setup.ts deleted file mode 100644 index 32c8fe97b..000000000 --- a/packages/server/src/interfaces/Setup.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { ISystemUser } from '@/interfaces'; - -export interface IOrganizationSetupDTO { - organizationName: string; - baseCurrency: string; - fiscalYear: string; - industry: string; - timeZone: string; -} - -export interface IOrganizationBuildDTO { - name: string; - industry: string; - location: string; - baseCurrency: string; - timezone: string; - fiscalYear: string; - dateFormat?: string; -} - -interface OrganizationAddressDTO { - address1: string; - address2: string; - postalCode: string; - city: string; - stateProvince: string; - phone: string; -} - -export interface IOrganizationUpdateDTO { - name: string; - location?: string; - baseCurrency?: string; - timezone?: string; - fiscalYear?: string; - industry?: string; - taxNumber?: string; - primaryColor?: string; - logoKey?: string; - address?: OrganizationAddressDTO; -} - -export interface IOrganizationBuildEventPayload { - tenantId: number; - buildDTO: IOrganizationBuildDTO; - systemUser: ISystemUser; -} - -export interface IOrganizationBuiltEventPayload { - tenantId: number; -} diff --git a/packages/server/src/interfaces/SmsNotifications.ts b/packages/server/src/interfaces/SmsNotifications.ts deleted file mode 100644 index 2649f0deb..000000000 --- a/packages/server/src/interfaces/SmsNotifications.ts +++ /dev/null @@ -1,51 +0,0 @@ -export interface ISmsNotificationAllowedVariable { - variable: string; - description: string; -} -export interface ISmsNotificationDefined { - notificationLabel: string; - notificationDescription: string; - key: string; - module: string; - moduleFormatted: string; - allowedVariables: ISmsNotificationAllowedVariable[]; - - defaultSmsMessage: string; - defaultIsNotificationEnabled: boolean; -} - -export interface ISmsNotificationMeta { - notificationLabel: string; - notificationDescription: string; - key: string; - module: string; - moduleFormatted: string; - allowedVariables: ISmsNotificationAllowedVariable[]; - smsMessage: string; - isNotificationEnabled: boolean; -} - -export interface IEditSmsNotificationDTO { - notificationKey: string; - messageText: string; - isNotificationEnabled: boolean; -} - -export interface ISaleInvoiceSmsDetailsDTO { - notificationKey: 'details' | 'reminder'; -} - -export interface ISaleInvoiceSmsDetails { - customerName: string; - customerPhoneNumber: string; - smsMessage: string; -} - -export enum SMS_NOTIFICATION_KEY { - SALE_INVOICE_DETAILS = 'sale-invoice-details', - SALE_INVOICE_REMINDER = 'sale-invoice-reminder', - SALE_ESTIMATE_DETAILS = 'sale-estimate-details', - SALE_RECEIPT_DETAILS = 'sale-receipt-details', - PAYMENT_RECEIVE_DETAILS = 'payment-receive-details', - CUSTOMER_BALANCE = 'customer-balance', -} diff --git a/packages/server/src/interfaces/StripePayment.ts b/packages/server/src/interfaces/StripePayment.ts deleted file mode 100644 index 41b1d6e23..000000000 --- a/packages/server/src/interfaces/StripePayment.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface StripePaymentLinkCreatedEventPayload { - tenantId: number; - paymentLinkId: string; - saleInvoiceId: number; - stripeIntegrationId: number; -} - -export interface StripeCheckoutSessionCompletedEventPayload { - event: any; -} - -export interface StripeInvoiceCheckoutSessionPOJO { - sessionId: string; - publishableKey: string; - redirectTo: string; -} - -export interface StripeWebhookEventPayload { - event: any; -} diff --git a/packages/server/src/interfaces/Subscription.ts b/packages/server/src/interfaces/Subscription.ts deleted file mode 100644 index 90afdaf77..000000000 --- a/packages/server/src/interfaces/Subscription.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface SubscriptionPayload { - lemonSqueezyId?: string; -} - -export enum SubscriptionPaymentStatus { - Succeed = 'succeed', - Failed = 'failed', -} diff --git a/packages/server-nest/src/interfaces/SubscriptionPlan.ts b/packages/server/src/interfaces/SubscriptionPlan.ts similarity index 100% rename from packages/server-nest/src/interfaces/SubscriptionPlan.ts rename to packages/server/src/interfaces/SubscriptionPlan.ts diff --git a/packages/server/src/interfaces/Table.ts b/packages/server/src/interfaces/Table.ts deleted file mode 100644 index a567d2d92..000000000 --- a/packages/server/src/interfaces/Table.ts +++ /dev/null @@ -1,40 +0,0 @@ -export interface IColumnMapperMeta { - key: string; - accessor?: string; - value?: string; -} - -export interface ITableCell { - value: string; - key: string; -} - -export type ITableRow = { - cells: ITableCell[]; -}; - -export interface ITableColumn { - key: string; - label: string; - cellIndex?: number; - children?: ITableColumn[]; -} - -export interface ITable { - columns: ITableColumn[]; - data: ITableRow[]; -} - -export interface ITableColumnAccessor { - key: string; - accessor: string; -} - -export interface ITableData { - columns: ITableColumn[]; - rows: ITableRow[]; -} - -export interface IFinancialTable { - table: ITableData; -} diff --git a/packages/server/src/interfaces/Tasks.ts b/packages/server/src/interfaces/Tasks.ts deleted file mode 100644 index c3b3fc70e..000000000 --- a/packages/server/src/interfaces/Tasks.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Knex } from 'knex'; -import { ProjectTaskChargeType } from '@/services/Projects/Tasks/constants'; - -export interface IProjectTask { - id?: number; - name: string; - chargeType: string; - estimateHours: number; - actualHours: number; - invoicedHours: number; - billableHours: number; - projectId: number; - - billableAmount?: number; - createdAt?: Date|string; -} - -export interface BaseTaskDTO { - name: string; - rate: number; - chargeType: ProjectTaskChargeType; - estimateHours: number; -} -export interface ICreateTaskDTO extends BaseTaskDTO {} -export interface IEditTaskDTO extends BaseTaskDTO {} - -export interface IProjectTaskCreatePOJO extends IProjectTask {} -export interface IProjectTaskEditPOJO extends IProjectTask {} -export interface IProjectTaskGetPOJO extends IProjectTask {} - -export interface ITaskCreateEventPayload { - tenantId: number; - taskDTO: ICreateTaskDTO; -} -export interface ITaskCreatedEventPayload { - tenantId: number; - taskDTO: ICreateTaskDTO; - task: any; - trx: Knex.Transaction; -} -export interface ITaskCreatingEventPayload { - tenantId: number; - taskDTO: ICreateTaskDTO; - trx: Knex.Transaction; -} -export interface ITaskDeleteEventPayload { - tenantId: number; - taskId: number; -} -export interface ITaskDeletingEventPayload { - tenantId: number; - oldTask: IProjectTask; - trx: Knex.Transaction; -} -export interface ITaskDeletedEventPayload { - tenantId: number; - oldTask: IProjectTask; - task: IProjectTask; - trx: Knex.Transaction; -} -export interface ITaskEditEventPayload { - tenantId: number; - taskId: number; - taskDTO: IEditTaskDTO; -} -export interface ITaskEditingEventPayload { - tenantId: number; - oldTask: IProjectTask; - taskDTO: IEditTaskDTO; - trx: Knex.Transaction; -} -export interface ITaskEditedEventPayload { - tenantId: number; - oldTask: IProjectTask; - task: IProjectTask; - taskDTO: IEditTaskDTO; - trx: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/TaxRate.ts b/packages/server/src/interfaces/TaxRate.ts deleted file mode 100644 index d1e27383d..000000000 --- a/packages/server/src/interfaces/TaxRate.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Knex } from 'knex'; - -export interface ITaxRate { - id?: number; - name: string; - code: string; - rate: number; - description: string; - IsNonRecoverable: boolean; - IsCompound: boolean; - active: boolean; -} - -export interface ICommonTaxRateDTO { - name: string; - code: string; - rate: number; - description: string; - IsNonRecoverable: boolean; - IsCompound: boolean; - active: boolean; -} -export interface ICreateTaxRateDTO extends ICommonTaxRateDTO {} -export interface IEditTaxRateDTO extends ICommonTaxRateDTO {} - -export interface ITaxRateCreatingPayload { - createTaxRateDTO: ICreateTaxRateDTO; - tenantId: number; - trx: Knex.Transaction; -} -export interface ITaxRateCreatedPayload { - createTaxRateDTO: ICreateTaxRateDTO; - taxRate: ITaxRate; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ITaxRateEditingPayload { - oldTaxRate: ITaxRate; - editTaxRateDTO: IEditTaxRateDTO; - tenantId: number; - trx: Knex.Transaction; -} -export interface ITaxRateEditedPayload { - editTaxRateDTO: IEditTaxRateDTO; - oldTaxRate: ITaxRate; - taxRate: ITaxRate; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ITaxRateDeletingPayload { - oldTaxRate: ITaxRate; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ITaxRateActivatingPayload { - taxRateId: number; - tenantId: number; - trx: Knex.Transaction; -} -export interface ITaxRateActivatedPayload { - taxRateId: number; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ITaxRateDeletedPayload { - oldTaxRate: ITaxRate; - tenantId: number; - trx: Knex.Transaction; -} - -export interface ITaxTransaction { - id?: number; - taxRateId: number; - referenceType: string; - referenceId: number; - rate: number; - taxAccountId: number; -} - -export enum TaxRateAction { - CREATE = 'Create', - EDIT = 'Edit', - DELETE = 'Delete', - VIEW = 'View', -} diff --git a/packages/server/src/interfaces/Tenancy.ts b/packages/server/src/interfaces/Tenancy.ts deleted file mode 100644 index 3c8ae2f71..000000000 --- a/packages/server/src/interfaces/Tenancy.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Knex } from 'knex'; - -export interface ITenantMetadata { - currencyCode: string; -} -export interface ITenant { - id: number, - organizationId: string, - - initializedAt: Date|null, - seededAt: Date|null, - builtAt: Date|null, - createdAt: Date|null, - - metadata?: ITenantMetadata -} - -export interface ITenantDBManager { - constructor(); - - databaseExists(tenant: ITenant): Promise; - createDatabase(tenant: ITenant): Promise; - - migrate(tenant: ITenant): Promise; - seed(tenant: ITenant): Promise; - - setupKnexInstance(tenant: ITenant): Knex; - getKnexInstance(tenantId: number): Knex; -} - -export interface ITenantManager { - tenantDBManager: ITenantDBManager; - tenant: ITenant; - - constructor(): void; - - createTenant(): Promise; - createDatabase(tenant: ITenant): Promise; - hasDatabase(tenant: ITenant): Promise; - - dropTenant(tenant: ITenant): Promise; - - migrateTenant(tenant: ITenant): Promise; - seedTenant(tenant: ITenant): Promise; - - setupKnexInstance(tenant: ITenant): Knex; - getKnexInstance(tenantId: number): Knex; -} - -export interface ISystemService { - cache(); - repositories(); - knex(); -} \ No newline at end of file diff --git a/packages/server-nest/src/interfaces/Tenant.ts b/packages/server/src/interfaces/Tenant.ts similarity index 100% rename from packages/server-nest/src/interfaces/Tenant.ts rename to packages/server/src/interfaces/Tenant.ts diff --git a/packages/server/src/interfaces/Times.ts b/packages/server/src/interfaces/Times.ts deleted file mode 100644 index 2e9f44a5b..000000000 --- a/packages/server/src/interfaces/Times.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; - -export interface IProjectTime { - id?: number; - duration: number; - description: string; - date: string | Date; - taskId: number; - projectId: number; -} -export interface BaseProjectTimeDTO { - name: string; - rate: number; - chargeType: string; - estimateHours: number; -} -export interface IProjectTimeCreateDTO extends BaseProjectTimeDTO {} -export interface IProjectTimeEditDTO extends BaseProjectTimeDTO {} - -export interface IProjectTimeCreatePOJO extends IProjectTime {} -export interface IProjectTimeEditPOJO extends IProjectTime{} -export interface IProjectTimeGetPOJO extends IProjectTime{} - -export interface IProjectTimeCreateEventPayload { - tenantId: number; - timeDTO: IProjectTimeCreateDTO; -} -export interface IProjectTimeCreatedEventPayload { - tenantId: number; - timeDTO: IProjectTimeEditDTO; - time: any; - trx: Knex.Transaction; -} -export interface IProjectTimeCreatingEventPayload { - tenantId: number; - timeDTO: IProjectTimeEditDTO; - trx: Knex.Transaction; -} -export interface IProjectTimeDeleteEventPayload { - tenantId: number; - timeId: number; - trx?: Knex.Transaction; -} -export interface IProjectTimeDeletingEventPayload { - tenantId: number; - oldTime: IProjectTime; - trx: Knex.Transaction; -} -export interface IProjectTimeDeletedEventPayload { - tenantId: number; - oldTime: IProjectTime; - trx: Knex.Transaction; -} -export interface IProjectTimeEditEventPayload { - tenantId: number; - oldTime: IProjectTime; - timeDTO: IProjectTimeEditDTO; -} -export interface IProjectTimeEditingEventPayload { - tenantId: number; - oldTime: IProjectTime; - timeDTO: IProjectTimeEditDTO; - trx: Knex.Transaction; -} - -export interface IProjectTimeEditedEventPayload { - tenantId: number; - oldTime: IProjectTime; - time: IProjectTime; - timeDTO: IProjectTimeEditDTO; - trx: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/TransactionsByContacts.ts b/packages/server/src/interfaces/TransactionsByContacts.ts deleted file mode 100644 index 82a38002a..000000000 --- a/packages/server/src/interfaces/TransactionsByContacts.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { INumberFormatQuery } from './FinancialStatements'; - -export interface ITransactionsByContactsAmount { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface ITransactionsByContactsTransaction { - date: string|Date, - credit: ITransactionsByContactsAmount; - debit: ITransactionsByContactsAmount; - accountName: string, - runningBalance: ITransactionsByContactsAmount; - currencyCode: string; - transactionType: string; - transactionNumber: string; - createdAt: string|Date, -}; - -export interface ITransactionsByContactsContact { - openingBalance: ITransactionsByContactsAmount, - closingBalance: ITransactionsByContactsAmount, - transactions: ITransactionsByContactsTransaction[], -} - -export interface ITransactionsByContactsFilter { - fromDate: Date|string; - toDate: Date|string; - numberFormat: INumberFormatQuery; - noneTransactions: boolean; - noneZero: boolean; -} diff --git a/packages/server/src/interfaces/TransactionsByCustomers.ts b/packages/server/src/interfaces/TransactionsByCustomers.ts deleted file mode 100644 index e47098b36..000000000 --- a/packages/server/src/interfaces/TransactionsByCustomers.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { IFinancialSheetCommonMeta } from './FinancialStatements'; -import { IFinancialTable, ITableData } from './Table'; -import { - ITransactionsByContactsAmount, - ITransactionsByContactsTransaction, - ITransactionsByContactsFilter, -} from './TransactionsByContacts'; - -export interface ITransactionsByCustomersAmount - extends ITransactionsByContactsAmount {} - -export interface ITransactionsByCustomersTransaction - extends ITransactionsByContactsTransaction {} - -export interface ITransactionsByCustomersCustomer { - customerName: string; - openingBalance: ITransactionsByCustomersAmount; - closingBalance: ITransactionsByCustomersAmount; - transactions: ITransactionsByCustomersTransaction[]; -} - -export interface ITransactionsByCustomersFilter - extends ITransactionsByContactsFilter { - customersIds: number[]; -} - -export type ITransactionsByCustomersData = ITransactionsByCustomersCustomer[]; - -export interface ITransactionsByCustomersStatement { - data: ITransactionsByCustomersData; - query: ITransactionsByCustomersFilter; - meta: ITransactionsByCustomersMeta; -} - -export interface ITransactionsByCustomersTable extends IFinancialTable { - query: ITransactionsByCustomersFilter; - meta: ITransactionsByCustomersMeta; -} - -export interface ITransactionsByCustomersService { - transactionsByCustomers( - tenantId: number, - filter: ITransactionsByCustomersFilter - ): Promise; -} -export interface ITransactionsByCustomersMeta - extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} diff --git a/packages/server/src/interfaces/TransactionsByReference.ts b/packages/server/src/interfaces/TransactionsByReference.ts deleted file mode 100644 index 214fbb09e..000000000 --- a/packages/server/src/interfaces/TransactionsByReference.ts +++ /dev/null @@ -1,31 +0,0 @@ - - -export interface ITransactionsByReferenceQuery { - referenceType: string; - referenceId: string; -} - -export interface ITransactionsByReferenceAmount { - amount: number; - formattedAmount: string; - currencyCode: string; -} - -export interface ITransactionsByReferenceTransaction{ - credit: ITransactionsByReferenceAmount; - debit: ITransactionsByReferenceAmount; - - contactType: string; - formattedContactType: string; - - contactId: number; - - referenceType: string; - formattedReferenceType: string; - - referenceId: number; - - accountName: string; - accountCode: string; - accountId: number; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/TransactionsByVendors.ts b/packages/server/src/interfaces/TransactionsByVendors.ts deleted file mode 100644 index 7a5b16013..000000000 --- a/packages/server/src/interfaces/TransactionsByVendors.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { IFinancialSheetCommonMeta } from './FinancialStatements'; -import { IFinancialTable } from './Table'; -import { - ITransactionsByContactsAmount, - ITransactionsByContactsTransaction, - ITransactionsByContactsFilter, -} from './TransactionsByContacts'; - -export interface ITransactionsByVendorsAmount - extends ITransactionsByContactsAmount {} - -export interface ITransactionsByVendorsTransaction - extends ITransactionsByContactsTransaction {} - -export interface ITransactionsByVendorsVendor { - vendorName: string; - openingBalance: ITransactionsByVendorsAmount; - closingBalance: ITransactionsByVendorsAmount; - transactions: ITransactionsByVendorsTransaction[]; -} - -export interface ITransactionsByVendorsFilter - extends ITransactionsByContactsFilter { - vendorsIds: number[]; -} - -export type ITransactionsByVendorsData = ITransactionsByVendorsVendor[]; - -export interface ITransactionsByVendorsStatement { - data: ITransactionsByVendorsData; - query: ITransactionsByVendorsFilter; - meta: ITransactionsByVendorMeta; -} - -export interface ITransactionsByVendorsService { - transactionsByVendors( - tenantId: number, - filter: ITransactionsByVendorsFilter - ): Promise; -} - -export interface ITransactionsByVendorTable extends IFinancialTable { - query: ITransactionsByVendorsFilter; - meta: ITransactionsByVendorMeta; -} -export interface ITransactionsByVendorMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} diff --git a/packages/server/src/interfaces/TransactionsLocking.ts b/packages/server/src/interfaces/TransactionsLocking.ts deleted file mode 100644 index 9b57d9b23..000000000 --- a/packages/server/src/interfaces/TransactionsLocking.ts +++ /dev/null @@ -1,71 +0,0 @@ -export interface ITransactionsLockingAllDTO { - lockToDate: Date; - reason: string; -} -export interface ITransactionsLockingCashflowDTO {} -export interface ITransactionsLockingSalesDTO {} -export interface ITransactionsLockingPurchasesDTO {} - -export enum TransactionsLockingGroup { - All = 'all', - Sales = 'sales', - Purchases = 'purchases', - Financial = 'financial', -} - -export enum TransactionsLockingType { - Partial = 'partial', - All = 'all', -} - -export interface ITransactionsLockingPartialUnlocked { - tenantId: number; - module: TransactionsLockingGroup; - transactionLockingDTO: ITransactionsLockingAllDTO; -} - -export interface ITransactionsLockingCanceled { - tenantId: number; - module: TransactionsLockingGroup; - cancelLockingDTO: ICancelTransactionsLockingDTO; -} - -export interface ITransactionLockingPartiallyDTO { - unlockFromDate: Date; - unlockToDate: Date; - reason: string; -} -export interface ICancelTransactionsLockingDTO { - reason: string; -} -export interface ITransactionMeta { - isEnabled: boolean; - isPartialUnlock: boolean; - lockToDate: Date; - unlockFromDate: string; - unlockToDate: string; - lockReason: string; - unlockReason: string; - partialUnlockReason: string; -} - -export interface ITransactionLockingMetaPOJO { - module: string; - formattedModule: string; - description: string; - - formattedLockToDate: Date; - formattedUnlockFromDate: string; - formattedunlockToDate: string; -} -export interface ITransactionsLockingListPOJO { - lockingType: string; - all: ITransactionLockingMetaPOJO; - modules: ITransactionLockingMetaPOJO[]; -} - -export interface ITransactionsLockingSchema { - module: TransactionsLockingGroup; - formattedModule: string; - description: string; -} diff --git a/packages/server/src/interfaces/TrialBalanceSheet.ts b/packages/server/src/interfaces/TrialBalanceSheet.ts deleted file mode 100644 index b6cd79736..000000000 --- a/packages/server/src/interfaces/TrialBalanceSheet.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface ITrialBalanceSheetQuery { - fromDate: Date | string; - toDate: Date | string; - numberFormat: INumberFormatQuery; - basis: 'cash' | 'accrual'; - noneZero: boolean; - noneTransactions: boolean; - onlyActive: boolean; - accountIds: number[]; - branchesIds?: number[]; -} - -export interface ITrialBalanceTotal { - credit: number; - debit: number; - balance: number; - currencyCode: string; - - formattedCredit: string; - formattedDebit: string; - formattedBalance: string; -} - -export interface ITrialBalanceSheetMeta extends IFinancialSheetCommonMeta { - formattedFromDate: string; - formattedToDate: string; - formattedDateRange: string; -} - -export interface ITrialBalanceAccount extends ITrialBalanceTotal { - id: number; - parentAccountId: number; - name: string; - formattedName: string; - code: string; - accountNormal: string; -} - -export type ITrialBalanceSheetData = { - accounts: ITrialBalanceAccount[]; - total: ITrialBalanceTotal; -}; - -export interface ITrialBalanceStatement { - data: ITrialBalanceSheetData; - query: ITrialBalanceSheetQuery; - meta: ITrialBalanceSheetMeta; -} - -export interface ITrialBalanceSheetTable extends IFinancialTable { - meta: ITrialBalanceSheetMeta; - query: ITrialBalanceSheetQuery; -} diff --git a/packages/server/src/interfaces/User.ts b/packages/server/src/interfaces/User.ts deleted file mode 100644 index 4b4077eca..000000000 --- a/packages/server/src/interfaces/User.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { AnyObject } from '@casl/ability/dist/types/types'; -import { ITenant } from '@/interfaces'; -import { Model } from 'objection'; -import { Tenant } from '@/system/models'; - -export interface ISystemUser extends Model { - id: number; - firstName: string; - lastName: string; - active: boolean; - password: string; - email: string; - - verifyToken: string; - verified: boolean; - - roleId: number; - tenantId: number; - - inviteAcceptAt: Date; - lastLoginAt: Date; - deletedAt: Date; - - createdAt: Date; - updatedAt: Date; -} - -export interface ISystemUserDTO { - firstName: string; - lastName: string; - password: string; - active: boolean; - email: string; - roleId?: number; -} - -export interface IEditUserDTO { - firstName: string; - lastName: string; - active: boolean; - email: string; - roleId: number; -} - -export interface IInviteUserInput { - firstName: string; - lastName: string; - password: string; -} -export interface IUserInvite { - id: number; - email: string; - token: string; - tenantId: number; - userId: number; - createdAt?: Date; -} - -export interface IInviteUserService { - acceptInvite(token: string, inviteUserInput: IInviteUserInput): Promise; - - /** - * Re-send user invite. - * @param {number} tenantId - - * @param {string} email - - * @return {Promise<{ invite: IUserInvite }>} - */ - resendInvite( - tenantId: number, - userId: number, - authorizedUser: ISystemUser - ): Promise<{ - user: ITenantUser; - }>; - - /** - * Sends invite mail to the given email from the given tenant and user. - * @param {number} tenantId - - * @param {string} email - - * @param {IUser} authorizedUser - - * @return {Promise} - */ - sendInvite( - tenantId: number, - sendInviteDTO: IUserSendInviteDTO, - authorizedUser: ISystemUser - ): Promise<{ - invitedUser: ITenantUser; - }>; -} - -export interface IAcceptInviteUserService { - /** - * Accept the received invite. - * @param {string} token - * @param {IInviteUserInput} inviteUserInput - * @throws {ServiceErrors} - * @returns {Promise} - */ - acceptInvite(token: string, inviteUserDTO: IInviteUserInput): Promise; - - /** - * Validate the given invite token. - * @param {string} token - the given token string. - * @throws {ServiceError} - */ - checkInvite( - token: string - ): Promise<{ inviteToken: IUserInvite; orgName: object }>; -} - -export interface ITenantUser {} - -export interface ITenantUserEditedPayload { - tenantId: number; - userId: number; - editUserDTO: IEditUserDTO; - tenantUser: ITenantUser; - oldTenantUser: ITenantUser; -} - -export interface ITenantUserActivatedPayload { - tenantId: number; - userId: number; - authorizedUser: ISystemUser; - tenantUser: ITenantUser; -} - -export interface ITenantUserInactivatedPayload { - tenantId: number; - userId: number; - authorizedUser: ISystemUser; - tenantUser: ITenantUser; -} - -export interface ITenantUserDeletedPayload { - tenantId: number; - userId: number; - tenantUser: ITenantUser; -} - -export interface ITenantUser { - id?: number; - firstName: string; - lastName: string; - active: boolean; - email: string; - roleId?: number; - systemUserId: number; - invitedAt: Date | null; - inviteAcceptedAt: Date | null; -} - -export interface IUserInvitedEventPayload { - inviteToken: string; - authorizedUser: ISystemUser; - tenantId: number; - user: ITenantUser; -} -export interface IUserInviteTenantSyncedEventPayload { - invite: IUserInvite; - authorizedUser: ISystemUser; - tenantId: number; - user: ITenantUser; -} - -export interface IUserInviteResendEventPayload { - inviteToken: string; - authorizedUser: ISystemUser; - tenantId: number; - user: ITenantUser; -} - -export interface IAcceptInviteEventPayload { - inviteToken: IUserInvite; - user: ISystemUser; - inviteUserDTO: IInviteUserInput; -} - -export interface ICheckInviteEventPayload { - inviteToken: IUserInvite; - tenant: Tenant; -} - -export interface IUserSendInviteDTO { - email: string; - roleId: number; -} diff --git a/packages/server/src/interfaces/VendorBalanceSummary.ts b/packages/server/src/interfaces/VendorBalanceSummary.ts deleted file mode 100644 index 5c603c51d..000000000 --- a/packages/server/src/interfaces/VendorBalanceSummary.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { - IFinancialSheetCommonMeta, - INumberFormatQuery, -} from './FinancialStatements'; -import { IFinancialTable } from './Table'; - -export interface IVendorBalanceSummaryQuery { - asDate: Date; - vendorsIds: number[]; - numberFormat: INumberFormatQuery; - percentageColumn: boolean; - noneTransactions: boolean; - noneZero: boolean; -} - -export interface IVendorBalanceSummaryAmount { - amount: number; - formattedAmount: string; - currencyCode: string; -} -export interface IVendorBalanceSummaryPercentage { - amount: number; - formattedAmount: string; -} - -export interface IVendorBalanceSummaryVendor { - id: number; - vendorName: string; - total: IVendorBalanceSummaryAmount; - percentageOfColumn?: IVendorBalanceSummaryPercentage; -} - -export interface IVendorBalanceSummaryTotal { - total: IVendorBalanceSummaryAmount; - percentageOfColumn?: IVendorBalanceSummaryPercentage; -} - -export interface IVendorBalanceSummaryData { - vendors: IVendorBalanceSummaryVendor[]; - total: IVendorBalanceSummaryTotal; -} - -export interface IVendorBalanceSummaryStatement { - data: IVendorBalanceSummaryData; - query: IVendorBalanceSummaryQuery; - meta: IVendorBalanceSummaryMeta; - -} - -export interface IVendorBalanceSummaryService { - vendorBalanceSummary( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise; -} - -export interface IVendorBalanceSummaryTable extends IFinancialTable { - query: IVendorBalanceSummaryQuery; - meta: IVendorBalanceSummaryMeta; -} - -export interface IVendorBalanceSummaryMeta extends IFinancialSheetCommonMeta { - formattedAsDate: string; -} diff --git a/packages/server/src/interfaces/VendorCredit.ts b/packages/server/src/interfaces/VendorCredit.ts deleted file mode 100644 index 29254337f..000000000 --- a/packages/server/src/interfaces/VendorCredit.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { DiscountType, IDynamicListFilter, IItemEntry, IItemEntryDTO } from '@/interfaces'; -import { Knex } from 'knex'; -import { AttachmentLinkDTO } from './Attachments'; - -export enum VendorCreditAction { - Create = 'Create', - Edit = 'Edit', - Delete = 'Delete', - View = 'View', - Refund = 'Refund', -} - -export interface IVendorCredit { - id: number | null; - vendorId: number; - amount: number; - localAmount?: number; - currencyCode: string; - exchangeRate: number; - vendorCreditNumber: string; - vendorCreditDate: Date; - referenceNo: string; - entries?: IItemEntry[]; - openedAt: Date | null; - isOpen: boolean; - isPublished: boolean; - isClosed: boolean; - isDraft: boolean; - creditsRemaining: number; - branchId?: number; - warehouseId?: number, -} - -export interface IVendorCreditEntryDTO extends IItemEntryDTO {} - -export interface IRefundVendorCredit { - id?: number | null; - date: Date; - referenceNo: string; - amount: number; - currencyCode: string; - exchangeRate: number; - depositAccountId: number; - description: string; - vendorCreditId: number; - createdAt: Date | null; - userId: number; - branchId?: number; - - vendorCredit?: IVendorCredit -} - -export interface IVendorCreditDTO { - vendorId: number; - exchangeRate?: number; - vendorCreditNumber: string; - referenceNo: string; - vendorCreditDate: Date; - note: string; - open: boolean; - entries: IVendorCreditEntryDTO[]; - - branchId?: number; - warehouseId?: number; - attachments?: AttachmentLinkDTO[]; - - discount?: number; - discountType?: DiscountType; - - adjustment?: number; -} - -export interface IVendorCreditCreateDTO extends IVendorCreditDTO {} -export interface IVendorCreditEditDTO extends IVendorCreditDTO {} -export interface IVendorCreditCreatePayload { - tenantId: number; - refundVendorCreditDTO: IRefundVendorCreditDTO; - vendorCreditId: number; -} - -export interface IVendorCreditCreatingPayload { - tenantId: number; - vendorCredit: IVendorCredit; - vendorCreditId: number; - vendorCreditCreateDTO: IVendorCreditCreateDTO; - trx: Knex.Transaction; -} - -export interface IVendorCreditCreatedPayload { - tenantId: number; - vendorCredit: IVendorCredit; - vendorCreditCreateDTO: IVendorCreditCreateDTO; - trx: Knex.Transaction; -} - -export interface IVendorCreditCreatedPayload {} -export interface IVendorCreditDeletedPayload { - trx: Knex.Transaction; - tenantId: number; - vendorCreditId: number; - oldVendorCredit: IVendorCredit; -} - -export interface IVendorCreditDeletingPayload { - trx: Knex.Transaction; - tenantId: number; - oldVendorCredit: IVendorCredit; -} - -export interface IVendorCreditsQueryDTO extends IDynamicListFilter { - page: number; - pageSize: number; - searchKeyword?: string; - filterQuery?: (q: any) => void; -} - -export interface IVendorCreditEditingPayload { - tenantId: number; - oldVendorCredit: IVendorCredit; - vendorCreditDTO: IVendorCreditEditDTO; - trx: Knex.Transaction; -} - -export interface IVendorCreditEditedPayload { - tenantId: number; - oldVendorCredit: IVendorCredit; - vendorCredit: IVendorCredit; - vendorCreditId: number; - vendorCreditDTO: IVendorCreditEditDTO; - trx: Knex.Transaction; -} - -export interface IRefundVendorCreditDTO { - amount: number; - exchangeRate?: number; - depositAccountId: number; - description: string; - date: Date; - branchId?: number; -} - -export interface IRefundVendorCreditDeletedPayload { - trx: Knex.Transaction; - refundCreditId: number; - oldRefundCredit: IRefundVendorCredit; - tenantId: number; -} - -export interface IRefundVendorCreditDeletePayload { - trx: Knex.Transaction; - refundCreditId: number; - oldRefundCredit: IRefundVendorCredit; - tenantId: number; -} -export interface IRefundVendorCreditDeletingPayload { - trx: Knex.Transaction; - refundCreditId: number; - oldRefundCredit: IRefundVendorCredit; - tenantId: number; -} - -export interface IRefundVendorCreditCreatingPayload { - trx: Knex.Transaction; - vendorCredit: IVendorCredit; - refundVendorCreditDTO: IRefundVendorCreditDTO; - tenantId: number; -} - -export interface IRefundVendorCreditCreatedPayload { - refundVendorCredit: IRefundVendorCredit; - vendorCredit: IVendorCredit; - trx: Knex.Transaction; - tenantId: number; -} -export interface IRefundVendorCreditPOJO {} - -export interface IApplyCreditToBillEntryDTO { - amount: number; - billId: number; -} - -export interface IApplyCreditToBillsDTO { - entries: IApplyCreditToBillEntryDTO[]; -} - -export interface IVendorCreditOpenedPayload { - tenantId: number; - vendorCreditId: number; - vendorCredit: IVendorCredit; - trx: Knex.Transaction; -} - -export interface IVendorCreditOpenPayload { - tenantId: number; - vendorCreditId: number; - oldVendorCredit: IVendorCredit; -} - -export interface IVendorCreditOpeningPayload { - tenantId: number; - vendorCreditId: number; - oldVendorCredit: IVendorCredit; - trx: Knex.Transaction; -} - -export interface IVendorCreditApplyToBillsCreatedPayload { - tenantId: number; - vendorCredit: IVendorCredit; - vendorCreditAppliedBills: IVendorCreditAppliedBill[]; - trx: Knex.Transaction; -} -export interface IVendorCreditApplyToBillsCreatingPayload { - trx: Knex.Transaction; -} -export interface IVendorCreditApplyToBillsCreatePayload { - trx: Knex.Transaction; -} -export interface IVendorCreditApplyToBillDeletedPayload { - tenantId: number; - vendorCredit: IVendorCredit; - oldCreditAppliedToBill: IVendorCreditAppliedBill; - trx: Knex.Transaction; -} - -export interface IVendorCreditApplyToInvoiceDTO { - amount: number; - billId: number; -} - -export interface IVendorCreditApplyToInvoicesDTO { - entries: IVendorCreditApplyToInvoiceDTO[]; -} - -export interface IVendorCreditApplyToInvoiceModel { - billId: number; - amount: number; - vendorCreditId: number; -} - -export interface IVendorCreditApplyToInvoicesModel { - entries: IVendorCreditApplyToInvoiceModel[]; - amount: number; -} - -export interface IVendorCreditAppliedBill { - billId: number; - amount: number; - vendorCreditId: number; -} diff --git a/packages/server/src/interfaces/View.ts b/packages/server/src/interfaces/View.ts deleted file mode 100644 index 39c32190c..000000000 --- a/packages/server/src/interfaces/View.ts +++ /dev/null @@ -1,68 +0,0 @@ - -export interface IView { - id: number, - name: string, - slug: string; - predefined: boolean, - resourceModel: string, - favourite: boolean, - rolesLogicExpression: string, - - roles: IViewRole[], - columns: IViewHasColumn[], -}; - -export interface IViewRole { - id: number, - fieldKey: string, - index: number, - comparator: string, - value: string, - viewId: number, -}; - -export interface IViewHasColumn { - id :number, - viewId: number, - fieldId: number, - index: number, -} - -export interface IViewRoleDTO { - index: number, - fieldKey: string, - comparator: string, - value: string, - viewId: number, -} - -export interface IViewColumnDTO { - id: number, - index: number, - viewId: number, - fieldKey: string, -}; - -export interface IViewDTO { - name: string, - logicExpression: string, - resourceModel: string, - - roles: IViewRoleDTO[], - columns: IViewColumnDTO[], -}; - -export interface IViewEditDTO { - name: string, - logicExpression: string, - - roles: IViewRoleDTO[], - columns: IViewColumnDTO[], -}; - -export interface IViewsService { - listResourceViews(tenantId: number, resourceModel: string): Promise; - newView(tenantId: number, viewDTO: IViewDTO): Promise; - editView(tenantId: number, viewId: number, viewEditDTO: IViewEditDTO): Promise; - deleteView(tenantId: number, viewId: number): Promise; -} \ No newline at end of file diff --git a/packages/server/src/interfaces/Warehouses.ts b/packages/server/src/interfaces/Warehouses.ts deleted file mode 100644 index 7cfd8d803..000000000 --- a/packages/server/src/interfaces/Warehouses.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { Knex } from 'knex'; - -export interface IWarehouse { - id?: number; -} -export interface IWarehouseTransfer { - id?: number; - date: Date; - fromWarehouseId: number; - toWarehouseId: number; - reason?: string; - transactionNumber: string; - entries: IWarehouseTransferEntry[]; - transferInitiatedAt?: Date; - transferDeliveredAt?: Date; - - isInitiated?: boolean; - isTransferred?: boolean; -} -export interface IWarehouseTransferEntry { - id?: number; - index?: number; - itemId: number; - description: string; - quantity: number; - cost: number; -} -export interface ICreateWarehouseDTO { - name: string; - code: string; - - city?: string; - country?: string; - address?: string; - - primary?: boolean; -} -export interface IEditWarehouseDTO { - name: string; - code: string; - - city: string; - country: string; - address: string; -} - -export interface IWarehouseTransferEntryDTO { - index?: number; - itemId: number; - description: string; - quantity: number; - cost?: number; -} - -export interface ICreateWarehouseTransferDTO { - fromWarehouseId: number; - toWarehouseId: number; - transactionNumber: string; - date: Date; - transferInitiated: boolean; - transferDelivered: boolean; - entries: IWarehouseTransferEntryDTO[]; -} -export interface IEditWarehouseTransferDTO { - fromWarehouseId: number; - toWarehouseId: number; - transactionNumber: string; - date: Date; - entries: { - id?: number; - itemId: number; - description: string; - quantity: number; - }[]; -} - -export interface IWarehouseEditPayload { - tenantId: number; - warehouseId: number; - warehouseDTO: IEditWarehouseDTO; - trx: Knex.Transaction; -} - -export interface IWarehouseEditedPayload { - tenantId: number; - warehouse: IWarehouse; - warehouseDTO: IEditWarehouseDTO; - trx: Knex.Transaction; -} - -export interface IWarehouseDeletePayload { - tenantId: number; - warehouseId: number; - trx: Knex.Transaction; -} -export interface IWarehouseDeletedPayload { - tenantId: number; - warehouseId: number; - trx: Knex.Transaction; -} -export interface IWarehouseCreatePayload { - tenantId: number; - warehouseDTO: ICreateWarehouseDTO; - trx: Knex.Transaction; -} - -export interface IWarehouseCreatedPayload { - tenantId: number; - warehouse: IWarehouse; - warehouseDTO: ICreateWarehouseDTO; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferCreate { - trx: Knex.Transaction; - warehouseTransferDTO: ICreateWarehouseTransferDTO; - tenantId: number; -} - -export interface IWarehouseTransferCreated { - trx: Knex.Transaction; - warehouseTransfer: IWarehouseTransfer; - warehouseTransferDTO: ICreateWarehouseTransferDTO; - tenantId: number; -} - -export interface IWarehouseTransferEditPayload { - tenantId: number; - editWarehouseDTO: IEditWarehouseTransferDTO; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferEditedPayload { - tenantId: number; - editWarehouseDTO: IEditWarehouseTransferDTO; - oldWarehouseTransfer: IWarehouseTransfer; - warehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferDeletePayload { - tenantId: number; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferDeletedPayload { - tenantId: number; - warehouseTransfer: IWarehouseTransfer; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - -export interface IGetWarehousesTransfersFilterDTO { - page: number; - pageSize: number; - searchKeyword: string; -} - -export interface IItemWarehouseQuantityChange { - itemId: number; - warehouseId: number; - amount: number; -} - -export interface IWarehousesActivatePayload { - tenantId: number; -} -export interface IWarehousesActivatedPayload { - tenantId: number; - primaryWarehouse: IWarehouse; -} - -export interface IWarehouseMarkAsPrimaryPayload { - tenantId: number; - oldWarehouse: IWarehouse; - trx: Knex.Transaction; -} -export interface IWarehouseMarkedAsPrimaryPayload { - tenantId: number; - oldWarehouse: IWarehouse; - markedWarehouse: IWarehouse; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferInitiatePayload { - tenantId: number; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - - -export interface IWarehouseTransferInitiatedPayload { - tenantId: number; - warehouseTransfer: IWarehouseTransfer; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferTransferingPayload { - tenantId: number; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} - -export interface IWarehouseTransferTransferredPayload { - tenantId: number; - warehouseTransfer: IWarehouseTransfer; - oldWarehouseTransfer: IWarehouseTransfer; - trx: Knex.Transaction; -} diff --git a/packages/server/src/interfaces/index.ts b/packages/server/src/interfaces/index.ts deleted file mode 100644 index cf7fc1669..000000000 --- a/packages/server/src/interfaces/index.ts +++ /dev/null @@ -1,82 +0,0 @@ -export * from './Model'; -export * from './InventoryTransaction'; -export * from './BillPayment'; -export * from './Bill'; -export * from './InventoryCostMethod'; -export * from './ItemEntry'; -export * from './Item'; -export * from './License'; -export * from './ItemCategory'; -export * from './Payment'; -export * from './SaleInvoice'; -export * from './SaleReceipt'; -export * from './PaymentReceive'; -export * from './SaleEstimate'; -export * from './Authentication'; -export * from './User'; -export * from './Metable'; -export * from './Options'; -export * from './Account'; -export * from './DynamicFilter'; -export * from './Journal'; -export * from './Contact'; -export * from './Expenses'; -export * from './Tenancy'; -export * from './View'; -export * from './ManualJournal'; -export * from './Currency'; -export * from './ExchangeRate'; -export * from './Media'; -export * from './SaleEstimate'; -export * from './FinancialStatements'; -export * from './BalanceSheet'; -export * from './TrialBalanceSheet'; -export * from './GeneralLedgerSheet'; -export * from './ProfitLossSheet'; -export * from './JournalReport'; -export * from './AgingReport'; -export * from './ARAgingSummaryReport'; -export * from './APAgingSummaryReport'; -export * from './Mailable'; -export * from './InventoryAdjustment'; -export * from './Setup'; -export * from './IInventoryValuationSheet'; -export * from './SalesByItemsSheet'; -export * from './CustomerBalanceSummary'; -export * from './VendorBalanceSummary'; -export * from './ContactBalanceSummary'; -export * from './TransactionsByCustomers'; -export * from './TransactionsByContacts'; -export * from './TransactionsByVendors'; -export * from './Table'; -export * from './Ledger'; -export * from './CashFlow'; -export * from './InventoryDetails'; -export * from './LandedCost'; -export * from './Entry'; -export * from './TransactionsByReference'; -export * from './Jobs'; -export * from './CashflowService'; -export * from './FinancialReports/CashflowAccountTransactions'; -export * from './SmsNotifications'; -export * from './Roles'; -export * from './TransactionsLocking'; -export * from './User'; -export * from './Preferences'; -export * from './CreditNote'; -export * from './VendorCredit'; -export * from './Warehouses'; -export * from './Branches'; -export * from './Features'; -export * from './InventoryCost'; -export * from './Project'; -export * from './Tasks'; -export * from './Times'; -export * from './ProjectProfitabilitySummary'; -export * from './TaxRate'; -export * from './Plaid'; -export * from './Subscription'; - -export interface I18nService { - __: (input: string) => string; -} diff --git a/packages/server/src/jobs/ComputeItemCost.ts b/packages/server/src/jobs/ComputeItemCost.ts deleted file mode 100644 index af6a19cbe..000000000 --- a/packages/server/src/jobs/ComputeItemCost.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Container } from 'typedi'; -import events from '@/subscribers/events'; -import InventoryService from '@/services/Inventory/Inventory'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { - IComputeItemCostJobCompletedPayload, - IComputeItemCostJobStartedPayload, -} from '@/interfaces'; - -export default class ComputeItemCostJob { - agenda: any; - eventPublisher: EventPublisher; - - /** - * Constructor method. - * @param agenda - */ - constructor(agenda) { - this.agenda = agenda; - this.eventPublisher = Container.get(EventPublisher); - - agenda.define( - 'compute-item-cost', - { priority: 'high', concurrency: 20 }, - this.handler.bind(this) - ); - this.agenda.on('start:compute-item-cost', this.onJobStart.bind(this)); - this.agenda.on( - 'complete:compute-item-cost', - this.onJobCompleted.bind(this) - ); - } - - /** - * The job handler. - */ - public async handler(job, done: Function): Promise { - const { startingDate, itemId, tenantId } = job.attrs.data; - const inventoryService = Container.get(InventoryService); - - try { - await inventoryService.computeItemCost(tenantId, startingDate, itemId); - done(); - } catch (e) { - done(e); - } - } - - /** - * Handle the job started. - */ - async onJobStart(job) { - const { startingDate, itemId, tenantId } = job.attrs.data; - - await this.eventPublisher.emitAsync( - events.inventory.onComputeItemCostJobStarted, - { startingDate, itemId, tenantId } as IComputeItemCostJobStartedPayload - ); - } - - /** - * Handle job complete items cost finished. - * @param {Job} job - - */ - async onJobCompleted(job) { - const { startingDate, itemId, tenantId } = job.attrs.data; - - await this.eventPublisher.emitAsync( - events.inventory.onComputeItemCostJobCompleted, - { startingDate, itemId, tenantId } as IComputeItemCostJobCompletedPayload - ); - } -} diff --git a/packages/server/src/jobs/OrganizationSetup.ts b/packages/server/src/jobs/OrganizationSetup.ts deleted file mode 100644 index 0d94d69e7..000000000 --- a/packages/server/src/jobs/OrganizationSetup.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Container } from 'typedi'; -import OrganizationService from '@/services/Organization/OrganizationService'; - -export default class OrganizationSetupJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'organization-setup', - { priority: 'high', concurrency: 20 }, - this.handler - ); - } - - /** - * Handle job action. - */ - async handler(job, done: Function): Promise { - const { tenantId, buildDTO, authorizedUser, _id } = job.attrs.data; - const organizationService = Container.get(OrganizationService); - - try { - await organizationService.build(tenantId, buildDTO, authorizedUser); - done(); - } catch (e) { - // Unlock build status of the tenant. - await organizationService.revertBuildRunJob(tenantId, _id); - - console.error(e); - done(e); - } - } -} diff --git a/packages/server/src/jobs/OrganizationUpgrade.ts b/packages/server/src/jobs/OrganizationUpgrade.ts deleted file mode 100644 index 1ea911baf..000000000 --- a/packages/server/src/jobs/OrganizationUpgrade.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Container } from 'typedi'; -import OrganizationUpgrade from '@/services/Organization/OrganizationUpgrade'; - -export default class OrganizationUpgradeJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'organization-upgrade', - { priority: 'high', concurrency: 1 }, - this.handler - ); - } - - /** - * Handle job action. - */ - async handler(job, done: Function): Promise { - const { tenantId, _id } = job.attrs.data; - const organizationUpgrade = Container.get(OrganizationUpgrade); - - try { - await organizationUpgrade.upgradeJob(tenantId); - done(); - } catch (e) { - console.error(e); - done(e); - } - } -} diff --git a/packages/server/src/jobs/ResetPasswordMail.ts b/packages/server/src/jobs/ResetPasswordMail.ts deleted file mode 100644 index 193e6bfe6..000000000 --- a/packages/server/src/jobs/ResetPasswordMail.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Container } from 'typedi'; -import AuthenticationMailMesssages from '@/services/Authentication/AuthenticationMailMessages'; - -export default class ResetPasswordEmailJob { - /** - * Constructor method. - * @param {Agenda} agenda - */ - constructor(agenda) { - agenda.define( - 'reset-password-mail', - { priority: 'high' }, - this.handler.bind(this) - ); - } - - /** - * Handle send welcome mail job. - * @param {Job} job - * @param {Function} done - */ - public async handler(job, done: Function): Promise { - const { data } = job.attrs; - const { user, token } = data; - const authService = Container.get(AuthenticationMailMesssages); - - try { - await authService.sendResetPasswordMessage(user, token); - done(); - } catch (error) { - console.log(error); - done(error); - } - } -} diff --git a/packages/server/src/jobs/UserInviteMail.ts b/packages/server/src/jobs/UserInviteMail.ts deleted file mode 100644 index 5585c79e1..000000000 --- a/packages/server/src/jobs/UserInviteMail.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Container, Inject } from 'typedi'; -import InviteUserService from '@/services/InviteUsers/AcceptInviteUser'; -import SendInviteUsersMailMessage from '@/services/InviteUsers/SendInviteUsersMailMessage'; - -export default class UserInviteMailJob { - /** - * Constructor method. - * @param {Agenda} agenda - */ - constructor(agenda) { - agenda.define( - 'user-invite-mail', - { priority: 'high' }, - this.handler.bind(this) - ); - } - - /** - * Handle invite user job. - * @param {Job} job - * @param {Function} done - */ - public async handler(job, done: Function): Promise { - const { invite, authorizedUser, tenantId } = job.attrs.data; - const sendInviteMailMessage = Container.get(SendInviteUsersMailMessage); - - try { - await sendInviteMailMessage.sendInviteMail( - tenantId, - authorizedUser, - invite - ); - done(); - } catch (error) { - console.log(error); - done(error); - } - } -} diff --git a/packages/server/src/jobs/WriteInvoicesJEntries.ts b/packages/server/src/jobs/WriteInvoicesJEntries.ts deleted file mode 100644 index 738c47eee..000000000 --- a/packages/server/src/jobs/WriteInvoicesJEntries.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Container } from 'typedi'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { SaleInvoicesCost } from '@/services/Sales/Invoices/SalesInvoicesCost'; - -export default class WriteInvoicesJournalEntries { - eventPublisher: EventPublisher; - - /** - * Constructor method. - */ - constructor(agenda) { - const eventName = 'rewrite-invoices-journal-entries'; - this.eventPublisher = Container.get(EventPublisher); - - agenda.define( - eventName, - { priority: 'normal', concurrency: 20 }, - this.handler.bind(this) - ); - agenda.on(`complete:${eventName}`, this.onJobCompleted.bind(this)); - } - - /** - * Handle the job execuation. - */ - public async handler(job, done: Function): Promise { - const { startingDate, tenantId } = job.attrs.data; - const salesInvoicesCost = Container.get(SaleInvoicesCost); - - try { - await salesInvoicesCost.writeCostLotsGLEntries(tenantId, startingDate); - done(); - } catch (e) { - done(e); - } - } - - /** - * Handle the job complete. - */ - async onJobCompleted(job) { - const { startingDate, itemId, tenantId } = job.attrs.data; - - await this.eventPublisher.emitAsync( - events.inventory.onInventoryCostEntriesWritten, - { startingDate, itemId, tenantId } - ); - } -} diff --git a/packages/server/src/lib/AccountTypes/index.ts b/packages/server/src/lib/AccountTypes/index.ts deleted file mode 100644 index 2084d4b8d..000000000 --- a/packages/server/src/lib/AccountTypes/index.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { get } from 'lodash'; -import { ACCOUNT_TYPES } from '@/data/AccountTypes'; - -export default class AccountTypesUtils { - /** - * Retrieve account types list. - */ - static getList() { - return ACCOUNT_TYPES; - } - - /** - * Retrieve accounts types by the given root type. - * @param {string} rootType - - * @return {string} - */ - static getTypesByRootType(rootType: string) { - return ACCOUNT_TYPES.filter((type) => type.rootType === rootType); - } - - /** - * Retrieve account type by the given account type key. - * @param {string} key - * @param {string} accessor - */ - static getType(key: string, accessor?: string) { - const type = ACCOUNT_TYPES.find((type) => type.key === key); - - if (accessor) { - return get(type, accessor); - } - return type; - } - - /** - * Retrieve accounts types by the parent account type. - * @param {string} parentType - */ - static getTypesByParentType(parentType: string) { - return ACCOUNT_TYPES.filter((type) => type.parentType === parentType); - } - - /** - * Retrieve accounts types by the given account normal. - * @param {string} normal - */ - static getTypesByNormal(normal: string) { - return ACCOUNT_TYPES.filter((type) => type.normal === normal); - } - - /** - * Detarmines whether the root type equals the account type. - * @param {string} key - * @param {string} rootType - */ - static isRootTypeEqualsKey(key: string, rootType: string): boolean { - return ACCOUNT_TYPES.some((type) => { - const isType = type.key === key; - const isRootType = type.rootType === rootType; - - return isType && isRootType; - }); - } - - /** - * Detarmines whether the parent account type equals the account type key. - * @param {string} key - Account type key. - * @param {string} parentType - Account parent type. - */ - static isParentTypeEqualsKey(key: string, parentType: string): boolean { - return ACCOUNT_TYPES.some((type) => { - const isType = type.key === key; - const isParentType = type.parentType === parentType; - - return isType && isParentType; - }); - } - - /** - * Detarmines whether account type has balance sheet. - * @param {string} key - Account type key. - * - */ - static isTypeBalanceSheet(key: string): boolean { - return ACCOUNT_TYPES.some((type) => { - const isType = type.key === key; - return isType && type.balanceSheet; - }); - } - - /** - * Detarmines whether account type has profit/loss sheet. - * @param {string} key - Account type key. - */ - static isTypePLSheet(key: string): boolean { - return ACCOUNT_TYPES.some((type) => { - const isType = type.key === key; - return isType && type.incomeSheet; - }); - } -} \ No newline at end of file diff --git a/packages/server/src/lib/Cachable/CachableModel.js b/packages/server/src/lib/Cachable/CachableModel.js deleted file mode 100644 index e5ff8bfd5..000000000 --- a/packages/server/src/lib/Cachable/CachableModel.js +++ /dev/null @@ -1,16 +0,0 @@ -import BaseModel from 'models/Model'; -import CacheService from '@/services/Cache'; - -export default (Model) => { - return class CachableModel extends Model{ - static flushCache(key) { - const modelName = this.name; - - if (key) { - CacheService.del(`${modelName}.${key}`); - } else { - CacheService.delStartWith(modelName); - } - } - }; -} \ No newline at end of file diff --git a/packages/server/src/lib/Cachable/CachableQueryBuilder.js b/packages/server/src/lib/Cachable/CachableQueryBuilder.js deleted file mode 100644 index 41fa8fbea..000000000 --- a/packages/server/src/lib/Cachable/CachableQueryBuilder.js +++ /dev/null @@ -1,69 +0,0 @@ -import { QueryBuilder } from 'objection'; -import crypto from 'crypto'; -import CacheService from '@/services/Cache'; - -export default class CachableQueryBuilder extends QueryBuilder{ - - async then(...args) { - // Flush model cache after insert, delete or update transaction. - if (this.isInsert() || this.isDelete() || this.isUpdate()) { - this.modelClass().flushCache(); - } - if (this.cacheTag && this.isFind()) { - this.setCacheKey(); - return this.getOrStoreCache().then(...args); - } else { - const promise = this.execute(); - - return promise.then((result) => { - this.setCache(result); - return result; - }).then(...args); - } - } - - getOrStoreCache() { - const storeFunction = () => this.execute(); - - return new Promise((resolve, reject) => { - CacheService.get(this.cacheKey, storeFunction) - .then((result) => { resolve(result); }); - }); - } - - setCache(results) { - CacheService.set(`${this.cacheKey}`, results, this.cacheSeconds); - } - - generateCacheKey() { - const knexSql = this.toKnexQuery().toSQL(); - const hashedQuery = crypto.createHash('md5').update(knexSql.sql).digest("hex"); - - return hashedQuery; - } - - remember(key, seconds) { - const modelName = this.modelClass().name; - - this.cacheSeconds = seconds; - this.cacheTag = (key) ? `${modelName}.${key}` : modelName; - - return this; - } - - withGraphFetched(relation, settings) { - if (!this.graphAppends) { - this.graphAppends = [relation]; - } else { - this.graphAppends.push(relation); - } - return super.withGraphFetched(relation, settings); - } - - setCacheKey() { - const hashedQuery = this.generateCacheKey(); - const appends = (this.graphAppends || []).join(this.graphAppends, ','); - - this.cacheKey = `${this.cacheTag}.${hashedQuery}.${appends}`; - } -} \ No newline at end of file diff --git a/packages/server/src/lib/Chromiumly/Chromiumly.ts b/packages/server/src/lib/Chromiumly/Chromiumly.ts deleted file mode 100644 index 276ca4538..000000000 --- a/packages/server/src/lib/Chromiumly/Chromiumly.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ChromiumRoute, LibreOfficeRoute, PdfEngineRoute } from './_types'; - -export class Chromiumly { - public static readonly GOTENBERG_ENDPOINT = process.env.GOTENBERG_URL || ''; - - public static readonly CHROMIUM_PATH = 'forms/chromium/convert'; - public static readonly PDF_ENGINES_PATH = 'forms/pdfengines'; - public static readonly LIBRE_OFFICE_PATH = 'forms/libreoffice'; - - public static readonly GOTENBERG_DOCS_ENDPOINT = - process.env.GOTENBERG_DOCS_URL || ''; - - public static readonly CHROMIUM_ROUTES = { - url: ChromiumRoute.URL, - html: ChromiumRoute.HTML, - markdown: ChromiumRoute.MARKDOWN, - }; - - public static readonly PDF_ENGINE_ROUTES = { - merge: PdfEngineRoute.MERGE, - }; - - public static readonly LIBRE_OFFICE_ROUTES = { - convert: LibreOfficeRoute.CONVERT, - }; -} diff --git a/packages/server/src/lib/Chromiumly/ConvertUtils.ts b/packages/server/src/lib/Chromiumly/ConvertUtils.ts deleted file mode 100644 index 38d27fd99..000000000 --- a/packages/server/src/lib/Chromiumly/ConvertUtils.ts +++ /dev/null @@ -1,66 +0,0 @@ -import FormData from 'form-data'; -import { GotenbergUtils } from './GotenbergUtils'; -import { PageProperties } from './_types'; - -export class ConverterUtils { - public static injectPageProperties( - data: FormData, - pageProperties: PageProperties - ): void { - if (pageProperties.size) { - GotenbergUtils.assert( - pageProperties.size.width >= 1.0 && pageProperties.size.height >= 1.5, - 'size is smaller than the minimum printing requirements (i.e. 1.0 x 1.5 in)' - ); - - data.append('paperWidth', pageProperties.size.width); - data.append('paperHeight', pageProperties.size.height); - } - if (pageProperties.margins) { - GotenbergUtils.assert( - pageProperties.margins.top >= 0 && - pageProperties.margins.bottom >= 0 && - pageProperties.margins.left >= 0 && - pageProperties.margins.left >= 0, - 'negative margins are not allowed' - ); - data.append('marginTop', pageProperties.margins.top); - data.append('marginBottom', pageProperties.margins.bottom); - data.append('marginLeft', pageProperties.margins.left); - data.append('marginRight', pageProperties.margins.right); - } - if (pageProperties.preferCssPageSize) { - data.append( - 'preferCssPageSize', - String(pageProperties.preferCssPageSize) - ); - } - if (pageProperties.printBackground) { - data.append('printBackground', String(pageProperties.printBackground)); - } - if (pageProperties.landscape) { - data.append('landscape', String(pageProperties.landscape)); - } - if (pageProperties.scale) { - GotenbergUtils.assert( - pageProperties.scale >= 0.1 && pageProperties.scale <= 2.0, - 'scale is outside of [0.1 - 2] range' - ); - data.append('scale', pageProperties.scale); - } - - if (pageProperties.nativePageRanges) { - GotenbergUtils.assert( - pageProperties.nativePageRanges.from > 0 && - pageProperties.nativePageRanges.to > 0 && - pageProperties.nativePageRanges.to >= - pageProperties.nativePageRanges.from, - 'page ranges syntax error' - ); - data.append( - 'nativePageRanges', - `${pageProperties.nativePageRanges.from}-${pageProperties.nativePageRanges.to}` - ); - } - } -} diff --git a/packages/server/src/lib/Chromiumly/Converter.ts b/packages/server/src/lib/Chromiumly/Converter.ts deleted file mode 100644 index cf8f70f4a..000000000 --- a/packages/server/src/lib/Chromiumly/Converter.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Chromiumly } from './Chromiumly'; -import { ChromiumRoute } from './_types'; - -export abstract class Converter { - readonly endpoint: string; - - constructor(route: ChromiumRoute) { - this.endpoint = `${Chromiumly.GOTENBERG_ENDPOINT}/${Chromiumly.CHROMIUM_PATH}/${Chromiumly.CHROMIUM_ROUTES[route]}`; - } -} diff --git a/packages/server/src/lib/Chromiumly/GotenbergUtils.ts b/packages/server/src/lib/Chromiumly/GotenbergUtils.ts deleted file mode 100644 index 63a609792..000000000 --- a/packages/server/src/lib/Chromiumly/GotenbergUtils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import FormData from 'form-data'; -import Axios from 'axios'; - -export class GotenbergUtils { - public static assert(condition: boolean, message: string): asserts condition { - if (!condition) { - throw new Error(message); - } - } - - public static async fetch(endpoint: string, data: FormData): Promise { - try { - const response = await Axios.post(endpoint, data, { - headers: { - ...data.getHeaders(), - }, - responseType: 'arraybuffer', // This ensures you get a Buffer bac - }); - return response.data; - } catch (error) { - console.error(error); - } - } -} diff --git a/packages/server/src/lib/Chromiumly/HTMLConvert.ts b/packages/server/src/lib/Chromiumly/HTMLConvert.ts deleted file mode 100644 index 3eb109405..000000000 --- a/packages/server/src/lib/Chromiumly/HTMLConvert.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { constants, createReadStream, PathLike, promises } from 'fs'; -import FormData from 'form-data'; -import { GotenbergUtils } from './GotenbergUtils'; -import { IConverter, PageProperties } from './_types'; -import { PdfFormat, ChromiumRoute } from './_types'; -import { ConverterUtils } from './ConvertUtils'; -import { Converter } from './Converter'; - -export class HtmlConverter extends Converter implements IConverter { - constructor() { - super(ChromiumRoute.HTML); - } - - async convert({ - html, - properties, - pdfFormat, - }: { - html: PathLike; - properties?: PageProperties; - pdfFormat?: PdfFormat; - }): Promise { - try { - await promises.access(html, constants.R_OK); - const data = new FormData(); - if (pdfFormat) { - data.append('pdfFormat', pdfFormat); - } - data.append('index.html', createReadStream(html)); - if (properties) { - ConverterUtils.injectPageProperties(data, properties); - } - return GotenbergUtils.fetch(this.endpoint, data); - } catch (error) { - throw error; - } - } -} diff --git a/packages/server/src/lib/Chromiumly/UrlConvert.ts b/packages/server/src/lib/Chromiumly/UrlConvert.ts deleted file mode 100644 index d1a462124..000000000 --- a/packages/server/src/lib/Chromiumly/UrlConvert.ts +++ /dev/null @@ -1,38 +0,0 @@ -import FormData from 'form-data'; -import { IConverter, PageProperties, PdfFormat, ChromiumRoute } from './_types'; -import { ConverterUtils } from './ConvertUtils'; -import { Converter } from './Converter'; -import { GotenbergUtils } from './GotenbergUtils'; - -export class UrlConverter extends Converter implements IConverter { - constructor() { - super(ChromiumRoute.URL); - } - - async convert({ - url, - properties, - pdfFormat, - }: { - url: string; - properties?: PageProperties; - pdfFormat?: PdfFormat; - }): Promise { - try { - const _url = new URL(url); - const data = new FormData(); - - if (pdfFormat) { - data.append('pdfFormat', pdfFormat); - } - data.append('url', _url.href); - - if (properties) { - ConverterUtils.injectPageProperties(data, properties); - } - return GotenbergUtils.fetch(this.endpoint, data); - } catch (error) { - throw error; - } - } -} diff --git a/packages/server/src/lib/Chromiumly/_types.ts b/packages/server/src/lib/Chromiumly/_types.ts deleted file mode 100644 index 453f59ed8..000000000 --- a/packages/server/src/lib/Chromiumly/_types.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { PathLike } from 'fs'; - -export type PageSize = { - width: number; // Paper width, in inches (default 8.5) - height: number; //Paper height, in inches (default 11) -}; - -export type PageMargins = { - top: number; // Top margin, in inches (default 0.39) - bottom: number; // Bottom margin, in inches (default 0.39) - left: number; // Left margin, in inches (default 0.39) - right: number; // Right margin, in inches (default 0.39) -}; - -export type PageProperties = { - size?: PageSize; - margins?: PageMargins; - preferCssPageSize?: boolean; // Define whether to prefer page size as defined by CSS (default false) - printBackground?: boolean; // Print the background graphics (default false) - landscape?: boolean; // Set the paper orientation to landscape (default false) - scale?: number; // The scale of the page rendering (default 1.0) - nativePageRanges?: { from: number; to: number }; // Page ranges to print -}; - -export interface IConverter { - convert({ - ...args - }: { - [x: string]: string | PathLike | PageProperties | PdfFormat; - }): Promise; -} - -export enum PdfFormat { - A_1a = 'PDF/A-1a', - A_2b = 'PDF/A-2b', - A_3b = 'PDF/A-3b', -} - -export enum ChromiumRoute { - URL = 'url', - HTML = 'html', - MARKDOWN = 'markdown', -} - -export enum PdfEngineRoute { - MERGE = 'merge', -} - -export enum LibreOfficeRoute { - CONVERT = 'convert', -} diff --git a/packages/server/src/lib/DependencyGraph/index.js b/packages/server/src/lib/DependencyGraph/index.js deleted file mode 100644 index 0785f5e9c..000000000 --- a/packages/server/src/lib/DependencyGraph/index.js +++ /dev/null @@ -1,350 +0,0 @@ -/** - * A simple dependency graph - */ - -/** - * Helper for creating a Topological Sort using Depth-First-Search on a set of edges. - * - * Detects cycles and throws an Error if one is detected (unless the "circular" - * parameter is "true" in which case it ignores them). - * - * @param edges The set of edges to DFS through - * @param leavesOnly Whether to only return "leaf" nodes (ones who have no edges) - * @param result An array in which the results will be populated - * @param circular A boolean to allow circular dependencies - */ -function createDFS(edges, leavesOnly, result, circular) { - var visited = {}; - return function (start) { - if (visited[start]) { - return; - } - var inCurrentPath = {}; - var currentPath = []; - var todo = []; // used as a stack - todo.push({ node: start, processed: false }); - while (todo.length > 0) { - var current = todo[todo.length - 1]; // peek at the todo stack - var processed = current.processed; - var node = current.node; - if (!processed) { - // Haven't visited edges yet (visiting phase) - if (visited[node]) { - todo.pop(); - continue; - } else if (inCurrentPath[node]) { - // It's not a DAG - if (circular) { - todo.pop(); - // If we're tolerating cycles, don't revisit the node - continue; - } - currentPath.push(node); - throw new DepGraphCycleError(currentPath); - } - - inCurrentPath[node] = true; - currentPath.push(node); - var nodeEdges = edges[node]; - // (push edges onto the todo stack in reverse order to be order-compatible with the old DFS implementation) - for (var i = nodeEdges.length - 1; i >= 0; i--) { - todo.push({ node: nodeEdges[i], processed: false }); - } - current.processed = true; - } else { - // Have visited edges (stack unrolling phase) - todo.pop(); - currentPath.pop(); - inCurrentPath[node] = false; - visited[node] = true; - if (!leavesOnly || edges[node].length === 0) { - result.push(node); - } - } - } - }; -} - -/** - * Simple Dependency Graph - */ -var DepGraph = (DepGraph = function DepGraph(opts) { - this.nodes = {}; // Node -> Node/Data (treated like a Set) - this.outgoingEdges = {}; // Node -> [Dependency Node] - this.incomingEdges = {}; // Node -> [Dependant Node] - this.circular = opts && !!opts.circular; // Allows circular deps -}); - -DepGraph.fromArray = ( - items, - options = { itemId: 'id', parentItemId: 'parent_id' } -) => { - const depGraph = new DepGraph(); - - items.forEach((item) => { - depGraph.addNode(item[options.itemId], item); - }); - items.forEach((item) => { - if (item[options.parentItemId]) { - depGraph.addDependency(item[options.parentItemId], item[options.itemId]); - } - }); - return depGraph; -}; - -DepGraph.prototype = { - /** - * The number of nodes in the graph. - */ - size: function () { - return Object.keys(this.nodes).length; - }, - /** - * Add a node to the dependency graph. If a node already exists, this method will do nothing. - */ - addNode: function (node, data) { - if (!this.hasNode(node)) { - // Checking the arguments length allows the user to add a node with undefined data - if (arguments.length === 2) { - this.nodes[node] = data; - } else { - this.nodes[node] = node; - } - this.outgoingEdges[node] = []; - this.incomingEdges[node] = []; - } - }, - /** - * Remove a node from the dependency graph. If a node does not exist, this method will do nothing. - */ - removeNode: function (node) { - if (this.hasNode(node)) { - delete this.nodes[node]; - delete this.outgoingEdges[node]; - delete this.incomingEdges[node]; - [this.incomingEdges, this.outgoingEdges].forEach(function (edgeList) { - Object.keys(edgeList).forEach(function (key) { - var idx = edgeList[key].indexOf(node); - if (idx >= 0) { - edgeList[key].splice(idx, 1); - } - }, this); - }); - } - }, - /** - * Check if a node exists in the graph - */ - hasNode: function (node) { - return this.nodes.hasOwnProperty(node); - }, - /** - * Get the data associated with a node name - */ - getNodeData: function (node) { - if (this.hasNode(node)) { - return this.nodes[node]; - } else { - throw new Error('Node does not exist: ' + node); - } - }, - - /** - * Set the associated data for a given node name. If the node does not exist, this method will throw an error - */ - setNodeData: function (node, data) { - if (this.hasNode(node)) { - this.nodes[node] = data; - } else { - throw new Error('Node does not exist: ' + node); - } - }, - /** - * Add a dependency between two nodes. If either of the nodes does not exist, - * an Error will be thrown. - */ - addDependency: function (from, to) { - if (!this.hasNode(from)) { - throw new Error('Node does not exist: ' + from); - } - if (!this.hasNode(to)) { - throw new Error('Node does not exist: ' + to); - } - if (this.outgoingEdges[from].indexOf(to) === -1) { - this.outgoingEdges[from].push(to); - } - if (this.incomingEdges[to].indexOf(from) === -1) { - this.incomingEdges[to].push(from); - } - return true; - }, - /** - * Remove a dependency between two nodes. - */ - removeDependency: function (from, to) { - var idx; - if (this.hasNode(from)) { - idx = this.outgoingEdges[from].indexOf(to); - if (idx >= 0) { - this.outgoingEdges[from].splice(idx, 1); - } - } - - if (this.hasNode(to)) { - idx = this.incomingEdges[to].indexOf(from); - if (idx >= 0) { - this.incomingEdges[to].splice(idx, 1); - } - } - }, - /** - * Return a clone of the dependency graph. If any custom data is attached - * to the nodes, it will only be shallow copied. - */ - clone: function () { - var source = this; - var result = new DepGraph(); - var keys = Object.keys(source.nodes); - keys.forEach(function (n) { - result.nodes[n] = source.nodes[n]; - result.outgoingEdges[n] = source.outgoingEdges[n].slice(0); - result.incomingEdges[n] = source.incomingEdges[n].slice(0); - }); - return result; - }, - /** - * Get an array containing the nodes that the specified node depends on (transitively). - * - * Throws an Error if the graph has a cycle, or the specified node does not exist. - * - * If `leavesOnly` is true, only nodes that do not depend on any other nodes will be returned - * in the array. - */ - dependenciesOf: function (node, leavesOnly) { - if (this.hasNode(node)) { - var result = []; - var DFS = createDFS( - this.outgoingEdges, - leavesOnly, - result, - this.circular - ); - DFS(node); - var idx = result.indexOf(node); - if (idx >= 0) { - result.splice(idx, 1); - } - return result; - } else { - throw new Error('Node does not exist: ' + node); - } - }, - /** - * get an array containing the nodes that depend on the specified node (transitively). - * - * Throws an Error if the graph has a cycle, or the specified node does not exist. - * - * If `leavesOnly` is true, only nodes that do not have any dependants will be returned in the array. - */ - dependantsOf: function (node, leavesOnly) { - if (this.hasNode(node)) { - var result = []; - var DFS = createDFS( - this.incomingEdges, - leavesOnly, - result, - this.circular - ); - DFS(node); - var idx = result.indexOf(node); - if (idx >= 0) { - result.splice(idx, 1); - } - return result; - } else { - throw new Error('Node does not exist: ' + node); - } - }, - /** - * Construct the overall processing order for the dependency graph. - * - * Throws an Error if the graph has a cycle. - * - * If `leavesOnly` is true, only nodes that do not depend on any other nodes will be returned. - */ - overallOrder: function (leavesOnly) { - var self = this; - var result = []; - var keys = Object.keys(this.nodes); - if (keys.length === 0) { - return result; // Empty graph - } else { - if (!this.circular) { - // Look for cycles - we run the DFS starting at all the nodes in case there - // are several disconnected subgraphs inside this dependency graph. - var CycleDFS = createDFS(this.outgoingEdges, false, [], this.circular); - keys.forEach(function (n) { - CycleDFS(n); - }); - } - - var DFS = createDFS( - this.outgoingEdges, - leavesOnly, - result, - this.circular - ); - // Find all potential starting points (nodes with nothing depending on them) an - // run a DFS starting at these points to get the order - keys - .filter(function (node) { - return self.incomingEdges[node].length === 0; - }) - .forEach(function (n) { - DFS(n); - }); - - // If we're allowing cycles - we need to run the DFS against any remaining - // nodes that did not end up in the initial result (as they are part of a - // subgraph that does not have a clear starting point) - if (this.circular) { - keys - .filter(function (node) { - return result.indexOf(node) === -1; - }) - .forEach(function (n) { - DFS(n); - }); - } - - return result; - } - }, - - mapNodes(mapper) {}, -}; - -/** - * Cycle error, including the path of the cycle. - */ -var DepGraphCycleError = (exports.DepGraphCycleError = function (cyclePath) { - var message = 'Dependency Cycle Found: ' + cyclePath.join(' -> '); - var instance = new Error(message); - instance.cyclePath = cyclePath; - Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); - if (Error.captureStackTrace) { - Error.captureStackTrace(instance, DepGraphCycleError); - } - return instance; -}); -DepGraphCycleError.prototype = Object.create(Error.prototype, { - constructor: { - value: Error, - enumerable: false, - writable: true, - configurable: true, - }, -}); -Object.setPrototypeOf(DepGraphCycleError, Error); - -export default DepGraph; diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilter.ts b/packages/server/src/lib/DynamicFilter/DynamicFilter.ts deleted file mode 100644 index b50391dc2..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilter.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { forEach, uniqBy } from 'lodash'; -import DynamicFilterAbstractor from './DynamicFilterAbstractor'; -import { IDynamicFilter, IFilterRole, IModel } from '@/interfaces'; - -export default class DynamicFilter extends DynamicFilterAbstractor{ - private model: IModel; - private tableName: string; - private dynamicFilters: IDynamicFilter[]; - - /** - * Constructor. - * @param {String} tableName - - */ - constructor(model) { - super(); - - this.model = model; - this.tableName = model.tableName; - this.dynamicFilters = []; - } - - /** - * Registers the given dynamic filter. - * @param {IDynamicFilter} filterRole - Filter role. - */ - public setFilter = (dynamicFilter: IDynamicFilter) => { - dynamicFilter.setModel(this.model); - - dynamicFilter.onInitialize(); - - this.dynamicFilters.push(dynamicFilter); - } - - /** - * Retrieve dynamic filter build queries. - * @returns - */ - private dynamicFiltersBuildQuery = () => { - return this.dynamicFilters.map((filter) => { - return filter.buildQuery() - }); - } - - /** - * Retrieve dynamic filter roles. - * @returns {IFilterRole[]} - */ - private dynamicFilterTableColumns = (): IFilterRole[] => { - const localFilterRoles = []; - - this.dynamicFilters.forEach((dynamicFilter) => { - const { filterRoles } = dynamicFilter; - - localFilterRoles.push( - ...(Array.isArray(filterRoles) ? filterRoles : [filterRoles]) - ); - }); - return localFilterRoles; - } - - /** - * Builds queries of filter roles. - */ - public buildQuery = () => { - const buildersCallbacks = this.dynamicFiltersBuildQuery(); - const tableColumns = this.dynamicFilterTableColumns(); - - return (builder) => { - buildersCallbacks.forEach((builderCallback) => { - builderCallback(builder); - }); - this.buildFilterRolesJoins(builder); - }; - } - - /** - * Retrieve response metadata from all filters adapters. - */ - public getResponseMeta = () => { - const responseMeta = {}; - - this.dynamicFilters.forEach((filter) => { - const { responseMeta: filterMeta } = filter; - - forEach(filterMeta, (value, key) => { - responseMeta[key] = value; - }); - }); - return responseMeta; - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterAbstractor.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterAbstractor.ts deleted file mode 100644 index 256333c68..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterAbstractor.ts +++ /dev/null @@ -1,50 +0,0 @@ - -export default class DynamicFilterAbstractor { - /** - * Extract relation table name from relation. - * @param {String} column - - * @return {String} - join relation table. - */ - protected getTableFromRelationColumn = (column: string) => { - const splitedColumn = column.split('.'); - return splitedColumn.length > 0 ? splitedColumn[0] : ''; - }; - - /** - * Builds view roles join queries. - * @param {String} tableName - Table name. - * @param {Array} roles - Roles. - */ - protected buildFilterRolesJoins = (builder) => { - this.dynamicFilters.forEach((dynamicFilter) => { - const relationsFields = dynamicFilter.relationFields; - - this.buildFieldsJoinQueries(builder, relationsFields); - }); - }; - - /** - * Builds join queries of fields. - * @param builder - - * @param {string[]} fieldsRelations - - */ - private buildFieldsJoinQueries = (builder, fieldsRelations: string[]) => { - fieldsRelations.forEach((fieldRelation) => { - const relation = this.model.relationMappings[fieldRelation]; - - if (relation) { - const splitToRelation = relation.join.to.split('.'); - const relationTable = splitToRelation[0] || ''; - - builder.join(relationTable, relation.join.from, '=', relation.join.to); - } - }); - }; - - /** - * Retrieve the dynamic filter mode. - */ - protected getModel() { - return this.model; - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterAdvancedFilter.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterAdvancedFilter.ts deleted file mode 100644 index e18560208..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterAdvancedFilter.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IFilterRole } from '@/interfaces'; -import DynamicFilterFilterRoles from './DynamicFilterFilterRoles'; - -export default class DynamicFilterAdvancedFilter extends DynamicFilterFilterRoles { - private filterRoles: IFilterRole[]; - - /** - * Constructor method. - * @param {Array} filterRoles - - * @param {Array} resourceFields - - */ - constructor(filterRoles: IFilterRole[]) { - super(); - - this.filterRoles = filterRoles; - this.setResponseMeta(); - } - - /** - * Sets response meta. - */ - private setResponseMeta() { - this.responseMeta = { - filterRoles: this.filterRoles, - }; - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterFilterRoles.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterFilterRoles.ts deleted file mode 100644 index 0bacf4d80..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterFilterRoles.ts +++ /dev/null @@ -1,52 +0,0 @@ -import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor'; -import { IFilterRole } from '@/interfaces'; - -export default class FilterRoles extends DynamicFilterRoleAbstractor { - private filterRoles: IFilterRole[]; - - /** - * On initialize filter roles. - */ - public onInitialize() { - super.onInitialize(); - this.setFilterRolesRelations(); - } - - /** - * Builds filter roles logic expression. - * @return {string} - */ - private buildLogicExpression(): string { - let expression = ''; - - this.filterRoles.forEach((role, index) => { - expression += - index === 0 ? `${role.index} ` : `${role.condition} ${role.index} `; - }); - return expression.trim(); - } - - /** - * Builds database query of view roles. - */ - protected buildQuery() { - const logicExpression = this.buildLogicExpression(); - - return (builder) => { - this.buildFilterQuery( - this.model, - this.filterRoles, - logicExpression - )(builder); - }; - } - - /** - * Sets filter roles relations if field was relation type. - */ - private setFilterRolesRelations() { - this.filterRoles.forEach((relationRole) => { - this.setRelationIfRelationField(relationRole.fieldKey); - }); - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterQueryParser.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterQueryParser.ts deleted file mode 100644 index d57f82030..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterQueryParser.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { OPERATION } from '../LogicEvaluation/Parser'; - -export default class QueryParser { - constructor(tree, queries) { - this.tree = tree; - this.queries = queries; - this.query = null; - } - - setQuery(query) { - this.query = query.clone(); - } - - parse() { - return this.parseNode(this.tree); - } - - parseNode(node) { - if (typeof node === 'string') { - const nodeQuery = this.getQuery(node); - return (query) => { - nodeQuery(query); - }; - } - if (OPERATION[node.operation] === undefined) { - throw new Error(`unknow expression ${node.operation}`); - } - const leftQuery = this.getQuery(node.left); - const rightQuery = this.getQuery(node.right); - - switch (node.operation) { - case '&&': - case 'AND': - default: - return (nodeQuery) => - nodeQuery.where((query) => { - query.where((q) => { - leftQuery(q); - }); - query.andWhere((q) => { - rightQuery(q); - }); - }); - case '||': - case 'OR': - return (nodeQuery) => - nodeQuery.where((query) => { - query.where((q) => { - leftQuery(q); - }); - query.orWhere((q) => { - rightQuery(q); - }); - }); - } - } - - getQuery(node) { - if (typeof node !== 'string' && node !== null) { - return this.parseNode(node); - } - const value = parseFloat(node); - - if (!isNaN(value)) { - if (typeof this.queries[node] === 'undefined') { - throw new Error(`unknow query under index ${node}`); - } - return this.queries[node]; - } - return null; - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterRoleAbstractor.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterRoleAbstractor.ts deleted file mode 100644 index 488f48919..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterRoleAbstractor.ts +++ /dev/null @@ -1,387 +0,0 @@ -import moment from 'moment'; -import * as R from 'ramda'; -import { IFilterRole, IDynamicFilter, IModel } from '@/interfaces'; -import Parser from '../LogicEvaluation/Parser'; -import DynamicFilterQueryParser from './DynamicFilterQueryParser'; -import { Lexer } from '../LogicEvaluation/Lexer'; -import { COMPARATOR_TYPE, FIELD_TYPE } from './constants'; - -export default abstract class DynamicFilterAbstractor - implements IDynamicFilter -{ - protected filterRoles: IFilterRole[] = []; - protected tableName: string; - protected model: IModel; - protected responseMeta: { [key: string]: any } = {}; - public relationFields = []; - - /** - * Sets model the dynamic filter service. - * @param {IModel} model - */ - public setModel(model: IModel) { - this.model = model; - this.tableName = model.tableName; - } - - /** - * Transformes filter roles to map by index. - * @param {IModel} model - * @param {IFilterRole[]} roles - * @returns - */ - protected convertRolesMapByIndex = (model, roles) => { - const rolesIndexSet = {}; - - roles.forEach((role) => { - rolesIndexSet[role.index] = this.buildRoleQuery(model, role); - }); - return rolesIndexSet; - }; - - /** - * Builds database query from stored view roles. - * @param {Array} roles - - * @return {Function} - */ - protected buildFilterRolesQuery = ( - model: IModel, - roles: IFilterRole[], - logicExpression: string = '' - ) => { - const rolesIndexSet = this.convertRolesMapByIndex(model, roles); - - // Lexer for logic expression. - const lexer = new Lexer(logicExpression); - const tokens = lexer.getTokens(); - - // Parse the logic expression. - const parser = new Parser(tokens); - const parsedTree = parser.parse(); - - const queryParser = new DynamicFilterQueryParser(parsedTree, rolesIndexSet); - - return queryParser.parse(); - }; - - /** - * Parses the logic expression to base expression. - * @param {string} logicExpression - - * @return {string} - */ - private parseLogicExpression(logicExpression: string): string { - return R.compose( - R.replace(/or|OR/g, '||'), - R.replace(/and|AND/g, '&&'), - )(logicExpression); - } - - /** - * Builds filter query for query builder. - * @param {String} tableName - Table name. - * @param {Array} roles - Filter roles. - * @param {String} logicExpression - Logic expression. - */ - protected buildFilterQuery = ( - model: IModel, - roles: IFilterRole[], - logicExpression: string - ) => { - const basicExpression = this.parseLogicExpression(logicExpression); - - return (builder) => { - this.buildFilterRolesQuery(model, roles, basicExpression)(builder); - }; - }; - - /** - * Retrieve relation column of comparator fieldز - */ - private getFieldComparatorRelationColumn(field) { - const relation = this.model.relationMappings[field.relationKey]; - - if (relation) { - const relationModel = relation.modelClass; - const relationColumn = - field.relationEntityKey === 'id' - ? 'id' - : relationModel.getField(field.relationEntityKey, 'column'); - - return `${relationModel.tableName}.${relationColumn}`; - } - } - - /** - * Retrieve the comparator field column. - * @param {IModel} model - - * @param {} - - */ - private getFieldComparatorColumn = (field) => { - return field.fieldType === FIELD_TYPE.RELATION - ? this.getFieldComparatorRelationColumn(field) - : `${this.tableName}.${field.column}`; - }; - - /** - * Builds roles queries. - * @param {IModel} model - - * @param {Object} role - - */ - protected buildRoleQuery = (model: IModel, role: IFilterRole) => { - const field = model.getField(role.fieldKey); - const comparatorColumn = this.getFieldComparatorColumn(field); - - // Field relation custom query. - if (typeof field.filterCustomQuery !== 'undefined') { - return (builder) => { - field.filterCustomQuery(builder, role); - }; - } - switch (field.fieldType) { - case FIELD_TYPE.BOOLEAN: - case FIELD_TYPE.ENUMERATION: - return this.booleanRoleQueryBuilder(role, comparatorColumn); - case FIELD_TYPE.NUMBER: - return this.numberRoleQueryBuilder(role, comparatorColumn); - case FIELD_TYPE.DATE: - return this.dateQueryBuilder(role, comparatorColumn); - case FIELD_TYPE.TEXT: - default: - return this.textRoleQueryBuilder(role, comparatorColumn); - } - }; - - /** - * Boolean column query builder. - * @param {IFilterRole} role - * @param {string} comparatorColumn - * @returns - */ - protected booleanRoleQueryBuilder = ( - role: IFilterRole, - comparatorColumn: string - ) => { - switch (role.comparator) { - case COMPARATOR_TYPE.EQUALS: - case COMPARATOR_TYPE.EQUAL: - case COMPARATOR_TYPE.IS: - default: - return (builder) => { - builder.where(comparatorColumn, '=', role.value); - }; - case COMPARATOR_TYPE.NOT_EQUAL: - case COMPARATOR_TYPE.NOT_EQUALS: - case COMPARATOR_TYPE.IS_NOT: - return (builder) => { - builder.where(comparatorColumn, '<>', role.value); - }; - } - }; - - /** - * Numeric column query builder. - * @param {IFilterRole} role - * @param {string} comparatorColumn - * @returns - */ - protected numberRoleQueryBuilder = ( - role: IFilterRole, - comparatorColumn: string - ) => { - switch (role.comparator) { - case COMPARATOR_TYPE.EQUALS: - case COMPARATOR_TYPE.EQUAL: - default: - return (builder) => { - builder.where(comparatorColumn, '=', role.value); - }; - case COMPARATOR_TYPE.NOT_EQUAL: - case COMPARATOR_TYPE.NOT_EQUALS: - return (builder) => { - builder.whereNot(comparatorColumn, role.value); - }; - case COMPARATOR_TYPE.BIGGER_THAN: - case COMPARATOR_TYPE.BIGGER: - return (builder) => { - builder.where(comparatorColumn, '>', role.value); - }; - case COMPARATOR_TYPE.BIGGER_OR_EQUALS: - return (builder) => { - builder.where(comparatorColumn, '>=', role.value); - }; - case COMPARATOR_TYPE.SMALLER_THAN: - case COMPARATOR_TYPE.SMALLER: - return (builder) => { - builder.where(comparatorColumn, '<', role.value); - }; - case COMPARATOR_TYPE.SMALLER_OR_EQUALS: - return (builder) => { - builder.where(comparatorColumn, '<=', role.value); - }; - } - }; - - /** - * Text column query builder. - * @param {IFilterRole} role - * @param {string} comparatorColumn - * @returns {Function} - */ - protected textRoleQueryBuilder = ( - role: IFilterRole, - comparatorColumn: string - ) => { - switch (role.comparator) { - case COMPARATOR_TYPE.EQUAL: - case COMPARATOR_TYPE.EQUALS: - case COMPARATOR_TYPE.IS: - default: - return (builder) => { - builder.where(comparatorColumn, role.value); - }; - case COMPARATOR_TYPE.NOT_EQUALS: - case COMPARATOR_TYPE.NOT_EQUAL: - case COMPARATOR_TYPE.IS_NOT: - return (builder) => { - builder.whereNot(comparatorColumn, role.value); - }; - case COMPARATOR_TYPE.CONTAIN: - case COMPARATOR_TYPE.CONTAINS: - return (builder) => { - builder.where(comparatorColumn, 'LIKE', `%${role.value}%`); - }; - case COMPARATOR_TYPE.NOT_CONTAIN: - case COMPARATOR_TYPE.NOT_CONTAINS: - return (builder) => { - builder.whereNot(comparatorColumn, 'LIKE', `%${role.value}%`); - }; - case COMPARATOR_TYPE.STARTS_WITH: - case COMPARATOR_TYPE.START_WITH: - return (builder) => { - builder.where(comparatorColumn, 'LIKE', `${role.value}%`); - }; - case COMPARATOR_TYPE.ENDS_WITH: - case COMPARATOR_TYPE.END_WITH: - return (builder) => { - builder.where(comparatorColumn, 'LIKE', `%${role.value}`); - }; - - } - }; - - /** - * Date column query builder. - * @param {IFilterRole} role - * @param {string} comparatorColumn - * @returns {Function} - */ - protected dateQueryBuilder = ( - role: IFilterRole, - comparatorColumn: string - ) => { - switch (role.comparator) { - case COMPARATOR_TYPE.AFTER: - case COMPARATOR_TYPE.BEFORE: - return (builder) => { - this.dateQueryAfterBeforeComparator(role, comparatorColumn, builder); - }; - case COMPARATOR_TYPE.IN: - return (builder) => { - this.dateQueryInComparator(role, comparatorColumn, builder); - }; - } - }; - - /** - * Date query 'IN' comparator type. - * @param {IFilterRole} role - * @param {string} comparatorColumn - * @param builder - */ - protected dateQueryInComparator = ( - role: IFilterRole, - comparatorColumn: string, - builder - ) => { - const hasTimeFormat = moment( - role.value, - 'YYYY-MM-DD HH:MM', - true - ).isValid(); - const dateFormat = 'YYYY-MM-DD HH:MM:SS'; - - if (hasTimeFormat) { - const targetDateTime = moment(role.value).format(dateFormat); - builder.where(comparatorColumn, '=', targetDateTime); - } else { - const startDate = moment(role.value).startOf('day'); - const endDate = moment(role.value).endOf('day'); - - builder.where(comparatorColumn, '>=', startDate.format(dateFormat)); - builder.where(comparatorColumn, '<=', endDate.format(dateFormat)); - } - }; - - /** - * Date query after/before comparator type. - * @param {IFilterRole} role - * @param {string} comparatorColumn - Column. - * @param builder - */ - protected dateQueryAfterBeforeComparator = ( - role: IFilterRole, - comparatorColumn: string, - builder - ) => { - const comparator = role.comparator === COMPARATOR_TYPE.BEFORE ? '<' : '>'; - const hasTimeFormat = moment( - role.value, - 'YYYY-MM-DD HH:MM', - true - ).isValid(); - const targetDate = moment(role.value); - const dateFormat = 'YYYY-MM-DD HH:MM:SS'; - - if (!hasTimeFormat) { - if (role.comparator === COMPARATOR_TYPE.BEFORE) { - targetDate.startOf('day'); - } else { - targetDate.endOf('day'); - } - } - const comparatorValue = targetDate.format(dateFormat); - builder.where(comparatorColumn, comparator, comparatorValue); - }; - - /** - * Registers relation field if the given field was relation type - * and not registered. - * @param {string} fieldKey - Field key. - */ - protected setRelationIfRelationField = (fieldKey: string): void => { - const field = this.model.getField(fieldKey); - const isAlreadyRegistered = this.relationFields.some( - (field) => field === fieldKey - ); - - if ( - !isAlreadyRegistered && - field && - field.fieldType === FIELD_TYPE.RELATION - ) { - this.relationFields.push(field.relationKey); - } - }; - - /** - * Retrieve the model. - */ - getModel() { - return this.model; - } - - /** - * On initialize the registered dynamic filter. - */ - onInitialize() {} -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterSearch.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterSearch.ts deleted file mode 100644 index 3e8650872..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterSearch.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { IFilterRole } from '@/interfaces'; -import DynamicFilterFilterRoles from './DynamicFilterFilterRoles'; - -export default class DynamicFilterSearch extends DynamicFilterFilterRoles { - private searchKeyword: string; - private filterRoles: IFilterRole[]; - - /** - * Constructor method. - * @param {string} searchKeyword - Search keyword. - */ - constructor(searchKeyword: string) { - super(); - this.searchKeyword = searchKeyword; - } - - /** - * On initialize the dynamic filter. - */ - public onInitialize() { - super.onInitialize(); - this.filterRoles = this.getModelSearchFilterRoles(this.searchKeyword); - } - - /** - * Retrieve the filter roles from model search roles. - * @param {string} searchKeyword - * @returns {IFilterRole[]} - */ - private getModelSearchFilterRoles(searchKeyword: string): IFilterRole[] { - const model = this.getModel(); - - return model.searchRoles.map((searchRole, index) => ({ - ...searchRole, - value: searchKeyword, - index: index + 1, - })); - } - - /** - * - */ - setResponseMeta() { - this.responseMeta = { - searchKeyword: this.searchKeyword, - }; - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterSortBy.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterSortBy.ts deleted file mode 100644 index d70ff3603..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterSortBy.ts +++ /dev/null @@ -1,92 +0,0 @@ -import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor'; -import { FIELD_TYPE } from './constants'; - -interface ISortRole { - fieldKey: string; - order: string; -} - -export default class DynamicFilterSortBy extends DynamicFilterRoleAbstractor { - private sortRole: ISortRole = {}; - - /** - * Constructor method. - * @param {string} sortByFieldKey - * @param {string} sortDirection - */ - constructor(sortByFieldKey: string, sortDirection: string) { - super(); - - this.sortRole = { - fieldKey: sortByFieldKey, - order: sortDirection, - }; - this.setResponseMeta(); - } - - /** - * On initialize the dyanmic sort by. - */ - public onInitialize() { - this.setRelationIfRelationField(this.sortRole.fieldKey); - } - - /** - * Retrieve field comparator relatin column. - * @param field - * @returns {string} - */ - private getFieldComparatorRelationColumn = (field): string => { - const relation = this.model.relationMappings[field.relationKey]; - - if (relation) { - const relationModel = relation.modelClass; - const relationField = relationModel.getField(field.relationEntityLabel); - - return `${relationModel.tableName}.${relationField.column}`; - } - return ''; - }; - - /** - * Retrieve the comparator field column. - * @param {IModel} field - * @returns {string} - */ - private getFieldComparatorColumn = (field): string => { - return field.fieldType === FIELD_TYPE.RELATION - ? this.getFieldComparatorRelationColumn(field) - : `${this.tableName}.${field.column}`; - }; - - /** - * Builds database query of sort by column on the given direction. - */ - public buildQuery = () => { - const field = this.model.getField(this.sortRole.fieldKey); - const comparatorColumn = this.getFieldComparatorColumn(field); - - // Sort custom query. - if (typeof field.sortCustomQuery !== 'undefined') { - return (builder) => { - field.sortCustomQuery(builder, this.sortRole); - }; - } - - return (builder) => { - if (this.sortRole.fieldKey) { - builder.orderBy(`${comparatorColumn}`, this.sortRole.order); - } - }; - }; - - /** - * Sets response meta. - */ - public setResponseMeta() { - this.responseMeta = { - sortOrder: this.sortRole.fieldKey, - sortBy: this.sortRole.order, - }; - } -} diff --git a/packages/server/src/lib/DynamicFilter/DynamicFilterViews.ts b/packages/server/src/lib/DynamicFilter/DynamicFilterViews.ts deleted file mode 100644 index 289e616ab..000000000 --- a/packages/server/src/lib/DynamicFilter/DynamicFilterViews.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { omit } from 'lodash'; -import { IView, IViewRole } from '@/interfaces'; -import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor'; - -export default class DynamicFilterViews extends DynamicFilterRoleAbstractor { - private viewSlug: string; - private logicExpression: string; - private filterRoles: IViewRole[]; - private viewColumns = []; - - /** - * Constructor method. - * @param {IView} view - - */ - constructor(view: IView) { - super(); - - this.viewSlug = view.slug; - this.filterRoles = view.roles; - this.viewColumns = view.columns; - this.logicExpression = view.rolesLogicExpression - .replace('AND', '&&') - .replace('OR', '||'); - - this.setResponseMeta(); - } - - /** - * Builds database query of view roles. - */ - public buildQuery() { - return (builder) => { - this.buildFilterQuery( - this.model, - this.filterRoles, - this.logicExpression - )(builder); - }; - } - - /** - * Sets response meta. - */ - public setResponseMeta() { - this.responseMeta = { - view: { - logicExpression: this.logicExpression, - filterRoles: this.filterRoles.map((filterRole) => ({ - ...omit(filterRole, ['id', 'viewId']), - })), - viewSlug: this.viewSlug, - viewColumns: this.viewColumns, - }, - }; - } -} diff --git a/packages/server/src/lib/DynamicFilter/constants.ts b/packages/server/src/lib/DynamicFilter/constants.ts deleted file mode 100644 index f845e16c9..000000000 --- a/packages/server/src/lib/DynamicFilter/constants.ts +++ /dev/null @@ -1,43 +0,0 @@ -export const COMPARATOR_TYPE = { - EQUAL: 'equal', - EQUALS: 'equals', - - NOT_EQUAL: 'not_equal', - NOT_EQUALS: 'not_equals', - - BIGGER_THAN: 'bigger_than', - BIGGER: 'bigger', - BIGGER_OR_EQUALS: 'bigger_or_equals', - - SMALLER_THAN: 'smaller_than', - SMALLER: 'smaller', - SMALLER_OR_EQUALS: 'smaller_or_equals', - - IS: 'is', - IS_NOT: 'is_not', - - CONTAINS: 'contains', - CONTAIN: 'contain', - NOT_CONTAINS: 'contains', - NOT_CONTAIN: 'contain', - - AFTER: 'after', - BEFORE: 'before', - IN: 'in', - - STARTS_WITH: 'starts_with', - START_WITH: 'start_with', - - ENDS_WITH: 'ends_with', - END_WITH: 'end_with' -}; - -export const FIELD_TYPE = { - TEXT: 'text', - NUMBER: 'number', - ENUMERATION: 'enumeration', - BOOLEAN: 'boolean', - RELATION: 'relation', - DATE: 'date', - COMPUTED: 'computed' -}; diff --git a/packages/server/src/lib/DynamicFilter/index.ts b/packages/server/src/lib/DynamicFilter/index.ts deleted file mode 100644 index 10cc6221c..000000000 --- a/packages/server/src/lib/DynamicFilter/index.ts +++ /dev/null @@ -1,13 +0,0 @@ - - -import DynamicFilter from './DynamicFilter'; -import DynamicFilterSortBy from './DynamicFilterSortBy'; -import DynamicFilterViews from './DynamicFilterViews'; -import DynamicFilterFilterRoles from './DynamicFilterFilterRoles'; - -export { - DynamicFilter, - DynamicFilterSortBy, - DynamicFilterViews, - DynamicFilterFilterRoles, -}; \ No newline at end of file diff --git a/packages/server/src/lib/EventPublisher/EventPublisher.ts b/packages/server/src/lib/EventPublisher/EventPublisher.ts deleted file mode 100644 index 23a3b7103..000000000 --- a/packages/server/src/lib/EventPublisher/EventPublisher.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Container } from 'typedi'; -import { EventEmitter2 } from 'eventemitter2'; - -interface IEventPublisherArgs { - subscribers: EventSubscriber[]; -} -class PublishEvent { - constructor(public id: string) {} -} - -type SubscribeListenerFunction = (event: PublishEvent) => void; -type SubscribeFunction = (id: string, cb: SubscribeListenerFunction) => void; - -interface IEventBus { - subscribe: SubscribeFunction; -} - -export abstract class EventSubscriber { - abstract attach(bus: IEventBus): void; -} - -export class EventPublisher { - private emitter: EventEmitter2; - - /** - * - * @param {IEventPublisherArgs} args - */ - constructor() { - this.emitter = new EventEmitter2({ wildcard: true, delimiter: '.' }); - } - - /** - * - * @param {EventSubscriber} args - */ - loadSubscribers(subscribers: EventSubscriber[]) { - const bus: IEventBus = { - subscribe: (id, cb) => { - this.emitter.on(id, cb); - }, - }; - for (const Subscriber of subscribers) { - const subscriberInstance = Container.get(Subscriber); - subscriberInstance.attach(bus); - } - } - - /** - * - * @param event - * @param payload - */ - emit(event: string, payload) { - return this.emitter.emit(event, payload); - } - - /** - * - * @param event - * @param payload - */ - emitAsync(event: string, payload) { - return this.emitter.emitAsync(event, payload); - } -} diff --git a/packages/server/src/lib/ExchangeRate/ExchangeRate.ts b/packages/server/src/lib/ExchangeRate/ExchangeRate.ts deleted file mode 100644 index 5bb84cff3..000000000 --- a/packages/server/src/lib/ExchangeRate/ExchangeRate.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { OpenExchangeRate } from './OpenExchangeRate'; -import { ExchangeRateServiceType, IExchangeRateService } from './types'; - -export class ExchangeRate { - private exchangeRateService: IExchangeRateService; - private exchangeRateServiceType: ExchangeRateServiceType; - - /** - * Constructor method. - * @param {ExchangeRateServiceType} service - */ - constructor(service: ExchangeRateServiceType) { - this.exchangeRateServiceType = service; - this.initService(); - } - - /** - * Initialize the exchange rate service based on the service type. - */ - private initService() { - if ( - this.exchangeRateServiceType === ExchangeRateServiceType.OpenExchangeRate - ) { - this.setExchangeRateService(new OpenExchangeRate()); - } - } - - /** - * Sets the exchange rate service. - * @param {IExchangeRateService} service - */ - private setExchangeRateService(service: IExchangeRateService) { - this.exchangeRateService = service; - } - - /** - * Gets the latest exchange rate. - * @param {string} baseCurrency - * @param {string} toCurrency - * @returns {number} - */ - public latest(baseCurrency: string, toCurrency: string): Promise { - return this.exchangeRateService.latest(baseCurrency, toCurrency); - } -} diff --git a/packages/server/src/lib/ExchangeRate/OpenExchangeRate.ts b/packages/server/src/lib/ExchangeRate/OpenExchangeRate.ts deleted file mode 100644 index 221c5c5c5..000000000 --- a/packages/server/src/lib/ExchangeRate/OpenExchangeRate.ts +++ /dev/null @@ -1,81 +0,0 @@ -import Axios, { AxiosError } from 'axios'; -import { - EchangeRateErrors, - IExchangeRateService, - OPEN_EXCHANGE_RATE_LATEST_URL, -} from './types'; -import config from '@/config'; -import { ServiceError } from '@/exceptions'; - -export class OpenExchangeRate implements IExchangeRateService { - /** - * Gets the latest exchange rate. - * @param {string} baseCurrency - * @param {string} toCurrency - * @returns {Promise { - // Vaclidates the Open Exchange Rate api id early. - this.validateApiIdExistance(); - - try { - const result = await Axios.get(OPEN_EXCHANGE_RATE_LATEST_URL, { - params: { - app_id: config.exchangeRate.openExchangeRate.appId, - base: baseCurrency, - symbols: toCurrency, - }, - }); - return result.data.rates[toCurrency] || (1 as number); - } catch (error) { - this.handleLatestErrors(error); - } - } - - /** - * Validates the Open Exchange Rate api id. - * @throws {ServiceError} - */ - private validateApiIdExistance() { - const apiId = config.exchangeRate.openExchangeRate.appId; - - if (!apiId) { - throw new ServiceError( - EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED, - 'Invalid App ID provided. Please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org.' - ); - } - } - - /** - * Handles the latest errors. - * @param {any} error - * @throws {ServiceError} - */ - private handleLatestErrors(error: any) { - if (error.response.data?.message === 'missing_app_id') { - throw new ServiceError( - EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED, - 'Invalid App ID provided. Please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org.' - ); - } else if (error.response.data?.message === 'invalid_app_id') { - throw new ServiceError( - EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED, - 'Invalid App ID provided. Please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org.' - ); - } else if (error.response.data?.message === 'not_allowed') { - throw new ServiceError( - EchangeRateErrors.EX_RATE_SERVICE_NOT_ALLOWED, - 'Getting the exchange rate from the given base currency to the given currency is not allowed.' - ); - } else if (error.response.data?.message === 'invalid_base') { - throw new ServiceError( - EchangeRateErrors.EX_RATE_INVALID_BASE_CURRENCY, - 'The given base currency is invalid.' - ); - } - } -} diff --git a/packages/server/src/lib/ExchangeRate/types.ts b/packages/server/src/lib/ExchangeRate/types.ts deleted file mode 100644 index 8b40125cd..000000000 --- a/packages/server/src/lib/ExchangeRate/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface IExchangeRateService { - latest(baseCurrency: string, toCurrency: string): Promise; -} - -export enum ExchangeRateServiceType { - OpenExchangeRate = 'OpenExchangeRate', -} - -export enum EchangeRateErrors { - EX_RATE_SERVICE_NOT_ALLOWED = 'EX_RATE_SERVICE_NOT_ALLOWED', - EX_RATE_LIMIT_EXCEEDED = 'EX_RATE_LIMIT_EXCEEDED', - EX_RATE_SERVICE_API_KEY_REQUIRED = 'EX_RATE_SERVICE_API_KEY_REQUIRED', - EX_RATE_INVALID_BASE_CURRENCY = 'EX_RATE_INVALID_BASE_CURRENCY', -} - -export const OPEN_EXCHANGE_RATE_LATEST_URL = - 'https://openexchangerates.org/api/latest.json'; diff --git a/packages/server/src/lib/KnexFactory/index.js b/packages/server/src/lib/KnexFactory/index.js deleted file mode 100644 index 866af6eae..000000000 --- a/packages/server/src/lib/KnexFactory/index.js +++ /dev/null @@ -1,55 +0,0 @@ -const { extend, isFunction, isObject } = require('lodash'); - -export default class KnexFactory { - - constructor(knex) { - this.knex = knex; - - this.factories = []; - } - - define(name, tableName, defaultAttributes) { - this.factories[name] = { tableName, defaultAttributes }; - } - - async build(factoryName, attributes) { - const factory = this.factories[factoryName]; - - if (!factory) { - throw `Unkown factory: ${factoryName}`; - } - let { defaultAttributes } = factory; - const insertData = {}; - - if( 'function' === typeof defaultAttributes) { - defaultAttributes = await defaultAttributes(); - } - extend(insertData, defaultAttributes, attributes); - - for (let k in insertData) { - const v = insertData[k]; - - if (isFunction(v)) { - insertData[k] = await v(); - } else { - insertData[k] = await v; - } - if (isObject(insertData[k]) && insertData[k].id) { - insertData[k] = insertData[k].id; - } - }; - - return insertData; - } - - async create(factoryName, attributes) { - const factory = this.factories[factoryName]; - const insertData = await this.build(factoryName, attributes); - const { tableName } = factory; - - const [id] = await this.knex(tableName).insert(insertData); - const record = await this.knex(tableName).where({ id }).first(); - - return record; - } -} \ No newline at end of file diff --git a/packages/server/src/lib/LogicEvaluation/Lexer.js b/packages/server/src/lib/LogicEvaluation/Lexer.js deleted file mode 100644 index 3cfc04f41..000000000 --- a/packages/server/src/lib/LogicEvaluation/Lexer.js +++ /dev/null @@ -1,172 +0,0 @@ - -const OperationType = { - LOGIC: 'LOGIC', - STRING: 'STRING', - COMPARISON: 'COMPARISON', - MATH: 'MATH', -}; - -export class Lexer { - // operation table - static get optable() { - return { - '=': OperationType.LOGIC, - '&': OperationType.LOGIC, - '|': OperationType.LOGIC, - '?': OperationType.LOGIC, - ':': OperationType.LOGIC, - - '\'': OperationType.STRING, - '"': OperationType.STRING, - - '!': OperationType.COMPARISON, - '>': OperationType.COMPARISON, - '<': OperationType.COMPARISON, - - '(': OperationType.MATH, - ')': OperationType.MATH, - '+': OperationType.MATH, - '-': OperationType.MATH, - '*': OperationType.MATH, - '/': OperationType.MATH, - '%': OperationType.MATH, - }; - } - - /** - * Constructor - * @param {*} expression - - */ - constructor(expression) { - this.currentIndex = 0; - this.input = expression; - this.tokenList = []; - } - - getTokens() { - let tok; - do { - // read current token, so step should be -1 - tok = this.pickNext(-1); - const pos = this.currentIndex; - switch (Lexer.optable[tok]) { - case OperationType.LOGIC: - // == && || === - this.readLogicOpt(tok); - break; - - case OperationType.STRING: - this.readString(tok); - break; - - case OperationType.COMPARISON: - this.readCompare(tok); - break; - - case OperationType.MATH: - this.receiveToken(); - break; - - default: - this.readValue(tok); - } - - // if the pos not changed, this loop will go into a infinite loop, every step of while loop, - // we must move the pos forward - // so here we should throw error, for example `1 & 2` - if (pos === this.currentIndex && tok !== undefined) { - const err = new Error(`unkonw token ${tok} from input string ${this.input}`); - err.name = 'UnknowToken'; - throw err; - } - } while (tok !== undefined) - - return this.tokenList; - } - - /** - * read next token, the index param can set next step, default go foward 1 step - * - * @param index next postion - */ - pickNext(index = 0) { - return this.input[index + this.currentIndex + 1]; - } - - /** - * Store token into result tokenList, and move the pos index - * - * @param index - */ - receiveToken(index = 1) { - const tok = this.input.slice(this.currentIndex, this.currentIndex + index).trim(); - // skip empty string - if (tok) { - this.tokenList.push(tok); - } - - this.currentIndex += index; - } - - // ' or " - readString(tok) { - let next; - let index = 0; - do { - next = this.pickNext(index); - index += 1; - } while (next !== tok && next !== undefined); - this.receiveToken(index + 1); - } - - // > or < or >= or <= or !== - // tok in (>, <, !) - readCompare(tok) { - if (this.pickNext() !== '=') { - this.receiveToken(1); - return; - } - // !== - if (tok === '!' && this.pickNext(1) === '=') { - this.receiveToken(3); - return; - } - this.receiveToken(2); - } - - // === or == - // && || - readLogicOpt(tok) { - if (this.pickNext() === tok) { - // === - if (tok === '=' && this.pickNext(1) === tok) { - return this.receiveToken(3); - } - // == && || - return this.receiveToken(2); - } - // handle as && - // a ? b : c is equal to a && b || c - if (tok === '?' || tok === ':') { - return this.receiveToken(1); - } - } - - readValue(tok) { - if (!tok) { - return; - } - - let index = 0; - while (!Lexer.optable[tok] && tok !== undefined) { - tok = this.pickNext(index); - index += 1; - } - this.receiveToken(index); - } -} - -export default function token(expression) { - const lexer = new Lexer(expression); - return lexer.getTokens(); -} diff --git a/packages/server/src/lib/LogicEvaluation/Parser.js b/packages/server/src/lib/LogicEvaluation/Parser.js deleted file mode 100644 index 8e7156592..000000000 --- a/packages/server/src/lib/LogicEvaluation/Parser.js +++ /dev/null @@ -1,159 +0,0 @@ -export const OPERATION = { - '!': 5, - '*': 4, - '/': 4, - '%': 4, - '+': 3, - '-': 3, - '>': 2, - '<': 2, - '>=': 2, - '<=': 2, - '===': 2, - '!==': 2, - '==': 2, - '!=': 2, - '&&': 1, - '||': 1, - '?': 1, - ':': 1, -}; - -// export interface Node { -// left: Node | string | null; -// right: Node | string | null; -// operation: string; -// grouped?: boolean; -// }; - -export default class Parser { - - constructor(token) { - this.index = -1; - this.blockLevel = 0; - this.token = token; - } - - /** - * - * @return {Node | string} =- - */ - parse() { - let tok; - let root = { - left: null, - right: null, - operation: null, - }; - - do { - tok = this.parseStatement(); - - if (tok === null || tok === undefined) { - break; - } - - if (root.left === null) { - root.left = tok; - root.operation = this.nextToken(); - - if (!root.operation) { - return tok; - } - - root.right = this.parseStatement(); - } else { - if (typeof tok !== 'string') { - throw new Error('operation must be string, but get ' + JSON.stringify(tok)); - } - root = this.addNode(tok, this.parseStatement(), root); - } - } while (tok); - - return root; - } - - nextToken() { - this.index += 1; - return this.token[this.index]; - } - - prevToken() { - return this.token[this.index - 1]; - } - - /** - * - * @param {string} operation - * @param {Node|String|null} right - * @param {Node} root - */ - addNode(operation, right, root) { - let pre = root; - - if (this.compare(pre.operation, operation) < 0 && !pre.grouped) { - - while (pre.right !== null && - typeof pre.right !== 'string' && - this.compare(pre.right.operation, operation) < 0 && !pre.right.grouped) { - pre = pre.right; - } - - pre.right = { - operation, - left: pre.right, - right, - }; - return root; - } - return { - left: pre, - right, - operation, - } - } - - /** - * - * @param {String} a - * @param {String} b - */ - compare(a, b) { - if (!OPERATION.hasOwnProperty(a) || !OPERATION.hasOwnProperty(b)) { - throw new Error(`unknow operation ${a} or ${b}`); - } - return OPERATION[a] - OPERATION[b]; - } - - /** - * @return string | Node | null - */ - parseStatement() { - const token = this.nextToken(); - if (token === '(') { - this.blockLevel += 1; - const node = this.parse(); - this.blockLevel -= 1; - - if (typeof node !== 'string') { - node.grouped = true; - } - return node; - } - - if (token === ')') { - return null; - } - - if (token === '!') { - return { left: null, operation: token, right: this.parseStatement() } - } - - // 3 > -12 or -12 + 10 - if (token === '-' && (OPERATION[this.prevToken()] > 0 || this.prevToken() === undefined)) { - return { left: '0', operation: token, right: this.parseStatement(), grouped: true }; - } - - return token; - } -} diff --git a/packages/server/src/lib/LogicEvaluation/QueryParser.js b/packages/server/src/lib/LogicEvaluation/QueryParser.js deleted file mode 100644 index cd31c128d..000000000 --- a/packages/server/src/lib/LogicEvaluation/QueryParser.js +++ /dev/null @@ -1,61 +0,0 @@ -import { OPERATION } from './Parser'; - -export default class QueryParser { - - constructor(tree, queries) { - this.tree = tree; - this.queries = queries; - this.query = null; - } - - setQuery(query) { - this.query = query.clone(); - } - - parse() { - return this.parseNode(this.tree); - } - - parseNode(node) { - if (typeof node === 'string') { - const nodeQuery = this.getQuery(node); - return (query) => { nodeQuery(query); }; - } - if (OPERATION[node.operation] === undefined) { - throw new Error(`unknow expression ${node.operation}`); - } - const leftQuery = this.getQuery(node.left); - const rightQuery = this.getQuery(node.right); - - switch (node.operation) { - case '&&': - case 'AND': - default: - return (nodeQuery) => nodeQuery.where((query) => { - query.where((q) => { leftQuery(q); }); - query.andWhere((q) => { rightQuery(q); }); - }); - case '||': - case 'OR': - return (nodeQuery) => nodeQuery.where((query) => { - query.where((q) => { leftQuery(q); }); - query.orWhere((q) => { rightQuery(q); }); - }); - } - } - - getQuery(node) { - if (typeof node !== 'string' && node !== null) { - return this.parseNode(node); - } - const value = parseFloat(node); - - if (!isNaN(value)) { - if (typeof this.queries[node] === 'undefined') { - throw new Error(`unknow query under index ${node}`); - } - return this.queries[node]; - } - return null; - } -} \ No newline at end of file diff --git a/packages/server/src/lib/Mail/index.ts b/packages/server/src/lib/Mail/index.ts deleted file mode 100644 index e0fbdae31..000000000 --- a/packages/server/src/lib/Mail/index.ts +++ /dev/null @@ -1,131 +0,0 @@ -import * as fs from 'fs'; -import Mustache from 'mustache'; -import path from 'path'; -import { IMailAttachment } from '@/interfaces'; - -export default class Mail { - view: string; - subject: string = ''; - content: string = ''; - to: string | string[]; - cc: string | string[]; - bcc: string | string[]; - replyTo: string | string[]; - from: string = `${process.env.MAIL_FROM_NAME} ${process.env.MAIL_FROM_ADDRESS}`; - data: { [key: string]: string | number }; - attachments: IMailAttachment[]; - - /** - * Mail options. - */ - public get mailOptions() { - return { - to: this.to, - from: this.from, - cc: this.cc, - bcc: this.bcc, - subject: this.subject, - html: this.html, - attachments: this.attachments, - replyTo: this.replyTo, - }; - } - - /** - * Retrieves the html content of the mail. - * @returns {string} - */ - public get html() { - return this.view ? Mail.render(this.view, this.data) : this.content; - } - - /** - * Set send mail to address. - * @param {string} to - - */ - setTo(to: string | string[]) { - this.to = to; - return this; - } - - setCC(cc: string | string[]) { - this.cc = cc; - return this; - } - - setBCC(bcc: string | string[]) { - this.bcc = bcc; - return this; - } - - setReplyTo(replyTo: string | string[]) { - this.replyTo = replyTo; - return this; - } - - /** - * Sets from address to the mail. - * @param {string} from - * @return {} - */ - setFrom(from: string) { - this.from = from; - return this; - } - - /** - * Set attachments to the mail. - * @param {IMailAttachment[]} attachments - * @returns {Mail} - */ - setAttachments(attachments: IMailAttachment[]) { - this.attachments = attachments; - return this; - } - - /** - * Set mail subject. - * @param {string} subject - */ - setSubject(subject: string) { - this.subject = subject; - return this; - } - - /** - * Set view directory. - * @param {string} view - */ - setView(view: string) { - this.view = view; - return this; - } - - setData(data) { - this.data = data; - return this; - } - - setContent(content: string) { - this.content = content; - return this; - } - - /** - * Renders the view template with the given data. - * @param {object} data - * @return {string} - */ - static render(view: string, data: Record): string { - const viewContent = Mail.getViewContent(view); - return Mustache.render(viewContent, data); - } - - /** - * Retrieve view content from the view directory. - */ - static getViewContent(view: string): string { - const filePath = path.join(global.__views_dir, `/${view}`); - return fs.readFileSync(filePath, 'utf8'); - } -} diff --git a/packages/server/src/lib/Metable/MetableConfig.ts b/packages/server/src/lib/Metable/MetableConfig.ts deleted file mode 100644 index 21febaffd..000000000 --- a/packages/server/src/lib/Metable/MetableConfig.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { get } from 'lodash'; - -export default class MetableConfig { - readonly config: any; - - constructor(config) { - this.setConfig(config); - } - - /** - * Sets config. - */ - setConfig(config) { - this.config = config; - } - - /** - * - * @param {string} key - * @param {string} group - * @param {string} accessor - * @returns {object|string} - */ - getMetaConfig(key: string, group?: string, accessor?: string) { - const configGroup = get(this.config, group); - const config = get(configGroup, key); - - return accessor ? get(config, accessor) : config; - } - - /** - * - * @param {string} key - * @param {string} group - * @returns {string} - */ - getMetaType(key: string, group?: string) { - return this.getMetaConfig(key, group, 'type'); - } -} \ No newline at end of file diff --git a/packages/server/src/lib/Metable/MetableModel.js b/packages/server/src/lib/Metable/MetableModel.js deleted file mode 100644 index f1e489a1a..000000000 --- a/packages/server/src/lib/Metable/MetableModel.js +++ /dev/null @@ -1,12 +0,0 @@ - - -export default class Metable{ - - static get modifiers() { - return { - whereKey(builder, key) { - builder.where('key', key); - }, - }; - } -} \ No newline at end of file diff --git a/packages/server/src/lib/Metable/MetableStore.ts b/packages/server/src/lib/Metable/MetableStore.ts deleted file mode 100644 index 0dd7861d0..000000000 --- a/packages/server/src/lib/Metable/MetableStore.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { Model } from 'objection'; -import { omit, isEmpty } from 'lodash'; -import { IMetadata, IMetaQuery, IMetableStore } from '@/interfaces'; -import { itemsStartWith } from 'utils'; - -export default class MetableStore implements IMetableStore { - metadata: IMetadata[]; - model: Model; - extraColumns: string[]; - - /** - * Constructor method. - */ - constructor() { - this.metadata = []; - this.model = null; - this.extraColumns = []; - } - - /** - * Sets a extra columns. - * @param {Array} columns - - */ - setExtraColumns(columns: string[]): void { - this.extraColumns = columns; - } - - /** - * Find the given metadata key. - * @param {string|IMetaQuery} query - - * @returns {IMetadata} - Metadata object. - */ - find(query: string | IMetaQuery): IMetadata { - const { key, value, ...extraColumns } = this.parseQuery(query); - - return this.metadata.find((meta: IMetadata) => { - const isSameKey = meta.key === key; - const sameExtraColumns = this.extraColumns.some( - (extraColumn: string) => extraColumns[extraColumn] === meta[extraColumn] - ); - - const isSameExtraColumns = sameExtraColumns || isEmpty(extraColumns); - - return isSameKey && isSameExtraColumns; - }); - } - - /** - * Retrieve all metadata. - * @returns {IMetadata[]} - */ - all(): IMetadata[] { - return this.metadata - .filter((meta: IMetadata) => !meta._markAsDeleted) - .map((meta: IMetadata) => - omit(meta, itemsStartWith(Object.keys(meta), '_')) - ); - } - - /** - * Retrieve metadata of the given key. - * @param {String} key - - * @param {Mixied} defaultValue - - */ - get(query: string | IMetaQuery, defaultValue: any): any | null { - const metadata = this.find(query); - return metadata - ? metadata.value - : typeof defaultValue !== 'undefined' - ? defaultValue - : null; - } - - /** - * Markes the metadata to should be deleted. - * @param {String} key - - */ - remove(query: string | IMetaQuery): void { - const metadata: IMetadata = this.find(query); - - if (metadata) { - metadata._markAsDeleted = true; - } - } - - /** - * Remove all meta data of the given group. - * @param {string} group - */ - removeAll(group: string = 'default'): void { - this.metadata = this.metadata.map((meta) => ({ - ...meta, - _markAsDeleted: true, - })); - } - - /** - * Set the meta data to the stack. - * @param {String} key - - * @param {String} value - - */ - set(query: IMetaQuery | IMetadata[] | string, metaValue?: any): void { - if (Array.isArray(query)) { - const metadata = query; - - metadata.forEach((meta: IMetadata) => { - this.set(meta); - }); - return; - } - const { key, value, ...extraColumns } = this.parseQuery(query); - const metadata = this.find(query); - const newValue = metaValue || value; - - if (metadata) { - metadata.value = newValue; - metadata._markAsUpdated = true; - } else { - this.metadata.push({ - value: newValue, - key, - ...extraColumns, - _markAsInserted: true, - }); - } - } - - /** - * Parses query query. - * @param query - * @param value - */ - parseQuery(query: string | IMetaQuery): IMetaQuery { - return typeof query !== 'object' ? { key: query } : { ...query }; - } - - /** - * Format the metadata before saving to the database. - * @param {string|number|boolean} value - - * @param {string} valueType - - * @return {string|number|boolean} - - */ - static formatMetaValue( - value: string | boolean | number, - valueType: string - ): string | number | boolean { - let parsedValue; - - switch (valueType) { - case 'number': - parsedValue = `${value}`; - break; - case 'boolean': - parsedValue = value ? '1' : '0'; - break; - case 'json': - parsedValue = JSON.stringify(parsedValue); - break; - default: - parsedValue = value; - break; - } - return parsedValue; - } - - /** - * Parse the metadata to the collection. - * @param {Array} collection - - */ - mapMetadataToCollection(metadata: IMetadata[], parseType: string = 'parse') { - return metadata.map((model) => - this.mapMetadataToCollection(model, parseType) - ); - } - - /** - * Load metadata to the metable collection. - * @param {Array} meta - - */ - from(meta: []) { - if (Array.isArray(meta)) { - meta.forEach((m) => { - this.from(m); - }); - return; - } - this.metadata.push(meta); - } - - /** - * - * @returns {array} - */ - toArray(): IMetadata[] { - return this.metadata; - } - - /** - * Static method to load metadata to the collection. - * @param {Array} meta - */ - static from(meta) { - const collection = new MetableCollection(); - collection.from(meta); - - return collection; - } - - /** - * Reset the momerized metadata. - */ - resetMetadata() { - this.metadata = []; - } -} diff --git a/packages/server/src/lib/Metable/MetableStoreDB.ts b/packages/server/src/lib/Metable/MetableStoreDB.ts deleted file mode 100644 index 1f5e956de..000000000 --- a/packages/server/src/lib/Metable/MetableStoreDB.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { IMetadata, IMetableStoreStorage } from '@/interfaces'; -import MetableStore from './MetableStore'; -import { isBlank, parseBoolean } from 'utils'; -import MetableConfig from './MetableConfig'; -import config from '@/data/options' -export default class MetableDBStore - extends MetableStore - implements IMetableStoreStorage { - repository: any; - KEY_COLUMN: string; - VALUE_COLUMN: string; - TYPE_COLUMN: string; - extraQuery: Function; - loaded: Boolean; - config: MetableConfig; - - /** - * Constructor method. - */ - constructor() { - super(); - - this.loaded = false; - this.KEY_COLUMN = 'key'; - this.VALUE_COLUMN = 'value'; - this.TYPE_COLUMN = 'type'; - this.repository = null; - - this.extraQuery = (meta) => { - return { - key: meta[this.KEY_COLUMN], - ...this.transfromMetaExtraColumns(meta), - }; - }; - this.config = new MetableConfig(config); - } - - /** - * Transformes meta query. - * @param {IMetadata} meta - */ - private transfromMetaExtraColumns(meta: IMetadata) { - return this.extraColumns.reduce((obj, column) => { - const metaValue = meta[column]; - - if (!isBlank(metaValue)) { - obj[column] = metaValue; - } - return obj; - }, {}); - } - - /** - * Set repository entity of this metadata collection. - * @param {Object} repository - - */ - setRepository(repository) { - this.repository = repository; - } - - /** - * Sets a extra query callback. - * @param callback - */ - setExtraQuery(callback) { - this.extraQuery = callback; - } - - /** - * Saves the modified, deleted and insert metadata. - */ - save() { - this.validateStoreIsLoaded(); - - return Promise.all([ - this.saveUpdated(this.metadata), - this.saveDeleted(this.metadata), - this.saveInserted(this.metadata), - ]); - } - - /** - * Saves the updated metadata. - * @param {IMetadata[]} metadata - - * @returns {Promise} - */ - saveUpdated(metadata: IMetadata[]) { - const updated = metadata.filter((m) => m._markAsUpdated === true); - const opers = []; - - updated.forEach((meta) => { - const updateOper = this.repository - .update( - { [this.VALUE_COLUMN]: meta.value }, - { ...this.extraQuery(meta) } - ) - .then(() => { - meta._markAsUpdated = false; - }); - opers.push(updateOper); - }); - return Promise.all(opers); - } - - /** - * Saves the deleted metadata. - * @param {IMetadata[]} metadata - - * @returns {Promise} - */ - saveDeleted(metadata: IMetadata[]) { - const deleted = metadata.filter( - (m: IMetadata) => m._markAsDeleted === true - ); - const opers: Promise = []; - - if (deleted.length > 0) { - deleted.forEach((meta) => { - const deleteOper = this.repository - .deleteBy({ - ...this.extraQuery(meta), - }) - .then(() => { - meta._markAsDeleted = false; - }); - opers.push(deleteOper); - }); - } - return Promise.all(opers); - } - - /** - * Saves the inserted metadata. - * @param {IMetadata[]} metadata - - * @returns {Promise} - */ - saveInserted(metadata: IMetadata[]) { - const inserted = metadata.filter( - (m: IMetadata) => m._markAsInserted === true - ); - const opers: Promise = []; - - inserted.forEach((meta) => { - const insertData = { - [this.KEY_COLUMN]: meta.key, - [this.VALUE_COLUMN]: meta.value, - ...this.transfromMetaExtraColumns(meta), - }; - const insertOper = this.repository.create(insertData).then(() => { - meta._markAsInserted = false; - }); - opers.push(insertOper); - }); - return Promise.all(opers); - } - - /** - * Loads the metadata from the storage. - * @param {String|Array} key - - * @param {Boolean} force - - */ - async load() { - const metadata = await this.repository.all(); - const mappedMetadata = this.mapMetadataCollection(metadata); - - this.resetMetadata(); - - mappedMetadata.forEach((meta: IMetadata) => { - this.metadata.push(meta); - }); - this.loaded = true; - } - - /** - * Parse the metadata values after fetching it from the storage. - * @param {String|Number|Boolean} value - - * @param {String} valueType - - * @return {String|Number|Boolean} - - */ - static parseMetaValue( - value: string, - valueType: string | false - ): string | boolean | number { - let parsedValue: string | number | boolean; - - switch (valueType) { - case 'number': - parsedValue = parseFloat(value); - break; - case 'boolean': - parsedValue = parseBoolean(value, false); - break; - case 'json': - parsedValue = JSON.stringify(parsedValue); - break; - default: - parsedValue = value; - break; - } - return parsedValue; - } - - /** - * Mapping and parse metadata to collection entries. - * @param {Meta} attr - - * @param {String} parseType - - */ - mapMetadata(metadata: IMetadata) { - const metaType = this.config.getMetaType( - metadata[this.KEY_COLUMN], - metadata['group'], - ); - return { - key: metadata[this.KEY_COLUMN], - value: MetableDBStore.parseMetaValue( - metadata[this.VALUE_COLUMN], - metaType - ), - ...this.extraColumns.reduce((obj, extraCol: string) => { - obj[extraCol] = metadata[extraCol] || null; - return obj; - }, {}), - }; - } - - /** - * Parse the metadata to the collection. - * @param {Array} collection - - */ - mapMetadataCollection(metadata: IMetadata[]) { - return metadata.map((model) => this.mapMetadata(model)); - } - - /** - * Throw error in case the store is not loaded yet. - */ - private validateStoreIsLoaded() { - if (!this.loaded) { - throw new Error( - 'You could not save the store before loaded from the storage.' - ); - } - } -} diff --git a/packages/server/src/lib/MomentFormats/index.ts b/packages/server/src/lib/MomentFormats/index.ts deleted file mode 100644 index 4b3e7103f..000000000 --- a/packages/server/src/lib/MomentFormats/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -import moment from 'moment'; - -moment.prototype.toMySqlDateTime = function () { - return this.format('YYYY-MM-DD HH:mm:ss'); -}; - -// moment.fn.businessDiff = function (param) { -// param = moment(param); -// var signal = param.unix() < this.unix() ? 1 : -1; -// var start = moment.min(param, this).clone(); -// var end = moment.max(param, this).clone(); -// var start_offset = start.day() - 7; -// var end_offset = end.day(); - -// var end_sunday = end.clone().subtract('d', end_offset); -// var start_sunday = start.clone().subtract('d', start_offset); -// var weeks = end_sunday.diff(start_sunday, 'days') / 7; - -// start_offset = Math.abs(start_offset); -// if (start_offset == 7) -// start_offset = 5; -// else if (start_offset == 1) -// start_offset = 0; -// else -// start_offset -= 2; - -// if (end_offset == 6) -// end_offset--; - -// return signal * (weeks * 5 + start_offset + end_offset); -// }; - -// moment.fn.businessAdd = function (days) { -// var signal = days < 0 ? -1 : 1; -// days = Math.abs(days); -// var d = this.clone().add(Math.floor(days / 5) * 7 * signal, 'd'); -// var remaining = days % 5; -// while (remaining) { -// d.add(signal, 'd'); -// if (d.day() !== 0 && d.day() !== 6) -// remaining--; -// } -// return d; -// }; - -// moment.fn.businessSubtract = function (days) { -// return this.businessAdd(-days); -// }; diff --git a/packages/server/src/lib/NestedSet/NestedSetNode.js b/packages/server/src/lib/NestedSet/NestedSetNode.js deleted file mode 100644 index 60655589f..000000000 --- a/packages/server/src/lib/NestedSet/NestedSetNode.js +++ /dev/null @@ -1,9 +0,0 @@ - - -class NestedSetNode { - - // Saves - appendToNode($parent) { - - } -} \ No newline at end of file diff --git a/packages/server/src/lib/Plaid/Plaid.ts b/packages/server/src/lib/Plaid/Plaid.ts deleted file mode 100644 index 05875a27c..000000000 --- a/packages/server/src/lib/Plaid/Plaid.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Configuration, PlaidApi, PlaidEnvironments } from 'plaid'; -import config from '@/config'; - -// Wrapper for the Plaid client. This allows us to easily log data for all Plaid client requests. -export class PlaidClientWrapper { - private static instance: PlaidClientWrapper; - private client: PlaidApi; - - private constructor() { - // Initialize the Plaid client. - const configuration = new Configuration({ - basePath: PlaidEnvironments[config.plaid.env], - baseOptions: { - headers: { - 'PLAID-CLIENT-ID': config.plaid.clientId, - 'PLAID-SECRET': config.plaid.secret, - 'Plaid-Version': '2020-09-14', - }, - }, - }); - this.client = new PlaidApi(configuration); - } - - public static getClient(): PlaidApi { - if (!PlaidClientWrapper.instance) { - PlaidClientWrapper.instance = new PlaidClientWrapper(); - } - return PlaidClientWrapper.instance.client; - } -} diff --git a/packages/server/src/lib/Plaid/PlaidApiEventsDBSync.ts b/packages/server/src/lib/Plaid/PlaidApiEventsDBSync.ts deleted file mode 100644 index 9d257b727..000000000 --- a/packages/server/src/lib/Plaid/PlaidApiEventsDBSync.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Creates a single Plaid api event log entry. - * - * @param {string} itemId the item id in the request. - * @param {string} userId the user id in the request. - * @param {string} plaidMethod the Plaid client method called. - * @param {Array} clientMethodArgs the arguments passed to the Plaid client method. - * @param {Object} response the Plaid api response object. - */ -export const createPlaidApiEvent = async ( - itemId, - userId, - plaidMethod, - clientMethodArgs, - response -) => { - const { - error_code: errorCode, - error_type: errorType, - request_id: requestId, - } = response; - const query = { - text: ` - INSERT INTO plaid_api_events_table - ( - item_id, - user_id, - plaid_method, - arguments, - request_id, - error_type, - error_code - ) - VALUES - ($1, $2, $3, $4, $5, $6, $7); - `, - values: [ - itemId, - userId, - plaidMethod, - JSON.stringify(clientMethodArgs), - requestId, - errorType, - errorCode, - ], - }; - // await db.query(query); -}; diff --git a/packages/server/src/lib/Plaid/index.ts b/packages/server/src/lib/Plaid/index.ts deleted file mode 100644 index 9f3f903ca..000000000 --- a/packages/server/src/lib/Plaid/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Plaid'; diff --git a/packages/server/src/lib/QueryBuilderBulkOperations/QueryBuilder.js b/packages/server/src/lib/QueryBuilderBulkOperations/QueryBuilder.js deleted file mode 100644 index 6aa08ab82..000000000 --- a/packages/server/src/lib/QueryBuilderBulkOperations/QueryBuilder.js +++ /dev/null @@ -1,27 +0,0 @@ -import { QueryBuilder } from "knex" -import { QueryBuilder } from 'objection'; - -export default class BulkOperationsQueryBuilder extends QueryBuilder { - - bulkInsert(collection) { - const opers = []; - - collection.forEach((dataset) => { - const insertOper = this.insert({ ...dataset }); - opers.push(insertOper); - }); - return Promise.all(opers); - } - - bulkDelete(rowsIds) { - - } - - bulkUpdate(dataset, whereColumn) { - - } - - bulkPatch(newDataset, oldDataset) { - - } -} \ No newline at end of file diff --git a/packages/server/src/lib/S3/S3.ts b/packages/server/src/lib/S3/S3.ts deleted file mode 100644 index 96567e238..000000000 --- a/packages/server/src/lib/S3/S3.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { S3Client } from '@aws-sdk/client-s3'; -import config from '@/config'; - -export const s3 = new S3Client({ - region: config.s3.region, - credentials: { - accessKeyId: config.s3.accessKeyId, - secretAccessKey: config.s3.secretAccessKey, - }, - endpoint: config.s3.endpoint, - forcePathStyle: config.s3.forcePathStyle, -}); diff --git a/packages/server/src/lib/Seeder/FsMigrations.ts b/packages/server/src/lib/Seeder/FsMigrations.ts deleted file mode 100644 index 605f6b421..000000000 --- a/packages/server/src/lib/Seeder/FsMigrations.ts +++ /dev/null @@ -1,100 +0,0 @@ -import path from 'path'; -import { sortBy } from 'lodash'; -import fs from 'fs'; -import { promisify } from 'util'; -import { MigrateItem } from './interfaces'; -import { importWebpackSeedModule } from './Utils'; -import { DEFAULT_LOAD_EXTENSIONS } from './constants'; -import { filterMigrations } from './MigrateUtils'; - -const readdir = promisify(fs.readdir); - -class FsMigrations { - private sortDirsSeparately: boolean; - private migrationsPaths: string[]; - private loadExtensions: string[]; - - /** - * Constructor method. - * @param migrationDirectories - * @param sortDirsSeparately - * @param loadExtensions - */ - constructor( - migrationDirectories: string[], - sortDirsSeparately: boolean, - loadExtensions: string[] - ) { - this.sortDirsSeparately = sortDirsSeparately; - - if (!Array.isArray(migrationDirectories)) { - migrationDirectories = [migrationDirectories]; - } - this.migrationsPaths = migrationDirectories; - this.loadExtensions = loadExtensions || DEFAULT_LOAD_EXTENSIONS; - } - - /** - * Gets the migration names - * @returns Promise - */ - public getMigrations(loadExtensions = null): Promise { - // Get a list of files in all specified migration directories - const readMigrationsPromises = this.migrationsPaths.map((configDir) => { - const absoluteDir = path.resolve(process.cwd(), configDir); - return readdir(absoluteDir).then((files) => ({ - files, - configDir, - absoluteDir, - })); - }); - - return Promise.all(readMigrationsPromises).then((allMigrations) => { - const migrations = allMigrations.reduce((acc, migrationDirectory) => { - // When true, files inside the folder should be sorted - if (this.sortDirsSeparately) { - migrationDirectory.files = migrationDirectory.files.sort(); - } - migrationDirectory.files.forEach((file) => - acc.push({ file, directory: migrationDirectory.configDir }) - ); - return acc; - }, []); - - // If true we have already sorted the migrations inside the folders - // return the migrations fully qualified - if (this.sortDirsSeparately) { - return filterMigrations( - this, - migrations, - loadExtensions || this.loadExtensions - ); - } - return filterMigrations( - this, - sortBy(migrations, 'file'), - loadExtensions || this.loadExtensions - ); - }); - } - - /** - * Retrieve the file name from given migrate item. - * @param {MigrateItem} migration - * @returns {string} - */ - public getMigrationName(migration: MigrateItem): string { - return migration.file; - } - - /** - * Retrieve the migrate file content from given migrate item. - * @param {MigrateItem} migration - * @returns {string} - */ - public getMigration(migration: MigrateItem): string { - return importWebpackSeedModule(migration.file); - } -} - -export { DEFAULT_LOAD_EXTENSIONS, FsMigrations }; diff --git a/packages/server/src/lib/Seeder/MigrateUtils.ts b/packages/server/src/lib/Seeder/MigrateUtils.ts deleted file mode 100644 index efed89f28..000000000 --- a/packages/server/src/lib/Seeder/MigrateUtils.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { differenceWith } from 'lodash'; -import path from 'path'; -import { FsMigrations } from './FsMigrations'; -import { - getTable, - getTableName, - getLockTableName, - getLockTableNameWithSchema, -} from './TableUtils'; -import { ISeederConfig, MigrateItem } from './interfaces'; - -/** - * Get schema-aware schema builder for a given schema nam - * @param trxOrKnex - * @param {string} schemaName - * @returns - */ -function getSchemaBuilder(trxOrKnex, schemaName: string | null = null) { - return schemaName - ? trxOrKnex.schema.withSchema(schemaName) - : trxOrKnex.schema; -} - -/** - * Creates migration table of the given table name. - * @param {string} tableName - * @param {string} schemaName - * @param trxOrKnex - * @returns - */ -function createMigrationTable( - tableName: string, - schemaName: string, - trxOrKnex -) { - return getSchemaBuilder(trxOrKnex, schemaName).createTable( - getTableName(tableName), - (t) => { - t.increments(); - t.string('name'); - t.integer('batch'); - t.timestamp('migration_time'); - } - ); -} - -/** - * Creates a migration lock table of the given table name. - * @param {string} tableName - * @param {string} schemaName - * @param trxOrKnex - * @returns - */ -function createMigrationLockTable( - tableName: string, - schemaName: string, - trxOrKnex -) { - return getSchemaBuilder(trxOrKnex, schemaName).createTable(tableName, (t) => { - t.increments('index').primary(); - t.integer('is_locked'); - }); -} - -/** - * - * @param tableName - * @param schemaName - * @param trxOrKnex - * @returns - */ -export function ensureMigrationTables( - tableName: string, - schemaName: string, - trxOrKnex -) { - const lockTable = getLockTableName(tableName); - const lockTableWithSchema = getLockTableNameWithSchema(tableName, schemaName); - - return getSchemaBuilder(trxOrKnex, schemaName) - .hasTable(tableName) - .then((exists) => { - return !exists && createMigrationTable(tableName, schemaName, trxOrKnex); - }) - .then(() => { - return getSchemaBuilder(trxOrKnex, schemaName).hasTable(lockTable); - }) - .then((exists) => { - return ( - !exists && createMigrationLockTable(lockTable, schemaName, trxOrKnex) - ); - }) - .then(() => { - return getTable(trxOrKnex, lockTable, schemaName).select('*'); - }) - .then((data) => { - return ( - !data.length && - trxOrKnex.into(lockTableWithSchema).insert({ is_locked: 0 }) - ); - }); -} - -/** - * Lists all available migration versions, as a sorted array. - * @param migrationSource - * @param loadExtensions - * @returns - */ -function listAll( - migrationSource: FsMigrations, - loadExtensions -): Promise { - return migrationSource.getMigrations(loadExtensions); -} - -/** - * Lists all migrations that have been completed for the current db, as an array. - * @param {string} tableName - * @param {string} schemaName - * @param {} trxOrKnex - * @returns Promise - */ -export async function listCompleted( - tableName: string, - schemaName: string, - trxOrKnex -): Promise { - const completedMigrations = await trxOrKnex - .from(getTableName(tableName, schemaName)) - .orderBy('id') - .select('name'); - - return completedMigrations.map((migration) => { - return migration.name; - }); -} - -/** - * Gets the migration list from the migration directory specified in config, as well as - * the list of completed migrations to check what should be run. - */ -export function listAllAndCompleted(config: ISeederConfig, trxOrKnex) { - return Promise.all([ - listAll(config.migrationSource, config.loadExtensions), - listCompleted(config.tableName, config.schemaName, trxOrKnex), - ]); -} - -/** - * - * @param migrationSource - * @param all - * @param completed - * @returns - */ -export function getNewMigrations( - migrationSource: FsMigrations, - all: MigrateItem[], - completed: string[] -): MigrateItem[] { - return differenceWith(all, completed, (allMigration, completedMigration) => { - return ( - completedMigration === migrationSource.getMigrationName(allMigration) - ); - }); -} - -function startsWithNumber(str) { - return /^\d/.test(str); -} -/** - * - * @param {FsMigrations} migrationSource - - * @param {MigrateItem[]} migrations - - * @param {string[]} loadExtensions - - * @returns - */ -export function filterMigrations( - migrationSource: FsMigrations, - migrations: MigrateItem[], - loadExtensions: string[] -) { - return migrations.filter((migration) => { - const migrationName = migrationSource.getMigrationName(migration); - const extension = path.extname(migrationName); - - return ( - loadExtensions.includes(extension) && startsWithNumber(migrationName) - ); - }); -} diff --git a/packages/server/src/lib/Seeder/SeedMigration.ts b/packages/server/src/lib/Seeder/SeedMigration.ts deleted file mode 100644 index 519445c36..000000000 --- a/packages/server/src/lib/Seeder/SeedMigration.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { Knex } from 'knex'; -import Bluebird from 'bluebird'; -import { getTable, getTableName, getLockTableName } from './TableUtils'; -import getMergedConfig from './SeederConfig'; -import { - listAllAndCompleted, - getNewMigrations, - listCompleted, - ensureMigrationTables, -} from './MigrateUtils'; -import { MigrateItem, SeedMigrationContext, ISeederConfig } from './interfaces'; -import { FsMigrations } from './FsMigrations'; - -export class SeedMigration { - knex: Knex; - config: ISeederConfig; - migrationSource: FsMigrations; - context: SeedMigrationContext; - - /** - * Constructor method. - * @param {Knex} knex - Knex instance. - * @param {SeedMigrationContext} context - - */ - constructor(knex: Knex, context: SeedMigrationContext) { - this.knex = knex; - this.config = getMergedConfig(this.knex.client.config.seeds, undefined); - this.migrationSource = this.config.migrationSource; - this.context = context; - } - - /** - * Latest migration. - * @returns {Promise} - */ - async latest(config = null): Promise { - // Merges the configuration. - this.config = getMergedConfig(config, this.config); - - // Ensure migration tables. - await ensureMigrationTables(this.config.tableName, null, this.knex); - - // Retrieve all and completed migrations. - const [all, completed] = await listAllAndCompleted(this.config, this.knex); - - // Retrieve the new migrations. - const migrations = getNewMigrations(this.migrationSource, all, completed); - - // Run the latest migration on one batch. - return this.knex.transaction((trx: Knex.Transaction) => { - return this.runBatch(migrations, 'up', trx); - }); - } - - /** - * Add migration lock flag. - * @param {Knex.Transaction} trx - * @returns - */ - private migrateLockTable(trx: Knex.Transaction) { - const tableName = getLockTableName(this.config.tableName); - return getTable(this.knex, tableName, this.config.schemaName) - .transacting(trx) - .where('is_locked', '=', 0) - .update({ is_locked: 1 }) - .then((rowCount) => { - if (rowCount != 1) { - throw new Error('Migration table is already locked'); - } - }); - } - - /** - * Add migration lock flag. - * @param {Knex.Transaction} trx - * @returns - */ - private migrationLock(trx: Knex.Transaction) { - return this.migrateLockTable(trx); - } - - /** - * Free the migration lock flag. - * @param {Knex.Transaction} trx - * @returns - */ - private freeLock(trx = this.knex): Promise { - const tableName = getLockTableName(this.config.tableName); - - return getTable(trx, tableName, this.config.schemaName).update({ - is_locked: 0, - }); - } - - /** - * Returns the latest batch number. - * @param trx - * @returns - */ - private latestBatchNumber(trx = this.knex): number { - return trx - .from(getTableName(this.config.tableName, this.config.schemaName)) - .max('batch as max_batch') - .then((obj) => obj[0].max_batch || 0); - } - - /** - * Runs a batch of `migrations` in a specified `direction`, saving the - * appropriate database information as the migrations are run. - * @param {number} batchNo - * @param {MigrateItem[]} migrations - * @param {string} direction - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - private waterfallBatch( - batchNo: number, - migrations: MigrateItem[], - direction: string, - trx: Knex.Transaction - ): Promise { - const { tableName } = this.config; - - return Bluebird.each(migrations, (migration) => { - const name = this.migrationSource.getMigrationName(migration); - - return this.migrationSource - .getMigration(migration) - .then((migrationContent) => - this.runMigrationContent(migrationContent.default, direction, trx) - ) - .then(() => { - if (direction === 'up') { - return trx.into(getTableName(tableName)).insert({ - name, - batch: batchNo, - migration_time: new Date(), - }); - } - if (direction === 'down') { - return trx.from(getTableName(tableName)).where({ name }).del(); - } - }); - }); - } - - /** - * Runs and builds the given migration class. - */ - private runMigrationContent(Migration, direction, trx) { - const instance = new Migration(trx); - - if (this.context.i18n) { - instance.setI18n(this.context.i18n); - } - instance.setTenant(this.context.tenant); - - return instance[direction](trx); - } - - /** - * Validates some migrations by requiring and checking for an `up` and `down`function. - * @param {MigrateItem} migration - * @returns {MigrateItem} - */ - async validateMigrationStructure(migration: MigrateItem): MigrateItem { - const migrationName = this.migrationSource.getMigrationName(migration); - - // maybe promise - const migrationContent = await this.migrationSource.getMigration(migration); - if ( - typeof migrationContent.up !== 'function' || - typeof migrationContent.down !== 'function' - ) { - throw new Error( - `Invalid migration: ${migrationName} must have both an up and down function` - ); - } - return migration; - } - - /** - * Run a batch of current migrations, in sequence. - * @param {MigrateItem[]} migrations - * @param {string} direction - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - private async runBatch( - migrations: MigrateItem[], - direction: string, - trx: Knex.Transaction - ): Promise { - // Adds flag to migration lock. - await this.migrationLock(trx); - - // When there is a wrapping transaction, some migrations - // could have been done while waiting for the lock: - const completed = await listCompleted( - this.config.tableName, - this.config.schemaName, - trx - ); - // Differentiate between all and completed to get new migrations. - const newMigrations = getNewMigrations( - this.config.migrationSource, - migrations, - completed - ); - // Retrieve the latest batch number. - const batchNo = await this.latestBatchNumber(trx); - - // Increment the next batch number. - const newBatchNo = direction === 'up' ? batchNo + 1 : batchNo; - - // Run all migration files in waterfall. - await this.waterfallBatch(newBatchNo, newMigrations, direction, trx); - - // Free the migration lock flag. - await this.freeLock(trx); - } -} diff --git a/packages/server/src/lib/Seeder/Seeder.ts b/packages/server/src/lib/Seeder/Seeder.ts deleted file mode 100644 index 8ad674048..000000000 --- a/packages/server/src/lib/Seeder/Seeder.ts +++ /dev/null @@ -1,11 +0,0 @@ - -export class Seeder { - knex: any; - - constructor(knex) { - this.knex = knex; - } - up(knex) {} - down(knex) {} -} - diff --git a/packages/server/src/lib/Seeder/SeederConfig.ts b/packages/server/src/lib/Seeder/SeederConfig.ts deleted file mode 100644 index 77ea2e57d..000000000 --- a/packages/server/src/lib/Seeder/SeederConfig.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { DEFAULT_LOAD_EXTENSIONS, FsMigrations } from './FsMigrations'; - -const CONFIG_DEFAULT = Object.freeze({ - extension: 'js', - loadExtensions: DEFAULT_LOAD_EXTENSIONS, - tableName: 'knex_migrations', - schemaName: null, - directory: './migrations', - disableTransactions: false, - disableMigrationsListValidation: false, - sortDirsSeparately: false, -}); - -export default function getMergedConfig(config, currentConfig) { - // config is the user specified config, mergedConfig has defaults and current config - // applied to it. - const mergedConfig = { - ...CONFIG_DEFAULT, - ...(currentConfig || {}), - ...config, - }; - - if ( - config && - // If user specifies any FS related config, - // clear specified migrationSource to avoid ambiguity - (config.directory || - config.sortDirsSeparately !== undefined || - config.loadExtensions) - ) { - mergedConfig.migrationSource = null; - } - - // If the user has not specified any configs, we need to - // default to fs migrations to maintain compatibility - if (!mergedConfig.migrationSource) { - mergedConfig.migrationSource = new FsMigrations( - mergedConfig.directory, - mergedConfig.sortDirsSeparately, - mergedConfig.loadExtensions - ); - } - return mergedConfig; -} diff --git a/packages/server/src/lib/Seeder/TableUtils.ts b/packages/server/src/lib/Seeder/TableUtils.ts deleted file mode 100644 index 587112887..000000000 --- a/packages/server/src/lib/Seeder/TableUtils.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Get schema-aware query builder for a given table and schema name. - * @param {Knex} trxOrKnex - - * @param {string} tableName - - * @param {string} schemaName - - * @returns {string} - */ -export function getTable(trx, tableName: string, schemaName = null) { - return schemaName ? trx(tableName).withSchema(schemaName) : trx(tableName); -} - -/** - * Get schema-aware table name. - * @param {string} tableName - - * @returns {string} - */ -export function getTableName(tableName: string, schemaName = null): string { - return schemaName ? `${schemaName}.${tableName}` : tableName; -} - -/** - * Retrieve the lock table name from given migration table name. - * @param {string} tableName - * @returns {string} - */ -export function getLockTableName(tableName: string): string { - return `${tableName}_lock`; -} - -/** - * Retireve the lock table name from ginve migration table name with schema. - * @param {string} tableName - * @param {string} schemaName - * @returns {string} - */ -export function getLockTableNameWithSchema( - tableName: string, - schemaName = null -): string { - return schemaName - ? `${schemaName} + ${getLockTableName(tableName)}` - : getLockTableName(tableName); -} diff --git a/packages/server/src/lib/Seeder/TenantSeeder.ts b/packages/server/src/lib/Seeder/TenantSeeder.ts deleted file mode 100644 index 6c54b868e..000000000 --- a/packages/server/src/lib/Seeder/TenantSeeder.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Seeder } from "./Seeder"; - -export class TenantSeeder extends Seeder{ - public knex: any; - public i18n: i18nAPI; - public models: any; - public tenant: any; - - constructor(knex) { - super(knex); - this.knex = knex; - } - - setI18n(i18n) { - this.i18n = i18n; - } - - setModels(models) { - this.models = models; - } - - setTenant(tenant) { - this.tenant = tenant; - } -} diff --git a/packages/server/src/lib/Seeder/Utils.ts b/packages/server/src/lib/Seeder/Utils.ts deleted file mode 100644 index 29a8f0084..000000000 --- a/packages/server/src/lib/Seeder/Utils.ts +++ /dev/null @@ -1,42 +0,0 @@ -import fs from 'fs'; - -const { promisify } = require('util'); -const readFile = promisify(fs.readFile); - -/** - * Detarmines the module type of the given file path. - * @param {string} filepath - * @returns {boolean} - */ -async function isModuleType(filepath: string): boolean { - if (process.env.npm_package_json) { - // npm >= 7.0.0 - const packageJson = JSON.parse( - await readFile(process.env.npm_package_json, 'utf-8') - ); - if (packageJson.type === 'module') { - return true; - } - } - return process.env.npm_package_type === 'module' || filepath.endsWith('.mjs'); -} - -/** - * Imports content of the given file path. - * @param {string} filepath - * @returns - */ -export async function importFile(filepath: string): any { - return (await isModuleType(filepath)) - ? import(require('url').pathToFileURL(filepath)) - : require(filepath); -} - -/** - * - * @param {string} moduleName - * @returns - */ -export async function importWebpackSeedModule(moduleName: string): any { - return import(`@/database/seeds/core/${moduleName}`); -} diff --git a/packages/server/src/lib/Seeder/constants.ts b/packages/server/src/lib/Seeder/constants.ts deleted file mode 100644 index 86fa35eec..000000000 --- a/packages/server/src/lib/Seeder/constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Default load extensions. -export const DEFAULT_LOAD_EXTENSIONS = [ - '.co', - '.coffee', - '.eg', - '.iced', - '.js', - '.cjs', - '.litcoffee', - '.ls', - '.ts', -]; diff --git a/packages/server/src/lib/Seeder/interfaces.ts b/packages/server/src/lib/Seeder/interfaces.ts deleted file mode 100644 index a2214e678..000000000 --- a/packages/server/src/lib/Seeder/interfaces.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ITenant } from "interfaces"; - -export interface FsMigrations {} - -export interface ISeederConfig { - tableName: string; - migrationSource: FsMigrations; - schemaName?: string; - loadExtensions: string[]; -} - -export interface MigrateItem { - file: string; - directory: string; -} - -export interface SeedMigrationContext { - i18n: i18nAPI; - tenant: ITenant; -} \ No newline at end of file diff --git a/packages/server/src/lib/Transformer/Transformer.ts b/packages/server/src/lib/Transformer/Transformer.ts deleted file mode 100644 index 0514cd657..000000000 --- a/packages/server/src/lib/Transformer/Transformer.ts +++ /dev/null @@ -1,243 +0,0 @@ -import moment from 'moment'; -import * as R from 'ramda'; -import { includes, isFunction, isObject, isUndefined, omit } from 'lodash'; -import { formatNumber, sortObjectKeysAlphabetically } from 'utils'; -import { EXPORT_DTE_FORMAT } from '@/services/Export/constants'; - -export class Transformer { - public context: any; - public options: Record; - - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return []; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return []; - }; - - /** - * Detarmines whether to exclude all attributes except the include attributes. - * @returns {boolean} - */ - public isExcludeAllAttributes = () => { - return includes(this.excludeAttributes(), '*'); - }; - - /** - * - * @param object - */ - transform = (object: any) => { - return object; - }; - - /** - * - * @param object - * @returns - */ - protected preCollectionTransform = (object: any) => { - return object; - }; - - /** - * - * @param object - * @returns - */ - protected postCollectionTransform = (object: any) => { - return object; - }; - - /** - * - */ - public work = (object: any) => { - if (Array.isArray(object)) { - const preTransformed = this.preCollectionTransform(object); - const transformed = preTransformed.map(this.getTransformation); - - return this.postCollectionTransform(transformed); - } else if (isObject(object)) { - return this.getTransformation(object); - } - return object; - }; - - /** - * Transformes the given item to desired output. - * @param item - * @returns - */ - protected getTransformation = (item) => { - const normlizedItem = this.normalizeModelItem(item); - - return R.compose( - sortObjectKeysAlphabetically, - this.transform, - R.when(this.hasExcludeAttributes, this.excludeAttributesTransformed), - this.includeAttributesTransformed - )(normlizedItem); - }; - - /** - * - * @param item - * @returns - */ - protected normalizeModelItem = (item) => { - return !isUndefined(item.toJSON) ? item.toJSON() : item; - }; - - /** - * Exclude attributes from the given item. - */ - protected excludeAttributesTransformed = (item) => { - const exclude = this.excludeAttributes(); - - return omit(item, exclude); - }; - - /** - * Incldues virtual attributes. - */ - protected getIncludeAttributesTransformed = (item) => { - const attributes = this.includeAttributes(); - - return attributes - .filter( - (attribute) => - isFunction(this[attribute]) || !isUndefined(item[attribute]) - ) - .reduce((acc, attribute: string) => { - acc[attribute] = isFunction(this[attribute]) - ? this[attribute](item) - : item[attribute]; - - return acc; - }, {}); - }; - - /** - * - * @param item - * @returns - */ - protected includeAttributesTransformed = (item) => { - const excludeAll = this.isExcludeAllAttributes(); - const virtualAttrs = this.getIncludeAttributesTransformed(item); - - return { - ...(!excludeAll ? item : {}), - ...virtualAttrs, - }; - }; - - /** - * - * @returns - */ - private hasExcludeAttributes = () => { - return this.excludeAttributes().length > 0; - }; - - private dateFormat = 'YYYY MMM DD'; - - setDateFormat(format: string) { - this.dateFormat = format; - } - - /** - * Format date. - * @param {} date - * @param {string} format - - * @returns {} - */ - protected formatDate(date, format?: string) { - // Use the export date format if the async operation is in exporting, - // otherwise use the given or default format. - const _format = this.context.exportAls.isExport - ? EXPORT_DTE_FORMAT - : format || this.dateFormat; - - return date ? moment(date).format(_format) : ''; - } - - /** - * - * @param date - * @returns {} - */ - protected formatDateFromNow(date) { - return date ? moment(date).fromNow(true) : ''; - } - - /** - * - * @param number - * @returns {} - */ - protected formatNumber(number, props?) { - return formatNumber(number, { money: false, ...props }); - } - - /** - * - * @param money - * @param options - * @returns {} - */ - protected formatMoney(money, options?) { - return formatNumber(money, { - currencyCode: this.context.organization.baseCurrency, - ...options, - }); - } - - /** - * - * @param obj - * @param transformer - * @param options - */ - public item( - obj: Record, - transformer: Transformer, - options?: any - ) { - transformer.setOptions(options); - transformer.setContext(this.context); - transformer.setDateFormat(this.dateFormat); - - return transformer.work(obj); - } - - /** - * Sets custom options to the application. - * @param {} options - * @returns {Transformer} - */ - public setOptions(options) { - this.options = options; - return this; - } - - /** - * Sets the application context to the application. - * @param {} context - * @returns {Transformer} - */ - public setContext(context) { - this.context = context; - return this; - } -} diff --git a/packages/server/src/lib/Transformer/TransformerInjectable.ts b/packages/server/src/lib/Transformer/TransformerInjectable.ts deleted file mode 100644 index 5f1643312..000000000 --- a/packages/server/src/lib/Transformer/TransformerInjectable.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { isNull } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TenantMetadata } from '@/system/models'; -import { Transformer } from './Transformer'; -import { ImportAls } from '@/services/Import/ImportALS'; -import { ExportAls } from '@/services/Export/ExportAls'; - -@Service() -export class TransformerInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private exportAls: ExportAls; - - /** - * Retrieves the application context of all tenant transformers. - * @param {number} tenantId - * @returns {} - */ - async getApplicationContext(tenantId: number) { - const i18n = this.tenancy.i18n(tenantId); - const organization = await TenantMetadata.query().findOne({ tenantId }); - const exportAls = this.exportAls; - - return { - organization, - i18n, - exportAls, - }; - } - - /** - * Retrieves the given tenatn date format. - * @param {number} tenantId - * @returns {string} - */ - async getTenantDateFormat(tenantId: number) { - const metadata = await TenantMetadata.query().findOne('tenantId', tenantId); - - return metadata.dateFormat; - } - - /** - * Transformes the given transformer after inject the tenant context. - * @param {number} tenantId - * @param {Record | Record[]} object - * @param {Transformer} transformer - * @param {Record} options - * @returns {Record} - */ - async transform( - tenantId: number, - object: Record | Record[], - transformer: Transformer, - options?: Record - ) { - if (!isNull(tenantId)) { - const context = await this.getApplicationContext(tenantId); - transformer.setContext(context); - - const dateFormat = await this.getTenantDateFormat(tenantId); - transformer.setDateFormat(dateFormat); - } - - transformer.setOptions(options); - - return transformer.work(object); - } -} diff --git a/packages/server/src/lib/ViewRolesBuilder/FilterRolesDynamicFilter.js b/packages/server/src/lib/ViewRolesBuilder/FilterRolesDynamicFilter.js deleted file mode 100644 index c07af232b..000000000 --- a/packages/server/src/lib/ViewRolesBuilder/FilterRolesDynamicFilter.js +++ /dev/null @@ -1,44 +0,0 @@ -import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor'; -import { - validateViewRoles, - buildFilterQuery, -} from '@/lib/ViewRolesBuilder'; - -export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstractor { - /** - * Constructor method. - * @param {*} filterRoles - - * @param {*} logicExpression - - */ - constructor(filterRoles, logicExpression) { - super(); - - this.filterRoles = filterRoles; - this.logicExpression = logicExpression; - - this.tableName = ''; - } - - /** - * Retrieve logic expression. - */ - buildLogicExpression() { - return this.logicExpression; - } - - /** - * Validates filter roles. - */ - validateFilterRoles() { - return validateViewRoles(this.filterRoles, this.logicExpression); - } - - /** - * Builds database query of view roles. - */ - buildQuery() { - return (builder) => { - buildFilterQuery(this.tableName, this.filterRoles, this.logicExpression)(builder); - }; - } -} diff --git a/packages/server/src/lib/ViewRolesBuilder/index.ts b/packages/server/src/lib/ViewRolesBuilder/index.ts deleted file mode 100644 index 681bd60d7..000000000 --- a/packages/server/src/lib/ViewRolesBuilder/index.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { difference } from 'lodash'; - -import { IFilterRole, IModel } from '@/interfaces'; - -/** - * Get field column metadata and its relation with other tables. - * @param {String} tableName - Table name of target column. - * @param {String} fieldKey - Target column key that stored in resource field. - */ -export function getRoleFieldColumn(model: IModel, fieldKey: string) { - const tableFields = model.fields; - return tableFields[fieldKey] ? tableFields[fieldKey] : null; -} - -export function buildSortColumnJoin(model: IModel, sortColumnKey: string) { - return (builder) => { - const fieldColumn = getRoleFieldColumn(model, sortColumnKey); - - if (fieldColumn.relation) { - const joinTable = getTableFromRelationColumn(fieldColumn.relation); - builder.join( - joinTable, - `${model.tableName}.${fieldColumn.column}`, - '=', - fieldColumn.relation - ); - } - }; -} - -/** - * Mapes the view roles to view conditionals. - * @param {Array} viewRoles - - * @return {Array} - */ -export function mapViewRolesToConditionals(viewRoles) { - return viewRoles.map((viewRole) => ({ - comparator: viewRole.comparator, - value: viewRole.value, - index: viewRole.index, - - columnKey: viewRole.field.key, - slug: viewRole.field.slug, - })); -} - -export function mapFilterRolesToDynamicFilter(roles) { - return roles.map((role) => ({ - ...role, - columnKey: role.fieldKey, - })); -} - -/** - * Builds sort column query. - * @param {String} tableName - - * @param {String} columnKey - - * @param {String} sortDirection - - */ -export function buildSortColumnQuery( - model: IModel, - columnKey: string, - sortDirection: string -) { - const fieldRelation = getRoleFieldColumn(model, columnKey); - const sortColumn = - fieldRelation.relation || `${model.tableName}.${fieldRelation.column}`; - - return (builder) => { - builder.orderBy(sortColumn, sortDirection); - buildSortColumnJoin(model, columnKey)(builder); - }; -} - -export function validateFilterLogicExpression( - logicExpression: string, - indexes -) { - const logicExpIndexes = logicExpression.match(/\d+/g) || []; - const diff = difference(logicExpIndexes.map(Number), indexes); - - return diff.length > 0 ? false : true; -} - -export function validateRolesLogicExpression( - logicExpression: string, - roles: IFilterRole[] -) { - return validateFilterLogicExpression( - logicExpression, - roles.map((r) => r.index) - ); -} - -export function validateFieldKeyExistance(model: any, fieldKey: string) { - return model?.fields?.[fieldKey] || false; -} - - -/** - * Retrieve model fields keys. - * @param {IModel} Model - * @return {string[]} - */ -export function getModelFieldsKeys(Model: IModel) { - const fields = Object.keys(Model.fields); - - return fields.sort((a, b) => { - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - return 0; - }); -} - -export function getModelFields(Model: IModel) { - const fieldsKey = this.getModelFieldsKeys(Model); - - return fieldsKey.map((fieldKey) => { - const field = Model.fields[fieldKey]; - return { - ...field, - key: fieldKey, - }; - }); -} diff --git a/packages/server/src/lib/Xlsx/TableSheet.ts b/packages/server/src/lib/Xlsx/TableSheet.ts deleted file mode 100644 index 5bffd1bcf..000000000 --- a/packages/server/src/lib/Xlsx/TableSheet.ts +++ /dev/null @@ -1,134 +0,0 @@ -import xlsx, { WorkBook } from 'xlsx'; -import { IFinancialTable, ITableData } from '@/interfaces'; -import { FinancialTableStructure } from '@/services/FinancialStatements/FinancialTableStructure'; - -interface ITableSheet { - convertToXLSX(): WorkBook; - convertToCSV(): string; - convertToBuffer(workbook: WorkBook, fileType: string): Buffer; -} - -export class TableSheet implements ITableSheet { - private table: ITableData; - - constructor(table: ITableData) { - this.table = table; - } - - /** - * Retrieves the columns labels. - * @returns {string[]} - */ - private get columns() { - return this.table.columns.map((col) => col.label); - } - - /** - * Retrieves the columns accessors. - * @returns {string[]} - */ - private get columnsAccessors() { - return this.table.columns.map((col, index) => { - return `${index}`; - }); - } - - /** - * Retrieves the rows data cellIndex/Value. - * @returns {Record} - */ - private get rows() { - const computedRows = FinancialTableStructure.flatNestedTree( - this.table.rows - ); - return computedRows.map((row) => { - const entries = row.cells.map((cell, index) => { - return [`${index}`, cell.value]; - }); - return Object.fromEntries(entries); - }); - } - - /** - * Converts the table to a CSV string. - * @returns {string} - */ - public convertToCSV(): string { - // Define custom headers - const headers = this.columns; - - // Convert data to worksheet with headers - const worksheet = xlsx.utils.json_to_sheet(this.rows, { - header: this.columnsAccessors, - }); - // Add custom headers to the worksheet - xlsx.utils.sheet_add_aoa(worksheet, [headers], { origin: 'A1' }); - - // Convert worksheet to CSV format - const csvOutput = xlsx.utils.sheet_to_csv(worksheet); - - return csvOutput; - } - - /** - * Convert the array of objects to an XLSX file with styled headers - * @returns {Workbook} - */ - public convertToXLSX(): WorkBook { - // Create a new workbook and a worksheet - const workbook = xlsx.utils.book_new(); - const worksheet = xlsx.utils.json_to_sheet(this.rows, { - header: this.columnsAccessors, - }); - // Add custom headers to the worksheet - xlsx.utils.sheet_add_aoa(worksheet, [this.columns], { - origin: 'A1', - }); - // Adjust column width. - worksheet['!cols'] = this.computeXlsxColumnsWidths(this.rows); - - // Append the worksheet to the workbook - xlsx.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); - - return workbook; - } - - /** - * Converts the given workbook to buffer of the given file type - * @param {WorkBook} workbook - * @param {string} fileType - * @returns {Promise} - */ - public convertToBuffer(workbook: WorkBook, fileType: 'xlsx' | 'csv'): Buffer { - return xlsx.write(workbook, { - type: 'buffer', - bookType: fileType, - cellStyles: true, - }); - } - - /** - * Adjusts and computes the columns width. - * @param {} rows - * @returns {{wch: number}[]} - */ - private computeXlsxColumnsWidths = (rows): { wch: number }[] => { - const cols = [{ wch: 60 }]; - - this.columns.map((column) => { - cols.push({ wch: column.length }); - }); - rows.forEach((row) => { - const entries = Object.entries(row); - - entries.forEach(([key, value]) => { - if (cols[key]) { - cols[key].wch = Math.max(cols[key].wch, String(value).length); - } else { - cols[key] = { wch: String(value).length }; - } - }); - }); - return cols; - }; -} diff --git a/packages/server-nest/src/libs/accounts-utils/AccountTypesUtils.ts b/packages/server/src/libs/accounts-utils/AccountTypesUtils.ts similarity index 100% rename from packages/server-nest/src/libs/accounts-utils/AccountTypesUtils.ts rename to packages/server/src/libs/accounts-utils/AccountTypesUtils.ts diff --git a/packages/server-nest/src/libs/chromiumly/Chromiumly.ts b/packages/server/src/libs/chromiumly/Chromiumly.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/Chromiumly.ts rename to packages/server/src/libs/chromiumly/Chromiumly.ts diff --git a/packages/server-nest/src/libs/chromiumly/ConvertUtils.ts b/packages/server/src/libs/chromiumly/ConvertUtils.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/ConvertUtils.ts rename to packages/server/src/libs/chromiumly/ConvertUtils.ts diff --git a/packages/server-nest/src/libs/chromiumly/Converter.ts b/packages/server/src/libs/chromiumly/Converter.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/Converter.ts rename to packages/server/src/libs/chromiumly/Converter.ts diff --git a/packages/server-nest/src/libs/chromiumly/GotenbergUtils.ts b/packages/server/src/libs/chromiumly/GotenbergUtils.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/GotenbergUtils.ts rename to packages/server/src/libs/chromiumly/GotenbergUtils.ts diff --git a/packages/server-nest/src/libs/chromiumly/HTMLConvert.ts b/packages/server/src/libs/chromiumly/HTMLConvert.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/HTMLConvert.ts rename to packages/server/src/libs/chromiumly/HTMLConvert.ts diff --git a/packages/server-nest/src/libs/chromiumly/UrlConvert.ts b/packages/server/src/libs/chromiumly/UrlConvert.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/UrlConvert.ts rename to packages/server/src/libs/chromiumly/UrlConvert.ts diff --git a/packages/server-nest/src/libs/chromiumly/_types.ts b/packages/server/src/libs/chromiumly/_types.ts similarity index 100% rename from packages/server-nest/src/libs/chromiumly/_types.ts rename to packages/server/src/libs/chromiumly/_types.ts diff --git a/packages/server-nest/src/libs/dependency-graph/index.ts b/packages/server/src/libs/dependency-graph/index.ts similarity index 100% rename from packages/server-nest/src/libs/dependency-graph/index.ts rename to packages/server/src/libs/dependency-graph/index.ts diff --git a/packages/server-nest/src/libs/logic-evaluation/Lexer.ts b/packages/server/src/libs/logic-evaluation/Lexer.ts similarity index 100% rename from packages/server-nest/src/libs/logic-evaluation/Lexer.ts rename to packages/server/src/libs/logic-evaluation/Lexer.ts diff --git a/packages/server-nest/src/libs/logic-evaluation/Parser.ts b/packages/server/src/libs/logic-evaluation/Parser.ts similarity index 100% rename from packages/server-nest/src/libs/logic-evaluation/Parser.ts rename to packages/server/src/libs/logic-evaluation/Parser.ts diff --git a/packages/server-nest/src/libs/logic-evaluation/QueryParser.ts b/packages/server/src/libs/logic-evaluation/QueryParser.ts similarity index 100% rename from packages/server-nest/src/libs/logic-evaluation/QueryParser.ts rename to packages/server/src/libs/logic-evaluation/QueryParser.ts diff --git a/packages/server-nest/src/libs/migration-seed/FsMigrations.ts b/packages/server/src/libs/migration-seed/FsMigrations.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/FsMigrations.ts rename to packages/server/src/libs/migration-seed/FsMigrations.ts diff --git a/packages/server-nest/src/libs/migration-seed/MigrateUtils.ts b/packages/server/src/libs/migration-seed/MigrateUtils.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/MigrateUtils.ts rename to packages/server/src/libs/migration-seed/MigrateUtils.ts diff --git a/packages/server-nest/src/libs/migration-seed/SeedMigration.ts b/packages/server/src/libs/migration-seed/SeedMigration.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/SeedMigration.ts rename to packages/server/src/libs/migration-seed/SeedMigration.ts diff --git a/packages/server-nest/src/libs/migration-seed/Seeder.ts b/packages/server/src/libs/migration-seed/Seeder.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/Seeder.ts rename to packages/server/src/libs/migration-seed/Seeder.ts diff --git a/packages/server-nest/src/libs/migration-seed/SeederConfig.ts b/packages/server/src/libs/migration-seed/SeederConfig.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/SeederConfig.ts rename to packages/server/src/libs/migration-seed/SeederConfig.ts diff --git a/packages/server-nest/src/libs/migration-seed/TableUtils.ts b/packages/server/src/libs/migration-seed/TableUtils.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/TableUtils.ts rename to packages/server/src/libs/migration-seed/TableUtils.ts diff --git a/packages/server-nest/src/libs/migration-seed/TenantSeeder.ts b/packages/server/src/libs/migration-seed/TenantSeeder.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/TenantSeeder.ts rename to packages/server/src/libs/migration-seed/TenantSeeder.ts diff --git a/packages/server-nest/src/libs/migration-seed/Utils.ts b/packages/server/src/libs/migration-seed/Utils.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/Utils.ts rename to packages/server/src/libs/migration-seed/Utils.ts diff --git a/packages/server-nest/src/libs/migration-seed/constants.ts b/packages/server/src/libs/migration-seed/constants.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/constants.ts rename to packages/server/src/libs/migration-seed/constants.ts diff --git a/packages/server-nest/src/libs/migration-seed/interfaces.ts b/packages/server/src/libs/migration-seed/interfaces.ts similarity index 100% rename from packages/server-nest/src/libs/migration-seed/interfaces.ts rename to packages/server/src/libs/migration-seed/interfaces.ts diff --git a/packages/server/src/loaders/agenda.ts b/packages/server/src/loaders/agenda.ts deleted file mode 100644 index e370a1436..000000000 --- a/packages/server/src/loaders/agenda.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Agenda from 'agenda'; -import config from '@/config'; - -export default ({ mongoConnection }) => { - return new Agenda({ - mongo: mongoConnection, - db: { collection: config.agenda.dbCollection }, - processEvery: config.agenda.pooltime, - maxConcurrency: config.agenda.concurrency, - }); -}; diff --git a/packages/server/src/loaders/database.ts b/packages/server/src/loaders/database.ts deleted file mode 100644 index 8299573f8..000000000 --- a/packages/server/src/loaders/database.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Knex from 'knex'; -import { knexSnakeCaseMappers } from 'objection'; -import { systemKnexConfig } from '@/config/knexConfig'; - -export default () => { - return Knex({ - ...systemKnexConfig, - ...knexSnakeCaseMappers({ upperCase: true }), - }); -}; \ No newline at end of file diff --git a/packages/server/src/loaders/dependencyInjector.ts b/packages/server/src/loaders/dependencyInjector.ts deleted file mode 100644 index 7befb88c5..000000000 --- a/packages/server/src/loaders/dependencyInjector.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Container } from 'typedi'; -import LoggerInstance from '@/loaders/logger'; -import agendaFactory from '@/loaders/agenda'; -import SmsClientLoader from '@/loaders/smsClient'; -import mailInstance from '@/loaders/mail'; -import i18n from '@/loaders/i18n'; -import repositoriesLoader from '@/loaders/systemRepositories'; -import Cache from '@/services/Cache'; -import config from '@/config' -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import rateLimiterLoaders from './rateLimiterLoader'; -import eventEmitter, { susbcribers } from './eventEmitter'; - -export default ({ mongoConnection, knex }) => { - try { - const agendaInstance = agendaFactory({ mongoConnection }); - const smsClientInstance = SmsClientLoader(config.easySMSGateway.api_key); - const cacheInstance = new Cache(); - - Container.set('logger', LoggerInstance); - Container.set('knex', knex); - Container.set('SMSClient', smsClientInstance); - Container.set('mail', mailInstance); - - LoggerInstance.info( - '[DI] Database manager has been injected into container.' - ); - - Container.set('agenda', agendaInstance); - LoggerInstance.info('[DI] Agenda has been injected into container'); - - Container.set('i18n', i18n()); - LoggerInstance.info('[DI] i18n has been injected into container'); - - Container.set('cache', cacheInstance); - LoggerInstance.info('[DI] cache has been injected into container'); - - Container.set('repositories', repositoriesLoader()); - LoggerInstance.info('[DI] repositories has been injected into container'); - - rateLimiterLoaders(); - LoggerInstance.info('[DI] rate limiter has been injected into container.'); - - Container.set(EventPublisher, eventEmitter()); - - const emitter = Container.get(EventPublisher); - - emitter.loadSubscribers(susbcribers()); - - - return { agenda: agendaInstance }; - } catch (e) { - LoggerInstance.error('Error on dependency injector loader: %o', e); - throw e; - } -}; diff --git a/packages/server/src/loaders/eventEmitter.ts b/packages/server/src/loaders/eventEmitter.ts deleted file mode 100644 index 97814413f..000000000 --- a/packages/server/src/loaders/eventEmitter.ts +++ /dev/null @@ -1,302 +0,0 @@ -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -import InventoryAdjustmentsSubscriber from '@/subscribers/Inventory/InventoryAdjustment'; -import BillWriteInventoryTransactionsSubscriber from '@/subscribers/Bills/WriteInventoryTransactions'; -import PaymentSyncBillBalance from '@/subscribers/PaymentMades/PaymentSyncBillBalance'; -import SaleReceiptInventoryTransactionsSubscriber from '@/subscribers/SaleReceipt/WriteInventoryTransactions'; -import SaleInvoiceWriteInventoryTransactions from '@/subscribers/SaleInvoices/WriteInventoryTransactions'; -import SaleInvoiceWriteGLEntriesSubscriber from '@/subscribers/SaleInvoices/WriteJournalEntries'; -import SaleReceiptWriteGLEntriesSubscriber from '@/subscribers/SaleReceipt/WriteJournalEntries'; -import PaymentReceiveSyncInvoices from '@/subscribers/PaymentReceive/PaymentReceiveSyncInvoices'; -import CashflowTransactionSubscriber from '@/services/Cashflow/CashflowTransactionSubscriber'; -import PaymentReceivesWriteGLEntriesSubscriber from '@/subscribers/PaymentReceive/WriteGLEntries'; -import InventorySubscriber from '@/subscribers/Inventory/Inventory'; -import { CustomerWriteGLOpeningBalanceSubscriber } from '@/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber'; -import { VendorsWriteGLOpeningSubscriber } from '@/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber'; -import SaleEstimateAutoSerialSubscriber from '@/subscribers/SaleEstimate/AutoIncrementSerial'; -import SaleEstimateSmsNotificationSubscriber from '@/subscribers/SaleEstimate/SmsNotifications'; -import { ExpensesWriteGLSubscriber } from '@/services/Expenses/ExpenseGLEntriesSubscriber'; -import SaleReceiptAutoSerialSubscriber from '@/subscribers/SaleReceipt/AutoIncrementSerial'; -import SaleInvoiceAutoIncrementSubscriber from '@/subscribers/SaleInvoices/AutoIncrementSerial'; -import SaleInvoiceConvertFromEstimateSubscriber from '@/subscribers/SaleInvoices/ConvertFromEstimate'; -import PaymentReceiveAutoSerialSubscriber from '@/subscribers/PaymentReceive/AutoSerialIncrement'; -import SyncSystemSendInvite from '@/services/InviteUsers/SyncSystemSendInvite'; -import InviteSendMainNotification from '@/services/InviteUsers/InviteSendMailNotificationSubscribe'; -import SyncTenantAcceptInvite from '@/services/InviteUsers/SyncTenantAcceptInvite'; -import SyncTenantUserMutate from '@/services/Users/SyncTenantUserSaved'; -import { SyncTenantUserDelete } from '@/services/Users/SyncTenantUserDeleted'; -import OrgSyncTenantAdminUserSubscriber from '@/subscribers/Organization/SyncTenantAdminUser'; -import OrgBuildSmsNotificationSubscriber from '@/subscribers/Organization/BuildSmsNotification'; -import PurgeUserAbilityCache from '@/services/Users/PurgeUserAbilityCache'; -import ResetLoginThrottleSubscriber from '@/subscribers/Authentication/ResetLoginThrottle'; -import AuthenticationSubscriber from '@/subscribers/Authentication/SendResetPasswordMail'; -import PurgeAuthorizedUserOnceRoleMutate from '@/services/Roles/PurgeAuthorizedUser'; -import SendSmsNotificationToCustomer from '@/subscribers/SaleInvoices/SendSmsNotificationToCustomer'; -import SendSmsNotificationSaleReceipt from '@/subscribers/SaleReceipt/SendSmsNotificationToCustomer'; -import SendSmsNotificationPaymentReceive from '@/subscribers/PaymentReceive/SendSmsNotificationToCustomer'; -import SaleInvoiceWriteoffSubscriber from '@/services/Sales/Invoices/SaleInvoiceWriteoffSubscriber'; -import LandedCostSyncCostTransactionsSubscriber from '@/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber'; -import LandedCostInventoryTransactionsSubscriber from '@/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber'; -import CreditNoteGLEntriesSubscriber from '@/services/CreditNotes/CreditNoteGLEntriesSubscriber'; -import VendorCreditGlEntriesSubscriber from '@/services/Purchases/VendorCredits/VendorCreditGLEntriesSubscriber'; -import CreditNoteInventoryTransactionsSubscriber from '@/services/CreditNotes/CreditNoteInventoryTransactionsSubscriber'; -import VendorCreditInventoryTransactionsSubscriber from '@/services/Purchases/VendorCredits/VendorCreditInventoryTransactionsSusbcriber'; -import CreditNoteAutoSerialSubscriber from '@/services/CreditNotes/CreditNoteAutoSerialSubscriber'; -import VendorCreditAutoSerialSubscriber from '@/services/Purchases/VendorCredits/VendorCreditAutoSerialSubscriber'; -import LandedCostGLEntriesSubscriber from '@/services/Purchases/LandedCost/LandedCostGLEntriesSubscriber'; -import RefundCreditNoteGLEntriesSubscriber from '@/services/CreditNotes/RefundCreditNoteGLEntriesSubscriber'; -import RefundVendorCreditGLEntriesSubscriber from '@/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntriesSubscriber'; -import RefundSyncCreditNoteBalanceSubscriber from '@/services/CreditNotes/RefundSyncCreditNoteBalanceSubscriber'; -import RefundSyncVendorCreditBalanceSubscriber from '@/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalanceSubscriber'; -import CreditNoteApplySyncCreditSubscriber from '@/services/CreditNotes/CreditNoteApplySyncCreditSubscriber'; -import CreditNoteApplySyncInvoicesCreditedAmountSubscriber from '@/services/CreditNotes/CreditNoteApplySyncInvoicesSubscriber'; -import ApplyVendorCreditSyncInvoicedSubscriber from '@/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoicedSubscriber'; -import ApplyVendorCreditSyncBillsSubscriber from '@/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBillsSubscriber'; -import DeleteCustomerLinkedCreditSubscriber from '@/services/CreditNotes/DeleteCustomerLinkedCreditSubscriber'; -import DeleteVendorAssociatedVendorCredit from '@/services/Purchases/VendorCredits/DeleteVendorAssociatedVendorCredit'; -import SalesTransactionLockingGuardSubscriber from '@/services/TransactionsLocking/SalesTransactionLockingGuardSubscriber'; -import PurchasesTransactionLockingGuardSubscriber from '@/services/TransactionsLocking/PurchasesTransactionLockingGuardSubscriber'; -import FinancialTransactionLockingGuardSubscriber from '@/services/TransactionsLocking/FinancialsTransactionLockingGuardSubscriber'; -import CashflowWithAccountSubscriber from '@/services/Cashflow/CashflowWithAccountSubscriber'; -import { WarehousesItemsQuantitySyncSubscriber } from '@/services/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber'; -import { WarehouseTransferInventoryTransactionsSubscriber } from '@/services/Warehouses/WarehousesTransfers/WarehouseTransferInventoryTransactionsSubscriber'; -import { AccountsTransactionsWarehousesSubscribe } from '@/services/Accounting/AccountsTransactionsWarehousesSubscribe'; -import { ActivateWarehousesSubscriber } from '@/services/Warehouses/ActivateWarehousesSubscriber'; -import { ManualJournalWriteGLSubscriber } from '@/services/ManualJournals/ManualJournalGLEntriesSubscriber'; -import { BillGLEntriesSubscriber } from '@/services/Purchases/Bills/BillGLEntriesSubscriber'; -import { PaymentWriteGLEntriesSubscriber } from '@/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber'; -import BranchesIntegrationsSubscribers from '@/services/Branches/EventsProvider'; -import WarehousesIntegrationsSubscribers from '@/services/Warehouses/EventsProvider'; -import { WarehouseTransferAutoIncrementSubscriber } from '@/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber'; -import { InvoicePaymentGLRewriteSubscriber } from '@/services/Sales/Invoices/subscribers/InvoicePaymentGLRewriteSubscriber'; -import { BillPaymentsGLEntriesRewriteSubscriber } from '@/services/Purchases/Bills/BillPaymentsGLEntriesRewriteSubscriber'; -import { InvoiceCostGLEntriesSubscriber } from '@/services/Sales/Invoices/subscribers/InvoiceCostGLEntriesSubscriber'; -import { InventoryCostGLBeforeWriteSubscriber } from '@/services/Inventory/subscribers/InventoryCostGLBeforeWriteSubscriber'; -import { SaleReceiptCostGLEntriesSubscriber } from '@/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber'; -import { SeedInitialCurrenciesOnSetupSubsriber } from '@/services/Currencies/subscribers/SeedInitialCurrenciesOnSetupSubscriber'; -import { MutateBaseCurrencyAccountsSubscriber } from '@/services/Accounts/susbcribers/MutateBaseCurrencyAccounts'; -import { ProjectBillableTasksSubscriber } from '@/services/Projects/Projects/ProjectBillableTasksSubscriber'; -import { ProjectBillableExpensesSubscriber } from '@/services/Projects/Projects/ProjectBillableExpenseSubscriber'; -import { ProjectBillableBillSubscriber } from '@/services/Projects/Projects/ProjectBillableBillSubscriber'; -import { SyncActualTimeTaskSubscriber } from '@/services/Projects/Times/SyncActualTimeTaskSubscriber'; -import { SaleInvoiceTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber'; -import { WriteInvoiceTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber'; -import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/BillTaxRateValidateSubscriber'; -import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber'; -import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber'; -import { PlaidUpdateTransactionsOnItemCreatedSubscriber } from '@/services/Banking/Plaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber'; -import { InvoiceChangeStatusOnMailSentSubscriber } from '@/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber'; -import { SaleReceiptMarkClosedOnMailSentSubcriber } from '@/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber'; -import { SaleEstimateMarkApprovedOnMailSent } from '@/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent'; -import { DeleteCashflowTransactionOnUncategorize } from '@/services/Cashflow/subscribers/DeleteCashflowTransactionOnUncategorize'; -import { PreventDeleteTransactionOnDelete } from '@/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete'; -import { SubscribeFreeOnSignupCommunity } from '@/services/Subscription/events/SubscribeFreeOnSignupCommunity'; -import { SendVerfiyMailOnSignUp } from '@/services/Authentication/events/SendVerfiyMailOnSignUp'; -import { AttachmentsOnSaleInvoiceCreated } from '@/services/Attachments/events/AttachmentsOnSaleInvoice'; -import { AttachmentsOnSaleReceipt } from '@/services/Attachments/events/AttachmentsOnSaleReceipts'; -import { AttachmentsOnManualJournals } from '@/services/Attachments/events/AttachmentsOnManualJournals'; -import { AttachmentsOnExpenses } from '@/services/Attachments/events/AttachmentsOnExpenses'; -import { AttachmentsOnBills } from '@/services/Attachments/events/AttachmentsOnBills'; -import { AttachmentsOnPaymentsReceived } from '@/services/Attachments/events/AttachmentsOnPaymentsReceived'; -import { AttachmentsOnVendorCredits } from '@/services/Attachments/events/AttachmentsOnVendorCredits'; -import { AttachmentsOnCreditNote } from '@/services/Attachments/events/AttachmentsOnCreditNote'; -import { AttachmentsOnBillPayments } from '@/services/Attachments/events/AttachmentsOnPaymentsMade'; -import { AttachmentsOnSaleEstimates } from '@/services/Attachments/events/AttachmentsOnSaleEstimates'; -import { TriggerRecognizedTransactions } from '@/services/Banking/RegonizeTranasctions/events/TriggerRecognizedTransactions'; -import { ValidateMatchingOnExpenseDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnExpenseDelete'; -import { ValidateMatchingOnManualJournalDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnManualJournalDelete'; -import { ValidateMatchingOnPaymentReceivedDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnPaymentReceivedDelete'; -import { ValidateMatchingOnPaymentMadeDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnPaymentMadeDelete'; -import { ValidateMatchingOnCashflowDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnCashflowDelete'; -import { RecognizeSyncedBankTranasctions } from '@/services/Banking/Plaid/subscribers/RecognizeSyncedBankTransactions'; -import { UnlinkBankRuleOnDeleteBankRule } from '@/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule'; -import { DecrementUncategorizedTransactionOnMatching } from '@/services/Banking/Matching/events/DecrementUncategorizedTransactionsOnMatch'; -import { DecrementUncategorizedTransactionOnExclude } from '@/services/Banking/Exclude/events/DecrementUncategorizedTransactionOnExclude'; -import { DecrementUncategorizedTransactionOnCategorize } from '@/services/Cashflow/subscribers/DecrementUncategorizedTransactionOnCategorize'; -import { DisconnectPlaidItemOnAccountDeleted } from '@/services/Banking/BankAccounts/events/DisconnectPlaidItemOnAccountDeleted'; -import { LoopsEventsSubscriber } from '@/services/Loops/LoopsEventsSubscriber'; -import { DeleteUncategorizedTransactionsOnAccountDeleting } from '@/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting'; -import { SeedInitialDemoAccountDataOnOrgBuild } from '@/services/OneClickDemo/events/SeedInitialDemoAccountData'; -import { EventsTrackerListeners } from '@/services/EventsTracker/events/events'; -import { InvoicePaymentIntegrationSubscriber } from '@/services/Sales/Invoices/subscribers/InvoicePaymentIntegrationSubscriber'; -import { StripeWebhooksSubscriber } from '@/services/StripePayment/events/StripeWebhooksSubscriber'; -import { SeedStripeAccountsOnOAuthGrantedSubscriber } from '@/services/StripePayment/events/SeedStripeAccounts'; - -export default () => { - return new EventPublisher(); -}; - -export const susbcribers = () => { - return [ - InventoryAdjustmentsSubscriber, - BillWriteInventoryTransactionsSubscriber, - PaymentSyncBillBalance, - SaleReceiptInventoryTransactionsSubscriber, - SaleReceiptWriteGLEntriesSubscriber, - SaleInvoiceWriteInventoryTransactions, - SaleInvoiceWriteGLEntriesSubscriber, - PaymentReceiveSyncInvoices, - PaymentReceivesWriteGLEntriesSubscriber, - CashflowTransactionSubscriber, - InventorySubscriber, - CustomerWriteGLOpeningBalanceSubscriber, - VendorsWriteGLOpeningSubscriber, - - // # Estimate - SaleEstimateAutoSerialSubscriber, - SaleEstimateSmsNotificationSubscriber, - SaleEstimateMarkApprovedOnMailSent, - - ExpensesWriteGLSubscriber, - SaleReceiptAutoSerialSubscriber, - SaleInvoiceAutoIncrementSubscriber, - SaleInvoiceConvertFromEstimateSubscriber, - PaymentReceiveAutoSerialSubscriber, - SyncSystemSendInvite, - SyncTenantAcceptInvite, - InviteSendMainNotification, - SyncTenantUserMutate, - SyncTenantUserDelete, - OrgSyncTenantAdminUserSubscriber, - OrgBuildSmsNotificationSubscriber, - PurgeUserAbilityCache, - ResetLoginThrottleSubscriber, - AuthenticationSubscriber, - PurgeAuthorizedUserOnceRoleMutate, - SendSmsNotificationToCustomer, - SendSmsNotificationSaleReceipt, - SendSmsNotificationPaymentReceive, - SaleInvoiceWriteoffSubscriber, - LandedCostSyncCostTransactionsSubscriber, - LandedCostInventoryTransactionsSubscriber, - CreditNoteGLEntriesSubscriber, - VendorCreditGlEntriesSubscriber, - CreditNoteInventoryTransactionsSubscriber, - VendorCreditInventoryTransactionsSubscriber, - CreditNoteAutoSerialSubscriber, - VendorCreditAutoSerialSubscriber, - LandedCostGLEntriesSubscriber, - RefundCreditNoteGLEntriesSubscriber, - RefundVendorCreditGLEntriesSubscriber, - RefundSyncCreditNoteBalanceSubscriber, - RefundSyncVendorCreditBalanceSubscriber, - CreditNoteApplySyncCreditSubscriber, - CreditNoteApplySyncInvoicesCreditedAmountSubscriber, - ApplyVendorCreditSyncInvoicedSubscriber, - ApplyVendorCreditSyncBillsSubscriber, - DeleteCustomerLinkedCreditSubscriber, - DeleteVendorAssociatedVendorCredit, - - // # Inventory - InventoryCostGLBeforeWriteSubscriber, - - // #Invoices - InvoicePaymentGLRewriteSubscriber, - InvoiceCostGLEntriesSubscriber, - InvoiceChangeStatusOnMailSentSubscriber, - - BillPaymentsGLEntriesRewriteSubscriber, - - // # Receipts - SaleReceiptCostGLEntriesSubscriber, - SaleReceiptMarkClosedOnMailSentSubcriber, - - // Transaction locking. - SalesTransactionLockingGuardSubscriber, - PurchasesTransactionLockingGuardSubscriber, - FinancialTransactionLockingGuardSubscriber, - CashflowWithAccountSubscriber, - - // Warehouses - WarehousesItemsQuantitySyncSubscriber, - WarehouseTransferInventoryTransactionsSubscriber, - WarehouseTransferAutoIncrementSubscriber, - ActivateWarehousesSubscriber, - - // Branches. - AccountsTransactionsWarehousesSubscribe, - ...BranchesIntegrationsSubscribers(), - ...WarehousesIntegrationsSubscribers(), - - // Manual Journals - ManualJournalWriteGLSubscriber, - - // Bills - BillGLEntriesSubscriber, - PaymentWriteGLEntriesSubscriber, - - SeedInitialCurrenciesOnSetupSubsriber, - MutateBaseCurrencyAccountsSubscriber, - - // # Projects - SyncActualTimeTaskSubscriber, - ProjectBillableTasksSubscriber, - ProjectBillableExpensesSubscriber, - ProjectBillableBillSubscriber, - - // Tax Rates - Sale Invoice - SaleInvoiceTaxRateValidateSubscriber, - WriteInvoiceTaxTransactionsSubscriber, - - // Tax Rates - Bills - BillTaxRateValidateSubscriber, - WriteBillTaxTransactionsSubscriber, - - SyncItemTaxRateOnEditTaxSubscriber, - - // Plaid - PlaidUpdateTransactionsOnItemCreatedSubscriber, - - // Cashflow - DeleteCashflowTransactionOnUncategorize, - PreventDeleteTransactionOnDelete, - - // Subscription - SubscribeFreeOnSignupCommunity, - SendVerfiyMailOnSignUp, - - // Attachments - AttachmentsOnSaleInvoiceCreated, - AttachmentsOnSaleEstimates, - AttachmentsOnSaleReceipt, - AttachmentsOnPaymentsReceived, - AttachmentsOnCreditNote, - AttachmentsOnVendorCredits, - AttachmentsOnBills, - AttachmentsOnBillPayments, - AttachmentsOnManualJournals, - AttachmentsOnExpenses, - - // Bank Rules - TriggerRecognizedTransactions, - UnlinkBankRuleOnDeleteBankRule, - DecrementUncategorizedTransactionOnMatching, - DecrementUncategorizedTransactionOnExclude, - DecrementUncategorizedTransactionOnCategorize, - - // Validate matching - ValidateMatchingOnCashflowDelete, - ValidateMatchingOnExpenseDelete, - ValidateMatchingOnManualJournalDelete, - ValidateMatchingOnPaymentReceivedDelete, - ValidateMatchingOnPaymentMadeDelete, - - // Plaid - RecognizeSyncedBankTranasctions, - DisconnectPlaidItemOnAccountDeleted, - DeleteUncategorizedTransactionsOnAccountDeleting, - - // Loops - LoopsEventsSubscriber, - - // Demo Account - SeedInitialDemoAccountDataOnOrgBuild, - - // Stripe Payment - InvoicePaymentIntegrationSubscriber, - StripeWebhooksSubscriber, - SeedStripeAccountsOnOAuthGrantedSubscriber, - - ...EventsTrackerListeners - ]; -}; diff --git a/packages/server/src/loaders/events.ts b/packages/server/src/loaders/events.ts deleted file mode 100644 index 9591e6b90..000000000 --- a/packages/server/src/loaders/events.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Here we import all events. -// import 'subscribers/authentication'; -// import 'subscribers/organization'; -// import 'subscribers/inviteUser'; -// import 'subscribers/manualJournals'; -// import 'subscribers/expenses'; - -// import 'subscribers/Bills'; -// import 'subscribers/Bills/WriteJournalEntries'; -// import 'subscribers/Bills/WriteInventoryTransactions'; - -// // import 'subscribers/SaleInvoices'; -// // import 'subscribers/SaleInvoices/WriteInventoryTransactions'; -// // import 'subscribers/SaleInvoices/WriteJournalEntries'; - -// import 'subscribers/SaleReceipt'; -// import 'subscribers/SaleReceipt/WriteInventoryTransactions'; -// import 'subscribers/SaleReceipt/WriteJournalEntries'; - -// import 'subscribers/Inventory/Inventory'; -// import 'subscribers/Inventory/InventoryAdjustment'; - -// import 'subscribers/customers'; -// import 'subscribers/vendors'; -// import 'subscribers/paymentMades'; -// import 'subscribers/paymentReceives'; -// import 'subscribers/saleEstimates'; -// import 'subscribers/items'; - -// import 'subscribers/LandedCost'; - -// import 'services/Cashflow/CashflowTransactionSubscriber'; - -// import 'services/Sales/SaleInvoiceWriteoffSubscriber'; -// import 'subscribers/SaleInvoices/SendSmsNotificationToCustomer'; -// import 'subscribers/SaleReceipt/SendNotificationToCustomer'; -// import 'services/Sales/PaymentReceived/PaymentReceiveSmsSubscriber'; \ No newline at end of file diff --git a/packages/server/src/loaders/express.ts b/packages/server/src/loaders/express.ts deleted file mode 100644 index e3afad411..000000000 --- a/packages/server/src/loaders/express.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { json, Request, Response, NextFunction } from 'express'; -import express from 'express'; -import helmet from 'helmet'; -import boom from 'express-boom'; -import errorHandler from 'errorhandler'; -import bodyParser from 'body-parser'; -import { Server } from 'socket.io'; -import Container from 'typedi'; -import routes from 'api'; -import LoggerMiddleware from '@/api/middleware/LoggerMiddleware'; -import AgendashController from '@/api/controllers/Agendash'; -import ConvertEmptyStringsToNull from '@/api/middleware/ConvertEmptyStringsToNull'; -import RateLimiterMiddleware from '@/api/middleware/RateLimiterMiddleware'; -import { - JSONResponseTransformer, - snakecaseResponseTransformer, -} from '@/api/middleware/JSONResponseTransformer'; -import config from '@/config'; -import path from 'path'; -import { ObjectionErrorException } from '@/api/exceptions/ObjectionErrorException'; -import { ServiceErrorException } from '@/api/exceptions/ServiceErrorException'; -import { GlobalErrorException } from '@/api/exceptions/GlobalErrorException'; - -export default ({ app }) => { - // Express configuration. - app.set('port', 3000); - - // Template engine configuration. - app.set('views', path.join(__dirname, '../resources/views')); - app.set('view engine', 'pug'); - - // Helmet helps you secure your Express apps by setting various HTTP headers. - app.use(helmet()); - - // Boom response objects. - app.use(boom()); - - app.use( - bodyParser.json({ - verify: (req, res, buf) => { - req.rawBody = buf; - }, - }) - ); - - // Parses both json and urlencoded. - app.use(json()); - - // Middleware for intercepting and transforming json responses. - app.use(JSONResponseTransformer(snakecaseResponseTransformer)); - - app.use('/public', express.static(path.join(global.__storage_dir))); - - // Logger middleware. - app.use(LoggerMiddleware); - - // Converts empty strings to null of request body. - app.use(ConvertEmptyStringsToNull); - - // Prefix all application routes. - app.use(config.api.prefix, RateLimiterMiddleware); - app.use(config.api.prefix, routes()); - - // Agendash application load. - app.use('/agendash', AgendashController.router()); - - // Handles errors. - app.use(ObjectionErrorException); - app.use(ServiceErrorException); - app.use(GlobalErrorException); - - // catch 404 and forward to error handler - app.use((req: Request, res: Response, next: NextFunction) => { - return res.boom.notFound(); - }); - const server = app.listen(app.get('port'), (err) => { - if (err) { - console.log(err); - process.exit(1); - return; - } - console.log(` - ################################################ - Server listening on port: ${app.get('port')} - ################################################ - `); - }); - const io = new Server(server, { path: '/socket' }); - - // Set socket.io listeners. - io.on('connection', (socket) => { - console.log('SOCKET CONNECTED'); - - socket.on('disconnect', () => { - console.log('SOCKET DISCONNECTED'); - }); - }); - // Middleware to pass socket to each request object. - app.use((req: Request, res: Response, next: NextFunction) => { - req.io = io; - next(); - }); - Container.set('socket', io); -}; diff --git a/packages/server/src/loaders/i18n.ts b/packages/server/src/loaders/i18n.ts deleted file mode 100644 index 3d703b0c9..000000000 --- a/packages/server/src/loaders/i18n.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { I18n } from 'i18n'; - -export default () => new I18n({ - locales: ['en', 'ar'], - defaultLocale: 'en', - register: global, - directory: global.__locales_dir, - updateFiles: false, -}); \ No newline at end of file diff --git a/packages/server/src/loaders/index.ts b/packages/server/src/loaders/index.ts deleted file mode 100644 index 08e9e1afd..000000000 --- a/packages/server/src/loaders/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import Logger from '@/loaders/logger'; -import mongooseLoader from '@/loaders/mongoose'; -import jobsLoader from '@/loaders/jobs'; -import expressLoader from '@/loaders/express'; -import databaseLoader from '@/loaders/database'; -import dependencyInjectorLoader from '@/loaders/dependencyInjector'; -import objectionLoader from '@/database/objection'; -import i18nConfig from '@/loaders/i18n'; - -// We have to import at least all the events once so they can be triggered -// import '@/loaders/events'; - -export default async ({ expressApp }) => { - const mongoConnection = await mongooseLoader(); - Logger.info('[init] MongoDB loaded and connected!'); - - // Initialize the system database once app started. - const knex = databaseLoader(); - - // Initialize the objection.js from knex instance. - objectionLoader({ knex }); - - // It returns the agenda instance because it's needed in the subsequent loaders - const { agenda } = await dependencyInjectorLoader({ mongoConnection, knex }); - - await jobsLoader({ agenda }); - Logger.info('[init] Jobs loaded'); - - expressLoader({ app: expressApp }); - Logger.info('[init] Express loaded'); - - i18nConfig(); - Logger.info('[init] I18n node configured.'); -}; diff --git a/packages/server/src/loaders/jobs.ts b/packages/server/src/loaders/jobs.ts deleted file mode 100644 index 3ca6ec25f..000000000 --- a/packages/server/src/loaders/jobs.ts +++ /dev/null @@ -1,42 +0,0 @@ -import Agenda from 'agenda'; -import ResetPasswordMailJob from 'jobs/ResetPasswordMail'; -import ComputeItemCost from 'jobs/ComputeItemCost'; -import RewriteInvoicesJournalEntries from 'jobs/WriteInvoicesJEntries'; -import UserInviteMailJob from 'jobs/UserInviteMail'; -import OrganizationSetupJob from 'jobs/OrganizationSetup'; -import OrganizationUpgrade from 'jobs/OrganizationUpgrade'; -import { SendSaleInvoiceMailJob } from '@/services/Sales/Invoices/SendSaleInvoiceMailJob'; -import { SendSaleInvoiceReminderMailJob } from '@/services/Sales/Invoices/SendSaleInvoiceMailReminderJob'; -import { SendSaleEstimateMailJob } from '@/services/Sales/Estimates/SendSaleEstimateMailJob'; -import { SaleReceiptMailNotificationJob } from '@/services/Sales/Receipts/SaleReceiptMailNotificationJob'; -import { PaymentReceivedMailNotificationJob } from '@/services/Sales/PaymentReceived/PaymentReceivedMailNotificationJob'; -import { PlaidFetchTransactionsJob } from '@/services/Banking/Plaid/PlaidFetchTransactionsJob'; -import { ImportDeleteExpiredFilesJobs } from '@/services/Import/jobs/ImportDeleteExpiredFilesJob'; -import { SendVerifyMailJob } from '@/services/Authentication/jobs/SendVerifyMailJob'; -import { ReregonizeTransactionsJob } from '@/services/Banking/RegonizeTranasctions/jobs/RerecognizeTransactionsJob'; -import { RegonizeTransactionsJob } from '@/services/Banking/RegonizeTranasctions/jobs/RecognizeTransactionsJob'; -import { RevertRegonizeTransactionsJob } from '@/services/Banking/RegonizeTranasctions/jobs/RevertRecognizedTransactionsJob'; - -export default ({ agenda }: { agenda: Agenda }) => { - new ResetPasswordMailJob(agenda); - new UserInviteMailJob(agenda); - new ComputeItemCost(agenda); - new RewriteInvoicesJournalEntries(agenda); - new OrganizationSetupJob(agenda); - new OrganizationUpgrade(agenda); - new SendSaleInvoiceMailJob(agenda); - new SendSaleInvoiceReminderMailJob(agenda); - new SendSaleEstimateMailJob(agenda); - new SaleReceiptMailNotificationJob(agenda); - new PaymentReceivedMailNotificationJob(agenda); - new PlaidFetchTransactionsJob(agenda); - new ImportDeleteExpiredFilesJobs(agenda); - new SendVerifyMailJob(agenda); - new RegonizeTransactionsJob(agenda); - new ReregonizeTransactionsJob(agenda); - new RevertRegonizeTransactionsJob(agenda); - - agenda.start().then(() => { - agenda.every('1 hours', 'delete-expired-imported-files', {}); - }); -}; diff --git a/packages/server/src/loaders/logger.ts b/packages/server/src/loaders/logger.ts deleted file mode 100644 index cbdf1a3fa..000000000 --- a/packages/server/src/loaders/logger.ts +++ /dev/null @@ -1,13 +0,0 @@ -import winston from 'winston'; - -const transports = { - console: new winston.transports.Console({ level: 'warn' }), - file: new winston.transports.File({ filename: 'stdout.log' }), -}; - -export default winston.createLogger({ - transports: [ - transports.console, - transports.file, - ], -}); diff --git a/packages/server/src/loaders/mail.ts b/packages/server/src/loaders/mail.ts deleted file mode 100644 index 496a7f78a..000000000 --- a/packages/server/src/loaders/mail.ts +++ /dev/null @@ -1,15 +0,0 @@ -import nodemailer from 'nodemailer'; -import config from '@/config'; - -// create reusable transporter object using the default SMTP transport -const transporter = nodemailer.createTransport({ - host: config.mail.host, - port: config.mail.port, - secure: config.mail.secure, // true for 465, false for other ports - auth: { - user: config.mail.username, - pass: config.mail.password, - }, -}); - -export default transporter; \ No newline at end of file diff --git a/packages/server/src/loaders/mongoose.ts b/packages/server/src/loaders/mongoose.ts deleted file mode 100644 index e241afd33..000000000 --- a/packages/server/src/loaders/mongoose.ts +++ /dev/null @@ -1,11 +0,0 @@ -import mongoose from 'mongoose'; -import { Db } from 'mongodb'; -import config from '@/config'; - -export default async (): Promise => { - const connection = await mongoose.connect( - config.mongoDb.databaseURL, - { useNewUrlParser: true, useCreateIndex: true }, - ); - return connection.connection.db; -}; diff --git a/packages/server/src/loaders/rateLimiterLoader.ts b/packages/server/src/loaders/rateLimiterLoader.ts deleted file mode 100644 index b272f0d53..000000000 --- a/packages/server/src/loaders/rateLimiterLoader.ts +++ /dev/null @@ -1,24 +0,0 @@ -import RateLimiter from '@/services/Authentication/RateLimiter'; -import { Container } from 'typedi'; -import { RateLimiterMemory } from 'rate-limiter-flexible'; -import config from '@/config'; - -export default () => { - const rateLimiterRequestsMemory = new RateLimiterMemory({ - points: config.throttler.requests.points, - duration: config.throttler.requests.duration, - blockDuration: config.throttler.requests.blockDuration, - }); - const rateLimiterMemoryLogin = new RateLimiterMemory({ - points: config.throttler.login.points, - duration: config.throttler.login.duration, - blockDuration: config.throttler.login.blockDuration, - }); - - const rateLimiterRequest = new RateLimiter(rateLimiterRequestsMemory); - const rateLimiterLogin = new RateLimiter(rateLimiterMemoryLogin) - - // Inject the rate limiter of the global requests and login into the container. - Container.set('rateLimiter.request', rateLimiterRequest); - Container.set('rateLimiter.login', rateLimiterLogin); -}; \ No newline at end of file diff --git a/packages/server/src/loaders/smsClient.ts b/packages/server/src/loaders/smsClient.ts deleted file mode 100644 index b61d01bbf..000000000 --- a/packages/server/src/loaders/smsClient.ts +++ /dev/null @@ -1,9 +0,0 @@ -import SMSClient from '@/services/SMSClient'; -import EasySMSGateway from '@/services/SMSClient/EasySmsClient'; - -export default (token: string) => { - const easySmsGateway = new EasySMSGateway(token); - const smsClient = new SMSClient(easySmsGateway); - - return smsClient; -}; diff --git a/packages/server/src/loaders/systemRepositories.ts b/packages/server/src/loaders/systemRepositories.ts deleted file mode 100644 index 4d84583ca..000000000 --- a/packages/server/src/loaders/systemRepositories.ts +++ /dev/null @@ -1,17 +0,0 @@ -import Container from 'typedi'; -import { - SystemUserRepository, - SubscriptionRepository, - TenantRepository, -} from '@/system/repositories'; - -export default () => { - const knex = Container.get('knex'); - const cache = Container.get('cache'); - - return { - systemUserRepository: new SystemUserRepository(knex, cache), - subscriptionRepository: new SubscriptionRepository(knex, cache), - tenantRepository: new TenantRepository(knex, cache), - }; -} \ No newline at end of file diff --git a/packages/server/src/loaders/tenantCache.ts b/packages/server/src/loaders/tenantCache.ts deleted file mode 100644 index 79cae5915..000000000 --- a/packages/server/src/loaders/tenantCache.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Container } from 'typedi'; -import Cache from '@/services/Cache'; - -export default (tenantId: number) => { - const cacheInstance = new Cache(); - - return cacheInstance; -}; \ No newline at end of file diff --git a/packages/server/src/loaders/tenantModels.ts b/packages/server/src/loaders/tenantModels.ts deleted file mode 100644 index 75de1cef1..000000000 --- a/packages/server/src/loaders/tenantModels.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { mapValues } from 'lodash'; - -import Account from 'models/Account'; -import AccountTransaction from 'models/AccountTransaction'; -import Item from 'models/Item'; -import ItemEntry from 'models/ItemEntry'; -import ItemCategory from 'models/ItemCategory'; -import Bill from 'models/Bill'; -import BillPayment from 'models/BillPayment'; -import BillPaymentEntry from 'models/BillPaymentEntry'; -import Currency from 'models/Currency'; -import Contact from 'models/Contact'; -import Vendor from 'models/Vendor'; -import Customer from 'models/Customer'; -import ExchangeRate from 'models/ExchangeRate'; -import Expense from 'models/Expense'; -import ExpenseCategory from 'models/ExpenseCategory'; -import View from 'models/View'; -import ViewRole from 'models/ViewRole'; -import ViewColumn from 'models/ViewColumn'; -import Setting from 'models/Setting'; -import SaleInvoice from 'models/SaleInvoice'; -import SaleInvoiceEntry from 'models/SaleInvoiceEntry'; -import SaleReceipt from 'models/SaleReceipt'; -import SaleReceiptEntry from 'models/SaleReceiptEntry'; -import SaleEstimate from 'models/SaleEstimate'; -import SaleEstimateEntry from 'models/SaleEstimateEntry'; -import PaymentReceive from 'models/PaymentReceive'; -import PaymentReceiveEntry from 'models/PaymentReceiveEntry'; -import Option from 'models/Option'; -import InventoryCostLotTracker from 'models/InventoryCostLotTracker'; -import InventoryTransaction from 'models/InventoryTransaction'; -import ManualJournal from 'models/ManualJournal'; -import ManualJournalEntry from 'models/ManualJournalEntry'; -import Media from 'models/Media'; -import MediaLink from 'models/MediaLink'; -import InventoryAdjustment from 'models/InventoryAdjustment'; -import InventoryAdjustmentEntry from 'models/InventoryAdjustmentEntry'; -import BillLandedCost from 'models/BillLandedCost'; -import BillLandedCostEntry from 'models/BillLandedCostEntry'; -import CashflowAccount from 'models/CashflowAccount'; -import CashflowTransaction from 'models/CashflowTransaction'; -import CashflowTransactionLine from 'models/CashflowTransactionLine'; -import Role from 'models/Role'; -import RolePermission from 'models/RolePermission'; -import User from 'models/User'; -import CreditNote from 'models/CreditNote'; -import VendorCredit from 'models/VendorCredit'; -import RefundCreditNote from 'models/RefundCreditNote'; -import RefundVendorCredit from 'models/RefundVendorCredit'; -import CreditNoteAppliedInvoice from 'models/CreditNoteAppliedInvoice'; -import VendorCreditAppliedBill from 'models/VendorCreditAppliedBill'; -import Branch from 'models/Branch'; -import Warehouse from 'models/Warehouse'; -import WarehouseTransfer from 'models/WarehouseTransfer'; -import WarehouseTransferEntry from 'models/WarehouseTransferEntry'; -import ItemWarehouseQuantity from 'models/ItemWarehouseQuantity'; -import Project from 'models/Project'; -import Time from 'models/Time'; -import Task from 'models/Task'; -import TaxRate from 'models/TaxRate'; -import TaxRateTransaction from 'models/TaxRateTransaction'; -import PlaidItem from 'models/PlaidItem'; -import UncategorizedCashflowTransaction from 'models/UncategorizedCashflowTransaction'; -import Document from '@/models/Document'; -import DocumentLink from '@/models/DocumentLink'; -import { BankRule } from '@/models/BankRule'; -import { BankRuleCondition } from '@/models/BankRuleCondition'; -import { RecognizedBankTransaction } from '@/models/RecognizedBankTransaction'; -import { MatchedBankTransaction } from '@/models/MatchedBankTransaction'; -import { PdfTemplate } from '@/models/PdfTemplate'; -import { PaymentIntegration } from '@/models/PaymentIntegration'; -import { TransactionPaymentServiceEntry } from '@/models/TransactionPaymentServiceEntry'; - -export default (knex) => { - const models = { - Option, - Account, - AccountTransaction, - Item, - ItemCategory, - ItemEntry, - ManualJournal, - ManualJournalEntry, - Bill, - BillPayment, - BillPaymentEntry, - Currency, - ExchangeRate, - Expense, - ExpenseCategory, - View, - ViewRole, - ViewColumn, - Setting, - SaleInvoice, - SaleInvoiceEntry, - SaleReceipt, - SaleReceiptEntry, - SaleEstimate, - SaleEstimateEntry, - PaymentReceive, - PaymentReceiveEntry, - InventoryTransaction, - InventoryCostLotTracker, - Media, - MediaLink, - Vendor, - Customer, - Contact, - InventoryAdjustment, - InventoryAdjustmentEntry, - BillLandedCost, - BillLandedCostEntry, - CashflowTransaction, - CashflowTransactionLine, - CashflowAccount, - Role, - RolePermission, - User, - VendorCredit, - CreditNote, - RefundCreditNote, - RefundVendorCredit, - CreditNoteAppliedInvoice, - VendorCreditAppliedBill, - Branch, - Warehouse, - WarehouseTransfer, - WarehouseTransferEntry, - ItemWarehouseQuantity, - Project, - Time, - Task, - TaxRate, - TaxRateTransaction, - Document, - DocumentLink, - PlaidItem, - UncategorizedCashflowTransaction, - BankRule, - BankRuleCondition, - RecognizedBankTransaction, - MatchedBankTransaction, - PdfTemplate, - PaymentIntegration, - TransactionPaymentServiceEntry, - }; - return mapValues(models, (model) => model.bindKnex(knex)); -}; diff --git a/packages/server/src/loaders/tenantRepositories.ts b/packages/server/src/loaders/tenantRepositories.ts deleted file mode 100644 index c5f3dbec1..000000000 --- a/packages/server/src/loaders/tenantRepositories.ts +++ /dev/null @@ -1,41 +0,0 @@ -import AccountRepository from '@/repositories/AccountRepository'; -import VendorRepository from '@/repositories/VendorRepository'; -import CustomerRepository from '@/repositories/CustomerRepository'; -import ExpenseRepository from '@/repositories/ExpenseRepository'; -import ViewRepository from '@/repositories/ViewRepository'; -import ViewRoleRepository from '@/repositories/ViewRoleRepository'; -import ContactRepository from '@/repositories/ContactRepository'; -import AccountTransactionsRepository from '@/repositories/AccountTransactionRepository'; -import SettingRepository from '@/repositories/SettingRepository'; -import ExpenseEntryRepository from '@/repositories/ExpenseEntryRepository'; -import BillRepository from '@/repositories/BillRepository'; -import SaleInvoiceRepository from '@/repositories/SaleInvoiceRepository'; -import ItemRepository from '@/repositories/ItemRepository'; -import InventoryTransactionRepository from '@/repositories/InventoryTransactionRepository'; - -export default (knex, cache, i18n) => { - return { - accountRepository: new AccountRepository(knex, cache, i18n), - transactionsRepository: new AccountTransactionsRepository( - knex, - cache, - i18n - ), - customerRepository: new CustomerRepository(knex, cache, i18n), - vendorRepository: new VendorRepository(knex, cache, i18n), - contactRepository: new ContactRepository(knex, cache, i18n), - expenseRepository: new ExpenseRepository(knex, cache, i18n), - expenseEntryRepository: new ExpenseEntryRepository(knex, cache, i18n), - viewRepository: new ViewRepository(knex, cache, i18n), - viewRoleRepository: new ViewRoleRepository(knex, cache, i18n), - settingRepository: new SettingRepository(knex, cache, i18n), - billRepository: new BillRepository(knex, cache, i18n), - saleInvoiceRepository: new SaleInvoiceRepository(knex, cache, i18n), - itemRepository: new ItemRepository(knex, cache, i18n), - inventoryTransactionRepository: new InventoryTransactionRepository( - knex, - cache, - i18n - ), - }; -}; diff --git a/packages/server-nest/src/main.ts b/packages/server/src/main.ts similarity index 100% rename from packages/server-nest/src/main.ts rename to packages/server/src/main.ts diff --git a/packages/server-nest/src/middleware/logger.middleware.ts b/packages/server/src/middleware/logger.middleware.ts similarity index 100% rename from packages/server-nest/src/middleware/logger.middleware.ts rename to packages/server/src/middleware/logger.middleware.ts diff --git a/packages/server/src/models/Account.Settings.ts b/packages/server/src/models/Account.Settings.ts deleted file mode 100644 index 0d4690041..000000000 --- a/packages/server/src/models/Account.Settings.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { ACCOUNT_TYPES } from '@/data/AccountTypes'; - -export default { - defaultFilterField: 'name', - defaultSort: { - sortOrder: 'DESC', - sortField: 'name', - }, - importable: true, - exportable: true, - print: { - pageTitle: 'Chart of Accounts', - }, - fields: { - name: { - name: 'account.field.name', - column: 'name', - fieldType: 'text', - }, - description: { - name: 'account.field.description', - column: 'description', - fieldType: 'text', - }, - slug: { - name: 'account.field.slug', - column: 'slug', - fieldType: 'text', - columnable: false, - filterable: false, - }, - code: { - name: 'account.field.code', - column: 'code', - fieldType: 'text', - }, - root_type: { - name: 'account.field.root_type', - fieldType: 'enumeration', - options: [ - { key: 'asset', label: 'Asset' }, - { key: 'liability', label: 'Liability' }, - { key: 'equity', label: 'Equity' }, - { key: 'Income', label: 'Income' }, - { key: 'expense', label: 'Expense' }, - ], - filterCustomQuery: RootTypeFieldFilterQuery, - sortable: false, - }, - normal: { - name: 'account.field.normal', - fieldType: 'enumeration', - options: [ - { key: 'debit', label: 'account.field.normal.debit' }, - { key: 'credit', label: 'account.field.normal.credit' }, - ], - filterCustomQuery: NormalTypeFieldFilterQuery, - sortable: false, - }, - type: { - name: 'account.field.type', - column: 'account_type', - fieldType: 'enumeration', - options: ACCOUNT_TYPES.map((accountType) => ({ - label: accountType.label, - key: accountType.key, - })), - }, - active: { - name: 'account.field.active', - column: 'active', - fieldType: 'boolean', - filterable: false, - }, - balance: { - name: 'account.field.balance', - column: 'amount', - fieldType: 'number', - }, - currency: { - name: 'account.field.currency', - column: 'currency_code', - fieldType: 'text', - filterable: false, - }, - created_at: { - name: 'account.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - name: { - name: 'account.field.name', - type: 'text', - }, - code: { - name: 'account.field.code', - type: 'text', - }, - rootType: { - name: 'account.field.root_type', - type: 'text', - accessor: 'accountRootType', - }, - accountType: { - name: 'account.field.type', - accessor: 'accountTypeLabel', - type: 'text', - }, - accountNormal: { - name: 'account.field.normal', - accessor: 'accountNormalFormatted', - }, - currencyCode: { - name: 'account.field.currency', - type: 'text', - }, - bankBalance: { - name: 'account.field.bank_balance', - accessor: 'bankBalanceFormatted', - type: 'text', - exportable: true, - }, - balance: { - name: 'account.field.balance', - accessor: 'formattedAmount', - }, - description: { - name: 'account.field.description', - type: 'text', - }, - active: { - name: 'account.field.active', - type: 'boolean', - }, - createdAt: { - name: 'account.field.created_at', - printable: false, - }, - }, - fields2: { - name: { - name: 'account.field.name', - fieldType: 'text', - unique: true, - required: true, - }, - description: { - name: 'account.field.description', - fieldType: 'text', - }, - code: { - name: 'account.field.code', - fieldType: 'text', - minLength: 3, - maxLength: 6, - unique: true, - importHint: 'Unique number to identify the account.', - }, - accountType: { - name: 'account.field.type', - fieldType: 'enumeration', - options: ACCOUNT_TYPES.map((accountType) => ({ - label: accountType.label, - key: accountType.key, - })), - required: true, - }, - active: { - name: 'account.field.active', - fieldType: 'boolean', - }, - currencyCode: { - name: 'account.field.currency', - fieldType: 'text', - }, - parentAccountId: { - name: 'account.field.parent_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - }, - }, -}; - -/** - * Filter query of root type field . - */ -function RootTypeFieldFilterQuery(query, role) { - query.modify('filterByRootType', role.value); -} - -/** - * Filter query of normal field . - */ -function NormalTypeFieldFilterQuery(query, role) { - query.modify('filterByAccountNormal', role.value); -} diff --git a/packages/server/src/models/Account.ts b/packages/server/src/models/Account.ts deleted file mode 100644 index d9972251a..000000000 --- a/packages/server/src/models/Account.ts +++ /dev/null @@ -1,448 +0,0 @@ -/* eslint-disable global-require */ -import { mixin, Model } from 'objection'; -import { castArray } from 'lodash'; -import TenantModel from '@/models/TenantModel'; -import { buildFilterQuery, buildSortColumnQuery } from '@/lib/ViewRolesBuilder'; -import { flatToNestedArray } from 'utils'; -import DependencyGraph from '@/lib/DependencyGraph'; -import AccountTypesUtils from '@/lib/AccountTypes'; -import AccountSettings from './Account.Settings'; -import ModelSettings from './ModelSetting'; -import { - ACCOUNT_TYPES, - getAccountsSupportsMultiCurrency, -} from '@/data/AccountTypes'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Accounts/constants'; -import ModelSearchable from './ModelSearchable'; - -export default class Account extends mixin(TenantModel, [ - ModelSettings, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name. - */ - static get tableName() { - return 'accounts'; - } - - /** - * Timestamps columns. - */ - static get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'accountTypeLabel', - 'accountParentType', - 'accountRootType', - 'accountNormal', - 'accountNormalFormatted', - 'isBalanceSheetAccount', - 'isPLSheet', - ]; - } - - /** - * Account normal. - */ - get accountNormal() { - return AccountTypesUtils.getType(this.accountType, 'normal'); - } - - get accountNormalFormatted() { - const paris = { - credit: 'Credit', - debit: 'Debit', - }; - return paris[this.accountNormal] || ''; - } - - /** - * Retrieve account type label. - */ - get accountTypeLabel() { - return AccountTypesUtils.getType(this.accountType, 'label'); - } - - /** - * Retrieve account parent type. - */ - get accountParentType() { - return AccountTypesUtils.getType(this.accountType, 'parentType'); - } - - /** - * Retrieve account root type. - */ - get accountRootType() { - return AccountTypesUtils.getType(this.accountType, 'rootType'); - } - - /** - * Retrieve whether the account is balance sheet account. - */ - get isBalanceSheetAccount() { - return this.isBalanceSheet(); - } - - /** - * Retrieve whether the account is profit/loss sheet account. - */ - get isPLSheet() { - return this.isProfitLossSheet(); - } - /** - * Allows to mark model as resourceable to viewable and filterable. - */ - static get resourceable() { - return true; - } - - /** - * Model modifiers. - */ - static get modifiers() { - const TABLE_NAME = Account.tableName; - - return { - /** - * Inactive/Active mode. - */ - inactiveMode(query, active = false) { - query.where('accounts.active', !active); - }, - - filterAccounts(query, accountIds) { - if (accountIds.length > 0) { - query.whereIn(`${TABLE_NAME}.id`, accountIds); - } - }, - filterAccountTypes(query, typesIds) { - if (typesIds.length > 0) { - query.whereIn('account_types.account_type_id', typesIds); - } - }, - viewRolesBuilder(query, conditionals, expression) { - buildFilterQuery(Account.tableName, conditionals, expression)(query); - }, - sortColumnBuilder(query, columnKey, direction) { - buildSortColumnQuery(Account.tableName, columnKey, direction)(query); - }, - - /** - * Filter by root type. - */ - filterByRootType(query, rootType) { - const filterTypes = ACCOUNT_TYPES.filter( - (accountType) => accountType.rootType === rootType - ).map((accountType) => accountType.key); - - query.whereIn('account_type', filterTypes); - }, - - /** - * Filter by account normal - */ - filterByAccountNormal(query, accountNormal) { - const filterTypes = ACCOUNT_TYPES.filter( - (accountType) => accountType.normal === accountNormal - ).map((accountType) => accountType.key); - - query.whereIn('account_type', filterTypes); - }, - - /** - * Finds account by the given slug. - * @param {*} query - * @param {*} slug - */ - findBySlug(query, slug) { - query.where('slug', slug).first(); - }, - - /** - * - * @param {*} query - * @param {*} baseCyrrency - */ - preventMutateBaseCurrency(query) { - const accountsTypes = getAccountsSupportsMultiCurrency(); - const accountsTypesKeys = accountsTypes.map((type) => type.key); - - query - .whereIn('accountType', accountsTypesKeys) - .where('seededAt', null) - .first(); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const AccountTransaction = require('models/AccountTransaction'); - const Item = require('models/Item'); - const InventoryAdjustment = require('models/InventoryAdjustment'); - const ManualJournalEntry = require('models/ManualJournalEntry'); - const Expense = require('models/Expense'); - const ExpenseEntry = require('models/ExpenseCategory'); - const ItemEntry = require('models/ItemEntry'); - const UncategorizedTransaction = require('models/UncategorizedCashflowTransaction'); - const PlaidItem = require('models/PlaidItem'); - - return { - /** - * Account model may has many transactions. - */ - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'accounts.id', - to: 'accounts_transactions.accountId', - }, - }, - - /** - * - */ - itemsCostAccount: { - relation: Model.HasManyRelation, - modelClass: Item.default, - join: { - from: 'accounts.id', - to: 'items.costAccountId', - }, - }, - - /** - * - */ - itemsSellAccount: { - relation: Model.HasManyRelation, - modelClass: Item.default, - join: { - from: 'accounts.id', - to: 'items.sellAccountId', - }, - }, - - /** - * - */ - inventoryAdjustments: { - relation: Model.HasManyRelation, - modelClass: InventoryAdjustment.default, - join: { - from: 'accounts.id', - to: 'inventory_adjustments.adjustmentAccountId', - }, - }, - - /** - * - */ - manualJournalEntries: { - relation: Model.HasManyRelation, - modelClass: ManualJournalEntry.default, - join: { - from: 'accounts.id', - to: 'manual_journals_entries.accountId', - }, - }, - - /** - * - */ - expensePayments: { - relation: Model.HasManyRelation, - modelClass: Expense.default, - join: { - from: 'accounts.id', - to: 'expenses_transactions.paymentAccountId', - }, - }, - - /** - * - */ - expenseEntries: { - relation: Model.HasManyRelation, - modelClass: ExpenseEntry.default, - join: { - from: 'accounts.id', - to: 'expense_transaction_categories.expenseAccountId', - }, - }, - - /** - * - */ - entriesCostAccount: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'accounts.id', - to: 'items_entries.costAccountId', - }, - }, - - /** - * - */ - entriesSellAccount: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'accounts.id', - to: 'items_entries.sellAccountId', - }, - }, - - /** - * Associated uncategorized transactions. - */ - uncategorizedTransactions: { - relation: Model.HasManyRelation, - modelClass: UncategorizedTransaction.default, - join: { - from: 'accounts.id', - to: 'uncategorized_cashflow_transactions.accountId', - }, - filter: (query) => { - query.where('categorized', false); - }, - }, - - /** - * Account model may belongs to a Plaid item. - */ - plaidItem: { - relation: Model.BelongsToOneRelation, - modelClass: PlaidItem.default, - join: { - from: 'accounts.plaidItemId', - to: 'plaid_items.plaidItemId', - }, - }, - }; - } - - /** - * Detarmines whether the given type equals the account type. - * @param {string} accountType - * @return {boolean} - */ - isAccountType(accountType) { - const types = castArray(accountType); - return types.indexOf(this.accountType) !== -1; - } - - /** - * Detarmines whether the given root type equals the account type. - * @param {string} rootType - * @return {boolean} - */ - isRootType(rootType) { - return AccountTypesUtils.isRootTypeEqualsKey(this.accountType, rootType); - } - - /** - * Detarmine whether the given parent type equals the account type. - * @param {string} parentType - * @return {boolean} - */ - isParentType(parentType) { - return AccountTypesUtils.isParentTypeEqualsKey( - this.accountType, - parentType - ); - } - - /** - * Detarmines whether the account is balance sheet account. - * @return {boolean} - */ - isBalanceSheet() { - return AccountTypesUtils.isTypeBalanceSheet(this.accountType); - } - - /** - * Detarmines whether the account is profit/loss account. - * @return {boolean} - */ - isProfitLossSheet() { - return AccountTypesUtils.isTypePLSheet(this.accountType); - } - - /** - * Detarmines whether the account is income statement account - * @return {boolean} - */ - isIncomeSheet() { - return this.isProfitLossSheet(); - } - - /** - * Converts flatten accounts list to nested array. - * @param {Array} accounts - * @param {Object} options - */ - static toNestedArray(accounts, options = { children: 'children' }) { - return flatToNestedArray(accounts, { - id: 'id', - parentId: 'parentAccountId', - }); - } - - /** - * Transformes the accounts list to depenedency graph structure. - * @param {IAccount[]} accounts - */ - static toDependencyGraph(accounts) { - return DependencyGraph.fromArray(accounts, { - itemId: 'id', - parentItemId: 'parentAccountId', - }); - } - - /** - * Model settings. - */ - static get meta() { - return AccountSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search roles. - */ - static get searchRoles() { - return [ - { condition: 'or', fieldKey: 'name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'code', comparator: 'like' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/AccountTransaction.ts b/packages/server/src/models/AccountTransaction.ts deleted file mode 100644 index f5d968b53..000000000 --- a/packages/server/src/models/AccountTransaction.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { Model, raw } from 'objection'; -import moment from 'moment'; -import { isEmpty, castArray } from 'lodash'; -import TenantModel from 'models/TenantModel'; -import { getTransactionTypeLabel } from '@/utils/transactions-types'; - -export default class AccountTransaction extends TenantModel { - referenceType: string; - credit: number; - debit: number; - exchangeRate: number; - taxRate: number; - transactionType: string; - - /** - * Table name - */ - static get tableName() { - return 'accounts_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['referenceTypeFormatted', 'creditLocal', 'debitLocal']; - } - - /** - * Retrieves the credit amount in base currency. - * @return {number} - */ - get creditLocal() { - return this.credit * this.exchangeRate; - } - - /** - * Retrieves the debit amount in base currency. - * @return {number} - */ - get debitLocal() { - return this.debit * this.exchangeRate; - } - - /** - * Retrieve formatted reference type. - * @return {string} - */ - get referenceTypeFormatted() { - return getTransactionTypeLabel(this.referenceType, this.transactionType); - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters accounts by the given ids. - * @param {Query} query - * @param {number[]} accountsIds - */ - filterAccounts(query, accountsIds) { - if (Array.isArray(accountsIds) && accountsIds.length > 0) { - query.whereIn('account_id', accountsIds); - } - }, - filterTransactionTypes(query, types) { - if (Array.isArray(types) && types.length > 0) { - query.whereIn('reference_type', types); - } else if (typeof types === 'string') { - query.where('reference_type', types); - } - }, - filterDateRange(query, startDate, endDate, type = 'day') { - const dateFormat = 'YYYY-MM-DD'; - const fromDate = moment(startDate).startOf(type).format(dateFormat); - const toDate = moment(endDate).endOf(type).format(dateFormat); - - if (startDate) { - query.where('date', '>=', fromDate); - } - if (endDate) { - query.where('date', '<=', toDate); - } - }, - filterAmountRange(query, fromAmount, toAmount) { - if (fromAmount) { - query.andWhere((q) => { - q.where('credit', '>=', fromAmount); - q.orWhere('debit', '>=', fromAmount); - }); - } - if (toAmount) { - query.andWhere((q) => { - q.where('credit', '<=', toAmount); - q.orWhere('debit', '<=', toAmount); - }); - } - }, - sumationCreditDebit(query) { - query.select(['accountId']); - - query.sum('credit as credit'); - query.sum('debit as debit'); - query.groupBy('account_id'); - }, - filterContactType(query, contactType) { - query.where('contact_type', contactType); - }, - filterContactIds(query, contactIds) { - query.whereIn('contact_id', contactIds); - }, - openingBalance(query, fromDate) { - query.modify('filterDateRange', null, fromDate); - query.modify('sumationCreditDebit'); - }, - closingBalance(query, toDate) { - query.modify('filterDateRange', null, toDate); - query.modify('sumationCreditDebit'); - }, - contactsOpeningBalance( - query, - openingDate, - receivableAccounts, - customersIds - ) { - // Filter by date. - query.modify('filterDateRange', null, openingDate); - - // Filter by customers. - query.whereNot('contactId', null); - query.whereIn('accountId', castArray(receivableAccounts)); - - if (!isEmpty(customersIds)) { - query.whereIn('contactId', castArray(customersIds)); - } - // Group by the contact transactions. - query.groupBy('contactId'); - query.sum('credit as credit'); - query.sum('debit as debit'); - query.select('contactId'); - }, - creditDebitSummation(query) { - query.sum('credit as credit'); - query.sum('debit as debit'); - }, - groupByDateFormat(query, groupType = 'month') { - const groupBy = { - day: '%Y-%m-%d', - month: '%Y-%m', - year: '%Y', - }; - const dateFormat = groupBy[groupType]; - - query.select(raw(`DATE_FORMAT(DATE, '${dateFormat}')`).as('date')); - query.groupByRaw(`DATE_FORMAT(DATE, '${dateFormat}')`); - }, - - filterByBranches(query, branchesIds) { - const formattedBranchesIds = castArray(branchesIds); - - query.whereIn('branchId', formattedBranchesIds); - }, - - filterByProjects(query, projectsIds) { - const formattedProjectsIds = castArray(projectsIds); - - query.whereIn('projectId', formattedProjectsIds); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - const Contact = require('models/Contact'); - - return { - account: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'accounts_transactions.accountId', - to: 'accounts.id', - }, - }, - contact: { - relation: Model.BelongsToOneRelation, - modelClass: Contact.default, - join: { - from: 'accounts_transactions.contactId', - to: 'contacts.id', - }, - }, - }; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/Auth.ts b/packages/server/src/models/Auth.ts deleted file mode 100644 index 93dc11103..000000000 --- a/packages/server/src/models/Auth.ts +++ /dev/null @@ -1,38 +0,0 @@ - -export default class Auth { - /** - * Retrieve the authenticated user. - */ - static get user() { - return null; - } - - /** - * Sets the authenticated user. - * @param {User} user - */ - static setAuthenticatedUser(user) { - this.user = user; - } - - /** - * Retrieve the authenticated user ID. - */ - static userId() { - if (!this.user) { - return false; - } - return this.user.id; - } - - /** - * Whether the user is logged or not. - */ - static isLogged() { - return !!this.user; - } - - static loggedOut() { - this.user = null; - } -} diff --git a/packages/server/src/models/BankRule.ts b/packages/server/src/models/BankRule.ts deleted file mode 100644 index 051a0f226..000000000 --- a/packages/server/src/models/BankRule.ts +++ /dev/null @@ -1,70 +0,0 @@ -import TenantModel from 'models/TenantModel'; -import { Model } from 'objection'; - -export class BankRule extends TenantModel { - id!: number; - name!: string; - order!: number; - applyIfAccountId!: number; - applyIfTransactionType!: string; - assignCategory!: string; - assignAccountId!: number; - assignPayee!: string; - assignMemo!: string; - conditionsType!: string; - - /** - * Table name - */ - static get tableName() { - return 'bank_rules'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const { BankRuleCondition } = require('models/BankRuleCondition'); - const Account = require('models/Account'); - - return { - /** - * Sale invoice associated entries. - */ - conditions: { - relation: Model.HasManyRelation, - modelClass: BankRuleCondition, - join: { - from: 'bank_rules.id', - to: 'bank_rule_conditions.ruleId', - }, - }, - - /** - * Bank rule may associated to the assign account. - */ - assignAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'bank_rules.assignAccountId', - to: 'accounts.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/BankRuleCondition.ts b/packages/server/src/models/BankRuleCondition.ts deleted file mode 100644 index ff0fa7a06..000000000 --- a/packages/server/src/models/BankRuleCondition.ts +++ /dev/null @@ -1,24 +0,0 @@ -import TenantModel from 'models/TenantModel'; - -export class BankRuleCondition extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'bank_rule_conditions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } -} diff --git a/packages/server/src/models/Bill.Settings.ts b/packages/server/src/models/Bill.Settings.ts deleted file mode 100644 index f8464fefa..000000000 --- a/packages/server/src/models/Bill.Settings.ts +++ /dev/null @@ -1,286 +0,0 @@ -import { Features } from '@/interfaces'; - -export default { - defaultFilterField: 'vendor', - defaultSort: { - sortOrder: 'DESC', - sortField: 'bill_date', - }, - importable: true, - exportFlattenOn: 'entries', - exportable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'billNumber', - print: { - pageTitle: 'Bills', - }, - fields: { - vendor: { - name: 'bill.field.vendor', - column: 'vendor_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'vendor', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - bill_number: { - name: 'bill.field.bill_number', - column: 'bill_number', - columnable: true, - fieldType: 'text', - }, - bill_date: { - name: 'bill.field.bill_date', - column: 'bill_date', - columnable: true, - fieldType: 'date', - }, - due_date: { - name: 'bill.field.due_date', - column: 'due_date', - columnable: true, - fieldType: 'date', - }, - reference_no: { - name: 'bill.field.reference_no', - column: 'reference_no', - columnable: true, - fieldType: 'text', - }, - status: { - name: 'bill.field.status', - fieldType: 'enumeration', - columnable: true, - options: [ - { label: 'bill.field.status.paid', key: 'paid' }, - { label: 'bill.field.status.partially-paid', key: 'partially-paid' }, - { label: 'bill.field.status.overdue', key: 'overdue' }, - { label: 'bill.field.status.unpaid', key: 'unpaid' }, - { label: 'bill.field.status.opened', key: 'opened' }, - { label: 'bill.field.status.draft', key: 'draft' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - amount: { - name: 'bill.field.amount', - column: 'amount', - fieldType: 'number', - }, - payment_amount: { - name: 'bill.field.payment_amount', - column: 'payment_amount', - fieldType: 'number', - }, - note: { - name: 'bill.field.note', - column: 'note', - fieldType: 'text', - }, - created_at: { - name: 'bill.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - billDate: { - name: 'Date', - accessor: 'formattedBillDate', - }, - billNumber: { - name: 'Bill No.', - type: 'text', - }, - referenceNo: { - name: 'Reference No.', - type: 'text', - }, - dueDate: { - name: 'Due Date', - type: 'date', - accessor: 'formattedDueDate', - }, - vendorId: { - name: 'Vendor', - accessor: 'vendor.displayName', - type: 'text', - }, - amount: { - name: 'Amount', - accessor: 'formattedAmount', - }, - exchangeRate: { - name: 'Exchange Rate', - type: 'number', - printable: false, - }, - currencyCode: { - name: 'Currency Code', - type: 'text', - printable: false, - }, - dueAmount: { - name: 'Due Amount', - accessor: 'formattedDueAmount', - }, - paidAmount: { - name: 'Paid Amount', - accessor: 'formattedPaymentAmount', - }, - note: { - name: 'Note', - type: 'text', - printable: false, - }, - open: { - name: 'Open', - type: 'boolean', - printable: false, - }, - entries: { - name: 'Entries', - accessor: 'entries', - type: 'collection', - collectionOf: 'object', - columns: { - itemName: { - name: 'Item Name', - accessor: 'item.name', - }, - rate: { - name: 'Item Rate', - accessor: 'rateFormatted', - }, - quantity: { - name: 'Item Quantity', - accessor: 'quantityFormatted', - }, - description: { - name: 'Item Description', - }, - amount: { - name: 'Item Amount', - accessor: 'totalFormatted', - }, - }, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - warehouse: { - name: 'Warehouse', - type: 'text', - accessor: 'warehouse.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - billNumber: { - name: 'Bill No.', - fieldType: 'text', - required: true, - }, - referenceNo: { - name: 'Reference No.', - fieldType: 'text', - }, - billDate: { - name: 'Date', - fieldType: 'date', - required: true, - }, - dueDate: { - name: 'Due Date', - fieldType: 'date', - required: true, - }, - vendorId: { - name: 'Vendor', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: 'displayName', - required: true, - }, - exchangeRate: { - name: 'Exchange Rate', - fieldType: 'number', - }, - note: { - name: 'Note', - fieldType: 'text', - }, - open: { - name: 'Open', - fieldType: 'boolean', - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - itemId: { - name: 'Item', - fieldType: 'relation', - relationModel: 'Item', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the item name or code.', - }, - rate: { - name: 'Rate', - fieldType: 'number', - required: true, - }, - quantity: { - name: 'Quantity', - fieldType: 'number', - required: true, - }, - description: { - name: 'Line Description', - fieldType: 'text', - }, - }, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - warehouseId: { - name: 'Warehouse', - fieldType: 'relation', - relationModel: 'Warehouse', - relationImportMatch: ['name', 'code'], - features: [Features.WAREHOUSES], - required: true, - }, - }, -}; - -/** - * Status field filter custom query. - */ -function StatusFieldFilterQuery(query, role) { - query.modify('statusFilter', role.value); -} - -/** - * Status field sort custom query. - */ -function StatusFieldSortQuery(query, role) { - query.modify('sortByStatus', role.order); -} diff --git a/packages/server/src/models/Bill.ts b/packages/server/src/models/Bill.ts deleted file mode 100644 index e813ac52e..000000000 --- a/packages/server/src/models/Bill.ts +++ /dev/null @@ -1,625 +0,0 @@ -import { Model, raw, mixin } from 'objection'; -import { castArray, defaultTo, difference } from 'lodash'; -import moment from 'moment'; -import * as R from 'ramda'; -import TenantModel from 'models/TenantModel'; -import BillSettings from './Bill.Settings'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Purchases/Bills/constants'; -import ModelSearchable from './ModelSearchable'; -import { DiscountType } from '@/interfaces'; - -export default class Bill extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - public amount: number; - public paymentAmount: number; - public landedCostAmount: number; - public allocatedCostAmount: number; - public isInclusiveTax: boolean; - public taxAmountWithheld: number; - public exchangeRate: number; - - public discount: number; - public discountType: DiscountType; - - public adjustment: number; - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'balance', - 'dueAmount', - 'isOpen', - 'isPartiallyPaid', - 'isFullyPaid', - 'isPaid', - 'remainingDays', - 'overdueDays', - 'isOverdue', - 'unallocatedCostAmount', - 'localAmount', - 'localAllocatedCostAmount', - 'billableAmount', - 'amountLocal', - - 'discountAmount', - 'discountAmountLocal', - 'discountPercentage', - - 'adjustmentLocal', - - 'subtotal', - 'subtotalLocal', - 'subtotalExludingTax', - 'taxAmountWithheldLocal', - 'total', - 'totalLocal', - ]; - } - - /** - * Invoice amount in base currency. - * @returns {number} - */ - get amountLocal() { - return this.amount * this.exchangeRate; - } - - /** - * Subtotal. (Tax inclusive) if the tax inclusive is enabled. - * @returns {number} - */ - get subtotal() { - return this.amount; - } - - /** - * Subtotal in base currency. (Tax inclusive) if the tax inclusive is enabled. - * @returns {number} - */ - get subtotalLocal() { - return this.amountLocal; - } - - /** - * Sale invoice amount excluding tax. - * @returns {number} - */ - get subtotalExcludingTax() { - return this.isInclusiveTax - ? this.subtotal - this.taxAmountWithheld - : this.subtotal; - } - - /** - * Tax amount withheld in base currency. - * @returns {number} - */ - get taxAmountWithheldLocal() { - return this.taxAmountWithheld * this.exchangeRate; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Amount - ? this.discount - : this.subtotal * (this.discount / 100); - } - - /** - * Discount amount in local currency. - * @returns {number | null} - */ - get discountAmountLocal() { - return this.discountAmount ? this.discountAmount * this.exchangeRate : null; - } - - /** - /** - * Discount percentage. - * @returns {number | null} - */ - get discountPercentage(): number | null { - return this.discountType === DiscountType.Percentage ? this.discount : null; - } - - /** - * Adjustment amount in local currency. - * @returns {number | null} - */ - get adjustmentLocal() { - return this.adjustment ? this.adjustment * this.exchangeRate : null; - } - - /** - * Invoice total. (Tax included) - * @returns {number} - */ - get total() { - const adjustmentAmount = defaultTo(this.adjustment, 0); - - return R.compose( - R.add(adjustmentAmount), - R.subtract(R.__, this.discountAmount), - R.when(R.always(this.isInclusiveTax), R.add(this.taxAmountWithheld)) - )(this.subtotal); - } - - /** - * Invoice total in local currency. (Tax included) - * @returns {number} - */ - get totalLocal() { - return this.total * this.exchangeRate; - } - - /** - * Table name - */ - static get tableName() { - return 'bills'; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the bills in draft status. - */ - draft(query) { - query.where('opened_at', null); - }, - - /** - * Filters the opened bills. - */ - published(query) { - query.whereNot('openedAt', null); - }, - - /** - * Filters the opened bills. - */ - opened(query) { - query.whereNot('opened_at', null); - }, - /** - * Filters the unpaid bills. - */ - unpaid(query) { - query.where('payment_amount', 0); - }, - /** - * Filters the due bills. - */ - dueBills(query) { - query.where( - raw(`COALESCE(AMOUNT, 0) - - COALESCE(PAYMENT_AMOUNT, 0) - - COALESCE(CREDITED_AMOUNT, 0) > 0 - `) - ); - }, - /** - * Filters the overdue bills. - */ - overdue(query) { - query.where('due_date', '<', moment().format('YYYY-MM-DD')); - }, - /** - * Filters the not overdue invoices. - */ - notOverdue(query, asDate = moment().format('YYYY-MM-DD')) { - query.where('due_date', '>=', asDate); - }, - /** - * Filters the partially paid bills. - */ - partiallyPaid(query) { - query.whereNot('payment_amount', 0); - query.whereNot(raw('`PAYMENT_AMOUNT` = `AMOUNT`')); - }, - /** - * Filters the paid bills. - */ - paid(query) { - query.where(raw('`PAYMENT_AMOUNT` = `AMOUNT`')); - }, - /** - * Filters the bills from the given date. - */ - fromDate(query, fromDate) { - query.where('bill_date', '<=', fromDate); - }, - - /** - * Sort the bills by full-payment bills. - */ - sortByStatus(query, order) { - query.orderByRaw(`PAYMENT_AMOUNT = AMOUNT ${order}`); - }, - - /** - * Status filter. - */ - statusFilter(query, filterType) { - switch (filterType) { - case 'draft': - query.modify('draft'); - break; - case 'delivered': - query.modify('delivered'); - break; - case 'unpaid': - query.modify('unpaid'); - break; - case 'overdue': - default: - query.modify('overdue'); - break; - case 'partially-paid': - query.modify('partiallyPaid'); - break; - case 'paid': - query.modify('paid'); - break; - } - }, - - /** - * Filters by branches. - */ - filterByBranches(query, branchesIds) { - const formattedBranchesIds = castArray(branchesIds); - - query.whereIn('branchId', formattedBranchesIds); - }, - - dueBillsFromDate(query, asDate = moment().format('YYYY-MM-DD')) { - query.modify('dueBills'); - query.modify('notOverdue'); - query.modify('fromDate', asDate); - }, - - overdueBillsFromDate(query, asDate = moment().format('YYYY-MM-DD')) { - query.modify('dueBills'); - query.modify('overdue', asDate); - query.modify('fromDate', asDate); - }, - - /** - * - */ - billable(query) { - query.where(raw('AMOUNT > INVOICED_AMOUNT')); - }, - }; - } - - /** - * Invoice amount in organization base currency. - * @deprecated - * @returns {number} - */ - get localAmount() { - return this.amountLocal; - } - - /** - * Retrieves the local allocated cost amount. - * @returns {number} - */ - get localAllocatedCostAmount() { - return this.allocatedCostAmount * this.exchangeRate; - } - - /** - * Retrieves the local landed cost amount. - * @returns {number} - */ - get localLandedCostAmount() { - return this.landedCostAmount * this.exchangeRate; - } - - /** - * Retrieves the local unallocated cost amount. - * @returns {number} - */ - get localUnallocatedCostAmount() { - return this.unallocatedCostAmount * this.exchangeRate; - } - - /** - * Retrieve the balance of bill. - * @return {number} - */ - get balance() { - return this.paymentAmount + this.creditedAmount; - } - - /** - * Due amount of the given. - * @return {number} - */ - get dueAmount() { - return Math.max(this.total - this.balance, 0); - } - - /** - * Detarmine whether the bill is open. - * @return {boolean} - */ - get isOpen() { - return !!this.openedAt; - } - - /** - * Deetarmine whether the bill paid partially. - * @return {boolean} - */ - get isPartiallyPaid() { - return this.dueAmount !== this.total && this.dueAmount > 0; - } - - /** - * Deetarmine whether the bill paid fully. - * @return {boolean} - */ - get isFullyPaid() { - return this.dueAmount === 0; - } - - /** - * Detarmines whether the bill paid fully or partially. - * @return {boolean} - */ - get isPaid() { - return this.isPartiallyPaid || this.isFullyPaid; - } - - /** - * Retrieve the remaining days in number - * @return {number|null} - */ - get remainingDays() { - const currentMoment = moment(); - const dueDateMoment = moment(this.dueDate); - - return Math.max(dueDateMoment.diff(currentMoment, 'days'), 0); - } - - /** - * Retrieve the overdue days in number. - * @return {number|null} - */ - get overdueDays() { - const currentMoment = moment(); - const dueDateMoment = moment(this.dueDate); - - return Math.max(currentMoment.diff(dueDateMoment, 'days'), 0); - } - - /** - * Detarmines the due date is over. - * @return {boolean} - */ - get isOverdue() { - return this.overdueDays > 0; - } - - /** - * Retrieve the unallocated cost amount. - * @return {number} - */ - get unallocatedCostAmount() { - return Math.max(this.landedCostAmount - this.allocatedCostAmount, 0); - } - - /** - * Retrieves the calculated amount which have not been invoiced. - */ - get billableAmount() { - return Math.max(this.total - this.invoicedAmount, 0); - } - - /** - * Bill model settings. - */ - static get meta() { - return BillSettings; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Vendor = require('models/Vendor'); - const ItemEntry = require('models/ItemEntry'); - const BillLandedCost = require('models/BillLandedCost'); - const Branch = require('models/Branch'); - const Warehouse = require('models/Warehouse'); - const TaxRateTransaction = require('models/TaxRateTransaction'); - const Document = require('models/Document'); - const { MatchedBankTransaction } = require('models/MatchedBankTransaction'); - - return { - vendor: { - relation: Model.BelongsToOneRelation, - modelClass: Vendor.default, - join: { - from: 'bills.vendorId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'vendor'); - }, - }, - - entries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'bills.id', - to: 'items_entries.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'Bill'); - builder.orderBy('index', 'ASC'); - }, - }, - - locatedLandedCosts: { - relation: Model.HasManyRelation, - modelClass: BillLandedCost.default, - join: { - from: 'bills.id', - to: 'bill_located_costs.billId', - }, - }, - - /** - * Bill may belongs to associated branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'bills.branchId', - to: 'branches.id', - }, - }, - - /** - * Bill may has associated warehouse. - */ - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'bills.warehouseId', - to: 'warehouses.id', - }, - }, - - /** - * Bill may has associated tax rate transactions. - */ - taxes: { - relation: Model.HasManyRelation, - modelClass: TaxRateTransaction.default, - join: { - from: 'bills.id', - to: 'tax_rate_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'Bill'); - }, - }, - - /** - * Bill may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'bills.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'Bill'); - }, - }, - - /** - * Bill may belongs to matched bank transaction. - */ - matchedBankTransaction: { - relation: Model.HasManyRelation, - modelClass: MatchedBankTransaction, - join: { - from: 'bills.id', - to: 'matched_bank_transactions.referenceId', - }, - filter(query) { - query.where('reference_type', 'Bill'); - }, - }, - }; - } - - /** - * Retrieve the not found bills ids as array that associated to the given vendor. - * @param {Array} billsIds - * @param {number} vendorId - - * @return {Array} - */ - static async getNotFoundBills(billsIds, vendorId) { - const storedBills = await this.query().onBuild((builder) => { - builder.whereIn('id', billsIds); - - if (vendorId) { - builder.where('vendor_id', vendorId); - } - }); - - const storedBillsIds = storedBills.map((t) => t.id); - - const notFoundBillsIds = difference(billsIds, storedBillsIds); - return notFoundBillsIds; - } - - static changePaymentAmount(billId, amount, trx) { - const changeMethod = amount > 0 ? 'increment' : 'decrement'; - return this.query(trx) - .where('id', billId) - [changeMethod]('payment_amount', Math.abs(amount)); - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'bill_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/BillLandedCost.ts b/packages/server/src/models/BillLandedCost.ts deleted file mode 100644 index cc06b4f3c..000000000 --- a/packages/server/src/models/BillLandedCost.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Model } from 'objection'; -import { lowerCase } from 'lodash'; -import TenantModel from 'models/TenantModel'; - -export default class BillLandedCost extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'bill_located_costs'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['localAmount', 'allocationMethodFormatted']; - } - - /** - * Retrieves the cost local amount. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Allocation method formatted. - */ - get allocationMethodFormatted() { - const allocationMethod = lowerCase(this.allocationMethod); - - const keyLabelsPairs = { - value: 'allocation_method.value.label', - quantity: 'allocation_method.quantity.label', - }; - return keyLabelsPairs[allocationMethod] || ''; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const BillLandedCostEntry = require('models/BillLandedCostEntry'); - const Bill = require('models/Bill'); - const ItemEntry = require('models/ItemEntry'); - const ExpenseCategory = require('models/ExpenseCategory'); - - return { - bill: { - relation: Model.BelongsToOneRelation, - modelClass: Bill.default, - join: { - from: 'bill_located_costs.billId', - to: 'bills.id', - }, - }, - allocateEntries: { - relation: Model.HasManyRelation, - modelClass: BillLandedCostEntry.default, - join: { - from: 'bill_located_costs.id', - to: 'bill_located_cost_entries.billLocatedCostId', - }, - }, - allocatedFromBillEntry: { - relation: Model.BelongsToOneRelation, - modelClass: ItemEntry.default, - join: { - from: 'bill_located_costs.fromTransactionEntryId', - to: 'items_entries.id', - }, - }, - allocatedFromExpenseEntry: { - relation: Model.BelongsToOneRelation, - modelClass: ExpenseCategory.default, - join: { - from: 'bill_located_costs.fromTransactionEntryId', - to: 'expense_transaction_categories.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/BillLandedCostEntry.ts b/packages/server/src/models/BillLandedCostEntry.ts deleted file mode 100644 index 049bef1c5..000000000 --- a/packages/server/src/models/BillLandedCostEntry.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class BillLandedCostEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'bill_located_cost_entries'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const ItemEntry = require('models/ItemEntry'); - - return { - itemEntry: { - relation: Model.BelongsToOneRelation, - modelClass: ItemEntry.default, - join: { - from: 'bill_located_cost_entries.entryId', - to: 'items_entries.id', - }, - filter(builder) { - builder.where('reference_type', 'Bill'); - }, - }, - }; - } -} diff --git a/packages/server/src/models/BillPayment.Settings.ts b/packages/server/src/models/BillPayment.Settings.ts deleted file mode 100644 index fe456e981..000000000 --- a/packages/server/src/models/BillPayment.Settings.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { Features } from '@/interfaces'; - -export default { - defaultFilterField: 'vendor', - defaultSort: { - sortOrder: 'DESC', - sortField: 'bill_date', - }, - exportable: true, - exportFlattenOn: 'entries', - - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'paymentNumber', - fields: { - vendor: { - name: 'bill_payment.field.vendor', - column: 'vendor_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'vendor', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - amount: { - name: 'bill_payment.field.amount', - column: 'amount', - fieldType: 'number', - }, - due_amount: { - name: 'bill_payment.field.due_amount', - column: 'due_amount', - fieldType: 'number', - }, - payment_account: { - name: 'bill_payment.field.payment_account', - column: 'payment_account_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'paymentAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - payment_number: { - name: 'bill_payment.field.payment_number', - column: 'payment_number', - fieldType: 'text', - }, - payment_date: { - name: 'bill_payment.field.payment_date', - column: 'payment_date', - fieldType: 'date', - }, - reference_no: { - name: 'bill_payment.field.reference_no', - column: 'reference', - fieldType: 'text', - }, - description: { - name: 'bill_payment.field.description', - column: 'description', - fieldType: 'text', - }, - created_at: { - name: 'bill_payment.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - vendor: { - name: 'bill_payment.field.vendor', - type: 'relation', - accessor: 'vendor.displayName', - }, - paymentDate: { - name: 'bill_payment.field.payment_date', - type: 'date', - accessor: 'formattedPaymentDate', - }, - paymentNumber: { - name: 'bill_payment.field.payment_number', - type: 'text', - }, - paymentAccount: { - name: 'bill_payment.field.payment_account', - accessor: 'paymentAccount.name', - type: 'text', - }, - amount: { - name: 'Amount', - accessor: 'formattedAmount', - }, - currencyCode: { - name: 'Currency Code', - type: 'text', - printable: false, - }, - exchangeRate: { - name: 'bill_payment.field.exchange_rate', - type: 'number', - printable: false, - }, - statement: { - name: 'bill_payment.field.note', - type: 'text', - printable: false, - }, - reference: { - name: 'bill_payment.field.reference', - type: 'text', - }, - entries: { - name: 'Entries', - accessor: 'entries', - type: 'collection', - collectionOf: 'object', - columns: { - date: { - name: 'Bill date', - accessor: 'bill.formattedBillDate', - }, - billNo: { - name: 'Bill No.', - accessor: 'bill.billNo', - }, - billRefNo: { - name: 'Bill Reference No.', - accessor: 'bill.referenceNo', - }, - billAmount: { - name: 'Bill Amount', - accessor: 'bill.totalFormatted', - }, - paidAmount: { - name: 'Paid Amount', - accessor: 'paymentAmountFormatted', - }, - }, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - vendorId: { - name: 'bill_payment.field.vendor', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: ['displayName'], - required: true, - }, - payment_date: { - name: 'bill_payment.field.payment_date', - fieldType: 'date', - required: true, - }, - paymentNumber: { - name: 'bill_payment.field.payment_number', - fieldType: 'text', - unique: true, - importHint: 'The payment number should be unique.', - }, - paymentAccountId: { - name: 'bill_payment.field.payment_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the account name or code.', - }, - exchangeRate: { - name: 'bill_payment.field.exchange_rate', - fieldType: 'number', - }, - statement: { - name: 'bill_payment.field.note', - fieldType: 'text', - }, - reference: { - name: 'bill_payment.field.reference', - fieldType: 'text', - }, - entries: { - name: 'bill_payment.field.entries', - column: 'entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - billId: { - name: 'bill_payment.field.entries.bill', - fieldType: 'relation', - relationModel: 'Bill', - relationImportMatch: 'billNumber', - required: true, - importHint: 'Matches the bill number.', - }, - paymentAmount: { - name: 'bill_payment.field.entries.payment_amount', - fieldType: 'number', - required: true, - }, - }, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - }, -}; diff --git a/packages/server/src/models/BillPayment.ts b/packages/server/src/models/BillPayment.ts deleted file mode 100644 index fa20f8bde..000000000 --- a/packages/server/src/models/BillPayment.ts +++ /dev/null @@ -1,170 +0,0 @@ -import ModelBase from './Model'; -import BillPaymentSettings from './BillPayment.Settings'; -import { DEFAULT_VIEWS } from '@/services/Sales/PaymentReceived/constants'; - -export class BillPayment extends ModelBase { - vendorId: number; - amount: number; - currencyCode: string; - reference: string; - paymentAccountId: number; - paymentNumber: string; - paymentDate: Date; - exchangeRate: number | null; - userId: number; - statement: string; - - createdAt: Date; - updatedAt: Date; - - /** - * Table name - */ - static get tableName() { - return 'bills_payments'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['localAmount']; - } - - /** - * Payment amount in local currency. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Model settings. - */ - static get meta() { - return BillPaymentSettings; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const BillPaymentEntry = require('models/BillPaymentEntry'); - const AccountTransaction = require('models/AccountTransaction'); - const Vendor = require('models/Vendor'); - const Account = require('models/Account'); - const Branch = require('models/Branch'); - const Document = require('models/Document'); - - return { - entries: { - relation: Model.HasManyRelation, - modelClass: BillPaymentEntry.default, - join: { - from: 'bills_payments.id', - to: 'bills_payments_entries.billPaymentId', - }, - filter: (query) => { - query.orderBy('index', 'ASC'); - }, - }, - - vendor: { - relation: Model.BelongsToOneRelation, - modelClass: Vendor.default, - join: { - from: 'bills_payments.vendorId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'vendor'); - }, - }, - - paymentAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'bills_payments.paymentAccountId', - to: 'accounts.id', - }, - }, - - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'bills_payments.id', - to: 'accounts_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'BillPayment'); - }, - }, - - /** - * Bill payment may belongs to branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'bills_payments.branchId', - to: 'branches.id', - }, - }, - - /** - * Bill payment may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'bills_payments.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'BillPayment'); - }, - }, - }; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'payment_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/BillPaymentEntry.ts b/packages/server/src/models/BillPaymentEntry.ts deleted file mode 100644 index 4600eebb0..000000000 --- a/packages/server/src/models/BillPaymentEntry.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class BillPaymentEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'bills_payments_entries'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Bill = require('models/Bill'); - const BillPayment = require('models/BillPayment'); - - return { - payment: { - relation: Model.BelongsToOneRelation, - modelClass: BillPayment.default, - join: { - from: 'bills_payments_entries.billPaymentId', - to: 'bills_payments.id', - }, - }, - bill: { - relation: Model.BelongsToOneRelation, - modelClass: Bill.default, - join: { - from: 'bills_payments_entries.billId', - to: 'bills.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/Branch.settings.ts b/packages/server/src/models/Branch.settings.ts deleted file mode 100644 index 921dc5c0a..000000000 --- a/packages/server/src/models/Branch.settings.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default { - fields2: { - name: { - name: 'Name', - fieldType: 'text', - required: true, - }, - }, - columns: {}, - fields: {} -}; diff --git a/packages/server/src/models/Branch.ts b/packages/server/src/models/Branch.ts deleted file mode 100644 index ee143be6f..000000000 --- a/packages/server/src/models/Branch.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import BranchMetadata from './Branch.settings'; -import ModelSetting from './ModelSetting'; - -export default class Branch extends mixin(TenantModel, [ModelSetting]) { - /** - * Table name. - */ - static get tableName() { - return 'branches'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters accounts by the given ids. - * @param {Query} query - * @param {number[]} accountsIds - */ - isPrimary(query) { - query.where('primary', true); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleInvoice = require('models/SaleInvoice'); - const SaleEstimate = require('models/SaleEstimate'); - const SaleReceipt = require('models/SaleReceipt'); - const Bill = require('models/Bill'); - const PaymentReceive = require('models/PaymentReceive'); - const PaymentMade = require('models/BillPayment'); - const VendorCredit = require('models/VendorCredit'); - const CreditNote = require('models/CreditNote'); - const AccountTransaction = require('models/AccountTransaction'); - const InventoryTransaction = require('models/InventoryTransaction'); - - return { - /** - * Branch may belongs to associated sale invoices. - */ - invoices: { - relation: Model.HasManyRelation, - modelClass: SaleInvoice.default, - join: { - from: 'branches.id', - to: 'sales_invoices.branchId', - }, - }, - - /** - * Branch may belongs to associated sale estimates. - */ - estimates: { - relation: Model.HasManyRelation, - modelClass: SaleEstimate.default, - join: { - from: 'branches.id', - to: 'sales_estimates.branchId', - }, - }, - - /** - * Branch may belongs to associated sale receipts. - */ - receipts: { - relation: Model.HasManyRelation, - modelClass: SaleReceipt.default, - join: { - from: 'branches.id', - to: 'sales_receipts.branchId', - }, - }, - - /** - * Branch may belongs to associated payment receives. - */ - paymentReceives: { - relation: Model.HasManyRelation, - modelClass: PaymentReceive.default, - join: { - from: 'branches.id', - to: 'payment_receives.branchId', - }, - }, - - /** - * Branch may belongs to associated bills. - */ - bills: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'branches.id', - to: 'bills.branchId', - }, - }, - - /** - * Branch may belongs to associated payment mades. - */ - paymentMades: { - relation: Model.HasManyRelation, - modelClass: PaymentMade.default, - join: { - from: 'branches.id', - to: 'bills_payments.branchId', - }, - }, - - /** - * Branch may belongs to associated credit notes. - */ - creditNotes: { - relation: Model.HasManyRelation, - modelClass: CreditNote.default, - join: { - from: 'branches.id', - to: 'credit_notes.branchId', - }, - }, - - /** - * Branch may belongs to associated to vendor credits. - */ - vendorCredit: { - relation: Model.HasManyRelation, - modelClass: VendorCredit.default, - join: { - from: 'branches.id', - to: 'vendor_credits.branchId', - }, - }, - - /** - * Branch may belongs to associated to accounts transactions. - */ - accountsTransactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'branches.id', - to: 'accounts_transactions.branchId', - }, - }, - - /** - * Branch may belongs to associated to inventory transactions. - */ - inventoryTransactions: { - relation: Model.HasManyRelation, - modelClass: InventoryTransaction.default, - join: { - from: 'branches.id', - to: 'inventory_transactions.branchId', - }, - }, - }; - } - - /** - * Model settings. - */ - static get meta() { - return BranchMetadata; - } -} diff --git a/packages/server/src/models/CashflowAccount.Settings.ts b/packages/server/src/models/CashflowAccount.Settings.ts deleted file mode 100644 index 453f2dbbf..000000000 --- a/packages/server/src/models/CashflowAccount.Settings.ts +++ /dev/null @@ -1,54 +0,0 @@ - -export default { - defaultFilterField: 'name', - defaultSort: { - sortOrder: 'DESC', - sortField: 'name', - }, - fields: { - name: { - name: 'account.field.name', - column: 'name', - fieldType: 'text', - }, - description: { - name: 'account.field.description', - column: 'description', - fieldType: 'text', - }, - slug: { - name: 'account.field.slug', - column: 'slug', - fieldType: 'text', - columnable: false, - filterable: false, - }, - code: { - name: 'account.field.code', - column: 'code', - fieldType: 'text', - }, - active: { - name: 'account.field.active', - column: 'active', - fieldType: 'boolean', - filterable: false, - }, - balance: { - name: 'account.field.balance', - column: 'amount', - fieldType: 'number', - }, - currency: { - name: 'account.field.currency', - column: 'currency_code', - fieldType: 'text', - filterable: false, - }, - created_at: { - name: 'account.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, -}; \ No newline at end of file diff --git a/packages/server/src/models/CashflowAccount.ts b/packages/server/src/models/CashflowAccount.ts deleted file mode 100644 index 132832bca..000000000 --- a/packages/server/src/models/CashflowAccount.ts +++ /dev/null @@ -1,132 +0,0 @@ -/* eslint-disable global-require */ -import { mixin, Model } from 'objection'; -import { castArray } from 'lodash'; -import TenantModel from 'models/TenantModel'; -import AccountTypesUtils from '@/lib/AccountTypes'; -import CashflowAccountSettings from './CashflowAccount.Settings'; -import ModelSettings from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Accounts/constants'; -import ModelSearchable from './ModelSearchable'; - -export default class CashflowAccount extends mixin(TenantModel, [ - ModelSettings, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name. - */ - static get tableName() { - return 'accounts'; - } - - /** - * Timestamps columns. - */ - static get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['accountTypeLabel']; - } - - /** - * Retrieve account type label. - */ - get accountTypeLabel() { - return AccountTypesUtils.getType(this.accountType, 'label'); - } - - /** - * Allows to mark model as resourceable to viewable and filterable. - */ - static get resourceable() { - return true; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Inactive/Active mode. - */ - inactiveMode(query, active = false) { - query.where('accounts.active', !active); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const AccountTransaction = require('models/AccountTransaction'); - - return { - /** - * Account model may has many transactions. - */ - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'accounts.id', - to: 'accounts_transactions.accountId', - }, - }, - }; - } - - /** - * Detarmines whether the given type equals the account type. - * @param {string} accountType - * @return {boolean} - */ - isAccountType(accountType) { - const types = castArray(accountType); - return types.indexOf(this.accountType) !== -1; - } - - /** - * Detarmine whether the given parent type equals the account type. - * @param {string} parentType - * @return {boolean} - */ - isParentType(parentType) { - return AccountTypesUtils.isParentTypeEqualsKey( - this.accountType, - parentType - ); - } - - /** - * Model settings. - */ - static get meta() { - return CashflowAccountSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search roles. - */ - static get searchRoles() { - return [ - { condition: 'or', fieldKey: 'name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'code', comparator: 'like' }, - ]; - } -} diff --git a/packages/server/src/models/CashflowTransaction.ts b/packages/server/src/models/CashflowTransaction.ts deleted file mode 100644 index 3e50886f1..000000000 --- a/packages/server/src/models/CashflowTransaction.ts +++ /dev/null @@ -1,207 +0,0 @@ -/* eslint-disable global-require */ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import { - getCashflowAccountTransactionsTypes, - getCashflowTransactionType, -} from '@/services/Cashflow/utils'; -import { CASHFLOW_DIRECTION } from '@/services/Cashflow/constants'; -import { getCashflowTransactionFormattedType } from '@/utils/transactions-types'; - -export default class CashflowTransaction extends TenantModel { - transactionType: string; - amount: number; - exchangeRate: number; - uncategorize: boolean; - uncategorizedTransaction!: boolean; - - /** - * Table name. - */ - static get tableName() { - return 'cashflow_transactions'; - } - - /** - * Timestamps columns. - */ - static get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'localAmount', - 'transactionTypeFormatted', - 'isPublished', - 'typeMeta', - 'isCashCredit', - 'isCashDebit', - ]; - } - - /** - * Retrieves the local amount of cashflow transaction. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Detarmines whether the cashflow transaction is published. - * @return {boolean} - */ - get isPublished() { - return !!this.publishedAt; - } - - /** - * Transaction type formatted. - * @returns {string} - */ - get transactionTypeFormatted() { - return getCashflowTransactionFormattedType(this.transactionType); - } - - get typeMeta() { - return getCashflowTransactionType(this.transactionType); - } - - /** - * Detarmines whether the cashflow transaction cash credit type. - * @returns {boolean} - */ - get isCashCredit() { - return this.typeMeta?.direction === CASHFLOW_DIRECTION.OUT; - } - - /** - * Detarmines whether the cashflow transaction cash debit type. - * @returns {boolean} - */ - get isCashDebit() { - return this.typeMeta?.direction === CASHFLOW_DIRECTION.IN; - } - - /** - * Detarmines whether the transaction imported from uncategorized transaction. - * @returns {boolean} - */ - get isCategroizedTranasction() { - return !!this.uncategorizedTransaction; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filter the published transactions. - */ - published(query) { - query.whereNot('published_at', null); - }, - - /** - * Filter the not categorized transactions. - */ - notCategorized(query) { - query.whereNull('cashflowTransactions.uncategorizedTransactionId'); - }, - - /** - * Filter the categorized transactions. - */ - categorized(query) { - query.whereNotNull('cashflowTransactions.uncategorizedTransactionId'); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const CashflowTransactionLine = require('models/CashflowTransactionLine'); - const AccountTransaction = require('models/AccountTransaction'); - const Account = require('models/Account'); - const { MatchedBankTransaction } = require('models/MatchedBankTransaction'); - - return { - /** - * Cashflow transaction entries. - */ - entries: { - relation: Model.HasManyRelation, - modelClass: CashflowTransactionLine.default, - join: { - from: 'cashflow_transactions.id', - to: 'cashflow_transaction_lines.cashflowTransactionId', - }, - filter: (query) => { - query.orderBy('index', 'ASC'); - }, - }, - - /** - * Cashflow transaction has associated account transactions. - */ - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'cashflow_transactions.id', - to: 'accounts_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'CashflowTransaction'); - }, - }, - - /** - * Cashflow transaction may has associated cashflow account. - */ - cashflowAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'cashflow_transactions.cashflowAccountId', - to: 'accounts.id', - }, - }, - - /** - * Cashflow transcation may has associated to credit account. - */ - creditAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'cashflow_transactions.creditAccountId', - to: 'accounts.id', - }, - }, - - /** - * Cashflow transaction may belongs to matched bank transaction. - */ - matchedBankTransaction: { - relation: Model.HasManyRelation, - modelClass: MatchedBankTransaction, - join: { - from: 'cashflow_transactions.id', - to: 'matched_bank_transactions.referenceId', - }, - filter: (query) => { - const referenceTypes = getCashflowAccountTransactionsTypes(); - query.whereIn('reference_type', referenceTypes); - }, - }, - }; - } -} diff --git a/packages/server/src/models/CashflowTransactionLine.ts b/packages/server/src/models/CashflowTransactionLine.ts deleted file mode 100644 index 4be809cc8..000000000 --- a/packages/server/src/models/CashflowTransactionLine.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable global-require */ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class CashflowTransactionLine extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'cashflow_transaction_lines'; - } - - /** - * Timestamps columns. - */ - static get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - - return { - cashflowAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'cashflow_transaction_lines.cashflowAccountId', - to: 'accounts.id', - }, - }, - creditAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'cashflow_transaction_lines.creditAccountId', - to: 'accounts.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/Contact.ts b/packages/server/src/models/Contact.ts deleted file mode 100644 index 04b17727c..000000000 --- a/packages/server/src/models/Contact.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class Contact extends TenantModel { - email: string; - displayName: string; - - /** - * Table name - */ - static get tableName() { - return 'contacts'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Defined virtual attributes. - */ - static get virtualAttributes() { - return ['contactNormal', 'closingBalance', 'formattedContactService']; - } - - /** - * Retrieve the contact normal by the given contact type. - */ - static getContactNormalByType(contactType) { - const types = { - vendor: 'credit', - customer: 'debit', - }; - return types[contactType]; - } - - /** - * Retrieve the contact normal by the given contact service. - * @param {string} contactService - */ - static getFormattedContactService(contactService) { - const types = { - customer: 'Customer', - vendor: 'Vendor', - }; - return types[contactService]; - } - - /** - * Retrieve the contact normal. - */ - get contactNormal() { - return Contact.getContactNormalByType(this.contactService); - } - - /** - * Retrieve formatted contact service. - */ - get formattedContactService() { - return Contact.getFormattedContactService(this.contactService); - } - - /** - * Closing balance attribute. - */ - get closingBalance() { - return this.balance; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - filterContactIds(query, customerIds) { - query.whereIn('id', customerIds); - }, - - customer(query) { - query.where('contact_service', 'customer'); - }, - - vendor(query) { - query.where('contact_service', 'vendor'); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleEstimate = require('models/SaleEstimate'); - const SaleReceipt = require('models/SaleReceipt'); - const SaleInvoice = require('models/SaleInvoice'); - const PaymentReceive = require('models/PaymentReceive'); - const Bill = require('models/Bill'); - const BillPayment = require('models/BillPayment'); - const AccountTransaction = require('models/AccountTransaction'); - - return { - /** - * Contact may has many sales invoices. - */ - salesInvoices: { - relation: Model.HasManyRelation, - modelClass: SaleInvoice.default, - join: { - from: 'contacts.id', - to: 'sales_invoices.customerId', - }, - }, - - /** - * Contact may has many sales estimates. - */ - salesEstimates: { - relation: Model.HasManyRelation, - modelClass: SaleEstimate.default, - join: { - from: 'contacts.id', - to: 'sales_estimates.customerId', - }, - }, - - /** - * Contact may has many sales receipts. - */ - salesReceipts: { - relation: Model.HasManyRelation, - modelClass: SaleReceipt.default, - join: { - from: 'contacts.id', - to: 'sales_receipts.customerId', - }, - }, - - /** - * Contact may has many payments receives. - */ - paymentReceives: { - relation: Model.HasManyRelation, - modelClass: PaymentReceive.default, - join: { - from: 'contacts.id', - to: 'payment_receives.customerId', - }, - }, - - /** - * Contact may has many bills. - */ - bills: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'contacts.id', - to: 'bills.vendorId', - }, - }, - - /** - * Contact may has many bills payments. - */ - billPayments: { - relation: Model.HasManyRelation, - modelClass: BillPayment.default, - join: { - from: 'contacts.id', - to: 'bills_payments.vendorId', - }, - }, - - /** - * Contact may has many accounts transactions. - */ - accountsTransactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'contacts.id', - to: 'accounts_transactions.contactId', - }, - }, - }; - } -} diff --git a/packages/server/src/models/CreditNote.Meta.ts b/packages/server/src/models/CreditNote.Meta.ts deleted file mode 100644 index ae2dc7750..000000000 --- a/packages/server/src/models/CreditNote.Meta.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { Features } from '@/interfaces'; - -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} - -function StatusFieldSortQuery(query, role) { - query.modify('sortByStatus', role.order); -} - -export default { - defaultFilterField: 'name', - defaultSort: { - sortOrder: 'DESC', - sortField: 'name', - }, - exportable: true, - exportFlattenOn: 'entries', - - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'creditNoteNumber', - - print: { - pageTitle: 'Credit Notes', - }, - - fields: { - customer: { - name: 'credit_note.field.customer', - column: 'customer_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'customer', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - credit_date: { - name: 'credit_note.field.credit_note_date', - column: 'credit_note_date', - fieldType: 'date', - }, - credit_number: { - name: 'credit_note.field.credit_note_number', - column: 'credit_note_number', - fieldType: 'text', - }, - reference_no: { - name: 'credit_note.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - amount: { - name: 'credit_note.field.amount', - column: 'amount', - fieldType: 'number', - }, - currency_code: { - name: 'credit_note.field.currency_code', - column: 'currency_code', - fieldType: 'number', - }, - note: { - name: 'credit_note.field.note', - column: 'note', - fieldType: 'text', - }, - terms_conditions: { - name: 'credit_note.field.terms_conditions', - column: 'terms_conditions', - fieldType: 'text', - }, - status: { - name: 'credit_note.field.status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'credit_note.field.status.draft' }, - { key: 'published', label: 'credit_note.field.status.published' }, - { key: 'open', label: 'credit_note.field.status.open' }, - { key: 'closed', label: 'credit_note.field.status.closed' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - created_at: { - name: 'credit_note.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - customer: { - name: 'Customer', - accessor: 'customer.displayName', - }, - exchangeRate: { - name: 'Exchange Rate', - printable: false, - }, - creditNoteDate: { - name: 'Credit Note Date', - accessor: 'formattedCreditNoteDate', - }, - referenceNo: { - name: 'Reference No.', - }, - note: { - name: 'Note', - }, - termsConditions: { - name: 'Terms & Conditions', - printable: false, - }, - creditNoteNumber: { - name: 'Credit Note Number', - printable: false, - }, - open: { - name: 'Open', - type: 'boolean', - printable: false, - }, - entries: { - name: 'Entries', - type: 'collection', - collectionOf: 'object', - columns: { - itemName: { - name: 'Item Name', - accessor: 'item.name', - }, - rate: { - name: 'Item Rate', - accessor: 'rateFormatted', - }, - quantity: { - name: 'Item Quantity', - accessor: 'quantityFormatted', - }, - description: { - name: 'Item Description', - }, - amount: { - name: 'Item Amount', - accessor: 'totalFormatted', - }, - }, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - warehouse: { - name: 'Warehouse', - type: 'text', - accessor: 'warehouse.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - customerId: { - name: 'Customer', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: 'displayName', - required: true, - }, - exchangeRate: { - name: 'Exchange Rate', - fieldType: 'number', - }, - creditNoteDate: { - name: 'Credit Note Date', - fieldType: 'date', - required: true, - }, - referenceNo: { - name: 'Reference No.', - fieldType: 'text', - }, - note: { - name: 'Note', - fieldType: 'text', - }, - termsConditions: { - name: 'Terms & Conditions', - fieldType: 'text', - }, - creditNoteNumber: { - name: 'Credit Note Number', - fieldType: 'text', - }, - open: { - name: 'Open', - fieldType: 'boolean', - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - fields: { - itemId: { - name: 'Item', - fieldType: 'relation', - relationModel: 'Item', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the item name or code.', - }, - rate: { - name: 'Rate', - fieldType: 'number', - required: true, - }, - quantity: { - name: 'Quantity', - fieldType: 'number', - required: true, - }, - description: { - name: 'Description', - fieldType: 'text', - }, - }, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - warehouseId: { - name: 'Warehouse', - fieldType: 'relation', - relationModel: 'Warehouse', - relationImportMatch: ['name', 'code'], - features: [Features.WAREHOUSES], - required: true, - }, - }, -}; diff --git a/packages/server/src/models/CreditNote.ts b/packages/server/src/models/CreditNote.ts deleted file mode 100644 index ab5f6c878..000000000 --- a/packages/server/src/models/CreditNote.ts +++ /dev/null @@ -1,411 +0,0 @@ -import { mixin, Model, raw } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/CreditNotes/constants'; -import ModelSearchable from './ModelSearchable'; -import CreditNoteMeta from './CreditNote.Meta'; -import { DiscountType } from '@/interfaces'; - -export default class CreditNote extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - public amount: number; - public exchangeRate: number; - public openedAt: Date; - public discount: number; - public discountType: DiscountType; - public adjustment: number; - - /** - * Table name - */ - static get tableName() { - return 'credit_notes'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'localAmount', - 'isDraft', - 'isPublished', - 'isOpen', - 'isClosed', - - 'creditsRemaining', - 'creditsUsed', - - 'subtotal', - 'subtotalLocal', - - 'discountAmount', - 'discountAmountLocal', - 'discountPercentage', - - 'total', - 'totalLocal', - - 'adjustmentLocal', - ]; - } - - /** - * Credit note amount in local currency. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Credit note subtotal. - * @returns {number} - */ - get subtotal() { - return this.amount; - } - - /** - * Credit note subtotal in local currency. - * @returns {number} - */ - get subtotalLocal() { - return this.subtotal * this.exchangeRate; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Amount - ? this.discount - : this.subtotal * (this.discount / 100); - } - - /** - * Discount amount in local currency. - * @returns {number} - */ - get discountAmountLocal() { - return this.discountAmount ? this.discountAmount * this.exchangeRate : null; - } - - /** - * Discount percentage. - * @returns {number | null} - */ - get discountPercentage(): number | null { - return this.discountType === DiscountType.Percentage ? this.discount : null; - } - - /** - * Adjustment amount in local currency. - * @returns {number} - */ - get adjustmentLocal() { - return this.adjustment ? this.adjustment * this.exchangeRate : null; - } - - /** - * Credit note total. - * @returns {number} - */ - get total() { - return this.subtotal - this.discountAmount + this.adjustment; - } - - /** - * Credit note total in local currency. - * @returns {number} - */ - get totalLocal() { - return this.total * this.exchangeRate; - } - - /** - * Detarmines whether the credit note is draft. - * @returns {boolean} - */ - get isDraft() { - return !this.openedAt; - } - - /** - * Detarmines whether vendor credit is published. - * @returns {boolean} - */ - get isPublished() { - return !!this.openedAt; - } - - /** - * Detarmines whether the credit note is open. - * @return {boolean} - */ - get isOpen() { - return !!this.openedAt && this.creditsRemaining > 0; - } - - /** - * Detarmines whether the credit note is closed. - * @return {boolean} - */ - get isClosed() { - return this.openedAt && this.creditsRemaining === 0; - } - - /** - * Retrieve the credits remaining. - */ - get creditsRemaining() { - return Math.max(this.amount - this.refundedAmount - this.invoicesAmount, 0); - } - - get creditsUsed() { - return this.refundedAmount + this.invoicesAmount; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the credit notes in draft status. - */ - draft(query) { - query.where('opened_at', null); - }, - - /** - * Filters the. - */ - published(query) { - query.whereNot('opened_at', null); - }, - - /** - * Filters the open credit notes. - */ - open(query) { - query - .where( - raw(`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) < - COALESCE(AMOUNT)`) - ) - .modify('published'); - }, - - /** - * Filters the closed credit notes. - */ - closed(query) { - query - .where( - raw(`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) = - COALESCE(AMOUNT)`) - ) - .modify('published'); - }, - - /** - * Status filter. - */ - filterByStatus(query, filterType) { - switch (filterType) { - case 'draft': - query.modify('draft'); - break; - case 'published': - query.modify('published'); - break; - case 'open': - default: - query.modify('open'); - break; - case 'closed': - query.modify('closed'); - break; - } - }, - - /** - * - */ - sortByStatus(query, order) { - query.orderByRaw( - `COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) = COALESCE(AMOUNT) ${order}` - ); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const AccountTransaction = require('models/AccountTransaction'); - const ItemEntry = require('models/ItemEntry'); - const Customer = require('models/Customer'); - const Branch = require('models/Branch'); - const Document = require('models/Document'); - const Warehouse = require('models/Warehouse'); - const { PdfTemplate } = require('models/PdfTemplate'); - - return { - /** - * Credit note associated entries. - */ - entries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'credit_notes.id', - to: 'items_entries.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'CreditNote'); - builder.orderBy('index', 'ASC'); - }, - }, - - /** - * Belongs to customer model. - */ - customer: { - relation: Model.BelongsToOneRelation, - modelClass: Customer.default, - join: { - from: 'credit_notes.customerId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'Customer'); - }, - }, - - /** - * Credit note associated GL entries. - */ - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'credit_notes.id', - to: 'accounts_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'CreditNote'); - }, - }, - - /** - * Credit note may belongs to branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'credit_notes.branchId', - to: 'branches.id', - }, - }, - - /** - * Credit note may has associated warehouse. - */ - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'credit_notes.warehouseId', - to: 'warehouses.id', - }, - }, - - /** - * Credit note may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'credit_notes.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'CreditNote'); - }, - }, - - /** - * Credit note may belongs to pdf branding template. - */ - pdfTemplate: { - relation: Model.BelongsToOneRelation, - modelClass: PdfTemplate, - join: { - from: 'credit_notes.pdfTemplateId', - to: 'pdf_templates.id', - }, - }, - }; - } - - /** - * Sale invoice meta. - */ - static get meta() { - return CreditNoteMeta; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model searchable. - */ - static get searchable() { - return true; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'credit_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - * @returns {boolean} - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/CreditNoteAppliedInvoice.ts b/packages/server/src/models/CreditNoteAppliedInvoice.ts deleted file mode 100644 index 1f88de105..000000000 --- a/packages/server/src/models/CreditNoteAppliedInvoice.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { mixin, Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSearchable from './ModelSearchable'; - -export default class CreditNoteAppliedInvoice extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'credit_note_applied_invoice'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleInvoice = require('models/SaleInvoice'); - const CreditNote = require('models/CreditNote'); - - return { - saleInvoice: { - relation: Model.BelongsToOneRelation, - modelClass: SaleInvoice.default, - join: { - from: 'credit_note_applied_invoice.invoiceId', - to: 'sales_invoices.id', - }, - }, - - creditNote: { - relation: Model.BelongsToOneRelation, - modelClass: CreditNote.default, - join: { - from: 'credit_note_applied_invoice.creditNoteId', - to: 'credit_notes.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/CreditNoteAppliedInvoiceEntry.ts b/packages/server/src/models/CreditNoteAppliedInvoiceEntry.ts deleted file mode 100644 index 7f3fee75f..000000000 --- a/packages/server/src/models/CreditNoteAppliedInvoiceEntry.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSearchable from './ModelSearchable'; - -export default class CreditNoteAppliedInvoiceEntry extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'credit_associated_transaction_entry'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - return {}; - } -} diff --git a/packages/server/src/models/Currency.ts b/packages/server/src/models/Currency.ts deleted file mode 100644 index fe091dd67..000000000 --- a/packages/server/src/models/Currency.ts +++ /dev/null @@ -1,21 +0,0 @@ -import TenantModel from 'models/TenantModel'; - -export default class Currency extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'currencies'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - static get resourceable() { - return true; - } -} diff --git a/packages/server/src/models/CustomViewBaseModel.ts b/packages/server/src/models/CustomViewBaseModel.ts deleted file mode 100644 index 5c1dfec54..000000000 --- a/packages/server/src/models/CustomViewBaseModel.ts +++ /dev/null @@ -1,24 +0,0 @@ -export default (Model) => - class CustomViewBaseModel extends Model { - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return []; - } - - /** - * Retrieve the default view by the given slug. - */ - static getDefaultViewBySlug(viewSlug) { - return this.defaultViews.find((view) => view.slug === viewSlug) || null; - } - - /** - * Retrieve the default views. - * @returns {IView[]} - */ - static getDefaultViews() { - return this.defaultViews; - } - }; diff --git a/packages/server/src/models/Customer.Settings.ts b/packages/server/src/models/Customer.Settings.ts deleted file mode 100644 index 86a716507..000000000 --- a/packages/server/src/models/Customer.Settings.ts +++ /dev/null @@ -1,422 +0,0 @@ -export default { - importable: true, - exportable: true, - defaultFilterField: 'displayName', - defaultSort: { - sortOrder: 'DESC', - sortField: 'created_at', - }, - print: { - pageTitle: 'Customers', - }, - fields: { - first_name: { - name: 'vendor.field.first_name', - column: 'first_name', - fieldType: 'text', - }, - last_name: { - name: 'vendor.field.last_name', - column: 'last_name', - fieldType: 'text', - }, - display_name: { - name: 'vendor.field.display_name', - column: 'display_name', - fieldType: 'text', - }, - email: { - name: 'vendor.field.email', - column: 'email', - fieldType: 'text', - }, - work_phone: { - name: 'vendor.field.work_phone', - column: 'work_phone', - fieldType: 'text', - }, - personal_phone: { - name: 'vendor.field.personal_pone', - column: 'personal_phone', - fieldType: 'text', - }, - company_name: { - name: 'vendor.field.company_name', - column: 'company_name', - fieldType: 'text', - }, - website: { - name: 'vendor.field.website', - column: 'website', - fieldType: 'text', - }, - created_at: { - name: 'vendor.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - balance: { - name: 'vendor.field.balance', - column: 'balance', - fieldType: 'number', - }, - opening_balance: { - name: 'vendor.field.opening_balance', - column: 'opening_balance', - fieldType: 'number', - }, - opening_balance_at: { - name: 'vendor.field.opening_balance_at', - column: 'opening_balance_at', - fieldType: 'date', - }, - currency_code: { - name: 'vendor.field.currency', - column: 'currency_code', - fieldType: 'text', - }, - status: { - name: 'vendor.field.status', - type: 'enumeration', - options: [ - { key: 'overdue', label: 'vendor.field.status.overdue' }, - { key: 'unpaid', label: 'vendor.field.status.unpaid' }, - ], - filterCustomQuery: (query, role) => { - switch (role.value) { - case 'overdue': - query.modify('overdue'); - break; - case 'unpaid': - query.modify('unpaid'); - break; - } - }, - }, - }, - columns: { - customerType: { - name: 'Customer Type', - type: 'text', - accessor: 'formattedCustomerType', - }, - firstName: { - name: 'vendor.field.first_name', - type: 'text', - }, - lastName: { - name: 'vendor.field.last_name', - type: 'text', - }, - displayName: { - name: 'vendor.field.display_name', - type: 'text', - }, - email: { - name: 'vendor.field.email', - type: 'text', - }, - workPhone: { - name: 'vendor.field.work_phone', - type: 'text', - }, - personalPhone: { - name: 'vendor.field.personal_phone', - type: 'text', - }, - companyName: { - name: 'vendor.field.company_name', - type: 'text', - }, - website: { - name: 'vendor.field.website', - type: 'text', - }, - balance: { - name: 'vendor.field.balance', - type: 'number', - accessor: 'formattedBalance', - }, - openingBalance: { - name: 'vendor.field.opening_balance', - type: 'number', - printable: false, - }, - openingBalanceAt: { - name: 'vendor.field.opening_balance_at', - type: 'date', - printable: false, - accessor: 'formattedOpeningBalanceAt' - }, - currencyCode: { - name: 'vendor.field.currency', - type: 'text', - printable: false, - }, - status: { - name: 'vendor.field.status', - printable: false, - }, - note: { - name: 'vendor.field.note', - printable: false, - }, - // Billing Address - billingAddress1: { - name: 'Billing Address 1', - column: 'billing_address1', - type: 'text', - printable: false, - }, - billingAddress2: { - name: 'Billing Address 2', - column: 'billing_address2', - type: 'text', - printable: false, - }, - billingAddressCity: { - name: 'Billing Address City', - column: 'billing_address_city', - type: 'text', - printable: false, - }, - billingAddressCountry: { - name: 'Billing Address Country', - column: 'billing_address_country', - type: 'text', - printable: false, - }, - billingAddressPostcode: { - name: 'Billing Address Postcode', - column: 'billing_address_postcode', - type: 'text', - printable: false, - }, - billingAddressState: { - name: 'Billing Address State', - column: 'billing_address_state', - type: 'text', - printable: false, - }, - billingAddressPhone: { - name: 'Billing Address Phone', - column: 'billing_address_phone', - type: 'text', - printable: false, - }, - // Shipping Address - shippingAddress1: { - name: 'Shipping Address 1', - column: 'shipping_address1', - type: 'text', - printable: false, - }, - shippingAddress2: { - name: 'Shipping Address 2', - column: 'shipping_address2', - type: 'text', - printable: false, - }, - shippingAddressCity: { - name: 'Shipping Address City', - column: 'shipping_address_city', - type: 'text', - printable: false, - }, - shippingAddressCountry: { - name: 'Shipping Address Country', - column: 'shipping_address_country', - type: 'text', - printable: false, - }, - shippingAddressPostcode: { - name: 'Shipping Address Postcode', - column: 'shipping_address_postcode', - type: 'text', - printable: false, - }, - shippingAddressPhone: { - name: 'Shipping Address Phone', - column: 'shipping_address_phone', - type: 'text', - printable: false, - }, - shippingAddressState: { - name: 'Shipping Address State', - column: 'shipping_address_state', - type: 'text', - printable: false, - }, - createdAt: { - name: 'vendor.field.created_at', - type: 'date', - printable: false, - }, - }, - fields2: { - customerType: { - name: 'Customer Type', - fieldType: 'enumeration', - options: [ - { key: 'business', label: 'Business' }, - { key: 'individual', label: 'Individual' }, - ], - required: true, - }, - firstName: { - name: 'customer.field.first_name', - column: 'first_name', - fieldType: 'text', - }, - lastName: { - name: 'customer.field.last_name', - column: 'last_name', - fieldType: 'text', - }, - displayName: { - name: 'customer.field.display_name', - column: 'display_name', - fieldType: 'text', - required: true, - }, - email: { - name: 'customer.field.email', - column: 'email', - fieldType: 'text', - }, - workPhone: { - name: 'customer.field.work_phone', - column: 'work_phone', - fieldType: 'text', - }, - personalPhone: { - name: 'customer.field.personal_phone', - column: 'personal_phone', - fieldType: 'text', - }, - companyName: { - name: 'customer.field.company_name', - column: 'company_name', - fieldType: 'text', - }, - website: { - name: 'customer.field.website', - column: 'website', - fieldType: 'url', - }, - openingBalance: { - name: 'customer.field.opening_balance', - column: 'opening_balance', - fieldType: 'number', - }, - openingBalanceAt: { - name: 'customer.field.opening_balance_at', - column: 'opening_balance_at', - filterable: false, - fieldType: 'date', - }, - openingBalanceExchangeRate: { - name: 'Opening Balance Ex. Rate', - column: 'opening_balance_exchange_rate', - fieldType: 'number', - }, - currencyCode: { - name: 'customer.field.currency', - column: 'currency_code', - fieldType: 'text', - }, - note: { - name: 'Note', - column: 'note', - fieldType: 'text', - }, - active: { - name: 'Active', - column: 'active', - fieldType: 'boolean', - }, - // Billing Address - billingAddress1: { - name: 'Billing Address 1', - column: 'billing_address1', - fieldType: 'text', - }, - billingAddress2: { - name: 'Billing Address 2', - column: 'billing_address2', - fieldType: 'text', - }, - billingAddressCity: { - name: 'Billing Address City', - column: 'billing_address_city', - fieldType: 'text', - }, - billingAddressCountry: { - name: 'Billing Address Country', - column: 'billing_address_country', - fieldType: 'text', - }, - billingAddressPostcode: { - name: 'Billing Address Postcode', - column: 'billing_address_postcode', - fieldType: 'text', - }, - billingAddressState: { - name: 'Billing Address State', - column: 'billing_address_state', - fieldType: 'text', - }, - billingAddressPhone: { - name: 'Billing Address Phone', - column: 'billing_address_phone', - fieldType: 'text', - }, - // Shipping Address - shippingAddress1: { - name: 'Shipping Address 1', - column: 'shipping_address1', - fieldType: 'text', - }, - shippingAddress2: { - name: 'Shipping Address 2', - column: 'shipping_address2', - fieldType: 'text', - }, - shippingAddressCity: { - name: 'Shipping Address City', - column: 'shipping_address_city', - fieldType: 'text', - }, - shippingAddressCountry: { - name: 'Shipping Address Country', - column: 'shipping_address_country', - fieldType: 'text', - }, - shippingAddressPostcode: { - name: 'Shipping Address Postcode', - column: 'shipping_address_postcode', - fieldType: 'text', - }, - shippingAddressPhone: { - name: 'Shipping Address Phone', - column: 'shipping_address_phone', - fieldType: 'text', - }, - shippingAddressState: { - name: 'Shipping Address State', - column: 'shipping_address_state', - fieldType: 'text', - }, - }, -}; - -function statusFieldFilterQuery(query, role) { - switch (role.value) { - case 'overdue': - query.modify('overdue'); - break; - case 'unpaid': - query.modify('unpaid'); - break; - } -} diff --git a/packages/server/src/models/Customer.ts b/packages/server/src/models/Customer.ts deleted file mode 100644 index 631763b71..000000000 --- a/packages/server/src/models/Customer.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import PaginationQueryBuilder from './Pagination'; -import ModelSetting from './ModelSetting'; -import CustomerSettings from './Customer.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Contacts/Customers/constants'; -import ModelSearchable from './ModelSearchable'; - -class CustomerQueryBuilder extends PaginationQueryBuilder { - constructor(...args) { - super(...args); - - this.onBuild((builder) => { - if (builder.isFind() || builder.isDelete() || builder.isUpdate()) { - builder.where('contact_service', 'customer'); - } - }); - } -} - -export default class Customer extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - email: string; - displayName: string; - - /** - * Query builder. - */ - static get QueryBuilder() { - return CustomerQueryBuilder; - } - - /** - * Table name - */ - static get tableName() { - return 'contacts'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Defined virtual attributes. - */ - static get virtualAttributes() { - return ['localOpeningBalance', 'closingBalance', 'contactNormal']; - } - - /** - * Closing balance attribute. - */ - get closingBalance() { - return this.balance; - } - - /** - * Retrieves the local opening balance. - * @returns {number} - */ - get localOpeningBalance() { - return this.openingBalance - ? this.openingBalance * this.openingBalanceExchangeRate - : 0; - } - - /** - * Retrieve the contact noraml; - */ - get contactNormal() { - return 'debit'; - } - - /** - * - */ - get contactAddresses() { - return [ - { - mail: this.email, - label: this.displayName, - primary: true - }, - ].filter((c) => c.mail); - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Inactive/Active mode. - */ - inactiveMode(query, active = false) { - query.where('active', !active); - }, - - /** - * Filters the active customers. - */ - active(query) { - query.where('active', 1); - }, - /** - * Filters the inactive customers. - */ - inactive(query) { - query.where('active', 0); - }, - /** - * Filters the customers that have overdue invoices. - */ - overdue(query) { - query.select( - '*', - Customer.relatedQuery('overDueInvoices', query.knex()) - .count() - .as('countOverdue') - ); - query.having('countOverdue', '>', 0); - }, - /** - * Filters the unpaid customers. - */ - unpaid(query) { - query.whereRaw('`BALANCE` + `OPENING_BALANCE` <> 0'); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleInvoice = require('models/SaleInvoice'); - - return { - salesInvoices: { - relation: Model.HasManyRelation, - modelClass: SaleInvoice.default, - join: { - from: 'contacts.id', - to: 'sales_invoices.customerId', - }, - }, - - overDueInvoices: { - relation: Model.HasManyRelation, - modelClass: SaleInvoice.default, - join: { - from: 'contacts.id', - to: 'sales_invoices.customerId', - }, - filter: (query) => { - query.modify('overdue'); - }, - }, - }; - } - - static get meta() { - return CustomerSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'display_name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'first_name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'last_name', comparator: 'equals' }, - { condition: 'or', fieldKey: 'company_name', comparator: 'equals' }, - { condition: 'or', fieldKey: 'email', comparator: 'equals' }, - { condition: 'or', fieldKey: 'work_phone', comparator: 'equals' }, - { condition: 'or', fieldKey: 'personal_phone', comparator: 'equals' }, - { condition: 'or', fieldKey: 'website', comparator: 'equals' }, - ]; - } -} diff --git a/packages/server/src/models/DateSession.ts b/packages/server/src/models/DateSession.ts deleted file mode 100644 index 14f981ee7..000000000 --- a/packages/server/src/models/DateSession.ts +++ /dev/null @@ -1,34 +0,0 @@ -import moment from 'moment'; - -export default (Model) => { - return class DateSession extends Model { - - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - $beforeUpdate(opt, context) { - const maybePromise = super.$beforeUpdate(opt, context); - - return Promise.resolve(maybePromise).then(() => { - const key = this.timestamps[1]; - - if (key && !this[key]) { - this[key] = moment().format('YYYY/MM/DD HH:mm:ss'); - } - }); - } - - $beforeInsert(context) { - const maybePromise = super.$beforeInsert(context); - - return Promise.resolve(maybePromise).then(() => { - const key = this.timestamps[0]; - - if (key && !this[key]) { - this[key] = moment().format('YYYY/MM/DD HH:mm:ss'); - } - }); - } - } -} \ No newline at end of file diff --git a/packages/server/src/models/Document.ts b/packages/server/src/models/Document.ts deleted file mode 100644 index 5e99c1be6..000000000 --- a/packages/server/src/models/Document.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import ModelSearchable from './ModelSearchable'; - -export default class Document extends mixin(TenantModel, [ - ModelSetting, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'documents'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } -} diff --git a/packages/server/src/models/DocumentLink.ts b/packages/server/src/models/DocumentLink.ts deleted file mode 100644 index 4e7ac10fe..000000000 --- a/packages/server/src/models/DocumentLink.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import ModelSearchable from './ModelSearchable'; - -export default class DocumentLink extends mixin(TenantModel, [ - ModelSetting, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'document_links'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Document = require('models/Document'); - - return { - /** - * Sale invoice associated entries. - */ - document: { - relation: Model.HasOneRelation, - modelClass: Document.default, - join: { - from: 'document_links.documentId', - to: 'documents.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/ExchangeRate.ts b/packages/server/src/models/ExchangeRate.ts deleted file mode 100644 index c0e4c2939..000000000 --- a/packages/server/src/models/ExchangeRate.ts +++ /dev/null @@ -1,44 +0,0 @@ -import bcrypt from 'bcryptjs'; -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class ExchangeRate extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'exchange_rates'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Model defined fields. - */ - static get fields(){ - return { - currency_code: { - label: 'Currency', - column: 'currency_code' - }, - exchange_rate: { - label: 'Exchange rate', - column: 'exchange_rate', - }, - date: { - label: 'Date', - column: 'date', - }, - created_at: { - label: "Created at", - column: "created_at", - columnType: "date", - }, - } - } -} \ No newline at end of file diff --git a/packages/server/src/models/Expense.Settings.ts b/packages/server/src/models/Expense.Settings.ts deleted file mode 100644 index fc6d7f402..000000000 --- a/packages/server/src/models/Expense.Settings.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { Features } from '@/interfaces'; - -/** - * Expense - Settings. - */ -export default { - defaultFilterField: 'description', - defaultSort: { - sortOrder: 'DESC', - sortField: 'name', - }, - importable: true, - exportFlattenOn: 'categories', - exportable: true, - print: { - pageTitle: 'Expenses', - }, - fields: { - payment_date: { - name: 'expense.field.payment_date', - column: 'payment_date', - fieldType: 'date', - }, - payment_account: { - name: 'expense.field.payment_account', - column: 'payment_account_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'paymentAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - amount: { - name: 'expense.field.amount', - column: 'total_amount', - fieldType: 'number', - }, - reference_no: { - name: 'expense.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - description: { - name: 'expense.field.description', - column: 'description', - fieldType: 'text', - }, - published: { - name: 'expense.field.published', - column: 'published_at', - fieldType: 'date', - }, - status: { - name: 'expense.field.status', - fieldType: 'enumeration', - options: [ - { label: 'expense.field.status.draft', key: 'draft' }, - { label: 'expense.field.status.published', key: 'published' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - created_at: { - name: 'expense.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - paymentReceive: { - name: 'expense.field.payment_account', - type: 'text', - accessor: 'paymentAccount.name', - }, - referenceNo: { - name: 'expense.field.reference_no', - type: 'text', - }, - paymentDate: { - name: 'expense.field.payment_date', - accessor: 'formattedDate', - type: 'date', - }, - currencyCode: { - name: 'expense.field.currency_code', - type: 'text', - printable: false, - }, - exchangeRate: { - name: 'expense.field.exchange_rate', - type: 'number', - printable: false, - }, - description: { - name: 'expense.field.description', - type: 'text', - }, - categories: { - name: 'expense.field.categories', - type: 'collection', - collectionOf: 'object', - columns: { - expenseAccount: { - name: 'expense.field.expense_account', - accessor: 'expenseAccount.name', - }, - amount: { - name: 'expense.field.amount', - accessor: 'amountFormatted', - }, - description: { - name: 'expense.field.line_description', - type: 'text', - }, - }, - }, - publish: { - name: 'expense.field.publish', - type: 'boolean', - printable: false, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - paymentAccountId: { - name: 'expense.field.payment_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the account name or code.', - }, - referenceNo: { - name: 'expense.field.reference_no', - fieldType: 'text', - }, - paymentDate: { - name: 'expense.field.payment_date', - fieldType: 'date', - required: true, - }, - currencyCode: { - name: 'expense.field.currency_code', - fieldType: 'text', - }, - exchangeRate: { - name: 'expense.field.exchange_rate', - fieldType: 'number', - }, - description: { - name: 'expense.field.description', - fieldType: 'text', - }, - categories: { - name: 'expense.field.categories', - fieldType: 'collection', - collectionOf: 'object', - fields: { - expenseAccountId: { - name: 'expense.field.expense_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the account name or code.', - }, - amount: { - name: 'expense.field.amount', - fieldType: 'number', - required: true, - }, - description: { - name: 'expense.field.line_description', - fieldType: 'text', - }, - }, - }, - publish: { - name: 'expense.field.publish', - fieldType: 'boolean', - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - }, -}; - -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} - -function StatusFieldSortQuery(query, role) { - query.modify('sortByStatus', role.order); -} diff --git a/packages/server/src/models/Expense.ts b/packages/server/src/models/Expense.ts deleted file mode 100644 index 17e0b273d..000000000 --- a/packages/server/src/models/Expense.ts +++ /dev/null @@ -1,283 +0,0 @@ -import { Model, mixin, raw } from 'objection'; -import TenantModel from 'models/TenantModel'; -import { viewRolesBuilder } from '@/lib/ViewRolesBuilder'; -import ModelSetting from './ModelSetting'; -import ExpenseSettings from './Expense.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Expenses/constants'; -import ModelSearchable from './ModelSearchable'; -import moment from 'moment'; - -export default class Expense extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'expenses_transactions'; - } - - /** - * Account transaction reference type. - */ - static get referenceType() { - return 'Expense'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'isPublished', - 'unallocatedCostAmount', - 'localAmount', - 'localLandedCostAmount', - 'localUnallocatedCostAmount', - 'localAllocatedCostAmount', - 'billableAmount', - ]; - } - - /** - * Retrieves the local amount of expense. - * @returns {number} - */ - get localAmount() { - return this.totalAmount * this.exchangeRate; - } - - /** - * Rertieves the local landed cost amount of expense. - * @returns {number} - */ - get localLandedCostAmount() { - return this.landedCostAmount * this.exchangeRate; - } - - /** - * Retrieves the local allocated cost amount. - * @returns {number} - */ - get localAllocatedCostAmount() { - return this.allocatedCostAmount * this.exchangeRate; - } - - /** - * Retrieve the unallocated cost amount. - * @return {number} - */ - get unallocatedCostAmount() { - return Math.max(this.totalAmount - this.allocatedCostAmount, 0); - } - - /** - * Retrieves the local unallocated cost amount. - * @returns {number} - */ - get localUnallocatedCostAmount() { - return this.unallocatedCostAmount * this.exchangeRate; - } - - /** - * Detarmines whether the expense is published. - * @returns {boolean} - */ - get isPublished() { - return Boolean(this.publishedAt); - } - - /** - * Retrieves the calculated amount which have not been invoiced. - */ - get billableAmount() { - return Math.max(this.totalAmount - this.invoicedAmount, 0); - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - filterByDateRange(query, startDate, endDate) { - if (startDate) { - query.where('date', '>=', startDate); - } - if (endDate) { - query.where('date', '<=', endDate); - } - }, - filterByAmountRange(query, from, to) { - if (from) { - query.where('amount', '>=', from); - } - if (to) { - query.where('amount', '<=', to); - } - }, - filterByExpenseAccount(query, accountId) { - if (accountId) { - query.where('expense_account_id', accountId); - } - }, - filterByPaymentAccount(query, accountId) { - if (accountId) { - query.where('payment_account_id', accountId); - } - }, - viewRolesBuilder(query, conditionals, expression) { - viewRolesBuilder(conditionals, expression)(query); - }, - - filterByDraft(query) { - query.where('published_at', null); - }, - - filterByPublished(query) { - query.whereNot('published_at', null); - }, - - filterByStatus(query, status) { - switch (status) { - case 'draft': - query.modify('filterByDraft'); - break; - case 'published': - default: - query.modify('filterByPublished'); - break; - } - }, - - publish(query) { - query.update({ - publishedAt: moment().toMySqlDateTime(), - }); - }, - - /** - * Filters the expenses have billable amount. - */ - billable(query) { - query.where(raw('AMOUNT > INVOICED_AMOUNT')); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - const ExpenseCategory = require('models/ExpenseCategory'); - const Document = require('models/Document'); - const Branch = require('models/Branch'); - const { MatchedBankTransaction } = require('models/MatchedBankTransaction'); - - return { - paymentAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'expenses_transactions.paymentAccountId', - to: 'accounts.id', - }, - }, - categories: { - relation: Model.HasManyRelation, - modelClass: ExpenseCategory.default, - join: { - from: 'expenses_transactions.id', - to: 'expense_transaction_categories.expenseId', - }, - filter: (query) => { - query.orderBy('index', 'ASC'); - }, - }, - - /** - * Expense transction may belongs to a branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'expenses_transactions.branchId', - to: 'branches.id', - }, - }, - - /** - * Expense transaction may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'expenses_transactions.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'Expense'); - }, - }, - - /** - * Expense may belongs to matched bank transaction. - */ - matchedBankTransaction: { - relation: Model.HasManyRelation, - modelClass: MatchedBankTransaction, - join: { - from: 'expenses_transactions.id', - to: 'matched_bank_transactions.referenceId', - }, - filter(query) { - query.where('reference_type', 'Expense'); - }, - }, - }; - } - - static get meta() { - return ExpenseSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/ExpenseCategory.ts b/packages/server/src/models/ExpenseCategory.ts deleted file mode 100644 index 21d61f7e8..000000000 --- a/packages/server/src/models/ExpenseCategory.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class ExpenseCategory extends TenantModel { - amount: number; - - /** - * Table name - */ - static get tableName() { - return 'expense_transaction_categories'; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['unallocatedCostAmount']; - } - - /** - * Remain unallocated landed cost. - * @return {number} - */ - get unallocatedCostAmount() { - return Math.max(this.amount - this.allocatedCostAmount, 0); - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - - return { - expenseAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'expense_transaction_categories.expenseAccountId', - to: 'accounts.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/InventoryAdjustment.Settings.ts b/packages/server/src/models/InventoryAdjustment.Settings.ts deleted file mode 100644 index 9d7f65237..000000000 --- a/packages/server/src/models/InventoryAdjustment.Settings.ts +++ /dev/null @@ -1,107 +0,0 @@ -export default { - defaultFilterField: 'date', - defaultSort: { - sortOrder: 'DESC', - sortField: 'date', - }, - columns: { - date: { - name: 'inventory_adjustment.field.date', - column: 'date', - fieldType: 'date', - exportable: true, - }, - type: { - name: 'inventory_adjustment.field.type', - column: 'type', - fieldType: 'enumeration', - options: [ - { key: 'increment', name: 'inventory_adjustment.field.type.increment' }, - { key: 'decrement', name: 'inventory_adjustment.field.type.decrement' }, - ], - exportable: true, - }, - adjustmentAccount: { - name: 'inventory_adjustment.field.adjustment_account', - type: 'adjustment_account_id', - exportable: true, - }, - reason: { - name: 'inventory_adjustment.field.reason', - type: 'text', - exportable: true, - }, - referenceNo: { - name: 'inventory_adjustment.field.reference_no', - type: 'text', - exportable: true, - }, - description: { - name: 'inventory_adjustment.field.description', - type: 'text', - exportable: true, - }, - publishedAt: { - name: 'inventory_adjustment.field.published_at', - type: 'date', - exportable: true, - }, - createdAt: { - name: 'inventory_adjustment.field.created_at', - type: 'date', - exportable: true, - }, - }, - fields: { - date: { - name: 'inventory_adjustment.field.date', - column: 'date', - fieldType: 'date', - }, - type: { - name: 'inventory_adjustment.field.type', - column: 'type', - fieldType: 'enumeration', - options: [ - { key: 'increment', name: 'inventory_adjustment.field.type.increment' }, - { key: 'decrement', name: 'inventory_adjustment.field.type.decrement' }, - ], - }, - adjustment_account: { - name: 'inventory_adjustment.field.adjustment_account', - column: 'adjustment_account_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'adjustmentAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - reason: { - name: 'inventory_adjustment.field.reason', - column: 'reason', - fieldType: 'text', - }, - reference_no: { - name: 'inventory_adjustment.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - description: { - name: 'inventory_adjustment.field.description', - column: 'description', - fieldType: 'text', - }, - published_at: { - name: 'inventory_adjustment.field.published_at', - column: 'published_at', - fieldType: 'date', - }, - created_at: { - name: 'inventory_adjustment.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, -}; diff --git a/packages/server/src/models/InventoryAdjustment.ts b/packages/server/src/models/InventoryAdjustment.ts deleted file mode 100644 index 5e55b4c06..000000000 --- a/packages/server/src/models/InventoryAdjustment.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import InventoryAdjustmentSettings from './InventoryAdjustment.Settings'; -import ModelSetting from './ModelSetting'; - -export default class InventoryAdjustment extends mixin(TenantModel, [ - ModelSetting, -]) { - /** - * Table name - */ - static get tableName() { - return 'inventory_adjustments'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['formattedType', 'inventoryDirection', 'isPublished']; - } - - /** - * Retrieve formatted adjustment type. - */ - get formattedType() { - return InventoryAdjustment.getFormattedType(this.type); - } - - /** - * Retrieve formatted reference type. - */ - get inventoryDirection() { - return InventoryAdjustment.getInventoryDirection(this.type); - } - - /** - * Detarmines whether the adjustment is published. - * @return {boolean} - */ - get isPublished() { - return !!this.publishedAt; - } - - static getInventoryDirection(type) { - const directions = { - increment: 'IN', - decrement: 'OUT', - }; - return directions[type] || ''; - } - - /** - * Retrieve the formatted adjustment type of the given type. - * @param {string} type - * @returns {string} - */ - static getFormattedType(type) { - const types = { - increment: 'inventory_adjustment.type.increment', - decrement: 'inventory_adjustment.type.decrement', - }; - return types[type]; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const InventoryAdjustmentEntry = require('models/InventoryAdjustmentEntry'); - const Account = require('models/Account'); - - return { - /** - * Adjustment entries. - */ - entries: { - relation: Model.HasManyRelation, - modelClass: InventoryAdjustmentEntry.default, - join: { - from: 'inventory_adjustments.id', - to: 'inventory_adjustments_entries.adjustmentId', - }, - }, - - /** - * Inventory adjustment account. - */ - adjustmentAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'inventory_adjustments.adjustmentAccountId', - to: 'accounts.id', - }, - }, - }; - } - - /** - * Model settings. - */ - static get meta() { - return InventoryAdjustmentSettings; - } -} diff --git a/packages/server/src/models/InventoryAdjustmentEntry.ts b/packages/server/src/models/InventoryAdjustmentEntry.ts deleted file mode 100644 index 2e7159fcd..000000000 --- a/packages/server/src/models/InventoryAdjustmentEntry.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class InventoryAdjustmentEntry extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'inventory_adjustments_entries'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const InventoryAdjustment = require('models/InventoryAdjustment'); - const Item = require('models/Item'); - - return { - inventoryAdjustment: { - relation: Model.BelongsToOneRelation, - modelClass: InventoryAdjustment.default, - join: { - from: 'inventory_adjustments_entries.adjustmentId', - to: 'inventory_adjustments.id', - }, - }, - - /** - * Entry item. - */ - item: { - relation: Model.BelongsToOneRelation, - modelClass: Item.default, - join: { - from: 'inventory_adjustments_entries.itemId', - to: 'items.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/InventoryCostLotTracker.ts b/packages/server/src/models/InventoryCostLotTracker.ts deleted file mode 100644 index 7b644f9a5..000000000 --- a/packages/server/src/models/InventoryCostLotTracker.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Model } from 'objection'; -import { castArray, isEmpty } from 'lodash'; -import moment from 'moment'; -import TenantModel from 'models/TenantModel'; - -export default class InventoryCostLotTracker extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'inventory_cost_lot_tracker'; - } - - /** - * Model timestamps. - */ - static get timestamps() { - return []; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - groupedEntriesCost(query) { - query.select(['date', 'item_id', 'transaction_id', 'transaction_type']); - query.sum('cost as cost'); - - query.groupBy('transaction_id'); - query.groupBy('transaction_type'); - query.groupBy('date'); - query.groupBy('item_id'); - }, - filterDateRange(query, startDate, endDate, type = 'day') { - const dateFormat = 'YYYY-MM-DD'; - const fromDate = moment(startDate).startOf(type).format(dateFormat); - const toDate = moment(endDate).endOf(type).format(dateFormat); - - if (startDate) { - query.where('date', '>=', fromDate); - } - if (endDate) { - query.where('date', '<=', toDate); - } - }, - - /** - * Filters transactions by the given branches. - */ - filterByBranches(query, branchesIds) { - const formattedBranchesIds = castArray(branchesIds); - - query.whereIn('branchId', formattedBranchesIds); - }, - - /** - * Filters transactions by the given warehosues. - */ - filterByWarehouses(query, branchesIds) { - const formattedWarehousesIds = castArray(branchesIds); - - query.whereIn('warehouseId', formattedWarehousesIds); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Item = require('models/Item'); - const SaleInvoice = require('models/SaleInvoice'); - const ItemEntry = require('models/ItemEntry'); - const SaleReceipt = require('models/SaleReceipt'); - - return { - item: { - relation: Model.BelongsToOneRelation, - modelClass: Item.default, - join: { - from: 'inventory_cost_lot_tracker.itemId', - to: 'items.id', - }, - }, - invoice: { - relation: Model.BelongsToOneRelation, - modelClass: SaleInvoice.default, - join: { - from: 'inventory_cost_lot_tracker.transactionId', - to: 'sales_invoices.id', - }, - }, - itemEntry: { - relation: Model.BelongsToOneRelation, - modelClass: ItemEntry.default, - join: { - from: 'inventory_cost_lot_tracker.entryId', - to: 'items_entries.id', - }, - }, - receipt: { - relation: Model.BelongsToOneRelation, - modelClass: SaleReceipt.default, - join: { - from: 'inventory_cost_lot_tracker.transactionId', - to: 'sales_receipts.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/InventoryTransaction.ts b/packages/server/src/models/InventoryTransaction.ts deleted file mode 100644 index ffdf2471d..000000000 --- a/packages/server/src/models/InventoryTransaction.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { Model, raw } from 'objection'; -import { castArray } from 'lodash'; -import moment from 'moment'; -import TenantModel from 'models/TenantModel'; -import { getTransactionTypeLabel } from '@/utils/transactions-types'; - -export default class InventoryTransaction extends TenantModel { - transactionId: number; - transactionType: string; - - /** - * Table name - */ - static get tableName() { - return 'inventory_transactions'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Retrieve formatted reference type. - * @return {string} - */ - get transcationTypeFormatted() { - return getTransactionTypeLabel(this.transactionType); - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - filterDateRange(query, startDate, endDate, type = 'day') { - const dateFormat = 'YYYY-MM-DD'; - const fromDate = moment(startDate).startOf(type).format(dateFormat); - const toDate = moment(endDate).endOf(type).format(dateFormat); - - if (startDate) { - query.where('date', '>=', fromDate); - } - if (endDate) { - query.where('date', '<=', toDate); - } - }, - - itemsTotals(builder) { - builder.select('itemId'); - builder.sum('rate as rate'); - builder.sum('quantity as quantity'); - builder.select(raw('SUM(`QUANTITY` * `RATE`) as COST')); - builder.groupBy('itemId'); - }, - - INDirection(builder) { - builder.where('direction', 'IN'); - }, - - OUTDirection(builder) { - builder.where('direction', 'OUT'); - }, - - /** - * Filters transactions by the given branches. - */ - filterByBranches(query, branchesIds) { - const formattedBranchesIds = castArray(branchesIds); - - query.whereIn('branch_id', formattedBranchesIds); - }, - - /** - * Filters transactions by the given warehosues. - */ - filterByWarehouses(query, warehousesIds) { - const formattedWarehousesIds = castArray(warehousesIds); - - query.whereIn('warehouse_id', formattedWarehousesIds); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Item = require('models/Item'); - const ItemEntry = require('models/ItemEntry'); - const InventoryTransactionMeta = require('models/InventoryTransactionMeta'); - const InventoryCostLots = require('models/InventoryCostLotTracker'); - - return { - // Transaction meta. - meta: { - relation: Model.HasOneRelation, - modelClass: InventoryTransactionMeta.default, - join: { - from: 'inventory_transactions.id', - to: 'inventory_transaction_meta.inventoryTransactionId', - }, - }, - // Item cost aggregated. - itemCostAggregated: { - relation: Model.HasOneRelation, - modelClass: InventoryCostLots.default, - join: { - from: 'inventory_transactions.itemId', - to: 'inventory_cost_lot_tracker.itemId', - }, - filter(query) { - query.select('itemId'); - query.sum('cost as cost'); - query.sum('quantity as quantity'); - query.groupBy('itemId'); - }, - }, - costLotAggregated: { - relation: Model.HasOneRelation, - modelClass: InventoryCostLots.default, - join: { - from: 'inventory_transactions.id', - to: 'inventory_cost_lot_tracker.inventoryTransactionId', - }, - filter(query) { - query.sum('cost as cost'); - query.sum('quantity as quantity'); - query.groupBy('inventoryTransactionId'); - }, - }, - item: { - relation: Model.BelongsToOneRelation, - modelClass: Item.default, - join: { - from: 'inventory_transactions.itemId', - to: 'items.id', - }, - }, - itemEntry: { - relation: Model.BelongsToOneRelation, - modelClass: ItemEntry.default, - join: { - from: 'inventory_transactions.entryId', - to: 'items_entries.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/InventoryTransactionMeta.ts b/packages/server/src/models/InventoryTransactionMeta.ts deleted file mode 100644 index 62a232b64..000000000 --- a/packages/server/src/models/InventoryTransactionMeta.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Model, raw } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class InventoryTransactionMeta extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'inventory_transaction_meta'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const InventoryTransactions = require('models/InventoryTransaction'); - - return { - inventoryTransaction: { - relation: Model.BelongsToOneRelation, - modelClass: InventoryTransactions.default, - join: { - from: 'inventory_transaction_meta.inventoryTransactionId', - to: 'inventory_transactions.inventoryTransactionId' - } - } - }; - } -} diff --git a/packages/server/src/models/Item.Settings.ts b/packages/server/src/models/Item.Settings.ts deleted file mode 100644 index a8e02cc8b..000000000 --- a/packages/server/src/models/Item.Settings.ts +++ /dev/null @@ -1,309 +0,0 @@ -export default { - importable: true, - exportable: true, - defaultFilterField: 'name', - defaultSort: { - sortField: 'name', - sortOrder: 'DESC', - }, - print: { - pageTitle: 'Items', - }, - fields: { - type: { - name: 'item.field.type', - column: 'type', - fieldType: 'enumeration', - options: [ - { key: 'inventory', label: 'item.field.type.inventory' }, - { key: 'service', label: 'item.field.type.service' }, - { key: 'non-inventory', label: 'item.field.type.non-inventory' }, - ], - }, - name: { - name: 'item.field.name', - column: 'name', - fieldType: 'text', - }, - code: { - name: 'item.field.code', - column: 'code', - fieldType: 'text', - }, - sellable: { - name: 'item.field.sellable', - column: 'sellable', - fieldType: 'boolean', - }, - purchasable: { - name: 'item.field.purchasable', - column: 'purchasable', - fieldType: 'boolean', - }, - sell_price: { - name: 'item.field.sell_price', - column: 'sell_price', - fieldType: 'number', - }, - cost_price: { - name: 'item.field.cost_price', - column: 'cost_price', - fieldType: 'number', - }, - cost_account: { - name: 'item.field.cost_account', - column: 'cost_account_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'costAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - sell_account: { - name: 'item.field.sell_account', - column: 'sell_account_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'sellAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - inventory_account: { - name: 'item.field.inventory_account', - column: 'inventory_account_id', - - relationType: 'enumeration', - relationKey: 'inventoryAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - sell_description: { - name: 'Sell description', - column: 'sell_description', - fieldType: 'text', - }, - purchase_description: { - name: 'Purchase description', - column: 'purchase_description', - fieldType: 'text', - }, - quantity_on_hand: { - name: 'item.field.quantity_on_hand', - column: 'quantity_on_hand', - fieldType: 'number', - }, - note: { - name: 'item.field.note', - column: 'note', - fieldType: 'text', - }, - category: { - name: 'item.field.category', - column: 'category_id', - - relationType: 'enumeration', - relationKey: 'category', - - relationEntityLabel: 'name', - relationEntityKey: 'id', - }, - active: { - name: 'item.field.active', - column: 'active', - fieldType: 'boolean', - filterable: false, - }, - created_at: { - name: 'item.field.created_at', - column: 'created_at', - columnType: 'date', - fieldType: 'date', - }, - }, - columns: { - type: { - name: 'item.field.type', - type: 'text', - exportable: true, - accessor: 'typeFormatted', - }, - name: { - name: 'item.field.name', - type: 'text', - exportable: true, - }, - code: { - name: 'item.field.code', - type: 'text', - exportable: true, - }, - sellable: { - name: 'item.field.sellable', - type: 'boolean', - exportable: true, - printable: false, - }, - purchasable: { - name: 'item.field.purchasable', - type: 'boolean', - exportable: true, - printable: false, - }, - sellPrice: { - name: 'item.field.sell_price', - type: 'number', - exportable: true, - }, - costPrice: { - name: 'item.field.cost_price', - type: 'number', - exportable: true, - }, - costAccount: { - name: 'item.field.cost_account', - type: 'text', - accessor: 'costAccount.name', - exportable: true, - printable: false, - }, - sellAccount: { - name: 'item.field.sell_account', - type: 'text', - accessor: 'sellAccount.name', - exportable: true, - printable: false, - }, - inventoryAccount: { - name: 'item.field.inventory_account', - type: 'text', - accessor: 'inventoryAccount.name', - exportable: true, - }, - sellDescription: { - name: 'Sell description', - type: 'text', - exportable: true, - printable: false, - }, - purchaseDescription: { - name: 'Purchase description', - type: 'text', - exportable: true, - printable: false, - }, - quantityOnHand: { - name: 'item.field.quantity_on_hand', - type: 'number', - exportable: true, - }, - note: { - name: 'item.field.note', - type: 'text', - exportable: true, - }, - category: { - name: 'item.field.category', - type: 'text', - accessor: 'category.name', - exportable: true, - }, - active: { - name: 'item.field.active', - fieldType: 'boolean', - exportable: true, - printable: false, - }, - createdAt: { - name: 'item.field.created_at', - type: 'date', - exportable: true, - printable: false, - }, - }, - fields2: { - type: { - name: 'item.field.type', - fieldType: 'enumeration', - options: [ - { key: 'inventory', label: 'item.field.type.inventory' }, - { key: 'service', label: 'item.field.type.service' }, - { key: 'non-inventory', label: 'item.field.type.non-inventory' }, - ], - required: true, - }, - name: { - name: 'item.field.name', - fieldType: 'text', - required: true, - }, - code: { - name: 'item.field.code', - fieldType: 'text', - }, - sellable: { - name: 'item.field.sellable', - fieldType: 'boolean', - }, - purchasable: { - name: 'item.field.purchasable', - fieldType: 'boolean', - }, - sellPrice: { - name: 'item.field.sell_price', - fieldType: 'number', - }, - costPrice: { - name: 'item.field.cost_price', - fieldType: 'number', - }, - costAccountId: { - name: 'item.field.cost_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - importHint: 'Matches the account name or code.', - }, - sellAccountId: { - name: 'item.field.sell_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - importHint: 'Matches the account name or code.', - }, - inventoryAccountId: { - name: 'item.field.inventory_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - importHint: 'Matches the account name or code.', - }, - sellDescription: { - name: 'Sell Description', - fieldType: 'text', - }, - purchaseDescription: { - name: 'Purchase Description', - fieldType: 'text', - }, - note: { - name: 'item.field.note', - fieldType: 'text', - }, - categoryId: { - name: 'item.field.category', - fieldType: 'relation', - relationModel: 'ItemCategory', - relationImportMatch: ['name'], - importHint: 'Matches the category name.', - }, - active: { - name: 'item.field.active', - fieldType: 'boolean', - }, - }, -}; diff --git a/packages/server/src/models/Item.ts b/packages/server/src/models/Item.ts deleted file mode 100644 index 45e5afd2f..000000000 --- a/packages/server/src/models/Item.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import { buildFilterQuery } from '@/lib/ViewRolesBuilder'; -import ItemSettings from './Item.Settings'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Items/constants'; -import ModelSearchable from './ModelSearchable'; - -export default class Item extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'items'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Allows to mark model as resourceable to viewable and filterable. - */ - static get resourceable() { - return true; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - sortBy(query, columnSort, sortDirection) { - query.orderBy(columnSort, sortDirection); - }, - viewRolesBuilder(query, conditions, logicExpression) { - buildFilterQuery(Item.tableName, conditions, logicExpression)(query); - }, - - /** - * Inactive/Active mode. - */ - inactiveMode(query, active = false) { - query.where('items.active', !active); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Media = require('models/Media'); - const Account = require('models/Account'); - const ItemCategory = require('models/ItemCategory'); - const ItemWarehouseQuantity = require('models/ItemWarehouseQuantity'); - const ItemEntry = require('models/ItemEntry'); - const WarehouseTransferEntry = require('models/WarehouseTransferEntry'); - const InventoryAdjustmentEntry = require('models/InventoryAdjustmentEntry'); - const TaxRate = require('models/TaxRate'); - - return { - /** - * Item may belongs to cateogory model. - */ - category: { - relation: Model.BelongsToOneRelation, - modelClass: ItemCategory.default, - join: { - from: 'items.categoryId', - to: 'items_categories.id', - }, - }, - - /** - * Item may belongs to cost account. - */ - costAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'items.costAccountId', - to: 'accounts.id', - }, - }, - - /** - * Item may belongs to sell account. - */ - sellAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'items.sellAccountId', - to: 'accounts.id', - }, - }, - - /** - * Item may belongs to inventory account. - */ - inventoryAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'items.inventoryAccountId', - to: 'accounts.id', - }, - }, - - /** - * Item has many warehouses quantities. - */ - itemWarehouses: { - relation: Model.HasManyRelation, - modelClass: ItemWarehouseQuantity.default, - join: { - from: 'items.id', - to: 'items_warehouses_quantity.itemId', - }, - }, - - /** - * Item may has many item entries. - */ - itemEntries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'items.id', - to: 'items_entries.itemId', - }, - }, - - /** - * Item may has many warehouses transfers entries. - */ - warehousesTransfersEntries: { - relation: Model.HasManyRelation, - modelClass: WarehouseTransferEntry.default, - join: { - from: 'items.id', - to: 'warehouses_transfers_entries.itemId', - }, - }, - - /** - * Item has many inventory adjustment entries. - */ - inventoryAdjustmentsEntries: { - relation: Model.HasManyRelation, - modelClass: InventoryAdjustmentEntry.default, - join: { - from: 'items.id', - to: 'inventory_adjustments_entries.itemId', - }, - }, - - /** - * - */ - media: { - relation: Model.ManyToManyRelation, - modelClass: Media.default, - join: { - from: 'items.id', - through: { - from: 'media_links.model_id', - to: 'media_links.media_id', - }, - to: 'media.id', - }, - }, - - /** - * Item may has sell tax rate. - */ - sellTaxRate: { - relation: Model.BelongsToOneRelation, - modelClass: TaxRate.default, - join: { - from: 'items.sellTaxRateId', - to: 'tax_rates.id', - }, - }, - - /** - * Item may has purchase tax rate. - */ - purchaseTaxRate: { - relation: Model.BelongsToOneRelation, - modelClass: TaxRate.default, - join: { - from: 'items.purchaseTaxRateId', - to: 'tax_rates.id', - }, - }, - }; - } - - /** - * - */ - static get secureDeleteRelations() { - return [ - 'itemEntries', - 'inventoryAdjustmentsEntries', - 'warehousesTransfersEntries', - ]; - } - - /** - * Model settings. - */ - static get meta() { - return ItemSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search roles. - */ - static get searchRoles() { - return [ - { fieldKey: 'name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'code', comparator: 'like' }, - ]; - } -} diff --git a/packages/server/src/models/ItemCategory.Settings.ts b/packages/server/src/models/ItemCategory.Settings.ts deleted file mode 100644 index 66b7af28f..000000000 --- a/packages/server/src/models/ItemCategory.Settings.ts +++ /dev/null @@ -1,62 +0,0 @@ -export default { - defaultFilterField: 'name', - defaultSort: { - sortField: 'name', - sortOrder: 'DESC', - }, - importable: true, - exportable: true, - fields: { - name: { - name: 'item_category.field.name', - column: 'name', - fieldType: 'text', - }, - description: { - name: 'item_category.field.description', - column: 'description', - fieldType: 'text', - }, - count: { - name: 'item_category.field.count', - column: 'count', - fieldType: 'number', - virtualColumn: true, - }, - created_at: { - name: 'item_category.field.created_at', - column: 'created_at', - columnType: 'date', - }, - }, - columns: { - name: { - name: 'item_category.field.name', - type: 'text', - }, - description: { - name: 'item_category.field.description', - type: 'text', - }, - count: { - name: 'item_category.field.count', - type: 'text', - }, - createdAt: { - name: 'item_category.field.created_at', - type: 'text', - }, - }, - fields2: { - name: { - name: 'item_category.field.name', - column: 'name', - fieldType: 'text', - }, - description: { - name: 'item_category.field.description', - column: 'description', - fieldType: 'text', - }, - }, -}; diff --git a/packages/server/src/models/ItemCategory.ts b/packages/server/src/models/ItemCategory.ts deleted file mode 100644 index ef11ada3f..000000000 --- a/packages/server/src/models/ItemCategory.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import ItemCategorySettings from './ItemCategory.Settings'; - -export default class ItemCategory extends mixin(TenantModel, [ModelSetting]) { - /** - * Table name. - */ - static get tableName() { - return 'items_categories'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Item = require('models/Item'); - - return { - /** - * Item category may has many items. - */ - items: { - relation: Model.HasManyRelation, - modelClass: Item.default, - join: { - from: 'items_categories.id', - to: 'items.categoryId', - }, - }, - }; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Inactive/Active mode. - */ - sortByCount(query, order = 'asc') { - query.orderBy('count', order); - }, - }; - } - - /** - * Model meta. - */ - static get meta() { - return ItemCategorySettings; - } -} diff --git a/packages/server/src/models/ItemEntry.ts b/packages/server/src/models/ItemEntry.ts deleted file mode 100644 index 3152779ce..000000000 --- a/packages/server/src/models/ItemEntry.ts +++ /dev/null @@ -1,267 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import { getExlusiveTaxAmount, getInclusiveTaxAmount } from '@/utils/taxRate'; -import { DiscountType } from '@/interfaces'; - -// Subtotal (qty * rate) (tax inclusive) -// Subtotal Tax Exclusive (Subtotal - Tax Amount) -// Discount (Is percentage ? amount * discount : discount) -// Total (Subtotal - Discount) - -export default class ItemEntry extends TenantModel { - public taxRate: number; - public discount: number; - public quantity: number; - public rate: number; - public isInclusiveTax: number; - public discountType: DiscountType; - /** - * Table name. - * @returns {string} - */ - static get tableName() { - return 'items_entries'; - } - - /** - * Timestamps columns. - * @returns {string[]} - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - * @returns {string[]} - */ - static get virtualAttributes() { - return [ - // Amount (qty * rate) - 'amount', - - 'taxAmount', - - // Subtotal (qty * rate) + (tax inclusive) - 'subtotalInclusingTax', - - // Subtotal Tax Exclusive (Subtotal - Tax Amount) - 'subtotalExcludingTax', - - // Subtotal (qty * rate) + (tax inclusive) - 'subtotal', - - // Discount (Is percentage ? amount * discount : discount) - 'discountAmount', - - // Total (Subtotal - Discount) - 'total', - ]; - } - - /** - * Item entry total. - * Amount of item entry includes tax and subtracted discount amount. - * @returns {number} - */ - get total() { - return this.subtotal - this.discountAmount; - } - - /** - * Total (excluding tax). - * @returns {number} - */ - get totalExcludingTax() { - return this.subtotalExcludingTax - this.discountAmount; - } - - /** - * Item entry amount. - * Amount of item entry that may include or exclude tax. - * @returns {number} - */ - get amount() { - return this.quantity * this.rate; - } - - /** - * Subtotal amount (tax inclusive). - * @returns {number} - */ - get subtotal() { - return this.subtotalInclusingTax; - } - - /** - * Item entry amount including tax. - * @returns {number} - */ - get subtotalInclusingTax() { - return this.isInclusiveTax ? this.amount : this.amount + this.taxAmount; - } - - /** - * Subtotal amount (tax exclusive). - * @returns {number} - */ - get subtotalExcludingTax() { - return this.isInclusiveTax ? this.amount - this.taxAmount : this.amount; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Percentage - ? this.amount * (this.discount / 100) - : this.discount; - } - - /** - * Tag rate fraction. - * @returns {number} - */ - get tagRateFraction() { - return this.taxRate / 100; - } - - /** - * Tax amount withheld. - * @returns {number} - */ - get taxAmount() { - return this.isInclusiveTax - ? getInclusiveTaxAmount(this.amount, this.taxRate) - : getExlusiveTaxAmount(this.amount, this.taxRate); - } - - static calcAmount(itemEntry) { - const { discount, quantity, rate } = itemEntry; - const total = quantity * rate; - - return discount ? total - total * discount * 0.01 : total; - } - - /** - * Item entry relations. - */ - static get relationMappings() { - const Item = require('models/Item'); - const BillLandedCostEntry = require('models/BillLandedCostEntry'); - const SaleInvoice = require('models/SaleInvoice'); - const Bill = require('models/Bill'); - const SaleReceipt = require('models/SaleReceipt'); - const SaleEstimate = require('models/SaleEstimate'); - const ProjectTask = require('models/Task'); - const Expense = require('models/Expense'); - const TaxRate = require('models/TaxRate'); - - return { - item: { - relation: Model.BelongsToOneRelation, - modelClass: Item.default, - join: { - from: 'items_entries.itemId', - to: 'items.id', - }, - }, - allocatedCostEntries: { - relation: Model.HasManyRelation, - modelClass: BillLandedCostEntry.default, - join: { - from: 'items_entries.referenceId', - to: 'bill_located_cost_entries.entryId', - }, - }, - - invoice: { - relation: Model.BelongsToOneRelation, - modelClass: SaleInvoice.default, - join: { - from: 'items_entries.referenceId', - to: 'sales_invoices.id', - }, - }, - - bill: { - relation: Model.BelongsToOneRelation, - modelClass: Bill.default, - join: { - from: 'items_entries.referenceId', - to: 'bills.id', - }, - }, - - estimate: { - relation: Model.BelongsToOneRelation, - modelClass: SaleEstimate.default, - join: { - from: 'items_entries.referenceId', - to: 'sales_estimates.id', - }, - }, - - /** - * Sale receipt reference. - */ - receipt: { - relation: Model.BelongsToOneRelation, - modelClass: SaleReceipt.default, - join: { - from: 'items_entries.referenceId', - to: 'sales_receipts.id', - }, - }, - - /** - * Project task reference. - */ - projectTaskRef: { - relation: Model.HasManyRelation, - modelClass: ProjectTask.default, - join: { - from: 'items_entries.projectRefId', - to: 'tasks.id', - }, - }, - - /** - * Project expense reference. - */ - projectExpenseRef: { - relation: Model.HasManyRelation, - modelClass: Expense.default, - join: { - from: 'items_entries.projectRefId', - to: 'expenses_transactions.id', - }, - }, - - /** - * Project bill reference. - */ - projectBillRef: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'items_entries.projectRefId', - to: 'bills.id', - }, - }, - - /** - * Tax rate reference. - */ - tax: { - relation: Model.HasOneRelation, - modelClass: TaxRate.default, - join: { - from: 'items_entries.taxRateId', - to: 'tax_rates.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/ItemWarehouseQuantity.ts b/packages/server/src/models/ItemWarehouseQuantity.ts deleted file mode 100644 index f90989c94..000000000 --- a/packages/server/src/models/ItemWarehouseQuantity.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class ItemWarehouseQuantity extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'items_warehouses_quantity'; - } - - static get relationMappings() { - const Item = require('models/Item'); - const Warehouse = require('models/Warehouse'); - - return { - item: { - relation: Model.BelongsToOneRelation, - modelClass: Item.default, - join: { - from: 'items_warehouses_quantity.itemId', - to: 'items.id', - }, - }, - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'items_warehouses_quantity.warehouseId', - to: 'warehouses.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/ManualJournal.Settings.ts b/packages/server/src/models/ManualJournal.Settings.ts deleted file mode 100644 index 84ce31367..000000000 --- a/packages/server/src/models/ManualJournal.Settings.ts +++ /dev/null @@ -1,230 +0,0 @@ -export default { - defaultFilterField: 'date', - defaultSort: { - sortOrder: 'DESC', - sortField: 'name', - }, - importable: true, - exportFlattenOn: 'entries', - - exportable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'journalNumber', - - print: { - pageTitle: 'Manual Journals', - }, - - fields: { - date: { - name: 'manual_journal.field.date', - column: 'date', - fieldType: 'date', - }, - journal_number: { - name: 'manual_journal.field.journal_number', - column: 'journal_number', - fieldType: 'text', - }, - reference: { - name: 'manual_journal.field.reference', - column: 'reference', - fieldType: 'text', - }, - journal_type: { - name: 'manual_journal.field.journal_type', - column: 'journal_type', - fieldType: 'text', - }, - amount: { - name: 'manual_journal.field.amount', - column: 'amount', - fieldType: 'number', - }, - description: { - name: 'manual_journal.field.description', - column: 'description', - fieldType: 'text', - }, - status: { - name: 'manual_journal.field.status', - column: 'status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'Draft' }, - { key: 'published', label: 'published' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - created_at: { - name: 'manual_journal.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - date: { - name: 'manual_journal.field.date', - type: 'date', - accessor: 'formattedDate', - }, - journalNumber: { - name: 'manual_journal.field.journal_number', - type: 'text', - }, - reference: { - name: 'manual_journal.field.reference', - type: 'text', - }, - journalType: { - name: 'manual_journal.field.journal_type', - type: 'text', - }, - amount: { - name: 'Amount', - accessor: 'formattedAmount', - }, - currencyCode: { - name: 'manual_journal.field.currency', - type: 'text', - printable: false, - }, - exchangeRate: { - name: 'manual_journal.field.exchange_rate', - type: 'number', - printable: false, - }, - description: { - name: 'manual_journal.field.description', - type: 'text', - }, - entries: { - name: 'Entries', - type: 'collection', - collectionOf: 'object', - columns: { - credit: { - name: 'Credit', - type: 'text', - }, - debit: { - name: 'Debit', - type: 'text', - }, - account: { - name: 'Account', - accessor: 'account.name', - }, - contact: { - name: 'Contact', - accessor: 'contact.displayName', - }, - note: { - name: 'Note', - }, - }, - publish: { - name: 'Publish', - type: 'boolean', - printable: false, - }, - publishedAt: { - name: 'Published At', - printable: false, - }, - }, - createdAt: { - name: 'Created At', - accessor: 'formattedCreatedAt', - printable: false, - }, - }, - fields2: { - date: { - name: 'manual_journal.field.date', - fieldType: 'date', - required: true, - }, - journalNumber: { - name: 'manual_journal.field.journal_number', - fieldType: 'text', - required: true, - }, - reference: { - name: 'manual_journal.field.reference', - fieldType: 'text', - }, - journalType: { - name: 'manual_journal.field.journal_type', - fieldType: 'text', - }, - currencyCode: { - name: 'manual_journal.field.currency', - fieldType: 'text', - }, - exchange_rate: { - name: 'manual_journal.field.exchange_rate', - fieldType: 'number', - }, - description: { - name: 'manual_journal.field.description', - fieldType: 'text', - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 2, - required: true, - fields: { - credit: { - name: 'Credit', - fieldType: 'number', - required: true, - }, - debit: { - name: 'Debit', - fieldType: 'number', - required: true, - }, - accountId: { - name: 'Account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - }, - contact: { - name: 'Contact', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: 'displayName', - }, - note: { - name: 'Note', - fieldType: 'text', - }, - }, - }, - publish: { - name: 'Publish', - fieldType: 'boolean', - }, - }, -}; - -/** - * Status field sorting custom query. - */ -function StatusFieldSortQuery(query, role) { - return query.modify('sortByStatus', role.order); -} - -/** - * Status field filter custom query. - */ -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} diff --git a/packages/server/src/models/ManualJournal.ts b/packages/server/src/models/ManualJournal.ts deleted file mode 100644 index 945af2aad..000000000 --- a/packages/server/src/models/ManualJournal.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import { formatNumber } from 'utils'; -import ModelSetting from './ModelSetting'; -import ManualJournalSettings from './ManualJournal.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/ManualJournals/constants'; -import ModelSearchable from './ModelSearchable'; -export default class ManualJournal extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name. - */ - static get tableName() { - return 'manual_journals'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['isPublished', 'amountFormatted']; - } - - /** - * Retrieve the amount formatted value. - */ - get amountFormatted() { - return formatNumber(this.amount, { currencyCode: this.currencyCode }); - } - - /** - * Detarmines whether the invoice is published. - * @return {boolean} - */ - get isPublished() { - return !!this.publishedAt; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Sort by status query. - */ - sortByStatus(query, order) { - query.orderByRaw(`PUBLISHED_AT IS NULL ${order}`); - }, - - /** - * Filter by draft status. - */ - filterByDraft(query) { - query.whereNull('publishedAt'); - }, - - /** - * Filter by published status. - */ - filterByPublished(query) { - query.whereNotNull('publishedAt'); - }, - - /** - * Filter by the given status. - */ - filterByStatus(query, filterType) { - switch (filterType) { - case 'draft': - query.modify('filterByDraft'); - break; - case 'published': - default: - query.modify('filterByPublished'); - break; - } - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const AccountTransaction = require('models/AccountTransaction'); - const ManualJournalEntry = require('models/ManualJournalEntry'); - const Document = require('models/Document'); - const { MatchedBankTransaction } = require('models/MatchedBankTransaction'); - - return { - entries: { - relation: Model.HasManyRelation, - modelClass: ManualJournalEntry.default, - join: { - from: 'manual_journals.id', - to: 'manual_journals_entries.manualJournalId', - }, - filter(query) { - query.orderBy('index', 'ASC'); - }, - }, - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'manual_journals.id', - to: 'accounts_transactions.referenceId', - }, - filter: (query) => { - query.where('referenceType', 'Journal'); - }, - }, - - /** - * Manual journal may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'manual_journals.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'ManualJournal'); - }, - }, - - /** - * Manual journal may belongs to matched bank transaction. - */ - matchedBankTransaction: { - relation: Model.BelongsToOneRelation, - modelClass: MatchedBankTransaction, - join: { - from: 'manual_journals.id', - to: 'matched_bank_transactions.referenceId', - }, - filter(query) { - query.where('reference_type', 'ManualJournal'); - }, - }, - }; - } - - static get meta() { - return ManualJournalSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'journal_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/ManualJournalEntry.ts b/packages/server/src/models/ManualJournalEntry.ts deleted file mode 100644 index 15d1ce79a..000000000 --- a/packages/server/src/models/ManualJournalEntry.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class ManualJournalEntry extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'manual_journals_entries'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - const Contact = require('models/Contact'); - const Branch = require('models/Branch'); - - return { - account: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'manual_journals_entries.accountId', - to: 'accounts.id', - }, - }, - contact: { - relation: Model.BelongsToOneRelation, - modelClass: Contact.default, - join: { - from: 'manual_journals_entries.contactId', - to: 'contacts.id', - }, - }, - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'manual_journals_entries.branchId', - to: 'branches.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/MatchedBankTransaction.ts b/packages/server/src/models/MatchedBankTransaction.ts deleted file mode 100644 index 4d5df6315..000000000 --- a/packages/server/src/models/MatchedBankTransaction.ts +++ /dev/null @@ -1,32 +0,0 @@ -import TenantModel from 'models/TenantModel'; -import { Model } from 'objection'; - -export class MatchedBankTransaction extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'matched_bank_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - return {}; - } -} diff --git a/packages/server/src/models/Media.ts b/packages/server/src/models/Media.ts deleted file mode 100644 index aab3aa227..000000000 --- a/packages/server/src/models/Media.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class Media extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'media'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const MediaLink = require('models/MediaLink'); - - return { - links: { - relation: Model.HasManyRelation, - modelClass: MediaLink.default, - join: { - from: 'media.id', - to: 'media_links.media_id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/MediaLink.ts b/packages/server/src/models/MediaLink.ts deleted file mode 100644 index 78f9d4888..000000000 --- a/packages/server/src/models/MediaLink.ts +++ /dev/null @@ -1,10 +0,0 @@ -import TenantModel from 'models/TenantModel'; - -export default class MediaLink extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'media_links'; - } -} diff --git a/packages/server/src/models/Metable.ts b/packages/server/src/models/Metable.ts deleted file mode 100644 index 8522120fe..000000000 --- a/packages/server/src/models/Metable.ts +++ /dev/null @@ -1,281 +0,0 @@ -import knex from '@/database/knex'; -// import cache from 'memory-cache'; - -// Metadata -export default { - METADATA_GROUP: 'default', - KEY_COLUMN: 'key', - VALUE_COLUMN: 'value', - TYPE_COLUMN: 'type', - - extraColumns: [], - metadata: [], - shouldReload: true, - extraMetadataQuery: () => {}, - - /** - * Set the value column key to query from. - * @param {String} name - - */ - setKeyColumnName(name) { - this.KEY_COLUMN = name; - }, - - /** - * Set the key column name to query from. - * @param {String} name - - */ - setValueColumnName(name) { - this.VALUE_COLUMN = name; - }, - - /** - * Set extra columns to be added to the rows. - * @param {Array} columns - - */ - setExtraColumns(columns) { - this.extraColumns = columns; - }, - - /** - * Metadata database query. - * @param {Object} query - - * @param {String} groupName - - */ - whereQuery(query, key) { - const groupName = this.METADATA_GROUP; - - if (groupName) { - query.where('group', groupName); - } - if (key) { - if (Array.isArray(key)) { - query.whereIn('key', key); - } else { - query.where('key', key); - } - } - }, - - /** - * Loads the metadata from the storage. - * @param {String|Array} key - - * @param {Boolean} force - - */ - async load(force = false) { - if (this.shouldReload || force) { - const metadataCollection = await this.query((query) => { - this.whereQuery(query); - this.extraMetadataQuery(query); - }).fetchAll(); - - this.shouldReload = false; - this.metadata = []; - - const metadataArray = this.mapMetadataCollection(metadataCollection); - metadataArray.forEach((metadata) => { this.metadata.push(metadata); }); - } - }, - - /** - * Fetches all the metadata that associate with the current group. - */ - async allMeta(force = false) { - await this.load(force); - return this.metadata; - }, - - /** - * Find the given metadata key. - * @param {String} key - - * @return {object} - Metadata object. - */ - findMeta(key) { - return this.metadata.find((meta) => meta.key === key); - }, - - /** - * Fetch the metadata of the current group. - * @param {*} key - - */ - async getMeta(key, defaultValue, force = false) { - await this.load(force); - - const metadata = this.findMeta(key); - return metadata ? metadata.value : defaultValue || false; - }, - - /** - * Markes the metadata to should be deleted. - * @param {String} key - - */ - async removeMeta(key) { - await this.load(); - const metadata = this.findMeta(key); - - if (metadata) { - metadata.markAsDeleted = true; - } - this.shouldReload = true; - }, - - /** - * Remove all meta data of the given group. - * @param {*} group - */ - removeAllMeta(group = 'default') { - this.metdata.map((meta) => ({ - ...(meta.group !== group) ? { markAsDeleted: true } : {}, - ...meta, - })); - this.shouldReload = true; - }, - - /** - * Set the meta data to the stack. - * @param {String} key - - * @param {String} value - - */ - async setMeta(key, value, payload) { - if (Array.isArray(key)) { - const metadata = key; - metadata.forEach((meta) => { - this.setMeta(meta.key, meta.value); - }); - return; - } - - await this.load(); - const metadata = this.findMeta(key); - - if (metadata) { - metadata.value = value; - metadata.markAsUpdated = true; - } else { - this.metadata.push({ - value, key, ...payload, markAsInserted: true, - }); - } - }, - - /** - * Saved the modified metadata. - */ - async saveMeta() { - const inserted = this.metadata.filter((m) => (m.markAsInserted === true)); - const updated = this.metadata.filter((m) => (m.markAsUpdated === true)); - const deleted = this.metadata.filter((m) => (m.markAsDeleted === true)); - - const metadataDeletedKeys = deleted.map((m) => m.key); - const metadataInserted = inserted.map((m) => this.mapMetadata(m, 'format')); - const metadataUpdated = updated.map((m) => this.mapMetadata(m, 'format')); - - const batchUpdate = (collection) => knex.transaction((trx) => { - const queries = collection.map((tuple) => { - const query = knex(this.tableName); - this.whereQuery(query, tuple.key); - this.extraMetadataQuery(query); - return query.update(tuple).transacting(trx); - }); - return Promise.all(queries).then(trx.commit).catch(trx.rollback); - }); - - await Promise.all([ - knex.insert(metadataInserted).into(this.tableName), - batchUpdate(metadataUpdated), - metadataDeletedKeys.length > 0 - ? this.query('whereIn', this.KEY_COLUMN, metadataDeletedKeys).destroy({ - require: true, - }) : null, - ]); - this.shouldReload = true; - }, - - /** - * Purge all the cached metadata in the memory. - */ - purgeMetadata() { - this.metadata = []; - this.shouldReload = true; - }, - - /** - * Parses the metadata value. - * @param {String} value - - * @param {String} valueType - - */ - parseMetaValue(value, valueType) { - let parsedValue; - - switch (valueType) { - case 'integer': - parsedValue = parseInt(value, 10); - break; - case 'float': - parsedValue = parseFloat(value); - break; - case 'boolean': - parsedValue = Boolean(value); - break; - case 'json': - parsedValue = JSON.parse(parsedValue); - break; - default: - parsedValue = value; - break; - } - return parsedValue; - }, - - /** - * Format the metadata before saving to the database. - * @param {String|Number|Boolean} value - - * @param {String} valueType - - * @return {String|Number|Boolean} - - */ - formatMetaValue(value, valueType) { - let parsedValue; - - switch (valueType) { - case 'number': - parsedValue = `${value}`; - break; - case 'boolean': - parsedValue = value ? '1' : '0'; - break; - case 'json': - parsedValue = JSON.stringify(parsedValue); - break; - default: - parsedValue = value; - break; - } - return parsedValue; - }, - - mapMetadata(attr, parseType = 'parse') { - return { - key: attr[this.KEY_COLUMN], - value: (parseType === 'parse') - ? this.parseMetaValue( - attr[this.VALUE_COLUMN], - this.TYPE_COLUMN ? attr[this.TYPE_COLUMN] : false, - ) - : this.formatMetaValue( - attr[this.VALUE_COLUMN], - this.TYPE_COLUMN ? attr[this.TYPE_COLUMN] : false, - ), - ...this.extraColumns.map((extraCol) => ({ - [extraCol]: attr[extraCol] || null, - })), - }; - }, - - /** - * Parse the metadata collection. - * @param {Array} collection - - */ - mapMetadataCollection(collection, parseType = 'parse') { - return collection.map((model) => this.mapMetadata(model.attributes, parseType)); - }, -}; diff --git a/packages/server/src/models/Model.ts b/packages/server/src/models/Model.ts index b31c329b5..45d09b2f3 100644 --- a/packages/server/src/models/Model.ts +++ b/packages/server/src/models/Model.ts @@ -1,48 +1,43 @@ -import { Model, mixin } from 'objection'; -import { snakeCase, transform } from 'lodash'; -import { mapKeysDeep } from 'utils'; -import PaginationQueryBuilder from 'models/Pagination'; -import DateSession from 'models/DateSession'; +import { QueryBuilder, Model } from 'objection'; -export default class ModelBase extends mixin(Model, [DateSession]) { - get timestamps() { - return []; - } +interface PaginationResult { + results: M[]; + pagination: { + total: number; + page: number; + pageSize: number; + }; +} - static get knexBinded() { - return this.knexBindInstance; - } +export type PaginationQueryBuilderType = QueryBuilder< + M, + PaginationResult +>; - static set knexBinded(knex) { - this.knexBindInstance = knex; - } - - static get collection() { - return Array; - } - - static query(...args) { - return super.query(...args).runAfter((result) => { - if (Array.isArray(result)) { - return this.collection.from(result); - } - return result; - }); - } - - static get QueryBuilder() { - return PaginationQueryBuilder; - } - - static relationBindKnex(model) { - return this.knexBinded ? model.bindKnex(this.knexBinded) : model; - } - - static changeAmount(whereAttributes, attribute, amount, trx) { - const changeMethod = amount > 0 ? 'increment' : 'decrement'; - - return this.query(trx) - .where(whereAttributes) - [changeMethod](attribute, Math.abs(amount)); +class PaginationQueryBuilder extends QueryBuilder< + M, + R +> { + pagination(page: number, pageSize: number): PaginationQueryBuilderType { + const query = super.page(page, pageSize); + + return query.runAfter(({ results, total }) => { + return { + results, + pagination: { + total, + page: page + 1, + pageSize, + }, + }; + }) as unknown as PaginationQueryBuilderType; } } + +export class BaseModel extends Model { + public readonly id: number; + public readonly tableName: string; + + QueryBuilderType!: PaginationQueryBuilder; + static QueryBuilder = PaginationQueryBuilder; +} diff --git a/packages/server/src/models/ModelSearchable.ts b/packages/server/src/models/ModelSearchable.ts deleted file mode 100644 index 511a9f4d7..000000000 --- a/packages/server/src/models/ModelSearchable.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { IModelMeta, ISearchRole } from '@/interfaces'; - -export default (Model) => - class ModelSearchable extends Model { - /** - * Searchable model. - */ - static get searchable(): IModelMeta { - throw true; - } - - /** - * Search roles. - */ - static get searchRoles(): ISearchRole[] { - return []; - } - }; diff --git a/packages/server/src/models/ModelSetting.ts b/packages/server/src/models/ModelSetting.ts deleted file mode 100644 index bd96d32ae..000000000 --- a/packages/server/src/models/ModelSetting.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { get } from 'lodash'; -import { - IModelMeta, - IModelMetaField, - IModelMetaDefaultSort, -} from '@/interfaces'; - -const defaultModelMeta = { - fields: {}, - fields2: {}, -}; - -export default (Model) => - class ModelSettings extends Model { - /** - * - * @returns {IModelMeta} - */ - static get meta(): IModelMeta { - throw new Error(''); - } - - /** - * Parsed meta merged with default emta. - * @returns {IModelMeta} - */ - static get parsedMeta(): IModelMeta { - return { - ...defaultModelMeta, - ...this.meta, - }; - } - - /** - * Retrieve specific model field meta of the given field key. - * @param {string} key - * @returns {IModelMetaField} - */ - public static getField(key: string, attribute?: string): IModelMetaField { - const field = get(this.meta.fields, key); - - return attribute ? get(field, attribute) : field; - } - - /** - * Retrieves the specific model meta. - * @param {string} key - * @returns - */ - public static getMeta(key?: string) { - return key ? get(this.parsedMeta, key) : this.parsedMeta; - } - - /** - * Retrieve the model meta fields. - * @return {{ [key: string]: IModelMetaField }} - */ - public static get fields(): { [key: string]: IModelMetaField } { - return this.getMeta('fields'); - } - - /** - * Retrieve the model default sort settings. - * @return {IModelMetaDefaultSort} - */ - public static get defaultSort(): IModelMetaDefaultSort { - return this.getMeta('defaultSort'); - } - - /** - * Retrieve the default filter field key. - * @return {string} - */ - public static get defaultFilterField(): string { - return this.getMeta('defaultFilterField'); - } - }; diff --git a/packages/server/src/models/Option.ts b/packages/server/src/models/Option.ts deleted file mode 100644 index 07fa6fb2d..000000000 --- a/packages/server/src/models/Option.ts +++ /dev/null @@ -1,30 +0,0 @@ -import TenantModel from 'models/TenantModel'; -import definedOptions from '@/data/options'; - - -export default class Option extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'options'; - } - - /** - * Validates the given options is defined or either not. - * @param {Array} options - * @return {Boolean} - */ - static validateDefined(options) { - const notDefined = []; - - options.forEach((option) => { - if (!definedOptions[option.group]) { - notDefined.push(option); - } else if (!definedOptions[option.group].some((o) => o.key === option.key)) { - notDefined.push(option); - } - }); - return notDefined; - } -} diff --git a/packages/server/src/models/Pagination.ts b/packages/server/src/models/Pagination.ts deleted file mode 100644 index 5d308e90e..000000000 --- a/packages/server/src/models/Pagination.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Model } from 'objection'; -import { castArray, omit, pick } from 'lodash'; -import { isEmpty } from 'lodash'; -import { ServiceError } from '@/exceptions'; - -export default class PaginationQueryBuilder extends Model.QueryBuilder { - pagination(page, pageSize) { - return super.page(page, pageSize).runAfter(({ results, total }) => { - return { - results, - pagination: { - total, - page: page + 1, - pageSize, - }, - }; - }); - } - - queryAndThrowIfHasRelations = ({ - type, - message, - excludeRelations = [], - includedRelations = [], - }) => { - const _excludeRelations = castArray(excludeRelations); - const _includedRelations = castArray(includedRelations); - - const model = this.modelClass(); - const modelRelations = Object.keys(model.relationMappings).filter( - (relation) => - [Model.HasManyRelation, Model.HasOneRelation].indexOf( - model.relationMappings[relation]?.relation - ) !== -1 - ); - const relations = model.secureDeleteRelations || modelRelations; - const filteredByIncluded = relations.filter((r) => - _includedRelations.includes(r) - ); - const filteredByExcluded = relations.filter( - (r) => !excludeRelations.includes(r) - ); - const filteredRelations = !isEmpty(_includedRelations) - ? filteredByIncluded - : !isEmpty(_excludeRelations) - ? filteredByExcluded - : relations; - - this.runAfter((model, query) => { - const nonEmptyRelations = filteredRelations.filter( - (relation) => !isEmpty(model[relation]) - ); - if (nonEmptyRelations.length > 0) { - throw new ServiceError(type || 'MODEL_HAS_RELATIONS', { message }); - } - return model; - }); - return this.onBuild((query) => { - filteredRelations.forEach((relation) => { - query.withGraphFetched(`${relation}(selectId)`).modifiers({ - selectId(builder) { - builder.select('id'); - }, - }); - }); - }); - }; -} diff --git a/packages/server/src/models/PaymentIntegration.ts b/packages/server/src/models/PaymentIntegration.ts deleted file mode 100644 index cb4c8c825..000000000 --- a/packages/server/src/models/PaymentIntegration.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export class PaymentIntegration extends Model { - paymentEnabled!: boolean; - payoutEnabled!: boolean; - - static get tableName() { - return 'payment_integrations'; - } - - static get idColumn() { - return 'id'; - } - - static get virtualAttributes() { - return ['fullEnabled']; - } - - static get jsonAttributes() { - return ['options']; - } - - get fullEnabled() { - return this.paymentEnabled && this.payoutEnabled; - } - - static get modifiers() { - return { - /** - * Query to filter enabled payment and payout. - */ - fullEnabled(query) { - query.where('paymentEnabled', true).andWhere('payoutEnabled', true); - }, - }; - } - - static get jsonSchema() { - return { - type: 'object', - required: ['name', 'service'], - properties: { - id: { type: 'integer' }, - service: { type: 'string' }, - paymentEnabled: { type: 'boolean' }, - payoutEnabled: { type: 'boolean' }, - accountId: { type: 'string' }, - options: { - type: 'object', - properties: { - bankAccountId: { type: 'number' }, - clearingAccountId: { type: 'number' }, - }, - }, - createdAt: { type: 'string', format: 'date-time' }, - updatedAt: { type: 'string', format: 'date-time' }, - }, - }; - } -} diff --git a/packages/server/src/models/PaymentReceive.Settings.ts b/packages/server/src/models/PaymentReceive.Settings.ts deleted file mode 100644 index aeb59b41f..000000000 --- a/packages/server/src/models/PaymentReceive.Settings.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { Features } from '@/interfaces'; - -export default { - importable: true, - - exportable: true, - exportFlattenOn: 'entries', - - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'paymentReceiveNo', - fields: { - customer: { - name: 'payment_receive.field.customer', - column: 'customer_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'customer', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - payment_date: { - name: 'payment_receive.field.payment_date', - column: 'payment_date', - fieldType: 'date', - }, - amount: { - name: 'payment_receive.field.amount', - column: 'amount', - fieldType: 'number', - }, - reference_no: { - name: 'payment_receive.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - deposit_account: { - name: 'payment_receive.field.deposit_account', - column: 'deposit_account_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'depositAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - payment_receive_no: { - name: 'payment_receive.field.payment_receive_no', - column: 'payment_receive_no', - fieldType: 'text', - }, - statement: { - name: 'payment_receive.field.statement', - column: 'statement', - fieldType: 'text', - }, - created_at: { - name: 'payment_receive.field.created_at', - column: 'created_at', - fieldDate: 'date', - }, - }, - columns: { - customer: { - name: 'payment_receive.field.customer', - accessor: 'customer.displayName', - type: 'text', - }, - paymentDate: { - name: 'payment_receive.field.payment_date', - type: 'date', - accessor: 'formattedPaymentDate', - }, - amount: { - name: 'payment_receive.field.amount', - type: 'number', - accessor: 'formattedAmount', - }, - referenceNo: { - name: 'payment_receive.field.reference_no', - type: 'text', - }, - depositAccount: { - name: 'payment_receive.field.deposit_account', - accessor: 'depositAccount.name', - type: 'text', - }, - paymentReceiveNo: { - name: 'payment_receive.field.payment_receive_no', - type: 'text', - }, - statement: { - name: 'payment_receive.field.statement', - type: 'text', - printable: false, - }, - entries: { - name: 'Entries', - accessor: 'entries', - type: 'collection', - collectionOf: 'object', - columns: { - date: { - name: 'Invoice date', - accessor: 'invoice.invoiceDateFormatted', - }, - invoiceNo: { - name: 'Invoice No.', - accessor: 'invoice.invoiceNo', - }, - invoiceRefNo: { - name: 'Invoice Reference No.', - accessor: 'invoice.referenceNo', - }, - invoiceAmount: { - name: 'Invoice Amount', - accessor: 'invoice.totalFormatted', - }, - paidAmount: { - name: 'Paid Amount', - accessor: 'paymentAmountFormatted', - }, - }, - }, - created_at: { - name: 'payment_receive.field.created_at', - type: 'date', - printable: false, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - customerId: { - name: 'payment_receive.field.customer', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: ['displayName'], - required: true, - }, - exchangeRate: { - name: 'payment_receive.field.exchange_rate', - fieldType: 'number', - }, - paymentDate: { - name: 'payment_receive.field.payment_date', - fieldType: 'date', - required: true, - }, - referenceNo: { - name: 'payment_receive.field.reference_no', - fieldType: 'text', - }, - depositAccountId: { - name: 'payment_receive.field.deposit_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the account name or code.', - }, - paymentReceiveNo: { - name: 'payment_receive.field.payment_receive_no', - fieldType: 'text', - importHint: 'The payment number should be unique.', - }, - statement: { - name: 'payment_receive.field.statement', - fieldType: 'text', - }, - entries: { - name: 'payment_receive.field.entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - invoiceId: { - name: 'payment_receive.field.invoice', - fieldType: 'relation', - relationModel: 'SaleInvoice', - relationImportMatch: 'invoiceNo', - required: true, - importHint: 'Matches the invoice number.', - }, - paymentAmount: { - name: 'payment_receive.field.entries.payment_amount', - fieldType: 'number', - required: true, - }, - }, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - }, -}; diff --git a/packages/server/src/models/PaymentReceive.ts b/packages/server/src/models/PaymentReceive.ts deleted file mode 100644 index cd7df23a6..000000000 --- a/packages/server/src/models/PaymentReceive.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import PaymentReceiveSettings from './PaymentReceive.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Sales/PaymentReceived/constants'; -import ModelSearchable from './ModelSearchable'; - -export default class PaymentReceive extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - amount!: number; - paymentAmount!: number; - exchangeRate!: number; - - /** - * Table name. - */ - static get tableName() { - return 'payment_receives'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['localAmount', 'total']; - } - - /** - * Payment receive amount in local currency. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Payment receive total. - * @returns {number} - */ - get total() { - return this.paymentAmount; - } - - /** - * Resourcable model. - */ - static get resourceable() { - return true; - } - - /* - * Relationship mapping. - */ - static get relationMappings() { - const PaymentReceiveEntry = require('models/PaymentReceiveEntry'); - const AccountTransaction = require('models/AccountTransaction'); - const Customer = require('models/Customer'); - const Account = require('models/Account'); - const Branch = require('models/Branch'); - const Document = require('models/Document'); - const { PdfTemplate } = require('models/PdfTemplate'); - - return { - customer: { - relation: Model.BelongsToOneRelation, - modelClass: Customer.default, - join: { - from: 'payment_receives.customerId', - to: 'contacts.id', - }, - filter: (query) => { - query.where('contact_service', 'customer'); - }, - }, - depositAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'payment_receives.depositAccountId', - to: 'accounts.id', - }, - }, - entries: { - relation: Model.HasManyRelation, - modelClass: PaymentReceiveEntry.default, - join: { - from: 'payment_receives.id', - to: 'payment_receives_entries.paymentReceiveId', - }, - filter: (query) => { - query.orderBy('index', 'ASC'); - }, - }, - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'payment_receives.id', - to: 'accounts_transactions.referenceId', - }, - filter: (builder) => { - builder.where('reference_type', 'PaymentReceive'); - }, - }, - - /** - * Payment receive may belongs to branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'payment_receives.branchId', - to: 'branches.id', - }, - }, - - /** - * Payment transaction may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'payment_receives.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'PaymentReceive'); - }, - }, - - /** - * Payment received may belongs to pdf branding template. - */ - pdfTemplate: { - relation: Model.BelongsToOneRelation, - modelClass: PdfTemplate, - join: { - from: 'payment_receives.pdfTemplateId', - to: 'pdf_templates.id', - }, - }, - }; - } - - /** - * - */ - static get meta() { - return PaymentReceiveSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'payment_receive_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/PaymentReceiveEntry.ts b/packages/server/src/models/PaymentReceiveEntry.ts deleted file mode 100644 index 7fcc6b2b0..000000000 --- a/packages/server/src/models/PaymentReceiveEntry.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class PaymentReceiveEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'payment_receives_entries'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const PaymentReceive = require('models/PaymentReceive'); - const SaleInvoice = require('models/SaleInvoice'); - - return { - /** - */ - payment: { - relation: Model.BelongsToOneRelation, - modelClass: PaymentReceive.default, - join: { - from: 'payment_receives_entries.paymentReceiveId', - to: 'payment_receives.id', - }, - }, - - /** - * The payment receive entry have have sale invoice. - */ - invoice: { - relation: Model.BelongsToOneRelation, - modelClass: SaleInvoice.default, - join: { - from: 'payment_receives_entries.invoiceId', - to: 'sales_invoices.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/PdfTemplate.ts b/packages/server/src/models/PdfTemplate.ts deleted file mode 100644 index 55f1556b3..000000000 --- a/packages/server/src/models/PdfTemplate.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { getUploadedObjectUri } from '@/services/Attachments/utils'; -import TenantModel from 'models/TenantModel'; - -export class PdfTemplate extends TenantModel { - public readonly attributes: Record; - - /** - * Table name. - */ - static get tableName() { - return 'pdf_templates'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Json schema. - */ - static get jsonSchema() { - return { - type: 'object', - properties: { - id: { type: 'integer' }, - templateName: { type: 'string' }, - attributes: { type: 'object' }, // JSON field definition - }, - }; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the due invoices. - */ - default(query) { - query.where('default', true); - }, - }; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['companyLogoUri']; - } - - /** - * Retrieves the company logo uri. - * @returns {string} - */ - get companyLogoUri() { - return this.attributes?.companyLogoKey - ? getUploadedObjectUri(this.attributes.companyLogoKey) - : ''; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - return {}; - } -} diff --git a/packages/server/src/models/PlaidItem.ts b/packages/server/src/models/PlaidItem.ts deleted file mode 100644 index aca189038..000000000 --- a/packages/server/src/models/PlaidItem.ts +++ /dev/null @@ -1,41 +0,0 @@ -import TenantModel from 'models/TenantModel'; - -export default class PlaidItem extends TenantModel { - pausedAt: Date; - - /** - * Table name. - */ - static get tableName() { - return 'plaid_items'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - return {}; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['isPaused']; - } - - /** - * Detarmines whether the Plaid item feeds syncing is paused. - * @return {boolean} - */ - get isPaused() { - return !!this.pausedAt; - } -} diff --git a/packages/server/src/models/Project.ts b/packages/server/src/models/Project.ts deleted file mode 100644 index 1d5560722..000000000 --- a/packages/server/src/models/Project.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { mixin, Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSetting from './ModelSetting'; -import ModelSearchable from './ModelSearchable'; - -export default class Project extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - costEstimate!: number; - deadline!: Date; - - /** - * Table name - */ - static get tableName() { - return 'projects'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - totalExpensesDetails(builder) { - builder - .withGraphFetched('expenses') - .modifyGraph('expenses', (builder) => { - builder.select(['projectId']); - builder.groupBy('projectId'); - - builder.sum('totalAmount as totalExpenses'); - builder.sum('invoicedAmount as totalInvoicedExpenses'); - }); - }, - - totalBillsDetails(builder) { - builder.withGraphFetched('tasks').modifyGraph('tasks', (builder) => { - builder.select(['projectId']); - builder.groupBy('projectId'); - - builder.modify('sumTotalActualHours'); - builder.modify('sumTotalEstimateHours'); - builder.modify('sumTotalInvoicedHours'); - - builder.modify('sumTotalActualAmount'); - builder.modify('sumTotalInvoicedAmount'); - builder.modify('sumTotalEstimateAmount'); - }); - }, - - totalTasksDetails(builder) { - builder.withGraphFetched('tasks').modifyGraph('tasks', (builder) => { - builder.select(['projectId']); - builder.groupBy('projectId'); - - builder.modify('sumTotalActualHours'); - builder.modify('sumTotalEstimateHours'); - builder.modify('sumTotalInvoicedHours'); - - builder.modify('sumTotalActualAmount'); - builder.modify('sumTotalInvoicedAmount'); - builder.modify('sumTotalEstimateAmount'); - }); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Contact = require('models/Contact'); - const Task = require('models/Task'); - const Time = require('models/Time'); - const Expense = require('models/Expense'); - const Bill = require('models/Bill'); - - return { - /** - * Belongs to customer model. - */ - contact: { - relation: Model.BelongsToOneRelation, - modelClass: Contact.default, - join: { - from: 'projects.contactId', - to: 'contacts.id', - }, - }, - - /** - * Project may has many associated tasks. - */ - tasks: { - relation: Model.HasManyRelation, - modelClass: Task.default, - join: { - from: 'projects.id', - to: 'tasks.projectId', - }, - }, - - /** - * Project may has many associated times. - */ - times: { - relation: Model.HasManyRelation, - modelClass: Time.default, - join: { - from: 'projects.id', - to: 'times.projectId', - }, - }, - - /** - * Project may has many associated expenses. - */ - expenses: { - relation: Model.HasManyRelation, - modelClass: Expense.default, - join: { - from: 'projects.id', - to: 'expenses_transactions.projectId', - }, - }, - - /** - * Project may has many associated bills. - */ - bills: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'projects.id', - to: 'bills.projectId', - }, - }, - }; - } -} diff --git a/packages/server/src/models/ProjectItemEntryRef.ts b/packages/server/src/models/ProjectItemEntryRef.ts deleted file mode 100644 index 797bc67c9..000000000 --- a/packages/server/src/models/ProjectItemEntryRef.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { mixin, Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSetting from './ModelSetting'; -import ModelSearchable from './ModelSearchable'; - -export default class ProjectItemEntryRef extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'projects_item_entries_links'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - static get relationMappings() { - const ItemEntry = require('models/ItemEntry'); - - return { - itemEntry: { - relation: Model.BelongsToOneRelation, - modelClass: ItemEntry.default, - join: { - from: 'projects_item_entries_links.itemEntryId', - to: 'items_entries.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/RecognizedBankTransaction.ts b/packages/server/src/models/RecognizedBankTransaction.ts deleted file mode 100644 index 3fcc8c48d..000000000 --- a/packages/server/src/models/RecognizedBankTransaction.ts +++ /dev/null @@ -1,79 +0,0 @@ -import TenantModel from 'models/TenantModel'; -import { Model } from 'objection'; - -export class RecognizedBankTransaction extends TenantModel { - public bankRuleId!: number; - public uncategorizedTransactionId!: number; - public assignedCategory!: string; - public assignedAccountId!: number; - public assignedPayee!: string; - public assignedMemo!: string; - - /** - * Table name. - */ - static get tableName() { - return 'recognized_bank_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const UncategorizedCashflowTransaction = require('./UncategorizedCashflowTransaction'); - const Account = require('./Account'); - const { BankRule } = require('./BankRule'); - - return { - /** - * Recognized bank transaction may belongs to uncategorized transactions. - */ - uncategorizedTransactions: { - relation: Model.HasManyRelation, - modelClass: UncategorizedCashflowTransaction.default, - join: { - from: 'recognized_bank_transactions.uncategorizedTransactionId', - to: 'uncategorized_cashflow_transactions.id', - }, - }, - - /** - * Recognized bank transaction may belongs to assign account. - */ - assignAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'recognized_bank_transactions.assignedAccountId', - to: 'accounts.id', - }, - }, - - /** - * Recognized bank transaction may belongs to bank rule. - */ - bankRule: { - relation: Model.BelongsToOneRelation, - modelClass: BankRule, - join: { - from: 'recognized_bank_transactions.bankRuleId', - to: 'bank_rules.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/RefundCreditNote.ts b/packages/server/src/models/RefundCreditNote.ts deleted file mode 100644 index c0c85ba6d..000000000 --- a/packages/server/src/models/RefundCreditNote.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSearchable from './ModelSearchable'; - -export default class RefundCreditNote extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name. - */ - static get tableName() { - return 'refund_credit_note_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /* - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - const CreditNote = require('models/CreditNote'); - - return { - fromAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'refund_credit_note_transactions.fromAccountId', - to: 'accounts.id', - }, - }, - creditNote: { - relation: Model.BelongsToOneRelation, - modelClass: CreditNote.default, - join: { - from: 'refund_credit_note_transactions.creditNoteId', - to: 'credit_notes.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/RefundVendorCredit.ts b/packages/server/src/models/RefundVendorCredit.ts deleted file mode 100644 index f81ae4713..000000000 --- a/packages/server/src/models/RefundVendorCredit.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSearchable from './ModelSearchable'; - -export default class RefundVendorCredit extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name. - */ - static get tableName() { - return 'refund_vendor_credit_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /* - * Relationship mapping. - */ - static get relationMappings() { - const VendorCredit = require('models/VendorCredit'); - const Account = require('models/Account'); - - return { - depositAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'refund_vendor_credit_transactions.depositAccountId', - to: 'accounts.id', - }, - }, - vendorCredit: { - relation: Model.BelongsToOneRelation, - modelClass: VendorCredit.default, - join: { - from: 'refund_vendor_credit_transactions.vendorCreditId', - to: 'vendor_credits.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/ResourcableModel.ts b/packages/server/src/models/ResourcableModel.ts deleted file mode 100644 index 289c2dfa3..000000000 --- a/packages/server/src/models/ResourcableModel.ts +++ /dev/null @@ -1,8 +0,0 @@ - - -export default class ResourceableModel { - - static get resourceable() { - return true; - } -} \ No newline at end of file diff --git a/packages/server/src/models/Role.ts b/packages/server/src/models/Role.ts deleted file mode 100644 index 3bad745ba..000000000 --- a/packages/server/src/models/Role.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; - - -export default class Role extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'roles'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const RolePermission = require('models/RolePermission'); - - return { - /** - * - */ - permissions: { - relation: Model.HasManyRelation, - modelClass: RolePermission.default, - join: { - from: 'roles.id', - to: 'role_permissions.roleId', - }, - }, - }; - } -} diff --git a/packages/server/src/models/RolePermission.ts b/packages/server/src/models/RolePermission.ts deleted file mode 100644 index 29d5bcf35..000000000 --- a/packages/server/src/models/RolePermission.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSearchable from './ModelSearchable'; - -export default class RolePermission extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'role_permissions'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Role = require('models/Role'); - - return { - /** - * - */ - role: { - relation: Model.BelongsToOneRelation, - modelClass: Role.default, - join: { - from: 'role_permissions.roleId', - to: 'roles.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/SaleEstimate.Settings.ts b/packages/server/src/models/SaleEstimate.Settings.ts deleted file mode 100644 index 490afc4f2..000000000 --- a/packages/server/src/models/SaleEstimate.Settings.ts +++ /dev/null @@ -1,294 +0,0 @@ -import { Features } from '@/interfaces'; - -export default { - defaultFilterField: 'estimate_date', - defaultSort: { - sortOrder: 'DESC', - sortField: 'estimate_date', - }, - exportable: true, - exportFlattenOn: 'entries', - - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'estimateNumber', - - print: { - pageTitle: 'Sale Estimates', - }, - - fields: { - amount: { - name: 'estimate.field.amount', - column: 'amount', - fieldType: 'number', - }, - estimate_number: { - name: 'estimate.field.estimate_number', - column: 'estimate_number', - fieldType: 'text', - }, - customer: { - name: 'estimate.field.customer', - column: 'customer_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'customer', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - estimate_date: { - name: 'estimate.field.estimate_date', - column: 'estimate_date', - fieldType: 'date', - }, - expiration_date: { - name: 'estimate.field.expiration_date', - column: 'expiration_date', - fieldType: 'date', - }, - reference_no: { - name: 'estimate.field.reference_no', - column: 'reference', - fieldType: 'text', - }, - note: { - name: 'estimate.field.note', - column: 'note', - fieldType: 'text', - }, - terms_conditions: { - name: 'estimate.field.terms_conditions', - column: 'terms_conditions', - fieldType: 'text', - }, - status: { - name: 'estimate.field.status', - fieldType: 'enumeration', - options: [ - { label: 'estimate.field.status.delivered', key: 'delivered' }, - { label: 'estimate.field.status.rejected', key: 'rejected' }, - { label: 'estimate.field.status.approved', key: 'approved' }, - { label: 'estimate.field.status.draft', key: 'draft' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - created_at: { - name: 'estimate.field.created_at', - column: 'created_at', - columnType: 'date', - }, - }, - columns: { - customer: { - name: 'Customer', - type: 'text', - accessor: 'customer.displayName', - exportable: true, - }, - estimateDate: { - name: 'Estimate Date', - type: 'date', - accessor: 'formattedEstimateDate', - exportable: true, - }, - expirationDate: { - name: 'Expiration Date', - type: 'date', - accessor: 'formattedExpirationDate', - exportable: true, - }, - estimateNumber: { - name: 'Estimate No.', - type: 'text', - exportable: true, - }, - reference: { - name: 'Reference No.', - type: 'text', - exportable: true, - }, - amount: { - name: 'Amount', - accessor: 'formattedAmount', - type: 'text', - }, - exchangeRate: { - name: 'Exchange Rate', - type: 'number', - exportable: true, - printable: false, - }, - currencyCode: { - name: 'Currency', - type: 'text', - exportable: true, - printable: false, - }, - note: { - name: 'Note', - type: 'text', - exportable: true, - printable: false, - }, - termsConditions: { - name: 'Terms & Conditions', - type: 'text', - exportable: true, - printable: false, - }, - delivered: { - name: 'Delivered', - type: 'boolean', - accessor: 'isDelivered', - exportable: true, - printable: false, - }, - entries: { - name: 'Entries', - accessor: 'entries', - type: 'collection', - collectionOf: 'object', - columns: { - itemName: { - name: 'Item Name', - accessor: 'item.name', - }, - rate: { - name: 'Item Rate', - accessor: 'rateFormatted', - }, - quantity: { - name: 'Item Quantity', - accessor: 'quantityFormatted', - }, - description: { - name: 'Item Description', - printable: false, - }, - amount: { - name: 'Item Amount', - accessor: 'totalFormatted', - }, - }, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - warehouse: { - name: 'Warehouse', - type: 'text', - accessor: 'warehouse.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - customerId: { - name: 'Customer', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: ['displayName'], - required: true, - }, - estimateDate: { - name: 'Estimate Date', - fieldType: 'date', - required: true, - }, - expirationDate: { - name: 'Expiration Date', - fieldType: 'date', - required: true, - }, - estimateNumber: { - name: 'Estimate No.', - fieldType: 'text', - }, - reference: { - name: 'Reference No.', - fieldType: 'text', - }, - exchangeRate: { - name: 'Exchange Rate', - fieldType: 'number', - }, - currencyCode: { - name: 'Currency', - fieldType: 'text', - }, - note: { - name: 'Note', - fieldType: 'text', - }, - termsConditions: { - name: 'Terms & Conditions', - fieldType: 'text', - }, - delivered: { - name: 'Delivered', - type: 'boolean', - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - itemId: { - name: 'invoice.field.item_name', - fieldType: 'relation', - relationModel: 'Item', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the item name or code.', - }, - rate: { - name: 'invoice.field.rate', - fieldType: 'number', - required: true, - }, - quantity: { - name: 'invoice.field.quantity', - fieldType: 'number', - required: true, - }, - description: { - name: 'Line Description', - fieldType: 'text', - }, - }, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - warehouseId: { - name: 'Warehouse', - fieldType: 'relation', - relationModel: 'Warehouse', - relationImportMatch: ['name', 'code'], - features: [Features.WAREHOUSES], - required: true, - }, - }, -}; - -function StatusFieldSortQuery(query, role) { - query.modify('orderByStatus', role.order); -} - -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} diff --git a/packages/server/src/models/SaleEstimate.ts b/packages/server/src/models/SaleEstimate.ts deleted file mode 100644 index fce0f334b..000000000 --- a/packages/server/src/models/SaleEstimate.ts +++ /dev/null @@ -1,380 +0,0 @@ -import moment from 'moment'; -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import { defaultToTransform } from 'utils'; -import SaleEstimateSettings from './SaleEstimate.Settings'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Sales/Estimates/constants'; -import ModelSearchable from './ModelSearchable'; -import { DiscountType } from '@/interfaces'; -import { defaultTo } from 'lodash'; - -export default class SaleEstimate extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - public amount: number; - public exchangeRate: number; - - public discount: number; - public discountType: DiscountType; - - public adjustment: number; - - public expirationDate!: string; - public deliveredAt!: string | null; - public approvedAt!: string | null; - public rejectedAt!: string | null; - - public convertedToInvoiceId!: number | null; - public convertedToInvoiceAt!: string | null; - - /** - * Table name - */ - static get tableName() { - return 'sales_estimates'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'localAmount', - 'discountAmount', - 'discountPercentage', - 'total', - 'totalLocal', - 'subtotal', - 'subtotalLocal', - 'isDelivered', - 'isExpired', - 'isConvertedToInvoice', - 'isApproved', - 'isRejected', - ]; - } - - /** - * Estimate amount in local currency. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Estimate subtotal. - * @returns {number} - */ - get subtotal() { - return this.amount;; - } - - /** - * Estimate subtotal in local currency. - * @returns {number} - */ - get subtotalLocal() { - return this.localAmount; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Amount - ? this.discount - : this.subtotal * (this.discount / 100); - } - - /** - * Discount percentage. - * @returns {number | null} - */ - get discountPercentage(): number | null { - return this.discountType === DiscountType.Percentage - ? this.discount - : null; - } - - /** - * Estimate total. - * @returns {number} - */ - get total() { - const adjustmentAmount = defaultTo(this.adjustment, 0); - - return this.subtotal - this.discountAmount + adjustmentAmount; - } - - /** - * Estimate total in local currency. - * @returns {number} - */ - get totalLocal() { - return this.total * this.exchangeRate; - } - - /** - * Detarmines whether the sale estimate converted to sale invoice. - * @return {boolean} - */ - get isConvertedToInvoice() { - return !!(this.convertedToInvoiceId && this.convertedToInvoiceAt); - } - - /** - * Detarmines whether the estimate is delivered. - * @return {boolean} - */ - get isDelivered() { - return !!this.deliveredAt; - } - - /** - * Detarmines whether the estimate is expired. - * @return {boolean} - */ - get isExpired() { - return defaultToTransform( - this.expirationDate, - moment().isAfter(this.expirationDate, 'day'), - false - ); - } - - /** - * Detarmines whether the estimate is approved. - * @return {boolean} - */ - get isApproved() { - return !!this.approvedAt; - } - - /** - * Detarmines whether the estimate is reject. - * @return {boolean} - */ - get isRejected() { - return !!this.rejectedAt; - } - - /** - * Allows to mark model as resourceable to viewable and filterable. - */ - static get resourceable() { - return true; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the drafted estimates transactions. - */ - draft(query) { - query.where('delivered_at', null); - }, - /** - * Filters the delivered estimates transactions. - */ - delivered(query) { - query.whereNot('delivered_at', null); - }, - /** - * Filters the expired estimates transactions. - */ - expired(query) { - query.where('expiration_date', '<', moment().format('YYYY-MM-DD')); - }, - /** - * Filters the rejected estimates transactions. - */ - rejected(query) { - query.whereNot('rejected_at', null); - }, - /** - * Filters the invoiced estimates transactions. - */ - invoiced(query) { - query.whereNot('converted_to_invoice_at', null); - }, - /** - * Filters the approved estimates transactions. - */ - approved(query) { - query.whereNot('approved_at', null); - }, - /** - * Sorting the estimates orders by delivery status. - */ - orderByStatus(query, order) { - query.orderByRaw(`delivered_at is null ${order}`); - }, - /** - * Filtering the estimates oreders by status field. - */ - filterByStatus(query, filterType) { - switch (filterType) { - case 'draft': - query.modify('draft'); - break; - case 'delivered': - query.modify('delivered'); - break; - case 'approved': - query.modify('approved'); - break; - case 'rejected': - query.modify('rejected'); - break; - case 'invoiced': - query.modify('invoiced'); - break; - case 'expired': - query.modify('expired'); - break; - } - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const ItemEntry = require('models/ItemEntry'); - const Customer = require('models/Customer'); - const Branch = require('models/Branch'); - const Warehouse = require('models/Warehouse'); - const Document = require('models/Document'); - const { PdfTemplate } = require('models/PdfTemplate'); - - return { - customer: { - relation: Model.BelongsToOneRelation, - modelClass: Customer.default, - join: { - from: 'sales_estimates.customerId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'customer'); - }, - }, - entries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'sales_estimates.id', - to: 'items_entries.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'SaleEstimate'); - builder.orderBy('index', 'ASC'); - }, - }, - - /** - * Sale estimate may belongs to branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'sales_estimates.branchId', - to: 'branches.id', - }, - }, - - /** - * Sale estimate may has associated warehouse. - */ - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'sales_estimates.warehouseId', - to: 'warehouses.id', - }, - }, - - /** - * Sale estimate transaction may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'sales_estimates.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'SaleEstimate'); - }, - }, - - /** - * Sale estimate may belongs to pdf branding template. - */ - pdfTemplate: { - relation: Model.BelongsToOneRelation, - modelClass: PdfTemplate, - join: { - from: 'sales_estimates.pdfTemplateId', - to: 'pdf_templates.id', - }, - }, - }; - } - - /** - * Model settings. - */ - static get meta() { - return SaleEstimateSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search roles. - */ - static get searchRoles() { - return [ - { fieldKey: 'amount', comparator: 'equals' }, - { condition: 'or', fieldKey: 'estimate_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/SaleEstimateEntry.ts b/packages/server/src/models/SaleEstimateEntry.ts deleted file mode 100644 index 35c3b5106..000000000 --- a/packages/server/src/models/SaleEstimateEntry.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - - -export default class SaleEstimateEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'sales_estimate_entries'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleEstimate = require('models/SaleEstimate'); - - return { - estimate: { - relation: Model.BelongsToOneRelation, - modelClass: SaleEstimate.default, - join: { - from: 'sales_estimates.id', - to: 'sales_estimate_entries.estimate_id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/SaleInvoice.Settings.ts b/packages/server/src/models/SaleInvoice.Settings.ts deleted file mode 100644 index 2992cd278..000000000 --- a/packages/server/src/models/SaleInvoice.Settings.ts +++ /dev/null @@ -1,316 +0,0 @@ -import { Features } from '@/interfaces'; - -export default { - defaultFilterField: 'customer', - defaultSort: { - sortOrder: 'DESC', - sortField: 'created_at', - }, - exportable: true, - exportFlattenOn: 'entries', - - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'invoiceNo', - - print: { - pageTitle: 'Sale invoices', - }, - fields: { - customer: { - name: 'invoice.field.customer', - column: 'customer_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'customer', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - invoice_date: { - name: 'invoice.field.invoice_date', - column: 'invoice_date', - fieldType: 'date', - }, - due_date: { - name: 'invoice.field.due_date', - column: 'due_date', - fieldType: 'date', - }, - invoice_no: { - name: 'invoice.field.invoice_no', - column: 'invoice_no', - fieldType: 'text', - }, - reference_no: { - name: 'invoice.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - invoice_message: { - name: 'invoice.field.invoice_message', - column: 'invoice_message', - fieldType: 'text', - }, - terms_conditions: { - name: 'invoice.field.terms_conditions', - column: 'terms_conditions', - fieldType: 'text', - }, - amount: { - name: 'invoice.field.amount', - column: 'balance', - fieldType: 'number', - }, - payment_amount: { - name: 'invoice.field.payment_amount', - column: 'payment_amount', - fieldType: 'number', - }, - due_amount: { - // calculated. - name: 'invoice.field.due_amount', - column: 'due_amount', - fieldType: 'number', - virtualColumn: true, - }, - status: { - name: 'invoice.field.status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'invoice.field.status.draft' }, - { key: 'delivered', label: 'invoice.field.status.delivered' }, - { key: 'unpaid', label: 'invoice.field.status.unpaid' }, - { key: 'overdue', label: 'invoice.field.status.overdue' }, - { key: 'partially-paid', label: 'invoice.field.status.partially-paid' }, - { key: 'paid', label: 'invoice.field.status.paid' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - created_at: { - name: 'invoice.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - invoiceDate: { - name: 'invoice.field.invoice_date', - type: 'date', - accessor: 'invoiceDateFormatted', - }, - dueDate: { - name: 'invoice.field.due_date', - type: 'date', - accessor: 'dueDateFormatted', - }, - referenceNo: { - name: 'invoice.field.reference_no', - type: 'text', - }, - invoiceNo: { - name: 'invoice.field.invoice_no', - type: 'text', - }, - customer: { - name: 'invoice.field.customer', - type: 'text', - accessor: 'customer.displayName', - }, - amount: { - name: 'invoice.field.amount', - type: 'text', - accessor: 'balanceAmountFormatted', - }, - exchangeRate: { - name: 'invoice.field.exchange_rate', - type: 'number', - printable: false, - }, - currencyCode: { - name: 'invoice.field.currency', - type: 'text', - printable: false, - }, - paidAmount: { - name: 'Paid Amount', - accessor: 'paymentAmountFormatted', - }, - dueAmount: { - name: 'Due Amount', - accessor: 'dueAmountFormatted', - }, - invoiceMessage: { - name: 'invoice.field.invoice_message', - type: 'text', - printable: false, - }, - termsConditions: { - name: 'invoice.field.terms_conditions', - type: 'text', - printable: false, - }, - delivered: { - name: 'invoice.field.delivered', - type: 'boolean', - printable: false, - accessor: 'isDelivered', - }, - entries: { - name: 'Entries', - accessor: 'entries', - type: 'collection', - collectionOf: 'object', - columns: { - itemName: { - name: 'Item Name', - accessor: 'item.name', - }, - rate: { - name: 'Item Rate', - accessor: 'rateFormatted', - }, - quantity: { - name: 'Item Quantity', - accessor: 'quantityFormatted', - }, - description: { - name: 'Item Description', - printable: false, - }, - amount: { - name: 'Item Amount', - accessor: 'totalFormatted', - }, - }, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - warehouse: { - name: 'Warehouse', - type: 'text', - accessor: 'warehouse.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - invoiceDate: { - name: 'invoice.field.invoice_date', - fieldType: 'date', - required: true, - }, - dueDate: { - name: 'invoice.field.due_date', - fieldType: 'date', - required: true, - }, - referenceNo: { - name: 'invoice.field.reference_no', - fieldType: 'text', - }, - invoiceNo: { - name: 'invoice.field.invoice_no', - fieldType: 'text', - }, - customerId: { - name: 'invoice.field.customer', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: 'displayName', - required: true, - }, - exchangeRate: { - name: 'invoice.field.exchange_rate', - fieldType: 'number', - printable: false, - }, - currencyCode: { - name: 'invoice.field.currency', - fieldType: 'text', - printable: false, - }, - invoiceMessage: { - name: 'invoice.field.invoice_message', - fieldType: 'text', - printable: false, - }, - termsConditions: { - name: 'invoice.field.terms_conditions', - fieldType: 'text', - printable: false, - }, - entries: { - name: 'invoice.field.entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - itemId: { - name: 'invoice.field.item_name', - fieldType: 'relation', - relationModel: 'Item', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the item name or code.', - }, - rate: { - name: 'invoice.field.rate', - fieldType: 'number', - required: true, - }, - quantity: { - name: 'invoice.field.quantity', - fieldType: 'number', - required: true, - }, - description: { - name: 'invoice.field.description', - fieldType: 'text', - }, - }, - }, - delivered: { - name: 'invoice.field.delivered', - fieldType: 'boolean', - printable: false, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - warehouseId: { - name: 'Warehouse', - fieldType: 'relation', - relationModel: 'Warehouse', - relationImportMatch: ['name', 'code'], - features: [Features.WAREHOUSES], - required: true, - }, - }, -}; - -/** - * Status field filter custom query. - */ -function StatusFieldFilterQuery(query, role) { - query.modify('statusFilter', role.value); -} - -/** - * Status field sort custom query. - */ -function StatusFieldSortQuery(query, role) { - query.modify('sortByStatus', role.order); -} diff --git a/packages/server/src/models/SaleInvoice.ts b/packages/server/src/models/SaleInvoice.ts deleted file mode 100644 index 145f7beeb..000000000 --- a/packages/server/src/models/SaleInvoice.ts +++ /dev/null @@ -1,716 +0,0 @@ -import { mixin, Model, raw } from 'objection'; -import * as R from 'ramda'; -import { castArray, defaultTo, takeWhile } from 'lodash'; -import moment from 'moment'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import SaleInvoiceMeta from './SaleInvoice.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Sales/Invoices/constants'; -import ModelSearchable from './ModelSearchable'; -import { DiscountType } from '@/interfaces'; - -export default class SaleInvoice extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - public taxAmountWithheld: number; - public balance: number; - public paymentAmount: number; - public exchangeRate: number; - public writtenoffAmount: number; - public creditedAmount: number; - public isInclusiveTax: boolean; - public writtenoffAt: Date; - public dueDate: Date; - public deliveredAt: Date; - public pdfTemplateId: number; - public discount: number; - public discountType: DiscountType; - public adjustment: number | null; - - /** - * Table name - */ - static get tableName() { - return 'sales_invoices'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * - */ - get pluralName() { - return 'asdfsdf'; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'isDelivered', - 'isOverdue', - 'isPartiallyPaid', - 'isFullyPaid', - 'isWrittenoff', - 'isPaid', - - 'dueAmount', - 'balanceAmount', - 'remainingDays', - 'overdueDays', - - 'subtotal', - 'subtotalLocal', - 'subtotalExludingTax', - - 'taxAmountWithheldLocal', - 'discountAmount', - 'discountAmountLocal', - 'discountPercentage', - - 'total', - 'totalLocal', - - 'writtenoffAmountLocal', - 'adjustmentLocal', - ]; - } - - /** - * Invoice amount. - * @todo Sugger attribute to balance, we need to rename the balance to amount. - * @returns {number} - */ - get amount() { - return this.balance; - } - - /** - * Invoice amount in base currency. - * @returns {number} - */ - get amountLocal() { - return this.amount * this.exchangeRate; - } - - /** - * Subtotal. (Tax inclusive) if the tax inclusive is enabled. - * @returns {number} - */ - get subtotal() { - return this.amount; - } - - /** - * Subtotal in base currency. (Tax inclusive) if the tax inclusive is enabled. - * @returns {number} - */ - get subtotalLocal() { - return this.amountLocal; - } - - /** - * Sale invoice amount excluding tax. - * @returns {number} - */ - get subtotalExludingTax() { - return this.isInclusiveTax - ? this.subtotal - this.taxAmountWithheld - : this.subtotal; - } - - /** - * Tax amount withheld in base currency. - * @returns {number} - */ - get taxAmountWithheldLocal() { - return this.taxAmountWithheld * this.exchangeRate; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Amount - ? this.discount - : this.subtotal * (this.discount / 100); - } - - /** - * Local discount amount. - * @returns {number | null} - */ - get discountAmountLocal() { - return this.discountAmount ? this.discountAmount * this.exchangeRate : null; - } - - /** - * Discount percentage. - * @returns {number | null} - */ - get discountPercentage(): number | null { - return this.discountType === DiscountType.Percentage ? this.discount : null; - } - - /** - * Adjustment amount in local currency. - * @returns {number | null} - */ - get adjustmentLocal(): number | null { - return this.adjustment ? this.adjustment * this.exchangeRate : null; - } - - /** - * Invoice total. (Tax included) - * @returns {number} - */ - get total() { - const adjustmentAmount = defaultTo(this.adjustment, 0); - - return R.compose( - R.add(adjustmentAmount), - R.subtract(R.__, this.discountAmount), - R.when(R.always(this.isInclusiveTax), R.add(this.taxAmountWithheld)) - )(this.subtotal); - } - - /** - * Invoice total in local currency. (Tax included) - * @returns {number} - */ - get totalLocal() { - return this.total * this.exchangeRate; - } - - /** - * Detarmines whether the invoice is delivered. - * @return {boolean} - */ - get isDelivered() { - return !!this.deliveredAt; - } - - /** - * Detarmines the due date is over. - * @return {boolean} - */ - get isOverdue() { - return this.overdueDays > 0; - } - - /** - * Retrieve the sale invoice balance. - * @return {number} - */ - get balanceAmount() { - return this.paymentAmount + this.writtenoffAmount + this.creditedAmount; - } - - /** - * Retrieve the invoice due amount. - * Equation (Invoice amount - payment amount = Due amount) - * @return {boolean} - */ - get dueAmount() { - return Math.max(this.total - this.balanceAmount, 0); - } - - /** - * Detarmine whether the invoice paid partially. - * @return {boolean} - */ - get isPartiallyPaid() { - return this.dueAmount !== this.total && this.dueAmount > 0; - } - - /** - * Deetarmine whether the invoice paid fully. - * @return {boolean} - */ - get isFullyPaid() { - return this.dueAmount === 0; - } - - /** - * Detarmines whether the invoice paid fully or partially. - * @return {boolean} - */ - get isPaid() { - return this.isPartiallyPaid || this.isFullyPaid; - } - - /** - * Detarmines whether the sale invoice is written-off. - * @return {boolean} - */ - get isWrittenoff() { - return Boolean(this.writtenoffAt); - } - - /** - * Retrieve the remaining days in number - * @return {number|null} - */ - get remainingDays() { - const dateMoment = moment(); - const dueDateMoment = moment(this.dueDate); - - return Math.max(dueDateMoment.diff(dateMoment, 'days'), 0); - } - - /** - * Retrieve the overdue days in number. - * @return {number|null} - */ - get overdueDays() { - const dateMoment = moment(); - const dueDateMoment = moment(this.dueDate); - - return Math.max(dateMoment.diff(dueDateMoment, 'days'), 0); - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the due invoices. - */ - dueInvoices(query) { - query.where( - raw(` - COALESCE(BALANCE, 0) - - COALESCE(PAYMENT_AMOUNT, 0) - - COALESCE(WRITTENOFF_AMOUNT, 0) - - COALESCE(CREDITED_AMOUNT, 0) > 0 - `) - ); - }, - /** - * Filters the invoices between the given date range. - */ - filterDateRange(query, startDate, endDate, type = 'day') { - const dateFormat = 'YYYY-MM-DD'; - const fromDate = moment(startDate).startOf(type).format(dateFormat); - const toDate = moment(endDate).endOf(type).format(dateFormat); - - if (startDate) { - query.where('invoice_date', '>=', fromDate); - } - if (endDate) { - query.where('invoice_date', '<=', toDate); - } - }, - /** - * Filters the invoices in draft status. - */ - draft(query) { - query.where('delivered_at', null); - }, - /** - * Filters the published invoices. - */ - published(query) { - query.whereNot('delivered_at', null); - }, - /** - * Filters the delivered invoices. - */ - delivered(query) { - query.whereNot('delivered_at', null); - }, - /** - * Filters the unpaid invoices. - */ - unpaid(query) { - query.where(raw('PAYMENT_AMOUNT = 0')); - }, - /** - * Filters the overdue invoices. - */ - overdue(query, asDate = moment().format('YYYY-MM-DD')) { - query.where('due_date', '<', asDate); - }, - /** - * Filters the not overdue invoices. - */ - notOverdue(query, asDate = moment().format('YYYY-MM-DD')) { - query.where('due_date', '>=', asDate); - }, - /** - * Filters the partially invoices. - */ - partiallyPaid(query) { - query.whereNot('payment_amount', 0); - query.whereNot(raw('`PAYMENT_AMOUNT` = `BALANCE`')); - }, - /** - * Filters the paid invoices. - */ - paid(query) { - query.where(raw('PAYMENT_AMOUNT = BALANCE')); - }, - /** - * Filters the sale invoices from the given date. - */ - fromDate(query, fromDate) { - query.where('invoice_date', '<=', fromDate); - }, - /** - * Sort the sale invoices by full-payment invoices. - */ - sortByStatus(query, order) { - query.orderByRaw(`PAYMENT_AMOUNT = BALANCE ${order}`); - }, - - /** - * Sort the sale invoices by the due amount. - */ - sortByDueAmount(query, order) { - query.orderByRaw(`BALANCE - PAYMENT_AMOUNT ${order}`); - }, - - /** - * Retrieve the max invoice - */ - maxInvoiceNo(query, prefix, number) { - query - .select(raw(`REPLACE(INVOICE_NO, "${prefix}", "") AS INV_NUMBER`)) - .havingRaw('CHAR_LENGTH(INV_NUMBER) = ??', [number.length]) - .orderBy('invNumber', 'DESC') - .limit(1) - .first(); - }, - - byPrefixAndNumber(query, prefix, number) { - query.where('invoice_no', `${prefix}${number}`); - }, - - /** - * Status filter. - */ - statusFilter(query, filterType) { - switch (filterType) { - case 'draft': - query.modify('draft'); - break; - case 'delivered': - query.modify('delivered'); - break; - case 'unpaid': - query.modify('unpaid'); - break; - case 'overdue': - default: - query.modify('overdue'); - break; - case 'partially-paid': - query.modify('partiallyPaid'); - break; - case 'paid': - query.modify('paid'); - break; - } - }, - - /** - * Filters by branches. - */ - filterByBranches(query, branchesIds) { - const formattedBranchesIds = castArray(branchesIds); - - query.whereIn('branchId', formattedBranchesIds); - }, - - dueInvoicesFromDate(query, asDate = moment().format('YYYY-MM-DD')) { - query.modify('dueInvoices'); - query.modify('notOverdue', asDate); - query.modify('fromDate', asDate); - }, - - overdueInvoicesFromDate(query, asDate = moment().format('YYYY-MM-DD')) { - query.modify('dueInvoices'); - query.modify('overdue', asDate); - query.modify('fromDate', asDate); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const AccountTransaction = require('models/AccountTransaction'); - const ItemEntry = require('models/ItemEntry'); - const Customer = require('models/Customer'); - const InventoryCostLotTracker = require('models/InventoryCostLotTracker'); - const PaymentReceiveEntry = require('models/PaymentReceiveEntry'); - const Branch = require('models/Branch'); - const Warehouse = require('models/Warehouse'); - const Account = require('models/Account'); - const TaxRateTransaction = require('models/TaxRateTransaction'); - const Document = require('models/Document'); - const { MatchedBankTransaction } = require('models/MatchedBankTransaction'); - const { - TransactionPaymentServiceEntry, - } = require('models/TransactionPaymentServiceEntry'); - const { PdfTemplate } = require('models/PdfTemplate'); - - return { - /** - * Sale invoice associated entries. - */ - entries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'sales_invoices.id', - to: 'items_entries.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'SaleInvoice'); - builder.orderBy('index', 'ASC'); - }, - }, - - /** - * Belongs to customer model. - */ - customer: { - relation: Model.BelongsToOneRelation, - modelClass: Customer.default, - join: { - from: 'sales_invoices.customerId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'Customer'); - }, - }, - - /** - * Invoice has associated account transactions. - */ - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'sales_invoices.id', - to: 'accounts_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'SaleInvoice'); - }, - }, - - /** - * Invoice may has associated cost transactions. - */ - costTransactions: { - relation: Model.HasManyRelation, - modelClass: InventoryCostLotTracker.default, - join: { - from: 'sales_invoices.id', - to: 'inventory_cost_lot_tracker.transactionId', - }, - filter(builder) { - builder.where('transaction_type', 'SaleInvoice'); - }, - }, - - /** - * Invoice may has associated payment entries. - */ - paymentEntries: { - relation: Model.HasManyRelation, - modelClass: PaymentReceiveEntry.default, - join: { - from: 'sales_invoices.id', - to: 'payment_receives_entries.invoiceId', - }, - }, - - /** - * Invoice may has associated branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'sales_invoices.branchId', - to: 'branches.id', - }, - }, - - /** - * Invoice may has associated warehouse. - */ - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'sales_invoices.warehouseId', - to: 'warehouses.id', - }, - }, - - /** - * Invoice may has associated written-off expense account. - */ - writtenoffExpenseAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'sales_invoices.writtenoffExpenseAccountId', - to: 'accounts.id', - }, - }, - - /** - * Invoice may has associated tax rate transactions. - */ - taxes: { - relation: Model.HasManyRelation, - modelClass: TaxRateTransaction.default, - join: { - from: 'sales_invoices.id', - to: 'tax_rate_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'SaleInvoice'); - }, - }, - - /** - * Sale invoice transaction may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'sales_invoices.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'SaleInvoice'); - }, - }, - - /** - * Sale invocie may belongs to matched bank transaction. - */ - matchedBankTransaction: { - relation: Model.HasManyRelation, - modelClass: MatchedBankTransaction, - join: { - from: 'sales_invoices.id', - to: 'matched_bank_transactions.referenceId', - }, - filter(query) { - query.where('reference_type', 'SaleInvoice'); - }, - }, - - /** - * Sale invoice may belongs to payment methods entries. - */ - paymentMethods: { - relation: Model.HasManyRelation, - modelClass: TransactionPaymentServiceEntry, - join: { - from: 'sales_invoices.id', - to: 'transactions_payment_methods.referenceId', - }, - beforeInsert: (model) => { - model.referenceType = 'SaleInvoice'; - }, - filter: (query) => { - query.where('reference_type', 'SaleInvoice'); - }, - }, - - /** - * Sale invoice may belongs to pdf branding template. - */ - pdfTemplate: { - relation: Model.BelongsToOneRelation, - modelClass: PdfTemplate, - join: { - from: 'sales_invoices.pdfTemplateId', - to: 'pdf_templates.id', - }, - }, - }; - } - - /** - * Change payment amount. - * @param {Integer} invoiceId - * @param {Numeric} amount - */ - static async changePaymentAmount(invoiceId, amount, trx) { - const changeMethod = amount > 0 ? 'increment' : 'decrement'; - - await this.query(trx) - .where('id', invoiceId) - [changeMethod]('payment_amount', Math.abs(amount)); - } - - /** - * Sale invoice meta. - */ - static get meta() { - return SaleInvoiceMeta; - } - - static dueAmountFieldSortQuery(query, role) { - query.modify('sortByDueAmount', role.order); - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model searchable. - */ - static get searchable() { - return true; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'invoice_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/SaleInvoiceEntry.ts b/packages/server/src/models/SaleInvoiceEntry.ts deleted file mode 100644 index 0d081bdb2..000000000 --- a/packages/server/src/models/SaleInvoiceEntry.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class SaleInvoiceEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'sales_invoices_entries'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleInvoice = require('models/SaleInvoice'); - - return { - saleInvoice: { - relation: Model.BelongsToOneRelation, - modelClass: SaleInvoice.default, - join: { - from: 'sales_invoices_entries.sale_invoice_id', - to: 'sales_invoices.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/SaleReceipt.Settings.ts b/packages/server/src/models/SaleReceipt.Settings.ts deleted file mode 100644 index 1759ac053..000000000 --- a/packages/server/src/models/SaleReceipt.Settings.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { Features } from '@/interfaces'; - -export default { - defaultFilterField: 'receipt_date', - defaultSort: { - sortOrder: 'DESC', - sortField: 'created_at', - }, - exportable: true, - exportFlattenOn: 'entries', - - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'receiptNumber', - - print: { - pageTitle: 'Sale Receipts', - }, - fields: { - amount: { - name: 'receipt.field.amount', - column: 'amount', - fieldType: 'number', - }, - deposit_account: { - column: 'deposit_account_id', - name: 'receipt.field.deposit_account', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'depositAccount', - - relationEntityLabel: 'name', - relationEntityKey: 'slug', - }, - customer: { - name: 'receipt.field.customer', - column: 'customer_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'customer', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - receipt_date: { - name: 'receipt.field.receipt_date', - column: 'receipt_date', - fieldType: 'date', - }, - receipt_number: { - name: 'receipt.field.receipt_number', - column: 'receipt_number', - fieldType: 'text', - }, - reference_no: { - name: 'receipt.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - receipt_message: { - name: 'receipt.field.receipt_message', - column: 'receipt_message', - fieldType: 'text', - }, - statement: { - name: 'receipt.field.statement', - column: 'statement', - fieldType: 'text', - }, - created_at: { - name: 'receipt.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - status: { - name: 'receipt.field.status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'receipt.field.status.draft' }, - { key: 'closed', label: 'receipt.field.status.closed' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - }, - columns: { - depositAccount: { - name: 'receipt.field.deposit_account', - type: 'text', - accessor: 'depositAccount.name', - }, - customer: { - name: 'receipt.field.customer', - type: 'text', - accessor: 'customer.displayName', - }, - receiptDate: { - name: 'receipt.field.receipt_date', - accessor: 'formattedReceiptDate', - type: 'date', - }, - receiptNumber: { - name: 'receipt.field.receipt_number', - type: 'text', - }, - referenceNo: { - name: 'receipt.field.reference_no', - column: 'reference_no', - type: 'text', - exportable: true, - }, - receiptMessage: { - name: 'receipt.field.receipt_message', - column: 'receipt_message', - type: 'text', - printable: false, - }, - amount: { - name: 'receipt.field.amount', - accessor: 'formattedAmount', - type: 'number', - }, - statement: { - name: 'receipt.field.statement', - type: 'text', - printable: false, - }, - status: { - name: 'receipt.field.status', - type: 'enumeration', - options: [ - { key: 'draft', label: 'receipt.field.status.draft' }, - { key: 'closed', label: 'receipt.field.status.closed' }, - ], - exportable: true, - printable: false, - }, - entries: { - name: 'Entries', - accessor: 'entries', - type: 'collection', - collectionOf: 'object', - columns: { - itemName: { - name: 'Item Name', - accessor: 'item.name', - }, - rate: { - name: 'Item Rate', - accessor: 'rateFormatted', - }, - quantity: { - name: 'Item Quantity', - accessor: 'quantityFormatted', - }, - description: { - name: 'Item Description', - printable: false, - }, - amount: { - name: 'Item Amount', - accessor: 'totalFormatted', - }, - }, - }, - createdAt: { - name: 'receipt.field.created_at', - type: 'date', - printable: false, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - warehouse: { - name: 'Warehouse', - type: 'text', - accessor: 'warehouse.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - receiptDate: { - name: 'Receipt Date', - fieldType: 'date', - required: true, - }, - customerId: { - name: 'Customer', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: 'displayName', - required: true, - }, - depositAccountId: { - name: 'Deposit Account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - }, - exchangeRate: { - name: 'Exchange Rate', - fieldType: 'number', - }, - receiptNumber: { - name: 'Receipt Number', - fieldType: 'text', - }, - referenceNo: { - name: 'Reference No.', - fieldType: 'text', - }, - closed: { - name: 'Closed', - fieldType: 'boolean', - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - itemId: { - name: 'invoice.field.item_name', - fieldType: 'relation', - relationModel: 'Item', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the item name or code.', - }, - rate: { - name: 'invoice.field.rate', - fieldType: 'number', - required: true, - }, - quantity: { - name: 'invoice.field.quantity', - fieldType: 'number', - required: true, - }, - description: { - name: 'invoice.field.description', - fieldType: 'text', - }, - }, - }, - statement: { - name: 'Statement', - fieldType: 'text', - }, - receiptMessage: { - name: 'Receipt Message', - fieldType: 'text', - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true, - }, - warehouseId: { - name: 'Warehouse', - fieldType: 'relation', - relationModel: 'Warehouse', - relationImportMatch: ['name', 'code'], - features: [Features.WAREHOUSES], - required: true, - }, - }, -}; - -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} - -function StatusFieldSortQuery(query, role) { - query.modify('sortByStatus', role.order); -} diff --git a/packages/server/src/models/SaleReceipt.ts b/packages/server/src/models/SaleReceipt.ts deleted file mode 100644 index 95abf7430..000000000 --- a/packages/server/src/models/SaleReceipt.ts +++ /dev/null @@ -1,353 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import SaleReceiptSettings from './SaleReceipt.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Sales/Receipts/constants'; -import ModelSearchable from './ModelSearchable'; -import { DiscountType } from '@/interfaces'; -import { defaultTo } from 'lodash'; - -export default class SaleReceipt extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - public amount: number; - public exchangeRate: number; - public closedAt: Date; - - public discount: number; - public discountType: DiscountType; - - public adjustment: number; - - /** - * Table name - */ - static get tableName() { - return 'sales_receipts'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'localAmount', - - 'subtotal', - 'subtotalLocal', - - 'total', - 'totalLocal', - - 'adjustment', - 'adjustmentLocal', - - 'discountAmount', - 'discountAmountLocal', - 'discountPercentage', - - 'paid', - 'paidLocal', - - 'isClosed', - 'isDraft', - ]; - } - - /** - * Estimate amount in local currency. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Receipt subtotal. - * @returns {number} - */ - get subtotal() { - return this.amount; - } - - /** - * Receipt subtotal in local currency. - * @returns {number} - */ - get subtotalLocal() { - return this.localAmount; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Amount - ? this.discount - : this.subtotal * (this.discount / 100); - } - - /** - * Discount amount in local currency. - * @returns {number | null} - */ - get discountAmountLocal() { - return this.discountAmount ? this.discountAmount * this.exchangeRate : null; - } - - /** - * Discount percentage. - * @returns {number | null} - */ - get discountPercentage(): number | null { - return this.discountType === DiscountType.Percentage ? this.discount : null; - } - - /** - * Receipt total. - * @returns {number} - */ - get total() { - const adjustmentAmount = defaultTo(this.adjustment, 0); - - return this.subtotal - this.discountAmount + adjustmentAmount; - } - - /** - * Receipt total in local currency. - * @returns {number} - */ - get totalLocal() { - return this.total * this.exchangeRate; - } - - /** - * Adjustment amount in local currency. - * @returns {number} - */ - get adjustmentLocal() { - return this.adjustment * this.exchangeRate; - } - - /** - * Receipt paid amount. - * @returns {number} - */ - get paid() { - return this.total; - } - - /** - * Receipt paid amount in local currency. - * @returns {number} - */ - get paidLocal() { - return this.paid * this.exchangeRate; - } - - /** - * Detarmine whether the sale receipt closed. - * @return {boolean} - */ - get isClosed() { - return !!this.closedAt; - } - - /** - * Detarmines whether the sale receipt drafted. - * @return {boolean} - */ - get isDraft() { - return !this.closedAt; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the closed receipts. - */ - closed(query) { - query.whereNot('closed_at', null); - }, - - /** - * Filters the invoices in draft status. - */ - draft(query) { - query.where('closed_at', null); - }, - - /** - * Sorting the receipts order by status. - */ - sortByStatus(query, order) { - query.orderByRaw(`CLOSED_AT IS NULL ${order}`); - }, - - /** - * Filtering the receipts orders by status. - */ - filterByStatus(query, status) { - switch (status) { - case 'draft': - query.modify('draft'); - break; - case 'closed': - default: - query.modify('closed'); - break; - } - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Customer = require('models/Customer'); - const Account = require('models/Account'); - const AccountTransaction = require('models/AccountTransaction'); - const ItemEntry = require('models/ItemEntry'); - const Branch = require('models/Branch'); - const Document = require('models/Document'); - const Warehouse = require('models/Warehouse'); - - return { - customer: { - relation: Model.BelongsToOneRelation, - modelClass: Customer.default, - join: { - from: 'sales_receipts.customerId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'customer'); - }, - }, - - depositAccount: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'sales_receipts.depositAccountId', - to: 'accounts.id', - }, - }, - - entries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'sales_receipts.id', - to: 'items_entries.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'SaleReceipt'); - builder.orderBy('index', 'ASC'); - }, - }, - - transactions: { - relation: Model.HasManyRelation, - modelClass: AccountTransaction.default, - join: { - from: 'sales_receipts.id', - to: 'accounts_transactions.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'SaleReceipt'); - }, - }, - - /** - * Sale receipt may belongs to branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'sales_receipts.branchId', - to: 'branches.id', - }, - }, - - /** - * Sale receipt may has associated warehouse. - */ - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'sales_receipts.warehouseId', - to: 'warehouses.id', - }, - }, - - /** - * Sale receipt transaction may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'sales_receipts.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'SaleReceipt'); - }, - }, - }; - } - - /** - * Sale invoice meta. - */ - static get meta() { - return SaleReceiptSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'receipt_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/SaleReceiptEntry.ts b/packages/server/src/models/SaleReceiptEntry.ts deleted file mode 100644 index 1d0f55b5f..000000000 --- a/packages/server/src/models/SaleReceiptEntry.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class SaleReceiptEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'sales_receipt_entries'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleReceipt = require('models/SaleReceipt'); - - return { - saleReceipt: { - relation: Model.BelongsToOneRelation, - modelClass: SaleReceipt.default, - join: { - from: 'sales_receipt_entries.sale_receipt_id', - to: 'sales_receipts.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/Setting.ts b/packages/server/src/models/Setting.ts deleted file mode 100644 index 471fccb66..000000000 --- a/packages/server/src/models/Setting.ts +++ /dev/null @@ -1,21 +0,0 @@ -import TenantModel from 'models/TenantModel'; -import Auth from './Auth'; - -export default class Setting extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'settings'; - } - - /** - * Extra metadata query to query with the current authenticate user. - * @param {Object} query - */ - static extraMetadataQuery(query) { - if (Auth.isLogged()) { - query.where('user_id', Auth.userId()); - } - } -} diff --git a/packages/server/src/models/Task.ts b/packages/server/src/models/Task.ts deleted file mode 100644 index 9843d3a6b..000000000 --- a/packages/server/src/models/Task.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { mixin, Model, raw } from 'objection'; -import TenantModel from 'models/TenantModel'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSetting from './ModelSetting'; -import ModelSearchable from './ModelSearchable'; -import { ProjectTaskChargeType } from '@/services/Projects/Tasks/constants'; -import { number } from 'mathjs'; - -export default class Task extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - type!: string; - rate!: number; - actualHours!: number; - invoicedHours!: number; - estimateHours!: number; - - /** - * Table name - */ - static get tableName() { - return 'tasks'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'actualAmount', - 'invoicedAmount', - 'estimateAmount', - 'billableAmount', - 'billableHours', - ]; - } - - /** - * Retrieves the actual amount. - */ - get actualAmount(): number { - return this.rate * this.actualHours; - } - - /** - * Retrieves the invoiced amount. - */ - get invoicedAmount(): number { - return this.rate * this.invoicedHours; - } - - /** - * Retrieves the estimate amount. - */ - get estimateAmount(): number { - return this.rate * this.estimateHours; - } - - /** - * Retrieves the billable amount. - */ - get billableAmount() { - return this.actualAmount - this.invoicedAmount; - } - - /** - * Retrieves the billable hours. - */ - get billableHours() { - return this.actualHours - this.invoicedHours; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Sumation of total actual hours. - * @param builder - */ - sumTotalActualHours(builder) { - builder.sum('actualHours as totalActualHours'); - }, - - /** - * Sumation total estimate hours. - * @param builder - */ - sumTotalEstimateHours(builder) { - builder.sum('estimateHours as totalEstimateHours'); - }, - - /** - * Sumation of total invoiced hours. - * @param builder - */ - sumTotalInvoicedHours(builder) { - builder.sum('invoicedHours as totalInvoicedHours'); - }, - - /** - * Sumation of total actual amount. - * @param builder - */ - sumTotalActualAmount(builder) { - builder.groupBy('totalActualAmount'); - builder.select(raw('ACTUAL_HOURS * RATE').as('totalActualAmount')); - }, - - /** - * Sumation of total invoiced amount. - * @param builder - */ - sumTotalInvoicedAmount(builder) { - this.groupBy('totalInvoicedAmount'); - builder.select(raw('INVOICED_HOURS * RATE').as('totalInvoicedAmount')); - }, - - /** - * Sumation of total estimate amount. - * @param builder - */ - sumTotalEstimateAmount(builder) { - builder.groupBy('totalEstimateAmount'); - builder.select(raw('ESTIMATE_HOURS * RATE').as('totalEstimateAmount')); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Time = require('models/Time'); - const Project = require('models/Project'); - - return { - /** - * Project may has many associated tasks. - */ - times: { - relation: Model.HasManyRelation, - modelClass: Time.default, - join: { - from: 'tasks.id', - to: 'times.taskId', - }, - }, - - /** - * Project may has many associated times. - */ - project: { - relation: Model.BelongsToOneRelation, - modelClass: Project.default, - join: { - from: 'tasks.projectId', - to: 'projects.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/TaxRate.settings.ts b/packages/server/src/models/TaxRate.settings.ts deleted file mode 100644 index a25ce2940..000000000 --- a/packages/server/src/models/TaxRate.settings.ts +++ /dev/null @@ -1,69 +0,0 @@ -export default { - defaultSort: { - sortOrder: 'DESC', - sortField: 'created_at', - }, - exportable: true, - importable: true, - print: { - pageTitle: 'Tax Rates', - }, - columns: { - name: { - name: 'Tax Rate Name', - type: 'text', - accessor: 'name', - }, - code: { - name: 'Code', - type: 'text', - accessor: 'code', - }, - rate: { - name: 'Rate', - type: 'text', - }, - description: { - name: 'Description', - type: 'text', - }, - isNonRecoverable: { - name: 'Is Non Recoverable', - type: 'boolean', - }, - active: { - name: 'Active', - type: 'boolean', - }, - }, - field: {}, - fields2: { - name: { - name: 'Tax name', - fieldType: 'name', - required: true, - }, - code: { - name: 'Code', - fieldType: 'code', - required: true, - }, - rate: { - name: 'Rate', - fieldType: 'number', - required: true, - }, - description: { - name: 'Description', - fieldType: 'text', - }, - isNonRecoverable: { - name: 'Is Non Recoverable', - fieldType: 'boolean', - }, - active: { - name: 'Active', - fieldType: 'boolean', - }, - }, -}; diff --git a/packages/server/src/models/TaxRate.ts b/packages/server/src/models/TaxRate.ts deleted file mode 100644 index 13863e233..000000000 --- a/packages/server/src/models/TaxRate.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { mixin, Model, raw } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSearchable from './ModelSearchable'; -import SoftDeleteQueryBuilder from '@/collection/SoftDeleteQueryBuilder'; -import TaxRateMeta from './TaxRate.settings'; -import ModelSetting from './ModelSetting'; - -export default class TaxRate extends mixin(TenantModel, [ - ModelSetting, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'tax_rates'; - } - - /** - * Soft delete query builder. - */ - static get QueryBuilder() { - return SoftDeleteQueryBuilder; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Retrieves the tax rate meta. - */ - static get meta() { - return TaxRateMeta; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return {}; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - return {}; - } -} diff --git a/packages/server/src/models/TaxRateTransaction.ts b/packages/server/src/models/TaxRateTransaction.ts deleted file mode 100644 index f38c655eb..000000000 --- a/packages/server/src/models/TaxRateTransaction.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { mixin, Model, raw } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSearchable from './ModelSearchable'; - -export default class TaxRateTransaction extends mixin(TenantModel, [ - ModelSearchable, -]) { - public rate: number; - public referenceId: number; - public referenceType: string; - public taxRateId: number; - - /** - * Table name - */ - static get tableName() { - return 'tax_rate_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return []; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return {}; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const TaxRate = require('models/TaxRate'); - - return { - /** - * Belongs to the tax rate. - */ - taxRate: { - relation: Model.BelongsToOneRelation, - modelClass: TaxRate.default, - join: { - from: 'tax_rate_transactions.taxRateId', - to: 'tax_rates.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/TenantModel.ts b/packages/server/src/models/TenantModel.ts deleted file mode 100644 index 9fbc9739e..000000000 --- a/packages/server/src/models/TenantModel.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Container } from 'typedi'; -import BaseModel from 'models/Model'; - -export default class TenantModel extends BaseModel { - /** - * Logging all tenant databases queries. - * @param {...any} args - */ - static query(...args) { - const Logger = Container.get('logger'); - - return super.query(...args).onBuildKnex((knexQueryBuilder) => { - const { userParams: { tenantId } } = knexQueryBuilder.client.config; - - knexQueryBuilder.on('query', queryData => { - Logger.info(`[query][tenant] ${queryData.sql}`, { - bindings: queryData.bindings, tenantId - }); - }); - }); - } -} diff --git a/packages/server/src/models/Time.ts b/packages/server/src/models/Time.ts deleted file mode 100644 index 7977edf5d..000000000 --- a/packages/server/src/models/Time.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { mixin, Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSetting from './ModelSetting'; -import ModelSearchable from './ModelSearchable'; - -export default class Time extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'times'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Task = require('models/Task'); - const Project = require('models/Project'); - - return { - /** - * Project may has many associated tasks. - */ - task: { - relation: Model.BelongsToOneRelation, - modelClass: Task.default, - join: { - from: 'times.taskId', - to: 'tasks.id', - }, - }, - - /** - * Project may has many associated times. - */ - project: { - relation: Model.BelongsToOneRelation, - modelClass: Project.default, - join: { - from: 'times.projectId', - to: 'projects.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/TransactionPaymentServiceEntry.ts b/packages/server/src/models/TransactionPaymentServiceEntry.ts deleted file mode 100644 index 59313830b..000000000 --- a/packages/server/src/models/TransactionPaymentServiceEntry.ts +++ /dev/null @@ -1,46 +0,0 @@ -import TenantModel from 'models/TenantModel'; - -export class TransactionPaymentServiceEntry extends TenantModel { - /** - * Table name - */ - static get tableName() { - return 'transactions_payment_methods'; - } - - /** - * Json schema of the model. - */ - static get jsonSchema() { - return { - type: 'object', - required: ['paymentIntegrationId'], - properties: { - id: { type: 'integer' }, - referenceId: { type: 'integer' }, - referenceType: { type: 'string' }, - paymentIntegrationId: { type: 'integer' }, - enable: { type: 'boolean' }, - options: { type: 'object' }, - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const { PaymentIntegration } = require('./PaymentIntegration'); - - return { - paymentIntegration: { - relation: TenantModel.BelongsToOneRelation, - modelClass: PaymentIntegration, - join: { - from: 'transactions_payment_methods.paymentIntegrationId', - to: 'payment_integrations.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts b/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts deleted file mode 100644 index d5b55d8fb..000000000 --- a/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts +++ /dev/null @@ -1,72 +0,0 @@ -export default { - defaultFilterField: 'createdAt', - defaultSort: { - sortOrder: 'DESC', - sortField: 'created_at', - }, - importable: true, - fields: { - date: { - name: 'Date', - column: 'date', - fieldType: 'date', - }, - payee: { - name: 'Payee', - column: 'payee', - fieldType: 'text', - }, - description: { - name: 'Description', - column: 'description', - fieldType: 'text', - }, - referenceNo: { - name: 'Reference No.', - column: 'reference_no', - fieldType: 'text', - }, - amount: { - name: 'Amount', - column: 'Amount', - fieldType: 'numeric', - required: true, - }, - account: { - name: 'Account', - column: 'account_id', - fieldType: 'relation', - to: { model: 'Account', to: 'id' }, - }, - createdAt: { - name: 'Created At', - column: 'createdAt', - fieldType: 'date', - importable: false, - }, - }, - fields2: { - date: { - name: 'Date', - fieldType: 'date', - required: true, - }, - payee: { - name: 'Payee', - fieldType: 'text', - }, - description: { - name: 'Description', - fieldType: 'text', - }, - referenceNo: { - name: 'Reference No.', - fieldType: 'text', - }, - amount: { - name: 'Amount', - fieldType: 'number', - required: true, - }, - }, -}; diff --git a/packages/server/src/models/UncategorizedCashflowTransaction.ts b/packages/server/src/models/UncategorizedCashflowTransaction.ts deleted file mode 100644 index 708cc123c..000000000 --- a/packages/server/src/models/UncategorizedCashflowTransaction.ts +++ /dev/null @@ -1,248 +0,0 @@ -/* eslint-disable global-require */ -import moment from 'moment'; -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSettings from './ModelSetting'; -import UncategorizedCashflowTransactionMeta from './UncategorizedCashflowTransaction.meta'; - -export default class UncategorizedCashflowTransaction extends mixin( - TenantModel, - [ModelSettings] -) { - id!: number; - date!: Date | string; - - /** - * Transaction amount. - * Negative represents to spending and positive to deposit/card charge. - * @param {number} - */ - amount!: number; - categorized!: boolean; - accountId!: number; - referenceNo!: string; - payee!: string; - description!: string; - plaidTransactionId!: string; - recognizedTransactionId!: number; - excludedAt: Date; - pending: boolean; - - /** - * Table name. - */ - static get tableName() { - return 'uncategorized_cashflow_transactions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'withdrawal', - 'deposit', - 'isDepositTransaction', - 'isWithdrawalTransaction', - 'isRecognized', - 'isExcluded', - 'isPending', - ]; - } - - static get meta() { - return UncategorizedCashflowTransactionMeta; - } - - /** - * Retrieves the withdrawal amount. - * @returns {number} - */ - public get withdrawal() { - return this.amount < 0 ? Math.abs(this.amount) : 0; - } - - /** - * Retrieves the deposit amount. - * @returns {number} - */ - public get deposit(): number { - return this.amount > 0 ? Math.abs(this.amount) : 0; - } - - /** - * Detarmines whether the transaction is deposit transaction. - */ - public get isDepositTransaction(): boolean { - return 0 < this.deposit; - } - - /** - * Detarmines whether the transaction is withdrawal transaction. - */ - public get isWithdrawalTransaction(): boolean { - return 0 < this.withdrawal; - } - - /** - * Detarmines whether the transaction is recognized. - */ - public get isRecognized(): boolean { - return !!this.recognizedTransactionId; - } - - /** - * Detarmines whether the transaction is excluded. - * @returns {boolean} - */ - public get isExcluded(): boolean { - return !!this.excludedAt; - } - - /** - * Detarmines whether the transaction is pending. - * @returns {boolean} - */ - public get isPending(): boolean { - return !!this.pending; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the not excluded transactions. - */ - notExcluded(query) { - query.whereNull('excluded_at'); - }, - - /** - * Filters the excluded transactions. - */ - excluded(query) { - query.whereNotNull('excluded_at'); - }, - - /** - * Filter out the recognized transactions. - * @param query - */ - recognized(query) { - query.whereNotNull('recognizedTransactionId'); - }, - - /** - * Filter out the not recognized transactions. - * @param query - */ - notRecognized(query) { - query.whereNull('recognizedTransactionId'); - }, - - categorized(query) { - query.whereNotNull('categorizeRefType'); - query.whereNotNull('categorizeRefId'); - }, - - notCategorized(query) { - query.whereNull('categorizeRefType'); - query.whereNull('categorizeRefId'); - }, - - /** - * Filters the not pending transactions. - */ - notPending(query) { - query.where('pending', false); - }, - - /** - * Filters the pending transactions. - */ - pending(query) { - query.where('pending', true); - }, - - minAmount(query, minAmount) { - query.where('amount', '>=', minAmount); - }, - - maxAmount(query, maxAmount) { - query.where('amount', '<=', maxAmount); - }, - - toDate(query, toDate) { - const dateFormat = 'YYYY-MM-DD'; - const _toDate = moment(toDate).endOf('day').format(dateFormat); - - query.where('date', '<=', _toDate); - }, - - fromDate(query, fromDate) { - const dateFormat = 'YYYY-MM-DD'; - const _fromDate = moment(fromDate).startOf('day').format(dateFormat); - - query.where('date', '>=', _fromDate); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Account = require('models/Account'); - const { - RecognizedBankTransaction, - } = require('models/RecognizedBankTransaction'); - const { MatchedBankTransaction } = require('models/MatchedBankTransaction'); - - return { - /** - * Transaction may has associated to account. - */ - account: { - relation: Model.BelongsToOneRelation, - modelClass: Account.default, - join: { - from: 'uncategorized_cashflow_transactions.accountId', - to: 'accounts.id', - }, - }, - - /** - * Transaction may has association to recognized transaction. - */ - recognizedTransaction: { - relation: Model.HasOneRelation, - modelClass: RecognizedBankTransaction, - join: { - from: 'uncategorized_cashflow_transactions.recognizedTransactionId', - to: 'recognized_bank_transactions.id', - }, - }, - - /** - * Uncategorized transaction may has association to matched transaction. - */ - matchedBankTransactions: { - relation: Model.HasManyRelation, - modelClass: MatchedBankTransaction, - join: { - from: 'uncategorized_cashflow_transactions.id', - to: 'matched_bank_transactions.uncategorizedTransactionId', - }, - }, - }; - } -} diff --git a/packages/server/src/models/User.ts b/packages/server/src/models/User.ts deleted file mode 100644 index 81144edad..000000000 --- a/packages/server/src/models/User.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class User extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'users'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['isInviteAccepted', 'fullName']; - } - - /** - * Detarmines whether the user ivnite is accept. - */ - get isInviteAccepted() { - return !!this.inviteAcceptedAt; - } - - /** - * Full name attribute. - */ - get fullName() { - return `${this.firstName} ${this.lastName}`.trim(); - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Role = require('models/Role'); - - return { - /** - * User belongs to user. - */ - role: { - relation: Model.BelongsToOneRelation, - modelClass: Role.default, - join: { - from: 'users.roleId', - to: 'roles.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/Vendor.Settings.ts b/packages/server/src/models/Vendor.Settings.ts deleted file mode 100644 index cf007f278..000000000 --- a/packages/server/src/models/Vendor.Settings.ts +++ /dev/null @@ -1,407 +0,0 @@ -export default { - defaultFilterField: 'displayName', - defaultSort: { - sortOrder: 'DESC', - sortField: 'created_at', - }, - importable: true, - exportable: true, - fields: { - first_name: { - name: 'vendor.field.first_name', - column: 'first_name', - fieldType: 'text', - }, - last_name: { - name: 'vendor.field.last_name', - column: 'last_name', - fieldType: 'text', - }, - display_name: { - name: 'vendor.field.display_name', - column: 'display_name', - fieldType: 'text', - }, - email: { - name: 'vendor.field.email', - column: 'email', - fieldType: 'text', - }, - work_phone: { - name: 'vendor.field.work_phone', - column: 'work_phone', - fieldType: 'text', - }, - personal_phone: { - name: 'vendor.field.personal_phone', - column: 'personal_phone', - fieldType: 'text', - }, - company_name: { - name: 'vendor.field.company_name', - column: 'company_name', - fieldType: 'text', - }, - website: { - name: 'vendor.field.website', - column: 'website', - fieldType: 'text', - }, - created_at: { - name: 'vendor.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - balance: { - name: 'vendor.field.balance', - column: 'balance', - fieldType: 'number', - }, - opening_balance: { - name: 'vendor.field.opening_balance', - column: 'opening_balance', - fieldType: 'number', - }, - opening_balance_at: { - name: 'vendor.field.opening_balance_at', - column: 'opening_balance_at', - fieldType: 'date', - }, - currency_code: { - name: 'vendor.field.currency', - column: 'currency_code', - fieldType: 'text', - }, - status: { - name: 'vendor.field.status', - type: 'enumeration', - options: [ - { key: 'overdue', label: 'vendor.field.status.overdue' }, - { key: 'unpaid', label: 'vendor.field.status.unpaid' }, - ], - filterCustomQuery: (query, role) => { - switch (role.value) { - case 'overdue': - query.modify('overdue'); - break; - case 'unpaid': - query.modify('unpaid'); - break; - } - }, - }, - }, - columns: { - firstName: { - name: 'vendor.field.first_name', - type: 'text', - }, - lastName: { - name: 'vendor.field.last_name', - type: 'text', - }, - displayName: { - name: 'vendor.field.display_name', - type: 'text', - }, - email: { - name: 'vendor.field.email', - type: 'text', - }, - workPhone: { - name: 'vendor.field.work_phone', - type: 'text', - }, - personalPhone: { - name: 'vendor.field.personal_phone', - type: 'text', - }, - companyName: { - name: 'vendor.field.company_name', - type: 'text', - }, - website: { - name: 'vendor.field.website', - type: 'text', - }, - balance: { - name: 'vendor.field.balance', - type: 'number', - }, - openingBalance: { - name: 'vendor.field.opening_balance', - type: 'number', - printable: false - }, - openingBalanceAt: { - name: 'vendor.field.opening_balance_at', - type: 'date', - printable: false - }, - currencyCode: { - name: 'vendor.field.currency', - type: 'text', - printable: false - }, - status: { - name: 'vendor.field.status', - printable: false - }, - note: { - name: 'vendor.field.note', - type: 'text', - printable: false - }, - // Billing Address - billingAddress1: { - name: 'Billing Address 1', - column: 'billing_address1', - type: 'text', - exportable: true, - printable: false - }, - billingAddress2: { - name: 'Billing Address 2', - column: 'billing_address2', - type: 'text', - exportable: true, - printable: false - }, - billingAddressCity: { - name: 'Billing Address City', - column: 'billing_address_city', - type: 'text', - exportable: true, - printable: false - }, - billingAddressCountry: { - name: 'Billing Address Country', - column: 'billing_address_country', - type: 'text', - exportable: true, - printable: false - }, - billingAddressPostcode: { - name: 'Billing Address Postcode', - column: 'billing_address_postcode', - type: 'text', - exportable: true, - printable: false - }, - billingAddressState: { - name: 'Billing Address State', - column: 'billing_address_state', - type: 'text', - exportable: true, - printable: false - }, - billingAddressPhone: { - name: 'Billing Address Phone', - column: 'billing_address_phone', - type: 'text', - exportable: true, - printable: false - }, - // Shipping Address - shippingAddress1: { - name: 'Shipping Address 1', - column: 'shipping_address1', - type: 'text', - exportable: true, - printable: false - }, - shippingAddress2: { - name: 'Shipping Address 2', - column: 'shipping_address2', - type: 'text', - exportable: true, - printable: false - }, - shippingAddressCity: { - name: 'Shipping Address City', - column: 'shipping_address_city', - type: 'text', - exportable: true, - printable: false - }, - shippingAddressCountry: { - name: 'Shipping Address Country', - column: 'shipping_address_country', - type: 'text', - exportable: true, - printable: false - }, - shippingAddressPostcode: { - name: 'Shipping Address Postcode', - column: 'shipping_address_postcode', - type: 'text', - exportable: true, - printable: false - }, - shippingAddressState: { - name: 'Shipping Address State', - column: 'shipping_address_state', - type: 'text', - exportable: true, - printable: false - }, - shippingAddressPhone: { - name: 'Shipping Address Phone', - column: 'shipping_address_phone', - type: 'text', - exportable: true, - printable: false - }, - createdAt: { - name: 'vendor.field.created_at', - type: 'date', - exportable: true, - printable: false - }, - }, - fields2: { - firstName: { - name: 'vendor.field.first_name', - column: 'first_name', - fieldType: 'text', - }, - lastName: { - name: 'vendor.field.last_name', - column: 'last_name', - fieldType: 'text', - }, - displayName: { - name: 'vendor.field.display_name', - column: 'display_name', - fieldType: 'text', - required: true, - }, - email: { - name: 'vendor.field.email', - column: 'email', - fieldType: 'text', - }, - workPhone: { - name: 'vendor.field.work_phone', - column: 'work_phone', - fieldType: 'text', - }, - personalPhone: { - name: 'vendor.field.personal_phone', - column: 'personal_phone', - fieldType: 'text', - }, - companyName: { - name: 'vendor.field.company_name', - column: 'company_name', - fieldType: 'text', - }, - website: { - name: 'vendor.field.website', - column: 'website', - fieldType: 'text', - }, - openingBalance: { - name: 'vendor.field.opening_balance', - column: 'opening_balance', - fieldType: 'number', - }, - openingBalanceAt: { - name: 'vendor.field.opening_balance_at', - column: 'opening_balance_at', - fieldType: 'date', - }, - openingBalanceExchangeRate: { - name: 'Opening Balance Ex. Rate', - column: 'opening_balance_exchange_rate', - fieldType: 'number', - }, - currencyCode: { - name: 'vendor.field.currency', - column: 'currency_code', - fieldType: 'text', - }, - note: { - name: 'Note', - column: 'note', - fieldType: 'text', - }, - active: { - name: 'Active', - column: 'active', - fieldType: 'boolean', - }, - // Billing Address - billingAddress1: { - name: 'Billing Address 1', - column: 'billing_address1', - fieldType: 'text', - }, - billingAddress2: { - name: 'Billing Address 2', - column: 'billing_address2', - fieldType: 'text', - }, - billingAddressCity: { - name: 'Billing Address City', - column: 'billing_address_city', - fieldType: 'text', - }, - billingAddressCountry: { - name: 'Billing Address Country', - column: 'billing_address_country', - fieldType: 'text', - }, - billingAddressPostcode: { - name: 'Billing Address Postcode', - column: 'billing_address_postcode', - fieldType: 'text', - }, - billingAddressState: { - name: 'Billing Address State', - column: 'billing_address_state', - fieldType: 'text', - }, - billingAddressPhone: { - name: 'Billing Address Phone', - column: 'billing_address_phone', - fieldType: 'text', - }, - // Shipping Address - shippingAddress1: { - name: 'Shipping Address 1', - column: 'shipping_address1', - fieldType: 'text', - }, - shippingAddress2: { - name: 'Shipping Address 2', - column: 'shipping_address2', - fieldType: 'text', - }, - shippingAddressCity: { - name: 'Shipping Address City', - column: 'shipping_address_city', - fieldType: 'text', - }, - shippingAddressCountry: { - name: 'Shipping Address Country', - column: 'shipping_address_country', - fieldType: 'text', - }, - shippingAddressPostcode: { - name: 'Shipping Address Postcode', - column: 'shipping_address_postcode', - fieldType: 'text', - }, - shippingAddressState: { - name: 'Shipping Address State', - column: 'shipping_address_state', - fieldType: 'text', - }, - shippingAddressPhone: { - name: 'Shipping Address Phone', - column: 'shipping_address_phone', - fieldType: 'text', - }, - }, -}; diff --git a/packages/server/src/models/Vendor.ts b/packages/server/src/models/Vendor.ts deleted file mode 100644 index 58cefbdac..000000000 --- a/packages/server/src/models/Vendor.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import PaginationQueryBuilder from './Pagination'; -import ModelSetting from './ModelSetting'; -import VendorSettings from './Vendor.Settings'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Contacts/Vendors/constants'; -import ModelSearchable from './ModelSearchable'; - -class VendorQueryBuilder extends PaginationQueryBuilder { - constructor(...args) { - super(...args); - - this.onBuild((builder) => { - if (builder.isFind() || builder.isDelete() || builder.isUpdate()) { - builder.where('contact_service', 'vendor'); - } - }); - } -} - -export default class Vendor extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Query builder. - */ - static get QueryBuilder() { - return VendorQueryBuilder; - } - - /** - * Table name - */ - static get tableName() { - return 'contacts'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Defined virtual attributes. - */ - static get virtualAttributes() { - return ['closingBalance', 'contactNormal', 'localOpeningBalance']; - } - - /** - * Closing balance attribute. - */ - get closingBalance() { - return this.balance; - } - - /** - * Retrieves the local opening balance. - * @returns {number} - */ - get localOpeningBalance() { - return this.openingBalance - ? this.openingBalance * this.openingBalanceExchangeRate - : 0; - } - - /** - * Retrieve the contact noraml; - */ - get contactNormal() { - return 'debit'; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Inactive/Active mode. - */ - inactiveMode(query, active = false) { - query.where('active', !active); - }, - - /** - * Filters the active customers. - */ - active(query) { - query.where('active', 1); - }, - /** - * Filters the inactive customers. - */ - inactive(query) { - query.where('active', 0); - }, - /** - * Filters the vendors that have overdue invoices. - */ - overdue(query) { - query.select( - '*', - Vendor.relatedQuery('overdueBills', query.knex()) - .count() - .as('countOverdue') - ); - query.having('countOverdue', '>', 0); - }, - /** - * Filters the unpaid customers. - */ - unpaid(query) { - query.whereRaw('`BALANCE` + `OPENING_BALANCE` <> 0'); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Bill = require('models/Bill'); - - return { - bills: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'contacts.id', - to: 'bills.vendorId', - }, - }, - overdueBills: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'contacts.id', - to: 'bills.vendorId', - }, - filter: (query) => { - query.modify('overdue'); - }, - }, - }; - } - - static get meta() { - return VendorSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'display_name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'first_name', comparator: 'contains' }, - { condition: 'or', fieldKey: 'last_name', comparator: 'equals' }, - { condition: 'or', fieldKey: 'company_name', comparator: 'equals' }, - { condition: 'or', fieldKey: 'email', comparator: 'equals' }, - { condition: 'or', fieldKey: 'work_phone', comparator: 'equals' }, - { condition: 'or', fieldKey: 'personal_phone', comparator: 'equals' }, - { condition: 'or', fieldKey: 'website', comparator: 'equals' }, - ]; - } -} diff --git a/packages/server/src/models/VendorCredit.Meta.ts b/packages/server/src/models/VendorCredit.Meta.ts deleted file mode 100644 index a2e197963..000000000 --- a/packages/server/src/models/VendorCredit.Meta.ts +++ /dev/null @@ -1,259 +0,0 @@ -import { Features } from '@/interfaces'; - -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} - -function StatusFieldSortQuery(query, role) { - query.modify('sortByStatus', role.order); -} - -export default { - defaultFilterField: 'name', - defaultSort: { - sortOrder: 'DESC', - sortField: 'name', - }, - exportable: true, - exportFlattenOn: 'entries', - - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'vendorCreditNumber', - - print: { - pageTitle: 'Vendor Credits', - }, - fields: { - vendor: { - name: 'vendor_credit.field.vendor', - column: 'vendor_id', - fieldType: 'relation', - - relationType: 'enumeration', - relationKey: 'vendor', - - relationEntityLabel: 'display_name', - relationEntityKey: 'id', - }, - amount: { - name: 'vendor_credit.field.amount', - column: 'amount', - fieldType: 'number', - }, - currency_code: { - name: 'vendor_credit.field.currency_code', - column: 'currency_code', - fieldType: 'string', - }, - credit_date: { - name: 'vendor_credit.field.credit_date', - column: 'vendor_credit_date', - fieldType: 'date', - }, - reference_no: { - name: 'vendor_credit.field.reference_no', - column: 'reference_no', - fieldType: 'text', - }, - credit_number: { - name: 'vendor_credit.field.credit_number', - column: 'vendor_credit_number', - fieldType: 'text', - }, - note: { - name: 'vendor_credit.field.note', - column: 'note', - fieldType: 'text', - }, - status: { - name: 'vendor_credit.field.status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'vendor_credit.field.status.draft' }, - { key: 'published', label: 'vendor_credit.field.status.published' }, - { key: 'open', label: 'vendor_credit.field.status.open' }, - { key: 'closed', label: 'vendor_credit.field.status.closed' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortCustomQuery: StatusFieldSortQuery, - }, - created_at: { - name: 'vendor_credit.field.created_at', - column: 'created_at', - fieldType: 'date', - }, - }, - columns: { - vendorId: { - name: 'Vendor', - type: 'relation', - accessor: 'vendor.displayName', - }, - exchangeRate: { - name: 'Echange Rate', - type: 'text', - printable: false, - }, - vendorCreditNumber: { - name: 'Vendor Credit No.', - type: 'text', - }, - referenceNo: { - name: 'Refernece No.', - type: 'text', - }, - vendorCreditDate: { - name: 'Vendor Credit Date', - accessor: 'formattedVendorCreditDate', - }, - amount: { - name: 'Amount', - accessor: 'formattedAmount', - }, - creditRemaining: { - name: 'Credits Remaining', - accessor: 'formattedCreditsRemaining', - printable: false, - }, - refundedAmount: { - name: 'Refunded Amount', - accessor: 'refundedAmount', - printable: false, - }, - invoicedAmount: { - name: 'Invoiced Amount', - accessor: 'formattedInvoicedAmount', - }, - note: { - name: 'Note', - type: 'text', - printable: false, - }, - open: { - name: 'Open', - type: 'boolean', - printable: false, - }, - entries: { - name: 'Entries', - type: 'collection', - collectionOf: 'object', - columns: { - itemName: { - name: 'Item Name', - accessor: 'item.name', - }, - rate: { - name: 'Item Rate', - accessor: 'rateFormatted', - }, - quantity: { - name: 'Item Quantity', - accessor: 'quantityFormatted', - }, - description: { - name: 'Item Description', - }, - amount: { - name: 'Item Amount', - accessor: 'totalFormatted', - }, - }, - }, - branch: { - name: 'Branch', - type: 'text', - accessor: 'branch.name', - features: [Features.BRANCHES], - }, - warehouse: { - name: 'Warehouse', - type: 'text', - accessor: 'warehouse.name', - features: [Features.BRANCHES], - }, - }, - fields2: { - vendorId: { - name: 'Vendor', - fieldType: 'relation', - relationModel: 'Contact', - relationImportMatch: 'displayName', - required: true, - }, - exchangeRate: { - name: 'Echange Rate', - fieldType: 'text', - }, - vendorCreditNumber: { - name: 'Vendor Credit No.', - fieldType: 'text', - }, - referenceNo: { - name: 'Refernece No.', - fieldType: 'text', - }, - vendorCreditDate: { - name: 'Vendor Credit Date', - fieldType: 'date', - required: true, - }, - note: { - name: 'Note', - fieldType: 'text', - }, - open: { - name: 'Open', - fieldType: 'boolean', - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 1, - required: true, - fields: { - itemId: { - name: 'Item Name', - fieldType: 'relation', - relationModel: 'Item', - relationImportMatch: ['name', 'code'], - required: true, - importHint: 'Matches the item name or code.', - }, - rate: { - name: 'Rate', - fieldType: 'number', - required: true, - }, - quantity: { - name: 'Quantity', - fieldType: 'number', - required: true, - }, - description: { - name: 'Description', - fieldType: 'text', - }, - }, - }, - branchId: { - name: 'Branch', - fieldType: 'relation', - relationModel: 'Branch', - relationImportMatch: ['name', 'code'], - features: [Features.BRANCHES], - required: true - }, - warehouseId: { - name: 'Warehouse', - fieldType: 'relation', - relationModel: 'Warehouse', - relationImportMatch: ['name', 'code'], - features: [Features.WAREHOUSES], - required: true - }, - }, -}; diff --git a/packages/server/src/models/VendorCredit.ts b/packages/server/src/models/VendorCredit.ts deleted file mode 100644 index 75473060e..000000000 --- a/packages/server/src/models/VendorCredit.ts +++ /dev/null @@ -1,369 +0,0 @@ -import { Model, raw, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import BillSettings from './Bill.Settings'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import { DEFAULT_VIEWS } from '@/services/Purchases/VendorCredits/constants'; -import ModelSearchable from './ModelSearchable'; -import VendorCreditMeta from './VendorCredit.Meta'; -import { DiscountType } from '@/interfaces'; - -export default class VendorCredit extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - public amount: number; - public exchangeRate: number; - public openedAt: Date; - public discount: number; - public discountType: DiscountType; - public adjustment: number; - - /** - * Table name - */ - static get tableName() { - return 'vendor_credits'; - } - /** - * Vendor credit amount in local currency. - * @returns {number} - */ - get localAmount() { - return this.amount * this.exchangeRate; - } - - /** - * Vendor credit subtotal. - * @returns {number} - */ - get subtotal() { - return this.amount; - } - - /** - * Vendor credit subtotal in local currency. - * @returns {number} - */ - get subtotalLocal() { - return this.subtotal * this.exchangeRate; - } - - /** - * Discount amount. - * @returns {number} - */ - get discountAmount() { - return this.discountType === DiscountType.Amount - ? this.discount - : this.subtotal * (this.discount / 100); - } - - /** - * Discount amount in local currency. - * @returns {number | null} - */ - get discountAmountLocal() { - return this.discountAmount ? this.discountAmount * this.exchangeRate : null; - } - - /** - * Discount percentage. - * @returns {number | null} - */ - get discountPercentage(): number | null { - return this.discountType === DiscountType.Percentage ? this.discount : null; - } - - /** - * Adjustment amount in local currency. - * @returns {number | null} - */ - get adjustmentLocal() { - return this.adjustment ? this.adjustment * this.exchangeRate : null; - } - - /** - * Vendor credit total. - * @returns {number} - */ - get total() { - return this.subtotal - this.discountAmount + this.adjustment; - } - - /** - * Vendor credit total in local currency. - * @returns {number} - */ - get totalLocal() { - return this.total * this.exchangeRate; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the credit notes in draft status. - */ - draft(query) { - query.where('opened_at', null); - }, - - /** - * Filters the published vendor credits. - */ - published(query) { - query.whereNot('opened_at', null); - }, - - /** - * Filters the open vendor credits. - */ - open(query) { - query - .where( - raw(`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICED_AMOUNT) < - COALESCE(AMOUNT)`) - ) - .modify('published'); - }, - - /** - * Filters the closed vendor credits. - */ - closed(query) { - query - .where( - raw(`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICED_AMOUNT) = - COALESCE(AMOUNT)`) - ) - .modify('published'); - }, - - /** - * Status filter. - */ - filterByStatus(query, filterType) { - switch (filterType) { - case 'draft': - query.modify('draft'); - break; - case 'published': - query.modify('published'); - break; - case 'open': - default: - query.modify('open'); - break; - case 'closed': - query.modify('closed'); - break; - } - }, - - /** - * - */ - sortByStatus(query, order) { - query.orderByRaw( - `COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICED_AMOUNT) = COALESCE(AMOUNT) ${order}` - ); - }, - }; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return [ - 'isDraft', - 'isPublished', - 'isOpen', - 'isClosed', - - 'creditsRemaining', - 'localAmount', - - 'discountAmount', - 'discountAmountLocal', - 'discountPercentage', - - 'adjustmentLocal', - - 'total', - 'totalLocal', - ]; - } - - /** - * Detarmines whether the vendor credit is draft. - * @returns {boolean} - */ - get isDraft() { - return !this.openedAt; - } - - /** - * Detarmines whether vendor credit is published. - * @returns {boolean} - */ - get isPublished() { - return !!this.openedAt; - } - - /** - * Detarmines whether the credit note is open. - * @return {boolean} - */ - get isOpen() { - return !!this.openedAt && this.creditsRemaining > 0; - } - - /** - * Detarmines whether the credit note is closed. - * @return {boolean} - */ - get isClosed() { - return this.openedAt && this.creditsRemaining === 0; - } - - /** - * Retrieve the credits remaining. - * @returns {number} - */ - get creditsRemaining() { - return Math.max(this.amount - this.refundedAmount - this.invoicedAmount, 0); - } - - /** - * Bill model settings. - */ - static get meta() { - return BillSettings; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Vendor = require('models/Vendor'); - const ItemEntry = require('models/ItemEntry'); - const Branch = require('models/Branch'); - const Document = require('models/Document'); - const Warehouse = require('models/Warehouse'); - - return { - vendor: { - relation: Model.BelongsToOneRelation, - modelClass: Vendor.default, - join: { - from: 'vendor_credits.vendorId', - to: 'contacts.id', - }, - filter(query) { - query.where('contact_service', 'vendor'); - }, - }, - - entries: { - relation: Model.HasManyRelation, - modelClass: ItemEntry.default, - join: { - from: 'vendor_credits.id', - to: 'items_entries.referenceId', - }, - filter(builder) { - builder.where('reference_type', 'VendorCredit'); - builder.orderBy('index', 'ASC'); - }, - }, - - /** - * Vendor credit may belongs to branch. - */ - branch: { - relation: Model.BelongsToOneRelation, - modelClass: Branch.default, - join: { - from: 'vendor_credits.branchId', - to: 'branches.id', - }, - }, - - /** - * Vendor credit may has associated warehouse. - */ - warehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'vendor_credits.warehouseId', - to: 'warehouses.id', - }, - }, - - /** - * Vendor credit may has many attached attachments. - */ - attachments: { - relation: Model.ManyToManyRelation, - modelClass: Document.default, - join: { - from: 'vendor_credits.id', - through: { - from: 'document_links.modelId', - to: 'document_links.documentId', - }, - to: 'documents.id', - }, - filter(query) { - query.where('model_ref', 'VendorCredit'); - }, - }, - }; - } - - /** - * - */ - static get meta() { - return VendorCreditMeta; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search attributes. - */ - static get searchRoles() { - return [ - { fieldKey: 'credit_number', comparator: 'contains' }, - { condition: 'or', fieldKey: 'reference_no', comparator: 'contains' }, - { condition: 'or', fieldKey: 'amount', comparator: 'equals' }, - ]; - } - - /** - * Prevents mutate base currency since the model is not empty. - * @returns {boolean} - */ - static get preventMutateBaseCurrency() { - return true; - } -} diff --git a/packages/server/src/models/VendorCreditAppliedBill.ts b/packages/server/src/models/VendorCreditAppliedBill.ts deleted file mode 100644 index c67aaaf4c..000000000 --- a/packages/server/src/models/VendorCreditAppliedBill.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { mixin, Model } from 'objection'; -import TenantModel from 'models/TenantModel'; -import ModelSetting from './ModelSetting'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSearchable from './ModelSearchable'; - -export default class VendorCreditAppliedBill extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name - */ - static get tableName() { - return 'vendor_credit_applied_bill'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Bill = require('models/Bill'); - const VendorCredit = require('models/VendorCredit'); - - return { - bill: { - relation: Model.BelongsToOneRelation, - modelClass: Bill.default, - join: { - from: 'vendor_credit_applied_bill.billId', - to: 'bills.id', - }, - }, - - vendorCredit: { - relation: Model.BelongsToOneRelation, - modelClass: VendorCredit.default, - join: { - from: 'vendor_credit_applied_bill.vendorCreditId', - to: 'vendor_credits.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/View.ts b/packages/server/src/models/View.ts deleted file mode 100644 index 2745326fd..000000000 --- a/packages/server/src/models/View.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class View extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'views'; - } - - /** - * Model timestamps. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - static get modifiers() { - const TABLE_NAME = View.tableName; - - return { - allMetadata(query) { - query.withGraphFetched('roles.field'); - query.withGraphFetched('columns'); - }, - - specificOrFavourite(query, viewId) { - if (viewId) { - query.where('id', viewId) - } else { - query.where('favourite', true); - } - return query; - } - } - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const ViewColumn = require('models/ViewColumn'); - const ViewRole = require('models/ViewRole'); - - return { - /** - * View model may has many columns. - */ - columns: { - relation: Model.HasManyRelation, - modelClass: ViewColumn.default, - join: { - from: 'views.id', - to: 'view_has_columns.viewId', - }, - }, - - /** - * View model may has many view roles. - */ - roles: { - relation: Model.HasManyRelation, - modelClass: ViewRole.default, - join: { - from: 'views.id', - to: 'view_roles.viewId', - }, - }, - }; - } -} diff --git a/packages/server/src/models/ViewColumn.ts b/packages/server/src/models/ViewColumn.ts deleted file mode 100644 index d3dc38e49..000000000 --- a/packages/server/src/models/ViewColumn.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class ViewColumn extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'view_has_columns'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - - return { - - }; - } -} diff --git a/packages/server/src/models/ViewRole.ts b/packages/server/src/models/ViewRole.ts deleted file mode 100644 index 24fe1f0da..000000000 --- a/packages/server/src/models/ViewRole.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class ViewRole extends TenantModel { - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['comparators']; - } - - static get comparators() { - return [ - 'equals', 'not_equal', 'contains', 'not_contain', - ]; - } - - /** - * Table name. - */ - static get tableName() { - return 'view_roles'; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const View = require('models/View'); - - return { - /** - * View role model may belongs to view model. - */ - view: { - relation: Model.BelongsToOneRelation, - modelClass: View.default, - join: { - from: 'view_roles.viewId', - to: 'views.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/Warehouse.settings.ts b/packages/server/src/models/Warehouse.settings.ts deleted file mode 100644 index 921dc5c0a..000000000 --- a/packages/server/src/models/Warehouse.settings.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default { - fields2: { - name: { - name: 'Name', - fieldType: 'text', - required: true, - }, - }, - columns: {}, - fields: {} -}; diff --git a/packages/server/src/models/Warehouse.ts b/packages/server/src/models/Warehouse.ts deleted file mode 100644 index 6657c9a15..000000000 --- a/packages/server/src/models/Warehouse.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class Warehouse extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'warehouses'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters accounts by the given ids. - * @param {Query} query - * @param {number[]} accountsIds - */ - isPrimary(query) { - query.where('primary', true); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const SaleInvoice = require('models/SaleInvoice'); - const SaleEstimate = require('models/SaleEstimate'); - const SaleReceipt = require('models/SaleReceipt'); - const Bill = require('models/Bill'); - const VendorCredit = require('models/VendorCredit'); - const CreditNote = require('models/CreditNote'); - const InventoryTransaction = require('models/InventoryTransaction'); - const WarehouseTransfer = require('models/WarehouseTransfer'); - const InventoryAdjustment = require('models/InventoryAdjustment'); - - return { - /** - * Warehouse may belongs to associated sale invoices. - */ - invoices: { - relation: Model.HasManyRelation, - modelClass: SaleInvoice.default, - join: { - from: 'warehouses.id', - to: 'sales_invoices.warehouseId', - }, - }, - - /** - * Warehouse may belongs to associated sale estimates. - */ - estimates: { - relation: Model.HasManyRelation, - modelClass: SaleEstimate.default, - join: { - from: 'warehouses.id', - to: 'sales_estimates.warehouseId', - }, - }, - - /** - * Warehouse may belongs to associated sale receipts. - */ - receipts: { - relation: Model.HasManyRelation, - modelClass: SaleReceipt.default, - join: { - from: 'warehouses.id', - to: 'sales_receipts.warehouseId', - }, - }, - - /** - * Warehouse may belongs to associated bills. - */ - bills: { - relation: Model.HasManyRelation, - modelClass: Bill.default, - join: { - from: 'warehouses.id', - to: 'bills.warehouseId', - }, - }, - - /** - * Warehouse may belongs to associated credit notes. - */ - creditNotes: { - relation: Model.HasManyRelation, - modelClass: CreditNote.default, - join: { - from: 'warehouses.id', - to: 'credit_notes.warehouseId', - }, - }, - - /** - * Warehouse may belongs to associated to vendor credits. - */ - vendorCredit: { - relation: Model.HasManyRelation, - modelClass: VendorCredit.default, - join: { - from: 'warehouses.id', - to: 'vendor_credits.warehouseId', - }, - }, - - /** - * Warehouse may belongs to associated to inventory transactions. - */ - inventoryTransactions: { - relation: Model.HasManyRelation, - modelClass: InventoryTransaction.default, - join: { - from: 'warehouses.id', - to: 'inventory_transactions.warehouseId', - }, - }, - - warehouseTransferTo: { - relation: Model.HasManyRelation, - modelClass: WarehouseTransfer.default, - join: { - from: 'warehouses.id', - to: 'warehouses_transfers.toWarehouseId', - }, - }, - - warehouseTransferFrom: { - relation: Model.HasManyRelation, - modelClass: WarehouseTransfer.default, - join: { - from: 'warehouses.id', - to: 'warehouses_transfers.fromWarehouseId', - }, - }, - - inventoryAdjustment: { - relation: Model.HasManyRelation, - modelClass: InventoryAdjustment.default, - join: { - from: 'warehouses.id', - to: 'inventory_adjustments.warehouseId', - }, - }, - }; - } -} diff --git a/packages/server/src/models/WarehouseTransfer.Settings.ts b/packages/server/src/models/WarehouseTransfer.Settings.ts deleted file mode 100644 index d20064187..000000000 --- a/packages/server/src/models/WarehouseTransfer.Settings.ts +++ /dev/null @@ -1,69 +0,0 @@ -function StatusFieldFilterQuery(query, role) { - query.modify('filterByStatus', role.value); -} - -export default { - defaultFilterField: 'name', - defaultSort: { - sortField: 'name', - sortOrder: 'DESC', - }, - columns: { - date: { - name: 'warehouse_transfer.field.date', - type: 'date', - exportable: true, - }, - transaction_number: { - name: 'warehouse_transfer.field.transaction_number', - type: 'text', - exportable: true, - }, - status: { - name: 'warehouse_transfer.field.status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'Draft' }, - { key: 'in-transit', label: 'In Transit' }, - { key: 'transferred', label: 'Transferred' }, - ], - sortable: false, - }, - created_at: { - name: 'warehouse_transfer.field.created_at', - column: 'created_at', - columnType: 'date', - fieldType: 'date', - }, - }, - fields: { - date: { - name: 'warehouse_transfer.field.date', - column: 'date', - columnType: 'date', - fieldType: 'date', - }, - transaction_number: { - name: 'warehouse_transfer.field.transaction_number', - column: 'transaction_number', - fieldType: 'text', - }, - status: { - name: 'warehouse_transfer.field.status', - fieldType: 'enumeration', - options: [ - { key: 'draft', label: 'Draft' }, - { key: 'in-transit', label: 'In Transit' }, - { key: 'transferred', label: 'Transferred' }, - ], - filterCustomQuery: StatusFieldFilterQuery, - sortable: false, - }, - created_at: { - name: 'warehouse_transfer.field.created_at', - column: 'created_at', - columnType: 'date', - fieldType: 'date', - }, - }, -}; diff --git a/packages/server/src/models/WarehouseTransfer.ts b/packages/server/src/models/WarehouseTransfer.ts deleted file mode 100644 index 82957dfeb..000000000 --- a/packages/server/src/models/WarehouseTransfer.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import WarehouseTransferSettings from './WarehouseTransfer.Settings'; -import ModelSearchable from './ModelSearchable'; -import CustomViewBaseModel from './CustomViewBaseModel'; -import ModelSetting from './ModelSetting'; -import { DEFAULT_VIEWS } from '../services/Warehouses/WarehousesTransfers/constants'; - -export default class WarehouseTransfer extends mixin(TenantModel, [ - ModelSetting, - CustomViewBaseModel, - ModelSearchable, -]) { - /** - * Table name. - */ - static get tableName() { - return 'warehouses_transfers'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['created_at', 'updated_at']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['isInitiated', 'isTransferred']; - } - - /** - * Detarmines whether the warehouse transfer initiated. - * @retruns {boolean} - */ - get isInitiated() { - return !!this.transferInitiatedAt; - } - - /** - * Detarmines whether the warehouse transfer transferred. - * @returns {boolean} - */ - get isTransferred() { - return !!this.transferDeliveredAt; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - filterByDraft(query) { - query.whereNull('transferInitiatedAt'); - query.whereNull('transferDeliveredAt'); - }, - filterByInTransit(query) { - query.whereNotNull('transferInitiatedAt'); - query.whereNull('transferDeliveredAt'); - }, - filterByTransferred(query) { - query.whereNotNull('transferInitiatedAt'); - query.whereNotNull('transferDeliveredAt'); - }, - filterByStatus(query, status) { - switch (status) { - case 'draft': - default: - return query.modify('filterByDraft'); - case 'in-transit': - return query.modify('filterByInTransit'); - case 'transferred': - return query.modify('filterByTransferred'); - } - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const WarehouseTransferEntry = require('models/WarehouseTransferEntry'); - const Warehouse = require('models/Warehouse'); - - return { - /** - * View model may has many columns. - */ - entries: { - relation: Model.HasManyRelation, - modelClass: WarehouseTransferEntry.default, - join: { - from: 'warehouses_transfers.id', - to: 'warehouses_transfers_entries.warehouseTransferId', - }, - }, - - /** - * - */ - fromWarehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'warehouses_transfers.fromWarehouseId', - to: 'warehouses.id', - }, - }, - - toWarehouse: { - relation: Model.BelongsToOneRelation, - modelClass: Warehouse.default, - join: { - from: 'warehouses_transfers.toWarehouseId', - to: 'warehouses.id', - }, - }, - }; - } - - /** - * Model settings. - */ - static get meta() { - return WarehouseTransferSettings; - } - - /** - * Retrieve the default custom views, roles and columns. - */ - static get defaultViews() { - return DEFAULT_VIEWS; - } - - /** - * Model search roles. - */ - static get searchRoles() { - return [ - // { fieldKey: 'name', comparator: 'contains' }, - // { condition: 'or', fieldKey: 'code', comparator: 'like' }, - ]; - } -} diff --git a/packages/server/src/models/WarehouseTransferEntry.ts b/packages/server/src/models/WarehouseTransferEntry.ts deleted file mode 100644 index 2fba52495..000000000 --- a/packages/server/src/models/WarehouseTransferEntry.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Model } from 'objection'; -import TenantModel from 'models/TenantModel'; - -export default class Warehouse extends TenantModel { - /** - * Table name. - */ - static get tableName() { - return 'warehouses_transfers_entries'; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['total']; - } - - /** - * Invoice amount in local currency. - * @returns {number} - */ - get total() { - return this.cost * this.quantity; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Item = require('models/Item'); - - return { - item: { - relation: Model.BelongsToOneRelation, - modelClass: Item.default, - join: { - from: 'warehouses_transfers_entries.itemId', - to: 'items.id', - }, - }, - }; - } -} diff --git a/packages/server/src/models/index.ts b/packages/server/src/models/index.ts deleted file mode 100644 index 5196acd92..000000000 --- a/packages/server/src/models/index.ts +++ /dev/null @@ -1,55 +0,0 @@ -import Option from './Option'; -import Setting from './Setting'; -import SaleEstimate from './SaleEstimate'; -import SaleEstimateEntry from './SaleEstimateEntry'; -import SaleReceipt from './SaleReceipt'; -import SaleReceiptEntry from './SaleReceiptEntry'; -import Item from './Item'; -import Account from './Account'; -import AccountTransaction from './AccountTransaction'; -import SaleInvoice from './SaleInvoice'; -import SaleInvoiceEntry from './SaleInvoiceEntry'; -import PaymentReceive from './PaymentReceive'; -import PaymentReceiveEntry from './PaymentReceiveEntry'; -import Bill from './Bill'; -import BillPayment from './BillPayment'; -import BillPaymentEntry from './BillPaymentEntry'; -import View from './View'; -import ItemEntry from './ItemEntry'; -import InventoryTransaction from './InventoryTransaction'; -import InventoryLotCostTracker from './InventoryCostLotTracker'; -import Customer from './Customer'; -import Contact from './Contact'; -import Vendor from './Vendor'; -import ExpenseCategory from './ExpenseCategory'; -import Expense from './Expense'; -import ManualJournal from './ManualJournal'; - -export { - SaleEstimate, - SaleEstimateEntry, - SaleReceipt, - SaleReceiptEntry, - SaleInvoice, - SaleInvoiceEntry, - Item, - Account, - AccountTransaction, - PaymentReceive, - PaymentReceiveEntry, - Bill, - BillPayment, - BillPaymentEntry, - View, - ItemEntry, - InventoryTransaction, - InventoryLotCostTracker, - Option, - Contact, - ExpenseCategory, - Expense, - ManualJournal, - Customer, - Vendor, - Setting -}; \ No newline at end of file diff --git a/packages/server-nest/src/modules/Accounts/Account.transformer.ts b/packages/server/src/modules/Accounts/Account.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/Account.transformer.ts rename to packages/server/src/modules/Accounts/Account.transformer.ts diff --git a/packages/server-nest/src/modules/Accounts/AccountTransaction.transformer.ts b/packages/server/src/modules/Accounts/AccountTransaction.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/AccountTransaction.transformer.ts rename to packages/server/src/modules/Accounts/AccountTransaction.transformer.ts diff --git a/packages/server-nest/src/modules/Accounts/Accounts.constants.ts b/packages/server/src/modules/Accounts/Accounts.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/Accounts.constants.ts rename to packages/server/src/modules/Accounts/Accounts.constants.ts diff --git a/packages/server-nest/src/modules/Accounts/Accounts.controller.ts b/packages/server/src/modules/Accounts/Accounts.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/Accounts.controller.ts rename to packages/server/src/modules/Accounts/Accounts.controller.ts diff --git a/packages/server-nest/src/modules/Accounts/Accounts.module.ts b/packages/server/src/modules/Accounts/Accounts.module.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/Accounts.module.ts rename to packages/server/src/modules/Accounts/Accounts.module.ts diff --git a/packages/server-nest/src/modules/Accounts/Accounts.types.ts b/packages/server/src/modules/Accounts/Accounts.types.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/Accounts.types.ts rename to packages/server/src/modules/Accounts/Accounts.types.ts diff --git a/packages/server-nest/src/modules/Accounts/AccountsApplication.service.ts b/packages/server/src/modules/Accounts/AccountsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/AccountsApplication.service.ts rename to packages/server/src/modules/Accounts/AccountsApplication.service.ts diff --git a/packages/server-nest/src/modules/Accounts/AccountsExportable.service.ts b/packages/server/src/modules/Accounts/AccountsExportable.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/AccountsExportable.service.ts rename to packages/server/src/modules/Accounts/AccountsExportable.service.ts diff --git a/packages/server-nest/src/modules/Accounts/AccountsImportable.SampleData.ts b/packages/server/src/modules/Accounts/AccountsImportable.SampleData.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/AccountsImportable.SampleData.ts rename to packages/server/src/modules/Accounts/AccountsImportable.SampleData.ts diff --git a/packages/server-nest/src/modules/Accounts/AccountsImportable.service.ts b/packages/server/src/modules/Accounts/AccountsImportable.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/AccountsImportable.service.ts rename to packages/server/src/modules/Accounts/AccountsImportable.service.ts diff --git a/packages/server-nest/src/modules/Accounts/ActivateAccount.service.ts b/packages/server/src/modules/Accounts/ActivateAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/ActivateAccount.service.ts rename to packages/server/src/modules/Accounts/ActivateAccount.service.ts diff --git a/packages/server-nest/src/modules/Accounts/CommandAccountValidators.service.ts b/packages/server/src/modules/Accounts/CommandAccountValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/CommandAccountValidators.service.ts rename to packages/server/src/modules/Accounts/CommandAccountValidators.service.ts diff --git a/packages/server-nest/src/modules/Accounts/CreateAccount.dto.ts b/packages/server/src/modules/Accounts/CreateAccount.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/CreateAccount.dto.ts rename to packages/server/src/modules/Accounts/CreateAccount.dto.ts diff --git a/packages/server-nest/src/modules/Accounts/CreateAccount.service.ts b/packages/server/src/modules/Accounts/CreateAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/CreateAccount.service.ts rename to packages/server/src/modules/Accounts/CreateAccount.service.ts diff --git a/packages/server-nest/src/modules/Accounts/DeleteAccount.service.ts b/packages/server/src/modules/Accounts/DeleteAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/DeleteAccount.service.ts rename to packages/server/src/modules/Accounts/DeleteAccount.service.ts diff --git a/packages/server-nest/src/modules/Accounts/EditAccount.dto.ts b/packages/server/src/modules/Accounts/EditAccount.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/EditAccount.dto.ts rename to packages/server/src/modules/Accounts/EditAccount.dto.ts diff --git a/packages/server-nest/src/modules/Accounts/EditAccount.service.ts b/packages/server/src/modules/Accounts/EditAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/EditAccount.service.ts rename to packages/server/src/modules/Accounts/EditAccount.service.ts diff --git a/packages/server-nest/src/modules/Accounts/GetAccount.service.ts b/packages/server/src/modules/Accounts/GetAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/GetAccount.service.ts rename to packages/server/src/modules/Accounts/GetAccount.service.ts diff --git a/packages/server-nest/src/modules/Accounts/GetAccountTransactions.service.ts b/packages/server/src/modules/Accounts/GetAccountTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/GetAccountTransactions.service.ts rename to packages/server/src/modules/Accounts/GetAccountTransactions.service.ts diff --git a/packages/server-nest/src/modules/Accounts/GetAccountTypes.service.ts b/packages/server/src/modules/Accounts/GetAccountTypes.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/GetAccountTypes.service.ts rename to packages/server/src/modules/Accounts/GetAccountTypes.service.ts diff --git a/packages/server-nest/src/modules/Accounts/GetAccounts.service.ts b/packages/server/src/modules/Accounts/GetAccounts.service.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/GetAccounts.service.ts rename to packages/server/src/modules/Accounts/GetAccounts.service.ts diff --git a/packages/server-nest/src/modules/Accounts/MutateBaseCurrencyAccounts.ts b/packages/server/src/modules/Accounts/MutateBaseCurrencyAccounts.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/MutateBaseCurrencyAccounts.ts rename to packages/server/src/modules/Accounts/MutateBaseCurrencyAccounts.ts diff --git a/packages/server-nest/src/modules/Accounts/constants.ts b/packages/server/src/modules/Accounts/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/constants.ts rename to packages/server/src/modules/Accounts/constants.ts diff --git a/packages/server-nest/src/modules/Accounts/models/Account.model.ts b/packages/server/src/modules/Accounts/models/Account.model.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/models/Account.model.ts rename to packages/server/src/modules/Accounts/models/Account.model.ts diff --git a/packages/server-nest/src/modules/Accounts/models/AccountTransaction.model.ts b/packages/server/src/modules/Accounts/models/AccountTransaction.model.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/models/AccountTransaction.model.ts rename to packages/server/src/modules/Accounts/models/AccountTransaction.model.ts diff --git a/packages/server-nest/src/modules/Accounts/repositories/Account.repository.ts b/packages/server/src/modules/Accounts/repositories/Account.repository.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/repositories/Account.repository.ts rename to packages/server/src/modules/Accounts/repositories/Account.repository.ts diff --git a/packages/server-nest/src/modules/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts b/packages/server/src/modules/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts rename to packages/server/src/modules/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts diff --git a/packages/server-nest/src/modules/Accounts/utils/AccountType.utils.ts b/packages/server/src/modules/Accounts/utils/AccountType.utils.ts similarity index 100% rename from packages/server-nest/src/modules/Accounts/utils/AccountType.utils.ts rename to packages/server/src/modules/Accounts/utils/AccountType.utils.ts diff --git a/packages/server-nest/src/modules/App/App.controller.spec.ts b/packages/server/src/modules/App/App.controller.spec.ts similarity index 100% rename from packages/server-nest/src/modules/App/App.controller.spec.ts rename to packages/server/src/modules/App/App.controller.spec.ts diff --git a/packages/server-nest/src/modules/App/App.controller.ts b/packages/server/src/modules/App/App.controller.ts similarity index 100% rename from packages/server-nest/src/modules/App/App.controller.ts rename to packages/server/src/modules/App/App.controller.ts diff --git a/packages/server-nest/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts similarity index 100% rename from packages/server-nest/src/modules/App/App.module.ts rename to packages/server/src/modules/App/App.module.ts diff --git a/packages/server-nest/src/modules/App/App.service.ts b/packages/server/src/modules/App/App.service.ts similarity index 100% rename from packages/server-nest/src/modules/App/App.service.ts rename to packages/server/src/modules/App/App.service.ts diff --git a/packages/server-nest/src/modules/Attachments/Attachment.module.ts b/packages/server/src/modules/Attachments/Attachment.module.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/Attachment.module.ts rename to packages/server/src/modules/Attachments/Attachment.module.ts diff --git a/packages/server-nest/src/modules/Attachments/Attachment.transformer.ts b/packages/server/src/modules/Attachments/Attachment.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/Attachment.transformer.ts rename to packages/server/src/modules/Attachments/Attachment.transformer.ts diff --git a/packages/server-nest/src/modules/Attachments/AttachmentTransformer.ts b/packages/server/src/modules/Attachments/AttachmentTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/AttachmentTransformer.ts rename to packages/server/src/modules/Attachments/AttachmentTransformer.ts diff --git a/packages/server-nest/src/modules/Attachments/Attachments.controller.ts b/packages/server/src/modules/Attachments/Attachments.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/Attachments.controller.ts rename to packages/server/src/modules/Attachments/Attachments.controller.ts diff --git a/packages/server-nest/src/modules/Attachments/Attachments.types.ts b/packages/server/src/modules/Attachments/Attachments.types.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/Attachments.types.ts rename to packages/server/src/modules/Attachments/Attachments.types.ts diff --git a/packages/server-nest/src/modules/Attachments/AttachmentsApplication.ts b/packages/server/src/modules/Attachments/AttachmentsApplication.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/AttachmentsApplication.ts rename to packages/server/src/modules/Attachments/AttachmentsApplication.ts diff --git a/packages/server-nest/src/modules/Attachments/DeleteAttachment.ts b/packages/server/src/modules/Attachments/DeleteAttachment.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/DeleteAttachment.ts rename to packages/server/src/modules/Attachments/DeleteAttachment.ts diff --git a/packages/server-nest/src/modules/Attachments/GetAttachment.ts b/packages/server/src/modules/Attachments/GetAttachment.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/GetAttachment.ts rename to packages/server/src/modules/Attachments/GetAttachment.ts diff --git a/packages/server-nest/src/modules/Attachments/GetAttachmentPresignedUrl.ts b/packages/server/src/modules/Attachments/GetAttachmentPresignedUrl.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/GetAttachmentPresignedUrl.ts rename to packages/server/src/modules/Attachments/GetAttachmentPresignedUrl.ts diff --git a/packages/server-nest/src/modules/Attachments/LinkAttachment.ts b/packages/server/src/modules/Attachments/LinkAttachment.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/LinkAttachment.ts rename to packages/server/src/modules/Attachments/LinkAttachment.ts diff --git a/packages/server-nest/src/modules/Attachments/S3UploadPipeline.ts b/packages/server/src/modules/Attachments/S3UploadPipeline.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/S3UploadPipeline.ts rename to packages/server/src/modules/Attachments/S3UploadPipeline.ts diff --git a/packages/server-nest/src/modules/Attachments/UnlinkAttachment.ts b/packages/server/src/modules/Attachments/UnlinkAttachment.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/UnlinkAttachment.ts rename to packages/server/src/modules/Attachments/UnlinkAttachment.ts diff --git a/packages/server-nest/src/modules/Attachments/UploadDocument.ts b/packages/server/src/modules/Attachments/UploadDocument.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/UploadDocument.ts rename to packages/server/src/modules/Attachments/UploadDocument.ts diff --git a/packages/server-nest/src/modules/Attachments/ValidateAttachments.ts b/packages/server/src/modules/Attachments/ValidateAttachments.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/ValidateAttachments.ts rename to packages/server/src/modules/Attachments/ValidateAttachments.ts diff --git a/packages/server-nest/src/modules/Attachments/_utils.ts b/packages/server/src/modules/Attachments/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/_utils.ts rename to packages/server/src/modules/Attachments/_utils.ts diff --git a/packages/server-nest/src/modules/Attachments/constants.ts b/packages/server/src/modules/Attachments/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/constants.ts rename to packages/server/src/modules/Attachments/constants.ts diff --git a/packages/server-nest/src/modules/Attachments/decorators/InjectAttachable.decorator.ts b/packages/server/src/modules/Attachments/decorators/InjectAttachable.decorator.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/decorators/InjectAttachable.decorator.ts rename to packages/server/src/modules/Attachments/decorators/InjectAttachable.decorator.ts diff --git a/packages/server-nest/src/modules/Attachments/dtos/Attachment.dto.ts b/packages/server/src/modules/Attachments/dtos/Attachment.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/dtos/Attachment.dto.ts rename to packages/server/src/modules/Attachments/dtos/Attachment.dto.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnBills.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnBills.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnBills.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnBills.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnCreditNote.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnCreditNote.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnCreditNote.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnCreditNote.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnExpenses.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnExpenses.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnExpenses.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnExpenses.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnManualJournals.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnManualJournals.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnManualJournals.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnManualJournals.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnPaymentsMade.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnPaymentsMade.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnPaymentsMade.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnPaymentsMade.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnPaymentsReceived.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnPaymentsReceived.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnPaymentsReceived.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnPaymentsReceived.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnSaleEstimates.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnSaleEstimates.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnSaleEstimates.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnSaleEstimates.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnSaleInvoice.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnSaleInvoice.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnSaleInvoice.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnSaleInvoice.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnSaleReceipts.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnSaleReceipts.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnSaleReceipts.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnSaleReceipts.ts diff --git a/packages/server-nest/src/modules/Attachments/events/AttachmentsOnVendorCredits.ts b/packages/server/src/modules/Attachments/events/AttachmentsOnVendorCredits.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/events/AttachmentsOnVendorCredits.ts rename to packages/server/src/modules/Attachments/events/AttachmentsOnVendorCredits.ts diff --git a/packages/server-nest/src/modules/Attachments/models/Document.model.ts b/packages/server/src/modules/Attachments/models/Document.model.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/models/Document.model.ts rename to packages/server/src/modules/Attachments/models/Document.model.ts diff --git a/packages/server-nest/src/modules/Attachments/models/DocumentLink.model.ts b/packages/server/src/modules/Attachments/models/DocumentLink.model.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/models/DocumentLink.model.ts rename to packages/server/src/modules/Attachments/models/DocumentLink.model.ts diff --git a/packages/server-nest/src/modules/Attachments/utils.ts b/packages/server/src/modules/Attachments/utils.ts similarity index 100% rename from packages/server-nest/src/modules/Attachments/utils.ts rename to packages/server/src/modules/Attachments/utils.ts diff --git a/packages/server-nest/src/modules/Auth/Auth.constants.ts b/packages/server/src/modules/Auth/Auth.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/Auth.constants.ts rename to packages/server/src/modules/Auth/Auth.constants.ts diff --git a/packages/server-nest/src/modules/Auth/Auth.controller.ts b/packages/server/src/modules/Auth/Auth.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/Auth.controller.ts rename to packages/server/src/modules/Auth/Auth.controller.ts diff --git a/packages/server-nest/src/modules/Auth/Auth.interfaces.ts b/packages/server/src/modules/Auth/Auth.interfaces.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/Auth.interfaces.ts rename to packages/server/src/modules/Auth/Auth.interfaces.ts diff --git a/packages/server-nest/src/modules/Auth/Auth.module.ts b/packages/server/src/modules/Auth/Auth.module.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/Auth.module.ts rename to packages/server/src/modules/Auth/Auth.module.ts diff --git a/packages/server-nest/src/modules/Auth/Auth.utils.ts b/packages/server/src/modules/Auth/Auth.utils.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/Auth.utils.ts rename to packages/server/src/modules/Auth/Auth.utils.ts diff --git a/packages/server-nest/src/modules/Auth/AuthApplication.sevice.ts b/packages/server/src/modules/Auth/AuthApplication.sevice.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/AuthApplication.sevice.ts rename to packages/server/src/modules/Auth/AuthApplication.sevice.ts diff --git a/packages/server-nest/src/modules/Auth/AuthMailMessages.esrvice.ts b/packages/server/src/modules/Auth/AuthMailMessages.esrvice.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/AuthMailMessages.esrvice.ts rename to packages/server/src/modules/Auth/AuthMailMessages.esrvice.ts diff --git a/packages/server-nest/src/modules/Auth/commands/AuthResetPassword.service.ts b/packages/server/src/modules/Auth/commands/AuthResetPassword.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/commands/AuthResetPassword.service.ts rename to packages/server/src/modules/Auth/commands/AuthResetPassword.service.ts diff --git a/packages/server-nest/src/modules/Auth/commands/AuthSendResetPassword.service.ts b/packages/server/src/modules/Auth/commands/AuthSendResetPassword.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/commands/AuthSendResetPassword.service.ts rename to packages/server/src/modules/Auth/commands/AuthSendResetPassword.service.ts diff --git a/packages/server-nest/src/modules/Auth/commands/AuthSignin.service.ts b/packages/server/src/modules/Auth/commands/AuthSignin.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/commands/AuthSignin.service.ts rename to packages/server/src/modules/Auth/commands/AuthSignin.service.ts diff --git a/packages/server-nest/src/modules/Auth/commands/AuthSignup.service.ts b/packages/server/src/modules/Auth/commands/AuthSignup.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/commands/AuthSignup.service.ts rename to packages/server/src/modules/Auth/commands/AuthSignup.service.ts diff --git a/packages/server-nest/src/modules/Auth/commands/AuthSignupConfirm.service.ts b/packages/server/src/modules/Auth/commands/AuthSignupConfirm.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/commands/AuthSignupConfirm.service.ts rename to packages/server/src/modules/Auth/commands/AuthSignupConfirm.service.ts diff --git a/packages/server-nest/src/modules/Auth/commands/AuthSignupConfirmResend.service.ts b/packages/server/src/modules/Auth/commands/AuthSignupConfirmResend.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/commands/AuthSignupConfirmResend.service.ts rename to packages/server/src/modules/Auth/commands/AuthSignupConfirmResend.service.ts diff --git a/packages/server-nest/src/modules/Auth/dtos/AuthSignin.dto.ts b/packages/server/src/modules/Auth/dtos/AuthSignin.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/dtos/AuthSignin.dto.ts rename to packages/server/src/modules/Auth/dtos/AuthSignin.dto.ts diff --git a/packages/server-nest/src/modules/Auth/dtos/AuthSignup.dto.ts b/packages/server/src/modules/Auth/dtos/AuthSignup.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/dtos/AuthSignup.dto.ts rename to packages/server/src/modules/Auth/dtos/AuthSignup.dto.ts diff --git a/packages/server-nest/src/modules/Auth/guards/Local.guard.ts b/packages/server/src/modules/Auth/guards/Local.guard.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/guards/Local.guard.ts rename to packages/server/src/modules/Auth/guards/Local.guard.ts diff --git a/packages/server-nest/src/modules/Auth/guards/jwt.guard.ts b/packages/server/src/modules/Auth/guards/jwt.guard.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/guards/jwt.guard.ts rename to packages/server/src/modules/Auth/guards/jwt.guard.ts diff --git a/packages/server-nest/src/modules/Auth/models/PasswordReset.ts b/packages/server/src/modules/Auth/models/PasswordReset.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/models/PasswordReset.ts rename to packages/server/src/modules/Auth/models/PasswordReset.ts diff --git a/packages/server-nest/src/modules/Auth/processors/SendResetPasswordMail.processor.ts b/packages/server/src/modules/Auth/processors/SendResetPasswordMail.processor.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/processors/SendResetPasswordMail.processor.ts rename to packages/server/src/modules/Auth/processors/SendResetPasswordMail.processor.ts diff --git a/packages/server-nest/src/modules/Auth/processors/SendSignupVerificationMail.processor.ts b/packages/server/src/modules/Auth/processors/SendSignupVerificationMail.processor.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/processors/SendSignupVerificationMail.processor.ts rename to packages/server/src/modules/Auth/processors/SendSignupVerificationMail.processor.ts diff --git a/packages/server-nest/src/modules/Auth/queries/GetAuthMeta.service.ts b/packages/server/src/modules/Auth/queries/GetAuthMeta.service.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/queries/GetAuthMeta.service.ts rename to packages/server/src/modules/Auth/queries/GetAuthMeta.service.ts diff --git a/packages/server-nest/src/modules/Auth/strategies/Jwt.strategy.ts b/packages/server/src/modules/Auth/strategies/Jwt.strategy.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/strategies/Jwt.strategy.ts rename to packages/server/src/modules/Auth/strategies/Jwt.strategy.ts diff --git a/packages/server-nest/src/modules/Auth/strategies/Local.strategy.ts b/packages/server/src/modules/Auth/strategies/Local.strategy.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/strategies/Local.strategy.ts rename to packages/server/src/modules/Auth/strategies/Local.strategy.ts diff --git a/packages/server-nest/src/modules/Auth/subscribers/AuthMail.subscriber.ts b/packages/server/src/modules/Auth/subscribers/AuthMail.subscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Auth/subscribers/AuthMail.subscriber.ts rename to packages/server/src/modules/Auth/subscribers/AuthMail.subscriber.ts diff --git a/packages/server-nest/src/modules/AutoIncrementOrders/AutoIncrementOrders.module.ts b/packages/server/src/modules/AutoIncrementOrders/AutoIncrementOrders.module.ts similarity index 100% rename from packages/server-nest/src/modules/AutoIncrementOrders/AutoIncrementOrders.module.ts rename to packages/server/src/modules/AutoIncrementOrders/AutoIncrementOrders.module.ts diff --git a/packages/server-nest/src/modules/AutoIncrementOrders/AutoIncrementOrders.service.ts b/packages/server/src/modules/AutoIncrementOrders/AutoIncrementOrders.service.ts similarity index 100% rename from packages/server-nest/src/modules/AutoIncrementOrders/AutoIncrementOrders.service.ts rename to packages/server/src/modules/AutoIncrementOrders/AutoIncrementOrders.service.ts diff --git a/packages/server-nest/src/modules/BankRules/BankRules.controller.ts b/packages/server/src/modules/BankRules/BankRules.controller.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/BankRules.controller.ts rename to packages/server/src/modules/BankRules/BankRules.controller.ts diff --git a/packages/server-nest/src/modules/BankRules/BankRules.module.ts b/packages/server/src/modules/BankRules/BankRules.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/BankRules.module.ts rename to packages/server/src/modules/BankRules/BankRules.module.ts diff --git a/packages/server-nest/src/modules/BankRules/BankRulesApplication.ts b/packages/server/src/modules/BankRules/BankRulesApplication.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/BankRulesApplication.ts rename to packages/server/src/modules/BankRules/BankRulesApplication.ts diff --git a/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts b/packages/server/src/modules/BankRules/commands/CreateBankRule.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts rename to packages/server/src/modules/BankRules/commands/CreateBankRule.service.ts diff --git a/packages/server-nest/src/modules/BankRules/commands/DeleteBankRule.service.ts b/packages/server/src/modules/BankRules/commands/DeleteBankRule.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/commands/DeleteBankRule.service.ts rename to packages/server/src/modules/BankRules/commands/DeleteBankRule.service.ts diff --git a/packages/server-nest/src/modules/BankRules/commands/DeleteBankRules.service.ts b/packages/server/src/modules/BankRules/commands/DeleteBankRules.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/commands/DeleteBankRules.service.ts rename to packages/server/src/modules/BankRules/commands/DeleteBankRules.service.ts diff --git a/packages/server-nest/src/modules/BankRules/commands/EditBankRule.service.ts b/packages/server/src/modules/BankRules/commands/EditBankRule.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/commands/EditBankRule.service.ts rename to packages/server/src/modules/BankRules/commands/EditBankRule.service.ts diff --git a/packages/server-nest/src/modules/BankRules/dtos/BankRule.dto.ts b/packages/server/src/modules/BankRules/dtos/BankRule.dto.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/dtos/BankRule.dto.ts rename to packages/server/src/modules/BankRules/dtos/BankRule.dto.ts diff --git a/packages/server-nest/src/modules/BankRules/events/UnlinkBankRuleOnDeleteBankRule.ts b/packages/server/src/modules/BankRules/events/UnlinkBankRuleOnDeleteBankRule.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/events/UnlinkBankRuleOnDeleteBankRule.ts rename to packages/server/src/modules/BankRules/events/UnlinkBankRuleOnDeleteBankRule.ts diff --git a/packages/server-nest/src/modules/BankRules/models/BankRule.ts b/packages/server/src/modules/BankRules/models/BankRule.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/models/BankRule.ts rename to packages/server/src/modules/BankRules/models/BankRule.ts diff --git a/packages/server-nest/src/modules/BankRules/models/BankRuleCondition.ts b/packages/server/src/modules/BankRules/models/BankRuleCondition.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/models/BankRuleCondition.ts rename to packages/server/src/modules/BankRules/models/BankRuleCondition.ts diff --git a/packages/server-nest/src/modules/BankRules/queries/GetBankRule.service.ts b/packages/server/src/modules/BankRules/queries/GetBankRule.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/queries/GetBankRule.service.ts rename to packages/server/src/modules/BankRules/queries/GetBankRule.service.ts diff --git a/packages/server-nest/src/modules/BankRules/queries/GetBankRuleTransformer.ts b/packages/server/src/modules/BankRules/queries/GetBankRuleTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/queries/GetBankRuleTransformer.ts rename to packages/server/src/modules/BankRules/queries/GetBankRuleTransformer.ts diff --git a/packages/server-nest/src/modules/BankRules/queries/GetBankRules.service.ts b/packages/server/src/modules/BankRules/queries/GetBankRules.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/queries/GetBankRules.service.ts rename to packages/server/src/modules/BankRules/queries/GetBankRules.service.ts diff --git a/packages/server-nest/src/modules/BankRules/queries/GetBankRulesTransformer.ts b/packages/server/src/modules/BankRules/queries/GetBankRulesTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/queries/GetBankRulesTransformer.ts rename to packages/server/src/modules/BankRules/queries/GetBankRulesTransformer.ts diff --git a/packages/server-nest/src/modules/BankRules/types.ts b/packages/server/src/modules/BankRules/types.ts similarity index 100% rename from packages/server-nest/src/modules/BankRules/types.ts rename to packages/server/src/modules/BankRules/types.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/BankAccounts.controller.ts b/packages/server/src/modules/BankingAccounts/BankAccounts.controller.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/BankAccounts.controller.ts rename to packages/server/src/modules/BankingAccounts/BankAccounts.controller.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/BankAccounts.module.ts b/packages/server/src/modules/BankingAccounts/BankAccounts.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/BankAccounts.module.ts rename to packages/server/src/modules/BankingAccounts/BankAccounts.module.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/BankAccountsApplication.service.ts b/packages/server/src/modules/BankingAccounts/BankAccountsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/BankAccountsApplication.service.ts rename to packages/server/src/modules/BankingAccounts/BankAccountsApplication.service.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/commands/DisconnectBankAccount.service.ts b/packages/server/src/modules/BankingAccounts/commands/DisconnectBankAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/commands/DisconnectBankAccount.service.ts rename to packages/server/src/modules/BankingAccounts/commands/DisconnectBankAccount.service.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/commands/PauseBankAccountFeeds.service.ts b/packages/server/src/modules/BankingAccounts/commands/PauseBankAccountFeeds.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/commands/PauseBankAccountFeeds.service.ts rename to packages/server/src/modules/BankingAccounts/commands/PauseBankAccountFeeds.service.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/commands/RefreshBankAccount.service.ts b/packages/server/src/modules/BankingAccounts/commands/RefreshBankAccount.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/commands/RefreshBankAccount.service.ts rename to packages/server/src/modules/BankingAccounts/commands/RefreshBankAccount.service.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/commands/ResumeBankAccountFeeds.service.ts b/packages/server/src/modules/BankingAccounts/commands/ResumeBankAccountFeeds.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/commands/ResumeBankAccountFeeds.service.ts rename to packages/server/src/modules/BankingAccounts/commands/ResumeBankAccountFeeds.service.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/queries/GetBankAccountSummary.ts b/packages/server/src/modules/BankingAccounts/queries/GetBankAccountSummary.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/queries/GetBankAccountSummary.ts rename to packages/server/src/modules/BankingAccounts/queries/GetBankAccountSummary.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/subscribers/DeleteUncategorizedTransactionsOnAccountDeleting.ts b/packages/server/src/modules/BankingAccounts/subscribers/DeleteUncategorizedTransactionsOnAccountDeleting.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/subscribers/DeleteUncategorizedTransactionsOnAccountDeleting.ts rename to packages/server/src/modules/BankingAccounts/subscribers/DeleteUncategorizedTransactionsOnAccountDeleting.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/subscribers/DisconnectPlaidItemOnAccountDeleted.ts b/packages/server/src/modules/BankingAccounts/subscribers/DisconnectPlaidItemOnAccountDeleted.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/subscribers/DisconnectPlaidItemOnAccountDeleted.ts rename to packages/server/src/modules/BankingAccounts/subscribers/DisconnectPlaidItemOnAccountDeleted.ts diff --git a/packages/server-nest/src/modules/BankingAccounts/types/BankAccounts.types.ts b/packages/server/src/modules/BankingAccounts/types/BankAccounts.types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingAccounts/types/BankAccounts.types.ts rename to packages/server/src/modules/BankingAccounts/types/BankAccounts.types.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/BankingCategorize.module.ts b/packages/server/src/modules/BankingCategorize/BankingCategorize.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/BankingCategorize.module.ts rename to packages/server/src/modules/BankingCategorize/BankingCategorize.module.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/CategorizeCashflowTransaction.ts b/packages/server/src/modules/BankingCategorize/commands/CategorizeCashflowTransaction.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/CategorizeCashflowTransaction.ts rename to packages/server/src/modules/BankingCategorize/commands/CategorizeCashflowTransaction.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/CategorizeTransactionAsExpense.ts b/packages/server/src/modules/BankingCategorize/commands/CategorizeTransactionAsExpense.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/CategorizeTransactionAsExpense.ts rename to packages/server/src/modules/BankingCategorize/commands/CategorizeTransactionAsExpense.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/CreateUncategorizedTransaction.service.ts b/packages/server/src/modules/BankingCategorize/commands/CreateUncategorizedTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/CreateUncategorizedTransaction.service.ts rename to packages/server/src/modules/BankingCategorize/commands/CreateUncategorizedTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/UncategorizeCashflowTransaction.service.ts b/packages/server/src/modules/BankingCategorize/commands/UncategorizeCashflowTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/UncategorizeCashflowTransaction.service.ts rename to packages/server/src/modules/BankingCategorize/commands/UncategorizeCashflowTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/UncategorizeCashflowTransactionsBulk.service.ts b/packages/server/src/modules/BankingCategorize/commands/UncategorizeCashflowTransactionsBulk.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/UncategorizeCashflowTransactionsBulk.service.ts rename to packages/server/src/modules/BankingCategorize/commands/UncategorizeCashflowTransactionsBulk.service.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/UncategorizedTransaction.transformer.ts b/packages/server/src/modules/BankingCategorize/commands/UncategorizedTransaction.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/UncategorizedTransaction.transformer.ts rename to packages/server/src/modules/BankingCategorize/commands/UncategorizedTransaction.transformer.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/commands/UncategorizedTransactionsImportable.ts b/packages/server/src/modules/BankingCategorize/commands/UncategorizedTransactionsImportable.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/commands/UncategorizedTransactionsImportable.ts rename to packages/server/src/modules/BankingCategorize/commands/UncategorizedTransactionsImportable.ts diff --git a/packages/server-nest/src/modules/BankingCategorize/types/BankingCategorize.types.ts b/packages/server/src/modules/BankingCategorize/types/BankingCategorize.types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingCategorize/types/BankingCategorize.types.ts rename to packages/server/src/modules/BankingCategorize/types/BankingCategorize.types.ts diff --git a/packages/server-nest/src/modules/BankingMatching/BankingMatching.controller.ts b/packages/server/src/modules/BankingMatching/BankingMatching.controller.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/BankingMatching.controller.ts rename to packages/server/src/modules/BankingMatching/BankingMatching.controller.ts diff --git a/packages/server-nest/src/modules/BankingMatching/BankingMatching.module.ts b/packages/server/src/modules/BankingMatching/BankingMatching.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/BankingMatching.module.ts rename to packages/server/src/modules/BankingMatching/BankingMatching.module.ts diff --git a/packages/server-nest/src/modules/BankingMatching/BankingMatchingApplication.ts b/packages/server/src/modules/BankingMatching/BankingMatchingApplication.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/BankingMatchingApplication.ts rename to packages/server/src/modules/BankingMatching/BankingMatchingApplication.ts diff --git a/packages/server-nest/src/modules/BankingMatching/_utils.ts b/packages/server/src/modules/BankingMatching/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/_utils.ts rename to packages/server/src/modules/BankingMatching/_utils.ts diff --git a/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactions.ts b/packages/server/src/modules/BankingMatching/commands/MatchTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/commands/MatchTransactions.ts rename to packages/server/src/modules/BankingMatching/commands/MatchTransactions.ts diff --git a/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactionsTypes.ts b/packages/server/src/modules/BankingMatching/commands/MatchTransactionsTypes.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/commands/MatchTransactionsTypes.ts rename to packages/server/src/modules/BankingMatching/commands/MatchTransactionsTypes.ts diff --git a/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactionsTypesRegistry.ts b/packages/server/src/modules/BankingMatching/commands/MatchTransactionsTypesRegistry.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/commands/MatchTransactionsTypesRegistry.ts rename to packages/server/src/modules/BankingMatching/commands/MatchTransactionsTypesRegistry.ts diff --git a/packages/server-nest/src/modules/BankingMatching/commands/UnmatchMatchedTransaction.service.ts b/packages/server/src/modules/BankingMatching/commands/UnmatchMatchedTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/commands/UnmatchMatchedTransaction.service.ts rename to packages/server/src/modules/BankingMatching/commands/UnmatchMatchedTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingMatching/commands/ValidateTransactionsMatched.service.ts b/packages/server/src/modules/BankingMatching/commands/ValidateTransactionsMatched.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/commands/ValidateTransactionsMatched.service.ts rename to packages/server/src/modules/BankingMatching/commands/ValidateTransactionsMatched.service.ts diff --git a/packages/server-nest/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts b/packages/server/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts rename to packages/server/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts diff --git a/packages/server-nest/src/modules/BankingMatching/events/DecrementUncategorizedTransactionsOnMatch.ts b/packages/server/src/modules/BankingMatching/events/DecrementUncategorizedTransactionsOnMatch.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/events/DecrementUncategorizedTransactionsOnMatch.ts rename to packages/server/src/modules/BankingMatching/events/DecrementUncategorizedTransactionsOnMatch.ts diff --git a/packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnCashflowDelete.ts b/packages/server/src/modules/BankingMatching/events/ValidateMatchingOnCashflowDelete.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnCashflowDelete.ts rename to packages/server/src/modules/BankingMatching/events/ValidateMatchingOnCashflowDelete.ts diff --git a/packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnExpenseDelete.ts b/packages/server/src/modules/BankingMatching/events/ValidateMatchingOnExpenseDelete.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnExpenseDelete.ts rename to packages/server/src/modules/BankingMatching/events/ValidateMatchingOnExpenseDelete.ts diff --git a/packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnManualJournalDelete.ts b/packages/server/src/modules/BankingMatching/events/ValidateMatchingOnManualJournalDelete.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnManualJournalDelete.ts rename to packages/server/src/modules/BankingMatching/events/ValidateMatchingOnManualJournalDelete.ts diff --git a/packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnPaymentMadeDelete.ts b/packages/server/src/modules/BankingMatching/events/ValidateMatchingOnPaymentMadeDelete.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnPaymentMadeDelete.ts rename to packages/server/src/modules/BankingMatching/events/ValidateMatchingOnPaymentMadeDelete.ts diff --git a/packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnPaymentReceivedDelete.ts b/packages/server/src/modules/BankingMatching/events/ValidateMatchingOnPaymentReceivedDelete.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/events/ValidateMatchingOnPaymentReceivedDelete.ts rename to packages/server/src/modules/BankingMatching/events/ValidateMatchingOnPaymentReceivedDelete.ts diff --git a/packages/server-nest/src/modules/BankingMatching/models/MatchedBankTransaction.ts b/packages/server/src/modules/BankingMatching/models/MatchedBankTransaction.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/models/MatchedBankTransaction.ts rename to packages/server/src/modules/BankingMatching/models/MatchedBankTransaction.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionBillsTransformer.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionBillsTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionBillsTransformer.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionBillsTransformer.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionCashflowTransformer.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionCashflowTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionCashflowTransformer.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionCashflowTransformer.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionExpensesTransformer.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionExpensesTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionExpensesTransformer.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionExpensesTransformer.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionInvoicesTransformer.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionInvoicesTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionInvoicesTransformer.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionInvoicesTransformer.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionManualJournalsTransformer.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionManualJournalsTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionManualJournalsTransformer.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionManualJournalsTransformer.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactions.service.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactions.service.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactions.service.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByCashflow.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByCashflow.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByCashflow.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByCashflow.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByExpenses.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByExpenses.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByExpenses.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByExpenses.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByInvoices.service.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByInvoices.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByInvoices.service.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByInvoices.service.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByManualJournals.service.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByManualJournals.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByManualJournals.service.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByManualJournals.service.ts diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByType.ts b/packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByType.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByType.ts rename to packages/server/src/modules/BankingMatching/queries/GetMatchedTransactionsByType.ts diff --git a/packages/server-nest/src/modules/BankingMatching/types.ts b/packages/server/src/modules/BankingMatching/types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingMatching/types.ts rename to packages/server/src/modules/BankingMatching/types.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/BankingPlaid.module.ts b/packages/server/src/modules/BankingPlaid/BankingPlaid.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/BankingPlaid.module.ts rename to packages/server/src/modules/BankingPlaid/BankingPlaid.module.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/PlaidApplication.ts b/packages/server/src/modules/BankingPlaid/PlaidApplication.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/PlaidApplication.ts rename to packages/server/src/modules/BankingPlaid/PlaidApplication.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/PlaidWebhookTenantBootMiddleware.ts b/packages/server/src/modules/BankingPlaid/PlaidWebhookTenantBootMiddleware.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/PlaidWebhookTenantBootMiddleware.ts rename to packages/server/src/modules/BankingPlaid/PlaidWebhookTenantBootMiddleware.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/command/PlaidItem.ts b/packages/server/src/modules/BankingPlaid/command/PlaidItem.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/command/PlaidItem.ts rename to packages/server/src/modules/BankingPlaid/command/PlaidItem.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/command/PlaidSyncDB.ts b/packages/server/src/modules/BankingPlaid/command/PlaidSyncDB.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/command/PlaidSyncDB.ts rename to packages/server/src/modules/BankingPlaid/command/PlaidSyncDB.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/command/PlaidUpdateTransactions.ts b/packages/server/src/modules/BankingPlaid/command/PlaidUpdateTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/command/PlaidUpdateTransactions.ts rename to packages/server/src/modules/BankingPlaid/command/PlaidUpdateTransactions.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/command/PlaidWebhooks.ts b/packages/server/src/modules/BankingPlaid/command/PlaidWebhooks.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/command/PlaidWebhooks.ts rename to packages/server/src/modules/BankingPlaid/command/PlaidWebhooks.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/jobs/PlaidFetchTransactionsJob.ts b/packages/server/src/modules/BankingPlaid/jobs/PlaidFetchTransactionsJob.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/jobs/PlaidFetchTransactionsJob.ts rename to packages/server/src/modules/BankingPlaid/jobs/PlaidFetchTransactionsJob.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/models/PlaidItem.ts b/packages/server/src/modules/BankingPlaid/models/PlaidItem.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/models/PlaidItem.ts rename to packages/server/src/modules/BankingPlaid/models/PlaidItem.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/models/SystemPlaidItem.ts b/packages/server/src/modules/BankingPlaid/models/SystemPlaidItem.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/models/SystemPlaidItem.ts rename to packages/server/src/modules/BankingPlaid/models/SystemPlaidItem.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/queries/GetPlaidLinkToken.service.ts b/packages/server/src/modules/BankingPlaid/queries/GetPlaidLinkToken.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/queries/GetPlaidLinkToken.service.ts rename to packages/server/src/modules/BankingPlaid/queries/GetPlaidLinkToken.service.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts b/packages/server/src/modules/BankingPlaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts rename to packages/server/src/modules/BankingPlaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/subscribers/RecognizeSyncedBankTransactions.subscriber.ts b/packages/server/src/modules/BankingPlaid/subscribers/RecognizeSyncedBankTransactions.subscriber.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/subscribers/RecognizeSyncedBankTransactions.subscriber.ts rename to packages/server/src/modules/BankingPlaid/subscribers/RecognizeSyncedBankTransactions.subscriber.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/types/BankingPlaid.types.ts b/packages/server/src/modules/BankingPlaid/types/BankingPlaid.types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/types/BankingPlaid.types.ts rename to packages/server/src/modules/BankingPlaid/types/BankingPlaid.types.ts diff --git a/packages/server-nest/src/modules/BankingPlaid/utils.ts b/packages/server/src/modules/BankingPlaid/utils.ts similarity index 100% rename from packages/server-nest/src/modules/BankingPlaid/utils.ts rename to packages/server/src/modules/BankingPlaid/utils.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts b/packages/server/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/_types.ts b/packages/server/src/modules/BankingTranasctionsRegonize/_types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/_types.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/_types.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/_utils.ts b/packages/server/src/modules/BankingTranasctionsRegonize/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/_utils.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/_utils.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts b/packages/server/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts b/packages/server/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts b/packages/server/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts b/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/jobs/RerecognizeTransactionsJob.ts b/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RerecognizeTransactionsJob.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/jobs/RerecognizeTransactionsJob.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/jobs/RerecognizeTransactionsJob.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/jobs/RevertRecognizedTransactionsJob.ts b/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RevertRecognizedTransactionsJob.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/jobs/RevertRecognizedTransactionsJob.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/jobs/RevertRecognizedTransactionsJob.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/models/RecognizedBankTransaction.ts b/packages/server/src/modules/BankingTranasctionsRegonize/models/RecognizedBankTransaction.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/models/RecognizedBankTransaction.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/models/RecognizedBankTransaction.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransaction.service.ts b/packages/server/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransaction.service.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransactionTransformer.ts b/packages/server/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransactionTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransactionTransformer.ts rename to packages/server/src/modules/BankingTranasctionsRegonize/queries/GetAutofillCategorizeTransactionTransformer.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/BankingTransactions.controller.ts b/packages/server/src/modules/BankingTransactions/BankingTransactions.controller.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/BankingTransactions.controller.ts rename to packages/server/src/modules/BankingTransactions/BankingTransactions.controller.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/BankingTransactions.module.ts b/packages/server/src/modules/BankingTransactions/BankingTransactions.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/BankingTransactions.module.ts rename to packages/server/src/modules/BankingTransactions/BankingTransactions.module.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts b/packages/server/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts rename to packages/server/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/BankTransactionAutoIncrement.service.ts b/packages/server/src/modules/BankingTransactions/commands/BankTransactionAutoIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/BankTransactionAutoIncrement.service.ts rename to packages/server/src/modules/BankingTransactions/commands/BankTransactionAutoIncrement.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/BankTransactionGL.ts b/packages/server/src/modules/BankingTransactions/commands/BankTransactionGL.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/BankTransactionGL.ts rename to packages/server/src/modules/BankingTransactions/commands/BankTransactionGL.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/BankTransactionGLEntries.ts b/packages/server/src/modules/BankingTransactions/commands/BankTransactionGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/BankTransactionGLEntries.ts rename to packages/server/src/modules/BankingTransactions/commands/BankTransactionGLEntries.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/CommandCasflowValidator.service.ts b/packages/server/src/modules/BankingTransactions/commands/CommandCasflowValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/CommandCasflowValidator.service.ts rename to packages/server/src/modules/BankingTransactions/commands/CommandCasflowValidator.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts b/packages/server/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/DeleteCashflowTransaction.service.ts b/packages/server/src/modules/BankingTransactions/commands/DeleteCashflowTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/DeleteCashflowTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/commands/DeleteCashflowTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/RemovePendingUncategorizedTransaction.service.ts b/packages/server/src/modules/BankingTransactions/commands/RemovePendingUncategorizedTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/RemovePendingUncategorizedTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/commands/RemovePendingUncategorizedTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/ValidateDeleteBankAccountTransactions.service.ts b/packages/server/src/modules/BankingTransactions/commands/ValidateDeleteBankAccountTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/commands/ValidateDeleteBankAccountTransactions.service.ts rename to packages/server/src/modules/BankingTransactions/commands/ValidateDeleteBankAccountTransactions.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/constants.ts b/packages/server/src/modules/BankingTransactions/constants.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/constants.ts rename to packages/server/src/modules/BankingTransactions/constants.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts b/packages/server/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts rename to packages/server/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/models/BankAccount.ts b/packages/server/src/modules/BankingTransactions/models/BankAccount.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/models/BankAccount.ts rename to packages/server/src/modules/BankingTransactions/models/BankAccount.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/models/BankTransaction.ts b/packages/server/src/modules/BankingTransactions/models/BankTransaction.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/models/BankTransaction.ts rename to packages/server/src/modules/BankingTransactions/models/BankTransaction.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/models/BankTransactionLine.ts b/packages/server/src/modules/BankingTransactions/models/BankTransactionLine.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/models/BankTransactionLine.ts rename to packages/server/src/modules/BankingTransactions/models/BankTransactionLine.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/models/UncategorizedBankTransaction.ts b/packages/server/src/modules/BankingTransactions/models/UncategorizedBankTransaction.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/models/UncategorizedBankTransaction.ts rename to packages/server/src/modules/BankingTransactions/models/UncategorizedBankTransaction.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/BankAccountTransformer.ts b/packages/server/src/modules/BankingTransactions/queries/BankAccountTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/BankAccountTransformer.ts rename to packages/server/src/modules/BankingTransactions/queries/BankAccountTransformer.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/BankTransactionTransformer.ts b/packages/server/src/modules/BankingTransactions/queries/BankTransactionTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/BankTransactionTransformer.ts rename to packages/server/src/modules/BankingTransactions/queries/BankTransactionTransformer.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/BankTransactionsTransformer.ts b/packages/server/src/modules/BankingTransactions/queries/BankTransactionsTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/BankTransactionsTransformer.ts rename to packages/server/src/modules/BankingTransactions/queries/BankTransactionsTransformer.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetBankAccounts.service.ts b/packages/server/src/modules/BankingTransactions/queries/GetBankAccounts.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetBankAccounts.service.ts rename to packages/server/src/modules/BankingTransactions/queries/GetBankAccounts.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetBankTransaction.service.ts b/packages/server/src/modules/BankingTransactions/queries/GetBankTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetBankTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/queries/GetBankTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetPendingBankAccountTransaction.service.ts b/packages/server/src/modules/BankingTransactions/queries/GetPendingBankAccountTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetPendingBankAccountTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/queries/GetPendingBankAccountTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetPendingBankAccountTransactionTransformer.ts b/packages/server/src/modules/BankingTransactions/queries/GetPendingBankAccountTransactionTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetPendingBankAccountTransactionTransformer.ts rename to packages/server/src/modules/BankingTransactions/queries/GetPendingBankAccountTransactionTransformer.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetRecognizedTransaction.service.ts b/packages/server/src/modules/BankingTransactions/queries/GetRecognizedTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetRecognizedTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/queries/GetRecognizedTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetRecognizedTransactionTransformer.ts b/packages/server/src/modules/BankingTransactions/queries/GetRecognizedTransactionTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetRecognizedTransactionTransformer.ts rename to packages/server/src/modules/BankingTransactions/queries/GetRecognizedTransactionTransformer.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetRecongizedTransactions.ts b/packages/server/src/modules/BankingTransactions/queries/GetRecongizedTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetRecongizedTransactions.ts rename to packages/server/src/modules/BankingTransactions/queries/GetRecongizedTransactions.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetUncategorizedBankTransaction.service.ts b/packages/server/src/modules/BankingTransactions/queries/GetUncategorizedBankTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetUncategorizedBankTransaction.service.ts rename to packages/server/src/modules/BankingTransactions/queries/GetUncategorizedBankTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/queries/GetUncategorizedTransactions.ts b/packages/server/src/modules/BankingTransactions/queries/GetUncategorizedTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/queries/GetUncategorizedTransactions.ts rename to packages/server/src/modules/BankingTransactions/queries/GetUncategorizedTransactions.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/subscribers/CashflowTransactionSubscriber.ts b/packages/server/src/modules/BankingTransactions/subscribers/CashflowTransactionSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/subscribers/CashflowTransactionSubscriber.ts rename to packages/server/src/modules/BankingTransactions/subscribers/CashflowTransactionSubscriber.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/subscribers/CashflowWithAccountSubscriber.ts b/packages/server/src/modules/BankingTransactions/subscribers/CashflowWithAccountSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/subscribers/CashflowWithAccountSubscriber.ts rename to packages/server/src/modules/BankingTransactions/subscribers/CashflowWithAccountSubscriber.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/subscribers/DecrementUncategorizedTransactionOnCategorize.ts b/packages/server/src/modules/BankingTransactions/subscribers/DecrementUncategorizedTransactionOnCategorize.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/subscribers/DecrementUncategorizedTransactionOnCategorize.ts rename to packages/server/src/modules/BankingTransactions/subscribers/DecrementUncategorizedTransactionOnCategorize.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/subscribers/DeleteCashflowTransactionOnUncategorize.ts b/packages/server/src/modules/BankingTransactions/subscribers/DeleteCashflowTransactionOnUncategorize.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/subscribers/DeleteCashflowTransactionOnUncategorize.ts rename to packages/server/src/modules/BankingTransactions/subscribers/DeleteCashflowTransactionOnUncategorize.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/subscribers/PreventDeleteTransactionsOnDelete.ts b/packages/server/src/modules/BankingTransactions/subscribers/PreventDeleteTransactionsOnDelete.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/subscribers/PreventDeleteTransactionsOnDelete.ts rename to packages/server/src/modules/BankingTransactions/subscribers/PreventDeleteTransactionsOnDelete.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/types/BankingTransactions.types.ts b/packages/server/src/modules/BankingTransactions/types/BankingTransactions.types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/types/BankingTransactions.types.ts rename to packages/server/src/modules/BankingTransactions/types/BankingTransactions.types.ts diff --git a/packages/server-nest/src/modules/BankingTransactions/utils.ts b/packages/server/src/modules/BankingTransactions/utils.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactions/utils.ts rename to packages/server/src/modules/BankingTransactions/utils.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.controller.ts b/packages/server/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.controller.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.controller.ts rename to packages/server/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.controller.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.module.ts b/packages/server/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.module.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.module.ts rename to packages/server/src/modules/BankingTransactionsExclude/BankingTransactionsExclude.module.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/ExcludeBankTransactionsApplication.ts b/packages/server/src/modules/BankingTransactionsExclude/ExcludeBankTransactionsApplication.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/ExcludeBankTransactionsApplication.ts rename to packages/server/src/modules/BankingTransactionsExclude/ExcludeBankTransactionsApplication.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransaction.service.ts b/packages/server/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransaction.service.ts rename to packages/server/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransactions.service.ts b/packages/server/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransactions.service.ts rename to packages/server/src/modules/BankingTransactionsExclude/commands/ExcludeBankTransactions.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts b/packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts rename to packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransactions.service.ts b/packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransactions.service.ts rename to packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransactions.service.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/commands/utils.ts b/packages/server/src/modules/BankingTransactionsExclude/commands/utils.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/commands/utils.ts rename to packages/server/src/modules/BankingTransactionsExclude/commands/utils.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/queries/GetExcludedBankTransactions.ts b/packages/server/src/modules/BankingTransactionsExclude/queries/GetExcludedBankTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/queries/GetExcludedBankTransactions.ts rename to packages/server/src/modules/BankingTransactionsExclude/queries/GetExcludedBankTransactions.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts b/packages/server/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts rename to packages/server/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/types/BankTransactionsExclude.types.ts b/packages/server/src/modules/BankingTransactionsExclude/types/BankTransactionsExclude.types.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/types/BankTransactionsExclude.types.ts rename to packages/server/src/modules/BankingTransactionsExclude/types/BankTransactionsExclude.types.ts diff --git a/packages/server-nest/src/modules/BankingTransactionsExclude/utils.ts b/packages/server/src/modules/BankingTransactionsExclude/utils.ts similarity index 100% rename from packages/server-nest/src/modules/BankingTransactionsExclude/utils.ts rename to packages/server/src/modules/BankingTransactionsExclude/utils.ts diff --git a/packages/server-nest/src/modules/BillLandedCosts/BillLandedCosts.module.ts b/packages/server/src/modules/BillLandedCosts/BillLandedCosts.module.ts similarity index 100% rename from packages/server-nest/src/modules/BillLandedCosts/BillLandedCosts.module.ts rename to packages/server/src/modules/BillLandedCosts/BillLandedCosts.module.ts diff --git a/packages/server-nest/src/modules/BillLandedCosts/TransactionLandedCostEntries.service.ts b/packages/server/src/modules/BillLandedCosts/TransactionLandedCostEntries.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillLandedCosts/TransactionLandedCostEntries.service.ts rename to packages/server/src/modules/BillLandedCosts/TransactionLandedCostEntries.service.ts diff --git a/packages/server-nest/src/modules/BillLandedCosts/models/BillLandedCost.ts b/packages/server/src/modules/BillLandedCosts/models/BillLandedCost.ts similarity index 100% rename from packages/server-nest/src/modules/BillLandedCosts/models/BillLandedCost.ts rename to packages/server/src/modules/BillLandedCosts/models/BillLandedCost.ts diff --git a/packages/server-nest/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts b/packages/server/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts similarity index 100% rename from packages/server-nest/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts rename to packages/server/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts diff --git a/packages/server-nest/src/modules/BillLandedCosts/types/BillLandedCosts.types.ts b/packages/server/src/modules/BillLandedCosts/types/BillLandedCosts.types.ts similarity index 100% rename from packages/server-nest/src/modules/BillLandedCosts/types/BillLandedCosts.types.ts rename to packages/server/src/modules/BillLandedCosts/types/BillLandedCosts.types.ts diff --git a/packages/server-nest/src/modules/BillPayments/BillPayments.controller.ts b/packages/server/src/modules/BillPayments/BillPayments.controller.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/BillPayments.controller.ts rename to packages/server/src/modules/BillPayments/BillPayments.controller.ts diff --git a/packages/server-nest/src/modules/BillPayments/BillPayments.module.ts b/packages/server/src/modules/BillPayments/BillPayments.module.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/BillPayments.module.ts rename to packages/server/src/modules/BillPayments/BillPayments.module.ts diff --git a/packages/server-nest/src/modules/BillPayments/BillPaymentsApplication.service.ts b/packages/server/src/modules/BillPayments/BillPaymentsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/BillPaymentsApplication.service.ts rename to packages/server/src/modules/BillPayments/BillPaymentsApplication.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/GetBillPayments.ts b/packages/server/src/modules/BillPayments/GetBillPayments.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/GetBillPayments.ts rename to packages/server/src/modules/BillPayments/GetBillPayments.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentExportable.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentExportable.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentExportable.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentExportable.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentGL.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentGL.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentGL.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentGL.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentGLEntries.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentGLEntries.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentGLEntries.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentValidators.service.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentValidators.service.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentValidators.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentsImportable.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentsImportable.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentsImportable.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentsImportable.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentsPages.service.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentsPages.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/BillPaymentsPages.service.ts rename to packages/server/src/modules/BillPayments/commands/BillPaymentsPages.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts b/packages/server/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts rename to packages/server/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/CreateBillPayment.service.ts b/packages/server/src/modules/BillPayments/commands/CreateBillPayment.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/CreateBillPayment.service.ts rename to packages/server/src/modules/BillPayments/commands/CreateBillPayment.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/DeleteBillPayment.service.ts b/packages/server/src/modules/BillPayments/commands/DeleteBillPayment.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/DeleteBillPayment.service.ts rename to packages/server/src/modules/BillPayments/commands/DeleteBillPayment.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/commands/EditBillPayment.service.ts b/packages/server/src/modules/BillPayments/commands/EditBillPayment.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/commands/EditBillPayment.service.ts rename to packages/server/src/modules/BillPayments/commands/EditBillPayment.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/constants.ts b/packages/server/src/modules/BillPayments/constants.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/constants.ts rename to packages/server/src/modules/BillPayments/constants.ts diff --git a/packages/server-nest/src/modules/BillPayments/dtos/BillPayment.dto.ts b/packages/server/src/modules/BillPayments/dtos/BillPayment.dto.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/dtos/BillPayment.dto.ts rename to packages/server/src/modules/BillPayments/dtos/BillPayment.dto.ts diff --git a/packages/server-nest/src/modules/BillPayments/models/BillPayment.ts b/packages/server/src/modules/BillPayments/models/BillPayment.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/models/BillPayment.ts rename to packages/server/src/modules/BillPayments/models/BillPayment.ts diff --git a/packages/server-nest/src/modules/BillPayments/models/BillPaymentEntry.ts b/packages/server/src/modules/BillPayments/models/BillPaymentEntry.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/models/BillPaymentEntry.ts rename to packages/server/src/modules/BillPayments/models/BillPaymentEntry.ts diff --git a/packages/server-nest/src/modules/BillPayments/queries/BillPaymentEntry.transformer.ts b/packages/server/src/modules/BillPayments/queries/BillPaymentEntry.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/queries/BillPaymentEntry.transformer.ts rename to packages/server/src/modules/BillPayments/queries/BillPaymentEntry.transformer.ts diff --git a/packages/server-nest/src/modules/BillPayments/queries/BillPaymentTransactionTransformer.ts b/packages/server/src/modules/BillPayments/queries/BillPaymentTransactionTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/queries/BillPaymentTransactionTransformer.ts rename to packages/server/src/modules/BillPayments/queries/BillPaymentTransactionTransformer.ts diff --git a/packages/server-nest/src/modules/BillPayments/queries/BillPaymentTransformer.ts b/packages/server/src/modules/BillPayments/queries/BillPaymentTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/queries/BillPaymentTransformer.ts rename to packages/server/src/modules/BillPayments/queries/BillPaymentTransformer.ts diff --git a/packages/server-nest/src/modules/BillPayments/queries/GetBillPayment.service.ts b/packages/server/src/modules/BillPayments/queries/GetBillPayment.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/queries/GetBillPayment.service.ts rename to packages/server/src/modules/BillPayments/queries/GetBillPayment.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/queries/GetPaymentBills.service.ts b/packages/server/src/modules/BillPayments/queries/GetPaymentBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/queries/GetPaymentBills.service.ts rename to packages/server/src/modules/BillPayments/queries/GetPaymentBills.service.ts diff --git a/packages/server-nest/src/modules/BillPayments/subscribers/BillPaymentGLEntriesSubscriber.ts b/packages/server/src/modules/BillPayments/subscribers/BillPaymentGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/subscribers/BillPaymentGLEntriesSubscriber.ts rename to packages/server/src/modules/BillPayments/subscribers/BillPaymentGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/BillPayments/types/BillPayments.types.ts b/packages/server/src/modules/BillPayments/types/BillPayments.types.ts similarity index 100% rename from packages/server-nest/src/modules/BillPayments/types/BillPayments.types.ts rename to packages/server/src/modules/BillPayments/types/BillPayments.types.ts diff --git a/packages/server-nest/src/modules/Bills/Bills.application.ts b/packages/server/src/modules/Bills/Bills.application.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/Bills.application.ts rename to packages/server/src/modules/Bills/Bills.application.ts diff --git a/packages/server-nest/src/modules/Bills/Bills.constants.ts b/packages/server/src/modules/Bills/Bills.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/Bills.constants.ts rename to packages/server/src/modules/Bills/Bills.constants.ts diff --git a/packages/server-nest/src/modules/Bills/Bills.controller.ts b/packages/server/src/modules/Bills/Bills.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/Bills.controller.ts rename to packages/server/src/modules/Bills/Bills.controller.ts diff --git a/packages/server-nest/src/modules/Bills/Bills.module.ts b/packages/server/src/modules/Bills/Bills.module.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/Bills.module.ts rename to packages/server/src/modules/Bills/Bills.module.ts diff --git a/packages/server-nest/src/modules/Bills/Bills.types.ts b/packages/server/src/modules/Bills/Bills.types.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/Bills.types.ts rename to packages/server/src/modules/Bills/Bills.types.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillDTOTransformer.service.ts b/packages/server/src/modules/Bills/commands/BillDTOTransformer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillDTOTransformer.service.ts rename to packages/server/src/modules/Bills/commands/BillDTOTransformer.service.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillInventoryTransactions.ts b/packages/server/src/modules/Bills/commands/BillInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillInventoryTransactions.ts rename to packages/server/src/modules/Bills/commands/BillInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillPaymentsGLEntriesRewrite.ts b/packages/server/src/modules/Bills/commands/BillPaymentsGLEntriesRewrite.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillPaymentsGLEntriesRewrite.ts rename to packages/server/src/modules/Bills/commands/BillPaymentsGLEntriesRewrite.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillPaymentsGLEntriesRewriteSubscriber.ts b/packages/server/src/modules/Bills/commands/BillPaymentsGLEntriesRewriteSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillPaymentsGLEntriesRewriteSubscriber.ts rename to packages/server/src/modules/Bills/commands/BillPaymentsGLEntriesRewriteSubscriber.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillsExportable.ts b/packages/server/src/modules/Bills/commands/BillsExportable.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillsExportable.ts rename to packages/server/src/modules/Bills/commands/BillsExportable.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillsGL.ts b/packages/server/src/modules/Bills/commands/BillsGL.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillsGL.ts rename to packages/server/src/modules/Bills/commands/BillsGL.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillsGLEntries.ts b/packages/server/src/modules/Bills/commands/BillsGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillsGLEntries.ts rename to packages/server/src/modules/Bills/commands/BillsGLEntries.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillsImportable.ts b/packages/server/src/modules/Bills/commands/BillsImportable.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillsImportable.ts rename to packages/server/src/modules/Bills/commands/BillsImportable.ts diff --git a/packages/server-nest/src/modules/Bills/commands/BillsValidators.service.ts b/packages/server/src/modules/Bills/commands/BillsValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/BillsValidators.service.ts rename to packages/server/src/modules/Bills/commands/BillsValidators.service.ts diff --git a/packages/server-nest/src/modules/Bills/commands/CreateBill.service.ts b/packages/server/src/modules/Bills/commands/CreateBill.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/CreateBill.service.ts rename to packages/server/src/modules/Bills/commands/CreateBill.service.ts diff --git a/packages/server-nest/src/modules/Bills/commands/DeleteBill.service.ts b/packages/server/src/modules/Bills/commands/DeleteBill.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/DeleteBill.service.ts rename to packages/server/src/modules/Bills/commands/DeleteBill.service.ts diff --git a/packages/server-nest/src/modules/Bills/commands/EditBill.service.ts b/packages/server/src/modules/Bills/commands/EditBill.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/EditBill.service.ts rename to packages/server/src/modules/Bills/commands/EditBill.service.ts diff --git a/packages/server-nest/src/modules/Bills/commands/OpenBill.service.ts b/packages/server/src/modules/Bills/commands/OpenBill.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/commands/OpenBill.service.ts rename to packages/server/src/modules/Bills/commands/OpenBill.service.ts diff --git a/packages/server-nest/src/modules/Bills/dtos/Bill.dto.ts b/packages/server/src/modules/Bills/dtos/Bill.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/dtos/Bill.dto.ts rename to packages/server/src/modules/Bills/dtos/Bill.dto.ts diff --git a/packages/server-nest/src/modules/Bills/models/Bill.ts b/packages/server/src/modules/Bills/models/Bill.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/models/Bill.ts rename to packages/server/src/modules/Bills/models/Bill.ts diff --git a/packages/server-nest/src/modules/Bills/queries/Bill.transformer.ts b/packages/server/src/modules/Bills/queries/Bill.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/queries/Bill.transformer.ts rename to packages/server/src/modules/Bills/queries/Bill.transformer.ts diff --git a/packages/server-nest/src/modules/Bills/queries/GetBill.ts b/packages/server/src/modules/Bills/queries/GetBill.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/queries/GetBill.ts rename to packages/server/src/modules/Bills/queries/GetBill.ts diff --git a/packages/server-nest/src/modules/Bills/queries/GetBillPayments.ts b/packages/server/src/modules/Bills/queries/GetBillPayments.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/queries/GetBillPayments.ts rename to packages/server/src/modules/Bills/queries/GetBillPayments.ts diff --git a/packages/server-nest/src/modules/Bills/queries/GetBills.service.ts b/packages/server/src/modules/Bills/queries/GetBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/queries/GetBills.service.ts rename to packages/server/src/modules/Bills/queries/GetBills.service.ts diff --git a/packages/server-nest/src/modules/Bills/queries/GetDueBills.service.ts b/packages/server/src/modules/Bills/queries/GetDueBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/queries/GetDueBills.service.ts rename to packages/server/src/modules/Bills/queries/GetDueBills.service.ts diff --git a/packages/server-nest/src/modules/Bills/subscribers/BillGLEntriesSubscriber.ts b/packages/server/src/modules/Bills/subscribers/BillGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/subscribers/BillGLEntriesSubscriber.ts rename to packages/server/src/modules/Bills/subscribers/BillGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/Bills/subscribers/BillWriteInventoryTransactionsSubscriber.ts b/packages/server/src/modules/Bills/subscribers/BillWriteInventoryTransactionsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Bills/subscribers/BillWriteInventoryTransactionsSubscriber.ts rename to packages/server/src/modules/Bills/subscribers/BillWriteInventoryTransactionsSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/BranchIntegrationErrorsMiddleware.ts b/packages/server/src/modules/Branches/BranchIntegrationErrorsMiddleware.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/BranchIntegrationErrorsMiddleware.ts rename to packages/server/src/modules/Branches/BranchIntegrationErrorsMiddleware.ts diff --git a/packages/server-nest/src/modules/Branches/Branches.controller.ts b/packages/server/src/modules/Branches/Branches.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/Branches.controller.ts rename to packages/server/src/modules/Branches/Branches.controller.ts diff --git a/packages/server-nest/src/modules/Branches/Branches.module.ts b/packages/server/src/modules/Branches/Branches.module.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/Branches.module.ts rename to packages/server/src/modules/Branches/Branches.module.ts diff --git a/packages/server-nest/src/modules/Branches/Branches.types.ts b/packages/server/src/modules/Branches/Branches.types.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/Branches.types.ts rename to packages/server/src/modules/Branches/Branches.types.ts diff --git a/packages/server-nest/src/modules/Branches/BranchesApplication.service.ts b/packages/server/src/modules/Branches/BranchesApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/BranchesApplication.service.ts rename to packages/server/src/modules/Branches/BranchesApplication.service.ts diff --git a/packages/server-nest/src/modules/Branches/BranchesSettings.ts b/packages/server/src/modules/Branches/BranchesSettings.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/BranchesSettings.ts rename to packages/server/src/modules/Branches/BranchesSettings.ts diff --git a/packages/server-nest/src/modules/Branches/CRUDBranch.ts b/packages/server/src/modules/Branches/CRUDBranch.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/CRUDBranch.ts rename to packages/server/src/modules/Branches/CRUDBranch.ts diff --git a/packages/server-nest/src/modules/Branches/EventsProvider.ts b/packages/server/src/modules/Branches/EventsProvider.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/EventsProvider.ts rename to packages/server/src/modules/Branches/EventsProvider.ts diff --git a/packages/server-nest/src/modules/Branches/commands/ActivateBranchesFeature.service.ts b/packages/server/src/modules/Branches/commands/ActivateBranchesFeature.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/commands/ActivateBranchesFeature.service.ts rename to packages/server/src/modules/Branches/commands/ActivateBranchesFeature.service.ts diff --git a/packages/server-nest/src/modules/Branches/commands/BranchCommandValidator.service.ts b/packages/server/src/modules/Branches/commands/BranchCommandValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/commands/BranchCommandValidator.service.ts rename to packages/server/src/modules/Branches/commands/BranchCommandValidator.service.ts diff --git a/packages/server-nest/src/modules/Branches/commands/CreateBranch.service.ts b/packages/server/src/modules/Branches/commands/CreateBranch.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/commands/CreateBranch.service.ts rename to packages/server/src/modules/Branches/commands/CreateBranch.service.ts diff --git a/packages/server-nest/src/modules/Branches/commands/DeleteBranch.service.ts b/packages/server/src/modules/Branches/commands/DeleteBranch.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/commands/DeleteBranch.service.ts rename to packages/server/src/modules/Branches/commands/DeleteBranch.service.ts diff --git a/packages/server-nest/src/modules/Branches/commands/EditBranch.service.ts b/packages/server/src/modules/Branches/commands/EditBranch.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/commands/EditBranch.service.ts rename to packages/server/src/modules/Branches/commands/EditBranch.service.ts diff --git a/packages/server-nest/src/modules/Branches/commands/MarkBranchAsPrimary.service.ts b/packages/server/src/modules/Branches/commands/MarkBranchAsPrimary.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/commands/MarkBranchAsPrimary.service.ts rename to packages/server/src/modules/Branches/commands/MarkBranchAsPrimary.service.ts diff --git a/packages/server-nest/src/modules/Branches/constants.ts b/packages/server/src/modules/Branches/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/constants.ts rename to packages/server/src/modules/Branches/constants.ts diff --git a/packages/server-nest/src/modules/Branches/dtos/Branch.dto.ts b/packages/server/src/modules/Branches/dtos/Branch.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/dtos/Branch.dto.ts rename to packages/server/src/modules/Branches/dtos/Branch.dto.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/BranchTransactionDTOTransform.ts b/packages/server/src/modules/Branches/integrations/BranchTransactionDTOTransform.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/BranchTransactionDTOTransform.ts rename to packages/server/src/modules/Branches/integrations/BranchTransactionDTOTransform.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Cashflow/CashflowActivateBranches.ts b/packages/server/src/modules/Branches/integrations/Cashflow/CashflowActivateBranches.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Cashflow/CashflowActivateBranches.ts rename to packages/server/src/modules/Branches/integrations/Cashflow/CashflowActivateBranches.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Expense/ExpensesActivateBranches.ts b/packages/server/src/modules/Branches/integrations/Expense/ExpensesActivateBranches.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Expense/ExpensesActivateBranches.ts rename to packages/server/src/modules/Branches/integrations/Expense/ExpensesActivateBranches.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/ManualJournals/ManualJournalBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/ManualJournals/ManualJournalBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/ManualJournals/ManualJournalBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/ManualJournals/ManualJournalBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/ManualJournals/ManualJournalDTOTransformer.service.ts b/packages/server/src/modules/Branches/integrations/ManualJournals/ManualJournalDTOTransformer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/ManualJournals/ManualJournalDTOTransformer.service.ts rename to packages/server/src/modules/Branches/integrations/ManualJournals/ManualJournalDTOTransformer.service.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/ManualJournals/ManualJournalsBranchesValidator.ts b/packages/server/src/modules/Branches/integrations/ManualJournals/ManualJournalsBranchesValidator.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/ManualJournals/ManualJournalsBranchesValidator.ts rename to packages/server/src/modules/Branches/integrations/ManualJournals/ManualJournalsBranchesValidator.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/ManualJournals/constants.ts b/packages/server/src/modules/Branches/integrations/ManualJournals/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/ManualJournals/constants.ts rename to packages/server/src/modules/Branches/integrations/ManualJournals/constants.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Purchases/BillBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Purchases/BillBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Purchases/BillBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Purchases/BillBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Purchases/PaymentMadeBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Purchases/PaymentMadeBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Purchases/PaymentMadeBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Purchases/PaymentMadeBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Purchases/VendorCreditBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Purchases/VendorCreditBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Purchases/VendorCreditBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Purchases/VendorCreditBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Sales/CreditNoteBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Sales/CreditNoteBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Sales/CreditNoteBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Sales/CreditNoteBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Sales/PaymentReceiveBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Sales/PaymentReceiveBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Sales/PaymentReceiveBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Sales/PaymentReceiveBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Sales/SaleEstimatesBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Sales/SaleEstimatesBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Sales/SaleEstimatesBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Sales/SaleEstimatesBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Sales/SaleInvoiceBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Sales/SaleInvoiceBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Sales/SaleInvoiceBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Sales/SaleInvoiceBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/Sales/SaleReceiptBranchesActivate.ts b/packages/server/src/modules/Branches/integrations/Sales/SaleReceiptBranchesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/Sales/SaleReceiptBranchesActivate.ts rename to packages/server/src/modules/Branches/integrations/Sales/SaleReceiptBranchesActivate.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/ValidateBranchExistance.ts b/packages/server/src/modules/Branches/integrations/ValidateBranchExistance.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/ValidateBranchExistance.ts rename to packages/server/src/modules/Branches/integrations/ValidateBranchExistance.ts diff --git a/packages/server-nest/src/modules/Branches/integrations/constants.ts b/packages/server/src/modules/Branches/integrations/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/integrations/constants.ts rename to packages/server/src/modules/Branches/integrations/constants.ts diff --git a/packages/server-nest/src/modules/Branches/models/Branch.model.ts b/packages/server/src/modules/Branches/models/Branch.model.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/models/Branch.model.ts rename to packages/server/src/modules/Branches/models/Branch.model.ts diff --git a/packages/server-nest/src/modules/Branches/queries/GetBranch.service.ts b/packages/server/src/modules/Branches/queries/GetBranch.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/queries/GetBranch.service.ts rename to packages/server/src/modules/Branches/queries/GetBranch.service.ts diff --git a/packages/server-nest/src/modules/Branches/queries/GetBranches.service.ts b/packages/server/src/modules/Branches/queries/GetBranches.service.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/queries/GetBranches.service.ts rename to packages/server/src/modules/Branches/queries/GetBranches.service.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/CashflowBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/CashflowBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/CashflowBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/CashflowBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/ExpenseBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/ExpenseBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/ExpenseBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/ExpenseBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/BillBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/BillBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/BillBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/BillBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/CreditNoteBranchesSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/CreditNoteBranchesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/CreditNoteBranchesSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/CreditNoteBranchesSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/CreditNoteRefundBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/CreditNoteRefundBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/CreditNoteRefundBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/CreditNoteRefundBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/ExpenseBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/ExpenseBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/ExpenseBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/ExpenseBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/InvoiceBranchValidatorSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/InvoiceBranchValidatorSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/InvoiceBranchValidatorSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/InvoiceBranchValidatorSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/ManualJournalBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/ManualJournalBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/ManualJournalBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/ManualJournalBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/PaymentMadeBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/PaymentMadeBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/PaymentMadeBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/PaymentMadeBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/PaymentReceiveBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/PaymentReceiveBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/PaymentReceiveBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/PaymentReceiveBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/SaleReceiptBranchesSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/SaleReceiptBranchesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/SaleReceiptBranchesSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/SaleReceiptBranchesSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/VendorCreditBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/VendorCreditBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/VendorCreditBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/VendorCreditBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/VendorCreditRefundBranchSubscriber.ts b/packages/server/src/modules/Branches/subscribers/Validators/VendorCreditRefundBranchSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Branches/subscribers/Validators/VendorCreditRefundBranchSubscriber.ts rename to packages/server/src/modules/Branches/subscribers/Validators/VendorCreditRefundBranchSubscriber.ts diff --git a/packages/server-nest/src/modules/ChromiumlyTenancy/ChromiumlyHtmlConvert.service.ts b/packages/server/src/modules/ChromiumlyTenancy/ChromiumlyHtmlConvert.service.ts similarity index 100% rename from packages/server-nest/src/modules/ChromiumlyTenancy/ChromiumlyHtmlConvert.service.ts rename to packages/server/src/modules/ChromiumlyTenancy/ChromiumlyHtmlConvert.service.ts diff --git a/packages/server-nest/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.module.ts b/packages/server/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.module.ts similarity index 100% rename from packages/server-nest/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.module.ts rename to packages/server/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.module.ts diff --git a/packages/server-nest/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.service.ts b/packages/server/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.service.ts similarity index 100% rename from packages/server-nest/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.service.ts rename to packages/server/src/modules/ChromiumlyTenancy/ChromiumlyTenancy.service.ts diff --git a/packages/server-nest/src/modules/ChromiumlyTenancy/models/Document.ts b/packages/server/src/modules/ChromiumlyTenancy/models/Document.ts similarity index 100% rename from packages/server-nest/src/modules/ChromiumlyTenancy/models/Document.ts rename to packages/server/src/modules/ChromiumlyTenancy/models/Document.ts diff --git a/packages/server-nest/src/modules/ChromiumlyTenancy/models/DocumentLink.ts b/packages/server/src/modules/ChromiumlyTenancy/models/DocumentLink.ts similarity index 100% rename from packages/server-nest/src/modules/ChromiumlyTenancy/models/DocumentLink.ts rename to packages/server/src/modules/ChromiumlyTenancy/models/DocumentLink.ts diff --git a/packages/server-nest/src/modules/ChromiumlyTenancy/utils.ts b/packages/server/src/modules/ChromiumlyTenancy/utils.ts similarity index 100% rename from packages/server-nest/src/modules/ChromiumlyTenancy/utils.ts rename to packages/server/src/modules/ChromiumlyTenancy/utils.ts diff --git a/packages/server-nest/src/modules/Contacts/Contact.transformer.ts b/packages/server/src/modules/Contacts/Contact.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Contacts/Contact.transformer.ts rename to packages/server/src/modules/Contacts/Contact.transformer.ts diff --git a/packages/server-nest/src/modules/Contacts/models/Contact.ts b/packages/server/src/modules/Contacts/models/Contact.ts similarity index 100% rename from packages/server-nest/src/modules/Contacts/models/Contact.ts rename to packages/server/src/modules/Contacts/models/Contact.ts diff --git a/packages/server-nest/src/modules/Contacts/types/Contacts.types.ts b/packages/server/src/modules/Contacts/types/Contacts.types.ts similarity index 100% rename from packages/server-nest/src/modules/Contacts/types/Contacts.types.ts rename to packages/server/src/modules/Contacts/types/Contacts.types.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts rename to packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts rename to packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts b/packages/server/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts rename to packages/server/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts b/packages/server/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts rename to packages/server/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/commands/DeleteRefundCreditNote.service.ts b/packages/server/src/modules/CreditNoteRefunds/commands/DeleteRefundCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/commands/DeleteRefundCreditNote.service.ts rename to packages/server/src/modules/CreditNoteRefunds/commands/DeleteRefundCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/commands/RefundCreditNote.service.ts b/packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/commands/RefundCreditNote.service.ts rename to packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts b/packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts rename to packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/commands/RefundSyncCreditNoteBalance.ts b/packages/server/src/modules/CreditNoteRefunds/commands/RefundSyncCreditNoteBalance.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/commands/RefundSyncCreditNoteBalance.ts rename to packages/server/src/modules/CreditNoteRefunds/commands/RefundSyncCreditNoteBalance.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts b/packages/server/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts rename to packages/server/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts b/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts rename to packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/queries/GetCreditNoteRefunds.service.ts b/packages/server/src/modules/CreditNoteRefunds/queries/GetCreditNoteRefunds.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/queries/GetCreditNoteRefunds.service.ts rename to packages/server/src/modules/CreditNoteRefunds/queries/GetCreditNoteRefunds.service.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/queries/GetRefundCreditNoteTransaction.service.ts b/packages/server/src/modules/CreditNoteRefunds/queries/GetRefundCreditNoteTransaction.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/queries/GetRefundCreditNoteTransaction.service.ts rename to packages/server/src/modules/CreditNoteRefunds/queries/GetRefundCreditNoteTransaction.service.ts diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts b/packages/server/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts rename to packages/server/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts diff --git a/packages/server-nest/src/modules/CreditNotes/CreditNoteApplication.service.ts b/packages/server/src/modules/CreditNotes/CreditNoteApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/CreditNoteApplication.service.ts rename to packages/server/src/modules/CreditNotes/CreditNoteApplication.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/CreditNotes.controller.ts b/packages/server/src/modules/CreditNotes/CreditNotes.controller.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/CreditNotes.controller.ts rename to packages/server/src/modules/CreditNotes/CreditNotes.controller.ts diff --git a/packages/server-nest/src/modules/CreditNotes/CreditNotes.module.ts b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/CreditNotes.module.ts rename to packages/server/src/modules/CreditNotes/CreditNotes.module.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts b/packages/server/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts rename to packages/server/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreateCreditNote.service.ts b/packages/server/src/modules/CreditNotes/commands/CreateCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreateCreditNote.service.ts rename to packages/server/src/modules/CreditNotes/commands/CreateCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreditNoteAutoIncrement.service.ts b/packages/server/src/modules/CreditNotes/commands/CreditNoteAutoIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreditNoteAutoIncrement.service.ts rename to packages/server/src/modules/CreditNotes/commands/CreditNoteAutoIncrement.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreditNoteGL.ts b/packages/server/src/modules/CreditNotes/commands/CreditNoteGL.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreditNoteGL.ts rename to packages/server/src/modules/CreditNotes/commands/CreditNoteGL.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreditNoteGLEntries.ts b/packages/server/src/modules/CreditNotes/commands/CreditNoteGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreditNoteGLEntries.ts rename to packages/server/src/modules/CreditNotes/commands/CreditNoteGLEntries.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreditNotesExportable.ts b/packages/server/src/modules/CreditNotes/commands/CreditNotesExportable.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreditNotesExportable.ts rename to packages/server/src/modules/CreditNotes/commands/CreditNotesExportable.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreditNotesImportable.ts b/packages/server/src/modules/CreditNotes/commands/CreditNotesImportable.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreditNotesImportable.ts rename to packages/server/src/modules/CreditNotes/commands/CreditNotesImportable.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreditNotesInventoryTransactions.ts b/packages/server/src/modules/CreditNotes/commands/CreditNotesInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/CreditNotesInventoryTransactions.ts rename to packages/server/src/modules/CreditNotes/commands/CreditNotesInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/DeleteCreditNote.service.ts b/packages/server/src/modules/CreditNotes/commands/DeleteCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/DeleteCreditNote.service.ts rename to packages/server/src/modules/CreditNotes/commands/DeleteCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/EditCreditNote.service.ts b/packages/server/src/modules/CreditNotes/commands/EditCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/EditCreditNote.service.ts rename to packages/server/src/modules/CreditNotes/commands/EditCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/commands/OpenCreditNote.service.ts b/packages/server/src/modules/CreditNotes/commands/OpenCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/commands/OpenCreditNote.service.ts rename to packages/server/src/modules/CreditNotes/commands/OpenCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/constants.ts b/packages/server/src/modules/CreditNotes/constants.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/constants.ts rename to packages/server/src/modules/CreditNotes/constants.ts diff --git a/packages/server-nest/src/modules/CreditNotes/dtos/CreditNote.dto.ts b/packages/server/src/modules/CreditNotes/dtos/CreditNote.dto.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/dtos/CreditNote.dto.ts rename to packages/server/src/modules/CreditNotes/dtos/CreditNote.dto.ts diff --git a/packages/server-nest/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts b/packages/server/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts rename to packages/server/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts diff --git a/packages/server-nest/src/modules/CreditNotes/models/CreditNote.ts b/packages/server/src/modules/CreditNotes/models/CreditNote.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/models/CreditNote.ts rename to packages/server/src/modules/CreditNotes/models/CreditNote.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts b/packages/server/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts rename to packages/server/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/CreditNoteTransformer.ts b/packages/server/src/modules/CreditNotes/queries/CreditNoteTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/CreditNoteTransformer.ts rename to packages/server/src/modules/CreditNotes/queries/CreditNoteTransformer.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/GetCreditNote.service.ts b/packages/server/src/modules/CreditNotes/queries/GetCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/GetCreditNote.service.ts rename to packages/server/src/modules/CreditNotes/queries/GetCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/GetCreditNotePdf.serivce.ts b/packages/server/src/modules/CreditNotes/queries/GetCreditNotePdf.serivce.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/GetCreditNotePdf.serivce.ts rename to packages/server/src/modules/CreditNotes/queries/GetCreditNotePdf.serivce.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/GetCreditNoteState.service.ts b/packages/server/src/modules/CreditNotes/queries/GetCreditNoteState.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/GetCreditNoteState.service.ts rename to packages/server/src/modules/CreditNotes/queries/GetCreditNoteState.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/GetCreditNotes.service.ts b/packages/server/src/modules/CreditNotes/queries/GetCreditNotes.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/GetCreditNotes.service.ts rename to packages/server/src/modules/CreditNotes/queries/GetCreditNotes.service.ts diff --git a/packages/server-nest/src/modules/CreditNotes/queries/RefundCreditNoteTransformer.ts b/packages/server/src/modules/CreditNotes/queries/RefundCreditNoteTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/queries/RefundCreditNoteTransformer.ts rename to packages/server/src/modules/CreditNotes/queries/RefundCreditNoteTransformer.ts diff --git a/packages/server-nest/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts rename to packages/server/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotes/subscribers/CreditNoteGLEntriesSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/CreditNoteGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/subscribers/CreditNoteGLEntriesSubscriber.ts rename to packages/server/src/modules/CreditNotes/subscribers/CreditNoteGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotes/subscribers/CreditNoteInventoryTransactionsSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/CreditNoteInventoryTransactionsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/subscribers/CreditNoteInventoryTransactionsSubscriber.ts rename to packages/server/src/modules/CreditNotes/subscribers/CreditNoteInventoryTransactionsSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts rename to packages/server/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts rename to packages/server/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts rename to packages/server/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotes/types/CreditNotes.types.ts b/packages/server/src/modules/CreditNotes/types/CreditNotes.types.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/types/CreditNotes.types.ts rename to packages/server/src/modules/CreditNotes/types/CreditNotes.types.ts diff --git a/packages/server-nest/src/modules/CreditNotes/utils.ts b/packages/server/src/modules/CreditNotes/utils.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotes/utils.ts rename to packages/server/src/modules/CreditNotes/utils.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncCredit.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncCredit.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncCredit.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncInvoices.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncInvoices.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncInvoices.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplySyncInvoices.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/DeleteCustomerLinkedCreditNote.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCustomerLinkedCreditNote.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/commands/DeleteCustomerLinkedCreditNote.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCustomerLinkedCreditNote.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts b/packages/server/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/CreditNoteAppliedInvoiceTransformer.ts b/packages/server/src/modules/CreditNotesApplyInvoice/queries/CreditNoteAppliedInvoiceTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/CreditNoteAppliedInvoiceTransformer.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/queries/CreditNoteAppliedInvoiceTransformer.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/CreditNoteWithInvoicesToApplyTransformer.ts b/packages/server/src/modules/CreditNotesApplyInvoice/queries/CreditNoteWithInvoicesToApplyTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/CreditNoteWithInvoicesToApplyTransformer.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/queries/CreditNoteWithInvoicesToApplyTransformer.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedAppliedInvoices.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedAppliedInvoices.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedAppliedInvoices.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedAppliedInvoices.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedInvoicesToApply.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedInvoicesToApply.service.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedInvoicesToApply.service.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/queries/GetCreditNoteAssociatedInvoicesToApply.service.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts b/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts b/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts diff --git a/packages/server-nest/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts b/packages/server/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts similarity index 100% rename from packages/server-nest/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts rename to packages/server/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts diff --git a/packages/server-nest/src/modules/CustomViews/CustomViewBaseModel.ts b/packages/server/src/modules/CustomViews/CustomViewBaseModel.ts similarity index 100% rename from packages/server-nest/src/modules/CustomViews/CustomViewBaseModel.ts rename to packages/server/src/modules/CustomViews/CustomViewBaseModel.ts diff --git a/packages/server-nest/src/modules/Customers/CustomerGLEntries.ts b/packages/server/src/modules/Customers/CustomerGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/CustomerGLEntries.ts rename to packages/server/src/modules/Customers/CustomerGLEntries.ts diff --git a/packages/server-nest/src/modules/Customers/CustomerGLEntriesStorage.ts b/packages/server/src/modules/Customers/CustomerGLEntriesStorage.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/CustomerGLEntriesStorage.ts rename to packages/server/src/modules/Customers/CustomerGLEntriesStorage.ts diff --git a/packages/server-nest/src/modules/Customers/Customers.controller.ts b/packages/server/src/modules/Customers/Customers.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/Customers.controller.ts rename to packages/server/src/modules/Customers/Customers.controller.ts diff --git a/packages/server-nest/src/modules/Customers/Customers.module.ts b/packages/server/src/modules/Customers/Customers.module.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/Customers.module.ts rename to packages/server/src/modules/Customers/Customers.module.ts diff --git a/packages/server-nest/src/modules/Customers/CustomersApplication.service.ts b/packages/server/src/modules/Customers/CustomersApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/CustomersApplication.service.ts rename to packages/server/src/modules/Customers/CustomersApplication.service.ts diff --git a/packages/server-nest/src/modules/Customers/CustomersExportable.ts b/packages/server/src/modules/Customers/CustomersExportable.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/CustomersExportable.ts rename to packages/server/src/modules/Customers/CustomersExportable.ts diff --git a/packages/server-nest/src/modules/Customers/CustomersImportable.ts b/packages/server/src/modules/Customers/CustomersImportable.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/CustomersImportable.ts rename to packages/server/src/modules/Customers/CustomersImportable.ts diff --git a/packages/server-nest/src/modules/Customers/_SampleData.ts b/packages/server/src/modules/Customers/_SampleData.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/_SampleData.ts rename to packages/server/src/modules/Customers/_SampleData.ts diff --git a/packages/server-nest/src/modules/Customers/commands/ActivateCustomer.service.ts b/packages/server/src/modules/Customers/commands/ActivateCustomer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/ActivateCustomer.service.ts rename to packages/server/src/modules/Customers/commands/ActivateCustomer.service.ts diff --git a/packages/server-nest/src/modules/Customers/commands/CreateCustomer.service.ts b/packages/server/src/modules/Customers/commands/CreateCustomer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/CreateCustomer.service.ts rename to packages/server/src/modules/Customers/commands/CreateCustomer.service.ts diff --git a/packages/server-nest/src/modules/Customers/commands/CreateEditCustomerDTO.service.ts b/packages/server/src/modules/Customers/commands/CreateEditCustomerDTO.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/CreateEditCustomerDTO.service.ts rename to packages/server/src/modules/Customers/commands/CreateEditCustomerDTO.service.ts diff --git a/packages/server-nest/src/modules/Customers/commands/CustomerValidators.service.ts b/packages/server/src/modules/Customers/commands/CustomerValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/CustomerValidators.service.ts rename to packages/server/src/modules/Customers/commands/CustomerValidators.service.ts diff --git a/packages/server-nest/src/modules/Customers/commands/DeleteCustomer.service.ts b/packages/server/src/modules/Customers/commands/DeleteCustomer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/DeleteCustomer.service.ts rename to packages/server/src/modules/Customers/commands/DeleteCustomer.service.ts diff --git a/packages/server-nest/src/modules/Customers/commands/EditCustomer.service.ts b/packages/server/src/modules/Customers/commands/EditCustomer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/EditCustomer.service.ts rename to packages/server/src/modules/Customers/commands/EditCustomer.service.ts diff --git a/packages/server-nest/src/modules/Customers/commands/EditOpeningBalanceCustomer.service.ts b/packages/server/src/modules/Customers/commands/EditOpeningBalanceCustomer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/commands/EditOpeningBalanceCustomer.service.ts rename to packages/server/src/modules/Customers/commands/EditOpeningBalanceCustomer.service.ts diff --git a/packages/server-nest/src/modules/Customers/constants.ts b/packages/server/src/modules/Customers/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/constants.ts rename to packages/server/src/modules/Customers/constants.ts diff --git a/packages/server-nest/src/modules/Customers/dtos/ContactAddress.dto.ts b/packages/server/src/modules/Customers/dtos/ContactAddress.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/dtos/ContactAddress.dto.ts rename to packages/server/src/modules/Customers/dtos/ContactAddress.dto.ts diff --git a/packages/server-nest/src/modules/Customers/dtos/CreateCustomer.dto.ts b/packages/server/src/modules/Customers/dtos/CreateCustomer.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/dtos/CreateCustomer.dto.ts rename to packages/server/src/modules/Customers/dtos/CreateCustomer.dto.ts diff --git a/packages/server-nest/src/modules/Customers/dtos/EditCustomer.dto.ts b/packages/server/src/modules/Customers/dtos/EditCustomer.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/dtos/EditCustomer.dto.ts rename to packages/server/src/modules/Customers/dtos/EditCustomer.dto.ts diff --git a/packages/server-nest/src/modules/Customers/models/Customer.ts b/packages/server/src/modules/Customers/models/Customer.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/models/Customer.ts rename to packages/server/src/modules/Customers/models/Customer.ts diff --git a/packages/server-nest/src/modules/Customers/queries/CustomerTransformer.ts b/packages/server/src/modules/Customers/queries/CustomerTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/queries/CustomerTransformer.ts rename to packages/server/src/modules/Customers/queries/CustomerTransformer.ts diff --git a/packages/server-nest/src/modules/Customers/queries/GetCustomer.service.ts b/packages/server/src/modules/Customers/queries/GetCustomer.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/queries/GetCustomer.service.ts rename to packages/server/src/modules/Customers/queries/GetCustomer.service.ts diff --git a/packages/server-nest/src/modules/Customers/queries/GetCustomers.service.ts b/packages/server/src/modules/Customers/queries/GetCustomers.service.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/queries/GetCustomers.service.ts rename to packages/server/src/modules/Customers/queries/GetCustomers.service.ts diff --git a/packages/server-nest/src/modules/Customers/subscribers/CustomerGLEntriesSubscriber.ts b/packages/server/src/modules/Customers/subscribers/CustomerGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/subscribers/CustomerGLEntriesSubscriber.ts rename to packages/server/src/modules/Customers/subscribers/CustomerGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/Customers/types/Customers.types.ts b/packages/server/src/modules/Customers/types/Customers.types.ts similarity index 100% rename from packages/server-nest/src/modules/Customers/types/Customers.types.ts rename to packages/server/src/modules/Customers/types/Customers.types.ts diff --git a/packages/server-nest/src/modules/Dashboard/Dashboard.controller.ts b/packages/server/src/modules/Dashboard/Dashboard.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Dashboard/Dashboard.controller.ts rename to packages/server/src/modules/Dashboard/Dashboard.controller.ts diff --git a/packages/server-nest/src/modules/Dashboard/Dashboard.module.ts b/packages/server/src/modules/Dashboard/Dashboard.module.ts similarity index 100% rename from packages/server-nest/src/modules/Dashboard/Dashboard.module.ts rename to packages/server/src/modules/Dashboard/Dashboard.module.ts diff --git a/packages/server-nest/src/modules/Dashboard/Dashboard.service.ts b/packages/server/src/modules/Dashboard/Dashboard.service.ts similarity index 100% rename from packages/server-nest/src/modules/Dashboard/Dashboard.service.ts rename to packages/server/src/modules/Dashboard/Dashboard.service.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilter.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilter.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilter.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilter.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilter.types.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilter.types.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilter.types.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilter.types.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterAbstractor.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterAbstractor.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterAbstractor.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterAbstractor.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterAdvancedFilter.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterAdvancedFilter.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterAdvancedFilter.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterAdvancedFilter.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterFilterRoles.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterFilterRoles.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterFilterRoles.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterFilterRoles.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterQueryParser.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterQueryParser.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterQueryParser.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterQueryParser.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterRoleAbstractor.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterRoleAbstractor.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterRoleAbstractor.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterRoleAbstractor.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterSearch.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterSearch.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterSearch.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterSearch.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterSortBy.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterSortBy.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterSortBy.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterSortBy.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterViews.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterViews.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/DynamicFilterViews.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/DynamicFilterViews.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/constants.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/constants.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/constants.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/constants.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicFilter/index.ts b/packages/server/src/modules/DynamicListing/DynamicFilter/index.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicFilter/index.ts rename to packages/server/src/modules/DynamicListing/DynamicFilter/index.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicList.module.ts b/packages/server/src/modules/DynamicListing/DynamicList.module.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicList.module.ts rename to packages/server/src/modules/DynamicListing/DynamicList.module.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicList.service.ts b/packages/server/src/modules/DynamicListing/DynamicList.service.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicList.service.ts rename to packages/server/src/modules/DynamicListing/DynamicList.service.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicListCustomView.service.ts b/packages/server/src/modules/DynamicListing/DynamicListCustomView.service.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicListCustomView.service.ts rename to packages/server/src/modules/DynamicListing/DynamicListCustomView.service.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicListFilterRoles.service.ts b/packages/server/src/modules/DynamicListing/DynamicListFilterRoles.service.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicListFilterRoles.service.ts rename to packages/server/src/modules/DynamicListing/DynamicListFilterRoles.service.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicListSearch.service.ts b/packages/server/src/modules/DynamicListing/DynamicListSearch.service.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicListSearch.service.ts rename to packages/server/src/modules/DynamicListing/DynamicListSearch.service.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicListServiceAbstract.ts b/packages/server/src/modules/DynamicListing/DynamicListServiceAbstract.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicListServiceAbstract.ts rename to packages/server/src/modules/DynamicListing/DynamicListServiceAbstract.ts diff --git a/packages/server-nest/src/modules/DynamicListing/DynamicListSortBy.service.ts b/packages/server/src/modules/DynamicListing/DynamicListSortBy.service.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/DynamicListSortBy.service.ts rename to packages/server/src/modules/DynamicListing/DynamicListSortBy.service.ts diff --git a/packages/server-nest/src/modules/DynamicListing/constants.ts b/packages/server/src/modules/DynamicListing/constants.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/constants.ts rename to packages/server/src/modules/DynamicListing/constants.ts diff --git a/packages/server-nest/src/modules/DynamicListing/models/CustomViewBaseModel.ts b/packages/server/src/modules/DynamicListing/models/CustomViewBaseModel.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/models/CustomViewBaseModel.ts rename to packages/server/src/modules/DynamicListing/models/CustomViewBaseModel.ts diff --git a/packages/server-nest/src/modules/DynamicListing/models/MetadataModel.ts b/packages/server/src/modules/DynamicListing/models/MetadataModel.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/models/MetadataModel.ts rename to packages/server/src/modules/DynamicListing/models/MetadataModel.ts diff --git a/packages/server-nest/src/modules/DynamicListing/models/SearchableBaseModel.ts b/packages/server/src/modules/DynamicListing/models/SearchableBaseModel.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/models/SearchableBaseModel.ts rename to packages/server/src/modules/DynamicListing/models/SearchableBaseModel.ts diff --git a/packages/server-nest/src/modules/DynamicListing/types/DynamicList.types.ts b/packages/server/src/modules/DynamicListing/types/DynamicList.types.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/types/DynamicList.types.ts rename to packages/server/src/modules/DynamicListing/types/DynamicList.types.ts diff --git a/packages/server-nest/src/modules/DynamicListing/validators.ts b/packages/server/src/modules/DynamicListing/validators.ts similarity index 100% rename from packages/server-nest/src/modules/DynamicListing/validators.ts rename to packages/server/src/modules/DynamicListing/validators.ts diff --git a/packages/server-nest/src/modules/EventsTracker/EventTracker.module.ts b/packages/server/src/modules/EventsTracker/EventTracker.module.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/EventTracker.module.ts rename to packages/server/src/modules/EventsTracker/EventTracker.module.ts diff --git a/packages/server-nest/src/modules/EventsTracker/EventTracker.service.ts b/packages/server/src/modules/EventsTracker/EventTracker.service.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/EventTracker.service.ts rename to packages/server/src/modules/EventsTracker/EventTracker.service.ts diff --git a/packages/server-nest/src/modules/EventsTracker/PostHog.constants.ts b/packages/server/src/modules/EventsTracker/PostHog.constants.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/PostHog.constants.ts rename to packages/server/src/modules/EventsTracker/PostHog.constants.ts diff --git a/packages/server-nest/src/modules/EventsTracker/event-tracker.ts b/packages/server/src/modules/EventsTracker/event-tracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/event-tracker.ts rename to packages/server/src/modules/EventsTracker/event-tracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/AccountEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/AccountEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/AccountEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/AccountEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/AuthenticationEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/AuthenticationEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/AuthenticationEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/AuthenticationEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/BankRuleEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/BankRuleEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/BankRuleEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/BankRuleEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/BankTransactionEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/BankTransactionEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/BankTransactionEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/BankTransactionEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/BillEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/BillEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/BillEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/BillEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/CustomerEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/CustomerEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/CustomerEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/CustomerEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/ExpenseEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/ExpenseEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/ExpenseEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/ExpenseEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/ItemEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/ItemEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/ItemEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/ItemEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/ManualJournalEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/ManualJournalEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/ManualJournalEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/ManualJournalEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/PaymentLinkEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/PaymentLinkEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/PaymentLinkEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/PaymentLinkEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/PaymentMadeEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/PaymentMadeEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/PaymentMadeEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/PaymentMadeEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/PaymentMethodEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/PaymentMethodEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/PaymentMethodEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/PaymentMethodEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/PaymentReceivedEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/PaymentReceivedEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/PaymentReceivedEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/PaymentReceivedEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/PdfTemplateEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/PdfTemplateEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/PdfTemplateEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/PdfTemplateEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/ReportsEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/ReportsEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/ReportsEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/ReportsEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/SaleEstimateEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/SaleEstimateEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/SaleEstimateEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/SaleEstimateEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/SaleInvoicesEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/SaleInvoicesEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/SaleInvoicesEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/SaleInvoicesEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/StripeIntegrationEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/StripeIntegrationEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/StripeIntegrationEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/StripeIntegrationEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/SubscriptionEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/SubscriptionEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/SubscriptionEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/SubscriptionEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/TransactionsLockingEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/TransactionsLockingEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/TransactionsLockingEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/TransactionsLockingEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/events/VendorEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/VendorEventsTracker.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/events/VendorEventsTracker.ts rename to packages/server/src/modules/EventsTracker/events/VendorEventsTracker.ts diff --git a/packages/server-nest/src/modules/EventsTracker/postHog.module.ts b/packages/server/src/modules/EventsTracker/postHog.module.ts similarity index 100% rename from packages/server-nest/src/modules/EventsTracker/postHog.module.ts rename to packages/server/src/modules/EventsTracker/postHog.module.ts diff --git a/packages/server-nest/src/modules/Expenses/Expenses.controller.ts b/packages/server/src/modules/Expenses/Expenses.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/Expenses.controller.ts rename to packages/server/src/modules/Expenses/Expenses.controller.ts diff --git a/packages/server-nest/src/modules/Expenses/Expenses.module.ts b/packages/server/src/modules/Expenses/Expenses.module.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/Expenses.module.ts rename to packages/server/src/modules/Expenses/Expenses.module.ts diff --git a/packages/server-nest/src/modules/Expenses/Expenses.types.ts b/packages/server/src/modules/Expenses/Expenses.types.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/Expenses.types.ts rename to packages/server/src/modules/Expenses/Expenses.types.ts diff --git a/packages/server-nest/src/modules/Expenses/ExpensesApplication.service.ts b/packages/server/src/modules/Expenses/ExpensesApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/ExpensesApplication.service.ts rename to packages/server/src/modules/Expenses/ExpensesApplication.service.ts diff --git a/packages/server-nest/src/modules/Expenses/ExpensesExportable.ts b/packages/server/src/modules/Expenses/ExpensesExportable.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/ExpensesExportable.ts rename to packages/server/src/modules/Expenses/ExpensesExportable.ts diff --git a/packages/server-nest/src/modules/Expenses/ExpensesImportable.ts b/packages/server/src/modules/Expenses/ExpensesImportable.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/ExpensesImportable.ts rename to packages/server/src/modules/Expenses/ExpensesImportable.ts diff --git a/packages/server-nest/src/modules/Expenses/commands/CommandExpenseDTO.transformer.ts b/packages/server/src/modules/Expenses/commands/CommandExpenseDTO.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/commands/CommandExpenseDTO.transformer.ts rename to packages/server/src/modules/Expenses/commands/CommandExpenseDTO.transformer.ts diff --git a/packages/server-nest/src/modules/Expenses/commands/CommandExpenseValidator.service.ts b/packages/server/src/modules/Expenses/commands/CommandExpenseValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/commands/CommandExpenseValidator.service.ts rename to packages/server/src/modules/Expenses/commands/CommandExpenseValidator.service.ts diff --git a/packages/server-nest/src/modules/Expenses/commands/CreateExpense.service.ts b/packages/server/src/modules/Expenses/commands/CreateExpense.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/commands/CreateExpense.service.ts rename to packages/server/src/modules/Expenses/commands/CreateExpense.service.ts diff --git a/packages/server-nest/src/modules/Expenses/commands/DeleteExpense.service.ts b/packages/server/src/modules/Expenses/commands/DeleteExpense.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/commands/DeleteExpense.service.ts rename to packages/server/src/modules/Expenses/commands/DeleteExpense.service.ts diff --git a/packages/server-nest/src/modules/Expenses/commands/EditExpense.service.ts b/packages/server/src/modules/Expenses/commands/EditExpense.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/commands/EditExpense.service.ts rename to packages/server/src/modules/Expenses/commands/EditExpense.service.ts diff --git a/packages/server-nest/src/modules/Expenses/commands/PublishExpense.service.ts b/packages/server/src/modules/Expenses/commands/PublishExpense.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/commands/PublishExpense.service.ts rename to packages/server/src/modules/Expenses/commands/PublishExpense.service.ts diff --git a/packages/server-nest/src/modules/Expenses/constants.ts b/packages/server/src/modules/Expenses/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/constants.ts rename to packages/server/src/modules/Expenses/constants.ts diff --git a/packages/server-nest/src/modules/Expenses/dtos/Expense.dto.ts b/packages/server/src/modules/Expenses/dtos/Expense.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/dtos/Expense.dto.ts rename to packages/server/src/modules/Expenses/dtos/Expense.dto.ts diff --git a/packages/server-nest/src/modules/Expenses/interfaces/Expenses.interface.ts b/packages/server/src/modules/Expenses/interfaces/Expenses.interface.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/interfaces/Expenses.interface.ts rename to packages/server/src/modules/Expenses/interfaces/Expenses.interface.ts diff --git a/packages/server-nest/src/modules/Expenses/models/Expense.model.ts b/packages/server/src/modules/Expenses/models/Expense.model.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/models/Expense.model.ts rename to packages/server/src/modules/Expenses/models/Expense.model.ts diff --git a/packages/server-nest/src/modules/Expenses/models/ExpenseCategory.model.ts b/packages/server/src/modules/Expenses/models/ExpenseCategory.model.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/models/ExpenseCategory.model.ts rename to packages/server/src/modules/Expenses/models/ExpenseCategory.model.ts diff --git a/packages/server-nest/src/modules/Expenses/queries/Expense.transformer.ts b/packages/server/src/modules/Expenses/queries/Expense.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/queries/Expense.transformer.ts rename to packages/server/src/modules/Expenses/queries/Expense.transformer.ts diff --git a/packages/server-nest/src/modules/Expenses/queries/ExpenseCategory.transformer.ts b/packages/server/src/modules/Expenses/queries/ExpenseCategory.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/queries/ExpenseCategory.transformer.ts rename to packages/server/src/modules/Expenses/queries/ExpenseCategory.transformer.ts diff --git a/packages/server-nest/src/modules/Expenses/queries/GetExpense.service.ts b/packages/server/src/modules/Expenses/queries/GetExpense.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/queries/GetExpense.service.ts rename to packages/server/src/modules/Expenses/queries/GetExpense.service.ts diff --git a/packages/server-nest/src/modules/Expenses/queries/GetExpenses.service.ts b/packages/server/src/modules/Expenses/queries/GetExpenses.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/queries/GetExpenses.service.ts rename to packages/server/src/modules/Expenses/queries/GetExpenses.service.ts diff --git a/packages/server-nest/src/modules/Expenses/subscribers/ExpenseGL.ts b/packages/server/src/modules/Expenses/subscribers/ExpenseGL.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/subscribers/ExpenseGL.ts rename to packages/server/src/modules/Expenses/subscribers/ExpenseGL.ts diff --git a/packages/server-nest/src/modules/Expenses/subscribers/ExpenseGLEntries.service.ts b/packages/server/src/modules/Expenses/subscribers/ExpenseGLEntries.service.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/subscribers/ExpenseGLEntries.service.ts rename to packages/server/src/modules/Expenses/subscribers/ExpenseGLEntries.service.ts diff --git a/packages/server-nest/src/modules/Expenses/subscribers/ExpenseGLEntries.subscriber.ts b/packages/server/src/modules/Expenses/subscribers/ExpenseGLEntries.subscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/subscribers/ExpenseGLEntries.subscriber.ts rename to packages/server/src/modules/Expenses/subscribers/ExpenseGLEntries.subscriber.ts diff --git a/packages/server-nest/src/modules/Expenses/subscribers/ExpenseGLEntriesStorage.sevice.ts b/packages/server/src/modules/Expenses/subscribers/ExpenseGLEntriesStorage.sevice.ts similarity index 100% rename from packages/server-nest/src/modules/Expenses/subscribers/ExpenseGLEntriesStorage.sevice.ts rename to packages/server/src/modules/Expenses/subscribers/ExpenseGLEntriesStorage.sevice.ts diff --git a/packages/server-nest/src/modules/Export/Export.controller.ts b/packages/server/src/modules/Export/Export.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Export/Export.controller.ts rename to packages/server/src/modules/Export/Export.controller.ts diff --git a/packages/server-nest/src/modules/Export/Export.module.ts b/packages/server/src/modules/Export/Export.module.ts similarity index 100% rename from packages/server-nest/src/modules/Export/Export.module.ts rename to packages/server/src/modules/Export/Export.module.ts diff --git a/packages/server-nest/src/modules/Export/ExportAls.ts b/packages/server/src/modules/Export/ExportAls.ts similarity index 100% rename from packages/server-nest/src/modules/Export/ExportAls.ts rename to packages/server/src/modules/Export/ExportAls.ts diff --git a/packages/server-nest/src/modules/Export/ExportApplication.ts b/packages/server/src/modules/Export/ExportApplication.ts similarity index 100% rename from packages/server-nest/src/modules/Export/ExportApplication.ts rename to packages/server/src/modules/Export/ExportApplication.ts diff --git a/packages/server-nest/src/modules/Export/ExportPdf.ts b/packages/server/src/modules/Export/ExportPdf.ts similarity index 100% rename from packages/server-nest/src/modules/Export/ExportPdf.ts rename to packages/server/src/modules/Export/ExportPdf.ts diff --git a/packages/server-nest/src/modules/Export/ExportRegistery.ts b/packages/server/src/modules/Export/ExportRegistery.ts similarity index 100% rename from packages/server-nest/src/modules/Export/ExportRegistery.ts rename to packages/server/src/modules/Export/ExportRegistery.ts diff --git a/packages/server-nest/src/modules/Export/ExportResources.ts b/packages/server/src/modules/Export/ExportResources.ts similarity index 100% rename from packages/server-nest/src/modules/Export/ExportResources.ts rename to packages/server/src/modules/Export/ExportResources.ts diff --git a/packages/server-nest/src/modules/Export/ExportService.ts b/packages/server/src/modules/Export/ExportService.ts similarity index 100% rename from packages/server-nest/src/modules/Export/ExportService.ts rename to packages/server/src/modules/Export/ExportService.ts diff --git a/packages/server-nest/src/modules/Export/Exportable.ts b/packages/server/src/modules/Export/Exportable.ts similarity index 100% rename from packages/server-nest/src/modules/Export/Exportable.ts rename to packages/server/src/modules/Export/Exportable.ts diff --git a/packages/server-nest/src/modules/Export/common.ts b/packages/server/src/modules/Export/common.ts similarity index 100% rename from packages/server-nest/src/modules/Export/common.ts rename to packages/server/src/modules/Export/common.ts diff --git a/packages/server-nest/src/modules/Export/constants.ts b/packages/server/src/modules/Export/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Export/constants.ts rename to packages/server/src/modules/Export/constants.ts diff --git a/packages/server-nest/src/modules/Export/dtos/ExportQuery.dto.ts b/packages/server/src/modules/Export/dtos/ExportQuery.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Export/dtos/ExportQuery.dto.ts rename to packages/server/src/modules/Export/dtos/ExportQuery.dto.ts diff --git a/packages/server-nest/src/modules/Export/utils.ts b/packages/server/src/modules/Export/utils.ts similarity index 100% rename from packages/server-nest/src/modules/Export/utils.ts rename to packages/server/src/modules/Export/utils.ts diff --git a/packages/server-nest/src/modules/Features/Features.module.ts b/packages/server/src/modules/Features/Features.module.ts similarity index 100% rename from packages/server-nest/src/modules/Features/Features.module.ts rename to packages/server/src/modules/Features/Features.module.ts diff --git a/packages/server-nest/src/modules/Features/FeaturesConfigure.ts b/packages/server/src/modules/Features/FeaturesConfigure.ts similarity index 100% rename from packages/server-nest/src/modules/Features/FeaturesConfigure.ts rename to packages/server/src/modules/Features/FeaturesConfigure.ts diff --git a/packages/server-nest/src/modules/Features/FeaturesConfigureManager.ts b/packages/server/src/modules/Features/FeaturesConfigureManager.ts similarity index 100% rename from packages/server-nest/src/modules/Features/FeaturesConfigureManager.ts rename to packages/server/src/modules/Features/FeaturesConfigureManager.ts diff --git a/packages/server-nest/src/modules/Features/FeaturesManager.ts b/packages/server/src/modules/Features/FeaturesManager.ts similarity index 100% rename from packages/server-nest/src/modules/Features/FeaturesManager.ts rename to packages/server/src/modules/Features/FeaturesManager.ts diff --git a/packages/server-nest/src/modules/Features/FeaturesSettingsDriver.ts b/packages/server/src/modules/Features/FeaturesSettingsDriver.ts similarity index 100% rename from packages/server-nest/src/modules/Features/FeaturesSettingsDriver.ts rename to packages/server/src/modules/Features/FeaturesSettingsDriver.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/FinancialStatements.module.ts b/packages/server/src/modules/FinancialStatements/FinancialStatements.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/FinancialStatements.module.ts rename to packages/server/src/modules/FinancialStatements/FinancialStatements.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialDatePeriods.ts b/packages/server/src/modules/FinancialStatements/common/FinancialDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialDateRanges.ts b/packages/server/src/modules/FinancialStatements/common/FinancialDateRanges.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialDateRanges.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialDateRanges.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialEvaluateEquation.ts b/packages/server/src/modules/FinancialStatements/common/FinancialEvaluateEquation.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialEvaluateEquation.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialEvaluateEquation.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialFilter.ts b/packages/server/src/modules/FinancialStatements/common/FinancialFilter.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialFilter.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialFilter.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialHorizTotals.ts b/packages/server/src/modules/FinancialStatements/common/FinancialHorizTotals.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialHorizTotals.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialHorizTotals.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialPreviousPeriod.ts b/packages/server/src/modules/FinancialStatements/common/FinancialPreviousPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialPreviousPeriod.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialPreviousPeriod.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialPreviousYear.ts b/packages/server/src/modules/FinancialStatements/common/FinancialPreviousYear.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialPreviousYear.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialPreviousYear.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialReportService.ts b/packages/server/src/modules/FinancialStatements/common/FinancialReportService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialReportService.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialReportService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialSchema.ts b/packages/server/src/modules/FinancialStatements/common/FinancialSchema.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialSchema.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialSchema.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialSheet.ts b/packages/server/src/modules/FinancialStatements/common/FinancialSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialSheet.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialSheetCommon.module.ts b/packages/server/src/modules/FinancialStatements/common/FinancialSheetCommon.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialSheetCommon.module.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialSheetCommon.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialSheetMeta.ts b/packages/server/src/modules/FinancialStatements/common/FinancialSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialSheetStructure.ts b/packages/server/src/modules/FinancialStatements/common/FinancialSheetStructure.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialSheetStructure.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialSheetStructure.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialTable.ts b/packages/server/src/modules/FinancialStatements/common/FinancialTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialTable.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialTablePreviousPeriod.ts b/packages/server/src/modules/FinancialStatements/common/FinancialTablePreviousPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialTablePreviousPeriod.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialTablePreviousPeriod.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialTablePreviousYear.ts b/packages/server/src/modules/FinancialStatements/common/FinancialTablePreviousYear.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialTablePreviousYear.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialTablePreviousYear.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/FinancialTableStructure.ts b/packages/server/src/modules/FinancialStatements/common/FinancialTableStructure.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/FinancialTableStructure.ts rename to packages/server/src/modules/FinancialStatements/common/FinancialTableStructure.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/TableSheet.ts b/packages/server/src/modules/FinancialStatements/common/TableSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/TableSheet.ts rename to packages/server/src/modules/FinancialStatements/common/TableSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/common/TableSheetPdf.ts b/packages/server/src/modules/FinancialStatements/common/TableSheetPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/common/TableSheetPdf.ts rename to packages/server/src/modules/FinancialStatements/common/TableSheetPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.module.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.module.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.types.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.types.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryApplication.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryMeta.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryPdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryPdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryPdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryPdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryRepository.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryService.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryService.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummarySheet.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummarySheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummarySheet.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummarySheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTable.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTable.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/utils.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/APAgingSummary/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/APAgingSummary/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.module.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.module.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.types.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.types.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryApplication.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryMeta.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryPdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryPdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryPdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryPdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryRepository.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryService.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryService.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummarySheet.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummarySheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummarySheet.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummarySheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTable.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTable.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/utils.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ARAgingSummary/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingReport.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingReport.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingReport.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingReport.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.module.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.module.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.types.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.types.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummary.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryMeta.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryTable.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryTable.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/AgingSummaryTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/_constants.ts b/packages/server/src/modules/FinancialStatements/modules/AgingSummary/_constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/AgingSummary/_constants.ts rename to packages/server/src/modules/FinancialStatements/modules/AgingSummary/_constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.module.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.module.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.types.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.types.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAccounts.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAccounts.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAccounts.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAccounts.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAggregators.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAggregators.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAggregators.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetAggregators.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetApplication.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetBase.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetBase.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetBase.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetBase.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousYear.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousYear.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousYear.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetComparsionPreviousYear.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetDatePeriods.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetFiltering.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetFiltering.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetFiltering.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetFiltering.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetMeta.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncome.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncome.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncome.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncome.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePP.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePP.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePP.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePP.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePY.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePY.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePY.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetNetIncomePY.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPercentage.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPercentage.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPercentage.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetPercentage.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetQuery.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetQuery.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetQuery.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetQuery.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepository.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepositoryNetIncome.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepositoryNetIncome.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepositoryNetIncome.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetRepositoryNetIncome.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetSchema.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetSchema.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetSchema.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetSchema.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTable.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTable.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableDatePeriods.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePercentage.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePercentage.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePercentage.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePercentage.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousPeriod.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousPeriod.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousPeriod.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousYear.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousYear.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousYear.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTablePreviousYear.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTotal.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTotal.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTotal.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetTotal.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/constants.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/BalanceSheet/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/BalanceSheet/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlow.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlow.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlow.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlow.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowDatePeriods.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowRepository.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowService.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowService.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowTable.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowTable.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashFlowTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.types.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.types.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetApplication.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetMeta.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatement.module.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatement.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatement.module.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatement.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementBase.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementBase.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementBase.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementBase.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/constants.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/schema.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/schema.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CashFlowStatement/schema.ts rename to packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/schema.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.ts b/packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.ts rename to packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.types.ts b/packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.types.ts rename to packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummary.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.module.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.module.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.types.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.types.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryService.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryService.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/_utils.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/_utils.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/_utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/constants.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/CustomerBalanceSummary/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.module.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.module.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.types.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.types.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerApplication.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerExport.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerExport.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerExport.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerExport.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerMeta.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerPdf.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerRepository.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerService.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerService.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTable.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTable.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/_utils.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/_utils.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/_utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/constants.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/utils.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/GeneralLedger/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/GeneralLedger/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.module.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.module.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.service.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.service.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.service.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.service.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.types.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.types.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsApplication.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsMeta.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsRepository.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTable.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTable.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTablePdf.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTablePdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTablePdf.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsTablePdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/constant.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/constant.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryItemDetails/constant.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/constant.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.module.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.module.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.types.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.types.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheet.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetApplication.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetExportable.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetExportable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetExportable.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetExportable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetMeta.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetPdf.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetRepository.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetService.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetService.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTable.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTable.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/_constants.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/_constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/InventoryValuationSheet/_constants.ts rename to packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/_constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.module.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.module.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.types.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.types.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetApplication.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetExport.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetExport.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetExport.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetExport.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetMeta.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetPdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetPdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetPdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetPdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetRepository.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetService.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetService.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTable.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTable.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/constant.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/constant.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/constant.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/constant.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/types.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/JournalSheet/types.ts rename to packages/server/src/modules/FinancialStatements/modules/JournalSheet/types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSchema.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSchema.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSchema.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSchema.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.module.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.module.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.types.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.types.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetApplication.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetBase.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetBase.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetBase.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetBase.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetDatePeriods.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetFilter.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetFilter.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetFilter.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetFilter.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetMeta.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPercentage.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPercentage.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPercentage.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPercentage.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousYear.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousYear.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousYear.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetPreviousYear.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetQuery.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetQuery.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetQuery.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetQuery.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetRepository.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetService.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetService.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTable.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTable.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTablePercentage.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTablePercentage.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTablePercentage.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetTablePercentage.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousYear.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousYear.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousYear.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossTablePreviousYear.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/constants.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/utils.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/ProfitLossSheet/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.module.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.module.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.service.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.service.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.service.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.service.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsApplication.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsExport.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsExport.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsExport.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsExport.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsMeta.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsPdf.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTable.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTable.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/_types.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/_types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/_types.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/_types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/types/PurchasesByItems.types.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/types/PurchasesByItems.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/types/PurchasesByItems.types.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/types/PurchasesByItems.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/utils.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/PurchasesByItems/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.module.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.module.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.types.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.types.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsApplication.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsExport.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsExport.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsExport.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsExport.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsMeta.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsPdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsPdfInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsPdfInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsPdfInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsService.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsService.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTable.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTable.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/constants.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/utils.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesByItems/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesByItems/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.module.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.module.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.types.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.types.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiability.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/_constants.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/_constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/_constants.ts rename to packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/_constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.types.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.types.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContact.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactRepository.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactTableRows.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactTableRows.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactTableRows.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByContact/TransactionsByContactTableRows.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.module.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.module.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.types.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.types.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomers.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomers.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomers.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomers.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersApplication.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersMeta.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersPdf.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersRepository.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersService.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersService.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/utils.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByCustomer/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionByReference.module.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionByReference.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionByReference.module.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionByReference.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.service.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.service.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.service.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.service.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.types.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.types.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReference.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceApplication.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceReport.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceReport.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceReport.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceReport.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceRepository.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/TransactionsByReferenceRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/_utils.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByReference/_utils.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByReference/_utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.module.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.module.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.types.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.types.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorApplication.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorMeta.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorPdf.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorRepository.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/constants.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/utils.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TransactionsByVendor/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.module.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.module.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.types.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.types.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetMeta.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetRepository.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTable.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTable.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/_constants.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/_constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/_constants.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/_constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/_types.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/_types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/_types.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/_types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/_utils.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/_utils.ts rename to packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/_utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.module.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.module.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.module.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.module.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.types.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.types.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryApplication.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryApplication.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryApplication.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryApplication.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryMeta.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryMeta.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryMeta.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryMeta.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryPdf.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryPdf.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryPdf.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryPdf.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryRepository.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryRepository.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryRepository.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryRepository.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryService.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryService.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryService.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryService.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/constants.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/constants.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/constants.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/constants.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/utils.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/modules/VendorBalanceSummary/utils.ts rename to packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/types/Report.types.ts b/packages/server/src/modules/FinancialStatements/types/Report.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/types/Report.types.ts rename to packages/server/src/modules/FinancialStatements/types/Report.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/types/Table.types.ts b/packages/server/src/modules/FinancialStatements/types/Table.types.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/types/Table.types.ts rename to packages/server/src/modules/FinancialStatements/types/Table.types.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/utils.ts b/packages/server/src/modules/FinancialStatements/utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/utils.ts rename to packages/server/src/modules/FinancialStatements/utils.ts diff --git a/packages/server-nest/src/modules/FinancialStatements/utils/Table.utils.ts b/packages/server/src/modules/FinancialStatements/utils/Table.utils.ts similarity index 100% rename from packages/server-nest/src/modules/FinancialStatements/utils/Table.utils.ts rename to packages/server/src/modules/FinancialStatements/utils/Table.utils.ts diff --git a/packages/server-nest/src/modules/Import/Import.module.ts b/packages/server/src/modules/Import/Import.module.ts similarity index 100% rename from packages/server-nest/src/modules/Import/Import.module.ts rename to packages/server/src/modules/Import/Import.module.ts diff --git a/packages/server-nest/src/modules/Import/ImportALS.ts b/packages/server/src/modules/Import/ImportALS.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportALS.ts rename to packages/server/src/modules/Import/ImportALS.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileCommon.ts b/packages/server/src/modules/Import/ImportFileCommon.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileCommon.ts rename to packages/server/src/modules/Import/ImportFileCommon.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileDataTransformer.ts b/packages/server/src/modules/Import/ImportFileDataTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileDataTransformer.ts rename to packages/server/src/modules/Import/ImportFileDataTransformer.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileDataValidator.ts b/packages/server/src/modules/Import/ImportFileDataValidator.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileDataValidator.ts rename to packages/server/src/modules/Import/ImportFileDataValidator.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileMapping.ts b/packages/server/src/modules/Import/ImportFileMapping.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileMapping.ts rename to packages/server/src/modules/Import/ImportFileMapping.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileMeta.ts b/packages/server/src/modules/Import/ImportFileMeta.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileMeta.ts rename to packages/server/src/modules/Import/ImportFileMeta.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileMetaTransformer.ts b/packages/server/src/modules/Import/ImportFileMetaTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileMetaTransformer.ts rename to packages/server/src/modules/Import/ImportFileMetaTransformer.ts diff --git a/packages/server-nest/src/modules/Import/ImportFilePreview.ts b/packages/server/src/modules/Import/ImportFilePreview.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFilePreview.ts rename to packages/server/src/modules/Import/ImportFilePreview.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileProcess.ts b/packages/server/src/modules/Import/ImportFileProcess.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileProcess.ts rename to packages/server/src/modules/Import/ImportFileProcess.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileProcessCommit.ts b/packages/server/src/modules/Import/ImportFileProcessCommit.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileProcessCommit.ts rename to packages/server/src/modules/Import/ImportFileProcessCommit.ts diff --git a/packages/server-nest/src/modules/Import/ImportFileUpload.ts b/packages/server/src/modules/Import/ImportFileUpload.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportFileUpload.ts rename to packages/server/src/modules/Import/ImportFileUpload.ts diff --git a/packages/server-nest/src/modules/Import/ImportRemoveExpiredFiles.ts b/packages/server/src/modules/Import/ImportRemoveExpiredFiles.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportRemoveExpiredFiles.ts rename to packages/server/src/modules/Import/ImportRemoveExpiredFiles.ts diff --git a/packages/server-nest/src/modules/Import/ImportResource.module.ts b/packages/server/src/modules/Import/ImportResource.module.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportResource.module.ts rename to packages/server/src/modules/Import/ImportResource.module.ts diff --git a/packages/server-nest/src/modules/Import/ImportResourceApplication.ts b/packages/server/src/modules/Import/ImportResourceApplication.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportResourceApplication.ts rename to packages/server/src/modules/Import/ImportResourceApplication.ts diff --git a/packages/server-nest/src/modules/Import/ImportSample.ts b/packages/server/src/modules/Import/ImportSample.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportSample.ts rename to packages/server/src/modules/Import/ImportSample.ts diff --git a/packages/server-nest/src/modules/Import/Importable.ts b/packages/server/src/modules/Import/Importable.ts similarity index 100% rename from packages/server-nest/src/modules/Import/Importable.ts rename to packages/server/src/modules/Import/Importable.ts diff --git a/packages/server-nest/src/modules/Import/ImportableRegistry.ts b/packages/server/src/modules/Import/ImportableRegistry.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportableRegistry.ts rename to packages/server/src/modules/Import/ImportableRegistry.ts diff --git a/packages/server-nest/src/modules/Import/ImportableResources.ts b/packages/server/src/modules/Import/ImportableResources.ts similarity index 100% rename from packages/server-nest/src/modules/Import/ImportableResources.ts rename to packages/server/src/modules/Import/ImportableResources.ts diff --git a/packages/server-nest/src/modules/Import/_constants.ts b/packages/server/src/modules/Import/_constants.ts similarity index 100% rename from packages/server-nest/src/modules/Import/_constants.ts rename to packages/server/src/modules/Import/_constants.ts diff --git a/packages/server-nest/src/modules/Import/_utils.ts b/packages/server/src/modules/Import/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/Import/_utils.ts rename to packages/server/src/modules/Import/_utils.ts diff --git a/packages/server-nest/src/modules/Import/interfaces.ts b/packages/server/src/modules/Import/interfaces.ts similarity index 100% rename from packages/server-nest/src/modules/Import/interfaces.ts rename to packages/server/src/modules/Import/interfaces.ts diff --git a/packages/server-nest/src/modules/Import/jobs/ImportDeleteExpiredFilesJob.ts b/packages/server/src/modules/Import/jobs/ImportDeleteExpiredFilesJob.ts similarity index 100% rename from packages/server-nest/src/modules/Import/jobs/ImportDeleteExpiredFilesJob.ts rename to packages/server/src/modules/Import/jobs/ImportDeleteExpiredFilesJob.ts diff --git a/packages/server-nest/src/modules/Import/models/Import.ts b/packages/server/src/modules/Import/models/Import.ts similarity index 100% rename from packages/server-nest/src/modules/Import/models/Import.ts rename to packages/server/src/modules/Import/models/Import.ts diff --git a/packages/server-nest/src/modules/Import/sheet_utils.ts b/packages/server/src/modules/Import/sheet_utils.ts similarity index 100% rename from packages/server-nest/src/modules/Import/sheet_utils.ts rename to packages/server/src/modules/Import/sheet_utils.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentTransformer.ts b/packages/server/src/modules/InventoryAdjutments/InventoryAdjustmentTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentTransformer.ts rename to packages/server/src/modules/InventoryAdjutments/InventoryAdjustmentTransformer.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts b/packages/server/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts rename to packages/server/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.module.ts b/packages/server/src/modules/InventoryAdjutments/InventoryAdjustments.module.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.module.ts rename to packages/server/src/modules/InventoryAdjutments/InventoryAdjustments.module.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts b/packages/server/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts rename to packages/server/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts b/packages/server/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts rename to packages/server/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/commands/DeleteInventoryAdjustment.service.ts b/packages/server/src/modules/InventoryAdjutments/commands/DeleteInventoryAdjustment.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/commands/DeleteInventoryAdjustment.service.ts rename to packages/server/src/modules/InventoryAdjutments/commands/DeleteInventoryAdjustment.service.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/commands/PublishInventoryAdjustment.service.ts b/packages/server/src/modules/InventoryAdjutments/commands/PublishInventoryAdjustment.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/commands/PublishInventoryAdjustment.service.ts rename to packages/server/src/modules/InventoryAdjutments/commands/PublishInventoryAdjustment.service.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentGL.ts b/packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentGL.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentGL.ts rename to packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentGL.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts b/packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts rename to packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/constants/InventoryAdjustments.constants.ts b/packages/server/src/modules/InventoryAdjutments/constants/InventoryAdjustments.constants.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/constants/InventoryAdjustments.constants.ts rename to packages/server/src/modules/InventoryAdjutments/constants/InventoryAdjustments.constants.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts b/packages/server/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts rename to packages/server/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactions.ts b/packages/server/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactions.ts rename to packages/server/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactionsSubscriber.ts b/packages/server/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactionsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactionsSubscriber.ts rename to packages/server/src/modules/InventoryAdjutments/inventory/InventoryAdjustmentInventoryTransactionsSubscriber.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts b/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts rename to packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts b/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts rename to packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/queries/GetInventoryAdjustment.service.ts b/packages/server/src/modules/InventoryAdjutments/queries/GetInventoryAdjustment.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/queries/GetInventoryAdjustment.service.ts rename to packages/server/src/modules/InventoryAdjutments/queries/GetInventoryAdjustment.service.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/queries/GetInventoryAdjustments.service.ts b/packages/server/src/modules/InventoryAdjutments/queries/GetInventoryAdjustments.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/queries/GetInventoryAdjustments.service.ts rename to packages/server/src/modules/InventoryAdjutments/queries/GetInventoryAdjustments.service.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/subscribers/InventoryAdjustmentGL.subscriber.ts b/packages/server/src/modules/InventoryAdjutments/subscribers/InventoryAdjustmentGL.subscriber.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/subscribers/InventoryAdjustmentGL.subscriber.ts rename to packages/server/src/modules/InventoryAdjutments/subscribers/InventoryAdjustmentGL.subscriber.ts diff --git a/packages/server-nest/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts b/packages/server/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts rename to packages/server/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts diff --git a/packages/server-nest/src/modules/InventoryCost/InventoryCost.module.ts b/packages/server/src/modules/InventoryCost/InventoryCost.module.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/InventoryCost.module.ts rename to packages/server/src/modules/InventoryCost/InventoryCost.module.ts diff --git a/packages/server-nest/src/modules/InventoryCost/InventoryCostApplication.ts b/packages/server/src/modules/InventoryCost/InventoryCostApplication.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/InventoryCostApplication.ts rename to packages/server/src/modules/InventoryCost/InventoryCostApplication.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryAverageCostMethod.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryAverageCostMethod.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryAverageCostMethod.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryAverageCostMethod.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryAverageCostMethod.ts b/packages/server/src/modules/InventoryCost/commands/InventoryAverageCostMethod.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryAverageCostMethod.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryAverageCostMethod.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryComputeCost.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryComputeCost.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryComputeCost.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryComputeCost.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryCostGLStorage.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryCostGLStorage.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryCostGLStorage.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryCostGLStorage.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryCosts.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryCosts.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryCosts.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryCosts.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryItemOpeningAvgCost.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryItemOpeningAvgCost.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryItemOpeningAvgCost.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryItemOpeningAvgCost.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryItemsQuantitySync.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryItemsQuantitySync.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryItemsQuantitySync.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryItemsQuantitySync.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryTransactions.service.ts b/packages/server/src/modules/InventoryCost/commands/InventoryTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/InventoryTransactions.service.ts rename to packages/server/src/modules/InventoryCost/commands/InventoryTransactions.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/commands/StoreInventortyLotsCost.service.ts b/packages/server/src/modules/InventoryCost/commands/StoreInventortyLotsCost.service.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/commands/StoreInventortyLotsCost.service.ts rename to packages/server/src/modules/InventoryCost/commands/StoreInventortyLotsCost.service.ts diff --git a/packages/server-nest/src/modules/InventoryCost/models/InventoryCostLotTracker.ts b/packages/server/src/modules/InventoryCost/models/InventoryCostLotTracker.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/models/InventoryCostLotTracker.ts rename to packages/server/src/modules/InventoryCost/models/InventoryCostLotTracker.ts diff --git a/packages/server-nest/src/modules/InventoryCost/models/InventoryTransaction.ts b/packages/server/src/modules/InventoryCost/models/InventoryTransaction.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/models/InventoryTransaction.ts rename to packages/server/src/modules/InventoryCost/models/InventoryTransaction.ts diff --git a/packages/server-nest/src/modules/InventoryCost/models/InventoryTransactionMeta.ts b/packages/server/src/modules/InventoryCost/models/InventoryTransactionMeta.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/models/InventoryTransactionMeta.ts rename to packages/server/src/modules/InventoryCost/models/InventoryTransactionMeta.ts diff --git a/packages/server-nest/src/modules/InventoryCost/processors/ComputeItemCost.processor.ts b/packages/server/src/modules/InventoryCost/processors/ComputeItemCost.processor.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/processors/ComputeItemCost.processor.ts rename to packages/server/src/modules/InventoryCost/processors/ComputeItemCost.processor.ts diff --git a/packages/server-nest/src/modules/InventoryCost/processors/WriteInventoryTransactionsGLEntries.processor.ts b/packages/server/src/modules/InventoryCost/processors/WriteInventoryTransactionsGLEntries.processor.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/processors/WriteInventoryTransactionsGLEntries.processor.ts rename to packages/server/src/modules/InventoryCost/processors/WriteInventoryTransactionsGLEntries.processor.ts diff --git a/packages/server-nest/src/modules/InventoryCost/subscribers/InventoryCost.subscriber.ts b/packages/server/src/modules/InventoryCost/subscribers/InventoryCost.subscriber.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/subscribers/InventoryCost.subscriber.ts rename to packages/server/src/modules/InventoryCost/subscribers/InventoryCost.subscriber.ts diff --git a/packages/server-nest/src/modules/InventoryCost/subscribers/InventoryCostGLBeforeWriteSubscriber.ts b/packages/server/src/modules/InventoryCost/subscribers/InventoryCostGLBeforeWriteSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/subscribers/InventoryCostGLBeforeWriteSubscriber.ts rename to packages/server/src/modules/InventoryCost/subscribers/InventoryCostGLBeforeWriteSubscriber.ts diff --git a/packages/server-nest/src/modules/InventoryCost/types/InventoryCost.types.ts b/packages/server/src/modules/InventoryCost/types/InventoryCost.types.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/types/InventoryCost.types.ts rename to packages/server/src/modules/InventoryCost/types/InventoryCost.types.ts diff --git a/packages/server-nest/src/modules/InventoryCost/utils.ts b/packages/server/src/modules/InventoryCost/utils.ts similarity index 100% rename from packages/server-nest/src/modules/InventoryCost/utils.ts rename to packages/server/src/modules/InventoryCost/utils.ts diff --git a/packages/server-nest/src/modules/ItemCategories/ItemCategoriesExportable.ts b/packages/server/src/modules/ItemCategories/ItemCategoriesExportable.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/ItemCategoriesExportable.ts rename to packages/server/src/modules/ItemCategories/ItemCategoriesExportable.ts diff --git a/packages/server-nest/src/modules/ItemCategories/ItemCategoriesImportable.ts b/packages/server/src/modules/ItemCategories/ItemCategoriesImportable.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/ItemCategoriesImportable.ts rename to packages/server/src/modules/ItemCategories/ItemCategoriesImportable.ts diff --git a/packages/server-nest/src/modules/ItemCategories/ItemCategory.application.ts b/packages/server/src/modules/ItemCategories/ItemCategory.application.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/ItemCategory.application.ts rename to packages/server/src/modules/ItemCategories/ItemCategory.application.ts diff --git a/packages/server-nest/src/modules/ItemCategories/ItemCategory.controller.ts b/packages/server/src/modules/ItemCategories/ItemCategory.controller.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/ItemCategory.controller.ts rename to packages/server/src/modules/ItemCategories/ItemCategory.controller.ts diff --git a/packages/server-nest/src/modules/ItemCategories/ItemCategory.interfaces.ts b/packages/server/src/modules/ItemCategories/ItemCategory.interfaces.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/ItemCategory.interfaces.ts rename to packages/server/src/modules/ItemCategories/ItemCategory.interfaces.ts diff --git a/packages/server-nest/src/modules/ItemCategories/ItemCategory.module.ts b/packages/server/src/modules/ItemCategories/ItemCategory.module.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/ItemCategory.module.ts rename to packages/server/src/modules/ItemCategories/ItemCategory.module.ts diff --git a/packages/server-nest/src/modules/ItemCategories/commands/CommandItemCategoryValidator.service.ts b/packages/server/src/modules/ItemCategories/commands/CommandItemCategoryValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/commands/CommandItemCategoryValidator.service.ts rename to packages/server/src/modules/ItemCategories/commands/CommandItemCategoryValidator.service.ts diff --git a/packages/server-nest/src/modules/ItemCategories/commands/CreateItemCategory.service.ts b/packages/server/src/modules/ItemCategories/commands/CreateItemCategory.service.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/commands/CreateItemCategory.service.ts rename to packages/server/src/modules/ItemCategories/commands/CreateItemCategory.service.ts diff --git a/packages/server-nest/src/modules/ItemCategories/commands/DeleteItemCategory.service.ts b/packages/server/src/modules/ItemCategories/commands/DeleteItemCategory.service.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/commands/DeleteItemCategory.service.ts rename to packages/server/src/modules/ItemCategories/commands/DeleteItemCategory.service.ts diff --git a/packages/server-nest/src/modules/ItemCategories/commands/EditItemCategory.service.ts b/packages/server/src/modules/ItemCategories/commands/EditItemCategory.service.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/commands/EditItemCategory.service.ts rename to packages/server/src/modules/ItemCategories/commands/EditItemCategory.service.ts diff --git a/packages/server-nest/src/modules/ItemCategories/constants.ts b/packages/server/src/modules/ItemCategories/constants.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/constants.ts rename to packages/server/src/modules/ItemCategories/constants.ts diff --git a/packages/server-nest/src/modules/ItemCategories/dtos/ItemCategory.dto.ts b/packages/server/src/modules/ItemCategories/dtos/ItemCategory.dto.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/dtos/ItemCategory.dto.ts rename to packages/server/src/modules/ItemCategories/dtos/ItemCategory.dto.ts diff --git a/packages/server-nest/src/modules/ItemCategories/models/ItemCategory.model.ts b/packages/server/src/modules/ItemCategories/models/ItemCategory.model.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/models/ItemCategory.model.ts rename to packages/server/src/modules/ItemCategories/models/ItemCategory.model.ts diff --git a/packages/server-nest/src/modules/ItemCategories/queries/GetItemCategories.service.ts b/packages/server/src/modules/ItemCategories/queries/GetItemCategories.service.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/queries/GetItemCategories.service.ts rename to packages/server/src/modules/ItemCategories/queries/GetItemCategories.service.ts diff --git a/packages/server-nest/src/modules/ItemCategories/queries/GetItemCategory.service.ts b/packages/server/src/modules/ItemCategories/queries/GetItemCategory.service.ts similarity index 100% rename from packages/server-nest/src/modules/ItemCategories/queries/GetItemCategory.service.ts rename to packages/server/src/modules/ItemCategories/queries/GetItemCategory.service.ts diff --git a/packages/server-nest/src/modules/Items/ActivateItem.service.ts b/packages/server/src/modules/Items/ActivateItem.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ActivateItem.service.ts rename to packages/server/src/modules/Items/ActivateItem.service.ts diff --git a/packages/server-nest/src/modules/Items/CreateItem.service.ts b/packages/server/src/modules/Items/CreateItem.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/CreateItem.service.ts rename to packages/server/src/modules/Items/CreateItem.service.ts diff --git a/packages/server-nest/src/modules/Items/DeleteItem.service.ts b/packages/server/src/modules/Items/DeleteItem.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/DeleteItem.service.ts rename to packages/server/src/modules/Items/DeleteItem.service.ts diff --git a/packages/server-nest/src/modules/Items/EditItem.service.ts b/packages/server/src/modules/Items/EditItem.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/EditItem.service.ts rename to packages/server/src/modules/Items/EditItem.service.ts diff --git a/packages/server-nest/src/modules/Items/GetItem.service.ts b/packages/server/src/modules/Items/GetItem.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/GetItem.service.ts rename to packages/server/src/modules/Items/GetItem.service.ts diff --git a/packages/server-nest/src/modules/Items/GetItems.service.ts b/packages/server/src/modules/Items/GetItems.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/GetItems.service.ts rename to packages/server/src/modules/Items/GetItems.service.ts diff --git a/packages/server-nest/src/modules/Items/InactivateItem.service.ts b/packages/server/src/modules/Items/InactivateItem.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/InactivateItem.service.ts rename to packages/server/src/modules/Items/InactivateItem.service.ts diff --git a/packages/server-nest/src/modules/Items/Item.controller.ts b/packages/server/src/modules/Items/Item.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Items/Item.controller.ts rename to packages/server/src/modules/Items/Item.controller.ts diff --git a/packages/server-nest/src/modules/Items/Item.schema.ts b/packages/server/src/modules/Items/Item.schema.ts similarity index 100% rename from packages/server-nest/src/modules/Items/Item.schema.ts rename to packages/server/src/modules/Items/Item.schema.ts diff --git a/packages/server-nest/src/modules/Items/Item.transformer.ts b/packages/server/src/modules/Items/Item.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Items/Item.transformer.ts rename to packages/server/src/modules/Items/Item.transformer.ts diff --git a/packages/server-nest/src/modules/Items/ItemBillsTransactions.transformer.ts b/packages/server/src/modules/Items/ItemBillsTransactions.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemBillsTransactions.transformer.ts rename to packages/server/src/modules/Items/ItemBillsTransactions.transformer.ts diff --git a/packages/server-nest/src/modules/Items/ItemEstimatesTransaction.transformer.ts b/packages/server/src/modules/Items/ItemEstimatesTransaction.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemEstimatesTransaction.transformer.ts rename to packages/server/src/modules/Items/ItemEstimatesTransaction.transformer.ts diff --git a/packages/server-nest/src/modules/Items/ItemInvoicesTransactions.transformer.ts b/packages/server/src/modules/Items/ItemInvoicesTransactions.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemInvoicesTransactions.transformer.ts rename to packages/server/src/modules/Items/ItemInvoicesTransactions.transformer.ts diff --git a/packages/server-nest/src/modules/Items/ItemReceiptsTransactions.transformer.ts b/packages/server/src/modules/Items/ItemReceiptsTransactions.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemReceiptsTransactions.transformer.ts rename to packages/server/src/modules/Items/ItemReceiptsTransactions.transformer.ts diff --git a/packages/server-nest/src/modules/Items/ItemTransactions.service.ts b/packages/server/src/modules/Items/ItemTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemTransactions.service.ts rename to packages/server/src/modules/Items/ItemTransactions.service.ts diff --git a/packages/server-nest/src/modules/Items/ItemValidator.service.ts b/packages/server/src/modules/Items/ItemValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemValidator.service.ts rename to packages/server/src/modules/Items/ItemValidator.service.ts diff --git a/packages/server-nest/src/modules/Items/Items.constants.ts b/packages/server/src/modules/Items/Items.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Items/Items.constants.ts rename to packages/server/src/modules/Items/Items.constants.ts diff --git a/packages/server-nest/src/modules/Items/Items.module.ts b/packages/server/src/modules/Items/Items.module.ts similarity index 100% rename from packages/server-nest/src/modules/Items/Items.module.ts rename to packages/server/src/modules/Items/Items.module.ts diff --git a/packages/server-nest/src/modules/Items/ItemsApplication.service.ts b/packages/server/src/modules/Items/ItemsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemsApplication.service.ts rename to packages/server/src/modules/Items/ItemsApplication.service.ts diff --git a/packages/server-nest/src/modules/Items/ItemsEntries.service.ts b/packages/server/src/modules/Items/ItemsEntries.service.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ItemsEntries.service.ts rename to packages/server/src/modules/Items/ItemsEntries.service.ts diff --git a/packages/server-nest/src/modules/Items/ServiceError.ts b/packages/server/src/modules/Items/ServiceError.ts similarity index 100% rename from packages/server-nest/src/modules/Items/ServiceError.ts rename to packages/server/src/modules/Items/ServiceError.ts diff --git a/packages/server-nest/src/modules/Items/dtos/Item.dto.ts b/packages/server/src/modules/Items/dtos/Item.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Items/dtos/Item.dto.ts rename to packages/server/src/modules/Items/dtos/Item.dto.ts diff --git a/packages/server-nest/src/modules/Items/events/ItemCreated.event.ts b/packages/server/src/modules/Items/events/ItemCreated.event.ts similarity index 100% rename from packages/server-nest/src/modules/Items/events/ItemCreated.event.ts rename to packages/server/src/modules/Items/events/ItemCreated.event.ts diff --git a/packages/server-nest/src/modules/Items/listeners/ItemCreated.listener.ts b/packages/server/src/modules/Items/listeners/ItemCreated.listener.ts similarity index 100% rename from packages/server-nest/src/modules/Items/listeners/ItemCreated.listener.ts rename to packages/server/src/modules/Items/listeners/ItemCreated.listener.ts diff --git a/packages/server-nest/src/modules/Items/models/Item.ts b/packages/server/src/modules/Items/models/Item.ts similarity index 100% rename from packages/server-nest/src/modules/Items/models/Item.ts rename to packages/server/src/modules/Items/models/Item.ts diff --git a/packages/server-nest/src/modules/Items/types/Items.types.ts b/packages/server/src/modules/Items/types/Items.types.ts similarity index 100% rename from packages/server-nest/src/modules/Items/types/Items.types.ts rename to packages/server/src/modules/Items/types/Items.types.ts diff --git a/packages/server-nest/src/modules/Ledger/JournalEntry.ts b/packages/server/src/modules/Ledger/JournalEntry.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/JournalEntry.ts rename to packages/server/src/modules/Ledger/JournalEntry.ts diff --git a/packages/server-nest/src/modules/Ledger/Ledger.module.ts b/packages/server/src/modules/Ledger/Ledger.module.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/Ledger.module.ts rename to packages/server/src/modules/Ledger/Ledger.module.ts diff --git a/packages/server-nest/src/modules/Ledger/Ledger.ts b/packages/server/src/modules/Ledger/Ledger.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/Ledger.ts rename to packages/server/src/modules/Ledger/Ledger.ts diff --git a/packages/server-nest/src/modules/Ledger/LedgerContactStorage.service.ts b/packages/server/src/modules/Ledger/LedgerContactStorage.service.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/LedgerContactStorage.service.ts rename to packages/server/src/modules/Ledger/LedgerContactStorage.service.ts diff --git a/packages/server-nest/src/modules/Ledger/LedgerEntriesStorage.service.ts b/packages/server/src/modules/Ledger/LedgerEntriesStorage.service.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/LedgerEntriesStorage.service.ts rename to packages/server/src/modules/Ledger/LedgerEntriesStorage.service.ts diff --git a/packages/server-nest/src/modules/Ledger/LedgerStorage.service.ts b/packages/server/src/modules/Ledger/LedgerStorage.service.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/LedgerStorage.service.ts rename to packages/server/src/modules/Ledger/LedgerStorage.service.ts diff --git a/packages/server-nest/src/modules/Ledger/LedgerStorageRevert.service.ts b/packages/server/src/modules/Ledger/LedgerStorageRevert.service.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/LedgerStorageRevert.service.ts rename to packages/server/src/modules/Ledger/LedgerStorageRevert.service.ts diff --git a/packages/server-nest/src/modules/Ledger/LedgetAccountStorage.service.ts b/packages/server/src/modules/Ledger/LedgetAccountStorage.service.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/LedgetAccountStorage.service.ts rename to packages/server/src/modules/Ledger/LedgetAccountStorage.service.ts diff --git a/packages/server-nest/src/modules/Ledger/types/Ledger.types.ts b/packages/server/src/modules/Ledger/types/Ledger.types.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/types/Ledger.types.ts rename to packages/server/src/modules/Ledger/types/Ledger.types.ts diff --git a/packages/server-nest/src/modules/Ledger/utils.ts b/packages/server/src/modules/Ledger/utils.ts similarity index 100% rename from packages/server-nest/src/modules/Ledger/utils.ts rename to packages/server/src/modules/Ledger/utils.ts diff --git a/packages/server-nest/src/modules/Loops/Loops.module.ts b/packages/server/src/modules/Loops/Loops.module.ts similarity index 100% rename from packages/server-nest/src/modules/Loops/Loops.module.ts rename to packages/server/src/modules/Loops/Loops.module.ts diff --git a/packages/server-nest/src/modules/Loops/LoopsEvents.subscriber.ts b/packages/server/src/modules/Loops/LoopsEvents.subscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Loops/LoopsEvents.subscriber.ts rename to packages/server/src/modules/Loops/LoopsEvents.subscriber.ts diff --git a/packages/server-nest/src/modules/Mail/Mail.constants.ts b/packages/server/src/modules/Mail/Mail.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Mail/Mail.constants.ts rename to packages/server/src/modules/Mail/Mail.constants.ts diff --git a/packages/server-nest/src/modules/Mail/Mail.module.ts b/packages/server/src/modules/Mail/Mail.module.ts similarity index 100% rename from packages/server-nest/src/modules/Mail/Mail.module.ts rename to packages/server/src/modules/Mail/Mail.module.ts diff --git a/packages/server-nest/src/modules/Mail/Mail.ts b/packages/server/src/modules/Mail/Mail.ts similarity index 100% rename from packages/server-nest/src/modules/Mail/Mail.ts rename to packages/server/src/modules/Mail/Mail.ts diff --git a/packages/server-nest/src/modules/Mail/Mail.types.ts b/packages/server/src/modules/Mail/Mail.types.ts similarity index 100% rename from packages/server-nest/src/modules/Mail/Mail.types.ts rename to packages/server/src/modules/Mail/Mail.types.ts diff --git a/packages/server-nest/src/modules/Mail/MailTransporter.service.ts b/packages/server/src/modules/Mail/MailTransporter.service.ts similarity index 100% rename from packages/server-nest/src/modules/Mail/MailTransporter.service.ts rename to packages/server/src/modules/Mail/MailTransporter.service.ts diff --git a/packages/server-nest/src/modules/MailNotification/ContactMailNotification.ts b/packages/server/src/modules/MailNotification/ContactMailNotification.ts similarity index 100% rename from packages/server-nest/src/modules/MailNotification/ContactMailNotification.ts rename to packages/server/src/modules/MailNotification/ContactMailNotification.ts diff --git a/packages/server-nest/src/modules/MailNotification/MailNotification.module.ts b/packages/server/src/modules/MailNotification/MailNotification.module.ts similarity index 100% rename from packages/server-nest/src/modules/MailNotification/MailNotification.module.ts rename to packages/server/src/modules/MailNotification/MailNotification.module.ts diff --git a/packages/server-nest/src/modules/MailNotification/MailNotification.types.ts b/packages/server/src/modules/MailNotification/MailNotification.types.ts similarity index 100% rename from packages/server-nest/src/modules/MailNotification/MailNotification.types.ts rename to packages/server/src/modules/MailNotification/MailNotification.types.ts diff --git a/packages/server-nest/src/modules/MailNotification/constants.ts b/packages/server/src/modules/MailNotification/constants.ts similarity index 100% rename from packages/server-nest/src/modules/MailNotification/constants.ts rename to packages/server/src/modules/MailNotification/constants.ts diff --git a/packages/server-nest/src/modules/MailNotification/utils.ts b/packages/server/src/modules/MailNotification/utils.ts similarity index 100% rename from packages/server-nest/src/modules/MailNotification/utils.ts rename to packages/server/src/modules/MailNotification/utils.ts diff --git a/packages/server-nest/src/modules/MailTenancy/MailTenancy.module.ts b/packages/server/src/modules/MailTenancy/MailTenancy.module.ts similarity index 100% rename from packages/server-nest/src/modules/MailTenancy/MailTenancy.module.ts rename to packages/server/src/modules/MailTenancy/MailTenancy.module.ts diff --git a/packages/server-nest/src/modules/MailTenancy/MailTenancy.service.ts b/packages/server/src/modules/MailTenancy/MailTenancy.service.ts similarity index 100% rename from packages/server-nest/src/modules/MailTenancy/MailTenancy.service.ts rename to packages/server/src/modules/MailTenancy/MailTenancy.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/ManualJournals.controller.ts b/packages/server/src/modules/ManualJournals/ManualJournals.controller.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/ManualJournals.controller.ts rename to packages/server/src/modules/ManualJournals/ManualJournals.controller.ts diff --git a/packages/server-nest/src/modules/ManualJournals/ManualJournals.module.ts b/packages/server/src/modules/ManualJournals/ManualJournals.module.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/ManualJournals.module.ts rename to packages/server/src/modules/ManualJournals/ManualJournals.module.ts diff --git a/packages/server-nest/src/modules/ManualJournals/ManualJournalsApplication.service.ts b/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/ManualJournalsApplication.service.ts rename to packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/AutoIncrementManualJournal.service.ts b/packages/server/src/modules/ManualJournals/commands/AutoIncrementManualJournal.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/AutoIncrementManualJournal.service.ts rename to packages/server/src/modules/ManualJournals/commands/AutoIncrementManualJournal.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/CommandManualJournalValidators.service.ts b/packages/server/src/modules/ManualJournals/commands/CommandManualJournalValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/CommandManualJournalValidators.service.ts rename to packages/server/src/modules/ManualJournals/commands/CommandManualJournalValidators.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/CreateManualJournal.service.ts b/packages/server/src/modules/ManualJournals/commands/CreateManualJournal.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/CreateManualJournal.service.ts rename to packages/server/src/modules/ManualJournals/commands/CreateManualJournal.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/DeleteManualJournal.service.ts b/packages/server/src/modules/ManualJournals/commands/DeleteManualJournal.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/DeleteManualJournal.service.ts rename to packages/server/src/modules/ManualJournals/commands/DeleteManualJournal.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/EditManualJournal.service.ts b/packages/server/src/modules/ManualJournals/commands/EditManualJournal.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/EditManualJournal.service.ts rename to packages/server/src/modules/ManualJournals/commands/EditManualJournal.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/ManualJournalExportable.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalExportable.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/ManualJournalExportable.ts rename to packages/server/src/modules/ManualJournals/commands/ManualJournalExportable.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/ManualJournalGL.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalGL.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/ManualJournalGL.ts rename to packages/server/src/modules/ManualJournals/commands/ManualJournalGL.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/ManualJournalGLEntries.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/ManualJournalGLEntries.ts rename to packages/server/src/modules/ManualJournals/commands/ManualJournalGLEntries.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/ManualJournalGLEntriesSubscriber.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/ManualJournalGLEntriesSubscriber.ts rename to packages/server/src/modules/ManualJournals/commands/ManualJournalGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/ManualJournalsImport.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalsImport.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/ManualJournalsImport.ts rename to packages/server/src/modules/ManualJournals/commands/ManualJournalsImport.ts diff --git a/packages/server-nest/src/modules/ManualJournals/commands/PublishManualJournal.service.ts b/packages/server/src/modules/ManualJournals/commands/PublishManualJournal.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/commands/PublishManualJournal.service.ts rename to packages/server/src/modules/ManualJournals/commands/PublishManualJournal.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/constants.ts b/packages/server/src/modules/ManualJournals/constants.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/constants.ts rename to packages/server/src/modules/ManualJournals/constants.ts diff --git a/packages/server-nest/src/modules/ManualJournals/dtos/ManualJournal.dto.ts b/packages/server/src/modules/ManualJournals/dtos/ManualJournal.dto.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/dtos/ManualJournal.dto.ts rename to packages/server/src/modules/ManualJournals/dtos/ManualJournal.dto.ts diff --git a/packages/server-nest/src/modules/ManualJournals/models/ManualJournal.ts b/packages/server/src/modules/ManualJournals/models/ManualJournal.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/models/ManualJournal.ts rename to packages/server/src/modules/ManualJournals/models/ManualJournal.ts diff --git a/packages/server-nest/src/modules/ManualJournals/models/ManualJournalEntry.ts b/packages/server/src/modules/ManualJournals/models/ManualJournalEntry.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/models/ManualJournalEntry.ts rename to packages/server/src/modules/ManualJournals/models/ManualJournalEntry.ts diff --git a/packages/server-nest/src/modules/ManualJournals/queries/GetManualJournal.service.ts b/packages/server/src/modules/ManualJournals/queries/GetManualJournal.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/queries/GetManualJournal.service.ts rename to packages/server/src/modules/ManualJournals/queries/GetManualJournal.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/queries/GetManualJournals.service.ts b/packages/server/src/modules/ManualJournals/queries/GetManualJournals.service.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/queries/GetManualJournals.service.ts rename to packages/server/src/modules/ManualJournals/queries/GetManualJournals.service.ts diff --git a/packages/server-nest/src/modules/ManualJournals/queries/ManualJournalTransformer.ts b/packages/server/src/modules/ManualJournals/queries/ManualJournalTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/queries/ManualJournalTransformer.ts rename to packages/server/src/modules/ManualJournals/queries/ManualJournalTransformer.ts diff --git a/packages/server-nest/src/modules/ManualJournals/types/ManualJournals.types.ts b/packages/server/src/modules/ManualJournals/types/ManualJournals.types.ts similarity index 100% rename from packages/server-nest/src/modules/ManualJournals/types/ManualJournals.types.ts rename to packages/server/src/modules/ManualJournals/types/ManualJournals.types.ts diff --git a/packages/server-nest/src/modules/Metable/MetableConfig.ts b/packages/server/src/modules/Metable/MetableConfig.ts similarity index 100% rename from packages/server-nest/src/modules/Metable/MetableConfig.ts rename to packages/server/src/modules/Metable/MetableConfig.ts diff --git a/packages/server-nest/src/modules/Metable/MetableModel.ts b/packages/server/src/modules/Metable/MetableModel.ts similarity index 100% rename from packages/server-nest/src/modules/Metable/MetableModel.ts rename to packages/server/src/modules/Metable/MetableModel.ts diff --git a/packages/server-nest/src/modules/Metable/MetableStore.ts b/packages/server/src/modules/Metable/MetableStore.ts similarity index 100% rename from packages/server-nest/src/modules/Metable/MetableStore.ts rename to packages/server/src/modules/Metable/MetableStore.ts diff --git a/packages/server-nest/src/modules/Metable/MetableStoreDB.ts b/packages/server/src/modules/Metable/MetableStoreDB.ts similarity index 100% rename from packages/server-nest/src/modules/Metable/MetableStoreDB.ts rename to packages/server/src/modules/Metable/MetableStoreDB.ts diff --git a/packages/server-nest/src/modules/Metable/types.ts b/packages/server/src/modules/Metable/types.ts similarity index 100% rename from packages/server-nest/src/modules/Metable/types.ts rename to packages/server/src/modules/Metable/types.ts diff --git a/packages/server-nest/src/modules/Organization/Organization.constants.ts b/packages/server/src/modules/Organization/Organization.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization.constants.ts rename to packages/server/src/modules/Organization/Organization.constants.ts diff --git a/packages/server-nest/src/modules/Organization/Organization.controller.ts b/packages/server/src/modules/Organization/Organization.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization.controller.ts rename to packages/server/src/modules/Organization/Organization.controller.ts diff --git a/packages/server-nest/src/modules/Organization/Organization.module.ts b/packages/server/src/modules/Organization/Organization.module.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization.module.ts rename to packages/server/src/modules/Organization/Organization.module.ts diff --git a/packages/server-nest/src/modules/Organization/Organization.types.ts b/packages/server/src/modules/Organization/Organization.types.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization.types.ts rename to packages/server/src/modules/Organization/Organization.types.ts diff --git a/packages/server-nest/src/modules/Organization/Organization.utils.ts b/packages/server/src/modules/Organization/Organization.utils.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization.utils.ts rename to packages/server/src/modules/Organization/Organization.utils.ts diff --git a/packages/server-nest/src/modules/Organization/Organization/OrganizationBaseCurrencyLocking.service.ts b/packages/server/src/modules/Organization/Organization/OrganizationBaseCurrencyLocking.service.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization/OrganizationBaseCurrencyLocking.service.ts rename to packages/server/src/modules/Organization/Organization/OrganizationBaseCurrencyLocking.service.ts diff --git a/packages/server-nest/src/modules/Organization/Organization/OrganizationUpgrade.ts b/packages/server/src/modules/Organization/Organization/OrganizationUpgrade.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization/OrganizationUpgrade.ts rename to packages/server/src/modules/Organization/Organization/OrganizationUpgrade.ts diff --git a/packages/server-nest/src/modules/Organization/Organization/_utils.ts b/packages/server/src/modules/Organization/Organization/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization/_utils.ts rename to packages/server/src/modules/Organization/Organization/_utils.ts diff --git a/packages/server-nest/src/modules/Organization/Organization/constants.ts b/packages/server/src/modules/Organization/Organization/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/Organization/constants.ts rename to packages/server/src/modules/Organization/Organization/constants.ts diff --git a/packages/server-nest/src/modules/Organization/commands/BuildOrganization.service.ts b/packages/server/src/modules/Organization/commands/BuildOrganization.service.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/commands/BuildOrganization.service.ts rename to packages/server/src/modules/Organization/commands/BuildOrganization.service.ts diff --git a/packages/server-nest/src/modules/Organization/commands/CommandOrganizationValidators.service.ts b/packages/server/src/modules/Organization/commands/CommandOrganizationValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/commands/CommandOrganizationValidators.service.ts rename to packages/server/src/modules/Organization/commands/CommandOrganizationValidators.service.ts diff --git a/packages/server-nest/src/modules/Organization/commands/UpdateOrganization.service.ts b/packages/server/src/modules/Organization/commands/UpdateOrganization.service.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/commands/UpdateOrganization.service.ts rename to packages/server/src/modules/Organization/commands/UpdateOrganization.service.ts diff --git a/packages/server-nest/src/modules/Organization/dtos/Organization.dto.ts b/packages/server/src/modules/Organization/dtos/Organization.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/dtos/Organization.dto.ts rename to packages/server/src/modules/Organization/dtos/Organization.dto.ts diff --git a/packages/server-nest/src/modules/Organization/processors/OrganizationBuild.processor.ts b/packages/server/src/modules/Organization/processors/OrganizationBuild.processor.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/processors/OrganizationBuild.processor.ts rename to packages/server/src/modules/Organization/processors/OrganizationBuild.processor.ts diff --git a/packages/server-nest/src/modules/Organization/queries/GetCurrentOrganization.service.ts b/packages/server/src/modules/Organization/queries/GetCurrentOrganization.service.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/queries/GetCurrentOrganization.service.ts rename to packages/server/src/modules/Organization/queries/GetCurrentOrganization.service.ts diff --git a/packages/server-nest/src/modules/Organization/queries/GetOrganizationBaseCurrencyLock.service.ts b/packages/server/src/modules/Organization/queries/GetOrganizationBaseCurrencyLock.service.ts similarity index 100% rename from packages/server-nest/src/modules/Organization/queries/GetOrganizationBaseCurrencyLock.service.ts rename to packages/server/src/modules/Organization/queries/GetOrganizationBaseCurrencyLock.service.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/CreateInvoiceCheckoutSession.ts b/packages/server/src/modules/PaymentLinks/CreateInvoiceCheckoutSession.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/CreateInvoiceCheckoutSession.ts rename to packages/server/src/modules/PaymentLinks/CreateInvoiceCheckoutSession.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/GetInvoicePaymentLinkMetadata.ts b/packages/server/src/modules/PaymentLinks/GetInvoicePaymentLinkMetadata.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/GetInvoicePaymentLinkMetadata.ts rename to packages/server/src/modules/PaymentLinks/GetInvoicePaymentLinkMetadata.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/GetPaymentLinkInvoicePdf.ts b/packages/server/src/modules/PaymentLinks/GetPaymentLinkInvoicePdf.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/GetPaymentLinkInvoicePdf.ts rename to packages/server/src/modules/PaymentLinks/GetPaymentLinkInvoicePdf.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/PaymentLinks.controller.ts b/packages/server/src/modules/PaymentLinks/PaymentLinks.controller.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/PaymentLinks.controller.ts rename to packages/server/src/modules/PaymentLinks/PaymentLinks.controller.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/PaymentLinks.module.ts b/packages/server/src/modules/PaymentLinks/PaymentLinks.module.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/PaymentLinks.module.ts rename to packages/server/src/modules/PaymentLinks/PaymentLinks.module.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/PaymentLinksApplication.ts b/packages/server/src/modules/PaymentLinks/PaymentLinksApplication.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/PaymentLinksApplication.ts rename to packages/server/src/modules/PaymentLinks/PaymentLinksApplication.ts diff --git a/packages/server-nest/src/modules/PaymentLinks/models/PaymentLink.ts b/packages/server/src/modules/PaymentLinks/models/PaymentLink.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentLinks/models/PaymentLink.ts rename to packages/server/src/modules/PaymentLinks/models/PaymentLink.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/PaymentReceived.application.ts b/packages/server/src/modules/PaymentReceived/PaymentReceived.application.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/PaymentReceived.application.ts rename to packages/server/src/modules/PaymentReceived/PaymentReceived.application.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/PaymentsReceived.controller.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.controller.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/PaymentsReceived.controller.ts rename to packages/server/src/modules/PaymentReceived/PaymentsReceived.controller.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/PaymentsReceived.module.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/PaymentsReceived.module.ts rename to packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts b/packages/server/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts rename to packages/server/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/DeletePaymentReceived.service.ts b/packages/server/src/modules/PaymentReceived/commands/DeletePaymentReceived.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/DeletePaymentReceived.service.ts rename to packages/server/src/modules/PaymentReceived/commands/DeletePaymentReceived.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts b/packages/server/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts rename to packages/server/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedDTOTransformer.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedDTOTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedDTOTransformer.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedDTOTransformer.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGL.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedGL.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGL.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedGL.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedIncrement.service.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedIncrement.service.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedIncrement.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedInvoiceSync.service.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedInvoiceSync.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedInvoiceSync.service.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedInvoiceSync.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedMailNotification.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedMailNotification.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedMailNotification.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedMailNotification.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedMailNotificationJob.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedMailNotificationJob.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedMailNotificationJob.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedMailNotificationJob.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedSmsNotify.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedSmsNotify.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedSmsNotify.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedSmsNotify.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts rename to packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/constants.ts b/packages/server/src/modules/PaymentReceived/constants.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/constants.ts rename to packages/server/src/modules/PaymentReceived/constants.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts b/packages/server/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts rename to packages/server/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/models/PaymentReceived.ts b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/models/PaymentReceived.ts rename to packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/models/PaymentReceivedEntry.ts b/packages/server/src/modules/PaymentReceived/models/PaymentReceivedEntry.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/models/PaymentReceivedEntry.ts rename to packages/server/src/modules/PaymentReceived/models/PaymentReceivedEntry.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/processors/PaymentReceivedMailNotification.processor.ts b/packages/server/src/modules/PaymentReceived/processors/PaymentReceivedMailNotification.processor.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/processors/PaymentReceivedMailNotification.processor.ts rename to packages/server/src/modules/PaymentReceived/processors/PaymentReceivedMailNotification.processor.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceived.service.ts b/packages/server/src/modules/PaymentReceived/queries/GetPaymentReceived.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceived.service.ts rename to packages/server/src/modules/PaymentReceived/queries/GetPaymentReceived.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceivedInvoices.service.ts b/packages/server/src/modules/PaymentReceived/queries/GetPaymentReceivedInvoices.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceivedInvoices.service.ts rename to packages/server/src/modules/PaymentReceived/queries/GetPaymentReceivedInvoices.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceivedPdf.service.ts b/packages/server/src/modules/PaymentReceived/queries/GetPaymentReceivedPdf.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceivedPdf.service.ts rename to packages/server/src/modules/PaymentReceived/queries/GetPaymentReceivedPdf.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceivedState.service.ts b/packages/server/src/modules/PaymentReceived/queries/GetPaymentReceivedState.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentReceivedState.service.ts rename to packages/server/src/modules/PaymentReceived/queries/GetPaymentReceivedState.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentsReceived.service.ts b/packages/server/src/modules/PaymentReceived/queries/GetPaymentsReceived.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/GetPaymentsReceived.service.ts rename to packages/server/src/modules/PaymentReceived/queries/GetPaymentsReceived.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts b/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts rename to packages/server/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/PaymentReceivedEntryTransformer.ts b/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedEntryTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/PaymentReceivedEntryTransformer.ts rename to packages/server/src/modules/PaymentReceived/queries/PaymentReceivedEntryTransformer.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/PaymentReceivedTransformer.ts b/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/PaymentReceivedTransformer.ts rename to packages/server/src/modules/PaymentReceived/queries/PaymentReceivedTransformer.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/queries/PaymentsReceivedPages.service.ts b/packages/server/src/modules/PaymentReceived/queries/PaymentsReceivedPages.service.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/queries/PaymentsReceivedPages.service.ts rename to packages/server/src/modules/PaymentReceived/queries/PaymentsReceivedPages.service.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedAutoIncrementSubscriber.ts b/packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedAutoIncrementSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedAutoIncrementSubscriber.ts rename to packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedAutoIncrementSubscriber.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedGLEntriesSubscriber.ts b/packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedGLEntriesSubscriber.ts rename to packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsNotificationSubscriber.ts b/packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsNotificationSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsNotificationSubscriber.ts rename to packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsNotificationSubscriber.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsSubscriber.ts b/packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsSubscriber.ts rename to packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedSmsSubscriber.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedSyncInvoices.ts b/packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedSyncInvoices.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/subscribers/PaymentReceivedSyncInvoices.ts rename to packages/server/src/modules/PaymentReceived/subscribers/PaymentReceivedSyncInvoices.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/types/PaymentReceived.types.ts b/packages/server/src/modules/PaymentReceived/types/PaymentReceived.types.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/types/PaymentReceived.types.ts rename to packages/server/src/modules/PaymentReceived/types/PaymentReceived.types.ts diff --git a/packages/server-nest/src/modules/PaymentReceived/utils.ts b/packages/server/src/modules/PaymentReceived/utils.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentReceived/utils.ts rename to packages/server/src/modules/PaymentReceived/utils.ts diff --git a/packages/server-nest/src/modules/PaymentServices/PaymentServices.controller.ts b/packages/server/src/modules/PaymentServices/PaymentServices.controller.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/PaymentServices.controller.ts rename to packages/server/src/modules/PaymentServices/PaymentServices.controller.ts diff --git a/packages/server-nest/src/modules/PaymentServices/PaymentServices.module.ts b/packages/server/src/modules/PaymentServices/PaymentServices.module.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/PaymentServices.module.ts rename to packages/server/src/modules/PaymentServices/PaymentServices.module.ts diff --git a/packages/server-nest/src/modules/PaymentServices/PaymentServicesApplication.ts b/packages/server/src/modules/PaymentServices/PaymentServicesApplication.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/PaymentServicesApplication.ts rename to packages/server/src/modules/PaymentServices/PaymentServicesApplication.ts diff --git a/packages/server-nest/src/modules/PaymentServices/commands/DeletePaymentMethodService.ts b/packages/server/src/modules/PaymentServices/commands/DeletePaymentMethodService.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/commands/DeletePaymentMethodService.ts rename to packages/server/src/modules/PaymentServices/commands/DeletePaymentMethodService.ts diff --git a/packages/server-nest/src/modules/PaymentServices/commands/EditPaymentMethodService.ts b/packages/server/src/modules/PaymentServices/commands/EditPaymentMethodService.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/commands/EditPaymentMethodService.ts rename to packages/server/src/modules/PaymentServices/commands/EditPaymentMethodService.ts diff --git a/packages/server-nest/src/modules/PaymentServices/models/PaymentIntegration.model.ts b/packages/server/src/modules/PaymentServices/models/PaymentIntegration.model.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/models/PaymentIntegration.model.ts rename to packages/server/src/modules/PaymentServices/models/PaymentIntegration.model.ts diff --git a/packages/server-nest/src/modules/PaymentServices/models/TransactionPaymentServiceEntry.model.ts b/packages/server/src/modules/PaymentServices/models/TransactionPaymentServiceEntry.model.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/models/TransactionPaymentServiceEntry.model.ts rename to packages/server/src/modules/PaymentServices/models/TransactionPaymentServiceEntry.model.ts diff --git a/packages/server-nest/src/modules/PaymentServices/queries/GetPaymentMethodsState.ts b/packages/server/src/modules/PaymentServices/queries/GetPaymentMethodsState.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/queries/GetPaymentMethodsState.ts rename to packages/server/src/modules/PaymentServices/queries/GetPaymentMethodsState.ts diff --git a/packages/server-nest/src/modules/PaymentServices/queries/GetPaymentService.ts b/packages/server/src/modules/PaymentServices/queries/GetPaymentService.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/queries/GetPaymentService.ts rename to packages/server/src/modules/PaymentServices/queries/GetPaymentService.ts diff --git a/packages/server-nest/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoice.ts b/packages/server/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoice.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoice.ts rename to packages/server/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoice.ts diff --git a/packages/server-nest/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoiceTransformer.ts b/packages/server/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoiceTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoiceTransformer.ts rename to packages/server/src/modules/PaymentServices/queries/GetPaymentServicesSpecificInvoiceTransformer.ts diff --git a/packages/server-nest/src/modules/PaymentServices/types.ts b/packages/server/src/modules/PaymentServices/types.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/types.ts rename to packages/server/src/modules/PaymentServices/types.ts diff --git a/packages/server-nest/src/modules/PaymentServices/utils.ts b/packages/server/src/modules/PaymentServices/utils.ts similarity index 100% rename from packages/server-nest/src/modules/PaymentServices/utils.ts rename to packages/server/src/modules/PaymentServices/utils.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/BrandingTemplateDTOTransformer.ts b/packages/server/src/modules/PdfTemplate/BrandingTemplateDTOTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/BrandingTemplateDTOTransformer.ts rename to packages/server/src/modules/PdfTemplate/BrandingTemplateDTOTransformer.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/GetPdfTemplateBrandingState.ts b/packages/server/src/modules/PdfTemplate/GetPdfTemplateBrandingState.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/GetPdfTemplateBrandingState.ts rename to packages/server/src/modules/PdfTemplate/GetPdfTemplateBrandingState.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/PdfTemplate.application.ts b/packages/server/src/modules/PdfTemplate/PdfTemplate.application.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/PdfTemplate.application.ts rename to packages/server/src/modules/PdfTemplate/PdfTemplate.application.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/PdfTemplates.controller.ts b/packages/server/src/modules/PdfTemplate/PdfTemplates.controller.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/PdfTemplates.controller.ts rename to packages/server/src/modules/PdfTemplate/PdfTemplates.controller.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/PdfTemplates.module.ts b/packages/server/src/modules/PdfTemplate/PdfTemplates.module.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/PdfTemplates.module.ts rename to packages/server/src/modules/PdfTemplate/PdfTemplates.module.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/commands/AssignPdfTemplateDefault.service.ts b/packages/server/src/modules/PdfTemplate/commands/AssignPdfTemplateDefault.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/commands/AssignPdfTemplateDefault.service.ts rename to packages/server/src/modules/PdfTemplate/commands/AssignPdfTemplateDefault.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/commands/CreatePdfTemplate.service.ts b/packages/server/src/modules/PdfTemplate/commands/CreatePdfTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/commands/CreatePdfTemplate.service.ts rename to packages/server/src/modules/PdfTemplate/commands/CreatePdfTemplate.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/commands/DeletePdfTemplate.service.ts b/packages/server/src/modules/PdfTemplate/commands/DeletePdfTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/commands/DeletePdfTemplate.service.ts rename to packages/server/src/modules/PdfTemplate/commands/DeletePdfTemplate.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/commands/EditPdfTemplate.service.ts b/packages/server/src/modules/PdfTemplate/commands/EditPdfTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/commands/EditPdfTemplate.service.ts rename to packages/server/src/modules/PdfTemplate/commands/EditPdfTemplate.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/dtos/PdfTemplate.dto.ts b/packages/server/src/modules/PdfTemplate/dtos/PdfTemplate.dto.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/dtos/PdfTemplate.dto.ts rename to packages/server/src/modules/PdfTemplate/dtos/PdfTemplate.dto.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/models/PdfTemplate.ts b/packages/server/src/modules/PdfTemplate/models/PdfTemplate.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/models/PdfTemplate.ts rename to packages/server/src/modules/PdfTemplate/models/PdfTemplate.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts b/packages/server/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts rename to packages/server/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplate.service.ts b/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplate.service.ts rename to packages/server/src/modules/PdfTemplate/queries/GetPdfTemplate.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplate.transformer.ts b/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplate.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplate.transformer.ts rename to packages/server/src/modules/PdfTemplate/queries/GetPdfTemplate.transformer.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplates.service.ts b/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplates.service.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplates.service.ts rename to packages/server/src/modules/PdfTemplate/queries/GetPdfTemplates.service.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplates.transformer.ts b/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplates.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/queries/GetPdfTemplates.transformer.ts rename to packages/server/src/modules/PdfTemplate/queries/GetPdfTemplates.transformer.ts diff --git a/packages/server-nest/src/modules/PdfTemplate/types.ts b/packages/server/src/modules/PdfTemplate/types.ts similarity index 100% rename from packages/server-nest/src/modules/PdfTemplate/types.ts rename to packages/server/src/modules/PdfTemplate/types.ts diff --git a/packages/server-nest/src/modules/Plaid/Plaid.module.ts b/packages/server/src/modules/Plaid/Plaid.module.ts similarity index 100% rename from packages/server-nest/src/modules/Plaid/Plaid.module.ts rename to packages/server/src/modules/Plaid/Plaid.module.ts diff --git a/packages/server-nest/src/modules/Resource/Resource.module.ts b/packages/server/src/modules/Resource/Resource.module.ts similarity index 100% rename from packages/server-nest/src/modules/Resource/Resource.module.ts rename to packages/server/src/modules/Resource/Resource.module.ts diff --git a/packages/server-nest/src/modules/Resource/ResourceService.ts b/packages/server/src/modules/Resource/ResourceService.ts similarity index 100% rename from packages/server-nest/src/modules/Resource/ResourceService.ts rename to packages/server/src/modules/Resource/ResourceService.ts diff --git a/packages/server-nest/src/modules/Resource/_utils.ts b/packages/server/src/modules/Resource/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/Resource/_utils.ts rename to packages/server/src/modules/Resource/_utils.ts diff --git a/packages/server-nest/src/modules/Resource/models/ResourcableModel.ts b/packages/server/src/modules/Resource/models/ResourcableModel.ts similarity index 100% rename from packages/server-nest/src/modules/Resource/models/ResourcableModel.ts rename to packages/server/src/modules/Resource/models/ResourcableModel.ts diff --git a/packages/server-nest/src/modules/Roles/AbilitySchema.ts b/packages/server/src/modules/Roles/AbilitySchema.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/AbilitySchema.ts rename to packages/server/src/modules/Roles/AbilitySchema.ts diff --git a/packages/server-nest/src/modules/Roles/Authorization.guard.ts b/packages/server/src/modules/Roles/Authorization.guard.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/Authorization.guard.ts rename to packages/server/src/modules/Roles/Authorization.guard.ts diff --git a/packages/server-nest/src/modules/Roles/Roles.application.ts b/packages/server/src/modules/Roles/Roles.application.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/Roles.application.ts rename to packages/server/src/modules/Roles/Roles.application.ts diff --git a/packages/server-nest/src/modules/Roles/Roles.controller.ts b/packages/server/src/modules/Roles/Roles.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/Roles.controller.ts rename to packages/server/src/modules/Roles/Roles.controller.ts diff --git a/packages/server-nest/src/modules/Roles/Roles.module.ts b/packages/server/src/modules/Roles/Roles.module.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/Roles.module.ts rename to packages/server/src/modules/Roles/Roles.module.ts diff --git a/packages/server-nest/src/modules/Roles/Roles.types.ts b/packages/server/src/modules/Roles/Roles.types.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/Roles.types.ts rename to packages/server/src/modules/Roles/Roles.types.ts diff --git a/packages/server-nest/src/modules/Roles/Roles.utils.ts b/packages/server/src/modules/Roles/Roles.utils.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/Roles.utils.ts rename to packages/server/src/modules/Roles/Roles.utils.ts diff --git a/packages/server-nest/src/modules/Roles/TenantAbilities.ts b/packages/server/src/modules/Roles/TenantAbilities.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/TenantAbilities.ts rename to packages/server/src/modules/Roles/TenantAbilities.ts diff --git a/packages/server-nest/src/modules/Roles/commands/CreateRole.service.ts b/packages/server/src/modules/Roles/commands/CreateRole.service.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/commands/CreateRole.service.ts rename to packages/server/src/modules/Roles/commands/CreateRole.service.ts diff --git a/packages/server-nest/src/modules/Roles/commands/DeleteRole.service.ts b/packages/server/src/modules/Roles/commands/DeleteRole.service.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/commands/DeleteRole.service.ts rename to packages/server/src/modules/Roles/commands/DeleteRole.service.ts diff --git a/packages/server-nest/src/modules/Roles/commands/EditRole.service.ts b/packages/server/src/modules/Roles/commands/EditRole.service.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/commands/EditRole.service.ts rename to packages/server/src/modules/Roles/commands/EditRole.service.ts diff --git a/packages/server-nest/src/modules/Roles/constants.ts b/packages/server/src/modules/Roles/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/constants.ts rename to packages/server/src/modules/Roles/constants.ts diff --git a/packages/server-nest/src/modules/Roles/dtos/Role.dto.ts b/packages/server/src/modules/Roles/dtos/Role.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/dtos/Role.dto.ts rename to packages/server/src/modules/Roles/dtos/Role.dto.ts diff --git a/packages/server-nest/src/modules/Roles/models/Role.model.ts b/packages/server/src/modules/Roles/models/Role.model.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/models/Role.model.ts rename to packages/server/src/modules/Roles/models/Role.model.ts diff --git a/packages/server-nest/src/modules/Roles/models/RolePermission.model.ts b/packages/server/src/modules/Roles/models/RolePermission.model.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/models/RolePermission.model.ts rename to packages/server/src/modules/Roles/models/RolePermission.model.ts diff --git a/packages/server-nest/src/modules/Roles/queries/GetRole.service.ts b/packages/server/src/modules/Roles/queries/GetRole.service.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/queries/GetRole.service.ts rename to packages/server/src/modules/Roles/queries/GetRole.service.ts diff --git a/packages/server-nest/src/modules/Roles/queries/GetRoles.service.ts b/packages/server/src/modules/Roles/queries/GetRoles.service.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/queries/GetRoles.service.ts rename to packages/server/src/modules/Roles/queries/GetRoles.service.ts diff --git a/packages/server-nest/src/modules/Roles/queries/RolePermissionsSchema.ts b/packages/server/src/modules/Roles/queries/RolePermissionsSchema.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/queries/RolePermissionsSchema.ts rename to packages/server/src/modules/Roles/queries/RolePermissionsSchema.ts diff --git a/packages/server-nest/src/modules/Roles/queries/RoleTransformer.ts b/packages/server/src/modules/Roles/queries/RoleTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/queries/RoleTransformer.ts rename to packages/server/src/modules/Roles/queries/RoleTransformer.ts diff --git a/packages/server-nest/src/modules/Roles/utils.ts b/packages/server/src/modules/Roles/utils.ts similarity index 100% rename from packages/server-nest/src/modules/Roles/utils.ts rename to packages/server/src/modules/Roles/utils.ts diff --git a/packages/server-nest/src/modules/S3/S3.module.ts b/packages/server/src/modules/S3/S3.module.ts similarity index 100% rename from packages/server-nest/src/modules/S3/S3.module.ts rename to packages/server/src/modules/S3/S3.module.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.application.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.application.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/SaleEstimates.application.ts rename to packages/server/src/modules/SaleEstimates/SaleEstimates.application.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.controller.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.controller.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/SaleEstimates.controller.ts rename to packages/server/src/modules/SaleEstimates/SaleEstimates.controller.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.module.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/SaleEstimates.module.ts rename to packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimatesExportable.ts b/packages/server/src/modules/SaleEstimates/SaleEstimatesExportable.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/SaleEstimatesExportable.ts rename to packages/server/src/modules/SaleEstimates/SaleEstimatesExportable.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimatesImportable.ts b/packages/server/src/modules/SaleEstimates/SaleEstimatesImportable.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/SaleEstimatesImportable.ts rename to packages/server/src/modules/SaleEstimates/SaleEstimatesImportable.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/ApproveSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/ApproveSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/ApproveSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/ApproveSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/ConvetSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/ConvetSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/ConvetSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/ConvetSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/DeleteSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/DeleteSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/DeleteSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/DeleteSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/DeliverSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/DeliverSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/DeliverSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/DeliverSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/RejectSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/RejectSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/RejectSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/RejectSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts b/packages/server/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts rename to packages/server/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateIncrement.service.ts b/packages/server/src/modules/SaleEstimates/commands/SaleEstimateIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateIncrement.service.ts rename to packages/server/src/modules/SaleEstimates/commands/SaleEstimateIncrement.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateSmsNotify.ts b/packages/server/src/modules/SaleEstimates/commands/SaleEstimateSmsNotify.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateSmsNotify.ts rename to packages/server/src/modules/SaleEstimates/commands/SaleEstimateSmsNotify.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateValidators.service.ts b/packages/server/src/modules/SaleEstimates/commands/SaleEstimateValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateValidators.service.ts rename to packages/server/src/modules/SaleEstimates/commands/SaleEstimateValidators.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SendSaleEstimateMail.ts b/packages/server/src/modules/SaleEstimates/commands/SendSaleEstimateMail.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/SendSaleEstimateMail.ts rename to packages/server/src/modules/SaleEstimates/commands/SendSaleEstimateMail.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SendSaleEstimateMailJob.ts b/packages/server/src/modules/SaleEstimates/commands/SendSaleEstimateMailJob.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/SendSaleEstimateMailJob.ts rename to packages/server/src/modules/SaleEstimates/commands/SendSaleEstimateMailJob.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/UnlinkConvertedSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/commands/UnlinkConvertedSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/commands/UnlinkConvertedSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/commands/UnlinkConvertedSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/constants.ts b/packages/server/src/modules/SaleEstimates/constants.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/constants.ts rename to packages/server/src/modules/SaleEstimates/constants.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts b/packages/server/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts rename to packages/server/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/models/SaleEstimate.ts b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/models/SaleEstimate.ts rename to packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/processes/SendSaleEstimateMail.process.ts b/packages/server/src/modules/SaleEstimates/processes/SendSaleEstimateMail.process.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/processes/SendSaleEstimateMail.process.ts rename to packages/server/src/modules/SaleEstimates/processes/SendSaleEstimateMail.process.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimate.service.ts b/packages/server/src/modules/SaleEstimates/queries/GetSaleEstimate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimate.service.ts rename to packages/server/src/modules/SaleEstimates/queries/GetSaleEstimate.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimatePdf.ts b/packages/server/src/modules/SaleEstimates/queries/GetSaleEstimatePdf.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimatePdf.ts rename to packages/server/src/modules/SaleEstimates/queries/GetSaleEstimatePdf.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimateState.service.ts b/packages/server/src/modules/SaleEstimates/queries/GetSaleEstimateState.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimateState.service.ts rename to packages/server/src/modules/SaleEstimates/queries/GetSaleEstimateState.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimates.service.ts b/packages/server/src/modules/SaleEstimates/queries/GetSaleEstimates.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/queries/GetSaleEstimates.service.ts rename to packages/server/src/modules/SaleEstimates/queries/GetSaleEstimates.service.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/queries/SaleEstimate.transformer.ts b/packages/server/src/modules/SaleEstimates/queries/SaleEstimate.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/queries/SaleEstimate.transformer.ts rename to packages/server/src/modules/SaleEstimates/queries/SaleEstimate.transformer.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts b/packages/server/src/modules/SaleEstimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts rename to packages/server/src/modules/SaleEstimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/types/SaleEstimates.types.ts b/packages/server/src/modules/SaleEstimates/types/SaleEstimates.types.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/types/SaleEstimates.types.ts rename to packages/server/src/modules/SaleEstimates/types/SaleEstimates.types.ts diff --git a/packages/server-nest/src/modules/SaleEstimates/utils.ts b/packages/server/src/modules/SaleEstimates/utils.ts similarity index 100% rename from packages/server-nest/src/modules/SaleEstimates/utils.ts rename to packages/server/src/modules/SaleEstimates/utils.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/InvoiceInventoryTransactions.ts b/packages/server/src/modules/SaleInvoices/InvoiceInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/InvoiceInventoryTransactions.ts rename to packages/server/src/modules/SaleInvoices/InvoiceInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/InvoicePaymentsGLRewrite.ts b/packages/server/src/modules/SaleInvoices/InvoicePaymentsGLRewrite.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/InvoicePaymentsGLRewrite.ts rename to packages/server/src/modules/SaleInvoices/InvoicePaymentsGLRewrite.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoice.types.ts b/packages/server/src/modules/SaleInvoices/SaleInvoice.types.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SaleInvoice.types.ts rename to packages/server/src/modules/SaleInvoices/SaleInvoice.types.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoiceCostGLEntries.ts b/packages/server/src/modules/SaleInvoices/SaleInvoiceCostGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SaleInvoiceCostGLEntries.ts rename to packages/server/src/modules/SaleInvoices/SaleInvoiceCostGLEntries.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoiceNotifyBySms.ts b/packages/server/src/modules/SaleInvoices/SaleInvoiceNotifyBySms.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SaleInvoiceNotifyBySms.ts rename to packages/server/src/modules/SaleInvoices/SaleInvoiceNotifyBySms.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.application.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.application.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SaleInvoices.application.ts rename to packages/server/src/modules/SaleInvoices/SaleInvoices.application.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.controller.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts rename to packages/server/src/modules/SaleInvoices/SaleInvoices.controller.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.module.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SaleInvoices.module.ts rename to packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/SalesInvoicesCost.ts b/packages/server/src/modules/SaleInvoices/SalesInvoicesCost.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/SalesInvoicesCost.ts rename to packages/server/src/modules/SaleInvoices/SalesInvoicesCost.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts b/packages/server/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts rename to packages/server/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceValidators.service.ts b/packages/server/src/modules/SaleInvoices/commands/CommandSaleInvoiceValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceValidators.service.ts rename to packages/server/src/modules/SaleInvoices/commands/CommandSaleInvoiceValidators.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts rename to packages/server/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/DeleteSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/commands/DeleteSaleInvoice.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/DeleteSaleInvoice.service.ts rename to packages/server/src/modules/SaleInvoices/commands/DeleteSaleInvoice.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/DeliverSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/commands/DeliverSaleInvoice.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/DeliverSaleInvoice.service.ts rename to packages/server/src/modules/SaleInvoices/commands/DeliverSaleInvoice.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts rename to packages/server/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/GenerateInvoicePaymentLink.service.ts b/packages/server/src/modules/SaleInvoices/commands/GenerateInvoicePaymentLink.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/GenerateInvoicePaymentLink.service.ts rename to packages/server/src/modules/SaleInvoices/commands/GenerateInvoicePaymentLink.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/GeneratePaymentLink.transformer.ts b/packages/server/src/modules/SaleInvoices/commands/GeneratePaymentLink.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/GeneratePaymentLink.transformer.ts rename to packages/server/src/modules/SaleInvoices/commands/GeneratePaymentLink.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SaleInvoiceIncrement.service.ts b/packages/server/src/modules/SaleInvoices/commands/SaleInvoiceIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SaleInvoiceIncrement.service.ts rename to packages/server/src/modules/SaleInvoices/commands/SaleInvoiceIncrement.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts b/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts rename to packages/server/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts b/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts rename to packages/server/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SendInvoiceInvoiceMailCommon.service.ts b/packages/server/src/modules/SaleInvoices/commands/SendInvoiceInvoiceMailCommon.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SendInvoiceInvoiceMailCommon.service.ts rename to packages/server/src/modules/SaleInvoices/commands/SendInvoiceInvoiceMailCommon.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SendSaleInvoiceMail.ts b/packages/server/src/modules/SaleInvoices/commands/SendSaleInvoiceMail.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SendSaleInvoiceMail.ts rename to packages/server/src/modules/SaleInvoices/commands/SendSaleInvoiceMail.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SendSaleInvoiceMailJob.ts b/packages/server/src/modules/SaleInvoices/commands/SendSaleInvoiceMailJob.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SendSaleInvoiceMailJob.ts rename to packages/server/src/modules/SaleInvoices/commands/SendSaleInvoiceMailJob.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/SendSaleInvoiceMailReminderJob.ts b/packages/server/src/modules/SaleInvoices/commands/SendSaleInvoiceMailReminderJob.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/SendSaleInvoiceMailReminderJob.ts rename to packages/server/src/modules/SaleInvoices/commands/SendSaleInvoiceMailReminderJob.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/WriteoffSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/commands/WriteoffSaleInvoice.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/WriteoffSaleInvoice.service.ts rename to packages/server/src/modules/SaleInvoices/commands/WriteoffSaleInvoice.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/inventory/InvoiceInventoryTransactions.ts b/packages/server/src/modules/SaleInvoices/commands/inventory/InvoiceInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/inventory/InvoiceInventoryTransactions.ts rename to packages/server/src/modules/SaleInvoices/commands/inventory/InvoiceInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGL.ts b/packages/server/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGL.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGL.ts rename to packages/server/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGL.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGLStorage.ts b/packages/server/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGLStorage.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGLStorage.ts rename to packages/server/src/modules/SaleInvoices/commands/writeoff/SaleInvoiceWriteoffGLStorage.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/constants.ts b/packages/server/src/modules/SaleInvoices/constants.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/constants.ts rename to packages/server/src/modules/SaleInvoices/constants.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts b/packages/server/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts rename to packages/server/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/ledger/InvoiceGL.ts b/packages/server/src/modules/SaleInvoices/ledger/InvoiceGL.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/ledger/InvoiceGL.ts rename to packages/server/src/modules/SaleInvoices/ledger/InvoiceGL.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/ledger/InvoiceGLEntries.ts b/packages/server/src/modules/SaleInvoices/ledger/InvoiceGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/ledger/InvoiceGLEntries.ts rename to packages/server/src/modules/SaleInvoices/ledger/InvoiceGLEntries.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/models/SaleInvoice.ts b/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/models/SaleInvoice.ts rename to packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/processors/SendSaleInvoiceMail.processor.ts b/packages/server/src/modules/SaleInvoices/processors/SendSaleInvoiceMail.processor.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/processors/SendSaleInvoiceMail.processor.ts rename to packages/server/src/modules/SaleInvoices/processors/SendSaleInvoiceMail.processor.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePaymentLink.transformer.ts b/packages/server/src/modules/SaleInvoices/queries/GetInvoicePaymentLink.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePaymentLink.transformer.ts rename to packages/server/src/modules/SaleInvoices/queries/GetInvoicePaymentLink.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePaymentMail.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetInvoicePaymentMail.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePaymentMail.service.ts rename to packages/server/src/modules/SaleInvoices/queries/GetInvoicePaymentMail.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePaymentMailAttributes.transformer.ts b/packages/server/src/modules/SaleInvoices/queries/GetInvoicePaymentMailAttributes.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePaymentMailAttributes.transformer.ts rename to packages/server/src/modules/SaleInvoices/queries/GetInvoicePaymentMailAttributes.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePayments.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetInvoicePayments.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetInvoicePayments.service.ts rename to packages/server/src/modules/SaleInvoices/queries/GetInvoicePayments.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceMailReminder.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceMailReminder.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceMailReminder.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceMailReminder.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.service.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.transformer.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.transformer.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceMailState.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceState.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceState.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoiceState.service.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoiceState.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoices.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoices.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoices.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoices.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoicesPayable.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoicesPayable.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/GetSaleInvoicesPayable.service.ts rename to packages/server/src/modules/SaleInvoices/queries/GetSaleInvoicesPayable.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/InvoicePaymentTransaction.transformer.ts b/packages/server/src/modules/SaleInvoices/queries/InvoicePaymentTransaction.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/InvoicePaymentTransaction.transformer.ts rename to packages/server/src/modules/SaleInvoices/queries/InvoicePaymentTransaction.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts b/packages/server/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts rename to packages/server/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoice.transformer.ts b/packages/server/src/modules/SaleInvoices/queries/SaleInvoice.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoice.transformer.ts rename to packages/server/src/modules/SaleInvoices/queries/SaleInvoice.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoicePdf.service.ts b/packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdf.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoicePdf.service.ts rename to packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdf.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts b/packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts rename to packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoiceTaxEntry.transformer.ts b/packages/server/src/modules/SaleInvoices/queries/SaleInvoiceTaxEntry.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/queries/SaleInvoiceTaxEntry.transformer.ts rename to packages/server/src/modules/SaleInvoices/queries/SaleInvoiceTaxEntry.transformer.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts b/packages/server/src/modules/SaleInvoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts rename to packages/server/src/modules/SaleInvoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceCostGLEntriesSubscriber.ts b/packages/server/src/modules/SaleInvoices/subscribers/InvoiceCostGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceCostGLEntriesSubscriber.ts rename to packages/server/src/modules/SaleInvoices/subscribers/InvoiceCostGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceGLEntriesSubscriber.ts b/packages/server/src/modules/SaleInvoices/subscribers/InvoiceGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceGLEntriesSubscriber.ts rename to packages/server/src/modules/SaleInvoices/subscribers/InvoiceGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts b/packages/server/src/modules/SaleInvoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts rename to packages/server/src/modules/SaleInvoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/InvoicePaymentIntegrationSubscriber.ts b/packages/server/src/modules/SaleInvoices/subscribers/InvoicePaymentIntegrationSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/InvoicePaymentIntegrationSubscriber.ts rename to packages/server/src/modules/SaleInvoices/subscribers/InvoicePaymentIntegrationSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceWriteInventoryTransactions.ts b/packages/server/src/modules/SaleInvoices/subscribers/InvoiceWriteInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/InvoiceWriteInventoryTransactions.ts rename to packages/server/src/modules/SaleInvoices/subscribers/InvoiceWriteInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/subscribers/SaleInvoiceWriteoffSubscriber.ts b/packages/server/src/modules/SaleInvoices/subscribers/SaleInvoiceWriteoffSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/subscribers/SaleInvoiceWriteoffSubscriber.ts rename to packages/server/src/modules/SaleInvoices/subscribers/SaleInvoiceWriteoffSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleInvoices/utils.ts b/packages/server/src/modules/SaleInvoices/utils.ts similarity index 100% rename from packages/server-nest/src/modules/SaleInvoices/utils.ts rename to packages/server/src/modules/SaleInvoices/utils.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/SaleReceiptApplication.service.ts b/packages/server/src/modules/SaleReceipts/SaleReceiptApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/SaleReceiptApplication.service.ts rename to packages/server/src/modules/SaleReceipts/SaleReceiptApplication.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/SaleReceipts.controller.ts b/packages/server/src/modules/SaleReceipts/SaleReceipts.controller.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/SaleReceipts.controller.ts rename to packages/server/src/modules/SaleReceipts/SaleReceipts.controller.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/SaleReceipts.module.ts b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/SaleReceipts.module.ts rename to packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/CloseSaleReceipt.service.ts b/packages/server/src/modules/SaleReceipts/commands/CloseSaleReceipt.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/CloseSaleReceipt.service.ts rename to packages/server/src/modules/SaleReceipts/commands/CloseSaleReceipt.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts b/packages/server/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts rename to packages/server/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/DeleteSaleReceipt.service.ts b/packages/server/src/modules/SaleReceipts/commands/DeleteSaleReceipt.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/DeleteSaleReceipt.service.ts rename to packages/server/src/modules/SaleReceipts/commands/DeleteSaleReceipt.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts b/packages/server/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts rename to packages/server/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptCostGLEntries.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptCostGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptCostGLEntries.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptCostGLEntries.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptIncrement.service.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptIncrement.service.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptIncrement.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptInventoryTransactions.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptInventoryTransactions.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptMailNotification.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptMailNotification.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptMailNotification.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptMailNotification.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptMailNotificationJob.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptMailNotificationJob.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptMailNotificationJob.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptMailNotificationJob.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptNotifyBySms.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptNotifyBySms.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptNotifyBySms.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptNotifyBySms.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptValidators.service.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptValidators.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptValidators.service.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptValidators.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptsImportable.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptsImportable.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptsImportable.ts rename to packages/server/src/modules/SaleReceipts/commands/SaleReceiptsImportable.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/constants.ts b/packages/server/src/modules/SaleReceipts/constants.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/constants.ts rename to packages/server/src/modules/SaleReceipts/constants.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts b/packages/server/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts rename to packages/server/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/inventory/SaleReceiptInventoryTransactions.ts b/packages/server/src/modules/SaleReceipts/inventory/SaleReceiptInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/inventory/SaleReceiptInventoryTransactions.ts rename to packages/server/src/modules/SaleReceipts/inventory/SaleReceiptInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/inventory/SaleReceiptWriteInventoryTransactions.ts b/packages/server/src/modules/SaleReceipts/inventory/SaleReceiptWriteInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/inventory/SaleReceiptWriteInventoryTransactions.ts rename to packages/server/src/modules/SaleReceipts/inventory/SaleReceiptWriteInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/ledger/SaleReceiptGL.ts b/packages/server/src/modules/SaleReceipts/ledger/SaleReceiptGL.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/ledger/SaleReceiptGL.ts rename to packages/server/src/modules/SaleReceipts/ledger/SaleReceiptGL.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/ledger/SaleReceiptGLEntries.ts b/packages/server/src/modules/SaleReceipts/ledger/SaleReceiptGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/ledger/SaleReceiptGLEntries.ts rename to packages/server/src/modules/SaleReceipts/ledger/SaleReceiptGLEntries.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/models/SaleReceipt.ts b/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/models/SaleReceipt.ts rename to packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/processes/SendSaleReceiptMail.process.ts b/packages/server/src/modules/SaleReceipts/processes/SendSaleReceiptMail.process.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/processes/SendSaleReceiptMail.process.ts rename to packages/server/src/modules/SaleReceipts/processes/SendSaleReceiptMail.process.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/queries/GetSaleReceipt.service.ts b/packages/server/src/modules/SaleReceipts/queries/GetSaleReceipt.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/queries/GetSaleReceipt.service.ts rename to packages/server/src/modules/SaleReceipts/queries/GetSaleReceipt.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/queries/GetSaleReceiptState.service.ts b/packages/server/src/modules/SaleReceipts/queries/GetSaleReceiptState.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/queries/GetSaleReceiptState.service.ts rename to packages/server/src/modules/SaleReceipts/queries/GetSaleReceiptState.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/queries/GetSaleReceipts.service.ts b/packages/server/src/modules/SaleReceipts/queries/GetSaleReceipts.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/queries/GetSaleReceipts.service.ts rename to packages/server/src/modules/SaleReceipts/queries/GetSaleReceipts.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/queries/SaleReceiptBrandingTemplate.service.ts b/packages/server/src/modules/SaleReceipts/queries/SaleReceiptBrandingTemplate.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/queries/SaleReceiptBrandingTemplate.service.ts rename to packages/server/src/modules/SaleReceipts/queries/SaleReceiptBrandingTemplate.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/queries/SaleReceiptTransformer.ts b/packages/server/src/modules/SaleReceipts/queries/SaleReceiptTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/queries/SaleReceiptTransformer.ts rename to packages/server/src/modules/SaleReceipts/queries/SaleReceiptTransformer.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/queries/SaleReceiptsPdf.service.ts b/packages/server/src/modules/SaleReceipts/queries/SaleReceiptsPdf.service.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/queries/SaleReceiptsPdf.service.ts rename to packages/server/src/modules/SaleReceipts/queries/SaleReceiptsPdf.service.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts b/packages/server/src/modules/SaleReceipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts rename to packages/server/src/modules/SaleReceipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/subscribers/SaleReceiptGLEntriesSubscriber.ts b/packages/server/src/modules/SaleReceipts/subscribers/SaleReceiptGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/subscribers/SaleReceiptGLEntriesSubscriber.ts rename to packages/server/src/modules/SaleReceipts/subscribers/SaleReceiptGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts b/packages/server/src/modules/SaleReceipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts rename to packages/server/src/modules/SaleReceipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/types/SaleReceipts.types.ts b/packages/server/src/modules/SaleReceipts/types/SaleReceipts.types.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/types/SaleReceipts.types.ts rename to packages/server/src/modules/SaleReceipts/types/SaleReceipts.types.ts diff --git a/packages/server-nest/src/modules/SaleReceipts/utils.ts b/packages/server/src/modules/SaleReceipts/utils.ts similarity index 100% rename from packages/server-nest/src/modules/SaleReceipts/utils.ts rename to packages/server/src/modules/SaleReceipts/utils.ts diff --git a/packages/server-nest/src/modules/Search/SearchableMdel.ts b/packages/server/src/modules/Search/SearchableMdel.ts similarity index 100% rename from packages/server-nest/src/modules/Search/SearchableMdel.ts rename to packages/server/src/modules/Search/SearchableMdel.ts diff --git a/packages/server-nest/src/modules/Settings/ModelSettings.ts b/packages/server/src/modules/Settings/ModelSettings.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/ModelSettings.ts rename to packages/server/src/modules/Settings/ModelSettings.ts diff --git a/packages/server-nest/src/modules/Settings/Settings.controller.ts b/packages/server/src/modules/Settings/Settings.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/Settings.controller.ts rename to packages/server/src/modules/Settings/Settings.controller.ts diff --git a/packages/server-nest/src/modules/Settings/Settings.module.ts b/packages/server/src/modules/Settings/Settings.module.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/Settings.module.ts rename to packages/server/src/modules/Settings/Settings.module.ts diff --git a/packages/server-nest/src/modules/Settings/Settings.types.ts b/packages/server/src/modules/Settings/Settings.types.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/Settings.types.ts rename to packages/server/src/modules/Settings/Settings.types.ts diff --git a/packages/server-nest/src/modules/Settings/SettingsApplication.service.ts b/packages/server/src/modules/Settings/SettingsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/SettingsApplication.service.ts rename to packages/server/src/modules/Settings/SettingsApplication.service.ts diff --git a/packages/server-nest/src/modules/Settings/SettingsStore.ts b/packages/server/src/modules/Settings/SettingsStore.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/SettingsStore.ts rename to packages/server/src/modules/Settings/SettingsStore.ts diff --git a/packages/server-nest/src/modules/Settings/commands/SaveSettings.service.ts b/packages/server/src/modules/Settings/commands/SaveSettings.service.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/commands/SaveSettings.service.ts rename to packages/server/src/modules/Settings/commands/SaveSettings.service.ts diff --git a/packages/server-nest/src/modules/Settings/models/Setting.ts b/packages/server/src/modules/Settings/models/Setting.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/models/Setting.ts rename to packages/server/src/modules/Settings/models/Setting.ts diff --git a/packages/server-nest/src/modules/Settings/queries/GetSettings.service.ts b/packages/server/src/modules/Settings/queries/GetSettings.service.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/queries/GetSettings.service.ts rename to packages/server/src/modules/Settings/queries/GetSettings.service.ts diff --git a/packages/server-nest/src/modules/Settings/repositories/Setting.repository.ts b/packages/server/src/modules/Settings/repositories/Setting.repository.ts similarity index 100% rename from packages/server-nest/src/modules/Settings/repositories/Setting.repository.ts rename to packages/server/src/modules/Settings/repositories/Setting.repository.ts diff --git a/packages/server-nest/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts b/packages/server/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts rename to packages/server/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts diff --git a/packages/server-nest/src/modules/StripePayment/CreateStripeAccountLink.ts b/packages/server/src/modules/StripePayment/CreateStripeAccountLink.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/CreateStripeAccountLink.ts rename to packages/server/src/modules/StripePayment/CreateStripeAccountLink.ts diff --git a/packages/server-nest/src/modules/StripePayment/CreateStripeAccountService.ts b/packages/server/src/modules/StripePayment/CreateStripeAccountService.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/CreateStripeAccountService.ts rename to packages/server/src/modules/StripePayment/CreateStripeAccountService.ts diff --git a/packages/server-nest/src/modules/StripePayment/ExchangeStripeOauthToken.ts b/packages/server/src/modules/StripePayment/ExchangeStripeOauthToken.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/ExchangeStripeOauthToken.ts rename to packages/server/src/modules/StripePayment/ExchangeStripeOauthToken.ts diff --git a/packages/server-nest/src/modules/StripePayment/GetStripeAuthorizationLink.ts b/packages/server/src/modules/StripePayment/GetStripeAuthorizationLink.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/GetStripeAuthorizationLink.ts rename to packages/server/src/modules/StripePayment/GetStripeAuthorizationLink.ts diff --git a/packages/server-nest/src/modules/StripePayment/StripePayment.controller.ts b/packages/server/src/modules/StripePayment/StripePayment.controller.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/StripePayment.controller.ts rename to packages/server/src/modules/StripePayment/StripePayment.controller.ts diff --git a/packages/server-nest/src/modules/StripePayment/StripePayment.module.ts b/packages/server/src/modules/StripePayment/StripePayment.module.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/StripePayment.module.ts rename to packages/server/src/modules/StripePayment/StripePayment.module.ts diff --git a/packages/server-nest/src/modules/StripePayment/StripePayment.types.ts b/packages/server/src/modules/StripePayment/StripePayment.types.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/StripePayment.types.ts rename to packages/server/src/modules/StripePayment/StripePayment.types.ts diff --git a/packages/server-nest/src/modules/StripePayment/StripePaymentApplication.ts b/packages/server/src/modules/StripePayment/StripePaymentApplication.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/StripePaymentApplication.ts rename to packages/server/src/modules/StripePayment/StripePaymentApplication.ts diff --git a/packages/server-nest/src/modules/StripePayment/StripePaymentService.ts b/packages/server/src/modules/StripePayment/StripePaymentService.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/StripePaymentService.ts rename to packages/server/src/modules/StripePayment/StripePaymentService.ts diff --git a/packages/server-nest/src/modules/StripePayment/models/PaymentIntegration.model.ts b/packages/server/src/modules/StripePayment/models/PaymentIntegration.model.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/models/PaymentIntegration.model.ts rename to packages/server/src/modules/StripePayment/models/PaymentIntegration.model.ts diff --git a/packages/server-nest/src/modules/StripePayment/subscribers/SeedStripeAccounts.ts b/packages/server/src/modules/StripePayment/subscribers/SeedStripeAccounts.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/subscribers/SeedStripeAccounts.ts rename to packages/server/src/modules/StripePayment/subscribers/SeedStripeAccounts.ts diff --git a/packages/server-nest/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts b/packages/server/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts rename to packages/server/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts diff --git a/packages/server-nest/src/modules/StripePayment/types.ts b/packages/server/src/modules/StripePayment/types.ts similarity index 100% rename from packages/server-nest/src/modules/StripePayment/types.ts rename to packages/server/src/modules/StripePayment/types.ts diff --git a/packages/server-nest/src/modules/Subscription/Subscription.module.ts b/packages/server/src/modules/Subscription/Subscription.module.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/Subscription.module.ts rename to packages/server/src/modules/Subscription/Subscription.module.ts diff --git a/packages/server-nest/src/modules/Subscription/SubscriptionApplication.ts b/packages/server/src/modules/Subscription/SubscriptionApplication.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/SubscriptionApplication.ts rename to packages/server/src/modules/Subscription/SubscriptionApplication.ts diff --git a/packages/server-nest/src/modules/Subscription/SubscriptionPeriod.ts b/packages/server/src/modules/Subscription/SubscriptionPeriod.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/SubscriptionPeriod.ts rename to packages/server/src/modules/Subscription/SubscriptionPeriod.ts diff --git a/packages/server-nest/src/modules/Subscription/Subscriptions.controller.ts b/packages/server/src/modules/Subscription/Subscriptions.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/Subscriptions.controller.ts rename to packages/server/src/modules/Subscription/Subscriptions.controller.ts diff --git a/packages/server-nest/src/modules/Subscription/SubscriptionsLemonWebhook.controller.ts b/packages/server/src/modules/Subscription/SubscriptionsLemonWebhook.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/SubscriptionsLemonWebhook.controller.ts rename to packages/server/src/modules/Subscription/SubscriptionsLemonWebhook.controller.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/CancelLemonSubscription.service.ts b/packages/server/src/modules/Subscription/commands/CancelLemonSubscription.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/CancelLemonSubscription.service.ts rename to packages/server/src/modules/Subscription/commands/CancelLemonSubscription.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/ChangeLemonSubscription.service.ts b/packages/server/src/modules/Subscription/commands/ChangeLemonSubscription.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/ChangeLemonSubscription.service.ts rename to packages/server/src/modules/Subscription/commands/ChangeLemonSubscription.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionCanceled.service.ts b/packages/server/src/modules/Subscription/commands/MarkSubscriptionCanceled.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionCanceled.service.ts rename to packages/server/src/modules/Subscription/commands/MarkSubscriptionCanceled.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionChanged.service.ts b/packages/server/src/modules/Subscription/commands/MarkSubscriptionChanged.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionChanged.service.ts rename to packages/server/src/modules/Subscription/commands/MarkSubscriptionChanged.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionPaymentFailed.service.ts b/packages/server/src/modules/Subscription/commands/MarkSubscriptionPaymentFailed.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionPaymentFailed.service.ts rename to packages/server/src/modules/Subscription/commands/MarkSubscriptionPaymentFailed.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionPaymentSuccessed.service.ts b/packages/server/src/modules/Subscription/commands/MarkSubscriptionPaymentSuccessed.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionPaymentSuccessed.service.ts rename to packages/server/src/modules/Subscription/commands/MarkSubscriptionPaymentSuccessed.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionResumed.sevice.ts b/packages/server/src/modules/Subscription/commands/MarkSubscriptionResumed.sevice.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/MarkSubscriptionResumed.sevice.ts rename to packages/server/src/modules/Subscription/commands/MarkSubscriptionResumed.sevice.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/NewSubscription.service.ts b/packages/server/src/modules/Subscription/commands/NewSubscription.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/NewSubscription.service.ts rename to packages/server/src/modules/Subscription/commands/NewSubscription.service.ts diff --git a/packages/server-nest/src/modules/Subscription/commands/ResumeLemonSubscription.service.ts b/packages/server/src/modules/Subscription/commands/ResumeLemonSubscription.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/commands/ResumeLemonSubscription.service.ts rename to packages/server/src/modules/Subscription/commands/ResumeLemonSubscription.service.ts diff --git a/packages/server-nest/src/modules/Subscription/exceptions/NotAllowedChangeSubscriptionPlan.ts b/packages/server/src/modules/Subscription/exceptions/NotAllowedChangeSubscriptionPlan.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/exceptions/NotAllowedChangeSubscriptionPlan.ts rename to packages/server/src/modules/Subscription/exceptions/NotAllowedChangeSubscriptionPlan.ts diff --git a/packages/server-nest/src/modules/Subscription/interceptors/Subscription.guard.ts b/packages/server/src/modules/Subscription/interceptors/Subscription.guard.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/interceptors/Subscription.guard.ts rename to packages/server/src/modules/Subscription/interceptors/Subscription.guard.ts diff --git a/packages/server-nest/src/modules/Subscription/models/Plan.ts b/packages/server/src/modules/Subscription/models/Plan.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/models/Plan.ts rename to packages/server/src/modules/Subscription/models/Plan.ts diff --git a/packages/server-nest/src/modules/Subscription/models/PlanSubscription.ts b/packages/server/src/modules/Subscription/models/PlanSubscription.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/models/PlanSubscription.ts rename to packages/server/src/modules/Subscription/models/PlanSubscription.ts diff --git a/packages/server-nest/src/modules/Subscription/queries/GetLemonSqueezyCheckout.service.ts b/packages/server/src/modules/Subscription/queries/GetLemonSqueezyCheckout.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/queries/GetLemonSqueezyCheckout.service.ts rename to packages/server/src/modules/Subscription/queries/GetLemonSqueezyCheckout.service.ts diff --git a/packages/server-nest/src/modules/Subscription/queries/GetSubscriptions.service.ts b/packages/server/src/modules/Subscription/queries/GetSubscriptions.service.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/queries/GetSubscriptions.service.ts rename to packages/server/src/modules/Subscription/queries/GetSubscriptions.service.ts diff --git a/packages/server-nest/src/modules/Subscription/queries/GetSubscriptionsTransformer.ts b/packages/server/src/modules/Subscription/queries/GetSubscriptionsTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/queries/GetSubscriptionsTransformer.ts rename to packages/server/src/modules/Subscription/queries/GetSubscriptionsTransformer.ts diff --git a/packages/server-nest/src/modules/Subscription/repositories/PlanSubscription.repository.ts b/packages/server/src/modules/Subscription/repositories/PlanSubscription.repository.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/repositories/PlanSubscription.repository.ts rename to packages/server/src/modules/Subscription/repositories/PlanSubscription.repository.ts diff --git a/packages/server-nest/src/modules/Subscription/subscribers/SubscribeFreeOnSignupCommunity.ts b/packages/server/src/modules/Subscription/subscribers/SubscribeFreeOnSignupCommunity.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/subscribers/SubscribeFreeOnSignupCommunity.ts rename to packages/server/src/modules/Subscription/subscribers/SubscribeFreeOnSignupCommunity.ts diff --git a/packages/server-nest/src/modules/Subscription/subscribers/TriggerInvalidateCacheOnSubscriptionChange.ts b/packages/server/src/modules/Subscription/subscribers/TriggerInvalidateCacheOnSubscriptionChange.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/subscribers/TriggerInvalidateCacheOnSubscriptionChange.ts rename to packages/server/src/modules/Subscription/subscribers/TriggerInvalidateCacheOnSubscriptionChange.ts diff --git a/packages/server-nest/src/modules/Subscription/types.ts b/packages/server/src/modules/Subscription/types.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/types.ts rename to packages/server/src/modules/Subscription/types.ts diff --git a/packages/server-nest/src/modules/Subscription/utils.ts b/packages/server/src/modules/Subscription/utils.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/utils.ts rename to packages/server/src/modules/Subscription/utils.ts diff --git a/packages/server-nest/src/modules/Subscription/webhooks/LemonSqueezyWebhooks.ts b/packages/server/src/modules/Subscription/webhooks/LemonSqueezyWebhooks.ts similarity index 100% rename from packages/server-nest/src/modules/Subscription/webhooks/LemonSqueezyWebhooks.ts rename to packages/server/src/modules/Subscription/webhooks/LemonSqueezyWebhooks.ts diff --git a/packages/server-nest/src/modules/System/SystemDB/SystemDB.constants.ts b/packages/server/src/modules/System/SystemDB/SystemDB.constants.ts similarity index 100% rename from packages/server-nest/src/modules/System/SystemDB/SystemDB.constants.ts rename to packages/server/src/modules/System/SystemDB/SystemDB.constants.ts diff --git a/packages/server-nest/src/modules/System/SystemDB/SystemDB.controller.ts b/packages/server/src/modules/System/SystemDB/SystemDB.controller.ts similarity index 100% rename from packages/server-nest/src/modules/System/SystemDB/SystemDB.controller.ts rename to packages/server/src/modules/System/SystemDB/SystemDB.controller.ts diff --git a/packages/server-nest/src/modules/System/SystemDB/SystemDB.module.ts b/packages/server/src/modules/System/SystemDB/SystemDB.module.ts similarity index 100% rename from packages/server-nest/src/modules/System/SystemDB/SystemDB.module.ts rename to packages/server/src/modules/System/SystemDB/SystemDB.module.ts diff --git a/packages/server-nest/src/modules/System/SystemModels/SystemModels.constants.ts b/packages/server/src/modules/System/SystemModels/SystemModels.constants.ts similarity index 100% rename from packages/server-nest/src/modules/System/SystemModels/SystemModels.constants.ts rename to packages/server/src/modules/System/SystemModels/SystemModels.constants.ts diff --git a/packages/server-nest/src/modules/System/SystemModels/SystemModels.module.ts b/packages/server/src/modules/System/SystemModels/SystemModels.module.ts similarity index 100% rename from packages/server-nest/src/modules/System/SystemModels/SystemModels.module.ts rename to packages/server/src/modules/System/SystemModels/SystemModels.module.ts diff --git a/packages/server-nest/src/modules/System/models/SystemModel.ts b/packages/server/src/modules/System/models/SystemModel.ts similarity index 100% rename from packages/server-nest/src/modules/System/models/SystemModel.ts rename to packages/server/src/modules/System/models/SystemModel.ts diff --git a/packages/server-nest/src/modules/System/models/SystemUser.ts b/packages/server/src/modules/System/models/SystemUser.ts similarity index 100% rename from packages/server-nest/src/modules/System/models/SystemUser.ts rename to packages/server/src/modules/System/models/SystemUser.ts diff --git a/packages/server-nest/src/modules/System/models/TenantBaseModel.ts b/packages/server/src/modules/System/models/TenantBaseModel.ts similarity index 100% rename from packages/server-nest/src/modules/System/models/TenantBaseModel.ts rename to packages/server/src/modules/System/models/TenantBaseModel.ts diff --git a/packages/server-nest/src/modules/System/models/TenantMetadataModel.ts b/packages/server/src/modules/System/models/TenantMetadataModel.ts similarity index 100% rename from packages/server-nest/src/modules/System/models/TenantMetadataModel.ts rename to packages/server/src/modules/System/models/TenantMetadataModel.ts diff --git a/packages/server-nest/src/modules/System/models/TenantModel.ts b/packages/server/src/modules/System/models/TenantModel.ts similarity index 100% rename from packages/server-nest/src/modules/System/models/TenantModel.ts rename to packages/server/src/modules/System/models/TenantModel.ts diff --git a/packages/server-nest/src/modules/System/repositories/Tenant.repository.ts b/packages/server/src/modules/System/repositories/Tenant.repository.ts similarity index 100% rename from packages/server-nest/src/modules/System/repositories/Tenant.repository.ts rename to packages/server/src/modules/System/repositories/Tenant.repository.ts diff --git a/packages/server-nest/src/modules/TaxRates/ItemEntriesTaxTransactions.service.ts b/packages/server/src/modules/TaxRates/ItemEntriesTaxTransactions.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/ItemEntriesTaxTransactions.service.ts rename to packages/server/src/modules/TaxRates/ItemEntriesTaxTransactions.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/SyncItemTaxRateOnEditTaxRate.ts b/packages/server/src/modules/TaxRates/SyncItemTaxRateOnEditTaxRate.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/SyncItemTaxRateOnEditTaxRate.ts rename to packages/server/src/modules/TaxRates/SyncItemTaxRateOnEditTaxRate.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRate.application.ts b/packages/server/src/modules/TaxRates/TaxRate.application.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRate.application.ts rename to packages/server/src/modules/TaxRates/TaxRate.application.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRate.controller.ts b/packages/server/src/modules/TaxRates/TaxRate.controller.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRate.controller.ts rename to packages/server/src/modules/TaxRates/TaxRate.controller.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRate.module.ts b/packages/server/src/modules/TaxRates/TaxRate.module.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRate.module.ts rename to packages/server/src/modules/TaxRates/TaxRate.module.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRates.types.ts b/packages/server/src/modules/TaxRates/TaxRates.types.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRates.types.ts rename to packages/server/src/modules/TaxRates/TaxRates.types.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRatesExportable.ts b/packages/server/src/modules/TaxRates/TaxRatesExportable.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRatesExportable.ts rename to packages/server/src/modules/TaxRates/TaxRatesExportable.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRatesImportable.SampleData.ts b/packages/server/src/modules/TaxRates/TaxRatesImportable.SampleData.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRatesImportable.SampleData.ts rename to packages/server/src/modules/TaxRates/TaxRatesImportable.SampleData.ts diff --git a/packages/server-nest/src/modules/TaxRates/TaxRatesImportable.ts b/packages/server/src/modules/TaxRates/TaxRatesImportable.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/TaxRatesImportable.ts rename to packages/server/src/modules/TaxRates/TaxRatesImportable.ts diff --git a/packages/server-nest/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts b/packages/server/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts rename to packages/server/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts diff --git a/packages/server-nest/src/modules/TaxRates/commands/ActivateTaxRate.service.ts b/packages/server/src/modules/TaxRates/commands/ActivateTaxRate.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/commands/ActivateTaxRate.service.ts rename to packages/server/src/modules/TaxRates/commands/ActivateTaxRate.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts b/packages/server/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts rename to packages/server/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/commands/CreateTaxRate.service.ts b/packages/server/src/modules/TaxRates/commands/CreateTaxRate.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/commands/CreateTaxRate.service.ts rename to packages/server/src/modules/TaxRates/commands/CreateTaxRate.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/commands/DeleteTaxRate.service.ts b/packages/server/src/modules/TaxRates/commands/DeleteTaxRate.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/commands/DeleteTaxRate.service.ts rename to packages/server/src/modules/TaxRates/commands/DeleteTaxRate.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/commands/EditTaxRate.service.ts b/packages/server/src/modules/TaxRates/commands/EditTaxRate.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/commands/EditTaxRate.service.ts rename to packages/server/src/modules/TaxRates/commands/EditTaxRate.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/commands/InactivateTaxRate.ts b/packages/server/src/modules/TaxRates/commands/InactivateTaxRate.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/commands/InactivateTaxRate.ts rename to packages/server/src/modules/TaxRates/commands/InactivateTaxRate.ts diff --git a/packages/server-nest/src/modules/TaxRates/constants.ts b/packages/server/src/modules/TaxRates/constants.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/constants.ts rename to packages/server/src/modules/TaxRates/constants.ts diff --git a/packages/server-nest/src/modules/TaxRates/dtos/TaxRate.dto.ts b/packages/server/src/modules/TaxRates/dtos/TaxRate.dto.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/dtos/TaxRate.dto.ts rename to packages/server/src/modules/TaxRates/dtos/TaxRate.dto.ts diff --git a/packages/server-nest/src/modules/TaxRates/models/TaxRate.model.ts b/packages/server/src/modules/TaxRates/models/TaxRate.model.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/models/TaxRate.model.ts rename to packages/server/src/modules/TaxRates/models/TaxRate.model.ts diff --git a/packages/server-nest/src/modules/TaxRates/models/TaxRateTransaction.model.ts b/packages/server/src/modules/TaxRates/models/TaxRateTransaction.model.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/models/TaxRateTransaction.model.ts rename to packages/server/src/modules/TaxRates/models/TaxRateTransaction.model.ts diff --git a/packages/server-nest/src/modules/TaxRates/queries/GetTaxRate.service.ts b/packages/server/src/modules/TaxRates/queries/GetTaxRate.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/queries/GetTaxRate.service.ts rename to packages/server/src/modules/TaxRates/queries/GetTaxRate.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/queries/GetTaxRates.service.ts b/packages/server/src/modules/TaxRates/queries/GetTaxRates.service.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/queries/GetTaxRates.service.ts rename to packages/server/src/modules/TaxRates/queries/GetTaxRates.service.ts diff --git a/packages/server-nest/src/modules/TaxRates/queries/TaxRate.transformer.ts b/packages/server/src/modules/TaxRates/queries/TaxRate.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/queries/TaxRate.transformer.ts rename to packages/server/src/modules/TaxRates/queries/TaxRate.transformer.ts diff --git a/packages/server-nest/src/modules/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts b/packages/server/src/modules/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts rename to packages/server/src/modules/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts diff --git a/packages/server-nest/src/modules/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts b/packages/server/src/modules/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts rename to packages/server/src/modules/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts diff --git a/packages/server-nest/src/modules/TaxRates/subscribers/SyncItemTaxRateOnEditTaxSubscriber.ts b/packages/server/src/modules/TaxRates/subscribers/SyncItemTaxRateOnEditTaxSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/subscribers/SyncItemTaxRateOnEditTaxSubscriber.ts rename to packages/server/src/modules/TaxRates/subscribers/SyncItemTaxRateOnEditTaxSubscriber.ts diff --git a/packages/server-nest/src/modules/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts b/packages/server/src/modules/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts rename to packages/server/src/modules/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts diff --git a/packages/server-nest/src/modules/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts b/packages/server/src/modules/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts rename to packages/server/src/modules/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts diff --git a/packages/server-nest/src/modules/TaxRates/utils.ts b/packages/server/src/modules/TaxRates/utils.ts similarity index 100% rename from packages/server-nest/src/modules/TaxRates/utils.ts rename to packages/server/src/modules/TaxRates/utils.ts diff --git a/packages/server-nest/src/modules/TemplateInjectable/TemplateInjectable.module.ts b/packages/server/src/modules/TemplateInjectable/TemplateInjectable.module.ts similarity index 100% rename from packages/server-nest/src/modules/TemplateInjectable/TemplateInjectable.module.ts rename to packages/server/src/modules/TemplateInjectable/TemplateInjectable.module.ts diff --git a/packages/server-nest/src/modules/TemplateInjectable/TemplateInjectable.service.ts b/packages/server/src/modules/TemplateInjectable/TemplateInjectable.service.ts similarity index 100% rename from packages/server-nest/src/modules/TemplateInjectable/TemplateInjectable.service.ts rename to packages/server/src/modules/TemplateInjectable/TemplateInjectable.service.ts diff --git a/packages/server-nest/src/modules/Tenancy/EnsureTenantIsInitialized.guard.ts b/packages/server/src/modules/Tenancy/EnsureTenantIsInitialized.guard.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/EnsureTenantIsInitialized.guard.ts rename to packages/server/src/modules/Tenancy/EnsureTenantIsInitialized.guard.ts diff --git a/packages/server-nest/src/modules/Tenancy/EnsureTenantIsSeeded.guards.ts b/packages/server/src/modules/Tenancy/EnsureTenantIsSeeded.guards.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/EnsureTenantIsSeeded.guards.ts rename to packages/server/src/modules/Tenancy/EnsureTenantIsSeeded.guards.ts diff --git a/packages/server-nest/src/modules/Tenancy/Tenancy.module.ts b/packages/server/src/modules/Tenancy/Tenancy.module.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/Tenancy.module.ts rename to packages/server/src/modules/Tenancy/Tenancy.module.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyCache/TenancyCache.module.ts b/packages/server/src/modules/Tenancy/TenancyCache/TenancyCache.module.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyCache/TenancyCache.module.ts rename to packages/server/src/modules/Tenancy/TenancyCache/TenancyCache.module.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyContext.service.ts b/packages/server/src/modules/Tenancy/TenancyContext.service.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyContext.service.ts rename to packages/server/src/modules/Tenancy/TenancyContext.service.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyDB/TenancyDB.constants.ts b/packages/server/src/modules/Tenancy/TenancyDB/TenancyDB.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyDB/TenancyDB.constants.ts rename to packages/server/src/modules/Tenancy/TenancyDB/TenancyDB.constants.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyDB/TenancyDB.module.ts b/packages/server/src/modules/Tenancy/TenancyDB/TenancyDB.module.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyDB/TenancyDB.module.ts rename to packages/server/src/modules/Tenancy/TenancyDB/TenancyDB.module.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyDB/TransactionsHooks.ts b/packages/server/src/modules/Tenancy/TenancyDB/TransactionsHooks.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyDB/TransactionsHooks.ts rename to packages/server/src/modules/Tenancy/TenancyDB/TransactionsHooks.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyDB/UnitOfWork.service.ts b/packages/server/src/modules/Tenancy/TenancyDB/UnitOfWork.service.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyDB/UnitOfWork.service.ts rename to packages/server/src/modules/Tenancy/TenancyDB/UnitOfWork.service.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyGlobal.guard.ts b/packages/server/src/modules/Tenancy/TenancyGlobal.guard.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyGlobal.guard.ts rename to packages/server/src/modules/Tenancy/TenancyGlobal.guard.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.constants.ts b/packages/server/src/modules/Tenancy/TenancyModels/Tenancy.constants.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.constants.ts rename to packages/server/src/modules/Tenancy/TenancyModels/Tenancy.constants.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.module.ts b/packages/server/src/modules/Tenancy/TenancyModels/Tenancy.module.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.module.ts rename to packages/server/src/modules/Tenancy/TenancyModels/Tenancy.module.ts diff --git a/packages/server-nest/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts b/packages/server/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts rename to packages/server/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts diff --git a/packages/server-nest/src/modules/Tenancy/Tenant.controller.ts b/packages/server/src/modules/Tenancy/Tenant.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Tenancy/Tenant.controller.ts rename to packages/server/src/modules/Tenancy/Tenant.controller.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/TenantDBManager.module.ts b/packages/server/src/modules/TenantDBManager/TenantDBManager.module.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/TenantDBManager.module.ts rename to packages/server/src/modules/TenantDBManager/TenantDBManager.module.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/TenantDBManager.ts b/packages/server/src/modules/TenantDBManager/TenantDBManager.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/TenantDBManager.ts rename to packages/server/src/modules/TenantDBManager/TenantDBManager.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/TenantsManager.ts b/packages/server/src/modules/TenantDBManager/TenantsManager.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/TenantsManager.ts rename to packages/server/src/modules/TenantDBManager/TenantsManager.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/_utils.ts b/packages/server/src/modules/TenantDBManager/_utils.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/_utils.ts rename to packages/server/src/modules/TenantDBManager/_utils.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/exceptions/TenantAlreadyInitialized.ts b/packages/server/src/modules/TenantDBManager/exceptions/TenantAlreadyInitialized.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/exceptions/TenantAlreadyInitialized.ts rename to packages/server/src/modules/TenantDBManager/exceptions/TenantAlreadyInitialized.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/exceptions/TenantAlreadySeeded.ts b/packages/server/src/modules/TenantDBManager/exceptions/TenantAlreadySeeded.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/exceptions/TenantAlreadySeeded.ts rename to packages/server/src/modules/TenantDBManager/exceptions/TenantAlreadySeeded.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/exceptions/TenantDBAlreadyExists.ts b/packages/server/src/modules/TenantDBManager/exceptions/TenantDBAlreadyExists.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/exceptions/TenantDBAlreadyExists.ts rename to packages/server/src/modules/TenantDBManager/exceptions/TenantDBAlreadyExists.ts diff --git a/packages/server-nest/src/modules/TenantDBManager/exceptions/TenantDatabaseNotBuilt.ts b/packages/server/src/modules/TenantDBManager/exceptions/TenantDatabaseNotBuilt.ts similarity index 100% rename from packages/server-nest/src/modules/TenantDBManager/exceptions/TenantDatabaseNotBuilt.ts rename to packages/server/src/modules/TenantDBManager/exceptions/TenantDatabaseNotBuilt.ts diff --git a/packages/server-nest/src/modules/TransactionItemEntry/ItemEntry.transformer.ts b/packages/server/src/modules/TransactionItemEntry/ItemEntry.transformer.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionItemEntry/ItemEntry.transformer.ts rename to packages/server/src/modules/TransactionItemEntry/ItemEntry.transformer.ts diff --git a/packages/server-nest/src/modules/TransactionItemEntry/ItemEntry.types.ts b/packages/server/src/modules/TransactionItemEntry/ItemEntry.types.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionItemEntry/ItemEntry.types.ts rename to packages/server/src/modules/TransactionItemEntry/ItemEntry.types.ts diff --git a/packages/server-nest/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts b/packages/server/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts rename to packages/server/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts diff --git a/packages/server-nest/src/modules/TransactionItemEntry/models/ItemEntry.ts b/packages/server/src/modules/TransactionItemEntry/models/ItemEntry.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionItemEntry/models/ItemEntry.ts rename to packages/server/src/modules/TransactionItemEntry/models/ItemEntry.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.controller.ts b/packages/server/src/modules/TransactionsLocking/TransactionsLocking.controller.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.controller.ts rename to packages/server/src/modules/TransactionsLocking/TransactionsLocking.controller.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.module.ts b/packages/server/src/modules/TransactionsLocking/TransactionsLocking.module.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.module.ts rename to packages/server/src/modules/TransactionsLocking/TransactionsLocking.module.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/TransactionsLockingRepository.ts b/packages/server/src/modules/TransactionsLocking/TransactionsLockingRepository.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/TransactionsLockingRepository.ts rename to packages/server/src/modules/TransactionsLocking/TransactionsLockingRepository.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts b/packages/server/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts rename to packages/server/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/constants.ts b/packages/server/src/modules/TransactionsLocking/constants.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/constants.ts rename to packages/server/src/modules/TransactionsLocking/constants.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts b/packages/server/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts rename to packages/server/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/guards/FinancialTransactionLockingGuard.ts b/packages/server/src/modules/TransactionsLocking/guards/FinancialTransactionLockingGuard.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/guards/FinancialTransactionLockingGuard.ts rename to packages/server/src/modules/TransactionsLocking/guards/FinancialTransactionLockingGuard.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/guards/PurchasesTransactionLockingGuard.ts b/packages/server/src/modules/TransactionsLocking/guards/PurchasesTransactionLockingGuard.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/guards/PurchasesTransactionLockingGuard.ts rename to packages/server/src/modules/TransactionsLocking/guards/PurchasesTransactionLockingGuard.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/guards/SalesTransactionLockingGuard.ts b/packages/server/src/modules/TransactionsLocking/guards/SalesTransactionLockingGuard.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/guards/SalesTransactionLockingGuard.ts rename to packages/server/src/modules/TransactionsLocking/guards/SalesTransactionLockingGuard.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/guards/TransactionsLockingGuard.ts b/packages/server/src/modules/TransactionsLocking/guards/TransactionsLockingGuard.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/guards/TransactionsLockingGuard.ts rename to packages/server/src/modules/TransactionsLocking/guards/TransactionsLockingGuard.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/queries/QueryTransactionsLocking.ts b/packages/server/src/modules/TransactionsLocking/queries/QueryTransactionsLocking.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/queries/QueryTransactionsLocking.ts rename to packages/server/src/modules/TransactionsLocking/queries/QueryTransactionsLocking.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/queries/TransactionsLockingMetaTransformer.ts b/packages/server/src/modules/TransactionsLocking/queries/TransactionsLockingMetaTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/queries/TransactionsLockingMetaTransformer.ts rename to packages/server/src/modules/TransactionsLocking/queries/TransactionsLockingMetaTransformer.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/subscribers/FinancialsTransactionLockingGuardSubscriber.ts b/packages/server/src/modules/TransactionsLocking/subscribers/FinancialsTransactionLockingGuardSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/subscribers/FinancialsTransactionLockingGuardSubscriber.ts rename to packages/server/src/modules/TransactionsLocking/subscribers/FinancialsTransactionLockingGuardSubscriber.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/subscribers/PurchasesTransactionLockingGuardSubscriber.ts b/packages/server/src/modules/TransactionsLocking/subscribers/PurchasesTransactionLockingGuardSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/subscribers/PurchasesTransactionLockingGuardSubscriber.ts rename to packages/server/src/modules/TransactionsLocking/subscribers/PurchasesTransactionLockingGuardSubscriber.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/subscribers/SalesTransactionLockingGuardSubscriber.ts b/packages/server/src/modules/TransactionsLocking/subscribers/SalesTransactionLockingGuardSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/subscribers/SalesTransactionLockingGuardSubscriber.ts rename to packages/server/src/modules/TransactionsLocking/subscribers/SalesTransactionLockingGuardSubscriber.ts diff --git a/packages/server-nest/src/modules/TransactionsLocking/types/TransactionsLocking.types.ts b/packages/server/src/modules/TransactionsLocking/types/TransactionsLocking.types.ts similarity index 100% rename from packages/server-nest/src/modules/TransactionsLocking/types/TransactionsLocking.types.ts rename to packages/server/src/modules/TransactionsLocking/types/TransactionsLocking.types.ts diff --git a/packages/server-nest/src/modules/Transformer/Transformer.module.ts b/packages/server/src/modules/Transformer/Transformer.module.ts similarity index 100% rename from packages/server-nest/src/modules/Transformer/Transformer.module.ts rename to packages/server/src/modules/Transformer/Transformer.module.ts diff --git a/packages/server-nest/src/modules/Transformer/Transformer.ts b/packages/server/src/modules/Transformer/Transformer.ts similarity index 100% rename from packages/server-nest/src/modules/Transformer/Transformer.ts rename to packages/server/src/modules/Transformer/Transformer.ts diff --git a/packages/server-nest/src/modules/Transformer/Transformer.types.ts b/packages/server/src/modules/Transformer/Transformer.types.ts similarity index 100% rename from packages/server-nest/src/modules/Transformer/Transformer.types.ts rename to packages/server/src/modules/Transformer/Transformer.types.ts diff --git a/packages/server-nest/src/modules/Transformer/TransformerInjectable.service.ts b/packages/server/src/modules/Transformer/TransformerInjectable.service.ts similarity index 100% rename from packages/server-nest/src/modules/Transformer/TransformerInjectable.service.ts rename to packages/server/src/modules/Transformer/TransformerInjectable.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/VendorCredits.controller.ts b/packages/server/src/modules/VendorCredit/VendorCredits.controller.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/VendorCredits.controller.ts rename to packages/server/src/modules/VendorCredit/VendorCredits.controller.ts diff --git a/packages/server-nest/src/modules/VendorCredit/VendorCredits.module.ts b/packages/server/src/modules/VendorCredit/VendorCredits.module.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/VendorCredits.module.ts rename to packages/server/src/modules/VendorCredit/VendorCredits.module.ts diff --git a/packages/server-nest/src/modules/VendorCredit/VendorCreditsApplication.service.ts b/packages/server/src/modules/VendorCredit/VendorCreditsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/VendorCreditsApplication.service.ts rename to packages/server/src/modules/VendorCredit/VendorCreditsApplication.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts b/packages/server/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts rename to packages/server/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/DeleteVendorCredit.service.ts b/packages/server/src/modules/VendorCredit/commands/DeleteVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/DeleteVendorCredit.service.ts rename to packages/server/src/modules/VendorCredit/commands/DeleteVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/EditVendorCredit.service.ts b/packages/server/src/modules/VendorCredit/commands/EditVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/EditVendorCredit.service.ts rename to packages/server/src/modules/VendorCredit/commands/EditVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/OpenVendorCredit.service.ts b/packages/server/src/modules/VendorCredit/commands/OpenVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/OpenVendorCredit.service.ts rename to packages/server/src/modules/VendorCredit/commands/OpenVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditAutoIncrement.service.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditAutoIncrement.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditAutoIncrement.service.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditAutoIncrement.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditGL.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditGL.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditGL.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditGL.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditGLEntries.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditGLEntries.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditGLEntries.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditInventoryTransactions.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditInventoryTransactions.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditsExportable.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditsExportable.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditsExportable.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditsExportable.ts diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditsImportable.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditsImportable.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/commands/VendorCreditsImportable.ts rename to packages/server/src/modules/VendorCredit/commands/VendorCreditsImportable.ts diff --git a/packages/server-nest/src/modules/VendorCredit/constants.ts b/packages/server/src/modules/VendorCredit/constants.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/constants.ts rename to packages/server/src/modules/VendorCredit/constants.ts diff --git a/packages/server-nest/src/modules/VendorCredit/dtos/VendorCredit.dto.ts b/packages/server/src/modules/VendorCredit/dtos/VendorCredit.dto.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/dtos/VendorCredit.dto.ts rename to packages/server/src/modules/VendorCredit/dtos/VendorCredit.dto.ts diff --git a/packages/server-nest/src/modules/VendorCredit/models/VendorCredit.ts b/packages/server/src/modules/VendorCredit/models/VendorCredit.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/models/VendorCredit.ts rename to packages/server/src/modules/VendorCredit/models/VendorCredit.ts diff --git a/packages/server-nest/src/modules/VendorCredit/queries/GetVendorCredit.service.ts b/packages/server/src/modules/VendorCredit/queries/GetVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/queries/GetVendorCredit.service.ts rename to packages/server/src/modules/VendorCredit/queries/GetVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/queries/GetVendorCredits.service.ts b/packages/server/src/modules/VendorCredit/queries/GetVendorCredits.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/queries/GetVendorCredits.service.ts rename to packages/server/src/modules/VendorCredit/queries/GetVendorCredits.service.ts diff --git a/packages/server-nest/src/modules/VendorCredit/queries/VendorCreditTransformer.ts b/packages/server/src/modules/VendorCredit/queries/VendorCreditTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/queries/VendorCreditTransformer.ts rename to packages/server/src/modules/VendorCredit/queries/VendorCreditTransformer.ts diff --git a/packages/server-nest/src/modules/VendorCredit/subscribers/DeleteVendorAssociatedVendorCredit.ts b/packages/server/src/modules/VendorCredit/subscribers/DeleteVendorAssociatedVendorCredit.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/subscribers/DeleteVendorAssociatedVendorCredit.ts rename to packages/server/src/modules/VendorCredit/subscribers/DeleteVendorAssociatedVendorCredit.ts diff --git a/packages/server-nest/src/modules/VendorCredit/subscribers/RefundSyncVendorCreditBalanceSubscriber.ts b/packages/server/src/modules/VendorCredit/subscribers/RefundSyncVendorCreditBalanceSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/subscribers/RefundSyncVendorCreditBalanceSubscriber.ts rename to packages/server/src/modules/VendorCredit/subscribers/RefundSyncVendorCreditBalanceSubscriber.ts diff --git a/packages/server-nest/src/modules/VendorCredit/subscribers/RefundVendorCreditGLEntriesSubscriber.ts b/packages/server/src/modules/VendorCredit/subscribers/RefundVendorCreditGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/subscribers/RefundVendorCreditGLEntriesSubscriber.ts rename to packages/server/src/modules/VendorCredit/subscribers/RefundVendorCreditGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/VendorCredit/subscribers/VendorCreditAutoSerialSubscriber.ts b/packages/server/src/modules/VendorCredit/subscribers/VendorCreditAutoSerialSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/subscribers/VendorCreditAutoSerialSubscriber.ts rename to packages/server/src/modules/VendorCredit/subscribers/VendorCreditAutoSerialSubscriber.ts diff --git a/packages/server-nest/src/modules/VendorCredit/subscribers/VendorCreditGLEntriesSubscriber.ts b/packages/server/src/modules/VendorCredit/subscribers/VendorCreditGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/subscribers/VendorCreditGLEntriesSubscriber.ts rename to packages/server/src/modules/VendorCredit/subscribers/VendorCreditGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts b/packages/server/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts rename to packages/server/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts diff --git a/packages/server-nest/src/modules/VendorCredit/types/VendorCredit.types.ts b/packages/server/src/modules/VendorCredit/types/VendorCredit.types.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCredit/types/VendorCredit.types.ts rename to packages/server/src/modules/VendorCredit/types/VendorCredit.types.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.controller.ts b/packages/server/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.controller.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.controller.ts rename to packages/server/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.controller.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.module.ts b/packages/server/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.module.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.module.ts rename to packages/server/src/modules/VendorCreditsApplyBills/VendorCreditApplyBills.module.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditApplyBillsApplication.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/VendorCreditApplyBillsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditApplyBillsApplication.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/VendorCreditApplyBillsApplication.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditsApplyBills.constants.ts b/packages/server/src/modules/VendorCreditsApplyBills/VendorCreditsApplyBills.constants.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/VendorCreditsApplyBills.constants.ts rename to packages/server/src/modules/VendorCreditsApplyBills/VendorCreditsApplyBills.constants.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncBills.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncBills.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncBills.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncInvoiced.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncInvoiced.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncInvoiced.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditSyncInvoiced.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditToBills.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditToBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditToBills.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/command/ApplyVendorCreditToBills.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/command/DeleteApplyVendorCreditToBill.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/command/DeleteApplyVendorCreditToBill.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/command/DeleteApplyVendorCreditToBill.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/command/DeleteApplyVendorCreditToBill.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts b/packages/server/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts rename to packages/server/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/queries/GetAppliedBillsToVendorCredit.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/queries/GetAppliedBillsToVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/queries/GetAppliedBillsToVendorCredit.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/queries/GetAppliedBillsToVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/queries/GetVendorCreditToApplyBills.service.ts b/packages/server/src/modules/VendorCreditsApplyBills/queries/GetVendorCreditToApplyBills.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/queries/GetVendorCreditToApplyBills.service.ts rename to packages/server/src/modules/VendorCreditsApplyBills/queries/GetVendorCreditToApplyBills.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/queries/VendorCreditAppliedBillTransformer.ts b/packages/server/src/modules/VendorCreditsApplyBills/queries/VendorCreditAppliedBillTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/queries/VendorCreditAppliedBillTransformer.ts rename to packages/server/src/modules/VendorCreditsApplyBills/queries/VendorCreditAppliedBillTransformer.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/queries/VendorCreditToApplyBillTransformer.ts b/packages/server/src/modules/VendorCreditsApplyBills/queries/VendorCreditToApplyBillTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/queries/VendorCreditToApplyBillTransformer.ts rename to packages/server/src/modules/VendorCreditsApplyBills/queries/VendorCreditToApplyBillTransformer.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncBillsSubscriber.ts b/packages/server/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncBillsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncBillsSubscriber.ts rename to packages/server/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncBillsSubscriber.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncInvoicedSubscriber.ts b/packages/server/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncInvoicedSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncInvoicedSubscriber.ts rename to packages/server/src/modules/VendorCreditsApplyBills/subscribers/ApplyVendorCreditSyncInvoicedSubscriber.ts diff --git a/packages/server-nest/src/modules/VendorCreditsApplyBills/types/VendorCreditApplyBills.types.ts b/packages/server/src/modules/VendorCreditsApplyBills/types/VendorCreditApplyBills.types.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsApplyBills/types/VendorCreditApplyBills.types.ts rename to packages/server/src/modules/VendorCreditsApplyBills/types/VendorCreditApplyBills.types.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/RefundCreditSyncBills.ts b/packages/server/src/modules/VendorCreditsRefund/RefundCreditSyncBills.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/RefundCreditSyncBills.ts rename to packages/server/src/modules/VendorCreditsRefund/RefundCreditSyncBills.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/VendorCreditsRefund.application.ts b/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.application.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/VendorCreditsRefund.application.ts rename to packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.application.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/VendorCreditsRefund.controller.ts b/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.controller.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/VendorCreditsRefund.controller.ts rename to packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.controller.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts b/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts rename to packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/CreateRefundVendorCredit.service.ts b/packages/server/src/modules/VendorCreditsRefund/commands/CreateRefundVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/CreateRefundVendorCredit.service.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/CreateRefundVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/DeleteRefundVendorCredit.service.ts b/packages/server/src/modules/VendorCreditsRefund/commands/DeleteRefundVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/DeleteRefundVendorCredit.service.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/DeleteRefundVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundSyncCreditRefundedAmount.service.ts b/packages/server/src/modules/VendorCreditsRefund/commands/RefundSyncCreditRefundedAmount.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundSyncCreditRefundedAmount.service.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/RefundSyncCreditRefundedAmount.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundSyncVendorCreditBalance.service.ts b/packages/server/src/modules/VendorCreditsRefund/commands/RefundSyncVendorCreditBalance.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundSyncVendorCreditBalance.service.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/RefundSyncVendorCreditBalance.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundVendorCredit.service.ts b/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundVendorCredit.service.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts b/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundVendorCreditTransformer.ts b/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/commands/RefundVendorCreditTransformer.ts rename to packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditTransformer.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/constants.ts b/packages/server/src/modules/VendorCreditsRefund/constants.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/constants.ts rename to packages/server/src/modules/VendorCreditsRefund/constants.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/dtos/RefundVendorCredit.dto.ts b/packages/server/src/modules/VendorCreditsRefund/dtos/RefundVendorCredit.dto.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/dtos/RefundVendorCredit.dto.ts rename to packages/server/src/modules/VendorCreditsRefund/dtos/RefundVendorCredit.dto.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts b/packages/server/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts rename to packages/server/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredit.service.ts b/packages/server/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredit.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredit.service.ts rename to packages/server/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredit.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredits.service.ts b/packages/server/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredits.service.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredits.service.ts rename to packages/server/src/modules/VendorCreditsRefund/queries/GetRefundVendorCredits.service.ts diff --git a/packages/server-nest/src/modules/VendorCreditsRefund/types/VendorCreditRefund.types.ts b/packages/server/src/modules/VendorCreditsRefund/types/VendorCreditRefund.types.ts similarity index 100% rename from packages/server-nest/src/modules/VendorCreditsRefund/types/VendorCreditRefund.types.ts rename to packages/server/src/modules/VendorCreditsRefund/types/VendorCreditRefund.types.ts diff --git a/packages/server-nest/src/modules/Vendors/VendorGLEntries.ts b/packages/server/src/modules/Vendors/VendorGLEntries.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/VendorGLEntries.ts rename to packages/server/src/modules/Vendors/VendorGLEntries.ts diff --git a/packages/server-nest/src/modules/Vendors/VendorGLEntriesStorage.ts b/packages/server/src/modules/Vendors/VendorGLEntriesStorage.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/VendorGLEntriesStorage.ts rename to packages/server/src/modules/Vendors/VendorGLEntriesStorage.ts diff --git a/packages/server-nest/src/modules/Vendors/Vendors.controller.ts b/packages/server/src/modules/Vendors/Vendors.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/Vendors.controller.ts rename to packages/server/src/modules/Vendors/Vendors.controller.ts diff --git a/packages/server-nest/src/modules/Vendors/Vendors.module.ts b/packages/server/src/modules/Vendors/Vendors.module.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/Vendors.module.ts rename to packages/server/src/modules/Vendors/Vendors.module.ts diff --git a/packages/server-nest/src/modules/Vendors/VendorsApplication.service.ts b/packages/server/src/modules/Vendors/VendorsApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/VendorsApplication.service.ts rename to packages/server/src/modules/Vendors/VendorsApplication.service.ts diff --git a/packages/server-nest/src/modules/Vendors/VendorsExportable.ts b/packages/server/src/modules/Vendors/VendorsExportable.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/VendorsExportable.ts rename to packages/server/src/modules/Vendors/VendorsExportable.ts diff --git a/packages/server-nest/src/modules/Vendors/VendorsImportable.ts b/packages/server/src/modules/Vendors/VendorsImportable.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/VendorsImportable.ts rename to packages/server/src/modules/Vendors/VendorsImportable.ts diff --git a/packages/server-nest/src/modules/Vendors/_SampleData.ts b/packages/server/src/modules/Vendors/_SampleData.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/_SampleData.ts rename to packages/server/src/modules/Vendors/_SampleData.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/ActivateVendor.service.ts b/packages/server/src/modules/Vendors/commands/ActivateVendor.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/ActivateVendor.service.ts rename to packages/server/src/modules/Vendors/commands/ActivateVendor.service.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/CreateEditVendorDTO.ts b/packages/server/src/modules/Vendors/commands/CreateEditVendorDTO.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/CreateEditVendorDTO.ts rename to packages/server/src/modules/Vendors/commands/CreateEditVendorDTO.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/CreateVendor.service.ts b/packages/server/src/modules/Vendors/commands/CreateVendor.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/CreateVendor.service.ts rename to packages/server/src/modules/Vendors/commands/CreateVendor.service.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/DeleteVendor.service.ts b/packages/server/src/modules/Vendors/commands/DeleteVendor.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/DeleteVendor.service.ts rename to packages/server/src/modules/Vendors/commands/DeleteVendor.service.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/EditOpeningBalanceVendor.service.ts b/packages/server/src/modules/Vendors/commands/EditOpeningBalanceVendor.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/EditOpeningBalanceVendor.service.ts rename to packages/server/src/modules/Vendors/commands/EditOpeningBalanceVendor.service.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/EditVendor.service.ts b/packages/server/src/modules/Vendors/commands/EditVendor.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/EditVendor.service.ts rename to packages/server/src/modules/Vendors/commands/EditVendor.service.ts diff --git a/packages/server-nest/src/modules/Vendors/commands/VendorValidators.ts b/packages/server/src/modules/Vendors/commands/VendorValidators.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/commands/VendorValidators.ts rename to packages/server/src/modules/Vendors/commands/VendorValidators.ts diff --git a/packages/server-nest/src/modules/Vendors/constants.ts b/packages/server/src/modules/Vendors/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/constants.ts rename to packages/server/src/modules/Vendors/constants.ts diff --git a/packages/server-nest/src/modules/Vendors/dtos/CreateVendor.dto.ts b/packages/server/src/modules/Vendors/dtos/CreateVendor.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/dtos/CreateVendor.dto.ts rename to packages/server/src/modules/Vendors/dtos/CreateVendor.dto.ts diff --git a/packages/server-nest/src/modules/Vendors/dtos/EditVendor.dto.ts b/packages/server/src/modules/Vendors/dtos/EditVendor.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/dtos/EditVendor.dto.ts rename to packages/server/src/modules/Vendors/dtos/EditVendor.dto.ts diff --git a/packages/server-nest/src/modules/Vendors/models/Vendor.ts b/packages/server/src/modules/Vendors/models/Vendor.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/models/Vendor.ts rename to packages/server/src/modules/Vendors/models/Vendor.ts diff --git a/packages/server-nest/src/modules/Vendors/queries/GetVendor.ts b/packages/server/src/modules/Vendors/queries/GetVendor.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/queries/GetVendor.ts rename to packages/server/src/modules/Vendors/queries/GetVendor.ts diff --git a/packages/server-nest/src/modules/Vendors/queries/GetVendors.service.ts b/packages/server/src/modules/Vendors/queries/GetVendors.service.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/queries/GetVendors.service.ts rename to packages/server/src/modules/Vendors/queries/GetVendors.service.ts diff --git a/packages/server-nest/src/modules/Vendors/queries/VendorTransformer.ts b/packages/server/src/modules/Vendors/queries/VendorTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/queries/VendorTransformer.ts rename to packages/server/src/modules/Vendors/queries/VendorTransformer.ts diff --git a/packages/server-nest/src/modules/Vendors/subscribers/VendorGLEntriesSubscriber.ts b/packages/server/src/modules/Vendors/subscribers/VendorGLEntriesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/subscribers/VendorGLEntriesSubscriber.ts rename to packages/server/src/modules/Vendors/subscribers/VendorGLEntriesSubscriber.ts diff --git a/packages/server-nest/src/modules/Vendors/types/Vendors.types.ts b/packages/server/src/modules/Vendors/types/Vendors.types.ts similarity index 100% rename from packages/server-nest/src/modules/Vendors/types/Vendors.types.ts rename to packages/server/src/modules/Vendors/types/Vendors.types.ts diff --git a/packages/server-nest/src/modules/Views/GetResourceColumns.service.ts b/packages/server/src/modules/Views/GetResourceColumns.service.ts similarity index 100% rename from packages/server-nest/src/modules/Views/GetResourceColumns.service.ts rename to packages/server/src/modules/Views/GetResourceColumns.service.ts diff --git a/packages/server-nest/src/modules/Views/GetResourceViews.service.ts b/packages/server/src/modules/Views/GetResourceViews.service.ts similarity index 100% rename from packages/server-nest/src/modules/Views/GetResourceViews.service.ts rename to packages/server/src/modules/Views/GetResourceViews.service.ts diff --git a/packages/server-nest/src/modules/Views/Views.types.ts b/packages/server/src/modules/Views/Views.types.ts similarity index 100% rename from packages/server-nest/src/modules/Views/Views.types.ts rename to packages/server/src/modules/Views/Views.types.ts diff --git a/packages/server-nest/src/modules/Views/models/View.model.ts b/packages/server/src/modules/Views/models/View.model.ts similarity index 100% rename from packages/server-nest/src/modules/Views/models/View.model.ts rename to packages/server/src/modules/Views/models/View.model.ts diff --git a/packages/server-nest/src/modules/Views/models/ViewColumn.model.ts b/packages/server/src/modules/Views/models/ViewColumn.model.ts similarity index 100% rename from packages/server-nest/src/modules/Views/models/ViewColumn.model.ts rename to packages/server/src/modules/Views/models/ViewColumn.model.ts diff --git a/packages/server-nest/src/modules/Views/models/ViewRole.model.ts b/packages/server/src/modules/Views/models/ViewRole.model.ts similarity index 100% rename from packages/server-nest/src/modules/Views/models/ViewRole.model.ts rename to packages/server/src/modules/Views/models/ViewRole.model.ts diff --git a/packages/server-nest/src/modules/Warehouses/AccountsTransactionsWarehouses.ts b/packages/server/src/modules/Warehouses/AccountsTransactionsWarehouses.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/AccountsTransactionsWarehouses.ts rename to packages/server/src/modules/Warehouses/AccountsTransactionsWarehouses.ts diff --git a/packages/server-nest/src/modules/Warehouses/AccountsTransactionsWarehousesSubscribe.ts b/packages/server/src/modules/Warehouses/AccountsTransactionsWarehousesSubscribe.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/AccountsTransactionsWarehousesSubscribe.ts rename to packages/server/src/modules/Warehouses/AccountsTransactionsWarehousesSubscribe.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/BillWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/BillWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/BillWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/BillWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/CreditNoteWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/CreditNoteWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/CreditNoteWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/CreditNoteWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/EstimateWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/EstimateWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/EstimateWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/EstimateWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/InvoiceWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/InvoiceWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/InvoiceWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/InvoiceWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/ReceiptWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/ReceiptWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/ReceiptWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/ReceiptWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/Activate/VendorCreditWarehousesActivate.ts b/packages/server/src/modules/Warehouses/Activate/VendorCreditWarehousesActivate.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Activate/VendorCreditWarehousesActivate.ts rename to packages/server/src/modules/Warehouses/Activate/VendorCreditWarehousesActivate.ts diff --git a/packages/server-nest/src/modules/Warehouses/ActivateWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/ActivateWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/ActivateWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/ActivateWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/CRUDWarehouse.ts b/packages/server/src/modules/Warehouses/CRUDWarehouse.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/CRUDWarehouse.ts rename to packages/server/src/modules/Warehouses/CRUDWarehouse.ts diff --git a/packages/server-nest/src/modules/Warehouses/CreateInitialWarehousesitemsQuantity.ts b/packages/server/src/modules/Warehouses/CreateInitialWarehousesitemsQuantity.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/CreateInitialWarehousesitemsQuantity.ts rename to packages/server/src/modules/Warehouses/CreateInitialWarehousesitemsQuantity.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/ValidateWarehouseExistance.ts b/packages/server/src/modules/Warehouses/Integrations/ValidateWarehouseExistance.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/ValidateWarehouseExistance.ts rename to packages/server/src/modules/Warehouses/Integrations/ValidateWarehouseExistance.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts b/packages/server/src/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts rename to packages/server/src/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts b/packages/server/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts rename to packages/server/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesItemsQuantity.ts b/packages/server/src/modules/Warehouses/Integrations/WarehousesItemsQuantity.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/WarehousesItemsQuantity.ts rename to packages/server/src/modules/Warehouses/Integrations/WarehousesItemsQuantity.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts b/packages/server/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts rename to packages/server/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySync.ts b/packages/server/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySync.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySync.ts rename to packages/server/src/modules/Warehouses/Integrations/WarehousesItemsQuantitySync.ts diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/constants.ts b/packages/server/src/modules/Warehouses/Integrations/constants.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Integrations/constants.ts rename to packages/server/src/modules/Warehouses/Integrations/constants.ts diff --git a/packages/server-nest/src/modules/Warehouses/Items/GetItemWarehouses.ts b/packages/server/src/modules/Warehouses/Items/GetItemWarehouses.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Items/GetItemWarehouses.ts rename to packages/server/src/modules/Warehouses/Items/GetItemWarehouses.ts diff --git a/packages/server-nest/src/modules/Warehouses/Items/GettItemWarehouseTransformer.ts b/packages/server/src/modules/Warehouses/Items/GettItemWarehouseTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Items/GettItemWarehouseTransformer.ts rename to packages/server/src/modules/Warehouses/Items/GettItemWarehouseTransformer.ts diff --git a/packages/server-nest/src/modules/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts b/packages/server/src/modules/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts rename to packages/server/src/modules/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts diff --git a/packages/server-nest/src/modules/Warehouses/Warehouse.types.ts b/packages/server/src/modules/Warehouses/Warehouse.types.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Warehouse.types.ts rename to packages/server/src/modules/Warehouses/Warehouse.types.ts diff --git a/packages/server-nest/src/modules/Warehouses/Warehouses.controller.ts b/packages/server/src/modules/Warehouses/Warehouses.controller.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Warehouses.controller.ts rename to packages/server/src/modules/Warehouses/Warehouses.controller.ts diff --git a/packages/server-nest/src/modules/Warehouses/Warehouses.module.ts b/packages/server/src/modules/Warehouses/Warehouses.module.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/Warehouses.module.ts rename to packages/server/src/modules/Warehouses/Warehouses.module.ts diff --git a/packages/server-nest/src/modules/Warehouses/WarehousesApplication.service.ts b/packages/server/src/modules/Warehouses/WarehousesApplication.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/WarehousesApplication.service.ts rename to packages/server/src/modules/Warehouses/WarehousesApplication.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/WarehousesSettings.ts b/packages/server/src/modules/Warehouses/WarehousesSettings.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/WarehousesSettings.ts rename to packages/server/src/modules/Warehouses/WarehousesSettings.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/ActivateWarehouses.service.ts b/packages/server/src/modules/Warehouses/commands/ActivateWarehouses.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/ActivateWarehouses.service.ts rename to packages/server/src/modules/Warehouses/commands/ActivateWarehouses.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/CreateInitialWarehouse.service.ts b/packages/server/src/modules/Warehouses/commands/CreateInitialWarehouse.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/CreateInitialWarehouse.service.ts rename to packages/server/src/modules/Warehouses/commands/CreateInitialWarehouse.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/CreateWarehouse.service.ts b/packages/server/src/modules/Warehouses/commands/CreateWarehouse.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/CreateWarehouse.service.ts rename to packages/server/src/modules/Warehouses/commands/CreateWarehouse.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/DeleteItemWarehousesQuantity.ts b/packages/server/src/modules/Warehouses/commands/DeleteItemWarehousesQuantity.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/DeleteItemWarehousesQuantity.ts rename to packages/server/src/modules/Warehouses/commands/DeleteItemWarehousesQuantity.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/DeleteWarehouse.service.ts b/packages/server/src/modules/Warehouses/commands/DeleteWarehouse.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/DeleteWarehouse.service.ts rename to packages/server/src/modules/Warehouses/commands/DeleteWarehouse.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/EditWarehouse.service.ts b/packages/server/src/modules/Warehouses/commands/EditWarehouse.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/EditWarehouse.service.ts rename to packages/server/src/modules/Warehouses/commands/EditWarehouse.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts b/packages/server/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts rename to packages/server/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/WarehouseValidator.service.ts b/packages/server/src/modules/Warehouses/commands/WarehouseValidator.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/WarehouseValidator.service.ts rename to packages/server/src/modules/Warehouses/commands/WarehouseValidator.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/contants.ts b/packages/server/src/modules/Warehouses/contants.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/contants.ts rename to packages/server/src/modules/Warehouses/contants.ts diff --git a/packages/server-nest/src/modules/Warehouses/dtos/Warehouse.dto.ts b/packages/server/src/modules/Warehouses/dtos/Warehouse.dto.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/dtos/Warehouse.dto.ts rename to packages/server/src/modules/Warehouses/dtos/Warehouse.dto.ts diff --git a/packages/server-nest/src/modules/Warehouses/models/ItemWarehouseQuantity.ts b/packages/server/src/modules/Warehouses/models/ItemWarehouseQuantity.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/models/ItemWarehouseQuantity.ts rename to packages/server/src/modules/Warehouses/models/ItemWarehouseQuantity.ts diff --git a/packages/server-nest/src/modules/Warehouses/models/Warehouse.model.ts b/packages/server/src/modules/Warehouses/models/Warehouse.model.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/models/Warehouse.model.ts rename to packages/server/src/modules/Warehouses/models/Warehouse.model.ts diff --git a/packages/server-nest/src/modules/Warehouses/queries/GetWarehouse.ts b/packages/server/src/modules/Warehouses/queries/GetWarehouse.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/queries/GetWarehouse.ts rename to packages/server/src/modules/Warehouses/queries/GetWarehouse.ts diff --git a/packages/server-nest/src/modules/Warehouses/queries/GetWarehouses.ts b/packages/server/src/modules/Warehouses/queries/GetWarehouses.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/queries/GetWarehouses.ts rename to packages/server/src/modules/Warehouses/queries/GetWarehouses.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/BillWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/BillWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/BillWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/BillWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/EstimateWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/EstimateWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/EstimateWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/EstimateWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/DeleteItemWarehousesQuantitySubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/DeleteItemWarehousesQuantitySubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/DeleteItemWarehousesQuantitySubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/DeleteItemWarehousesQuantitySubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/Purchases/BillWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/Purchases/BillWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/Purchases/BillWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/Purchases/BillWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts b/packages/server/src/modules/Warehouses/subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts rename to packages/server/src/modules/Warehouses/subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts b/packages/server/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts rename to packages/server/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts b/packages/server/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts rename to packages/server/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.module.ts b/packages/server/src/modules/WarehousesTransfers/WarehouseTransfers.module.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.module.ts rename to packages/server/src/modules/WarehousesTransfers/WarehouseTransfers.module.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/DeleteWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/commands/DeleteWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/DeleteWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/commands/DeleteWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/InitiateWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/commands/InitiateWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/InitiateWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/commands/InitiateWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/TransferredWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/commands/TransferredWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/TransferredWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/commands/TransferredWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/WarehouseTransferAutoIncrement.ts b/packages/server/src/modules/WarehousesTransfers/commands/WarehouseTransferAutoIncrement.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/WarehouseTransferAutoIncrement.ts rename to packages/server/src/modules/WarehousesTransfers/commands/WarehouseTransferAutoIncrement.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/WarehouseTransferWriteInventoryTransactions.ts b/packages/server/src/modules/WarehousesTransfers/commands/WarehouseTransferWriteInventoryTransactions.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/commands/WarehouseTransferWriteInventoryTransactions.ts rename to packages/server/src/modules/WarehousesTransfers/commands/WarehouseTransferWriteInventoryTransactions.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/constants.ts b/packages/server/src/modules/WarehousesTransfers/constants.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/constants.ts rename to packages/server/src/modules/WarehousesTransfers/constants.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts b/packages/server/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts rename to packages/server/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts b/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts rename to packages/server/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/queries/GetWarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/queries/GetWarehouseTransfer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/queries/GetWarehouseTransfer.ts rename to packages/server/src/modules/WarehousesTransfers/queries/GetWarehouseTransfer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/queries/GetWarehouseTransfers.ts b/packages/server/src/modules/WarehousesTransfers/queries/GetWarehouseTransfers.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/queries/GetWarehouseTransfers.ts rename to packages/server/src/modules/WarehousesTransfers/queries/GetWarehouseTransfers.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/queries/WarehouseTransferItemTransformer.ts b/packages/server/src/modules/WarehousesTransfers/queries/WarehouseTransferItemTransformer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/queries/WarehouseTransferItemTransformer.ts rename to packages/server/src/modules/WarehousesTransfers/queries/WarehouseTransferItemTransformer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/queries/WarehouseTransferTransfomer.ts b/packages/server/src/modules/WarehousesTransfers/queries/WarehouseTransferTransfomer.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/queries/WarehouseTransferTransfomer.ts rename to packages/server/src/modules/WarehousesTransfers/queries/WarehouseTransferTransfomer.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferAutoIncrementSubscriber.ts b/packages/server/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferAutoIncrementSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferAutoIncrementSubscriber.ts rename to packages/server/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferAutoIncrementSubscriber.ts diff --git a/packages/server-nest/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferInventoryTransactionsSubscriber.ts b/packages/server/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferInventoryTransactionsSubscriber.ts similarity index 100% rename from packages/server-nest/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferInventoryTransactionsSubscriber.ts rename to packages/server/src/modules/WarehousesTransfers/susbcribers/WarehouseTransferInventoryTransactionsSubscriber.ts diff --git a/packages/server/src/repositories/AccountRepository.ts b/packages/server/src/repositories/AccountRepository.ts deleted file mode 100644 index 43e320b22..000000000 --- a/packages/server/src/repositories/AccountRepository.ts +++ /dev/null @@ -1,397 +0,0 @@ -import { Account } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; -import { IAccount } from '@/interfaces'; -import { Knex } from 'knex'; -import { - DiscountExpenseAccount, - OtherChargesAccount, - OtherExpensesAccount, - PrepardExpenses, - PurchaseDiscountAccount, - StripeClearingAccount, - TaxPayableAccount, - UnearnedRevenueAccount, -} from '@/database/seeds/data/accounts'; -import { TenantMetadata } from '@/system/models'; - -export default class AccountRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return Account.bindKnex(this.knex); - } - - /** - * Retrieve accounts dependency graph. - * @returns {} - */ - async getDependencyGraph(withRelation, trx) { - const accounts = await this.all(withRelation, trx); - - return this.model.toDependencyGraph(accounts); - } - - /** - * Retrieve. - * @param {string} slug - * @return {Promise} - */ - findBySlug(slug: string) { - return this.findOne({ slug }); - } - - /** - * Changes account balance. - * @param {number} accountId - * @param {number} amount - * @return {Promise} - */ - async balanceChange(accountId: number, amount: number): Promise { - const method: string = amount < 0 ? 'decrement' : 'increment'; - - await this.model.query().where('id', accountId)[method]('amount', amount); - this.flushCache(); - } - - /** - * Activate user by the given id. - * @param {number} userId - User id. - * @return {Promise} - */ - activateById(userId: number): Promise { - return super.update({ active: 1 }, { id: userId }); - } - - /** - * Inactivate user by the given id. - * @param {number} userId - User id. - * @return {Promise} - */ - inactivateById(userId: number): Promise { - return super.update({ active: 0 }, { id: userId }); - } - - /** - * Activate user by the given id. - * @param {number} userId - User id. - * @return {Promise} - */ - async activateByIds(userIds: number[], trx): Promise { - const results = await this.model - .query(trx) - .whereIn('id', userIds) - .patch({ active: true }); - - this.flushCache(); - return results; - } - - /** - * Inactivate user by the given id. - * @param {number} userId - User id. - * @return {Promise} - */ - async inactivateByIds(userIds: number[], trx): Promise { - const results = await this.model - .query(trx) - .whereIn('id', userIds) - .patch({ active: false }); - - this.flushCache(); - return results; - } - - /** - * - * @param {string} currencyCode - * @param extraAttrs - * @param trx - * @returns - */ - findOrCreateAccountReceivable = async ( - currencyCode: string = '', - extraAttrs = {}, - trx?: Knex.Transaction - ) => { - let result = await this.model - .query(trx) - .onBuild((query) => { - if (currencyCode) { - query.where('currencyCode', currencyCode); - } - query.where('accountType', 'accounts-receivable'); - }) - .first(); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - name: this.i18n.__('account.accounts_receivable.currency', { - currency: currencyCode, - }), - accountType: 'accounts-receivable', - currencyCode, - active: 1, - ...extraAttrs, - }); - } - return result; - }; - - /** - * Find or create tax payable account. - * @param {Record}extraAttrs - * @param {Knex.Transaction} trx - * @returns - */ - async findOrCreateTaxPayable( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - let result = await this.model - .query(trx) - .findOne({ slug: TaxPayableAccount.slug, ...extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...TaxPayableAccount, - ...extraAttrs, - }); - } - return result; - } - - findOrCreateAccountsPayable = async ( - currencyCode: string = '', - extraAttrs = {}, - trx?: Knex.Transaction - ) => { - let result = await this.model - .query(trx) - .onBuild((query) => { - if (currencyCode) { - query.where('currencyCode', currencyCode); - } - query.where('accountType', 'accounts-payable'); - }) - .first(); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - name: this.i18n.__('account.accounts_payable.currency', { - currency: currencyCode, - }), - accountType: 'accounts-payable', - currencyCode, - active: 1, - ...extraAttrs, - }); - } - return result; - }; - - /** - * Finds or creates the unearned revenue. - * @param {Record} extraAttrs - * @param {Knex.Transaction} trx - * @returns - */ - public async findOrCreateUnearnedRevenue( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - let result = await this.model - .query(trx) - .findOne({ slug: UnearnedRevenueAccount.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...UnearnedRevenueAccount, - ..._extraAttrs, - }); - } - return result; - } - - /** - * Finds or creates the prepard expenses account. - * @param {Record} extraAttrs - * @param {Knex.Transaction} trx - * @returns - */ - public async findOrCreatePrepardExpenses( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - - let result = await this.model - .query(trx) - .findOne({ slug: PrepardExpenses.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...PrepardExpenses, - ..._extraAttrs, - }); - } - return result; - } - - /** - * Finds or creates the stripe clearing account. - * @param {Record} extraAttrs - * @param {Knex.Transaction} trx - * @returns - */ - public async findOrCreateStripeClearing( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - - let result = await this.model - .query(trx) - .findOne({ slug: StripeClearingAccount.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...StripeClearingAccount, - ..._extraAttrs, - }); - } - return result; - } - - /** - * Finds or creates the discount expense account. - * @param {Record} extraAttrs - * @param {Knex.Transaction} trx - * @returns - */ - public async findOrCreateDiscountAccount( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - - let result = await this.model - .query(trx) - .findOne({ slug: DiscountExpenseAccount.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...DiscountExpenseAccount, - ..._extraAttrs, - }); - } - return result; - } - - public async findOrCreatePurchaseDiscountAccount( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - - let result = await this.model - .query(trx) - .findOne({ slug: PurchaseDiscountAccount.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...PurchaseDiscountAccount, - ..._extraAttrs, - }); - } - return result; - } - - public async findOrCreateOtherChargesAccount( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - - let result = await this.model - .query(trx) - .findOne({ slug: OtherChargesAccount.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...OtherChargesAccount, - ..._extraAttrs, - }); - } - return result; - } - - public async findOrCreateOtherExpensesAccount( - extraAttrs: Record = {}, - trx?: Knex.Transaction - ) { - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ - tenantId: this.tenantId, - }); - const _extraAttrs = { - currencyCode: tenantMeta.baseCurrency, - ...extraAttrs, - }; - - let result = await this.model - .query(trx) - .findOne({ slug: OtherExpensesAccount.slug, ..._extraAttrs }); - - if (!result) { - result = await this.model.query(trx).insertAndFetch({ - ...OtherExpensesAccount, - ..._extraAttrs, - }); - } - return result; - } -} diff --git a/packages/server/src/repositories/AccountTransactionRepository.ts b/packages/server/src/repositories/AccountTransactionRepository.ts deleted file mode 100644 index 525b82c78..000000000 --- a/packages/server/src/repositories/AccountTransactionRepository.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { isEmpty, castArray } from 'lodash'; -import { AccountTransaction } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -interface IJournalTransactionsFilter { - fromDate: string | Date; - toDate: string | Date; - accountsIds: number[]; - sumationCreditDebit: boolean; - fromAmount: number; - toAmount: number; - contactsIds?: number[]; - contactType?: string; - referenceType?: string[]; - referenceId?: number[]; - index: number | number[]; - indexGroup: number | number[]; - branchesIds: number | number[]; -} - -export default class AccountTransactionsRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return AccountTransaction.bindKnex(this.knex); - } - - journal(filter: IJournalTransactionsFilter) { - return this.model - .query() - .modify('filterAccounts', filter.accountsIds) - .modify('filterDateRange', filter.fromDate, filter.toDate) - .withGraphFetched('account') - .onBuild((query) => { - if (filter.sumationCreditDebit) { - query.modify('sumationCreditDebit'); - } - if (filter.fromAmount || filter.toAmount) { - query.modify('filterAmountRange', filter.fromAmount, filter.toAmount); - } - if (filter.contactsIds) { - query.modify('filterContactIds', filter.contactsIds); - } - if (filter.contactType) { - query.where('contact_type', filter.contactType); - } - if (filter.referenceType && filter.referenceType.length > 0) { - query.whereIn('reference_type', filter.referenceType); - } - if (filter.referenceId && filter.referenceId.length > 0) { - query.whereIn('reference_id', filter.referenceId); - } - if (filter.index) { - if (Array.isArray(filter.index)) { - query.whereIn('index', filter.index); - } else { - query.where('index', filter.index); - } - } - if (filter.indexGroup) { - if (Array.isArray(filter.indexGroup)) { - query.whereIn('index_group', filter.indexGroup); - } else { - query.where('index_group', filter.indexGroup); - } - } - if (!isEmpty(filter.branchesIds)) { - query.modify('filterByBranches', filter.branchesIds); - } - }); - } - - openingBalance(fromDate) { - return AccountTransaction.query().modify('openingBalance', fromDate); - } - - closingOpening(toDate) { - return AccountTransaction.query().modify('closingBalance', toDate); - } - - /** - * Reverts the jouranl entries. - * @param {number|number[]} referenceId - Reference id. - * @param {string} referenceType - Reference type. - */ - public getTransactionsByReference = async ( - referenceId: number | number[], - referenceType: string | string[] - ) => { - const transactions = await this.model - .query() - .whereIn('reference_type', castArray(referenceType)) - .whereIn('reference_id', castArray(referenceId)) - .withGraphFetched('account'); - - return transactions; - }; -} diff --git a/packages/server/src/repositories/BaseModelRepository.ts b/packages/server/src/repositories/BaseModelRepository.ts deleted file mode 100644 index 09d17a6e9..000000000 --- a/packages/server/src/repositories/BaseModelRepository.ts +++ /dev/null @@ -1,5 +0,0 @@ - - -export default class BaseModelRepository { - -} \ No newline at end of file diff --git a/packages/server/src/repositories/BillRepository.ts b/packages/server/src/repositories/BillRepository.ts deleted file mode 100644 index 185507ef0..000000000 --- a/packages/server/src/repositories/BillRepository.ts +++ /dev/null @@ -1,30 +0,0 @@ -import moment from 'moment'; -import { Bill } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class BillRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return Bill.bindKnex(this.knex); - } - - dueBills(asDate = moment().format('YYYY-MM-DD'), withRelations) { - return this.model - .query() - .modify('dueBills') - .modify('notOverdue') - .modify('fromDate', asDate) - .withGraphFetched(withRelations); - } - - overdueBills(asDate = moment().format('YYYY-MM-DD'), withRelations) { - return this.model - .query() - .modify('dueBills') - .modify('overdue', asDate) - .modify('fromDate', asDate) - .withGraphFetched(withRelations); - } -} diff --git a/packages/server/src/repositories/CachableRepository.ts b/packages/server/src/repositories/CachableRepository.ts deleted file mode 100644 index d1e1a08c7..000000000 --- a/packages/server/src/repositories/CachableRepository.ts +++ /dev/null @@ -1,261 +0,0 @@ -import hashObject from 'object-hash'; -import EntityRepository from './EntityRepository'; - -export default class CachableRepository extends EntityRepository { - repositoryName: string; - cache: any; - i18n: any; - - /** - * Constructor method. - * @param {Knex} knex - * @param {Cache} cache - */ - constructor(knex, cache, i18n) { - super(knex); - - this.cache = cache; - this.i18n = i18n; - this.repositoryName = this.constructor.name; - } - - getByCache(key, callback) { - return callback(); - } - - /** - * Retrieve the cache key of the method name and arguments. - * @param {string} method - * @param {...any} args - * @return {string} - */ - getCacheKey(method, ...args) { - const hashArgs = hashObject({ ...args }); - const repositoryName = this.repositoryName; - - return `${repositoryName}-${method}-${hashArgs}`; - } - - /** - * Retrieve all entries with specified relations. - * @param withRelations - */ - all(withRelations?, trx?) { - const cacheKey = this.getCacheKey('all', withRelations); - - return this.getByCache(cacheKey, () => { - return super.all(withRelations, trx); - }); - } - - /** - * Finds list of entities with specified attributes - * @param {Object} attributeValues - values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve. - * @returns {Promise} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - find(attributeValues = {}, withRelations?) { - const cacheKey = this.getCacheKey('find', attributeValues, withRelations); - - return this.getByCache(cacheKey, () => { - return super.find(attributeValues, withRelations); - }); - } - - /** - * Finds list of entities with attribute values that are different from specified ones - * @param {Object} attributeValues - values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {Promise} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - findWhereNot(attributeValues = {}, withRelations?) { - const cacheKey = this.getCacheKey( - 'findWhereNot', - attributeValues, - withRelations - ); - - return this.getByCache(cacheKey, () => { - return super.findWhereNot(attributeValues, withRelations); - }); - } - - /** - * Finds list of entities with specified attributes (any of multiple specified values) - * Supports both ('attrName', ['value1', 'value2]) and ({attrName: ['value1', 'value2']} formats) - * - * @param {string|Object} searchParam - attribute name or search criteria object - * @param {*[]} [attributeValues] - attribute values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {PromiseLike} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - findWhereIn(searchParam, attributeValues, withRelations?) { - const cacheKey = this.getCacheKey( - 'findWhereIn', - attributeValues, - withRelations - ); - - return this.getByCache(cacheKey, () => { - return super.findWhereIn(searchParam, attributeValues, withRelations); - }); - } - - /** - * Finds first entity by given parameters - * - * @param {Object} attributeValues - values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {Promise} - */ - findOne(attributeValues = {}, withRelations?) { - const cacheKey = this.getCacheKey( - 'findOne', - attributeValues, - withRelations - ); - - return this.getByCache(cacheKey, () => { - return super.findOne(attributeValues, withRelations); - }); - } - - /** - * Finds first entity by given parameters - * - * @param {string || number} id - value of id column of the entity - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {Promise} - */ - findOneById(id, withRelations?) { - const cacheKey = this.getCacheKey('findOneById', id, withRelations); - - return this.getByCache(cacheKey, () => { - return super.findOneById(id, withRelations); - }); - } - - /** - * Persists new entity or an array of entities. - * This method does not recursively persist related entities, use createRecursively (to be implemented) for that. - * Batch insert only works on PostgreSQL - * @param {Object} entity - model instance or parameters for a new entity - * @returns {Promise} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - async create(entity, trx?) { - const result = await super.create(entity, trx); - - // Flushes the repository cache after insert operation. - this.flushCache(); - - return result; - } - - /** - * Persists updated entity. If previously set fields are not present, performs an incremental update (does not remove fields unless explicitly set to null) - * - * @param {Object} entity - single entity instance - * @param {Object} [trx] - knex transaction instance. If not specified, new implicit transaction will be used. - * @returns {Promise} number of affected rows - */ - async update(entity, whereAttributes?, trx?) { - const result = await super.update(entity, whereAttributes, trx); - - // Flushes the repository cache after update operation. - this.flushCache(); - - return result; - } - - /** - * @param {Object} attributeValues - values to filter deleted entities by - * @param {Object} [trx] - * @returns {Promise} Query builder. After promise is resolved, returns count of deleted rows - */ - async deleteBy(attributeValues, trx?) { - const result = await super.deleteBy(attributeValues, trx); - this.flushCache(); - - return result; - } - - /** - * @param {string || number} id - value of id column of the entity - * @returns {Promise} Query builder. After promise is resolved, returns count of deleted rows - */ - deleteById(id: number | string, trx?) { - const result = super.deleteById(id, trx); - - // Flushes the repository cache after insert operation. - this.flushCache(); - - return result; - } - - /** - * - * @param {string|number[]} values - - */ - async deleteWhereIn(field: string, values: string | number[]) { - const result = await super.deleteWhereIn(field, values); - - // Flushes the repository cache after delete operation. - this.flushCache(); - - return result; - } - - /** - * - * @param {string|number[]} values - */ - async deleteWhereIdIn(values: string | number[], trx?) { - const result = await super.deleteWhereIdIn(values, trx); - - // Flushes the repository cache after delete operation. - this.flushCache(); - - return result; - } - - /** - * - * @param graph - * @param options - */ - async upsertGraph(graph, options) { - const result = await super.upsertGraph(graph, options); - - // Flushes the repository cache after insert operation. - this.flushCache(); - - return result; - } - - /** - * - * @param {} whereAttributes - * @param {string} field - * @param {number} amount - */ - async changeNumber(whereAttributes, field: string, amount: number, trx?) { - const result = await super.changeNumber( - whereAttributes, - field, - amount, - trx - ); - - // Flushes the repository cache after update operation. - this.flushCache(); - - return result; - } - - /** - * Flush repository cache. - */ - flushCache(): void { - this.cache.delStartWith(this.repositoryName); - } -} diff --git a/packages/server/src/repositories/ContactRepository.ts b/packages/server/src/repositories/ContactRepository.ts deleted file mode 100644 index fc5c0f27e..000000000 --- a/packages/server/src/repositories/ContactRepository.ts +++ /dev/null @@ -1,12 +0,0 @@ -import TenantRepository from '@/repositories/TenantRepository'; -import { Contact } from 'models' - - -export default class ContactRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return Contact.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/CustomerRepository.ts b/packages/server/src/repositories/CustomerRepository.ts deleted file mode 100644 index 267e14d1f..000000000 --- a/packages/server/src/repositories/CustomerRepository.ts +++ /dev/null @@ -1,46 +0,0 @@ -import TenantRepository from "./TenantRepository"; -import { Customer } from 'models'; - -export default class CustomerRepository extends TenantRepository { - /** - * Contact repository. - */ - constructor(knex, cache, i18n) { - super(knex, cache, i18n); - this.repositoryName = 'CustomerRepository'; - } - - /** - * Gets the repository's model. - */ - get model() { - return Customer.bindKnex(this.knex); - } - - changeBalance(vendorId: number, amount: number) { - return super.changeNumber({ id: vendorId }, 'balance', amount); - } - - async changeDiffBalance( - vendorId: number, - amount: number, - oldAmount: number, - oldVendorId?: number, - ) { - const diffAmount = amount - oldAmount; - const asyncOpers = []; - const _oldVendorId = oldVendorId || vendorId; - - if (vendorId != _oldVendorId) { - const oldCustomerOper = this.changeBalance(_oldVendorId, (oldAmount * -1)); - const customerOper = this.changeBalance(vendorId, amount); - - asyncOpers.push(customerOper); - asyncOpers.push(oldCustomerOper); - } else { - const balanceChangeOper = this.changeBalance(vendorId, diffAmount); - asyncOpers.push(balanceChangeOper); - } - await Promise.all(asyncOpers); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/EntityRepository.ts b/packages/server/src/repositories/EntityRepository.ts deleted file mode 100644 index cc6ddf49c..000000000 --- a/packages/server/src/repositories/EntityRepository.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { cloneDeep, forOwn, isString } from 'lodash'; -import ModelEntityNotFound from 'exceptions/ModelEntityNotFound'; - -function applyGraphFetched(withRelations, builder) { - const relations = Array.isArray(withRelations) - ? withRelations - : typeof withRelations === 'string' - ? withRelations.split(',').map((relation) => relation.trim()) - : []; - - relations.forEach((relation) => { - builder.withGraphFetched(relation); - }); -} - -export default class EntityRepository { - idColumn: string; - knex: any; - - /** - * Constructor method. - * @param {Knex} knex - */ - constructor(knex) { - this.knex = knex; - this.idColumn = 'id'; - } - - /** - * Retrieve the repository model binded it to knex instance. - */ - get model() { - throw new Error("The repository's model is not defined."); - } - - /** - * Retrieve all entries with specified relations. - * - * @param withRelations - */ - all(withRelations?, trx?) { - const builder = this.model.query(trx); - applyGraphFetched(withRelations, builder); - - return builder; - } - - /** - * Finds list of entities with specified attributes - * - * @param {Object} attributeValues - values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve. - * @returns {Promise} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - find(attributeValues = {}, withRelations?) { - const builder = this.model.query().where(attributeValues); - - applyGraphFetched(withRelations, builder); - return builder; - } - - /** - * Finds list of entities with attribute values that are different from specified ones - * - * @param {Object} attributeValues - values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {PromiseLike} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - findWhereNot(attributeValues = {}, withRelations?) { - const builder = this.model.query().whereNot(attributeValues); - - applyGraphFetched(withRelations, builder); - return builder; - } - - /** - * Finds list of entities with specified attributes (any of multiple specified values) - * Supports both ('attrName', ['value1', 'value2]) and ({attrName: ['value1', 'value2']} formats) - * - * @param {string|Object} searchParam - attribute name or search criteria object - * @param {*[]} [attributeValues] - attribute values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {PromiseLike} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - findWhereIn(searchParam, attributeValues, withRelations?) { - const commonBuilder = (builder) => { - applyGraphFetched(withRelations, builder); - }; - if (isString(searchParam)) { - return this.model - .query() - .whereIn(searchParam, attributeValues) - .onBuild(commonBuilder); - } else { - const builder = this.model.query(this.knex).onBuild(commonBuilder); - - forOwn(searchParam, (value, key) => { - if (Array.isArray(value)) { - builder.whereIn(key, value); - } else { - builder.where(key, value); - } - }); - return builder; - } - } - - /** - * Finds first entity by given parameters - * - * @param {Object} attributeValues - values to filter retrieved entities by - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {Promise} - */ - async findOne(attributeValues = {}, withRelations?) { - const results = await this.find(attributeValues, withRelations); - return results[0] || null; - } - - /** - * Finds first entity by given parameters - * - * @param {string || number} id - value of id column of the entity - * @param {string || string[]} [withRelations] - name of relation(s) to eagerly retrieve, as defined in model relationMappings() - * @returns {Promise} - */ - findOneById(id, withRelations?) { - return this.findOne({ [this.idColumn]: id }, withRelations); - } - - /** - * Persists new entity or an array of entities. - * This method does not recursively persist related entities, use createRecursively (to be implemented) for that. - * Batch insert only works on PostgreSQL - * - * @param {Object} entity - model instance or parameters for a new entity - * @returns {Promise} - query builder. You can chain additional methods to it or call "await" or then() on it to execute - */ - create(entity, trx?) { - // Keep the input parameter immutable - const instanceDTO = cloneDeep(entity); - - return this.model.query(trx).insert(instanceDTO); - } - - /** - * Persists updated entity. If previously set fields are not present, performs an incremental update (does not remove fields unless explicitly set to null) - * - * @param {Object} entity - single entity instance - * @returns {Promise} number of affected rows - */ - async update(entity, whereAttributes?, trx?) { - const entityDto = cloneDeep(entity); - const identityClause = {}; - - if (Array.isArray(this.idColumn)) { - this.idColumn.forEach( - (idColumn) => (identityClause[idColumn] = entityDto[idColumn]) - ); - } else { - identityClause[this.idColumn] = entityDto[this.idColumn]; - } - const whereConditions = whereAttributes || identityClause; - const modifiedEntitiesCount = await this.model - .query(trx) - .where(whereConditions) - .update(entityDto); - - if (modifiedEntitiesCount === 0) { - throw new ModelEntityNotFound(entityDto[this.idColumn]); - } - return modifiedEntitiesCount; - } - - /** - * - * @param {Object} attributeValues - values to filter deleted entities by - * @param {Object} [trx] - * @returns {Promise} Query builder. After promise is resolved, returns count of deleted rows - */ - deleteBy(attributeValues, trx?) { - return this.model.query(trx).delete().where(attributeValues); - } - - /** - * @param {string || number} id - value of id column of the entity - * @returns {Promise} Query builder. After promise is resolved, returns count of deleted rows - */ - deleteById(id: number | string, trx?) { - return this.deleteBy( - { - [this.idColumn]: id, - }, - trx - ); - } - - /** - * Deletes the given entries in the array on the specific field. - * @param {string} field - - * @param {number|string} values - - */ - deleteWhereIn(field: string, values: string | number[], trx) { - return this.model.query(trx).whereIn(field, values).delete(); - } - - /** - * - * @param {string|number[]} values - */ - deleteWhereIdIn(values: string | number[], trx?) { - return this.deleteWhereIn(this.idColumn, values, trx); - } - - /** - * Arbitrary relation graphs can be upserted (insert + update + delete) - * using the upsertGraph method. - * @param graph - * @param options - */ - upsertGraph(graph, options) { - // Keep the input grpah immutable - const graphCloned = cloneDeep(graph); - return this.model.query().upsertGraph(graphCloned, options); - } - - /** - * - * @param {object} whereAttributes - * @param {string} field - * @param amount - */ - changeNumber(whereAttributes, field: string, amount: number, trx) { - const changeMethod = amount > 0 ? 'increment' : 'decrement'; - - return this.model - .query(trx) - .where(whereAttributes) - [changeMethod](field, Math.abs(amount)); - } -} diff --git a/packages/server/src/repositories/ExpenseEntryRepository.ts b/packages/server/src/repositories/ExpenseEntryRepository.ts deleted file mode 100644 index 4f84e81a3..000000000 --- a/packages/server/src/repositories/ExpenseEntryRepository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TenantRepository from "./TenantRepository"; -import { ExpenseCategory } from 'models'; - -export default class ExpenseEntryRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return ExpenseCategory.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/ExpenseRepository.ts b/packages/server/src/repositories/ExpenseRepository.ts deleted file mode 100644 index 2f9df91f6..000000000 --- a/packages/server/src/repositories/ExpenseRepository.ts +++ /dev/null @@ -1,35 +0,0 @@ -import TenantRepository from "./TenantRepository"; -import moment from "moment"; -import { Expense } from 'models'; - -export default class ExpenseRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return Expense.bindKnex(this.knex); - } - - /** - * Publish the given expense. - * @param {number} expenseId - */ - publish(expenseId: number): Promise { - return super.update({ - id: expenseId, - publishedAt: moment().toMySqlDateTime(), - }); - } - - /** - * Publishes the given expenses in bulk. - * @param {number[]} expensesIds - * @return {Promise} - */ - async whereIdInPublish(expensesIds: number): Promise { - await this.model.query().whereIn('id', expensesIds).patch({ - publishedAt: moment().toMySqlDateTime(), - }); - this.flushCache(); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/InventoryTransactionRepository.ts b/packages/server/src/repositories/InventoryTransactionRepository.ts deleted file mode 100644 index e4e6f80b5..000000000 --- a/packages/server/src/repositories/InventoryTransactionRepository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TenantRepository from '@/repositories/TenantRepository'; -import { InventoryTransaction } from 'models'; - -export default class InventoryTransactionRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return InventoryTransaction.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/ItemRepository.ts b/packages/server/src/repositories/ItemRepository.ts deleted file mode 100644 index 043d6a715..000000000 --- a/packages/server/src/repositories/ItemRepository.ts +++ /dev/null @@ -1,12 +0,0 @@ - -import { Item } from "models"; -import TenantRepository from "./TenantRepository"; - -export default class ItemRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return Item.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/JournalRepository.ts b/packages/server/src/repositories/JournalRepository.ts deleted file mode 100644 index ec91da4a1..000000000 --- a/packages/server/src/repositories/JournalRepository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ManualJournal } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class JournalRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return ManualJournal.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/PaymentReceiveEntryRepository.ts b/packages/server/src/repositories/PaymentReceiveEntryRepository.ts deleted file mode 100644 index 38f0cc5be..000000000 --- a/packages/server/src/repositories/PaymentReceiveEntryRepository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PaymentReceiveEntry } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class PaymentReceiveEntryRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return PaymentReceiveEntry.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/PaymentReceiveRepository.ts b/packages/server/src/repositories/PaymentReceiveRepository.ts deleted file mode 100644 index 3db6ba6e4..000000000 --- a/packages/server/src/repositories/PaymentReceiveRepository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PaymentReceive } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class PaymentReceiveRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return PaymentReceive.bindKnex(this.knex); - } -} diff --git a/packages/server/src/repositories/SaleInvoiceRepository.ts b/packages/server/src/repositories/SaleInvoiceRepository.ts deleted file mode 100644 index 3cb431da5..000000000 --- a/packages/server/src/repositories/SaleInvoiceRepository.ts +++ /dev/null @@ -1,30 +0,0 @@ -import moment from 'moment'; -import { SaleInvoice } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class SaleInvoiceRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return SaleInvoice.bindKnex(this.knex); - } - - dueInvoices(asDate = moment().format('YYYY-MM-DD'), withRelations) { - return this.model - .query() - .modify('dueInvoices') - .modify('notOverdue', asDate) - .modify('fromDate', asDate) - .withGraphFetched(withRelations); - } - - overdueInvoices(asDate = moment().format('YYYY-MM-DD'), withRelations) { - return this.model - .query() - .modify('dueInvoices') - .modify('overdue', asDate) - .modify('fromDate', asDate) - .withGraphFetched(withRelations); - } -} diff --git a/packages/server/src/repositories/SettingRepository.ts b/packages/server/src/repositories/SettingRepository.ts deleted file mode 100644 index 84cdde764..000000000 --- a/packages/server/src/repositories/SettingRepository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TenantRepository from '@/repositories/TenantRepository'; -import Setting from 'models/Setting'; - -export default class SettingRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return Setting.bindKnex(this.knex); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/TenantRepository.ts b/packages/server/src/repositories/TenantRepository.ts deleted file mode 100644 index ac85a82a7..000000000 --- a/packages/server/src/repositories/TenantRepository.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Container } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import CachableRepository from './CachableRepository'; - -export default class TenantRepository extends CachableRepository { - repositoryName: string; - tenantId: number; - - /** - * Constructor method. - * @param {number} tenantId - */ - constructor(knex, cache, i18n) { - super(knex, cache, i18n); - } - - setTenantId(tenantId: number) { - this.tenantId = tenantId; - } -} diff --git a/packages/server/src/repositories/VendorRepository.ts b/packages/server/src/repositories/VendorRepository.ts deleted file mode 100644 index af9e7a899..000000000 --- a/packages/server/src/repositories/VendorRepository.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Vendor } from "models"; -import TenantRepository from "./TenantRepository"; - -export default class VendorRepository extends TenantRepository { - /** - * Contact repository. - */ - constructor(knex, cache, i18n) { - super(knex, cache, i18n); - this.repositoryName = 'VendorRepository'; - } - - /** - * Gets the repository's model. - */ - get model() { - return Vendor.bindKnex(this.knex); - } - - unpaid() { - - } - - changeBalance(vendorId: number, amount: number) { - return super.changeNumber({ id: vendorId }, 'balance', amount); - } - - async changeDiffBalance( - vendorId: number, - amount: number, - oldAmount: number, - oldVendorId?: number, - ) { - const diffAmount = amount - oldAmount; - const asyncOpers = []; - const _oldVendorId = oldVendorId || vendorId; - - if (vendorId != _oldVendorId) { - const oldCustomerOper = this.changeBalance(_oldVendorId, (oldAmount * -1)); - const customerOper = this.changeBalance(vendorId, amount); - - asyncOpers.push(customerOper); - asyncOpers.push(oldCustomerOper); - } else { - const balanceChangeOper = this.changeBalance(vendorId, diffAmount); - asyncOpers.push(balanceChangeOper); - } - await Promise.all(asyncOpers); - } -} diff --git a/packages/server/src/repositories/ViewRepository.ts b/packages/server/src/repositories/ViewRepository.ts deleted file mode 100644 index 8bcfbf13f..000000000 --- a/packages/server/src/repositories/ViewRepository.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { View } from 'models'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class ViewRepository extends TenantRepository { - /** - * Gets the repository's model. - */ - get model() { - return View.bindKnex(this.knex); - } - - /** - * Retrieve all views of the given resource id. - */ - allByResource(resourceModel: string, withRelations?) { - return super.find({ resource_model: resourceModel }, withRelations); - } -} \ No newline at end of file diff --git a/packages/server/src/repositories/ViewRoleRepository.ts b/packages/server/src/repositories/ViewRoleRepository.ts deleted file mode 100644 index 1f96bb332..000000000 --- a/packages/server/src/repositories/ViewRoleRepository.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { omit } from 'lodash'; -import TenantRepository from '@/repositories/TenantRepository'; - -export default class ViewRoleRepository extends TenantRepository { - -} \ No newline at end of file diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts deleted file mode 100644 index 9b05fe2c0..000000000 --- a/packages/server/src/server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import 'reflect-metadata'; // We need this in order to use @Decorators -import 'newrelic'; -import './before'; -import '@/config'; - -import express from 'express'; -import loadersFactory from 'loaders'; - -async function startServer() { - const app = express(); - - // Intiialize all registered loaders. - await loadersFactory({ expressApp: app }); -} - -startServer(); diff --git a/packages/server/src/services/Accounting/AccountsTransactionsWarehouses.ts b/packages/server/src/services/Accounting/AccountsTransactionsWarehouses.ts deleted file mode 100644 index 2673c01ad..000000000 --- a/packages/server/src/services/Accounting/AccountsTransactionsWarehouses.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class InventoryTransactionsWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all accounts transctions with the priamry branch. - * @param tenantId - * @param primaryBranchId - */ - public updateTransactionsWithWarehouse = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { AccountTransaction } = await this.tenancy.models(tenantId); - - await AccountTransaction.query(trx).update({ - branchId: primaryBranchId, - }); - }; -} diff --git a/packages/server/src/services/Accounting/AccountsTransactionsWarehousesSubscribe.ts b/packages/server/src/services/Accounting/AccountsTransactionsWarehousesSubscribe.ts deleted file mode 100644 index b109d1237..000000000 --- a/packages/server/src/services/Accounting/AccountsTransactionsWarehousesSubscribe.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { InventoryTransactionsWarehouses } from './AccountsTransactionsWarehouses'; -import { IBranchesActivatedPayload } from '@/interfaces'; - -@Service() -export class AccountsTransactionsWarehousesSubscribe { - @Inject() - accountsTransactionsWarehouses: InventoryTransactionsWarehouses; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.branch.onActivated, - this.updateGLTransactionsToPrimaryBranchOnActivated - ); - return bus; - }; - - /** - * Updates all GL transactions to primary branch once - * the multi-branches activated. - * @param {IBranchesActivatedPayload} - */ - private updateGLTransactionsToPrimaryBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.accountsTransactionsWarehouses.updateTransactionsWithWarehouse( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Accounting/JournalCommands.ts b/packages/server/src/services/Accounting/JournalCommands.ts deleted file mode 100644 index ed7ad043d..000000000 --- a/packages/server/src/services/Accounting/JournalCommands.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { castArray } from 'lodash'; -import JournalPoster from './JournalPoster'; - -export default class JournalCommands { - journal: JournalPoster; - models: any; - repositories: any; - - /** - * Constructor method. - * @param {JournalPoster} journal - - */ - constructor(journal: JournalPoster) { - this.journal = journal; - this.repositories = this.journal.repositories; - this.models = this.journal.models; - } - /** - * Reverts the jouranl entries. - * @param {number|number[]} referenceId - Reference id. - * @param {string} referenceType - Reference type. - */ - async revertJournalEntries( - referenceId: number | number[], - referenceType: string | string[] - ) { - const { AccountTransaction } = this.models; - - const transactions = await AccountTransaction.query() - .whereIn('reference_type', castArray(referenceType)) - .whereIn('reference_id', castArray(referenceId)) - .withGraphFetched('account'); - - this.journal.fromTransactions(transactions); - this.journal.removeEntries(); - } - - /** - * Reverts the sale invoice cost journal entries. - * @param {Date|string} startingDate - * @return {Promise} - */ - async revertInventoryCostJournalEntries( - startingDate: Date | string - ): Promise { - const { AccountTransaction } = this.models; - - this.journal.fromTransactions(transactions); - this.journal.removeEntries(); - } - - /** - * Reverts sale invoice the income journal entries. - * @param {number} saleInvoiceId - */ - async revertInvoiceIncomeEntries(saleInvoiceId: number) { - const { transactionsRepository } = this.repositories; - - const transactions = await transactionsRepository.journal({ - referenceType: ['SaleInvoice'], - referenceId: [saleInvoiceId], - }); - this.journal.fromTransactions(transactions); - this.journal.removeEntries(); - } -} diff --git a/packages/server/src/services/Accounting/JournalContacts.ts b/packages/server/src/services/Accounting/JournalContacts.ts deleted file mode 100644 index 6ae2b22c5..000000000 --- a/packages/server/src/services/Accounting/JournalContacts.ts +++ /dev/null @@ -1,74 +0,0 @@ -import async from 'async'; - -export default class JournalContacts { - saveContactBalanceQueue: any; - contactsBalanceTable: { - [key: number]: { credit: number; debit: number }; - } = {}; - - constructor(journal) { - this.journal = journal; - this.saveContactBalanceQueue = async.queue( - this.saveContactBalanceChangeTask.bind(this), - 10 - ); - } - /** - * Sets the contact balance change. - */ - private getContactsBalanceChanges(entry) { - if (!entry.contactId) { - return; - } - const change = { - debit: entry.debit, - credit: entry.credit, - }; - if (!this.contactsBalanceTable[entry.contactId]) { - this.contactsBalanceTable[entry.contactId] = { credit: 0, debit: 0 }; - } - if (change.credit) { - this.contactsBalanceTable[entry.contactId].credit += change.credit; - } - if (change.debit) { - this.contactsBalanceTable[entry.contactId].debit += change.debit; - } - } - - /** - * Save contacts balance change. - */ - saveContactsBalance() { - const balanceChanges = Object.entries( - this.contactsBalanceTable - ).map(([contactId, { credit, debit }]) => ({ contactId, credit, debit })); - - return this.saveContactBalanceQueue.pushAsync(balanceChanges); - } - - /** - * Saves contact balance change task. - * @param {number} contactId - Contact id. - * @param {number} credit - Credit amount. - * @param {number} debit - Debit amount. - */ - async saveContactBalanceChangeTask({ contactId, credit, debit }, callback) { - const { contactRepository } = this.repositories; - - const contact = await contactRepository.findOneById(contactId); - let balanceChange = 0; - - if (contact.contactNormal === 'credit') { - balanceChange += credit - debit; - } else { - balanceChange += debit - credit; - } - // Contact change balance. - await contactRepository.changeNumber( - { id: contactId }, - 'balance', - balanceChange - ); - callback(); - } -} diff --git a/packages/server/src/services/Accounting/JournalEntry.ts b/packages/server/src/services/Accounting/JournalEntry.ts deleted file mode 100644 index 177ace1f1..000000000 --- a/packages/server/src/services/Accounting/JournalEntry.ts +++ /dev/null @@ -1,10 +0,0 @@ - -export default class JournalEntry { - constructor(entry) { - const defaults = { - credit: 0, - debit: 0, - }; - this.entry = { ...defaults, ...entry }; - } -} diff --git a/packages/server/src/services/Accounting/JournalFinancial.ts b/packages/server/src/services/Accounting/JournalFinancial.ts deleted file mode 100644 index 65e18491d..000000000 --- a/packages/server/src/services/Accounting/JournalFinancial.ts +++ /dev/null @@ -1,17 +0,0 @@ -import moment from 'moment'; -import { IJournalPoster } from '@/interfaces'; - -export default class JournalFinancial { - journal: IJournalPoster; - - accountsDepGraph: any; - - /** - * Journal poster. - * @param {IJournalPoster} journal - */ - constructor(journal: IJournalPoster) { - this.journal = journal; - this.accountsDepGraph = this.journal.accountsDepGraph; - } -} \ No newline at end of file diff --git a/packages/server/src/services/Accounting/JournalPoster.ts b/packages/server/src/services/Accounting/JournalPoster.ts deleted file mode 100644 index 1a2787488..000000000 --- a/packages/server/src/services/Accounting/JournalPoster.ts +++ /dev/null @@ -1,759 +0,0 @@ -import { omit, get, chain } from 'lodash'; -import moment from 'moment'; -import { Container } from 'typedi'; -import async from 'async'; -import JournalEntry from '@/services/Accounting/JournalEntry'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - IJournalEntry, - IJournalPoster, - IAccountChange, - IAccountsChange, - TEntryType, -} from '@/interfaces'; -import Knex from 'knex'; - -const CONTACTS_CONFIG = [ - { - accountBySlug: 'accounts-receivable', - contactService: 'customer', - assignRequired: true, - }, - { - accountBySlug: 'accounts-payable', - contactService: 'vendor', - assignRequired: true, - }, -]; - -export default class JournalPoster implements IJournalPoster { - tenantId: number; - tenancy: TenancyService; - logger: any; - models: any; - repositories: any; - - deletedEntriesIds: number[] = []; - entries: IJournalEntry[] = []; - balancesChange: IAccountsChange = {}; - accountsDepGraph: IAccountsChange; - - accountsBalanceTable: { [key: number]: number } = {}; - contactsBalanceTable: { - [key: number]: { credit: number; debit: number }[]; - } = {}; - saveContactBalanceQueue: any; - - /** - * Journal poster constructor. - * @param {number} tenantId - - */ - constructor(tenantId: number, accountsGraph?: any, trx?: Knex.Transaction) { - this.initTenancy(); - - this.tenantId = tenantId; - this.models = this.tenancy.models(tenantId); - this.repositories = this.tenancy.repositories(tenantId); - - if (accountsGraph) { - this.accountsDepGraph = accountsGraph; - } - this.trx = trx; - this.saveContactBalanceQueue = async.queue( - this.saveContactBalanceChangeTask.bind(this), - 10 - ); - } - - /** - * Initial tenancy. - * @private - */ - private initTenancy() { - try { - this.tenancy = Container.get(TenancyService); - this.logger = Container.get('logger'); - } catch (exception) { - throw new Error('Should execute this class inside tenancy area.'); - } - } - - /** - * Async initialize accounts dependency graph. - * @private - * @returns {Promise} - */ - public async initAccountsDepGraph(): Promise { - const { accountRepository } = this.repositories; - - if (!this.accountsDepGraph) { - const accountsDepGraph = await accountRepository.getDependencyGraph(); - this.accountsDepGraph = accountsDepGraph; - } - } - - /** - * Detarmines the ledger is empty. - */ - public isEmpty() { - return this.entries.length === 0; - } - - /** - * Writes the credit entry for the given account. - * @param {IJournalEntry} entry - - */ - public credit(entryModel: IJournalEntry): void { - if (entryModel instanceof JournalEntry === false) { - throw new Error('The entry is not instance of JournalEntry.'); - } - this.entries.push(entryModel.entry); - this.setAccountBalanceChange(entryModel.entry); - this.setContactBalanceChange(entryModel.entry); - } - - /** - * Writes the debit entry for the given account. - * @param {JournalEntry} entry - - */ - public debit(entryModel: IJournalEntry): void { - if (entryModel instanceof JournalEntry === false) { - throw new Error('The entry is not instance of JournalEntry.'); - } - this.entries.push(entryModel.entry); - this.setAccountBalanceChange(entryModel.entry); - this.setContactBalanceChange(entryModel.entry); - } - - /** - * Sets the contact balance change. - */ - private setContactBalanceChange(entry) { - if (!entry.contactId) { - return; - } - const change = { - debit: entry.debit || 0, - credit: entry.credit || 0, - account: entry.account, - }; - if (!this.contactsBalanceTable[entry.contactId]) { - this.contactsBalanceTable[entry.contactId] = []; - } - this.contactsBalanceTable[entry.contactId].push(change); - } - - /** - * Save contacts balance change. - */ - async saveContactsBalance() { - await this.initAccountsDepGraph(); - - const balanceChanges = Object.entries(this.contactsBalanceTable).map( - ([contactId, entries]) => ({ - contactId, - entries: entries.filter((entry) => { - const account = this.accountsDepGraph.getNodeData(entry.account); - - return ( - account && - CONTACTS_CONFIG.some((config) => { - return config.accountBySlug === account.slug; - }) - ); - }), - }) - ); - - const balanceEntries = chain(balanceChanges) - .map((change) => - change.entries.map((entry) => ({ - ...entry, - contactId: change.contactId, - })) - ) - .flatten() - .value(); - - return this.saveContactBalanceQueue.pushAsync(balanceEntries); - } - - /** - * Saves contact balance change task. - * @param {number} contactId - Contact id. - * @param {number} credit - Credit amount. - * @param {number} debit - Debit amount. - */ - async saveContactBalanceChangeTask({ contactId, credit, debit }) { - const { contactRepository } = this.repositories; - - const contact = await contactRepository.findOneById(contactId); - let balanceChange = 0; - - if (contact.contactNormal === 'credit') { - balanceChange += credit - debit; - } else { - balanceChange += debit - credit; - } - // Contact change balance. - await contactRepository.changeNumber( - { id: contactId }, - 'balance', - balanceChange, - this.trx - ); - } - - /** - * Sets account balance change. - * @param {JournalEntry} entry - * @param {String} type - */ - private setAccountBalanceChange(entry: IJournalEntry): void { - const accountChange: IAccountChange = { - debit: entry.debit, - credit: entry.credit, - }; - this._setAccountBalanceChange(entry.account, accountChange); - } - - /** - * Sets account balance change. - * @private - * @param {number} accountId - - * @param {IAccountChange} accountChange - */ - private _setAccountBalanceChange( - accountId: number, - accountChange: IAccountChange - ) { - this.balancesChange = this.accountBalanceChangeReducer( - this.balancesChange, - accountId, - accountChange - ); - } - - /** - * Accounts balance change reducer. - * @param {IAccountsChange} balancesChange - * @param {number} accountId - * @param {IAccountChange} accountChange - * @return {IAccountChange} - */ - private accountBalanceChangeReducer( - balancesChange: IAccountsChange, - accountId: number, - accountChange: IAccountChange - ) { - const change = { ...balancesChange }; - - if (!change[accountId]) { - change[accountId] = { credit: 0, debit: 0 }; - } - if (accountChange.credit) { - change[accountId].credit += accountChange.credit; - } - if (accountChange.debit) { - change[accountId].debit += accountChange.debit; - } - return change; - } - - /** - * Converts balance changes to array. - * @private - * @param {IAccountsChange} accountsChange - - * @return {Promise<{ account: number, change: number }>} - */ - private async convertBalanceChangesToArr( - accountsChange: IAccountsChange - ): Promise<{ account: number; change: number }[]> { - const mappedList: { account: number; change: number }[] = []; - const accountsIds: number[] = Object.keys(accountsChange).map((id) => - parseInt(id, 10) - ); - - await Promise.all( - accountsIds.map(async (account: number) => { - const accountChange = accountsChange[account]; - const accountNode = this.accountsDepGraph.getNodeData(account); - const normal = accountNode.accountNormal; - - let change = 0; - - if (accountChange.credit) { - change += - normal === 'credit' - ? accountChange.credit - : -1 * accountChange.credit; - } - if (accountChange.debit) { - change += - normal === 'debit' ? accountChange.debit : -1 * accountChange.debit; - } - mappedList.push({ account, change }); - }) - ); - return mappedList; - } - - /** - * Saves the balance change of journal entries. - * @returns {Promise} - */ - public async saveBalance() { - await this.initAccountsDepGraph(); - - const { Account } = this.models; - const accountsChange = this.balanceChangeWithDepends(this.balancesChange); - const balancesList = await this.convertBalanceChangesToArr(accountsChange); - const balancesAccounts = balancesList.map((b) => b.account); - - // Ensure the accounts has atleast zero in amount. - await Account.query(this.trx) - .where('amount', null) - .whereIn('id', balancesAccounts) - .patch({ amount: 0 }); - - const balanceUpdateOpers: Promise[] = []; - - balancesList.forEach((balance: { account: number; change: number }) => { - const method: string = balance.change < 0 ? 'decrement' : 'increment'; - - this.logger.info( - '[journal_poster] increment/decrement account balance.', - { - balance, - tenantId: this.tenantId, - } - ); - const query = Account.query(this.trx) - [method]('amount', Math.abs(balance.change)) - .where('id', balance.account); - - balanceUpdateOpers.push(query); - }); - - await Promise.all(balanceUpdateOpers); - this.resetAccountsBalanceChange(); - } - - /** - * Changes all accounts that dependencies of changed accounts. - * @param {IAccountsChange} accountsChange - * @returns {IAccountsChange} - */ - private balanceChangeWithDepends( - accountsChange: IAccountsChange - ): IAccountsChange { - const accountsIds = Object.keys(accountsChange); - let changes: IAccountsChange = {}; - - accountsIds.forEach((accountId) => { - const accountChange = accountsChange[accountId]; - const depAccountsIds = this.accountsDepGraph.dependantsOf(accountId); - - [accountId, ...depAccountsIds].forEach((account) => { - changes = this.accountBalanceChangeReducer( - changes, - account, - accountChange - ); - }); - }); - return changes; - } - - /** - * Resets accounts balance change. - * @private - */ - private resetAccountsBalanceChange() { - this.balancesChange = {}; - } - - /** - * Saves the stacked journal entries to the storage. - * @returns {Promise} - */ - public async saveEntries() { - const { transactionsRepository } = this.repositories; - const saveOperations: Promise[] = []; - - this.logger.info('[journal] trying to insert accounts transactions.'); - - this.entries.forEach((entry) => { - const oper = transactionsRepository.create( - { - accountId: entry.account, - ...omit(entry, ['account']), - }, - this.trx - ); - saveOperations.push(oper); - }); - await Promise.all(saveOperations); - } - - /** - * Reverses the stacked journal entries. - */ - public reverseEntries() { - const reverseEntries: IJournalEntry[] = []; - - this.entries.forEach((entry) => { - const reverseEntry = { ...entry }; - - if (entry.credit) { - reverseEntry.debit = entry.credit; - } - if (entry.debit) { - reverseEntry.credit = entry.debit; - } - reverseEntries.push(reverseEntry); - }); - this.entries = reverseEntries; - } - - /** - * Removes all stored entries or by the given in ids. - * @param {Array} ids - - */ - removeEntries(ids: number[] = []) { - const targetIds = ids.length <= 0 ? this.entries.map((e) => e.id) : ids; - const removeEntries = this.entries.filter( - (e) => targetIds.indexOf(e.id) !== -1 - ); - this.entries = this.entries.filter((e) => targetIds.indexOf(e.id) === -1); - - removeEntries.forEach((entry) => { - entry.credit = -1 * entry.credit; - entry.debit = -1 * entry.debit; - - this.setAccountBalanceChange(entry); - this.setContactBalanceChange(entry); - }); - this.deletedEntriesIds.push(...removeEntries.map((entry) => entry.id)); - } - - /** - * Delete all the stacked entries. - * @return {Promise} - */ - public async deleteEntries() { - const { transactionsRepository } = this.repositories; - - if (this.deletedEntriesIds.length > 0) { - await transactionsRepository.deleteWhereIdIn( - this.deletedEntriesIds, - this.trx - ); - } - } - - /** - * Load fetched accounts journal entries. - * @param {IJournalEntry[]} entries - - */ - fromTransactions(transactions) { - transactions.forEach((transaction) => { - this.entries.push({ - ...transaction, - referenceTypeFormatted: transaction.referenceTypeFormatted, - account: transaction.accountId, - accountNormal: get(transaction, 'account.accountNormal'), - }); - }); - } - - /** - * Calculates the entries balance change. - * @public - */ - public calculateEntriesBalanceChange() { - this.entries.forEach((entry) => { - if (entry.credit) { - this.setAccountBalanceChange(entry, 'credit'); - } - if (entry.debit) { - this.setAccountBalanceChange(entry, 'debit'); - } - }); - } - - static fromTransactions(entries, ...args: [number, ...any]) { - const journal = new this(...args); - journal.fromTransactions(entries); - - return journal; - } - - /** - * Retrieve the closing balance for the given account and closing date. - * @param {Number} accountId - - * @param {Date} closingDate - - * @param {string} dataType? - - * @return {number} - */ - getClosingBalance( - accountId: number, - closingDate: Date | string, - dateType: string = 'day' - ): number { - let closingBalance = 0; - const momentClosingDate = moment(closingDate); - - this.entries.forEach((entry) => { - // Can not continue if not before or event same closing date. - if ( - (!momentClosingDate.isAfter(entry.date, dateType) && - !momentClosingDate.isSame(entry.date, dateType)) || - (entry.account !== accountId && accountId) - ) { - return; - } - if (entry.accountNormal === 'credit') { - closingBalance += entry.credit ? entry.credit : -1 * entry.debit; - } else if (entry.accountNormal === 'debit') { - closingBalance += entry.debit ? entry.debit : -1 * entry.credit; - } - }); - return closingBalance; - } - - /** - * Retrieve the given account balance with dependencies accounts. - * @param {Number} accountId - - * @param {Date} closingDate - - * @param {String} dateType - - * @return {Number} - */ - getAccountBalance( - accountId: number, - closingDate: Date | string, - dateType: string - ) { - const accountNode = this.accountsDepGraph.getNodeData(accountId); - const depAccountsIds = this.accountsDepGraph.dependenciesOf(accountId); - const depAccounts = depAccountsIds.map((id) => - this.accountsDepGraph.getNodeData(id) - ); - - let balance: number = 0; - - [...depAccounts, accountNode].forEach((account) => { - const closingBalance = this.getClosingBalance( - account.id, - closingDate, - dateType - ); - this.accountsBalanceTable[account.id] = closingBalance; - balance += this.accountsBalanceTable[account.id]; - }); - return balance; - } - - /** - * Retrieve the credit/debit sumation for the given account and date. - * @param {Number} account - - * @param {Date|String} closingDate - - */ - getTrialBalance(accountId, closingDate) { - const momentClosingDate = moment(closingDate); - const result = { - credit: 0, - debit: 0, - balance: 0, - }; - this.entries.forEach((entry) => { - if ( - (!momentClosingDate.isAfter(entry.date, 'day') && - !momentClosingDate.isSame(entry.date, 'day')) || - (entry.account !== accountId && accountId) - ) { - return; - } - result.credit += entry.credit; - result.debit += entry.debit; - - if (entry.accountNormal === 'credit') { - result.balance += entry.credit - entry.debit; - } else if (entry.accountNormal === 'debit') { - result.balance += entry.debit - entry.credit; - } - }); - return result; - } - - /** - * Retrieve trial balance of the given account with depends. - * @param {Number} accountId - * @param {Date} closingDate - * @param {String} dateType - * @return {Number} - */ - - getTrialBalanceWithDepands( - accountId: number, - closingDate: Date, - dateType: string - ) { - const accountNode = this.accountsDepGraph.getNodeData(accountId); - const depAccountsIds = this.accountsDepGraph.dependenciesOf(accountId); - const depAccounts = depAccountsIds.map((id) => - this.accountsDepGraph.getNodeData(id) - ); - const trialBalance = { credit: 0, debit: 0, balance: 0 }; - - [...depAccounts, accountNode].forEach((account) => { - const _trialBalance = this.getTrialBalance( - account.id, - closingDate, - dateType - ); - - trialBalance.credit += _trialBalance.credit; - trialBalance.debit += _trialBalance.debit; - trialBalance.balance += _trialBalance.balance; - }); - return trialBalance; - } - - getContactTrialBalance( - accountId: number, - contactId: number, - contactType: string, - closingDate?: Date | string, - openingDate?: Date | string - ) { - const momentClosingDate = moment(closingDate); - const momentOpeningDate = moment(openingDate); - const trial = { - credit: 0, - debit: 0, - balance: 0, - }; - - this.entries.forEach((entry) => { - if ( - (closingDate && - !momentClosingDate.isAfter(entry.date, 'day') && - !momentClosingDate.isSame(entry.date, 'day')) || - (openingDate && - !momentOpeningDate.isBefore(entry.date, 'day') && - !momentOpeningDate.isSame(entry.date)) || - (accountId && entry.account !== accountId) || - (contactId && entry.contactId !== contactId) || - entry.contactType !== contactType - ) { - return; - } - if (entry.credit) { - trial.balance -= entry.credit; - trial.credit += entry.credit; - } - if (entry.debit) { - trial.balance += entry.debit; - trial.debit += entry.debit; - } - }); - return trial; - } - - /** - * Retrieve total balnace of the given customer/vendor contact. - * @param {Number} accountId - * @param {Number} contactId - * @param {String} contactType - * @param {Date} closingDate - */ - getContactBalance( - accountId: number, - contactId: number, - contactType: string, - closingDate: Date, - openingDate: Date - ) { - const momentClosingDate = moment(closingDate); - let balance = 0; - - this.entries.forEach((entry) => { - if ( - (closingDate && - !momentClosingDate.isAfter(entry.date, 'day') && - !momentClosingDate.isSame(entry.date, 'day')) || - (entry.account !== accountId && accountId) || - (contactId && entry.contactId !== contactId) || - entry.contactType !== contactType - ) { - return; - } - if (entry.credit) { - balance -= entry.credit; - } - if (entry.debit) { - balance += entry.debit; - } - }); - return balance; - } - - getAccountEntries(accountId: number) { - return this.entries.filter((entry) => entry.account === accountId); - } - - /** - * Retrieve account entries with depents accounts. - * @param {number} accountId - - */ - getAccountEntriesWithDepents(accountId: number) { - const depAccountsIds = this.accountsDepGraph.dependenciesOf(accountId); - const accountsIds = [accountId, ...depAccountsIds]; - - return this.entries.filter( - (entry) => accountsIds.indexOf(entry.account) !== -1 - ); - } - - /** - * Retrieve total balnace of the given customer/vendor contact. - * @param {Number} accountId - * @param {Number} contactId - * @param {String} contactType - * @param {Date} closingDate - */ - getEntriesBalance(entries) { - let balance = 0; - - entries.forEach((entry) => { - if (entry.credit) { - balance -= entry.credit; - } - if (entry.debit) { - balance += entry.debit; - } - }); - return balance; - } - - getContactEntries(contactId: number, openingDate: Date, closingDate?: Date) { - const momentClosingDate = moment(closingDate); - const momentOpeningDate = moment(openingDate); - - return this.entries.filter((entry) => { - if ( - (closingDate && - !momentClosingDate.isAfter(entry.date, 'day') && - !momentClosingDate.isSame(entry.date, 'day')) || - (openingDate && - !momentOpeningDate.isBefore(entry.date, 'day') && - !momentOpeningDate.isSame(entry.date)) || - entry.contactId === contactId - ) { - return true; - } - return false; - }); - } -} diff --git a/packages/server/src/services/Accounting/Ledger.ts b/packages/server/src/services/Accounting/Ledger.ts deleted file mode 100644 index 6e7519bc8..000000000 --- a/packages/server/src/services/Accounting/Ledger.ts +++ /dev/null @@ -1,291 +0,0 @@ -import moment from 'moment'; -import { defaultTo, sumBy, uniqBy } from 'lodash'; -import { IAccountTransaction, ILedger, ILedgerEntry } from '@/interfaces'; - -export default class Ledger implements ILedger { - readonly entries: ILedgerEntry[]; - - /** - * Constructor method. - * @param {ILedgerEntry[]} entries - */ - constructor(entries: ILedgerEntry[]) { - this.entries = entries; - } - - /** - * Filters the ledegr entries. - * @param callback - * @returns {ILedger} - */ - public filter(callback): ILedger { - const entries = this.entries.filter(callback); - return new Ledger(entries); - } - - /** - * Retrieve the all entries of the ledger. - * @return {ILedgerEntry[]} - */ - public getEntries(): ILedgerEntry[] { - return this.entries; - } - - /** - * Filters entries by th given contact id and returns a new ledger. - * @param {number} contactId - * @returns {ILedger} - */ - public whereContactId(contactId: number): ILedger { - return this.filter((entry) => entry.contactId === contactId); - } - - /** - * Filters entries by the given account id and returns a new ledger. - * @param {number} accountId - * @returns {ILedger} - */ - public whereAccountId(accountId: number): ILedger { - return this.filter((entry) => entry.accountId === accountId); - } - - /** - * Filters entries by the given accounts ids then returns a new ledger. - * @param {number[]} accountIds - * @returns {ILedger} - */ - public whereAccountsIds(accountIds: number[]): ILedger { - return this.filter((entry) => accountIds.indexOf(entry.accountId) !== -1); - } - - /** - * Filters entries that before or same the given date and returns a new ledger. - * @param {Date|string} fromDate - * @returns {ILedger} - */ - public whereFromDate(fromDate: Date | string): ILedger { - const fromDateParsed = moment(fromDate); - - return this.filter( - (entry) => - fromDateParsed.isBefore(entry.date) || fromDateParsed.isSame(entry.date) - ); - } - - /** - * Filters ledger entries that after the given date and retruns a new ledger. - * @param {Date|string} toDate - * @returns {ILedger} - */ - public whereToDate(toDate: Date | string): ILedger { - const toDateParsed = moment(toDate); - - return this.filter( - (entry) => - toDateParsed.isAfter(entry.date) || toDateParsed.isSame(entry.date) - ); - } - - /** - * Filters the ledget entries by the given currency code. - * @param {string} currencyCode - - * @returns {ILedger} - */ - public whereCurrencyCode(currencyCode: string): ILedger { - return this.filter((entry) => entry.currencyCode === currencyCode); - } - - /** - * Filters the ledger entries by the given branch id. - * @param {number} branchId - * @returns {ILedger} - */ - public whereBranch(branchId: number): ILedger { - return this.filter((entry) => entry.branchId === branchId); - } - - /** - * - * @param {number} projectId - * @returns {ILedger} - */ - public whereProject(projectId: number): ILedger { - return this.filter((entry) => entry.projectId === projectId); - } - - /** - * Filters the ledger entries by the given item id. - * @param {number} itemId - * @returns {ILedger} - */ - public whereItem(itemId: number): ILedger { - return this.filter((entry) => entry.itemId === itemId); - } - - /** - * Retrieve the closing balance of the entries. - * @returns {number} - */ - public getClosingBalance(): number { - let closingBalance = 0; - - this.entries.forEach((entry) => { - if (entry.accountNormal === 'credit') { - closingBalance += entry.credit - entry.debit; - } else if (entry.accountNormal === 'debit') { - closingBalance += entry.debit - entry.credit; - } - }); - return closingBalance; - } - - /** - * Retrieves the closing credit of the entries. - * @returns {number} - */ - public getClosingCredit(): number { - return sumBy(this.entries, 'credit'); - } - - /** - * Retrieves the closing debit of the entries. - * @returns {number} - */ - public getClosingDebit(): number { - return sumBy(this.entries, 'debit'); - } - - /** - * Retrieve the closing balance of the entries. - * @returns {number} - */ - public getForeignClosingBalance(): number { - let closingBalance = 0; - - this.entries.forEach((entry) => { - const exchangeRate = entry.exchangeRate || 1; - - if (entry.accountNormal === 'credit') { - closingBalance += (entry.credit - entry.debit) / exchangeRate; - } else if (entry.accountNormal === 'debit') { - closingBalance += (entry.debit - entry.credit) / exchangeRate; - } - }); - return closingBalance; - } - - /** - * Detarmines whether the ledger has no entries. - * @returns {boolean} - */ - public isEmpty(): boolean { - return this.entries.length === 0; - } - - /** - * Retrieves the accounts ids of the entries uniquely. - * @returns {number[]} - */ - public getAccountsIds = (): number[] => { - return uniqBy(this.entries, 'accountId').map( - (e: ILedgerEntry) => e.accountId - ); - }; - - /** - * Retrieves the contacts ids of the entries uniquely. - * @returns {number[]} - */ - public getContactsIds = (): number[] => { - return uniqBy(this.entries, 'contactId') - .filter((e: ILedgerEntry) => e.contactId) - .map((e: ILedgerEntry) => e.contactId); - }; - - /** - * Reverses the ledger entries. - * @returns {Ledger} - */ - public reverse = (): Ledger => { - const newEntries = this.entries.map((e) => { - const credit = e.debit; - const debit = e.credit; - - return { ...e, credit, debit }; - }); - return new Ledger(newEntries); - }; - - // --------------------------------- - // # STATIC METHODS. - // ---------------------------------- - - /** - * Mappes the account transactions to ledger entries. - * @param {IAccountTransaction[]} entries - * @returns {ILedgerEntry[]} - */ - static mappingTransactions(entries: IAccountTransaction[]): ILedgerEntry[] { - return entries.map(this.mapTransaction); - } - - /** - * Mappes the account transaction to ledger entry. - * @param {IAccountTransaction} entry - * @returns {ILedgerEntry} - */ - static mapTransaction(entry: IAccountTransaction): ILedgerEntry { - return { - credit: defaultTo(entry.credit, 0), - debit: defaultTo(entry.debit, 0), - - exchangeRate: entry.exchangeRate, - currencyCode: entry.currencyCode, - - accountNormal: entry.account.accountNormal, - accountId: entry.accountId, - contactId: entry.contactId, - - date: entry.date, - - transactionId: entry.referenceId, - transactionType: entry.referenceType, - transactionSubType: entry.transactionType, - - transactionNumber: entry.transactionNumber, - referenceNumber: entry.referenceNumber, - - index: entry.index, - indexGroup: entry.indexGroup, - - entryId: entry.id, - branchId: entry.branchId, - projectId: entry.projectId, - - taxRateId: entry.taxRateId, - taxRate: entry.taxRate, - - note: entry.note, - }; - } - - /** - * Mappes the account transactions to ledger entries. - * @param {IAccountTransaction[]} transactions - * @returns {ILedger} - */ - static fromTransactions(transactions: IAccountTransaction[]): Ledger { - const entries = Ledger.mappingTransactions(transactions); - return new Ledger(entries); - } - - /** - * Retrieve the transaction amount. - * @param {number} credit - Credit amount. - * @param {number} debit - Debit amount. - * @param {string} normal - Credit or debit. - */ - static getAmount(credit: number, debit: number, normal: string) { - return normal === 'credit' ? credit - debit : debit - credit; - } -} diff --git a/packages/server/src/services/Accounting/LedgerContactStorage.ts b/packages/server/src/services/Accounting/LedgerContactStorage.ts deleted file mode 100644 index 11825db8f..000000000 --- a/packages/server/src/services/Accounting/LedgerContactStorage.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Service, Inject } from 'typedi'; -import async from 'async'; -import { Knex } from 'knex'; -import { - ILedger, - ILedgerEntry, - ISaleContactsBalanceQueuePayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TenantMetadata } from '@/system/models'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -@Service() -export class LedgerContactsBalanceStorage { - @Inject() - private tenancy: HasTenancyService; - - /** - * - * @param {number} tenantId - - * @param {ILedger} ledger - - * @param {Knex.Transaction} trx - - * @returns {Promise} - */ - public saveContactsBalance = async ( - tenantId: number, - ledger: ILedger, - trx?: Knex.Transaction - ): Promise => { - // Save contact balance queue. - const saveContactsBalanceQueue = async.queue( - this.saveContactBalanceTask, - 10 - ); - // Retrieves the effected contacts ids. - const effectedContactsIds = ledger.getContactsIds(); - - effectedContactsIds.forEach((contactId: number) => { - saveContactsBalanceQueue.push({ tenantId, contactId, ledger, trx }); - }); - if (effectedContactsIds.length > 0) await saveContactsBalanceQueue.drain(); - }; - - /** - * - * @param {ISaleContactsBalanceQueuePayload} task - * @returns {Promise} - */ - private saveContactBalanceTask = async ( - task: ISaleContactsBalanceQueuePayload - ) => { - const { tenantId, contactId, ledger, trx } = task; - - await this.saveContactBalance(tenantId, ledger, contactId, trx); - }; - - /** - * Filters AP/AR ledger entries. - * @param {number} tenantId - * @param {Knex.Transaction} trx - * @returns {Promise<(entry: ILedgerEntry) => boolean>} - */ - private filterARAPLedgerEntris = async ( - tenantId: number, - trx?: Knex.Transaction - ): Promise<(entry: ILedgerEntry) => boolean> => { - const { Account } = this.tenancy.models(tenantId); - - const ARAPAccounts = await Account.query(trx).whereIn('accountType', [ - ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE, - ACCOUNT_TYPE.ACCOUNTS_PAYABLE, - ]); - const ARAPAccountsIds = ARAPAccounts.map((a) => a.id); - - return (entry: ILedgerEntry) => { - return ARAPAccountsIds.indexOf(entry.accountId) !== -1; - }; - }; - - /** - * - * @param {number} tenantId - * @param {ILedger} ledger - * @param {number} contactId - * @returns {Promise} - */ - private saveContactBalance = async ( - tenantId: number, - ledger: ILedger, - contactId: number, - trx?: Knex.Transaction - ): Promise => { - const { Contact } = this.tenancy.models(tenantId); - const contact = await Contact.query(trx).findById(contactId); - - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Detarmines whether the contact has foreign currency. - const isForeignContact = contact.currencyCode !== tenantMeta.baseCurrency; - - // Filters the ledger base on the given contact id. - const filterARAPLedgerEntris = await this.filterARAPLedgerEntris( - tenantId, - trx - ); - const contactLedger = ledger - // Filter entries only that have contact id. - .whereContactId(contactId) - // Filter entries on AR/AP accounts. - .filter(filterARAPLedgerEntris); - - const closingBalance = isForeignContact - ? contactLedger - .whereCurrencyCode(contact.currencyCode) - .getForeignClosingBalance() - : contactLedger.getClosingBalance(); - - await this.changeContactBalance(tenantId, contactId, closingBalance, trx); - }; - - /** - * - * @param {number} tenantId - * @param {number} contactId - * @param {number} change - * @returns - */ - private changeContactBalance = ( - tenantId: number, - contactId: number, - change: number, - trx?: Knex.Transaction - ) => { - const { Contact } = this.tenancy.models(tenantId); - - return Contact.changeAmount({ id: contactId }, 'balance', change, trx); - }; -} diff --git a/packages/server/src/services/Accounting/LedgerEntriesStorage.ts b/packages/server/src/services/Accounting/LedgerEntriesStorage.ts deleted file mode 100644 index 8f789e3cf..000000000 --- a/packages/server/src/services/Accounting/LedgerEntriesStorage.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import async from 'async'; -import { - ILedgerEntry, - ISaveLedgerEntryQueuePayload, - ILedger, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { transformLedgerEntryToTransaction } from './utils'; - -// Filter the blank entries. -const filterBlankEntry = (entry: ILedgerEntry) => Boolean(entry.credit || entry.debit); - -@Service() -export class LedgerEntriesStorage { - @Inject() - private tenancy: HasTenancyService; - /** - * Saves entries of the given ledger. - * @param {number} tenantId - * @param {ILedger} ledger - * @param {Knex.Transaction} knex - * @returns {Promise} - */ - public saveEntries = async ( - tenantId: number, - ledger: ILedger, - trx?: Knex.Transaction - ) => { - const saveEntryQueue = async.queue(this.saveEntryTask, 10); - const entries = ledger.filter(filterBlankEntry).getEntries(); - - entries.forEach((entry) => { - saveEntryQueue.push({ tenantId, entry, trx }); - }); - if (entries.length > 0) await saveEntryQueue.drain(); - }; - - /** - * Deletes the ledger entries. - * @param {number} tenantId - * @param {ILedger} ledger - * @param {Knex.Transaction} trx - */ - public deleteEntries = async ( - tenantId: number, - ledger: ILedger, - trx?: Knex.Transaction - ) => { - const { AccountTransaction } = this.tenancy.models(tenantId); - - const entriesIds = ledger - .getEntries() - .filter((e) => e.entryId) - .map((e) => e.entryId); - - await AccountTransaction.query(trx).whereIn('id', entriesIds).delete(); - }; - - /** - * Saves the ledger entry to the account transactions repository. - * @param {number} tenantId - * @param {ILedgerEntry} entry - * @returns {Promise} - */ - private saveEntry = async ( - tenantId: number, - entry: ILedgerEntry, - trx?: Knex.Transaction - ): Promise => { - const { AccountTransaction } = this.tenancy.models(tenantId); - const transaction = transformLedgerEntryToTransaction(entry); - - await AccountTransaction.query(trx).insert(transaction); - }; - - /** - * Save the ledger entry to the transactions repository async task. - * @param {ISaveLedgerEntryQueuePayload} task - * @returns {Promise} - */ - private saveEntryTask = async ( - task: ISaveLedgerEntryQueuePayload - ): Promise => { - const { entry, tenantId, trx } = task; - - await this.saveEntry(tenantId, entry, trx); - }; -} diff --git a/packages/server/src/services/Accounting/LedgerStorageRevert.ts b/packages/server/src/services/Accounting/LedgerStorageRevert.ts deleted file mode 100644 index 8d9b39971..000000000 --- a/packages/server/src/services/Accounting/LedgerStorageRevert.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Inject } from 'typedi'; -import { castArray } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import LedgerStorageService from './LedgerStorageService'; -import Ledger from './Ledger'; -import { Knex } from 'knex'; - -export class LedgerRevert { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Reverts the jouranl entries. - * @param {number|number[]} referenceId - Reference id. - * @param {string} referenceType - Reference type. - */ - public getTransactionsByReference = async ( - tenantId: number, - referenceId: number | number[], - referenceType: string | string[] - ) => { - const { AccountTransaction } = this.tenancy.models(tenantId); - - const transactions = await AccountTransaction.query() - .whereIn('reference_type', castArray(referenceType)) - .whereIn('reference_id', castArray(referenceId)) - .withGraphFetched('account'); - - return transactions; - }; - - /** - * - * @param tenantId - * @param referenceId - * @param referenceType - * @param trx - */ - public revertGLEntries = async ( - tenantId: number, - referenceId: number | number[], - referenceType: string | string[], - trx?: Knex.Transaction - ) => { - // - const transactions = await this.getTransactionsByReference( - tenantId, - referenceId, - referenceType - ); - // Creates a new ledger from transaction and reverse the entries. - const ledger = Ledger.fromTransactions(transactions); - const reversedLedger = ledger.reverse(); - - // - await this.ledgerStorage.commit(tenantId, reversedLedger, trx); - }; -} diff --git a/packages/server/src/services/Accounting/LedgerStorageService.ts b/packages/server/src/services/Accounting/LedgerStorageService.ts deleted file mode 100644 index 616ae6230..000000000 --- a/packages/server/src/services/Accounting/LedgerStorageService.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { ILedger } from '@/interfaces'; -import { LedgerContactsBalanceStorage } from './LedgerContactStorage'; -import { LedegrAccountsStorage } from './LedgetAccountStorage'; -import { LedgerEntriesStorage } from './LedgerEntriesStorage'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Ledger from './Ledger'; -@Service() -export default class LedgerStorageService { - @Inject() - private ledgerEntriesService: LedgerEntriesStorage; - - @Inject() - private ledgerContactsBalance: LedgerContactsBalanceStorage; - - @Inject() - private ledgerAccountsBalance: LedegrAccountsStorage; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Commit the ledger to the storage layer as one unit-of-work. - * @param {number} tenantId - * @param {ILedger} ledger - * @returns {Promise} - */ - public commit = async ( - tenantId: number, - ledger: ILedger, - trx?: Knex.Transaction - ): Promise => { - const tasks = [ - // Saves the ledger entries. - this.ledgerEntriesService.saveEntries(tenantId, ledger, trx), - - // Mutates the associated accounts balances. - this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx), - - // Mutates the associated contacts balances. - this.ledgerContactsBalance.saveContactsBalance(tenantId, ledger, trx), - ]; - await Promise.all(tasks); - }; - - /** - * Deletes the given ledger and revert balances. - * @param {number} tenantId - * @param {ILedger} ledger - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public delete = async ( - tenantId: number, - ledger: ILedger, - trx?: Knex.Transaction - ) => { - const tasks = [ - // Deletes the ledger entries. - this.ledgerEntriesService.deleteEntries(tenantId, ledger, trx), - - // Mutates the associated accounts balances. - this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx), - - // Mutates the associated contacts balances. - this.ledgerContactsBalance.saveContactsBalance(tenantId, ledger, trx), - ]; - await Promise.all(tasks); - }; - - /** - * @param tenantId - * @param referenceId - * @param referenceType - * @param trx - */ - public deleteByReference = async ( - tenantId: number, - referenceId: number | number[], - referenceType: string | string[], - trx?: Knex.Transaction - ) => { - const { transactionsRepository } = this.tenancy.repositories(tenantId); - - // Retrieves the transactions of the given reference. - const transactions = - await transactionsRepository.getTransactionsByReference( - referenceId, - referenceType - ); - // Creates a new ledger from transaction and reverse the entries. - const reversedLedger = Ledger.fromTransactions(transactions).reverse(); - - // Deletes and reverts the balances. - await this.delete(tenantId, reversedLedger, trx); - }; -} diff --git a/packages/server/src/services/Accounting/LedgetAccountStorage.ts b/packages/server/src/services/Accounting/LedgetAccountStorage.ts deleted file mode 100644 index 92d02c07e..000000000 --- a/packages/server/src/services/Accounting/LedgetAccountStorage.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { Service, Inject } from 'typedi'; -import async from 'async'; -import { Knex } from 'knex'; -import { uniq } from 'lodash'; -import { ILedger, ISaveAccountsBalanceQueuePayload } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class LedegrAccountsStorage { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve depepants ids of the give accounts ids. - * @param {number[]} accountsIds - * @param depGraph - * @returns {number[]} - */ - private getDependantsAccountsIds = ( - accountsIds: number[], - depGraph - ): number[] => { - const depAccountsIds = []; - - accountsIds.forEach((accountId: number) => { - const depAccountIds = depGraph.dependantsOf(accountId); - depAccountsIds.push(accountId, ...depAccountIds); - }); - return uniq(depAccountsIds); - }; - - /** - * - * @param {number} tenantId - * @param {number[]} accountsIds - * @returns {number[]} - */ - private findDependantsAccountsIds = async ( - tenantId: number, - accountsIds: number[], - trx?: Knex.Transaction - ): Promise => { - const { accountRepository } = this.tenancy.repositories(tenantId); - const accountsGraph = await accountRepository.getDependencyGraph(null, trx); - - return this.getDependantsAccountsIds(accountsIds, accountsGraph); - }; - - /** - * Atomic mutation for accounts balances. - * @param {number} tenantId - * @param {ILedger} ledger - * @param {Knex.Transaction} trx - - * @returns {Promise} - */ - public saveAccountsBalance = async ( - tenantId: number, - ledger: ILedger, - trx?: Knex.Transaction - ): Promise => { - // Initiate a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.saveAccountBalanceTask, - 10 - ); - const effectedAccountsIds = ledger.getAccountsIds(); - const dependAccountsIds = await this.findDependantsAccountsIds( - tenantId, - effectedAccountsIds, - trx - ); - dependAccountsIds.forEach((accountId: number) => { - saveAccountsBalanceQueue.push({ tenantId, ledger, accountId, trx }); - }); - if (dependAccountsIds.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Async task mutates the given account balance. - * @param {ISaveAccountsBalanceQueuePayload} task - * @returns {Promise} - */ - private saveAccountBalanceTask = async ( - task: ISaveAccountsBalanceQueuePayload - ): Promise => { - const { tenantId, ledger, accountId, trx } = task; - - await this.saveAccountBalanceFromLedger(tenantId, ledger, accountId, trx); - }; - - /** - * Saves specific account balance from the given ledger. - * @param {number} tenantId - * @param {ILedger} ledger - * @param {number} accountId - * @param {Knex.Transaction} trx - - * @returns {Promise} - */ - private saveAccountBalanceFromLedger = async ( - tenantId: number, - ledger: ILedger, - accountId: number, - trx?: Knex.Transaction - ): Promise => { - const { Account } = this.tenancy.models(tenantId); - const account = await Account.query(trx).findById(accountId); - - // Filters the ledger entries by the current account. - const accountLedger = ledger.whereAccountId(accountId); - - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Detarmines whether the account has foreign currency. - const isAccountForeign = account.currencyCode !== tenantMeta.baseCurrency; - - // Calculates the closing foreign balance by the given currency if account was has - // foreign currency otherwise get closing balance. - const closingBalance = isAccountForeign - ? accountLedger - .whereCurrencyCode(account.currencyCode) - .getForeignClosingBalance() - : accountLedger.getClosingBalance(); - - await this.saveAccountBalance(tenantId, accountId, closingBalance, trx); - }; - - /** - * Saves the account balance. - * @param {number} tenantId - * @param {number} accountId - * @param {number} change - * @param {Knex.Transaction} trx - - * @returns {Promise} - */ - private saveAccountBalance = async ( - tenantId: number, - accountId: number, - change: number, - trx?: Knex.Transaction - ) => { - const { Account } = this.tenancy.models(tenantId); - - // Ensure the account has atleast zero in amount. - await Account.query(trx) - .findById(accountId) - .whereNull('amount') - .patch({ amount: 0 }); - - await Account.changeAmount({ id: accountId }, 'amount', change, trx); - }; -} diff --git a/packages/server/src/services/Accounting/utils.ts b/packages/server/src/services/Accounting/utils.ts deleted file mode 100644 index 2edc25b97..000000000 --- a/packages/server/src/services/Accounting/utils.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { IAccountTransaction, ILedgerEntry } from '@/interfaces'; - -export const transformLedgerEntryToTransaction = ( - entry: ILedgerEntry -): IAccountTransaction => { - return { - date: entry.date, - - credit: entry.credit, - debit: entry.debit, - - currencyCode: entry.currencyCode, - exchangeRate: entry.exchangeRate, - - accountId: entry.accountId, - contactId: entry.contactId, - - referenceType: entry.transactionType, - referenceId: entry.transactionId, - - transactionNumber: entry.transactionNumber, - transactionType: entry.transactionSubType, - - referenceNumber: entry.referenceNumber, - - note: entry.note, - - index: entry.index, - indexGroup: entry.indexGroup, - - branchId: entry.branchId, - userId: entry.userId, - itemId: entry.itemId, - projectId: entry.projectId, - - costable: entry.costable, - - taxRateId: entry.taxRateId, - taxRate: entry.taxRate, - }; -}; diff --git a/packages/server/src/services/Accounts/AccountTransactionTransformer.ts b/packages/server/src/services/Accounts/AccountTransactionTransformer.ts deleted file mode 100644 index d0e3e487f..000000000 --- a/packages/server/src/services/Accounts/AccountTransactionTransformer.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { IAccountTransaction } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; - -export default class AccountTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'date', - 'formattedDate', - 'transactionType', - 'transactionId', - 'transactionTypeFormatted', - 'credit', - 'debit', - 'formattedCredit', - 'formattedDebit', - 'fcCredit', - 'fcDebit', - 'formattedFcCredit', - 'formattedFcDebit', - ]; - }; - - /** - * Exclude all attributes of the model. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieves the formatted date. - * @returns {string} - */ - public formattedDate(transaction: IAccountTransaction) { - return this.formatDate(transaction.date); - } - - /** - * Retrieves the formatted transaction type. - * @returns {string} - */ - public transactionTypeFormatted(transaction: IAccountTransaction) { - return this.context.i18n.__(transaction.referenceTypeFormatted); - } - - /** - * Retrieves the tranasction type. - * @returns {string} - */ - public transactionType(transaction: IAccountTransaction) { - return transaction.referenceType; - } - - /** - * Retrieves the transaction id. - * @returns {number} - */ - public transactionId(transaction: IAccountTransaction) { - return transaction.referenceId; - } - - /** - * Retrieves the credit amount. - * @returns {string} - */ - protected formattedCredit(transaction: IAccountTransaction) { - return this.formatMoney(transaction.credit, { - excerptZero: true, - }); - } - - /** - * Retrieves the credit amount. - * @returns {string} - */ - protected formattedDebit(transaction: IAccountTransaction) { - return this.formatMoney(transaction.debit, { - excerptZero: true, - }); - } - - /** - * Retrieves the foreign credit amount. - * @returns {number} - */ - protected fcCredit(transaction: IAccountTransaction) { - return transaction.credit * transaction.exchangeRate; - } - - /** - * Retrieves the foreign debit amount. - * @returns {number} - */ - protected fcDebit(transaction: IAccountTransaction) { - return transaction.debit * transaction.exchangeRate; - } - - /** - * Retrieves the formatted foreign credit amount. - * @returns {string} - */ - protected formattedFcCredit(transaction: IAccountTransaction) { - return this.formatMoney(this.fcCredit(transaction), { - currencyCode: transaction.currencyCode, - excerptZero: true, - }); - } - - /** - * Retrieves the formatted foreign debit amount. - * @returns {string} - */ - protected formattedFcDebit(transaction: IAccountTransaction) { - return this.formatMoney(this.fcDebit(transaction), { - currencyCode: transaction.currencyCode, - excerptZero: true, - }); - } -} diff --git a/packages/server/src/services/Accounts/AccountTransform.ts b/packages/server/src/services/Accounts/AccountTransform.ts deleted file mode 100644 index 2b3ec5229..000000000 --- a/packages/server/src/services/Accounts/AccountTransform.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { IAccount, IAccountsStructureType } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { - assocDepthLevelToObjectTree, - flatToNestedArray, - formatNumber, - nestedArrayToFlatten, -} from 'utils'; - -export class AccountTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'accountTypeLabel', - 'accountNormalFormatted', - 'formattedAmount', - 'flattenName', - 'bankBalanceFormatted', - 'lastFeedsUpdatedAtFormatted', - 'isFeedsPaused', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['plaidItem']; - }; - - /** - * Retrieves the flatten name with all dependants accounts names. - * @param {IAccount} account - - * @returns {string} - */ - public flattenName = (account: IAccount): string => { - const parentDependantsIds = this.options.accountsGraph.dependantsOf( - account.id - ); - const prefixAccounts = parentDependantsIds.map((dependId) => { - const node = this.options.accountsGraph.getNodeData(dependId); - return `${node.name}: `; - }); - return `${prefixAccounts}${account.name}`; - }; - - /** - * Retrieve formatted account amount. - * @param {IAccount} invoice - * @returns {string} - */ - protected formattedAmount = (account: IAccount): string => { - return formatNumber(account.amount, { currencyCode: account.currencyCode }); - }; - - /** - * Retrieves the formatted bank balance. - * @param {IAccount} account - * @returns {string} - */ - protected bankBalanceFormatted = (account: IAccount): string => { - return formatNumber(account.bankBalance, { - currencyCode: account.currencyCode, - }); - }; - - /** - * Retrieves the formatted last feeds update at. - * @param {IAccount} account - * @returns {string} - */ - protected lastFeedsUpdatedAtFormatted = (account: IAccount): string => { - return this.formatDate(account.lastFeedsUpdatedAt); - }; - - /** - * Detarmines whether the bank account connection is paused. - * @param account - * @returns {boolean} - */ - protected isFeedsPaused = (account: any): boolean => { - return account.plaidItem?.isPaused || false; - }; - - /** - * Retrieves formatted account type label. - * @returns {string} - */ - protected accountTypeLabel = (account: any): string => { - return this.context.i18n.__(account.accountTypeLabel); - }; - - /** - * Retrieves formatted account normal. - * @returns {string} - */ - protected accountNormalFormatted = (account: any): string => { - return this.context.i18n.__(account.accountNormalFormatted); - }; - - /** - * Transformes the accounts collection to flat or nested array. - * @param {IAccount[]} - * @returns {IAccount[]} - */ - protected postCollectionTransform = (accounts: IAccount[]) => { - // Transfom the flatten to accounts tree. - const transformed = flatToNestedArray(accounts, { - id: 'id', - parentId: 'parentAccountId', - }); - // Associate `accountLevel` attr to indicate object depth. - const transformed2 = assocDepthLevelToObjectTree( - transformed, - 1, - 'accountLevel' - ); - return this.options.structure === IAccountsStructureType.Flat - ? nestedArrayToFlatten(transformed2) - : transformed2; - }; -} diff --git a/packages/server/src/services/Accounts/AccountsApplication.ts b/packages/server/src/services/Accounts/AccountsApplication.ts deleted file mode 100644 index 8a06b410f..000000000 --- a/packages/server/src/services/Accounts/AccountsApplication.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IAccount, - IAccountCreateDTO, - IAccountEditDTO, - IAccountResponse, - IAccountsFilter, - IAccountsTransactionsFilter, - IFilterMeta, - IGetAccountTransactionPOJO, -} from '@/interfaces'; -import { CreateAccount } from './CreateAccount'; -import { DeleteAccount } from './DeleteAccount'; -import { EditAccount } from './EditAccount'; -import { ActivateAccount } from './ActivateAccount'; -import { GetAccounts } from './GetAccounts'; -import { GetAccount } from './GetAccount'; -import { GetAccountTransactions } from './GetAccountTransactions'; -import { Knex } from 'knex'; - -@Service() -export class AccountsApplication { - @Inject() - private createAccountService: CreateAccount; - - @Inject() - private deleteAccountService: DeleteAccount; - - @Inject() - private editAccountService: EditAccount; - - @Inject() - private activateAccountService: ActivateAccount; - - @Inject() - private getAccountsService: GetAccounts; - - @Inject() - private getAccountService: GetAccount; - - @Inject() - private getAccountTransactionsService: GetAccountTransactions; - - /** - * Creates a new account. - * @param {number} tenantId - * @param {IAccountCreateDTO} accountDTO - * @returns {Promise} - */ - public createAccount = ( - tenantId: number, - accountDTO: IAccountCreateDTO, - trx?: Knex.Transaction - ): Promise => { - return this.createAccountService.createAccount(tenantId, accountDTO, trx); - }; - - /** - * Deletes the given account. - * @param {number} tenantId - * @param {number} accountId - * @returns {Promise} - */ - public deleteAccount = (tenantId: number, accountId: number) => { - return this.deleteAccountService.deleteAccount(tenantId, accountId); - }; - - /** - * Edits the given account. - * @param {number} tenantId - * @param {number} accountId - * @param {IAccountEditDTO} accountDTO - * @returns - */ - public editAccount = ( - tenantId: number, - accountId: number, - accountDTO: IAccountEditDTO - ) => { - return this.editAccountService.editAccount(tenantId, accountId, accountDTO); - }; - - /** - * Activate the given account. - * @param {number} tenantId - - * @param {number} accountId - - */ - public activateAccount = (tenantId: number, accountId: number) => { - return this.activateAccountService.activateAccount( - tenantId, - accountId, - true - ); - }; - - /** - * Inactivate the given account. - * @param {number} tenantId - - * @param {number} accountId - - */ - public inactivateAccount = (tenantId: number, accountId: number) => { - return this.activateAccountService.activateAccount( - tenantId, - accountId, - false - ); - }; - - /** - * Retrieves the account details. - * @param {number} tenantId - * @param {number} accountId - * @returns {Promise} - */ - public getAccount = (tenantId: number, accountId: number) => { - return this.getAccountService.getAccount(tenantId, accountId); - }; - - /** - * Retrieves the accounts list. - * @param {number} tenantId - * @param {IAccountsFilter} filterDTO - * @returns {Promise<{ accounts: IAccountResponse[]; filterMeta: IFilterMeta }>} - */ - public getAccounts = ( - tenantId: number, - filterDTO: IAccountsFilter - ): Promise<{ accounts: IAccountResponse[]; filterMeta: IFilterMeta }> => { - return this.getAccountsService.getAccountsList(tenantId, filterDTO); - }; - - /** - * Retrieves the given account transactions. - * @param {number} tenantId - * @param {IAccountsTransactionsFilter} filter - * @returns {Promise} - */ - public getAccountsTransactions = ( - tenantId: number, - filter: IAccountsTransactionsFilter - ): Promise => { - return this.getAccountTransactionsService.getAccountsTransactions( - tenantId, - filter - ); - }; -} diff --git a/packages/server/src/services/Accounts/AccountsExportable.ts b/packages/server/src/services/Accounts/AccountsExportable.ts deleted file mode 100644 index b188a465b..000000000 --- a/packages/server/src/services/Accounts/AccountsExportable.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { AccountsApplication } from './AccountsApplication'; -import { Exportable } from '../Export/Exportable'; -import { IAccountsFilter, IAccountsStructureType } from '@/interfaces'; -import { EXPORT_SIZE_LIMIT } from '../Export/constants'; - -@Service() -export class AccountsExportable extends Exportable { - @Inject() - private accountsApplication: AccountsApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IAccountsFilter) { - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - inactiveMode: false, - ...query, - structure: IAccountsStructureType.Flat, - pageSize: EXPORT_SIZE_LIMIT, - page: 1, - } as IAccountsFilter; - - return this.accountsApplication - .getAccounts(tenantId, parsedQuery) - .then((output) => output.accounts); - } -} diff --git a/packages/server/src/services/Accounts/AccountsImportable.SampleData.ts b/packages/server/src/services/Accounts/AccountsImportable.SampleData.ts deleted file mode 100644 index 1757bd498..000000000 --- a/packages/server/src/services/Accounts/AccountsImportable.SampleData.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const AccountsSampleData = [ - { - 'Account Name': 'Utilities Expense', - 'Account Code': 9000, - Type: 'Expense', - Description: 'Omnis voluptatum consequatur.', - Active: 'T', - 'Currency Code': '', - }, - { - 'Account Name': 'Unearned Revenue', - 'Account Code': 9010, - Type: 'Long Term Liability', - Description: 'Autem odit voluptas nihil unde.', - Active: 'T', - 'Currency Code': '', - }, - { - 'Account Name': 'Long-Term Debt', - 'Account Code': 9020, - Type: 'Long Term Liability', - Description: 'In voluptas cumque exercitationem.', - Active: 'T', - 'Currency Code': '', - }, - { - 'Account Name': 'Salaries and Wages Expense', - 'Account Code': 9030, - Type: 'Expense', - Description: 'Assumenda aspernatur soluta aliquid perspiciatis quasi.', - Active: 'T', - 'Currency Code': '', - }, - { - 'Account Name': 'Rental Income', - 'Account Code': 9040, - Type: 'Income', - Description: 'Omnis possimus amet occaecati inventore.', - Active: 'T', - 'Currency Code': '', - }, - { - 'Account Name': 'Paypal', - 'Account Code': 9050, - Type: 'Bank', - Description: 'In voluptas cumque exercitationem.', - Active: 'T', - 'Currency Code': '', - }, -]; diff --git a/packages/server/src/services/Accounts/AccountsImportable.ts b/packages/server/src/services/Accounts/AccountsImportable.ts deleted file mode 100644 index 28a7a18a3..000000000 --- a/packages/server/src/services/Accounts/AccountsImportable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IAccountCreateDTO } from '@/interfaces'; -import { CreateAccount } from './CreateAccount'; -import { Importable } from '../Import/Importable'; -import { AccountsSampleData } from './AccountsImportable.SampleData'; - -@Service() -export class AccountsImportable extends Importable { - @Inject() - private createAccountService: CreateAccount; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: IAccountCreateDTO, - trx?: Knex.Transaction - ) { - return this.createAccountService.createAccount( - tenantId, - createAccountDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return AccountsSampleData; - } -} diff --git a/packages/server/src/services/Accounts/AccountsTypesServices.ts b/packages/server/src/services/Accounts/AccountsTypesServices.ts deleted file mode 100644 index 25de9ab5c..000000000 --- a/packages/server/src/services/Accounts/AccountsTypesServices.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAccountsTypesService, IAccountType } from '@/interfaces'; -import AccountTypesUtils from '@/lib/AccountTypes'; -import I18nService from '@/services/I18n/I18nService'; - - -@Service() -export default class AccountsTypesService implements IAccountsTypesService { - @Inject() - i18nService: I18nService; - - /** - * Retrieve all accounts types. - * @param {number} tenantId - - * @return {IAccountType} - */ - public getAccountsTypes(tenantId: number): IAccountType[] { - const accountTypes = AccountTypesUtils.getList(); - return this.i18nService.i18nMapper(accountTypes, ['label'], tenantId); - } -} diff --git a/packages/server/src/services/Accounts/ActivateAccount.ts b/packages/server/src/services/Accounts/ActivateAccount.ts deleted file mode 100644 index 26afd836d..000000000 --- a/packages/server/src/services/Accounts/ActivateAccount.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { IAccountEventActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class ActivateAccount { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Activates/Inactivates the given account. - * @param {number} tenantId - * @param {number} accountId - * @param {boolean} activate - */ - public activateAccount = async ( - tenantId: number, - accountId: number, - activate?: boolean - ) => { - const { Account } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Retrieve the given account or throw not found error. - const oldAccount = await Account.query() - .findById(accountId) - .throwIfNotFound(); - - // Get all children accounts. - const accountsGraph = await accountRepository.getDependencyGraph(); - const dependenciesAccounts = accountsGraph.dependenciesOf(accountId); - - const patchAccountsIds = [...dependenciesAccounts, accountId]; - - // Activate account and associated transactions under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Activate and inactivate the given accounts ids. - activate - ? await accountRepository.activateByIds(patchAccountsIds, trx) - : await accountRepository.inactivateByIds(patchAccountsIds, trx); - - // Triggers `onAccountActivated` event. - this.eventPublisher.emitAsync(events.accounts.onActivated, { - tenantId, - accountId, - trx, - } as IAccountEventActivatedPayload); - }); - }; -} diff --git a/packages/server/src/services/Accounts/CommandAccountValidators.ts b/packages/server/src/services/Accounts/CommandAccountValidators.ts deleted file mode 100644 index ed4d7ffbd..000000000 --- a/packages/server/src/services/Accounts/CommandAccountValidators.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { Inject, Service } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { IAccountDTO, IAccount, IAccountCreateDTO } from '@/interfaces'; -import AccountTypesUtils from '@/lib/AccountTypes'; -import { ERRORS, MAX_ACCOUNTS_CHART_DEPTH } from './constants'; - -@Service() -export class CommandAccountValidators { - @Inject() - private tenancy: TenancyService; - - /** - * Throws error if the account was prefined. - * @param {IAccount} account - */ - public throwErrorIfAccountPredefined(account: IAccount) { - if (account.predefined) { - throw new ServiceError(ERRORS.ACCOUNT_PREDEFINED); - } - } - - /** - * Diff account type between new and old account, throw service error - * if they have different account type. - * - * @param {IAccount|IAccountDTO} oldAccount - * @param {IAccount|IAccountDTO} newAccount - */ - public async isAccountTypeChangedOrThrowError( - oldAccount: IAccount | IAccountDTO, - newAccount: IAccount | IAccountDTO - ) { - if (oldAccount.accountType !== newAccount.accountType) { - throw new ServiceError(ERRORS.ACCOUNT_TYPE_NOT_ALLOWED_TO_CHANGE); - } - } - - /** - * Retrieve account type or throws service error. - * @param {number} tenantId - - * @param {number} accountTypeId - - * @return {IAccountType} - */ - public getAccountTypeOrThrowError(accountTypeKey: string) { - const accountType = AccountTypesUtils.getType(accountTypeKey); - - if (!accountType) { - throw new ServiceError(ERRORS.ACCOUNT_TYPE_NOT_FOUND); - } - return accountType; - } - - /** - * Retrieve parent account or throw service error. - * @param {number} tenantId - * @param {number} accountId - * @param {number} notAccountId - */ - public async getParentAccountOrThrowError( - tenantId: number, - accountId: number, - notAccountId?: number - ) { - const { Account } = this.tenancy.models(tenantId); - - const parentAccount = await Account.query() - .findById(accountId) - .onBuild((query) => { - if (notAccountId) { - query.whereNot('id', notAccountId); - } - }); - if (!parentAccount) { - throw new ServiceError(ERRORS.PARENT_ACCOUNT_NOT_FOUND); - } - return parentAccount; - } - - /** - * Throws error if the account type was not unique on the storage. - * @param {number} tenantId - * @param {string} accountCode - * @param {number} notAccountId - */ - public async isAccountCodeUniqueOrThrowError( - tenantId: number, - accountCode: string, - notAccountId?: number - ) { - const { Account } = this.tenancy.models(tenantId); - - const account = await Account.query() - .where('code', accountCode) - .onBuild((query) => { - if (notAccountId) { - query.whereNot('id', notAccountId); - } - }); - if (account.length > 0) { - throw new ServiceError( - ERRORS.ACCOUNT_CODE_NOT_UNIQUE, - 'Account code is not unique.' - ); - } - } - - /** - * Validates the account name uniquiness. - * @param {number} tenantId - * @param {string} accountName - * @param {number} notAccountId - Ignore the account id. - */ - public async validateAccountNameUniquiness( - tenantId: number, - accountName: string, - notAccountId?: number - ) { - const { Account } = this.tenancy.models(tenantId); - - const foundAccount = await Account.query() - .findOne('name', accountName) - .onBuild((query) => { - if (notAccountId) { - query.whereNot('id', notAccountId); - } - }); - if (foundAccount) { - throw new ServiceError( - ERRORS.ACCOUNT_NAME_NOT_UNIQUE, - 'Account name is not unique.' - ); - } - } - - /** - * Validates the given account type supports multi-currency. - * @param {IAccountDTO} accountDTO - - */ - public validateAccountTypeSupportCurrency = ( - accountDTO: IAccountCreateDTO, - baseCurrency: string - ) => { - // Can't continue to validate the type has multi-currency feature - // if the given currency equals the base currency or not assigned. - if (accountDTO.currencyCode === baseCurrency || !accountDTO.currencyCode) { - return; - } - const meta = AccountTypesUtils.getType(accountDTO.accountType); - - // Throw error if the account type does not support multi-currency. - if (!meta?.multiCurrency) { - throw new ServiceError(ERRORS.ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY); - } - }; - - /** - * Validates the account DTO currency code whether equals the currency code of - * parent account. - * @param {IAccountCreateDTO} accountDTO - * @param {IAccount} parentAccount - * @param {string} baseCurrency - - * @throws {ServiceError(ERRORS.ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT)} - */ - public validateCurrentSameParentAccount = ( - accountDTO: IAccountCreateDTO, - parentAccount: IAccount, - baseCurrency: string - ) => { - // If the account DTO currency not assigned and the parent account has no base currency. - if ( - !accountDTO.currencyCode && - parentAccount.currencyCode !== baseCurrency - ) { - throw new ServiceError(ERRORS.ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT); - } - // If the account DTO is assigned and not equals the currency code of parent account. - if ( - accountDTO.currencyCode && - parentAccount.currencyCode !== accountDTO.currencyCode - ) { - throw new ServiceError(ERRORS.ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT); - } - }; - - /** - * Throws service error if parent account has different type. - * @param {IAccountDTO} accountDTO - * @param {IAccount} parentAccount - */ - public throwErrorIfParentHasDiffType( - accountDTO: IAccountDTO, - parentAccount: IAccount - ) { - if (accountDTO.accountType !== parentAccount.accountType) { - throw new ServiceError(ERRORS.PARENT_ACCOUNT_HAS_DIFFERENT_TYPE); - } - } - - /** - * Retrieve account of throw service error in case account not found. - * @param {number} tenantId - * @param {number} accountId - * @return {IAccount} - */ - public async getAccountOrThrowError(tenantId: number, accountId: number) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const account = await accountRepository.findOneById(accountId); - - if (!account) { - throw new ServiceError(ERRORS.ACCOUNT_NOT_FOUND); - } - return account; - } - - /** - * Validates the max depth level of accounts chart. - * @param {numebr} tenantId - Tenant id. - * @param {number} parentAccountId - Parent account id. - */ - public async validateMaxParentAccountDepthLevels( - tenantId: number, - parentAccountId: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const accountsGraph = await accountRepository.getDependencyGraph(); - - const parentDependantsIds = accountsGraph.dependantsOf(parentAccountId); - - if (parentDependantsIds.length >= MAX_ACCOUNTS_CHART_DEPTH) { - throw new ServiceError(ERRORS.PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL); - } - } -} diff --git a/packages/server/src/services/Accounts/CreateAccount.ts b/packages/server/src/services/Accounts/CreateAccount.ts deleted file mode 100644 index 27ecbf580..000000000 --- a/packages/server/src/services/Accounts/CreateAccount.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { kebabCase } from 'lodash'; -import { Knex } from 'knex'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - IAccount, - IAccountEventCreatedPayload, - IAccountEventCreatingPayload, - IAccountCreateDTO, - CreateAccountParams, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { TenantMetadata } from '@/system/models'; -import { CommandAccountValidators } from './CommandAccountValidators'; - -@Service() -export class CreateAccount { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandAccountValidators; - - /** - * Authorize the account creation. - * @param {number} tenantId - * @param {IAccountCreateDTO} accountDTO - */ - private authorize = async ( - tenantId: number, - accountDTO: IAccountCreateDTO, - baseCurrency: string, - params?: CreateAccountParams - ) => { - // Validate account name uniquiness. - if (!params.ignoreUniqueName) { - await this.validator.validateAccountNameUniquiness( - tenantId, - accountDTO.name - ); - } - // Validate the account code uniquiness. - if (accountDTO.code) { - await this.validator.isAccountCodeUniqueOrThrowError( - tenantId, - accountDTO.code - ); - } - // Retrieve the account type meta or throw service error if not found. - this.validator.getAccountTypeOrThrowError(accountDTO.accountType); - - // Ingore the parent account validation if not presented. - if (accountDTO.parentAccountId) { - const parentAccount = await this.validator.getParentAccountOrThrowError( - tenantId, - accountDTO.parentAccountId - ); - this.validator.throwErrorIfParentHasDiffType(accountDTO, parentAccount); - - // Inherit active status from parent account. - accountDTO.active = parentAccount.active; - - // Validate should currency code be the same currency of parent account. - this.validator.validateCurrentSameParentAccount( - accountDTO, - parentAccount, - baseCurrency - ); - // Validates the max depth level of accounts chart. - await this.validator.validateMaxParentAccountDepthLevels( - tenantId, - accountDTO.parentAccountId - ); - } - // Validates the given account type supports the multi-currency. - this.validator.validateAccountTypeSupportCurrency(accountDTO, baseCurrency); - }; - - /** - * Transformes the create account DTO to input model. - * @param {IAccountCreateDTO} createAccountDTO - */ - private transformDTOToModel = ( - createAccountDTO: IAccountCreateDTO, - baseCurrency: string - ) => { - return { - ...createAccountDTO, - slug: kebabCase(createAccountDTO.name), - currencyCode: createAccountDTO.currencyCode || baseCurrency, - - // Mark the account is Plaid owner since Plaid item/account is defined on creating. - isSyncingOwner: Boolean( - createAccountDTO.plaidAccountId || createAccountDTO.plaidItemId - ), - }; - }; - - /** - * Creates a new account on the storage. - * @param {number} tenantId - * @param {IAccountCreateDTO} accountDTO - * @returns {Promise} - */ - public createAccount = async ( - tenantId: number, - accountDTO: IAccountCreateDTO, - trx?: Knex.Transaction, - params: CreateAccountParams = { ignoreUniqueName: false } - ): Promise => { - const { Account } = this.tenancy.models(tenantId); - - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Authorize the account creation. - await this.authorize(tenantId, accountDTO, tenantMeta.baseCurrency, params); - // Transformes the DTO to model. - const accountInputModel = this.transformDTOToModel( - accountDTO, - tenantMeta.baseCurrency - ); - // Creates a new account with associated transactions under unit-of-work envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onAccountCreating` event. - await this.eventPublisher.emitAsync(events.accounts.onCreating, { - tenantId, - accountDTO, - trx, - } as IAccountEventCreatingPayload); - - // Inserts account to the storage. - const account = await Account.query(trx).insertAndFetch({ - ...accountInputModel, - }); - // Triggers `onAccountCreated` event. - await this.eventPublisher.emitAsync(events.accounts.onCreated, { - tenantId, - account, - accountId: account.id, - trx, - } as IAccountEventCreatedPayload); - - return account; - }, - trx - ); - }; -} diff --git a/packages/server/src/services/Accounts/DeleteAccount.ts b/packages/server/src/services/Accounts/DeleteAccount.ts deleted file mode 100644 index 632c78f62..000000000 --- a/packages/server/src/services/Accounts/DeleteAccount.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { IAccountEventDeletedPayload, IAccount } from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandAccountValidators } from './CommandAccountValidators'; -import { ERRORS } from './constants'; - -@Service() -export class DeleteAccount { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandAccountValidators; - - /** - * Authorize account delete. - * @param {number} tenantId - Tenant id. - * @param {number} accountId - Account id. - */ - private authorize = async ( - tenantId: number, - accountId: number, - oldAccount: IAccount - ) => { - // Throw error if the account was predefined. - this.validator.throwErrorIfAccountPredefined(oldAccount); - }; - - /** - * Unlink the given parent account with children accounts. - * @param {number} tenantId - - * @param {number|number[]} parentAccountId - - */ - private async unassociateChildrenAccountsFromParent( - tenantId: number, - parentAccountId: number | number[], - trx?: Knex.Transaction - ) { - const { Account } = this.tenancy.models(tenantId); - const accountsIds = Array.isArray(parentAccountId) - ? parentAccountId - : [parentAccountId]; - - await Account.query(trx) - .whereIn('parent_account_id', accountsIds) - .patch({ parent_account_id: null }); - } - - /** - * Deletes the account from the storage. - * @param {number} tenantId - * @param {number} accountId - */ - public deleteAccount = async ( - tenantId: number, - accountId: number - ): Promise => { - const { Account } = this.tenancy.models(tenantId); - - // Retrieve account or not found service error. - const oldAccount = await Account.query() - .findById(accountId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.ACCOUNT_HAS_ASSOCIATED_TRANSACTIONS, - excludeRelations: ['uncategorizedTransactions', 'plaidItem'] - }); - // Authorize before delete account. - await this.authorize(tenantId, accountId, oldAccount); - - // Deletes the account and associated transactions under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onAccountDelete` event. - await this.eventPublisher.emitAsync(events.accounts.onDelete, { - trx, - oldAccount, - tenantId, - } as IAccountEventDeletedPayload); - - // Unlink the parent account from children accounts. - await this.unassociateChildrenAccountsFromParent( - tenantId, - accountId, - trx - ); - // Deletes account by the given id. - await Account.query(trx).findById(accountId).delete(); - - // Triggers `onAccountDeleted` event. - await this.eventPublisher.emitAsync(events.accounts.onDeleted, { - tenantId, - accountId, - oldAccount, - trx, - } as IAccountEventDeletedPayload); - }); - }; -} diff --git a/packages/server/src/services/Accounts/EditAccount.ts b/packages/server/src/services/Accounts/EditAccount.ts deleted file mode 100644 index 3f55f4eb0..000000000 --- a/packages/server/src/services/Accounts/EditAccount.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - IAccountEventEditedPayload, - IAccountEditDTO, - IAccount, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandAccountValidators } from './CommandAccountValidators'; - -@Service() -export class EditAccount { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandAccountValidators; - - /** - * Authorize the account editing. - * @param {number} tenantId - * @param {number} accountId - * @param {IAccountEditDTO} accountDTO - * @param {IAccount} oldAccount - - */ - private authorize = async ( - tenantId: number, - accountId: number, - accountDTO: IAccountEditDTO, - oldAccount: IAccount - ) => { - // Validate account name uniquiness. - await this.validator.validateAccountNameUniquiness( - tenantId, - accountDTO.name, - accountId - ); - // Validate the account type should be not mutated. - await this.validator.isAccountTypeChangedOrThrowError( - oldAccount, - accountDTO - ); - // Validate the account code not exists on the storage. - if (accountDTO.code && accountDTO.code !== oldAccount.code) { - await this.validator.isAccountCodeUniqueOrThrowError( - tenantId, - accountDTO.code, - oldAccount.id - ); - } - // Retrieve the parent account of throw not found service error. - if (accountDTO.parentAccountId) { - const parentAccount = await this.validator.getParentAccountOrThrowError( - tenantId, - accountDTO.parentAccountId, - oldAccount.id - ); - this.validator.throwErrorIfParentHasDiffType(accountDTO, parentAccount); - } - }; - - /** - * Edits details of the given account. - * @param {number} tenantId - * @param {number} accountId - * @param {IAccountDTO} accountDTO - */ - public async editAccount( - tenantId: number, - accountId: number, - accountDTO: IAccountEditDTO - ): Promise { - const { Account } = this.tenancy.models(tenantId); - - // Retrieve the old account or throw not found service error. - const oldAccount = await Account.query() - .findById(accountId) - .throwIfNotFound(); - - // Authorize the account editing. - await this.authorize(tenantId, accountId, accountDTO, oldAccount); - - // Edits account and associated transactions under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onAccountEditing` event. - await this.eventPublisher.emitAsync(events.accounts.onEditing, { - tenantId, - oldAccount, - accountDTO, - }); - // Update the account on the storage. - const account = await Account.query(trx) - .findById(accountId) - .update({ ...accountDTO }); - - // Triggers `onAccountEdited` event. - await this.eventPublisher.emitAsync(events.accounts.onEdited, { - tenantId, - account, - oldAccount, - trx, - } as IAccountEventEditedPayload); - - return account; - }); - } -} diff --git a/packages/server/src/services/Accounts/GetAccount.ts b/packages/server/src/services/Accounts/GetAccount.ts deleted file mode 100644 index 5ad0cc917..000000000 --- a/packages/server/src/services/Accounts/GetAccount.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { AccountTransformer } from './AccountTransform'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class GetAccount { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve the given account details. - * @param {number} tenantId - * @param {number} accountId - */ - public getAccount = async (tenantId: number, accountId: number) => { - const { Account } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Find the given account or throw not found error. - const account = await Account.query() - .findById(accountId) - .withGraphFetched('plaidItem') - .throwIfNotFound(); - - const accountsGraph = await accountRepository.getDependencyGraph(); - - // Transformes the account model to POJO. - const transformed = await this.transformer.transform( - tenantId, - account, - new AccountTransformer(), - { accountsGraph } - ); - const eventPayload = { tenantId, accountId }; - - // Triggers `onAccountViewed` event. - await this.eventPublisher.emitAsync(events.accounts.onViewed, eventPayload); - - return transformed; - }; -} diff --git a/packages/server/src/services/Accounts/GetAccountTransactions.ts b/packages/server/src/services/Accounts/GetAccountTransactions.ts deleted file mode 100644 index 7022666ee..000000000 --- a/packages/server/src/services/Accounts/GetAccountTransactions.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IAccountsTransactionsFilter, - IAccountTransaction, - IGetAccountTransactionPOJO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import AccountTransactionTransformer from './AccountTransactionTransformer'; - -@Service() -export class GetAccountTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the accounts transactions. - * @param {number} tenantId - - * @param {IAccountsTransactionsFilter} filter - - */ - public getAccountsTransactions = async ( - tenantId: number, - filter: IAccountsTransactionsFilter - ): Promise => { - const { AccountTransaction, Account } = this.tenancy.models(tenantId); - - // Retrieve the given account or throw not found error. - if (filter.accountId) { - await Account.query().findById(filter.accountId).throwIfNotFound(); - } - const transactions = await AccountTransaction.query().onBuild((query) => { - query.orderBy('date', 'DESC'); - - if (filter.accountId) { - query.where('account_id', filter.accountId); - } - query.withGraphFetched('account'); - query.withGraphFetched('contact'); - query.limit(filter.limit || 50); - }); - // Transform the account transaction. - return this.transformer.transform( - tenantId, - transactions, - new AccountTransactionTransformer() - ); - }; -} diff --git a/packages/server/src/services/Accounts/GetAccounts.ts b/packages/server/src/services/Accounts/GetAccounts.ts deleted file mode 100644 index 17d19bad2..000000000 --- a/packages/server/src/services/Accounts/GetAccounts.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { - IAccountsFilter, - IAccountResponse, - IFilterMeta, - IAccountsStructureType, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { AccountTransformer } from './AccountTransform'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { flatToNestedArray } from '@/utils'; - -@Service() -export class GetAccounts { - @Inject() - private tenancy: TenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve accounts datatable list. - * @param {number} tenantId - * @param {IAccountsFilter} accountsFilter - * @returns {Promise<{ accounts: IAccountResponse[]; filterMeta: IFilterMeta }>} - */ - public getAccountsList = async ( - tenantId: number, - filterDTO: IAccountsFilter - ): Promise<{ accounts: IAccountResponse[]; filterMeta: IFilterMeta }> => { - const { Account } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Parses the stringified filter roles. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - Account, - filter - ); - // Retrieve accounts model based on the given query. - const accounts = await Account.query().onBuild((builder) => { - dynamicList.buildQuery()(builder); - builder.modify('inactiveMode', filter.inactiveMode); - }); - - const accountsGraph = await accountRepository.getDependencyGraph(); - - // Retrieves the transformed accounts collection. - const transformedAccounts = await this.transformer.transform( - tenantId, - accounts, - new AccountTransformer(), - { accountsGraph, structure: filterDTO.structure } - ); - - return { - accounts: transformedAccounts, - filterMeta: dynamicList.getResponseMeta(), - }; - }; - - /** - * Parsees accounts list filter DTO. - * @param filterDTO - * @returns - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Accounts/MutateBaseCurrencyAccounts.ts b/packages/server/src/services/Accounts/MutateBaseCurrencyAccounts.ts deleted file mode 100644 index 46abfc33b..000000000 --- a/packages/server/src/services/Accounts/MutateBaseCurrencyAccounts.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class MutateBaseCurrencyAccounts { - @Inject() - tenancy: HasTenancyService; - - /** - * Mutates the all accounts or the organziation. - * @param {number} tenantId - * @param {string} currencyCode - */ - public mutateAllAccountsCurrency = async ( - tenantId: number, - currencyCode: string - ) => { - const { Account } = this.tenancy.models(tenantId); - - await Account.query().update({ currencyCode }); - }; -} diff --git a/packages/server/src/services/Accounts/constants.ts b/packages/server/src/services/Accounts/constants.ts deleted file mode 100644 index deab658bc..000000000 --- a/packages/server/src/services/Accounts/constants.ts +++ /dev/null @@ -1,103 +0,0 @@ -export const ERRORS = { - ACCOUNT_NOT_FOUND: 'account_not_found', - ACCOUNT_TYPE_NOT_FOUND: 'account_type_not_found', - PARENT_ACCOUNT_NOT_FOUND: 'parent_account_not_found', - ACCOUNT_CODE_NOT_UNIQUE: 'account_code_not_unique', - ACCOUNT_NAME_NOT_UNIQUE: 'account_name_not_unqiue', - PARENT_ACCOUNT_HAS_DIFFERENT_TYPE: 'parent_has_different_type', - ACCOUNT_TYPE_NOT_ALLOWED_TO_CHANGE: 'account_type_not_allowed_to_changed', - ACCOUNT_PREDEFINED: 'account_predefined', - ACCOUNT_HAS_ASSOCIATED_TRANSACTIONS: 'account_has_associated_transactions', - PREDEFINED_ACCOUNTS: 'predefined_accounts', - ACCOUNTS_HAVE_TRANSACTIONS: 'accounts_have_transactions', - CLOSE_ACCOUNT_AND_TO_ACCOUNT_NOT_SAME_TYPE: - 'close_account_and_to_account_not_same_type', - ACCOUNTS_NOT_FOUND: 'accounts_not_found', - ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY: - 'ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY', - ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT: - 'ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT', - PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL: - 'PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL', -}; - -// Default views columns. -export const DEFAULT_VIEW_COLUMNS = [ - { key: 'name', label: 'Account name' }, - { key: 'code', label: 'Account code' }, - { key: 'account_type_label', label: 'Account type' }, - { key: 'account_normal', label: 'Account normal' }, - { key: 'amount', label: 'Balance' }, - { key: 'currencyCode', label: 'Currency' }, -]; - -export const MAX_ACCOUNTS_CHART_DEPTH = 5; - -// Accounts default views. -export const DEFAULT_VIEWS = [ - { - name: 'Assets', - slug: 'assets', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'root_type', comparator: 'equals', value: 'asset' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Liabilities', - slug: 'liabilities', - rolesLogicExpression: '1', - roles: [ - { - fieldKey: 'root_type', - index: 1, - comparator: 'equals', - value: 'liability', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Equity', - slug: 'equity', - rolesLogicExpression: '1', - roles: [ - { - fieldKey: 'root_type', - index: 1, - comparator: 'equals', - value: 'equity', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Income', - slug: 'income', - rolesLogicExpression: '1', - roles: [ - { - fieldKey: 'root_type', - index: 1, - comparator: 'equals', - value: 'income', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Expenses', - slug: 'expenses', - rolesLogicExpression: '1', - roles: [ - { - fieldKey: 'root_type', - index: 1, - comparator: 'equals', - value: 'expense', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; diff --git a/packages/server/src/services/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts b/packages/server/src/services/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts deleted file mode 100644 index ba65e963d..000000000 --- a/packages/server/src/services/Accounts/susbcribers/MutateBaseCurrencyAccounts.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { MutateBaseCurrencyAccounts } from '../MutateBaseCurrencyAccounts'; - -@Service() -export class MutateBaseCurrencyAccountsSubscriber { - @Inject() - public mutateBaseCurrencyAccounts: MutateBaseCurrencyAccounts; - - /** - * Attaches the events with handles. - * @param bus - */ - attach(bus) { - bus.subscribe( - events.organization.baseCurrencyUpdated, - this.updateAccountsCurrencyOnBaseCurrencyMutated - ); - } - - /** - * Updates the all accounts currency once the base currency - * of the organization is mutated. - */ - private updateAccountsCurrencyOnBaseCurrencyMutated = async ({ - tenantId, - organizationDTO, - }) => { - await this.mutateBaseCurrencyAccounts.mutateAllAccountsCurrency( - tenantId, - organizationDTO.baseCurrency - ); - }; -} diff --git a/packages/server/src/services/Attachments/AttachmentTransformer.ts b/packages/server/src/services/Attachments/AttachmentTransformer.ts deleted file mode 100644 index e7cf70f91..000000000 --- a/packages/server/src/services/Attachments/AttachmentTransformer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class AttachmentTransformer extends Transformer { - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['id', 'createdAt']; - }; - - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return []; - }; -} diff --git a/packages/server/src/services/Attachments/AttachmentsApplication.ts b/packages/server/src/services/Attachments/AttachmentsApplication.ts deleted file mode 100644 index 6e75c9783..000000000 --- a/packages/server/src/services/Attachments/AttachmentsApplication.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { UploadDocument } from './UploadDocument'; -import { DeleteAttachment } from './DeleteAttachment'; -import { GetAttachment } from './GetAttachment'; -import { LinkAttachment } from './LinkAttachment'; -import { UnlinkAttachment } from './UnlinkAttachment'; -import { getAttachmentPresignedUrl } from './GetAttachmentPresignedUrl'; - -@Service() -export class AttachmentsApplication { - @Inject() - private uploadDocumentService: UploadDocument; - - @Inject() - private deleteDocumentService: DeleteAttachment; - - @Inject() - private getDocumentService: GetAttachment; - - @Inject() - private linkDocumentService: LinkAttachment; - - @Inject() - private unlinkDocumentService: UnlinkAttachment; - - @Inject() - private getPresignedUrlService: getAttachmentPresignedUrl; - - /** - * Saves the metadata of uploaded document to S3 on database. - * @param {number} tenantId - * @param {} file - * @returns {Promise} - */ - public upload(tenantId: number, file: any) { - return this.uploadDocumentService.upload(tenantId, file); - } - - /** - * Deletes the give file attachment file key. - * @param {number} tenantId - * @param {string} documentKey - * @returns {Promise} - */ - public delete(tenantId: number, documentKey: string) { - return this.deleteDocumentService.delete(tenantId, documentKey); - } - - /** - * Retrieves the document data. - * @param {number} tenantId - * @param {string} documentKey - */ - public get(tenantId: number, documentKey: string) { - return this.getDocumentService.getAttachment(tenantId, documentKey); - } - - /** - * Links the given document to resource model. - * @param {number} tenantId - * @param {string} filekey - * @param {string} modelRef - * @param {number} modelId - * @returns - */ - public link( - tenantId: number, - filekey: string, - modelRef: string, - modelId: number - ) { - return this.linkDocumentService.link(tenantId, filekey, modelRef, modelId); - } - - /** - * Unlinks the given document from resource model. - * @param {number} tenantId - * @param {string} filekey - * @param {string} modelRef - * @param {number} modelId - * @returns - */ - public unlink( - tenantId: number, - filekey: string, - modelRef: string, - modelId: number - ) { - return this.unlinkDocumentService.unlink( - tenantId, - filekey, - modelRef, - modelId - ); - } - - /** - * Retrieves the presigned url of the given attachment key. - * @param {number} tenantId - * @param {string} key - * @returns {Promise} - */ - public getPresignedUrl(tenantId: number, key: string): Promise { - return this.getPresignedUrlService.getPresignedUrl(tenantId, key); - } -} diff --git a/packages/server/src/services/Attachments/DeleteAttachment.ts b/packages/server/src/services/Attachments/DeleteAttachment.ts deleted file mode 100644 index 78db4b3d0..000000000 --- a/packages/server/src/services/Attachments/DeleteAttachment.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { DeleteObjectCommand } from '@aws-sdk/client-s3'; -import { Inject, Service } from 'typedi'; -import { s3 } from '@/lib/S3/S3'; -import HasTenancyService from '../Tenancy/TenancyService'; -import config from '@/config'; -import UnitOfWork from '../UnitOfWork'; -import { Knex } from 'knex'; - -@Service() -export class DeleteAttachment { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the give file attachment file key. - * @param {number} tenantId - * @param {string} filekey - */ - async delete(tenantId: number, filekey: string): Promise { - const { Document, DocumentLink } = this.tenancy.models(tenantId); - - const params = { - Bucket: config.s3.bucket, - Key: filekey, - }; - await s3.send(new DeleteObjectCommand(params)); - - const foundDocument = await Document.query() - .findOne('key', filekey) - .throwIfNotFound(); - - await this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Delete all document links - await DocumentLink.query(trx) - .where('documentId', foundDocument.id) - .delete(); - - // Delete thedocument. - await Document.query(trx).findById(foundDocument.id).delete(); - }); - } -} diff --git a/packages/server/src/services/Attachments/GetAttachment.ts b/packages/server/src/services/Attachments/GetAttachment.ts deleted file mode 100644 index 0f70cc9f9..000000000 --- a/packages/server/src/services/Attachments/GetAttachment.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Service } from 'typedi'; -import { GetObjectCommand } from '@aws-sdk/client-s3'; -import { s3 } from '@/lib/S3/S3'; -import config from '@/config'; - -@Service() -export class GetAttachment { - /** - * Retrieves data of the given document key. - * @param {number} tenantId - * @param {string} filekey - */ - async getAttachment(tenantId: number, filekey: string) { - const params = { - Bucket: config.s3.bucket, - Key: filekey, - }; - const data = await s3.send(new GetObjectCommand(params)); - - return data; - } -} diff --git a/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts b/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts deleted file mode 100644 index b76b5aa4e..000000000 --- a/packages/server/src/services/Attachments/GetAttachmentPresignedUrl.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { GetObjectCommand } from '@aws-sdk/client-s3'; -import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; -import { s3 } from '@/lib/S3/S3'; -import config from '@/config'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export class getAttachmentPresignedUrl { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the presigned url of the given attachment key with the original filename. - * @param {number} tenantId - * @param {string} key - * @returns {string} - */ - async getPresignedUrl(tenantId: number, key: string) { - const { Document } = this.tenancy.models(tenantId); - const foundDocument = await Document.query().findOne({ key }); - - let ResponseContentDisposition = 'attachment'; - if (foundDocument && foundDocument.originName) { - ResponseContentDisposition += `; filename="${foundDocument.originName}"`; - } - - const command = new GetObjectCommand({ - Bucket: config.s3.bucket, - Key: key, - ResponseContentDisposition, - }); - const signedUrl = await getSignedUrl(s3, command, { expiresIn: 300 }); - - return signedUrl; - } -} diff --git a/packages/server/src/services/Attachments/LinkAttachment.ts b/packages/server/src/services/Attachments/LinkAttachment.ts deleted file mode 100644 index b96a763c9..000000000 --- a/packages/server/src/services/Attachments/LinkAttachment.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Inject, Service } from 'typedi'; -import bluebird from 'bluebird'; -import { Knex } from 'knex'; -import { - validateLinkModelEntryExists, - validateLinkModelExists, -} from './_utils'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -@Service() -export class LinkAttachment { - @Inject() - private tenancy: HasTenancyService; - - /** - * Links the given file key to the given model type and id. - * @param {number} tenantId - * @param {string} filekey - * @param {string} modelRef - * @param {number} modelId - * @returns {Promise} - */ - async link( - tenantId: number, - filekey: string, - modelRef: string, - modelId: number, - trx?: Knex.Transaction - ) { - const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId); - const LinkModel = models[modelRef]; - validateLinkModelExists(LinkModel); - - const foundFile = await Document.query(trx) - .findOne('key', filekey) - .throwIfNotFound(); - - const foundLinkModel = await LinkModel.query(trx).findById(modelId); - validateLinkModelEntryExists(foundLinkModel); - - const foundLinks = await DocumentLink.query(trx) - .where('modelRef', modelRef) - .where('modelId', modelId) - .where('documentId', foundFile.id); - - if (foundLinks.length > 0) { - throw new ServiceError(ERRORS.DOCUMENT_LINK_ALREADY_LINKED); - } - await DocumentLink.query(trx).insert({ - modelRef, - modelId, - documentId: foundFile.id, - }); - } - - /** - * Links the given file keys to the given model type and id. - * @param {number} tenantId - * @param {string[]} filekeys - * @param {string} modelRef - * @param {number} modelId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - async bulkLink( - tenantId: number, - filekeys: string[], - modelRef: string, - modelId: number, - trx?: Knex.Transaction - ) { - return bluebird.each(filekeys, async (fieldKey: string) => { - try { - await this.link(tenantId, fieldKey, modelRef, modelId, trx); - } catch { - // Ignore catching exceptions in bulk action. - } - }); - } -} diff --git a/packages/server/src/services/Attachments/S3UploadPipeline.ts b/packages/server/src/services/Attachments/S3UploadPipeline.ts deleted file mode 100644 index 9e71cd39d..000000000 --- a/packages/server/src/services/Attachments/S3UploadPipeline.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { NextFunction, Request, Response } from 'express'; -import multer from 'multer'; -import type { Multer } from 'multer'; -import multerS3 from 'multer-s3'; -import { s3 } from '@/lib/S3/S3'; -import { Service } from 'typedi'; -import config from '@/config'; - -@Service() -export class AttachmentUploadPipeline { - /** - * Middleware to ensure that S3 configuration is properly set before proceeding. - * This function checks if the necessary S3 configuration keys are present and throws an error if any are missing. - * @param req The HTTP request object. - * @param res The HTTP response object. - * @param next The callback to pass control to the next middleware function. - */ - validateS3Configured(req: Request, res: Response, next: NextFunction) { - if ( - !config.s3.region || - !config.s3.accessKeyId || - !config.s3.secretAccessKey - ) { - const missingKeys = []; - if (!config.s3.region) missingKeys.push('region'); - if (!config.s3.accessKeyId) missingKeys.push('accessKeyId'); - if (!config.s3.secretAccessKey) missingKeys.push('secretAccessKey'); - const missing = missingKeys.join(', '); - - throw new Error(`S3 configuration error: Missing ${missing}`); - } - next(); - } - - /** - * Express middleware for uploading attachments to an S3 bucket. - * It utilizes the multer middleware for handling multipart/form-data, specifically for file uploads. - */ - public uploadPipeline(): Multer { - return multer({ - storage: multerS3({ - s3, - bucket: config.s3.bucket, - contentType: multerS3.AUTO_CONTENT_TYPE, - - metadata: function (req, file, cb) { - cb(null, { fieldName: file.fieldname }); - }, - key: function (req, file, cb) { - cb(null, Date.now().toString()); - }, - acl: function(req, file, cb) { - // Conditionally set file to public or private based on isPublic flag - const aclValue = true ? 'public-read' : 'private'; - cb(null, aclValue); // Set ACL based on the isPublic flag - } - }), - }); - } -} diff --git a/packages/server/src/services/Attachments/UnlinkAttachment.ts b/packages/server/src/services/Attachments/UnlinkAttachment.ts deleted file mode 100644 index 0633740bb..000000000 --- a/packages/server/src/services/Attachments/UnlinkAttachment.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Inject, Service } from 'typedi'; -import bluebird from 'bluebird'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { - validateLinkModelEntryExists, - validateLinkModelExists, -} from './_utils'; -import { Knex } from 'knex'; -import { difference } from 'lodash'; - -@Service() -export class UnlinkAttachment { - @Inject() - private tenancy: HasTenancyService; - - /** - * Unlink the attachments from the model entry. - * @param {number} tenantId - * @param {string} filekey - * @param {string} modelRef - * @param {number} modelId - */ - async unlink( - tenantId: number, - filekey: string, - modelRef: string, - modelId: number, - trx?: Knex.Transaction - ): Promise { - const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId); - const LinkModel = models[modelRef]; - validateLinkModelExists(LinkModel); - - const foundLinkModel = await LinkModel.query(trx).findById(modelId); - validateLinkModelEntryExists(foundLinkModel); - - const document = await Document.query(trx).findOne('key', filekey); - - // Delete the document link. - await DocumentLink.query(trx) - .where('modelRef', modelRef) - .where('modelId', modelId) - .where('documentId', document.id) - .delete(); - } - - /** - * Bulk unlink the attachments from the model entry. - * @param {number} tenantId - * @param {string} fieldkey - * @param {string} modelRef - * @param {number} modelId - * @returns {Promise} - */ - async bulkUnlink( - tenantId: number, - filekeys: string[], - modelRef: string, - modelId: number, - trx?: Knex.Transaction - ): Promise { - await bluebird.each(filekeys, (fieldKey: string) => { - try { - this.unlink(tenantId, fieldKey, modelRef, modelId, trx); - } catch { - // Ignore catching exceptions on bulk action. - } - }); - } - - /** - * Unlink all the unpresented keys of the given model type and id. - * @param {number} tenantId - * @param {string[]} presentedKeys - * @param {string} modelRef - * @param {number} modelId - * @param {Knex.Transaction} trx - */ - async unlinkUnpresentedKeys( - tenantId: number, - presentedKeys: string[], - modelRef: string, - modelId: number, - trx?: Knex.Transaction - ): Promise { - const { DocumentLink } = this.tenancy.models(tenantId); - - const modelLinks = await DocumentLink.query(trx) - .where('modelRef', modelRef) - .where('modelId', modelId) - .withGraphFetched('document'); - - const modelLinkKeys = modelLinks.map((link) => link.document.key); - const unpresentedKeys = difference(modelLinkKeys, presentedKeys); - - await this.bulkUnlink(tenantId, unpresentedKeys, modelRef, modelId, trx); - } - - /** - * Unlink all attachments of the given model type and id. - * @param {number} tenantId - * @param {string} modelRef - * @param {number} modelId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - async unlinkAllModelKeys( - tenantId: number, - modelRef: string, - modelId: number, - trx?: Knex.Transaction - ): Promise { - const { DocumentLink } = this.tenancy.models(tenantId); - - // Get all the keys of the modelRef and modelId. - const modelLinks = await DocumentLink.query(trx) - .where('modelRef', modelRef) - .where('modelId', modelId) - .withGraphFetched('document'); - - const modelLinkKeys = modelLinks.map((link) => link.document.key); - - await this.bulkUnlink(tenantId, modelLinkKeys, modelRef, modelId, trx); - } -} diff --git a/packages/server/src/services/Attachments/UploadDocument.ts b/packages/server/src/services/Attachments/UploadDocument.ts deleted file mode 100644 index 7d63938ef..000000000 --- a/packages/server/src/services/Attachments/UploadDocument.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export class UploadDocument { - @Inject() - private tenancy: HasTenancyService; - - /** - * Inserts the document metadata. - * @param {number} tenantId - * @param {} file - * @returns {} - */ - async upload(tenantId: number, file: any) { - const { Document } = this.tenancy.models(tenantId); - - const insertedDocument = await Document.query().insert({ - key: file.key, - mimeType: file.mimetype, - size: file.size, - originName: file.originalname, - }); - return insertedDocument; - } -} diff --git a/packages/server/src/services/Attachments/ValidateAttachments.ts b/packages/server/src/services/Attachments/ValidateAttachments.ts deleted file mode 100644 index 885833f40..000000000 --- a/packages/server/src/services/Attachments/ValidateAttachments.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { castArray, difference } from 'lodash'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { Inject, Service } from 'typedi'; - -@Service() -export class ValidateAttachments { - @Inject() - tenancy: HasTenancyService; - - /** - * Validates the given file keys existance. - * @param {number} tenantId - * @param {string|string[]} key - */ - async validate(tenantId: number, key: string | string[]) { - const { Document } = this.tenancy.models(tenantId); - - const keys = castArray(key); - const documents = await Document.query().whereIn('key', key); - const documentKeys = documents.map((document) => document.key); - - const notFoundKeys = difference(keys, documentKeys); - - if (notFoundKeys.length > 0) { - throw new ServiceError('DOCUMENT_KEYS_INVALID'); - } - } -} diff --git a/packages/server/src/services/Attachments/_utils.ts b/packages/server/src/services/Attachments/_utils.ts deleted file mode 100644 index 26f0f59c9..000000000 --- a/packages/server/src/services/Attachments/_utils.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -export const validateLinkModelExists = (LinkModel) => { - if (!LinkModel) { - throw new ServiceError(ERRORS.DOCUMENT_LINK_REF_INVALID); - } -}; - -export const validateLinkModelEntryExists = (foundLinkModel) => { - if (!foundLinkModel) { - throw new ServiceError(ERRORS.DOCUMENT_LINK_ID_INVALID); - } -}; diff --git a/packages/server/src/services/Attachments/constants.ts b/packages/server/src/services/Attachments/constants.ts deleted file mode 100644 index b046e9ca7..000000000 --- a/packages/server/src/services/Attachments/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum ERRORS { - DOCUMENT_LINK_REF_INVALID = 'DOCUMENT_LINK_REF_INVALID', - DOCUMENT_LINK_ID_INVALID = 'DOCUMENT_LINK_ID_INVALID', - DOCUMENT_LINK_ALREADY_LINKED = 'DOCUMENT_LINK_ALREADY_LINKED' -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnBills.ts b/packages/server/src/services/Attachments/events/AttachmentsOnBills.ts deleted file mode 100644 index 6909626ec..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnBills.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IBIllEventDeletedPayload, - IBillCreatedPayload, - IBillCreatingPayload, - IBillEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnBills { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.bill.onCreating, - this.validateAttachmentsOnBillCreate.bind(this) - ); - bus.subscribe( - events.bill.onCreated, - this.handleAttachmentsOnBillCreated.bind(this) - ); - bus.subscribe( - events.bill.onEdited, - this.handleUnlinkUnpresentedKeysOnBillEdited.bind(this) - ); - bus.subscribe( - events.bill.onEdited, - this.handleLinkPresentedKeysOnBillEdited.bind(this) - ); - bus.subscribe( - events.bill.onDeleting, - this.handleUnlinkAttachmentsOnBillDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating bill. - * @param {ISaleInvoiceCreatingPaylaod} - * @returns {Promise} - */ - private async validateAttachmentsOnBillCreate({ - billDTO, - tenantId, - }: IBillCreatingPayload): Promise { - if (isEmpty(billDTO.attachments)) { - return; - } - const documentKeys = billDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created bill. - * @param {ISaleInvoiceCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnBillCreated({ - tenantId, - bill, - billDTO, - trx, - }: IBillCreatedPayload): Promise { - if (isEmpty(billDTO.attachments)) return; - - const keys = billDTO.attachments?.map((attachment) => attachment.key); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'Bill', - bill.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited bill. - * @param {IBillEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnBillEdited({ - tenantId, - billDTO, - bill, - trx - }: IBillEditedPayload) { - const keys = billDTO.attachments?.map((attachment) => attachment.key); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'Bill', - bill.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited bill. - * @param {ISaleInvoiceEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnBillEdited({ - tenantId, - billDTO, - oldBill, - trx, - }: IBillEditedPayload) { - if (isEmpty(billDTO.attachments)) return; - - const keys = billDTO.attachments?.map((attachment) => attachment.key); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'Bill', - oldBill.id, - trx - ); - } - - /** - * Unlink all attachments once the bill deleted. - * @param {ISaleInvoiceDeletedPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnBillDeleted({ - tenantId, - oldBill, - trx, - }: IBIllEventDeletedPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'Bill', - oldBill.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnCreditNote.ts b/packages/server/src/services/Attachments/events/AttachmentsOnCreditNote.ts deleted file mode 100644 index 32547b036..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnCreditNote.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - ICreditNoteCreatedPayload, - ICreditNoteCreatingPayload, - ICreditNoteDeletingPayload, - ICreditNoteEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnCreditNote { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.creditNote.onCreating, - this.validateAttachmentsOnCreditNoteCreate.bind(this) - ); - bus.subscribe( - events.creditNote.onCreated, - this.handleAttachmentsOnCreditNoteCreated.bind(this) - ); - bus.subscribe( - events.creditNote.onEdited, - this.handleUnlinkUnpresentedKeysOnCreditNoteEdited.bind(this) - ); - bus.subscribe( - events.creditNote.onEdited, - this.handleLinkPresentedKeysOnCreditNoteEdited.bind(this) - ); - bus.subscribe( - events.creditNote.onDeleting, - this.handleUnlinkAttachmentsOnCreditNoteDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating credit note. - * @param {ICreditNoteCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnCreditNoteCreate({ - creditNoteDTO, - tenantId, - }: ICreditNoteCreatingPayload): Promise { - if (isEmpty(creditNoteDTO.attachments)) { - return; - } - const documentKeys = creditNoteDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created credit note. - * @param {ICreditNoteCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnCreditNoteCreated({ - tenantId, - creditNote, - creditNoteDTO, - trx, - }: ICreditNoteCreatedPayload): Promise { - if (isEmpty(creditNoteDTO.attachments)) return; - - const keys = creditNoteDTO.attachments?.map((attachment) => attachment.key); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'CreditNote', - creditNote.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited credit note. - * @param {ICreditNoteEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnCreditNoteEdited({ - tenantId, - creditNoteEditDTO, - oldCreditNote, - trx, - }: ICreditNoteEditedPayload) { - const keys = creditNoteEditDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'CreditNote', - oldCreditNote.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited credit note. - * @param {ICreditNoteEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnCreditNoteEdited({ - tenantId, - creditNoteEditDTO, - oldCreditNote, - trx, - }: ICreditNoteEditedPayload) { - if (isEmpty(creditNoteEditDTO.attachments)) return; - - const keys = creditNoteEditDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'CreditNote', - oldCreditNote.id, - trx - ); - } - - /** - * Unlink all attachments once the credit note deleted. - * @param {ICreditNoteDeletingPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnCreditNoteDeleted({ - tenantId, - oldCreditNote, - trx, - }: ICreditNoteDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'CreditNote', - oldCreditNote.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnExpenses.ts b/packages/server/src/services/Attachments/events/AttachmentsOnExpenses.ts deleted file mode 100644 index 77babe6c0..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnExpenses.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IExpenseCreatedPayload, - IExpenseCreatingPayload, - IExpenseDeletingPayload, - IExpenseEventEditPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnExpenses { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.expenses.onCreating, - this.validateAttachmentsOnExpenseCreate.bind(this) - ); - bus.subscribe( - events.expenses.onCreated, - this.handleAttachmentsOnExpenseCreated.bind(this) - ); - bus.subscribe( - events.expenses.onEdited, - this.handleUnlinkUnpresentedKeysOnExpenseEdited.bind(this) - ); - bus.subscribe( - events.expenses.onEdited, - this.handleLinkPresentedKeysOnExpenseEdited.bind(this) - ); - bus.subscribe( - events.expenses.onDeleting, - this.handleUnlinkAttachmentsOnExpenseDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating expense. - * @param {ISaleInvoiceCreatingPaylaod} - * @returns {Promise} - */ - private async validateAttachmentsOnExpenseCreate({ - expenseDTO, - tenantId, - }: IExpenseCreatingPayload): Promise { - if (isEmpty(expenseDTO.attachments)) { - return; - } - const documentKeys = expenseDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created expense. - * @param {ISaleInvoiceCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnExpenseCreated({ - tenantId, - expenseDTO, - expense, - trx, - }: IExpenseCreatedPayload): Promise { - if (isEmpty(expenseDTO.attachments)) return; - - const keys = expenseDTO.attachments?.map((attachment) => attachment.key); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'Expense', - expense.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited expense. - * @param {ISaleInvoiceEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnExpenseEdited({ - tenantId, - expenseDTO, - expense, - trx, - }: IExpenseEventEditPayload) { - const keys = expenseDTO.attachments?.map((attachment) => attachment.key); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'Expense', - expense.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited expense. - * @param {ISaleInvoiceEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnExpenseEdited({ - tenantId, - expenseDTO, - oldExpense, - trx, - }: IExpenseEventEditPayload) { - if (isEmpty(expenseDTO.attachments)) return; - - const keys = expenseDTO.attachments?.map((attachment) => attachment.key); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'Expense', - oldExpense.id, - trx - ); - } - - /** - * Unlink all attachments once the expense deleted. - * @param {ISaleInvoiceDeletedPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnExpenseDeleted({ - tenantId, - oldExpense, - trx, - }: IExpenseDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'Expense', - oldExpense.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnManualJournals.ts b/packages/server/src/services/Attachments/events/AttachmentsOnManualJournals.ts deleted file mode 100644 index b0a133d3a..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnManualJournals.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IManualJournalCreatingPayload, - IManualJournalEventCreatedPayload, - IManualJournalEventDeletedPayload, - IManualJournalEventEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnManualJournals { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.manualJournals.onCreating, - this.validateAttachmentsOnManualJournalCreate.bind(this) - ); - bus.subscribe( - events.manualJournals.onCreated, - this.handleAttachmentsOnManualJournalCreated.bind(this) - ); - bus.subscribe( - events.manualJournals.onEdited, - this.handleUnlinkUnpresentedKeysOnManualJournalEdited.bind(this) - ); - bus.subscribe( - events.manualJournals.onEdited, - this.handleLinkPresentedKeysOnManualJournalEdited.bind(this) - ); - bus.subscribe( - events.manualJournals.onDeleting, - this.handleUnlinkAttachmentsOnManualJournalDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating manual journal. - * @param {IManualJournalCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnManualJournalCreate({ - manualJournalDTO, - tenantId, - }: IManualJournalCreatingPayload): Promise { - if (isEmpty(manualJournalDTO.attachments)) { - return; - } - const documentKeys = manualJournalDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created manual journal. - * @param {IManualJournalEventCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnManualJournalCreated({ - tenantId, - manualJournalDTO, - manualJournal, - trx, - }: IManualJournalEventCreatedPayload): Promise { - if (isEmpty(manualJournalDTO.attachments)) return; - - const keys = manualJournalDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'ManualJournal', - manualJournal.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited manual journal. - * @param {ISaleInvoiceEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnManualJournalEdited({ - tenantId, - manualJournalDTO, - manualJournal, - trx - }: IManualJournalEventEditedPayload) { - const keys = manualJournalDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'SaleInvoice', - manualJournal.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited manual journal. - * @param {ISaleInvoiceEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnManualJournalEdited({ - tenantId, - manualJournalDTO, - oldManualJournal, - trx, - }: IManualJournalEventEditedPayload) { - if (isEmpty(manualJournalDTO.attachments)) return; - - const keys = manualJournalDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'ManualJournal', - oldManualJournal.id, - trx - ); - } - - /** - * Unlink all attachments once the manual journal deleted. - * @param {ISaleInvoiceDeletedPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnManualJournalDeleted({ - tenantId, - oldManualJournal, - trx, - }: IManualJournalEventDeletedPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'SaleInvoice', - oldManualJournal.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnPaymentsMade.ts b/packages/server/src/services/Attachments/events/AttachmentsOnPaymentsMade.ts deleted file mode 100644 index 276e1abbb..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnPaymentsMade.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IBillPaymentCreatingPayload, - IBillPaymentDeletingPayload, - IBillPaymentEventCreatedPayload, - IBillPaymentEventEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnBillPayments { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.billPayment.onCreating, - this.validateAttachmentsOnBillPaymentCreate.bind(this) - ); - bus.subscribe( - events.billPayment.onCreated, - this.handleAttachmentsOnBillPaymentCreated.bind(this) - ); - bus.subscribe( - events.billPayment.onEdited, - this.handleUnlinkUnpresentedKeysOnBillPaymentEdited.bind(this) - ); - bus.subscribe( - events.billPayment.onEdited, - this.handleLinkPresentedKeysOnBillPaymentEdited.bind(this) - ); - bus.subscribe( - events.billPayment.onDeleting, - this.handleUnlinkAttachmentsOnBillPaymentDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating bill payment. - * @param {IBillPaymentCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnBillPaymentCreate({ - billPaymentDTO, - tenantId, - }: IBillPaymentCreatingPayload): Promise { - if (isEmpty(billPaymentDTO.attachments)) { - return; - } - const documentKeys = billPaymentDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created bill payment. - * @param {IBillPaymentEventCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnBillPaymentCreated({ - tenantId, - billPaymentDTO, - billPayment, - trx, - }: IBillPaymentEventCreatedPayload): Promise { - if (isEmpty(billPaymentDTO.attachments)) return; - - const keys = billPaymentDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'BillPayment', - billPayment.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited bill payment. - * @param {IBillPaymentEventEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnBillPaymentEdited({ - tenantId, - billPaymentDTO, - oldBillPayment, - trx, - }: IBillPaymentEventEditedPayload) { - const keys = billPaymentDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'BillPayment', - oldBillPayment.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited bill payment. - * @param {IBillPaymentEventEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnBillPaymentEdited({ - tenantId, - billPaymentDTO, - oldBillPayment, - trx, - }: IBillPaymentEventEditedPayload) { - if (isEmpty(billPaymentDTO.attachments)) return; - - const keys = billPaymentDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'BillPayment', - oldBillPayment.id, - trx - ); - } - - /** - * Unlink all attachments once the bill payment deleted. - * @param {IBillPaymentDeletingPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnBillPaymentDeleted({ - tenantId, - oldBillPayment, - trx, - }: IBillPaymentDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'BillPayment', - oldBillPayment.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnPaymentsReceived.ts b/packages/server/src/services/Attachments/events/AttachmentsOnPaymentsReceived.ts deleted file mode 100644 index 311fbb8ea..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnPaymentsReceived.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IPaymentReceivedCreatedPayload, - IPaymentReceivedCreatingPayload, - IPaymentReceivedDeletingPayload, - IPaymentReceivedEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnPaymentsReceived { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onCreating, - this.validateAttachmentsOnPaymentCreate.bind(this) - ); - bus.subscribe( - events.paymentReceive.onCreated, - this.handleAttachmentsOnPaymentCreated.bind(this) - ); - bus.subscribe( - events.paymentReceive.onEdited, - this.handleUnlinkUnpresentedKeysOnPaymentEdited.bind(this) - ); - bus.subscribe( - events.paymentReceive.onEdited, - this.handleLinkPresentedKeysOnPaymentEdited.bind(this) - ); - bus.subscribe( - events.paymentReceive.onDeleting, - this.handleUnlinkAttachmentsOnPaymentDelete.bind(this) - ); - } - - /** - * Validates the attachment keys on creating payment. - * @param {IPaymentReceivedCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnPaymentCreate({ - paymentReceiveDTO, - tenantId, - }: IPaymentReceivedCreatingPayload): Promise { - if (isEmpty(paymentReceiveDTO.attachments)) { - return; - } - const documentKeys = paymentReceiveDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created payment. - * @param {IPaymentReceivedCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnPaymentCreated({ - tenantId, - paymentReceiveDTO, - paymentReceive, - trx, - }: IPaymentReceivedCreatedPayload): Promise { - if (isEmpty(paymentReceiveDTO.attachments)) return; - - const keys = paymentReceiveDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'PaymentReceive', - paymentReceive.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited payment. - * @param {IPaymentReceivedEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnPaymentEdited({ - tenantId, - paymentReceiveDTO, - oldPaymentReceive, - trx, - }: IPaymentReceivedEditedPayload) { - const keys = paymentReceiveDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'PaymentReceive', - oldPaymentReceive.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited payment. - * @param {IPaymentReceivedEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnPaymentEdited({ - tenantId, - paymentReceiveDTO, - oldPaymentReceive, - trx, - }: IPaymentReceivedEditedPayload) { - if (isEmpty(paymentReceiveDTO.attachments)) return; - - const keys = paymentReceiveDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'PaymentReceive', - oldPaymentReceive.id, - trx - ); - } - - /** - * Unlink all attachments once the payment deleted. - * @param {ISaleInvoiceDeletedPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnPaymentDelete({ - tenantId, - oldPaymentReceive, - trx, - }: IPaymentReceivedDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'PaymentReceive', - oldPaymentReceive.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnSaleEstimates.ts b/packages/server/src/services/Attachments/events/AttachmentsOnSaleEstimates.ts deleted file mode 100644 index 53eb483bb..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnSaleEstimates.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - ISaleEstimateCreatedPayload, - ISaleEstimateCreatingPayload, - ISaleEstimateDeletingPayload, - ISaleEstimateEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnSaleEstimates { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleEstimate.onCreating, - this.validateAttachmentsOnSaleEstimateCreated.bind(this) - ); - bus.subscribe( - events.saleEstimate.onCreated, - this.handleAttachmentsOnSaleEstimateCreated.bind(this) - ); - bus.subscribe( - events.saleEstimate.onEdited, - this.handleUnlinkUnpresentedKeysOnSaleEstimateEdited.bind(this) - ); - bus.subscribe( - events.saleEstimate.onEdited, - this.handleLinkPresentedKeysOnSaleEstimateEdited.bind(this) - ); - bus.subscribe( - events.saleEstimate.onDeleting, - this.handleUnlinkAttachmentsOnSaleEstimateDelete.bind(this) - ); - } - - /** - * Validates the attachment keys on creating sale estimate. - * @param {ISaleEstimateCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnSaleEstimateCreated({ - estimateDTO, - tenantId, - }: ISaleEstimateCreatingPayload): Promise { - if (isEmpty(estimateDTO.attachments)) { - return; - } - const documentKeys = estimateDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created sale estimate. - * @param {ISaleEstimateCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnSaleEstimateCreated({ - tenantId, - saleEstimateDTO, - saleEstimate, - trx, - }: ISaleEstimateCreatedPayload): Promise { - if (isEmpty(saleEstimateDTO.attachments)) return; - - const keys = saleEstimateDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'SaleEstimate', - saleEstimate.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited sale estimate. - * @param {ISaleEstimateEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnSaleEstimateEdited({ - tenantId, - estimateDTO, - oldSaleEstimate, - trx - }: ISaleEstimateEditedPayload) { - const keys = estimateDTO.attachments?.map((attachment) => attachment.key); - - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'SaleEstimate', - oldSaleEstimate.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited sale estimate. - * @param {ISaleEstimateEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnSaleEstimateEdited({ - tenantId, - estimateDTO, - oldSaleEstimate, - trx, - }: ISaleEstimateEditedPayload) { - if (isEmpty(estimateDTO.attachments)) return; - - const keys = estimateDTO.attachments?.map((attachment) => attachment.key); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'SaleEstimate', - oldSaleEstimate.id, - trx - ); - } - - /** - * Unlink all attachments once the estimate deleted. - * @param {ISaleEstimateDeletingPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnSaleEstimateDelete({ - tenantId, - oldSaleEstimate, - trx, - }: ISaleEstimateDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'SaleEstimate', - oldSaleEstimate.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnSaleInvoice.ts b/packages/server/src/services/Attachments/events/AttachmentsOnSaleInvoice.ts deleted file mode 100644 index 717d956dc..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnSaleInvoice.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceCreatingPaylaod, - ISaleInvoiceDeletingPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnSaleInvoiceCreated { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreating, - this.validateAttachmentsOnSaleInvoiceCreate.bind(this) - ); - bus.subscribe( - events.saleInvoice.onCreated, - this.handleAttachmentsOnSaleInvoiceCreated.bind(this) - ); - bus.subscribe( - events.saleInvoice.onEdited, - this.handleUnlinkUnpresentedKeysOnInvoiceEdited.bind(this) - ); - bus.subscribe( - events.saleInvoice.onEdited, - this.handleLinkPresentedKeysOnInvoiceEdited.bind(this) - ); - bus.subscribe( - events.saleInvoice.onDeleting, - this.handleUnlinkAttachmentsOnInvoiceDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating sale invoice. - * @param {ISaleInvoiceCreatingPaylaod} - * @returns {Promise} - */ - private async validateAttachmentsOnSaleInvoiceCreate({ - saleInvoiceDTO, - tenantId, - }: ISaleInvoiceCreatingPaylaod): Promise { - if (isEmpty(saleInvoiceDTO.attachments)) { - return; - } - const documentKeys = saleInvoiceDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created sale invoice. - * @param {ISaleInvoiceCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnSaleInvoiceCreated({ - tenantId, - saleInvoiceDTO, - saleInvoice, - trx, - }: ISaleInvoiceCreatedPayload): Promise { - if (isEmpty(saleInvoiceDTO.attachments)) return; - - const keys = saleInvoiceDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'SaleInvoice', - saleInvoice.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited sale invoice. - * @param {ISaleInvoiceEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnInvoiceEdited({ - tenantId, - saleInvoiceDTO, - saleInvoice, - trx, - }: ISaleInvoiceEditedPayload) { - // if (isEmpty(saleInvoiceDTO.attachments)) return; - - const keys = saleInvoiceDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'SaleInvoice', - saleInvoice.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited sale invoice. - * @param {ISaleInvoiceEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnInvoiceEdited({ - tenantId, - saleInvoiceDTO, - oldSaleInvoice, - trx, - }: ISaleInvoiceEditedPayload) { - if (isEmpty(saleInvoiceDTO.attachments)) return; - - const keys = saleInvoiceDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'SaleInvoice', - oldSaleInvoice.id, - trx - ); - } - - /** - * Unlink all attachments once the invoice deleted. - * @param {ISaleInvoiceDeletedPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnInvoiceDeleted({ - tenantId, - oldSaleInvoice, - trx, - }: ISaleInvoiceDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'SaleInvoice', - oldSaleInvoice.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnSaleReceipts.ts b/packages/server/src/services/Attachments/events/AttachmentsOnSaleReceipts.ts deleted file mode 100644 index 01a8d9fc3..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnSaleReceipts.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - ISaleReceiptCreatedPayload, - ISaleReceiptCreatingPayload, - ISaleReceiptDeletingPayload, - ISaleReceiptEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnSaleReceipt { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreating, - this.validateAttachmentsOnSaleInvoiceCreate.bind(this) - ); - bus.subscribe( - events.saleReceipt.onCreated, - this.handleAttachmentsOnSaleInvoiceCreated.bind(this) - ); - bus.subscribe( - events.saleReceipt.onEdited, - this.handleUnlinkUnpresentedKeysOnInvoiceEdited.bind(this) - ); - bus.subscribe( - events.saleReceipt.onEdited, - this.handleLinkPresentedKeysOnInvoiceEdited.bind(this) - ); - bus.subscribe( - events.saleReceipt.onDeleting, - this.handleUnlinkAttachmentsOnReceiptDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating sale receipt. - * @param {ISaleReceiptCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnSaleInvoiceCreate({ - saleReceiptDTO, - tenantId, - }: ISaleReceiptCreatingPayload): Promise { - if (isEmpty(saleReceiptDTO.attachments)) { - return; - } - const documentKeys = saleReceiptDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created sale receipt. - * @param {ISaleReceiptCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnSaleInvoiceCreated({ - tenantId, - saleReceiptDTO, - saleReceipt, - trx, - }: ISaleReceiptCreatedPayload): Promise { - if (isEmpty(saleReceiptDTO.attachments)) return; - - const keys = saleReceiptDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'SaleReceipt', - saleReceipt.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited sale receipt. - * @param {ISaleReceiptEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnInvoiceEdited({ - tenantId, - saleReceiptDTO, - saleReceipt, - trx, - }: ISaleReceiptEditedPayload) { - const keys = saleReceiptDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'SaleReceipt', - saleReceipt.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited sale receipt. - * @param {ISaleReceiptEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnInvoiceEdited({ - tenantId, - saleReceiptDTO, - oldSaleReceipt, - trx, - }: ISaleReceiptEditedPayload) { - if (isEmpty(saleReceiptDTO.attachments)) return; - - const keys = saleReceiptDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'SaleReceipt', - oldSaleReceipt.id, - trx - ); - } - - /** - * Unlink all attachments once the receipt deleted. - * @param {ISaleReceiptDeletingPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnReceiptDeleted({ - tenantId, - oldSaleReceipt, - trx, - }: ISaleReceiptDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'SaleReceipt', - oldSaleReceipt.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/events/AttachmentsOnVendorCredits.ts b/packages/server/src/services/Attachments/events/AttachmentsOnVendorCredits.ts deleted file mode 100644 index 30ce63ca5..000000000 --- a/packages/server/src/services/Attachments/events/AttachmentsOnVendorCredits.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IVendorCreditCreatedPayload, - IVendorCreditCreatingPayload, - IVendorCreditDeletingPayload, - IVendorCreditEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { LinkAttachment } from '../LinkAttachment'; -import { ValidateAttachments } from '../ValidateAttachments'; -import { UnlinkAttachment } from '../UnlinkAttachment'; - -@Service() -export class AttachmentsOnVendorCredits { - @Inject() - private linkAttachmentService: LinkAttachment; - - @Inject() - private unlinkAttachmentService: UnlinkAttachment; - - @Inject() - private validateDocuments: ValidateAttachments; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.vendorCredit.onCreating, - this.validateAttachmentsOnVendorCreditCreate.bind(this) - ); - bus.subscribe( - events.vendorCredit.onCreated, - this.handleAttachmentsOnVendorCreditCreated.bind(this) - ); - bus.subscribe( - events.vendorCredit.onEdited, - this.handleUnlinkUnpresentedKeysOnVendorCreditEdited.bind(this) - ); - bus.subscribe( - events.vendorCredit.onEdited, - this.handleLinkPresentedKeysOnVendorCreditEdited.bind(this) - ); - bus.subscribe( - events.vendorCredit.onDeleting, - this.handleUnlinkAttachmentsOnVendorCreditDeleted.bind(this) - ); - } - - /** - * Validates the attachment keys on creating vendor credit. - * @param {IVendorCreditCreatingPayload} - * @returns {Promise} - */ - private async validateAttachmentsOnVendorCreditCreate({ - vendorCreditCreateDTO, - tenantId, - }: IVendorCreditCreatingPayload): Promise { - if (isEmpty(vendorCreditCreateDTO.attachments)) { - return; - } - const documentKeys = vendorCreditCreateDTO?.attachments?.map((a) => a.key); - - await this.validateDocuments.validate(tenantId, documentKeys); - } - - /** - * Handles linking the attachments of the created vendor credit. - * @param {IVendorCreditCreatedPayload} - * @returns {Promise} - */ - private async handleAttachmentsOnVendorCreditCreated({ - tenantId, - vendorCreditCreateDTO, - vendorCredit, - trx, - }: IVendorCreditCreatedPayload): Promise { - if (isEmpty(vendorCreditCreateDTO.attachments)) return; - - const keys = vendorCreditCreateDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'VendorCredit', - vendorCredit.id, - trx - ); - } - - /** - * Handles unlinking all the unpresented keys of the edited vendor credit. - * @param {IVendorCreditEditedPayload} - */ - private async handleUnlinkUnpresentedKeysOnVendorCreditEdited({ - tenantId, - vendorCreditDTO, - oldVendorCredit, - trx, - }: IVendorCreditEditedPayload) { - const keys = vendorCreditDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.unlinkAttachmentService.unlinkUnpresentedKeys( - tenantId, - keys, - 'VendorCredit', - oldVendorCredit.id, - trx - ); - } - - /** - * Handles linking all the presented keys of the edited vendor credit. - * @param {IVendorCreditEditedPayload} - * @returns {Promise} - */ - private async handleLinkPresentedKeysOnVendorCreditEdited({ - tenantId, - vendorCreditDTO, - oldVendorCredit, - trx, - }: IVendorCreditEditedPayload) { - if (isEmpty(vendorCreditDTO.attachments)) return; - - const keys = vendorCreditDTO.attachments?.map( - (attachment) => attachment.key - ); - await this.linkAttachmentService.bulkLink( - tenantId, - keys, - 'VendorCredit', - oldVendorCredit.id, - trx - ); - } - - /** - * Unlink all attachments once the vendor credit deleted. - * @param {IVendorCreditDeletingPayload} - * @returns {Promise} - */ - private async handleUnlinkAttachmentsOnVendorCreditDeleted({ - tenantId, - oldVendorCredit, - trx, - }: IVendorCreditDeletingPayload) { - await this.unlinkAttachmentService.unlinkAllModelKeys( - tenantId, - 'VendorCredit', - oldVendorCredit.id, - trx - ); - } -} diff --git a/packages/server/src/services/Attachments/utils.ts b/packages/server/src/services/Attachments/utils.ts deleted file mode 100644 index 4f58fbc9c..000000000 --- a/packages/server/src/services/Attachments/utils.ts +++ /dev/null @@ -1,9 +0,0 @@ -import path from 'path'; -import config from '@/config'; - -export const getUploadedObjectUri = (objectKey: string) => { - return new URL( - path.join(config.s3.bucket, objectKey), - config.s3.endpoint - ).toString(); -}; diff --git a/packages/server/src/services/AuthenticatedAccount/index.ts b/packages/server/src/services/AuthenticatedAccount/index.ts deleted file mode 100644 index 1afb217dd..000000000 --- a/packages/server/src/services/AuthenticatedAccount/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ISystemUser } from '@/interfaces'; - -@Service() -export default class AuthenticatedAccount { - /** - * - * @param {number} tenantId - * @param {ISystemUser} authorizedUser - * @returns - */ - getAccount = async (tenantId: number, authorizedUser: ISystemUser) => { - return authorizedUser; - }; -} diff --git a/packages/server/src/services/Authentication/AuthApplication.ts b/packages/server/src/services/Authentication/AuthApplication.ts deleted file mode 100644 index 73f18941f..000000000 --- a/packages/server/src/services/Authentication/AuthApplication.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IRegisterDTO, - ISystemUser, - IPasswordReset, - IAuthGetMetaPOJO, -} from '@/interfaces'; -import { AuthSigninService } from './AuthSignin'; -import { AuthSignupService } from './AuthSignup'; -import { AuthSendResetPassword } from './AuthSendResetPassword'; -import { GetAuthMeta } from './GetAuthMeta'; -import { AuthSignupConfirmService } from './AuthSignupConfirm'; -import { SystemUser } from '@/system/models'; -import { AuthSignupConfirmResend } from './AuthSignupResend'; - -@Service() -export default class AuthenticationApplication { - @Inject() - private authSigninService: AuthSigninService; - - @Inject() - private authSignupService: AuthSignupService; - - @Inject() - private authSignupConfirmService: AuthSignupConfirmService; - - @Inject() - private authSignUpConfirmResendService: AuthSignupConfirmResend; - - @Inject() - private authResetPasswordService: AuthSendResetPassword; - - @Inject() - private authGetMeta: GetAuthMeta; - - /** - * Signin and generates JWT token. - * @throws {ServiceError} - * @param {string} email - Email address. - * @param {string} password - Password. - * @return {Promise<{user: IUser, token: string}>} - */ - public async signIn(email: string, password: string) { - return this.authSigninService.signIn(email, password); - } - - /** - * Signup a new user. - * @param {IRegisterDTO} signupDTO - * @returns {Promise} - */ - public async signUp(signupDTO: IRegisterDTO): Promise { - return this.authSignupService.signUp(signupDTO); - } - - /** - * Verfying the provided user's email after signin-up. - * @param {string} email - * @param {string} token - * @returns {Promise} - */ - public async signUpConfirm( - email: string, - token: string - ): Promise { - return this.authSignupConfirmService.signUpConfirm(email, token); - } - - /** - * Resends the confirmation email of the given system user. - * @param {number} userId - System user id. - * @returns {Promise} - */ - public async signUpConfirmResend(userId: number) { - return this.authSignUpConfirmResendService.signUpConfirmResend(userId); - } - - /** - * Generates and retrieve password reset token for the given user email. - * @param {string} email - * @return {} - */ - public async sendResetPassword(email: string): Promise { - return this.authResetPasswordService.sendResetPassword(email); - } - - /** - * Resets a user password from given token. - * @param {string} token - Password reset token. - * @param {string} password - New Password. - * @return {Promise} - */ - public async resetPassword(token: string, password: string): Promise { - return this.authResetPasswordService.resetPassword(token, password); - } - - /** - * Retrieves the authentication meta for SPA. - * @returns {Promise} - */ - public async getAuthMeta(): Promise { - return this.authGetMeta.getAuthMeta(); - } -} diff --git a/packages/server/src/services/Authentication/AuthSendResetPassword.ts b/packages/server/src/services/Authentication/AuthSendResetPassword.ts deleted file mode 100644 index c3a12b47b..000000000 --- a/packages/server/src/services/Authentication/AuthSendResetPassword.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { Inject, Service } from 'typedi'; -import uniqid from 'uniqid'; -import moment from 'moment'; -import config from '@/config'; -import { - IAuthResetedPasswordEventPayload, - IAuthSendedResetPassword, - IAuthSendingResetPassword, - IPasswordReset, - ISystemUser, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { PasswordReset } from '@/system/models'; -import { ERRORS } from './_constants'; -import { ServiceError } from '@/exceptions'; -import { hashPassword } from '@/utils'; - -@Service() -export class AuthSendResetPassword { - @Inject() - private eventPublisher: EventPublisher; - - @Inject('repositories') - private sysRepositories: any; - - /** - * Generates and retrieve password reset token for the given user email. - * @param {string} email - * @return {} - */ - public async sendResetPassword(email: string): Promise { - const user = await this.validateEmailExistance(email); - - const token: string = uniqid(); - - // Triggers sending reset password event. - await this.eventPublisher.emitAsync(events.auth.sendingResetPassword, { - user, - token, - } as IAuthSendingResetPassword); - - // Delete all stored tokens of reset password that associate to the give email. - this.deletePasswordResetToken(email); - - // Creates a new password reset row with unique token. - const passwordReset = await PasswordReset.query().insert({ email, token }); - - // Triggers sent reset password event. - await this.eventPublisher.emitAsync(events.auth.sendResetPassword, { - user, - token, - } as IAuthSendedResetPassword); - - return passwordReset; - } - - /** - * Resets a user password from given token. - * @param {string} token - Password reset token. - * @param {string} password - New Password. - * @return {Promise} - */ - public async resetPassword(token: string, password: string): Promise { - const { systemUserRepository } = this.sysRepositories; - - // Finds the password reset token. - const tokenModel: IPasswordReset = await PasswordReset.query().findOne( - 'token', - token - ); - // In case the password reset token not found throw token invalid error.. - if (!tokenModel) { - throw new ServiceError(ERRORS.TOKEN_INVALID); - } - // Different between tokne creation datetime and current time. - if ( - moment().diff(tokenModel.createdAt, 'seconds') > - config.resetPasswordSeconds - ) { - // Deletes the expired token by expired token email. - await this.deletePasswordResetToken(tokenModel.email); - throw new ServiceError(ERRORS.TOKEN_EXPIRED); - } - const user = await systemUserRepository.findOneByEmail(tokenModel.email); - - if (!user) { - throw new ServiceError(ERRORS.USER_NOT_FOUND); - } - const hashedPassword = await hashPassword(password); - - await systemUserRepository.update( - { password: hashedPassword }, - { id: user.id } - ); - // Deletes the used token. - await this.deletePasswordResetToken(tokenModel.email); - - // Triggers `onResetPassword` event. - await this.eventPublisher.emitAsync(events.auth.resetPassword, { - user, - token, - password, - } as IAuthResetedPasswordEventPayload); - } - - /** - * Deletes the password reset token by the given email. - * @param {string} email - * @returns {Promise} - */ - private async deletePasswordResetToken(email: string) { - return PasswordReset.query().where('email', email).delete(); - } - - /** - * Validates the given email existance on the storage. - * @throws {ServiceError} - * @param {string} email - email address. - */ - private async validateEmailExistance(email: string): Promise { - const { systemUserRepository } = this.sysRepositories; - const userByEmail = await systemUserRepository.findOneByEmail(email); - - if (!userByEmail) { - throw new ServiceError(ERRORS.EMAIL_NOT_FOUND); - } - return userByEmail; - } -} diff --git a/packages/server/src/services/Authentication/AuthSignin.ts b/packages/server/src/services/Authentication/AuthSignin.ts deleted file mode 100644 index ede392801..000000000 --- a/packages/server/src/services/Authentication/AuthSignin.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Container, Inject } from 'typedi'; -import { cloneDeep } from 'lodash'; -import { SystemUser, Tenant } from '@/system/models'; -import { - IAuthSignedInEventPayload, - IAuthSigningInEventPayload, - IAuthSignInPOJO, - ISystemUser, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { generateToken } from './_utils'; -import { ERRORS } from './_constants'; - -@Inject() -export class AuthSigninService { - @Inject() - private eventPublisher: EventPublisher; - - @Inject('repositories') - private sysRepositories: any; - - /** - * Validates the given email and password. - * @param {ISystemUser} user - * @param {string} email - * @param {string} password - */ - public async validateSignIn( - user: ISystemUser, - email: string, - password: string - ) { - const loginThrottler = Container.get('rateLimiter.login'); - - // Validate if the user is not exist. - if (!user) { - await loginThrottler.hit(email); - throw new ServiceError(ERRORS.INVALID_DETAILS); - } - // Validate if the given user's password is wrong. - if (!user.verifyPassword(password)) { - await loginThrottler.hit(email); - throw new ServiceError(ERRORS.INVALID_DETAILS); - } - // Validate if the given user is inactive. - if (!user.active) { - throw new ServiceError(ERRORS.USER_INACTIVE); - } - } - - /** - * Signin and generates JWT token. - * @throws {ServiceError} - * @param {string} email - Email address. - * @param {string} password - Password. - * @return {Promise<{user: IUser, token: string}>} - */ - public async signIn( - email: string, - password: string - ): Promise { - const { systemUserRepository } = this.sysRepositories; - - // Finds the user of the given email address. - const user = await SystemUser.query() - .findOne('email', email) - .modify('inviteAccepted'); - - // Validate the given email and password. - await this.validateSignIn(user, email, password); - - // Triggers on signing-in event. - await this.eventPublisher.emitAsync(events.auth.signingIn, { - email, - password, - user, - } as IAuthSigningInEventPayload); - - const token = generateToken(user); - - // Update the last login at of the user. - await systemUserRepository.patchLastLoginAt(user.id); - - // Triggers `onSignIn` event. - await this.eventPublisher.emitAsync(events.auth.signIn, { - email, - password, - user, - } as IAuthSignedInEventPayload); - - const tenant = await Tenant.query() - .findById(user.tenantId) - .withGraphFetched('metadata'); - - // Keep the user object immutable. - const outputUser = cloneDeep(user); - - // Remove password property from user object. - Reflect.deleteProperty(outputUser, 'password'); - - return { user: outputUser, token, tenant }; - } -} diff --git a/packages/server/src/services/Authentication/AuthSignup.ts b/packages/server/src/services/Authentication/AuthSignup.ts deleted file mode 100644 index 17c7f574c..000000000 --- a/packages/server/src/services/Authentication/AuthSignup.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { defaultTo, isEmpty, omit } from 'lodash'; -import moment from 'moment'; -import crypto from 'crypto'; -import { ServiceError } from '@/exceptions'; -import { - IAuthSignedUpEventPayload, - IAuthSigningUpEventPayload, - IRegisterDTO, - ISystemUser, -} from '@/interfaces'; -import { ERRORS } from './_constants'; -import { Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import TenantsManagerService from '../Tenancy/TenantsManager'; -import events from '@/subscribers/events'; -import { hashPassword } from '@/utils'; -import config from '@/config'; - -export class AuthSignupService { - @Inject() - private eventPublisher: EventPublisher; - - @Inject('repositories') - private sysRepositories: any; - - @Inject() - private tenantsManager: TenantsManagerService; - - /** - * Registers a new tenant with user from user input. - * @throws {ServiceErrors} - * @param {IRegisterDTO} signupDTO - * @returns {Promise} - */ - public async signUp(signupDTO: IRegisterDTO): Promise { - const { systemUserRepository } = this.sysRepositories; - - // Validates the signup disable restrictions. - await this.validateSignupRestrictions(signupDTO.email); - - // Validates the given email uniqiness. - await this.validateEmailUniqiness(signupDTO.email); - - const hashedPassword = await hashPassword(signupDTO.password); - - const verifyTokenCrypto = crypto.randomBytes(64).toString('hex'); - const verifiedEnabed = defaultTo(config.signupConfirmation.enabled, false); - const verifyToken = verifiedEnabed ? verifyTokenCrypto : ''; - const verified = !verifiedEnabed; - - const inviteAcceptedAt = moment().format('YYYY-MM-DD'); - - // Triggers signin up event. - await this.eventPublisher.emitAsync(events.auth.signingUp, { - signupDTO, - } as IAuthSigningUpEventPayload); - - const tenant = await this.tenantsManager.createTenant(); - const registeredUser = await systemUserRepository.create({ - ...omit(signupDTO, 'country'), - verifyToken, - verified, - active: true, - password: hashedPassword, - tenantId: tenant.id, - inviteAcceptedAt, - }); - // Triggers signed up event. - await this.eventPublisher.emitAsync(events.auth.signUp, { - signupDTO, - tenant, - user: registeredUser, - } as IAuthSignedUpEventPayload); - - return registeredUser; - } - - /** - * Validates email uniqiness on the storage. - * @throws {ServiceErrors} - * @param {string} email - Email address - */ - private async validateEmailUniqiness(email: string) { - const { systemUserRepository } = this.sysRepositories; - const isEmailExists = await systemUserRepository.findOneByEmail(email); - - if (isEmailExists) { - throw new ServiceError(ERRORS.EMAIL_EXISTS); - } - } - - /** - * Validate sign-up disable restrictions. - * @param {string} email - */ - private async validateSignupRestrictions(email: string) { - // Can't continue if the signup is not disabled. - if (!config.signupRestrictions.disabled) return; - - // Validate the allowed email addresses and domains. - if ( - !isEmpty(config.signupRestrictions.allowedEmails) || - !isEmpty(config.signupRestrictions.allowedDomains) - ) { - const emailDomain = email.split('@').pop(); - const isAllowedEmail = - config.signupRestrictions.allowedEmails.indexOf(email) !== -1; - - const isAllowedDomain = config.signupRestrictions.allowedDomains.some( - (domain) => emailDomain === domain - ); - - if (!isAllowedEmail && !isAllowedDomain) { - throw new ServiceError(ERRORS.SIGNUP_RESTRICTED_NOT_ALLOWED); - } - // Throw error if the signup is disabled with no exceptions. - } else { - throw new ServiceError(ERRORS.SIGNUP_RESTRICTED); - } - } -} diff --git a/packages/server/src/services/Authentication/AuthSignupConfirm.ts b/packages/server/src/services/Authentication/AuthSignupConfirm.ts deleted file mode 100644 index b08a4bd2e..000000000 --- a/packages/server/src/services/Authentication/AuthSignupConfirm.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { SystemUser } from '@/system/models'; -import { ERRORS } from './_constants'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { - IAuthSignUpVerifiedEventPayload, - IAuthSignUpVerifingEventPayload, -} from '@/interfaces'; - -@Service() -export class AuthSignupConfirmService { - @Inject() - private eventPublisher: EventPublisher; - - /** - * Verifies the provided user's email after signing-up. - * @throws {ServiceErrors} - * @param {IRegisterDTO} signupDTO - * @returns {Promise} - */ - public async signUpConfirm( - email: string, - verifyToken: string - ): Promise { - const foundUser = await SystemUser.query().findOne({ email, verifyToken }); - - if (!foundUser) { - throw new ServiceError(ERRORS.SIGNUP_CONFIRM_TOKEN_INVALID); - } - const userId = foundUser.id; - - // Triggers `signUpConfirming` event. - await this.eventPublisher.emitAsync(events.auth.signUpConfirming, { - email, - verifyToken, - userId, - } as IAuthSignUpVerifingEventPayload); - - const updatedUser = await SystemUser.query().patchAndFetchById( - foundUser.id, - { - verified: true, - verifyToken: '', - } - ); - // Triggers `signUpConfirmed` event. - await this.eventPublisher.emitAsync(events.auth.signUpConfirmed, { - email, - verifyToken, - userId, - } as IAuthSignUpVerifiedEventPayload); - - return updatedUser as SystemUser; - } -} diff --git a/packages/server/src/services/Authentication/AuthSignupResend.ts b/packages/server/src/services/Authentication/AuthSignupResend.ts deleted file mode 100644 index 8edb08f35..000000000 --- a/packages/server/src/services/Authentication/AuthSignupResend.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { SystemUser } from '@/system/models'; -import { ERRORS } from './_constants'; - -@Service() -export class AuthSignupConfirmResend { - @Inject('agenda') - private agenda: any; - - /** - * Resends the email confirmation of the given user. - * @param {number} userId - User ID. - * @returns {Promise} - */ - public async signUpConfirmResend(userId: number) { - const user = await SystemUser.query().findById(userId).throwIfNotFound(); - - // Throw error if the user is already verified. - if (user.verified) { - throw new ServiceError(ERRORS.USER_ALREADY_VERIFIED); - } - // Throw error if the verification token is not exist. - if (!user.verifyToken) { - throw new ServiceError(ERRORS.USER_ALREADY_VERIFIED); - } - const payload = { - email: user.email, - token: user.verifyToken, - fullName: user.firstName, - }; - await this.agenda.now('send-signup-verify-mail', payload); - } -} diff --git a/packages/server/src/services/Authentication/AuthenticationMailMessages.ts b/packages/server/src/services/Authentication/AuthenticationMailMessages.ts deleted file mode 100644 index 533315e72..000000000 --- a/packages/server/src/services/Authentication/AuthenticationMailMessages.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Service } from 'typedi'; -import { ISystemUser } from '@/interfaces'; -import config from '@/config'; -import Mail from '@/lib/Mail'; - -@Service() -export default class AuthenticationMailMesssages { - /** - * Sends reset password message. - * @param {ISystemUser} user - The system user. - * @param {string} token - Reset password token. - * @return {Promise} - */ - public async sendResetPasswordMessage( - user: ISystemUser, - token: string - ): Promise { - await new Mail() - .setSubject('Bigcapital - Password Reset') - .setView('mail/ResetPassword.html') - .setTo(user.email) - .setAttachments([ - { - filename: 'bigcapital.png', - path: `${global.__views_dir}/images/bigcapital.png`, - cid: 'bigcapital_logo', - }, - ]) - .setData({ - resetPasswordUrl: `${config.baseURL}/auth/reset_password/${token}`, - first_name: user.firstName, - last_name: user.lastName, - }) - .send(); - } - - /** - * Sends signup verification mail. - * @param {string} email - Email address - * @param {string} fullName - User name. - * @param {string} token - Verification token. - * @returns {Promise} - */ - public async sendSignupVerificationMail( - email: string, - fullName: string, - token: string - ) { - const verifyUrl = `${config.baseURL}/auth/email_confirmation?token=${token}&email=${email}`; - - await new Mail() - .setSubject('Bigcapital - Verify your email') - .setView('mail/SignupVerifyEmail.html') - .setTo(email) - .setAttachments([ - { - filename: 'bigcapital.png', - path: `${global.__views_dir}/images/bigcapital.png`, - cid: 'bigcapital_logo', - }, - ]) - .setData({ verifyUrl, fullName }) - .send(); - } -} diff --git a/packages/server/src/services/Authentication/GetAuthMeta.ts b/packages/server/src/services/Authentication/GetAuthMeta.ts deleted file mode 100644 index 0183043b8..000000000 --- a/packages/server/src/services/Authentication/GetAuthMeta.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Service } from 'typedi'; -import { IAuthGetMetaPOJO } from '@/interfaces'; -import config from '@/config'; - -@Service() -export class GetAuthMeta { - /** - * Retrieves the authentication meta for SPA. - * @returns {Promise} - */ - public async getAuthMeta(): Promise { - return { - signupDisabled: config.signupRestrictions.disabled, - oneClickDemo: { - enable: config.oneClickDemoAccounts.enable, - demoUrl: config.oneClickDemoAccounts.demoUrl, - }, - }; - } -} diff --git a/packages/server/src/services/Authentication/RateLimiter.ts b/packages/server/src/services/Authentication/RateLimiter.ts deleted file mode 100644 index efbe7b7d2..000000000 --- a/packages/server/src/services/Authentication/RateLimiter.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { RateLimiterClusterMasterPM2, RateLimiterMemory, RateLimiterRedis, RateLimiterRes } from 'rate-limiter-flexible'; - -export default class RateLimiter { - rateLimiter: RateLimiterRedis; - - /** - * Rate limiter redis constructor. - * @param {RateLimiterRedis} rateLimiter - */ - constructor(rateLimiter: RateLimiterMemory) { - this.rateLimiter = rateLimiter; - } - - /** - * - * @return {boolean} - */ - public attempt(key: string, pointsToConsume = 1): Promise { - return this.rateLimiter.consume(key, pointsToConsume); - } - - /** - * Increment the counter for a given key for a given decay time. - * @param {string} key - - */ - public hit( - key: string | number, - points: number, - secDuration: number, - ): Promise { - return this.rateLimiter.penalty(key, points, secDuration); - } - - /** - * Retrieve the rate limiter response of the given key. - * @param {string} key - */ - public get(key: string): Promise { - return this.rateLimiter.get(key); - } - - /** - * Resets the rate limiter of the given key. - * @param key - */ - public reset(key: string): Promise { - return this.rateLimiter.delete(key); - } -} \ No newline at end of file diff --git a/packages/server/src/services/Authentication/_constants.ts b/packages/server/src/services/Authentication/_constants.ts deleted file mode 100644 index 506525779..000000000 --- a/packages/server/src/services/Authentication/_constants.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const ERRORS = { - INVALID_DETAILS: 'INVALID_DETAILS', - USER_INACTIVE: 'USER_INACTIVE', - EMAIL_NOT_FOUND: 'EMAIL_NOT_FOUND', - TOKEN_INVALID: 'TOKEN_INVALID', - USER_NOT_FOUND: 'USER_NOT_FOUND', - TOKEN_EXPIRED: 'TOKEN_EXPIRED', - PHONE_NUMBER_EXISTS: 'PHONE_NUMBER_EXISTS', - EMAIL_EXISTS: 'EMAIL_EXISTS', - SIGNUP_RESTRICTED_NOT_ALLOWED: 'SIGNUP_RESTRICTED_NOT_ALLOWED', - SIGNUP_RESTRICTED: 'SIGNUP_RESTRICTED', - SIGNUP_CONFIRM_TOKEN_INVALID: 'SIGNUP_CONFIRM_TOKEN_INVALID', - USER_ALREADY_VERIFIED: 'USER_ALREADY_VERIFIED', -}; diff --git a/packages/server/src/services/Authentication/_utils.ts b/packages/server/src/services/Authentication/_utils.ts deleted file mode 100644 index 24158e3c9..000000000 --- a/packages/server/src/services/Authentication/_utils.ts +++ /dev/null @@ -1,22 +0,0 @@ -import JWT from 'jsonwebtoken'; -import { ISystemUser } from '@/interfaces'; -import config from '@/config'; - -/** - * Generates JWT token for the given user. - * @param {ISystemUser} user - * @return {string} token - */ -export const generateToken = (user: ISystemUser): string => { - const today = new Date(); - const exp = new Date(today); - exp.setDate(today.getDate() + 60); - - return JWT.sign( - { - id: user.id, // We are gonna use this in the middleware 'isAuth' - exp: exp.getTime() / 1000, - }, - config.jwtSecret - ); -}; diff --git a/packages/server/src/services/Authentication/events/SendVerfiyMailOnSignUp.ts b/packages/server/src/services/Authentication/events/SendVerfiyMailOnSignUp.ts deleted file mode 100644 index 19f432df2..000000000 --- a/packages/server/src/services/Authentication/events/SendVerfiyMailOnSignUp.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { IAuthSignedUpEventPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { Inject } from 'typedi'; - -export class SendVerfiyMailOnSignUp { - @Inject('agenda') - private agenda: any; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe(events.auth.signUp, this.handleSendVerifyMailOnSignup); - } - - /** - * - * @param {ITaxRateEditedPayload} payload - - */ - private handleSendVerifyMailOnSignup = async ({ - user, - }: IAuthSignedUpEventPayload) => { - // Can't continue if the user is verified. - if (user.verified) { - return; - } - const payload = { - email: user.email, - token: user.verifyToken, - fullName: user.firstName, - }; - await this.agenda.now('send-signup-verify-mail', payload); - }; -} diff --git a/packages/server/src/services/Authentication/jobs/SendVerifyMailJob.ts b/packages/server/src/services/Authentication/jobs/SendVerifyMailJob.ts deleted file mode 100644 index 8e09053da..000000000 --- a/packages/server/src/services/Authentication/jobs/SendVerifyMailJob.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Container } from 'typedi'; -import AuthenticationMailMesssages from '@/services/Authentication/AuthenticationMailMessages'; - -export class SendVerifyMailJob { - /** - * Constructor method. - * @param {Agenda} agenda - */ - constructor(agenda) { - agenda.define( - 'send-signup-verify-mail', - { priority: 'high' }, - this.handler.bind(this) - ); - } - - /** - * Handle send welcome mail job. - * @param {Job} job - * @param {Function} done - */ - public async handler(job, done: Function): Promise { - const { data } = job.attrs; - const { email, fullName, token } = data; - const authService = Container.get(AuthenticationMailMesssages); - - try { - await authService.sendSignupVerificationMail(email, fullName, token); - done(); - } catch (error) { - console.log(error); - done(error); - } - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/BankAccountsApplication.tsx b/packages/server/src/services/Banking/BankAccounts/BankAccountsApplication.tsx deleted file mode 100644 index b2fc48775..000000000 --- a/packages/server/src/services/Banking/BankAccounts/BankAccountsApplication.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { DisconnectBankAccount } from './DisconnectBankAccount'; -import { RefreshBankAccountService } from './RefreshBankAccount'; -import { PauseBankAccountFeeds } from './PauseBankAccountFeeds'; -import { ResumeBankAccountFeeds } from './ResumeBankAccountFeeds'; - -@Service() -export class BankAccountsApplication { - @Inject() - private disconnectBankAccountService: DisconnectBankAccount; - - @Inject() - private refreshBankAccountService: RefreshBankAccountService; - - @Inject() - private resumeBankAccountFeedsService: ResumeBankAccountFeeds; - - @Inject() - private pauseBankAccountFeedsService: PauseBankAccountFeeds; - - /** - * Disconnects the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - async disconnectBankAccount(tenantId: number, bankAccountId: number) { - return this.disconnectBankAccountService.disconnectBankAccount( - tenantId, - bankAccountId - ); - } - - /** - * Refresh the bank transactions of the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - async refreshBankAccount(tenantId: number, bankAccountId: number) { - return this.refreshBankAccountService.refreshBankAccount( - tenantId, - bankAccountId - ); - } - - /** - * Pauses the feeds sync of the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - async pauseBankAccount(tenantId: number, bankAccountId: number) { - return this.pauseBankAccountFeedsService.pauseBankAccountFeeds( - tenantId, - bankAccountId - ); - } - - /** - * Resumes the feeds sync of the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - async resumeBankAccount(tenantId: number, bankAccountId: number) { - return this.resumeBankAccountFeedsService.resumeBankAccountFeeds( - tenantId, - bankAccountId - ); - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/DisconnectBankAccount.tsx b/packages/server/src/services/Banking/BankAccounts/DisconnectBankAccount.tsx deleted file mode 100644 index fe43ef1e2..000000000 --- a/packages/server/src/services/Banking/BankAccounts/DisconnectBankAccount.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { PlaidClientWrapper } from '@/lib/Plaid'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { - ERRORS, - IBankAccountDisconnectedEventPayload, - IBankAccountDisconnectingEventPayload, -} from './types'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -@Service() -export class DisconnectBankAccount { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Disconnects the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - public async disconnectBankAccount(tenantId: number, bankAccountId: number) { - const { Account, PlaidItem } = this.tenancy.models(tenantId); - - // Retrieve the bank account or throw not found error. - const account = await Account.query() - .findById(bankAccountId) - .whereIn('account_type', [ACCOUNT_TYPE.CASH, ACCOUNT_TYPE.BANK]) - .withGraphFetched('plaidItem') - .throwIfNotFound(); - - const oldPlaidItem = account.plaidItem; - - if (!oldPlaidItem) { - throw new ServiceError(ERRORS.BANK_ACCOUNT_NOT_CONNECTED); - } - const plaidInstance = PlaidClientWrapper.getClient(); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBankAccountDisconnecting` event. - await this.eventPublisher.emitAsync(events.bankAccount.onDisconnecting, { - tenantId, - bankAccountId, - } as IBankAccountDisconnectingEventPayload); - - // Remove the Plaid item from the system. - await PlaidItem.query(trx).findById(account.plaidItemId).delete(); - - // Remove the plaid item association to the bank account. - await Account.query(trx).findById(bankAccountId).patch({ - plaidAccountId: null, - plaidItemId: null, - isFeedsActive: false, - }); - // Remove the Plaid item. - await plaidInstance.itemRemove({ - access_token: oldPlaidItem.plaidAccessToken, - }); - // Triggers `onBankAccountDisconnected` event. - await this.eventPublisher.emitAsync(events.bankAccount.onDisconnected, { - tenantId, - bankAccountId, - trx, - } as IBankAccountDisconnectedEventPayload); - }); - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/GetBankAccountSummary.ts b/packages/server/src/services/Banking/BankAccounts/GetBankAccountSummary.ts deleted file mode 100644 index 4d7b7885a..000000000 --- a/packages/server/src/services/Banking/BankAccounts/GetBankAccountSummary.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { UncategorizedTransactionTransformer } from '@/services/Cashflow/UncategorizedTransactionTransformer'; - -@Service() -export class GetBankAccountSummary { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the bank account meta summary - * @param {number} tenantId - * @param {number} bankAccountId - * @returns - */ - public async getBankAccountSummary(tenantId: number, bankAccountId: number) { - const knex = this.tenancy.knex(tenantId); - const { - Account, - UncategorizedCashflowTransaction, - RecognizedBankTransaction, - MatchedBankTransaction, - } = this.tenancy.models(tenantId); - - await initialize(knex, [ - UncategorizedCashflowTransaction, - RecognizedBankTransaction, - MatchedBankTransaction, - ]); - const bankAccount = await Account.query() - .findById(bankAccountId) - .throwIfNotFound(); - - const commonQuery = (q) => { - // Include just the given account. - q.where('accountId', bankAccountId); - - // Only the not excluded. - q.modify('notExcluded'); - - // Only the not categorized. - q.modify('notCategorized'); - }; - - // Retrieves the uncategorized transactions count of the given bank account. - const uncategorizedTranasctionsCount = - await UncategorizedCashflowTransaction.query().onBuild((q) => { - commonQuery(q); - - // Only the not matched bank transactions. - q.withGraphJoined('matchedBankTransactions'); - q.whereNull('matchedBankTransactions.id'); - - // Exclude the pending transactions. - q.modify('notPending'); - - // Count the results. - q.count('uncategorized_cashflow_transactions.id as total'); - q.first(); - }); - - // Retrives the recognized transactions count. - const recognizedTransactionsCount = - await UncategorizedCashflowTransaction.query().onBuild((q) => { - commonQuery(q); - - q.withGraphJoined('recognizedTransaction'); - q.whereNotNull('recognizedTransaction.id'); - - // Exclude the pending transactions. - q.modify('notPending'); - - // Count the results. - q.count('uncategorized_cashflow_transactions.id as total'); - q.first(); - }); - // Retrieves excluded transactions count. - const excludedTransactionsCount = - await UncategorizedCashflowTransaction.query().onBuild((q) => { - q.where('accountId', bankAccountId); - q.modify('excluded'); - - // Exclude the pending transactions. - q.modify('notPending'); - - // Count the results. - q.count('uncategorized_cashflow_transactions.id as total'); - q.first(); - }); - // Retrieves the pending transactions count. - const pendingTransactionsCount = - await UncategorizedCashflowTransaction.query().onBuild((q) => { - q.where('accountId', bankAccountId); - q.modify('pending'); - - // Count the results. - q.count('uncategorized_cashflow_transactions.id as total'); - q.first(); - }); - - const totalUncategorizedTransactions = - uncategorizedTranasctionsCount?.total || 0; - const totalRecognizedTransactions = recognizedTransactionsCount?.total || 0; - const totalExcludedTransactions = excludedTransactionsCount?.total || 0; - const totalPendingTransactions = pendingTransactionsCount?.total || 0; - - return { - name: bankAccount.name, - totalUncategorizedTransactions, - totalRecognizedTransactions, - totalExcludedTransactions, - totalPendingTransactions, - }; - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx b/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx deleted file mode 100644 index 3b16ecd76..000000000 --- a/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './types'; - -@Service() -export class PauseBankAccountFeeds { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - /** - * Pauses the bankfeed syncing of the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - public async pauseBankAccountFeeds(tenantId: number, bankAccountId: number) { - const { Account, PlaidItem } = this.tenancy.models(tenantId); - - const oldAccount = await Account.query() - .findById(bankAccountId) - .withGraphFetched('plaidItem') - .throwIfNotFound(); - - // Can't continue if the bank account is not connected. - if (!oldAccount.plaidItem) { - throw new ServiceError(ERRORS.BANK_ACCOUNT_NOT_CONNECTED); - } - // Cannot continue if the bank account feeds is already paused. - if (oldAccount.plaidItem.isPaused) { - throw new ServiceError(ERRORS.BANK_ACCOUNT_FEEDS_ALREADY_PAUSED); - } - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - await PlaidItem.query(trx).findById(oldAccount.plaidItem.id).patch({ - pausedAt: new Date(), - }); - }); - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/RefreshBankAccount.tsx b/packages/server/src/services/Banking/BankAccounts/RefreshBankAccount.tsx deleted file mode 100644 index 8efa5845d..000000000 --- a/packages/server/src/services/Banking/BankAccounts/RefreshBankAccount.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { PlaidClientWrapper } from '@/lib/Plaid'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './types'; - -@Service() -export class RefreshBankAccountService { - @Inject() - private tenancy: HasTenancyService; - - /** - * Asks Plaid to trigger syncing the given bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - public async refreshBankAccount(tenantId: number, bankAccountId: number) { - const { Account } = this.tenancy.models(tenantId); - - const bankAccount = await Account.query() - .findById(bankAccountId) - .withGraphFetched('plaidItem') - .throwIfNotFound(); - - // Can't continue if the given account is not linked with Plaid item. - if (!bankAccount.plaidItem) { - throw new ServiceError(ERRORS.BANK_ACCOUNT_NOT_CONNECTED); - } - const plaidInstance = PlaidClientWrapper.getClient(); - - await plaidInstance.transactionsRefresh({ - access_token: bankAccount.plaidItem.plaidAccessToken, - }); - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx b/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx deleted file mode 100644 index ab630a145..000000000 --- a/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './types'; - -@Service() -export class ResumeBankAccountFeeds { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - /** - * Resumes the bank feeds syncing of the bank account. - * @param {number} tenantId - * @param {number} bankAccountId - * @returns {Promise} - */ - public async resumeBankAccountFeeds(tenantId: number, bankAccountId: number) { - const { Account, PlaidItem } = this.tenancy.models(tenantId); - - const oldAccount = await Account.query() - .findById(bankAccountId) - .withGraphFetched('plaidItem'); - - // Can't continue if the bank account is not connected. - if (!oldAccount.plaidItem) { - throw new ServiceError(ERRORS.BANK_ACCOUNT_NOT_CONNECTED); - } - // Cannot continue if the bank account feeds is already paused. - if (!oldAccount.plaidItem.isPaused) { - throw new ServiceError(ERRORS.BANK_ACCOUNT_FEEDS_ALREADY_RESUMED); - } - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - await PlaidItem.query(trx).findById(oldAccount.plaidItem.id).patch({ - pausedAt: null, - }); - }); - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting.ts b/packages/server/src/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting.ts deleted file mode 100644 index f2d9202ee..000000000 --- a/packages/server/src/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { IAccountEventDeletePayload } from '@/interfaces'; -import { DeleteBankRulesService } from '../../Rules/DeleteBankRules'; -import { RevertRecognizedTransactions } from '../../RegonizeTranasctions/RevertRecognizedTransactions'; - -@Service() -export class DeleteUncategorizedTransactionsOnAccountDeleting { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private deleteBankRules: DeleteBankRulesService; - - @Inject() - private revertRecognizedTransactins: RevertRecognizedTransactions; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.accounts.onDelete, - this.handleDeleteBankRulesOnAccountDeleting.bind(this) - ); - } - - /** - * Handles revert the recognized transactions and delete all the bank rules - * associated to the deleted bank account. - * @param {IAccountEventDeletePayload} - */ - private async handleDeleteBankRulesOnAccountDeleting({ - tenantId, - oldAccount, - trx, - }: IAccountEventDeletePayload) { - const knex = this.tenancy.knex(tenantId); - const { - BankRule, - UncategorizedCashflowTransaction, - MatchedBankTransaction, - RecognizedBankTransaction, - } = this.tenancy.models(tenantId); - - const foundAssociatedRules = await BankRule.query(trx).where( - 'applyIfAccountId', - oldAccount.id - ); - const foundAssociatedRulesIds = foundAssociatedRules.map((rule) => rule.id); - - await initialize(knex, [ - UncategorizedCashflowTransaction, - RecognizedBankTransaction, - MatchedBankTransaction, - ]); - // Revert the recognized transactions of the given bank rules. - await this.revertRecognizedTransactins.revertRecognizedTransactions( - tenantId, - foundAssociatedRulesIds, - null, - trx - ); - // Delete the associated uncategorized transactions. - await UncategorizedCashflowTransaction.query(trx) - .where('accountId', oldAccount.id) - .delete(); - - // Delete the given bank rules. - await this.deleteBankRules.deleteBankRules( - tenantId, - foundAssociatedRulesIds, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/events/DisconnectPlaidItemOnAccountDeleted.ts b/packages/server/src/services/Banking/BankAccounts/events/DisconnectPlaidItemOnAccountDeleted.ts deleted file mode 100644 index 4ecf71e81..000000000 --- a/packages/server/src/services/Banking/BankAccounts/events/DisconnectPlaidItemOnAccountDeleted.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAccountEventDeletedPayload } from '@/interfaces'; -import { PlaidClientWrapper } from '@/lib/Plaid'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; - -@Service() -export class DisconnectPlaidItemOnAccountDeleted { - @Inject() - private tenancy: HasTenancyService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.accounts.onDeleted, - this.handleDisconnectPlaidItemOnAccountDelete.bind(this) - ); - } - - /** - * Deletes Plaid item from the system and Plaid once the account deleted. - * @param {IAccountEventDeletedPayload} payload - * @returns {Promise} - */ - private async handleDisconnectPlaidItemOnAccountDelete({ - tenantId, - oldAccount, - trx, - }: IAccountEventDeletedPayload) { - const { PlaidItem, Account } = this.tenancy.models(tenantId); - - // Can't continue if the deleted account is not linked to Plaid item. - if (!oldAccount.plaidItemId) return; - - // Retrieves the Plaid item that associated to the deleted account. - const oldPlaidItem = await PlaidItem.query(trx).findOne( - 'plaidItemId', - oldAccount.plaidItemId - ); - // Unlink the Plaid item from all account before deleting it. - await Account.query(trx) - .where('plaidItemId', oldAccount.plaidItemId) - .patch({ - plaidAccountId: null, - plaidItemId: null, - }); - // Remove the Plaid item from the system. - await PlaidItem.query(trx) - .findOne('plaidItemId', oldAccount.plaidItemId) - .delete(); - - // Remove Plaid item once the transaction resolve. - if (oldPlaidItem) { - const plaidInstance = PlaidClientWrapper.getClient(); - - // Remove the Plaid item. - await plaidInstance.itemRemove({ - access_token: oldPlaidItem.plaidAccessToken, - }); - } - } -} diff --git a/packages/server/src/services/Banking/BankAccounts/types.ts b/packages/server/src/services/Banking/BankAccounts/types.ts deleted file mode 100644 index cd21e490c..000000000 --- a/packages/server/src/services/Banking/BankAccounts/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Knex } from 'knex'; - -export interface IBankAccountDisconnectingEventPayload { - tenantId: number; - bankAccountId: number; - trx: Knex.Transaction; -} - -export interface IBankAccountDisconnectedEventPayload { - tenantId: number; - bankAccountId: number; - trx: Knex.Transaction; -} - -export const ERRORS = { - BANK_ACCOUNT_NOT_CONNECTED: 'BANK_ACCOUNT_NOT_CONNECTED', - BANK_ACCOUNT_FEEDS_ALREADY_PAUSED: 'BANK_ACCOUNT_FEEDS_ALREADY_PAUSED', - BANK_ACCOUNT_FEEDS_ALREADY_RESUMED: 'BANK_ACCOUNT_FEEDS_ALREADY_RESUMED', -}; diff --git a/packages/server/src/services/Banking/Exclude/ExcludeBankTransaction.ts b/packages/server/src/services/Banking/Exclude/ExcludeBankTransaction.ts deleted file mode 100644 index 7b8012ccd..000000000 --- a/packages/server/src/services/Banking/Exclude/ExcludeBankTransaction.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { - validateTransactionNotCategorized, - validateTransactionNotExcluded, -} from './utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { - IBankTransactionUnexcludedEventPayload, - IBankTransactionUnexcludingEventPayload, -} from './_types'; - -@Service() -export class ExcludeBankTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Marks the given bank transaction as excluded. - * @param {number} tenantId - * @param {number} bankTransactionId - * @returns {Promise} - */ - public async excludeBankTransaction( - tenantId: number, - uncategorizedTransactionId: number - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const oldUncategorizedTransaction = - await UncategorizedCashflowTransaction.query() - .findById(uncategorizedTransactionId) - .throwIfNotFound(); - - // Validate the transaction shouldn't be excluded. - validateTransactionNotExcluded(oldUncategorizedTransaction); - - // Validate the transaction shouldn't be categorized. - validateTransactionNotCategorized(oldUncategorizedTransaction); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - await this.eventPublisher.emitAsync(events.bankTransactions.onExcluding, { - tenantId, - uncategorizedTransactionId, - trx, - } as IBankTransactionUnexcludingEventPayload); - - await UncategorizedCashflowTransaction.query(trx) - .findById(uncategorizedTransactionId) - .patch({ - excludedAt: new Date(), - }); - - await this.eventPublisher.emitAsync(events.bankTransactions.onExcluded, { - tenantId, - uncategorizedTransactionId, - trx, - } as IBankTransactionUnexcludedEventPayload); - }); - } -} diff --git a/packages/server/src/services/Banking/Exclude/ExcludeBankTransactions.ts b/packages/server/src/services/Banking/Exclude/ExcludeBankTransactions.ts deleted file mode 100644 index 91bdf5320..000000000 --- a/packages/server/src/services/Banking/Exclude/ExcludeBankTransactions.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import PromisePool from '@supercharge/promise-pool'; -import { castArray, uniq } from 'lodash'; -import { ExcludeBankTransaction } from './ExcludeBankTransaction'; - -@Service() -export class ExcludeBankTransactions { - @Inject() - private excludeBankTransaction: ExcludeBankTransaction; - - /** - * Exclude bank transactions in bulk. - * @param {number} tenantId - * @param {number} bankTransactionIds - * @returns {Promise} - */ - public async excludeBankTransactions( - tenantId: number, - bankTransactionIds: Array | number - ) { - const _bankTransactionIds = uniq(castArray(bankTransactionIds)); - - await PromisePool.withConcurrency(1) - .for(_bankTransactionIds) - .process((bankTransactionId: number) => { - return this.excludeBankTransaction.excludeBankTransaction( - tenantId, - bankTransactionId - ); - }); - } -} diff --git a/packages/server/src/services/Banking/Exclude/ExcludeBankTransactionsApplication.ts b/packages/server/src/services/Banking/Exclude/ExcludeBankTransactionsApplication.ts deleted file mode 100644 index 621652d86..000000000 --- a/packages/server/src/services/Banking/Exclude/ExcludeBankTransactionsApplication.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ExcludeBankTransaction } from './ExcludeBankTransaction'; -import { UnexcludeBankTransaction } from './UnexcludeBankTransaction'; -import { GetExcludedBankTransactionsService } from './GetExcludedBankTransactions'; -import { ExcludedBankTransactionsQuery } from './_types'; -import { UnexcludeBankTransactions } from './UnexcludeBankTransactions'; -import { ExcludeBankTransactions } from './ExcludeBankTransactions'; - -@Service() -export class ExcludeBankTransactionsApplication { - @Inject() - private excludeBankTransactionService: ExcludeBankTransaction; - - @Inject() - private unexcludeBankTransactionService: UnexcludeBankTransaction; - - @Inject() - private getExcludedBankTransactionsService: GetExcludedBankTransactionsService; - - @Inject() - private excludeBankTransactionsService: ExcludeBankTransactions; - - @Inject() - private unexcludeBankTransactionsService: UnexcludeBankTransactions; - - /** - * Marks a bank transaction as excluded. - * @param {number} tenantId - The ID of the tenant. - * @param {number} bankTransactionId - The ID of the bank transaction to exclude. - * @returns {Promise} - */ - public excludeBankTransaction(tenantId: number, bankTransactionId: number) { - return this.excludeBankTransactionService.excludeBankTransaction( - tenantId, - bankTransactionId - ); - } - - /** - * Marks a bank transaction as not excluded. - * @param {number} tenantId - The ID of the tenant. - * @param {number} bankTransactionId - The ID of the bank transaction to exclude. - * @returns {Promise} - */ - public unexcludeBankTransaction(tenantId: number, bankTransactionId: number) { - return this.unexcludeBankTransactionService.unexcludeBankTransaction( - tenantId, - bankTransactionId - ); - } - - /** - * Retrieves the excluded bank transactions. - * @param {number} tenantId - * @param {ExcludedBankTransactionsQuery} filter - * @returns {} - */ - public getExcludedBankTransactions( - tenantId: number, - filter: ExcludedBankTransactionsQuery - ) { - return this.getExcludedBankTransactionsService.getExcludedBankTransactions( - tenantId, - filter - ); - } - - /** - * Exclude the given bank transactions in bulk. - * @param {number} tenantId - * @param {Array | number} bankTransactionIds - * @returns {Promise} - */ - public excludeBankTransactions( - tenantId: number, - bankTransactionIds: Array | number - ): Promise { - return this.excludeBankTransactionsService.excludeBankTransactions( - tenantId, - bankTransactionIds - ); - } - - /** - * Exclude the given bank transactions in bulk. - * @param {number} tenantId - * @param {Array | number} bankTransactionIds - * @returns {Promise} - */ - public unexcludeBankTransactions( - tenantId: number, - bankTransactionIds: Array | number - ): Promise { - return this.unexcludeBankTransactionsService.unexcludeBankTransactions( - tenantId, - bankTransactionIds - ); - } -} diff --git a/packages/server/src/services/Banking/Exclude/GetExcludedBankTransactions.ts b/packages/server/src/services/Banking/Exclude/GetExcludedBankTransactions.ts deleted file mode 100644 index 43bc523de..000000000 --- a/packages/server/src/services/Banking/Exclude/GetExcludedBankTransactions.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ExcludedBankTransactionsQuery } from './_types'; -import { UncategorizedTransactionTransformer } from '@/services/Cashflow/UncategorizedTransactionTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetExcludedBankTransactionsService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the excluded uncategorized bank transactions. - * @param {number} tenantId - * @param {ExcludedBankTransactionsQuery} filter - * @returns - */ - public async getExcludedBankTransactions( - tenantId: number, - filter: ExcludedBankTransactionsQuery - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - // Parsed query with default values. - const _query = { - page: 1, - pageSize: 20, - ...filter, - }; - const { results, pagination } = - await UncategorizedCashflowTransaction.query() - .onBuild((q) => { - q.modify('excluded'); - q.orderBy('date', 'DESC'); - - if (_query.accountId) { - q.where('account_id', _query.accountId); - } - if (_query.minDate) { - q.modify('fromDate', _query.minDate); - } - if (_query.maxDate) { - q.modify('toDate', _query.maxDate); - } - if (_query.minAmount) { - q.modify('minAmount', _query.minAmount); - } - if (_query.maxAmount) { - q.modify('maxAmount', _query.maxAmount); - } - }) - .pagination(_query.page - 1, _query.pageSize); - - const data = await this.transformer.transform( - tenantId, - results, - new UncategorizedTransactionTransformer() - ); - return { data, pagination }; - } -} diff --git a/packages/server/src/services/Banking/Exclude/UnexcludeBankTransaction.ts b/packages/server/src/services/Banking/Exclude/UnexcludeBankTransaction.ts deleted file mode 100644 index f6bb1bfad..000000000 --- a/packages/server/src/services/Banking/Exclude/UnexcludeBankTransaction.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { - validateTransactionNotCategorized, - validateTransactionShouldBeExcluded, -} from './utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { - IBankTransactionExcludedEventPayload, - IBankTransactionExcludingEventPayload, -} from './_types'; - -@Service() -export class UnexcludeBankTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Marks the given bank transaction as excluded. - * @param {number} tenantId - * @param {number} bankTransactionId - * @returns {Promise} - */ - public async unexcludeBankTransaction( - tenantId: number, - uncategorizedTransactionId: number - ): Promise { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const oldUncategorizedTransaction = - await UncategorizedCashflowTransaction.query() - .findById(uncategorizedTransactionId) - .throwIfNotFound(); - - // Validate the transaction should be excludded. - validateTransactionShouldBeExcluded(oldUncategorizedTransaction); - - // Validate the transaction shouldn't be categorized. - validateTransactionNotCategorized(oldUncategorizedTransaction); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - await this.eventPublisher.emitAsync( - events.bankTransactions.onUnexcluding, - { - tenantId, - uncategorizedTransactionId, - } as IBankTransactionExcludingEventPayload - ); - - await UncategorizedCashflowTransaction.query(trx) - .findById(uncategorizedTransactionId) - .patch({ - excludedAt: null, - }); - - await this.eventPublisher.emitAsync( - events.bankTransactions.onUnexcluded, - { - tenantId, - uncategorizedTransactionId, - } as IBankTransactionExcludedEventPayload - ); - }); - } -} diff --git a/packages/server/src/services/Banking/Exclude/UnexcludeBankTransactions.ts b/packages/server/src/services/Banking/Exclude/UnexcludeBankTransactions.ts deleted file mode 100644 index d3743aeeb..000000000 --- a/packages/server/src/services/Banking/Exclude/UnexcludeBankTransactions.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import PromisePool from '@supercharge/promise-pool'; -import { UnexcludeBankTransaction } from './UnexcludeBankTransaction'; -import { castArray, uniq } from 'lodash'; - -@Service() -export class UnexcludeBankTransactions { - @Inject() - private unexcludeBankTransaction: UnexcludeBankTransaction; - - /** - * Unexclude bank transactions in bulk. - * @param {number} tenantId - * @param {number} bankTransactionIds - */ - public async unexcludeBankTransactions( - tenantId: number, - bankTransactionIds: Array | number - ) { - const _bankTransactionIds = uniq(castArray(bankTransactionIds)); - - await PromisePool.withConcurrency(1) - .for(_bankTransactionIds) - .process((bankTransactionId: number) => { - return this.unexcludeBankTransaction.unexcludeBankTransaction( - tenantId, - bankTransactionId - ); - }); - } -} diff --git a/packages/server/src/services/Banking/Exclude/_types.ts b/packages/server/src/services/Banking/Exclude/_types.ts deleted file mode 100644 index 5d1e2842d..000000000 --- a/packages/server/src/services/Banking/Exclude/_types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Knex } from "knex"; - -export interface ExcludedBankTransactionsQuery { - page?: number; - pageSize?: number; - accountId?: number; - minDate?: Date; - maxDate?: Date; - minAmount?: number; - maxAmount?: number; -} - -export interface IBankTransactionUnexcludingEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - trx?: Knex.Transaction -} - -export interface IBankTransactionUnexcludedEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - trx?: Knex.Transaction -} - -export interface IBankTransactionExcludingEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - trx?: Knex.Transaction -} -export interface IBankTransactionExcludedEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - trx?: Knex.Transaction -} diff --git a/packages/server/src/services/Banking/Exclude/events/DecrementUncategorizedTransactionOnExclude.ts b/packages/server/src/services/Banking/Exclude/events/DecrementUncategorizedTransactionOnExclude.ts deleted file mode 100644 index 6f3aeba31..000000000 --- a/packages/server/src/services/Banking/Exclude/events/DecrementUncategorizedTransactionOnExclude.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - IBankTransactionExcludedEventPayload, - IBankTransactionUnexcludedEventPayload, -} from '../_types'; - -@Service() -export class DecrementUncategorizedTransactionOnExclude { - @Inject() - private tenancy: HasTenancyService; - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.bankTransactions.onExcluded, - this.decrementUnCategorizedTransactionsOnExclude.bind(this) - ); - bus.subscribe( - events.bankTransactions.onUnexcluded, - this.incrementUnCategorizedTransactionsOnUnexclude.bind(this) - ); - } - - /** - * Validates the cashflow transaction whether matched with bank transaction on deleting. - * @param {IManualJournalDeletingPayload} - */ - public async decrementUnCategorizedTransactionsOnExclude({ - tenantId, - uncategorizedTransactionId, - trx, - }: IBankTransactionExcludedEventPayload) { - const { UncategorizedCashflowTransaction, Account } = - this.tenancy.models(tenantId); - - const transaction = await UncategorizedCashflowTransaction.query( - trx - ).findById(uncategorizedTransactionId); - - await Account.query(trx) - .findById(transaction.accountId) - .decrement('uncategorizedTransactions', 1); - } - - /** - * Validates the cashflow transaction whether matched with bank transaction on deleting. - * @param {IManualJournalDeletingPayload} - */ - public async incrementUnCategorizedTransactionsOnUnexclude({ - tenantId, - uncategorizedTransactionId, - trx, - }: IBankTransactionUnexcludedEventPayload) { - const { UncategorizedCashflowTransaction, Account } = - this.tenancy.models(tenantId); - - const transaction = await UncategorizedCashflowTransaction.query().findById( - uncategorizedTransactionId - ); - // - await Account.query(trx) - .findById(transaction.accountId) - .increment('uncategorizedTransactions', 1); - } -} diff --git a/packages/server/src/services/Banking/Exclude/utils.ts b/packages/server/src/services/Banking/Exclude/utils.ts deleted file mode 100644 index 04b06e8ca..000000000 --- a/packages/server/src/services/Banking/Exclude/utils.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import UncategorizedCashflowTransaction from '@/models/UncategorizedCashflowTransaction'; - -const ERRORS = { - TRANSACTION_ALREADY_CATEGORIZED: 'TRANSACTION_ALREADY_CATEGORIZED', - TRANSACTION_ALREADY_EXCLUDED: 'TRANSACTION_ALREADY_EXCLUDED', - TRANSACTION_NOT_EXCLUDED: 'TRANSACTION_NOT_EXCLUDED', -}; - -export const validateTransactionNotCategorized = ( - transaction: UncategorizedCashflowTransaction -) => { - if (transaction.categorized) { - throw new ServiceError(ERRORS.TRANSACTION_ALREADY_CATEGORIZED); - } -}; - -export const validateTransactionNotExcluded = ( - transaction: UncategorizedCashflowTransaction -) => { - if (transaction.isExcluded) { - throw new ServiceError(ERRORS.TRANSACTION_ALREADY_EXCLUDED); - } -}; - -export const validateTransactionShouldBeExcluded = ( - transaction: UncategorizedCashflowTransaction -) => { - if (!transaction.isExcluded) { - throw new ServiceError(ERRORS.TRANSACTION_NOT_EXCLUDED); - } -}; diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionBillsTransformer.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionBillsTransformer.ts deleted file mode 100644 index 4f833c599..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionBillsTransformer.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetMatchedTransactionBillsTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'referenceNo', - 'amount', - 'amountFormatted', - 'transactionNo', - 'date', - 'dateFormatted', - 'transactionId', - 'transactionNo', - 'transactionType', - 'transsactionTypeFormatted', - 'transactionNormal', - 'referenceId', - 'referenceType', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieve the reference number of the bill. - * @param {Object} bill - The bill object. - * @returns {string} - */ - protected referenceNo(bill) { - return bill.referenceNo; - } - - /** - * Retrieve the amount of the bill. - * @param {Object} bill - The bill object. - * @returns {number} - */ - protected amount(bill) { - return bill.amount; - } - - /** - * Retrieve the formatted amount of the bill. - * @param {Object} bill - The bill object. - * @returns {string} - */ - protected amountFormatted(bill) { - return this.formatNumber(bill.amount, { - currencyCode: bill.currencyCode, - money: true, - }); - } - - /** - * Retrieve the date of the bill. - * @param {Object} bill - The bill object. - * @returns {string} - */ - protected date(bill) { - return bill.billDate; - } - - /** - * Retrieve the formatted date of the bill. - * @param {Object} bill - The bill object. - * @returns {string} - */ - protected dateFormatted(bill) { - return this.formatDate(bill.billDate); - } - - /** - * Retrieve the transcation id of the bill. - * @param {Object} bill - The bill object. - * @returns {number} - */ - protected transactionId(bill) { - return bill.id; - } - - /** - * Retrieve the manual journal transaction type. - * @returns {string} - */ - protected transactionType() { - return 'Bill'; - } - - /** - * Retrieves the manual journal formatted transaction type. - * @returns {string} - */ - protected transsactionTypeFormatted() { - return 'Bill'; - } - - /** - * Retrieves the bill transaction normal (debit or credit). - * @returns {string} - */ - protected transactionNormal() { - return 'credit'; - } - - /** - * Retrieve the match transaction reference id. - * @param bill - * @returns {number} - */ - protected referenceId(bill) { - return bill.id; - } - - /** - * Retrieve the match transaction referenece type. - * @returns {string} - */ - protected referenceType() { - return 'Bill'; - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionCashflowTransformer.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionCashflowTransformer.ts deleted file mode 100644 index cd40951ff..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionCashflowTransformer.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetMatchedTransactionCashflowTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'referenceNo', - 'amount', - 'amountFormatted', - 'transactionNo', - 'date', - 'dateFormatted', - 'transactionId', - 'transactionNo', - 'transactionType', - 'transsactionTypeFormatted', - 'transactionNormal', - 'referenceId', - 'referenceType', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieve the invoice reference number. - * @returns {string} - */ - protected referenceNo(invoice) { - return invoice.referenceNo; - } - - /** - * Retrieve the transaction amount. - * @param transaction - * @returns {number} - */ - protected amount(transaction) { - return transaction.amount; - } - - /** - * Retrieve the transaction formatted amount. - * @param transaction - * @returns {string} - */ - protected amountFormatted(transaction) { - return this.formatNumber(transaction.amount, { - currencyCode: transaction.currencyCode, - money: true, - }); - } - - /** - * Retrieve the date of the invoice. - * @param invoice - * @returns {Date} - */ - protected date(transaction) { - return transaction.date; - } - - /** - * Format the date of the invoice. - * @param invoice - * @returns {string} - */ - protected dateFormatted(transaction) { - return this.formatDate(transaction.date); - } - - /** - * Retrieve the transaction ID of the invoice. - * @param invoice - * @returns {number} - */ - protected transactionId(transaction) { - return transaction.id; - } - - /** - * Retrieve the invoice transaction number. - * @param invoice - * @returns {string} - */ - protected transactionNo(transaction) { - return transaction.transactionNumber; - } - - /** - * Retrieve the invoice transaction type. - * @param invoice - * @returns {String} - */ - protected transactionType(transaction) { - return transaction.transactionType; - } - - /** - * Retrieve the invoice formatted transaction type. - * @param invoice - * @returns {string} - */ - protected transsactionTypeFormatted(transaction) { - return transaction.transactionTypeFormatted; - } - - /** - * Retrieve the cashflow transaction normal (credit or debit). - * @param transaction - * @returns {string} - */ - protected transactionNormal(transaction) { - return transaction.isCashCredit ? 'credit' : 'debit'; - } - - /** - * Retrieves the cashflow transaction reference id. - * @param transaction - * @returns {number} - */ - protected referenceId(transaction) { - return transaction.id; - } - - /** - * Retrieves the cashflow transaction reference type. - * @returns {string} - */ - protected referenceType() { - return 'CashflowTransaction'; - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionExpensesTransformer.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionExpensesTransformer.ts deleted file mode 100644 index a77dcffb0..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionExpensesTransformer.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetMatchedTransactionExpensesTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'referenceNo', - 'amount', - 'amountFormatted', - 'transactionNo', - 'date', - 'dateFormatted', - 'transactionId', - 'transactionNo', - 'transactionType', - 'transsactionTypeFormatted', - 'transactionNormal', - 'referenceType', - 'referenceId', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieves the expense reference number. - * @param expense - * @returns {string} - */ - protected referenceNo(expense) { - return expense.referenceNo; - } - - /** - * Retrieves the expense amount. - * @param expense - * @returns {number} - */ - protected amount(expense) { - return expense.totalAmount; - } - - /** - * Formats the amount of the expense. - * @param expense - * @returns {string} - */ - protected amountFormatted(expense) { - return this.formatNumber(expense.totalAmount, { - currencyCode: expense.currencyCode, - money: true, - }); - } - - /** - * Retrieves the date of the expense. - * @param expense - * @returns {Date} - */ - protected date(expense) { - return expense.paymentDate; - } - - /** - * Formats the date of the expense. - * @param expense - * @returns {string} - */ - protected dateFormatted(expense) { - return this.formatDate(expense.paymentDate); - } - - /** - * Retrieves the transaction ID of the expense. - * @param expense - * @returns {number} - */ - protected transactionId(expense) { - return expense.id; - } - - /** - * Retrieves the expense transaction number. - * @param expense - * @returns {string} - */ - protected transactionNo(expense) { - return expense.expenseNo; - } - - /** - * Retrieves the expense transaction type. - * @param expense - * @returns {String} - */ - protected transactionType() { - return 'Expense'; - } - - /** - * Retrieves the formatted transaction type of the expense. - * @param expense - * @returns {string} - */ - protected transsactionTypeFormatted() { - return 'Expense'; - } - - /** - * Retrieve the expense transaction normal (credit or debit). - * @returns {string} - */ - protected transactionNormal() { - return 'credit'; - } - - /** - * Retrieve the transaction reference type. - * @returns {string} - */ - protected referenceType() { - return 'Expense'; - } - - /** - * Retrieve the transaction reference id. - * @param transaction - * @returns {number} - */ - protected referenceId(transaction) { - return transaction.id; - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionInvoicesTransformer.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionInvoicesTransformer.ts deleted file mode 100644 index dd5de9bfb..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionInvoicesTransformer.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetMatchedTransactionInvoicesTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'referenceNo', - 'amount', - 'amountFormatted', - 'transactionNo', - 'date', - 'dateFormatted', - 'transactionId', - 'transactionNo', - 'transactionType', - 'transsactionTypeFormatted', - 'transactionNormal', - 'referenceType', - 'referenceId' - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieve the invoice reference number. - * @returns {string} - */ - protected referenceNo(invoice) { - return invoice.referenceNo; - } - - /** - * Retrieve the invoice amount. - * @param invoice - * @returns {number} - */ - protected amount(invoice) { - return invoice.dueAmount; - } - /** - * Format the amount of the invoice. - * @param invoice - * @returns {string} - */ - protected amountFormatted(invoice) { - return this.formatNumber(invoice.dueAmount, { - currencyCode: invoice.currencyCode, - money: true, - }); - } - - /** - * Retrieve the date of the invoice. - * @param invoice - * @returns {Date} - */ - protected date(invoice) { - return invoice.invoiceDate; - } - - /** - * Format the date of the invoice. - * @param invoice - * @returns {string} - */ - protected dateFormatted(invoice) { - return this.formatDate(invoice.invoiceDate); - } - - /** - * Retrieve the transaction ID of the invoice. - * @param invoice - * @returns {number} - */ - protected transactionId(invoice) { - return invoice.id; - } - /** - * Retrieve the invoice transaction number. - * @param invoice - * @returns {string} - */ - protected transactionNo(invoice) { - return invoice.invoiceNo; - } - - /** - * Retrieve the invoice transaction type. - * @param invoice - * @returns {String} - */ - protected transactionType(invoice) { - return 'SaleInvoice'; - } - - /** - * Retrieve the invoice formatted transaction type. - * @param invoice - * @returns {string} - */ - protected transsactionTypeFormatted(invoice) { - return 'Sale invoice'; - } - - /** - * Retrieve the transaction normal of invoice (credit or debit). - * @returns {string} - */ - protected transactionNormal() { - return 'debit'; - } - - /** - * Retrieve the transaction reference type. - * @returns {string} - */ protected referenceType() { - return 'SaleInvoice'; - } - - /** - * Retrieve the transaction reference id. - * @param transaction - * @returns {number} - */ - protected referenceId(transaction) { - return transaction.id; - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionManualJournalsTransformer.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionManualJournalsTransformer.ts deleted file mode 100644 index 11ab194a0..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionManualJournalsTransformer.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { sumBy } from 'lodash'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { AccountNormal } from '@/interfaces'; - -export class GetMatchedTransactionManualJournalsTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'referenceNo', - 'amount', - 'amountFormatted', - 'transactionNo', - 'date', - 'dateFormatted', - 'transactionId', - 'transactionNo', - 'transactionType', - 'transsactionTypeFormatted', - 'transactionNormal', - 'referenceType', - 'referenceId', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieves the manual journal reference no. - * @param manualJournal - * @returns {string} - */ - protected referenceNo(manualJournal) { - return manualJournal.referenceNo; - } - - protected total(manualJournal) { - const credit = sumBy(manualJournal?.entries, 'credit'); - const debit = sumBy(manualJournal?.entries, 'debit'); - - return debit - credit; - } - - /** - * Retrieves the manual journal amount. - * @param manualJournal - * @returns {number} - */ - protected amount(manualJournal) { - return Math.abs(this.total(manualJournal)); - } - - /** - * Retrieves the manual journal formatted amount. - * @param manualJournal - * @returns {string} - */ - protected amountFormatted(manualJournal) { - return this.formatNumber(manualJournal.amount, { - currencyCode: manualJournal.currencyCode, - money: true, - }); - } - - /** - * Retreives the manual journal date. - * @param manualJournal - * @returns {Date} - */ - protected date(manualJournal) { - return manualJournal.date; - } - - /** - * Retrieves the manual journal formatted date. - * @param manualJournal - * @returns {string} - */ - protected dateFormatted(manualJournal) { - return this.formatDate(manualJournal.date); - } - - /** - * Retrieve the manual journal transaction id. - * @returns {number} - */ - protected transactionId(manualJournal) { - return manualJournal.id; - } - - /** - * Retrieve the manual journal transaction number. - * @param manualJournal - */ - protected transactionNo(manualJournal) { - return manualJournal.journalNumber; - } - - /** - * Retrieve the manual journal transaction type. - * @returns {string} - */ - protected transactionType() { - return 'ManualJournal'; - } - - /** - * Retrieves the manual journal formatted transaction type. - * @returns {string} - */ - protected transsactionTypeFormatted() { - return 'Manual Journal'; - } - - /** - * Retrieve the manual journal transaction normal (credit or debit). - * @returns {string} - */ - protected transactionNormal(transaction) { - const amount = this.total(transaction); - - return amount >= 0 ? AccountNormal.DEBIT : AccountNormal.CREDIT; - } - - /** - * Retrieve the manual journal reference type. - * @returns {string} - */ - protected referenceType() { - return 'ManualJournal'; - } - - /** - * Retrieves the manual journal reference id. - * @param transaction - * @returns {number} - */ - protected referenceId(transaction) { - return transaction.id; - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactions.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactions.ts deleted file mode 100644 index cf46790a3..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactions.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import moment from 'moment'; -import { first, sumBy } from 'lodash'; -import { PromisePool } from '@supercharge/promise-pool'; -import { GetMatchedTransactionsFilter, MatchedTransactionsPOJO } from './types'; -import { GetMatchedTransactionsByExpenses } from './GetMatchedTransactionsByExpenses'; -import { GetMatchedTransactionsByBills } from './GetMatchedTransactionsByBills'; -import { GetMatchedTransactionsByManualJournals } from './GetMatchedTransactionsByManualJournals'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { sortClosestMatchTransactions } from './_utils'; -import { GetMatchedTransactionsByCashflow } from './GetMatchedTransactionsByCashflow'; -import { GetMatchedTransactionsByInvoices } from './GetMatchedTransactionsByInvoices'; - -@Service() -export class GetMatchedTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private getMatchedInvoicesService: GetMatchedTransactionsByInvoices; - - @Inject() - private getMatchedBillsService: GetMatchedTransactionsByBills; - - @Inject() - private getMatchedManualJournalService: GetMatchedTransactionsByManualJournals; - - @Inject() - private getMatchedExpensesService: GetMatchedTransactionsByExpenses; - - @Inject() - private getMatchedCashflowService: GetMatchedTransactionsByCashflow; - - /** - * Registered matched transactions types. - */ - get registered() { - return [ - { type: 'SaleInvoice', service: this.getMatchedInvoicesService }, - { type: 'Bill', service: this.getMatchedBillsService }, - { type: 'Expense', service: this.getMatchedExpensesService }, - { type: 'ManualJournal', service: this.getMatchedManualJournalService }, - { type: 'Cashflow', service: this.getMatchedCashflowService }, - ]; - } - - /** - * Retrieves the matched transactions. - * @param {number} tenantId - - * @param {Array} uncategorizedTransactionIds - Uncategorized transactions ids. - * @param {GetMatchedTransactionsFilter} filter - - * @returns {Promise} - */ - public async getMatchedTransactions( - tenantId: number, - uncategorizedTransactionIds: Array, - filter: GetMatchedTransactionsFilter - ): Promise { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query() - .whereIn('id', uncategorizedTransactionIds) - .throwIfNotFound(); - - const totalPending = sumBy(uncategorizedTransactions, 'amount'); - - const filtered = filter.transactionType - ? this.registered.filter((item) => item.type === filter.transactionType) - : this.registered; - - const matchedTransactions = await PromisePool.withConcurrency(2) - .for(filtered) - .process(async ({ type, service }) => { - return service.getMatchedTransactions(tenantId, filter); - }); - const { perfectMatches, possibleMatches } = this.groupMatchedResults( - uncategorizedTransactions, - matchedTransactions - ); - return { - perfectMatches, - possibleMatches, - totalPending, - }; - } - - /** - * Groups the given results for getting perfect and possible matches - * based on the given uncategorized transaction. - * @param uncategorizedTransaction - * @param matchedTransactions - * @returns {MatchedTransactionsPOJO} - */ - private groupMatchedResults( - uncategorizedTransactions: Array, - matchedTransactions - ): MatchedTransactionsPOJO { - const results = R.compose(R.flatten)(matchedTransactions?.results); - - const firstUncategorized = first(uncategorizedTransactions); - const amount = sumBy(uncategorizedTransactions, 'amount'); - const date = firstUncategorized.date; - - // Sort the results based on amount, date, and transaction type - const closestResullts = sortClosestMatchTransactions(amount, date, results); - const perfectMatches = R.filter( - (match) => - match.amount === amount && moment(match.date).isSame(date, 'day'), - closestResullts - ); - const possibleMatches = R.difference(closestResullts, perfectMatches); - - return { perfectMatches, possibleMatches }; - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByBills.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByBills.ts deleted file mode 100644 index b9b85cb8c..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByBills.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import { Knex } from 'knex'; -import { first } from 'lodash'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetMatchedTransactionBillsTransformer } from './GetMatchedTransactionBillsTransformer'; -import { - GetMatchedTransactionsFilter, - IMatchTransactionDTO, - MatchedTransactionPOJO, -} from './types'; -import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; -import { CreateBillPayment } from '@/services/Purchases/BillPayments/CreateBillPayment'; -import { IBillPaymentDTO } from '@/interfaces'; - -@Service() -export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType { - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private createPaymentMadeService: CreateBillPayment; - - /** - * Retrieves the matched transactions. - * @param {number} tenantId - - * @param {GetMatchedTransactionsFilter} filter - - */ - public async getMatchedTransactions( - tenantId: number, - filter: GetMatchedTransactionsFilter - ) { - const { Bill, MatchedBankTransaction } = this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - // Initialize the models metadata. - await initialize(knex, [Bill, MatchedBankTransaction]); - - // Retrieves the bill matches. - const bills = await Bill.query().onBuild((q) => { - q.withGraphJoined('matchedBankTransaction'); - q.whereNull('matchedBankTransaction.id'); - q.modify('published'); - - if (filter.fromDate) { - q.where('billDate', '>=', filter.fromDate); - } - if (filter.toDate) { - q.where('billDate', '<=', filter.toDate); - } - q.orderBy('billDate', 'DESC'); - }); - - return this.transformer.transform( - tenantId, - bills, - new GetMatchedTransactionBillsTransformer() - ); - } - - /** - * Retrieves the given bill matched transaction. - * @param {number} tenantId - * @param {number} transactionId - * @returns {Promise} - */ - public async getMatchedTransaction( - tenantId: number, - transactionId: number - ): Promise { - const { Bill } = this.tenancy.models(tenantId); - - const bill = await Bill.query().findById(transactionId).throwIfNotFound(); - - return this.transformer.transform( - tenantId, - bill, - new GetMatchedTransactionBillsTransformer() - ); - } - - /** - * Creates the common matched transaction. - * @param {number} tenantId - * @param {Array} uncategorizedTransactionIds - * @param {IMatchTransactionDTO} matchTransactionDTO - * @param {Knex.Transaction} trx - */ - public async createMatchedTransaction( - tenantId: number, - uncategorizedTransactionIds: Array, - matchTransactionDTO: IMatchTransactionDTO, - trx?: Knex.Transaction - ): Promise { - await super.createMatchedTransaction( - tenantId, - uncategorizedTransactionIds, - matchTransactionDTO, - trx - ); - const { Bill, UncategorizedCashflowTransaction, MatchedBankTransaction } = - this.tenancy.models(tenantId); - - const uncategorizedTransactionId = first(uncategorizedTransactionIds); - const uncategorizedTransaction = - await UncategorizedCashflowTransaction.query(trx) - .findById(uncategorizedTransactionId) - .throwIfNotFound(); - - const bill = await Bill.query(trx) - .findById(matchTransactionDTO.referenceId) - .throwIfNotFound(); - - const createPaymentMadeDTO: IBillPaymentDTO = { - vendorId: bill.vendorId, - paymentAccountId: uncategorizedTransaction.accountId, - paymentDate: uncategorizedTransaction.date, - exchangeRate: 1, - entries: [ - { - paymentAmount: bill.dueAmount, - billId: bill.id, - }, - ], - branchId: bill.branchId, - }; - // Create a new bill payment associated to the matched bill. - const billPayment = await this.createPaymentMadeService.createBillPayment( - tenantId, - createPaymentMadeDTO, - trx - ); - // Link the create bill payment with matched transaction. - await super.createMatchedTransaction(tenantId, uncategorizedTransactionIds, { - referenceType: 'BillPayment', - referenceId: billPayment.id, - }, trx); - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByCashflow.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByCashflow.ts deleted file mode 100644 index ef8887ae7..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByCashflow.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; -import { GetMatchedTransactionCashflowTransformer } from './GetMatchedTransactionCashflowTransformer'; -import { GetMatchedTransactionsFilter } from './types'; - -@Service() -export class GetMatchedTransactionsByCashflow extends GetMatchedTransactionsByType { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the matched transactions of cash flow. - * @param {number} tenantId - * @param {GetMatchedTransactionsFilter} filter - * @returns - */ - async getMatchedTransactions( - tenantId: number, - filter: Omit - ) { - const { CashflowTransaction, MatchedBankTransaction } = - this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - // Initialize the ORM models metadata. - await initialize(knex, [CashflowTransaction, MatchedBankTransaction]); - - const transactions = await CashflowTransaction.query().onBuild((q) => { - // Not matched to bank transaction. - q.withGraphJoined('matchedBankTransaction'); - q.whereNull('matchedBankTransaction.id'); - - // Not categorized. - q.modify('notCategorized'); - - // Published. - q.modify('published'); - - if (filter.fromDate) { - q.where('date', '>=', filter.fromDate); - } - if (filter.toDate) { - q.where('date', '<=', filter.toDate); - } - q.orderBy('date', 'DESC'); - }); - - return this.transformer.transform( - tenantId, - transactions, - new GetMatchedTransactionCashflowTransformer() - ); - } - - /** - * Retrieves the matched transaction of cash flow. - * @param {number} tenantId - * @param {number} transactionId - * @returns - */ - async getMatchedTransaction(tenantId: number, transactionId: number) { - const { CashflowTransaction, MatchedBankTransaction } = - this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - // Initialize the ORM models metadata. - await initialize(knex, [CashflowTransaction, MatchedBankTransaction]); - - const transactions = await CashflowTransaction.query() - .findById(transactionId) - .withGraphJoined('matchedBankTransaction') - .whereNull('matchedBankTransaction.id') - .modify('notCategorized') - .modify('published') - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - transactions, - new GetMatchedTransactionCashflowTransformer() - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByExpenses.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByExpenses.ts deleted file mode 100644 index 39db88cf1..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByExpenses.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import { GetMatchedTransactionsFilter, MatchedTransactionPOJO } from './types'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; -import { GetMatchedTransactionExpensesTransformer } from './GetMatchedTransactionExpensesTransformer'; - -@Service() -export class GetMatchedTransactionsByExpenses extends GetMatchedTransactionsByType { - @Inject() - protected tenancy: HasTenancyService; - - @Inject() - protected transformer: TransformerInjectable; - - /** - * Retrieves the matched transactions of expenses. - * @param {number} tenantId - * @param {GetMatchedTransactionsFilter} filter - * @returns - */ - async getMatchedTransactions( - tenantId: number, - filter: GetMatchedTransactionsFilter - ) { - const { Expense, MatchedBankTransaction } = this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - // Initialize the models metadata. - await initialize(knex, [Expense, MatchedBankTransaction]); - - // Retrieve the expense matches. - const expenses = await Expense.query().onBuild((query) => { - // Filter out the not matched to bank transactions. - query.withGraphJoined('matchedBankTransaction'); - query.whereNull('matchedBankTransaction.id'); - - // Filter the published onyl - query.modify('filterByPublished'); - - if (filter.fromDate) { - query.where('paymentDate', '>=', filter.fromDate); - } - if (filter.toDate) { - query.where('paymentDate', '<=', filter.toDate); - } - if (filter.minAmount) { - query.where('totalAmount', '>=', filter.minAmount); - } - if (filter.maxAmount) { - query.where('totalAmount', '<=', filter.maxAmount); - } - query.orderBy('paymentDate', 'DESC'); - }); - return this.transformer.transform( - tenantId, - expenses, - new GetMatchedTransactionExpensesTransformer() - ); - } - - /** - * Retrieves the given matched expense transaction. - * @param {number} tenantId - * @param {number} transactionId - * @returns {GetMatchedTransactionExpensesTransformer-} - */ - public async getMatchedTransaction( - tenantId: number, - transactionId: number - ): Promise { - const { Expense } = this.tenancy.models(tenantId); - - const expense = await Expense.query() - .findById(transactionId) - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - expense, - new GetMatchedTransactionExpensesTransformer() - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByInvoices.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByInvoices.ts deleted file mode 100644 index 1d7baee7a..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByInvoices.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import { Knex } from 'knex'; -import { first } from 'lodash'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetMatchedTransactionInvoicesTransformer } from './GetMatchedTransactionInvoicesTransformer'; -import { - GetMatchedTransactionsFilter, - IMatchTransactionDTO, - MatchedTransactionPOJO, - MatchedTransactionsPOJO, -} from './types'; -import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; -import { CreatePaymentReceived } from '@/services/Sales/PaymentReceived/CreatePaymentReceived'; -import { IPaymentReceivedCreateDTO } from '@/interfaces'; - -@Service() -export class GetMatchedTransactionsByInvoices extends GetMatchedTransactionsByType { - @Inject() - protected transformer: TransformerInjectable; - - @Inject() - protected createPaymentReceivedService: CreatePaymentReceived; - - /** - * Retrieves the matched transactions. - * @param {number} tenantId - - * @param {GetMatchedTransactionsFilter} filter - - * @returns {Promise} - */ - public async getMatchedTransactions( - tenantId: number, - filter: GetMatchedTransactionsFilter - ): Promise { - const { SaleInvoice, MatchedBankTransaction } = - this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - // Initialize the models metadata. - await initialize(knex, [SaleInvoice, MatchedBankTransaction]); - - // Retrieve the invoices that not matched, unpaid. - const invoices = await SaleInvoice.query().onBuild((q) => { - q.withGraphJoined('matchedBankTransaction'); - q.whereNull('matchedBankTransaction.id'); - q.modify('unpaid'); - q.modify('published'); - - if (filter.fromDate) { - q.where('invoiceDate', '>=', filter.fromDate); - } - if (filter.toDate) { - q.where('invoiceDate', '<=', filter.toDate); - } - q.orderBy('invoiceDate', 'DESC'); - }); - - return this.transformer.transform( - tenantId, - invoices, - new GetMatchedTransactionInvoicesTransformer() - ); - } - - /** - * Retrieves the matched transaction. - * @param {number} tenantId - * @param {number} transactionId - * @returns {Promise} - */ - public async getMatchedTransaction( - tenantId: number, - transactionId: number - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const invoice = await SaleInvoice.query().findById(transactionId); - - return this.transformer.transform( - tenantId, - invoice, - new GetMatchedTransactionInvoicesTransformer() - ); - } - - /** - * Creates the common matched transaction. - * @param {number} tenantId - * @param {Array} uncategorizedTransactionIds - * @param {IMatchTransactionDTO} matchTransactionDTO - * @param {Knex.Transaction} trx - */ - public async createMatchedTransaction( - tenantId: number, - uncategorizedTransactionIds: Array, - matchTransactionDTO: IMatchTransactionDTO, - trx?: Knex.Transaction - ) { - await super.createMatchedTransaction( - tenantId, - uncategorizedTransactionIds, - matchTransactionDTO, - trx - ); - const { SaleInvoice, UncategorizedCashflowTransaction, MatchedBankTransaction } = - this.tenancy.models(tenantId); - - const uncategorizedTransactionId = first(uncategorizedTransactionIds); - const uncategorizedTransaction = - await UncategorizedCashflowTransaction.query(trx) - .findById(uncategorizedTransactionId) - .throwIfNotFound(); - - const invoice = await SaleInvoice.query(trx) - .findById(matchTransactionDTO.referenceId) - .throwIfNotFound(); - - const createPaymentReceivedDTO: IPaymentReceivedCreateDTO = { - customerId: invoice.customerId, - paymentDate: uncategorizedTransaction.date, - amount: invoice.dueAmount, - depositAccountId: uncategorizedTransaction.accountId, - entries: [ - { - index: 1, - invoiceId: invoice.id, - paymentAmount: invoice.dueAmount, - }, - ], - branchId: invoice.branchId, - }; - // Create a payment received associated to the matched invoice. - const paymentReceived = await this.createPaymentReceivedService.createPaymentReceived( - tenantId, - createPaymentReceivedDTO, - {}, - trx - ); - // Link the create payment received with matched invoice transaction. - await super.createMatchedTransaction(tenantId, uncategorizedTransactionIds, { - referenceType: 'PaymentReceive', - referenceId: paymentReceived.id, - }, trx) - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByManualJournals.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByManualJournals.ts deleted file mode 100644 index 42dae0988..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByManualJournals.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetMatchedTransactionManualJournalsTransformer } from './GetMatchedTransactionManualJournalsTransformer'; -import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; -import { GetMatchedTransactionsFilter } from './types'; - -@Service() -export class GetMatchedTransactionsByManualJournals extends GetMatchedTransactionsByType { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the matched transactions of manual journals. - * @param {number} tenantId - * @param {GetMatchedTransactionsFilter} filter - * @returns - */ - async getMatchedTransactions( - tenantId: number, - filter: Omit - ) { - const { ManualJournal, ManualJournalEntry, MatchedBankTransaction } = - this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - await initialize(knex, [ - ManualJournal, - ManualJournalEntry, - MatchedBankTransaction, - ]); - const accountId = 1000; - - const manualJournals = await ManualJournal.query().onBuild((query) => { - query.withGraphJoined('matchedBankTransaction'); - query.whereNull('matchedBankTransaction.id'); - - query.withGraphJoined('entries'); - query.where('entries.accountId', accountId); - - query.modify('filterByPublished'); - - if (filter.fromDate) { - query.where('date', '>=', filter.fromDate); - } - if (filter.toDate) { - query.where('date', '<=', filter.toDate); - } - if (filter.minAmount) { - query.where('amount', '>=', filter.minAmount); - } - if (filter.maxAmount) { - query.where('amount', '<=', filter.maxAmount); - } - }); - return this.transformer.transform( - tenantId, - manualJournals, - new GetMatchedTransactionManualJournalsTransformer() - ); - } - - /** - * Retrieves the matched transaction of manual journals. - * @param {number} tenantId - * @param {number} transactionId - * @returns - */ - async getMatchedTransaction(tenantId: number, transactionId: number) { - const { ManualJournal } = this.tenancy.models(tenantId); - - const manualJournal = await ManualJournal.query() - .findById(transactionId) - .whereNotExists(ManualJournal.relatedQuery('matchedBankTransaction')) - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - manualJournal, - new GetMatchedTransactionManualJournalsTransformer() - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByType.ts b/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByType.ts deleted file mode 100644 index 5d39c0740..000000000 --- a/packages/server/src/services/Banking/Matching/GetMatchedTransactionsByType.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - GetMatchedTransactionsFilter, - IMatchTransactionDTO, - MatchedTransactionPOJO, - MatchedTransactionsPOJO, -} from './types'; -import { Inject, Service } from 'typedi'; -import PromisePool from '@supercharge/promise-pool'; - -export abstract class GetMatchedTransactionsByType { - @Inject() - protected tenancy: HasTenancyService; - - /** - * Retrieves the matched transactions. - * @param {number} tenantId - - * @param {GetMatchedTransactionsFilter} filter - - * @returns {Promise} - */ - public async getMatchedTransactions( - tenantId: number, - filter: GetMatchedTransactionsFilter - ): Promise { - throw new Error( - 'The `getMatchedTransactions` method is not defined for the transaction type.' - ); - } - - /** - * Retrieves the matched transaction details. - * @param {number} tenantId - - * @param {number} transactionId - - * @returns {Promise} - */ - public async getMatchedTransaction( - tenantId: number, - transactionId: number - ): Promise { - throw new Error( - 'The `getMatchedTransaction` method is not defined for the transaction type.' - ); - } - - /** - * Creates the common matched transaction. - * @param {number} tenantId - * @param {Array} uncategorizedTransactionIds - * @param {IMatchTransactionDTO} matchTransactionDTO - * @param {Knex.Transaction} trx - */ - public async createMatchedTransaction( - tenantId: number, - uncategorizedTransactionIds: Array, - matchTransactionDTO: IMatchTransactionDTO, - trx?: Knex.Transaction - ) { - const { MatchedBankTransaction } = this.tenancy.models(tenantId); - - await PromisePool.withConcurrency(2) - .for(uncategorizedTransactionIds) - .process(async (uncategorizedTransactionId) => { - await MatchedBankTransaction.query(trx).insert({ - uncategorizedTransactionId, - referenceType: matchTransactionDTO.referenceType, - referenceId: matchTransactionDTO.referenceId, - }); - }); - } -} diff --git a/packages/server/src/services/Banking/Matching/MatchBankTransactionsApplication.ts b/packages/server/src/services/Banking/Matching/MatchBankTransactionsApplication.ts deleted file mode 100644 index dd60c166c..000000000 --- a/packages/server/src/services/Banking/Matching/MatchBankTransactionsApplication.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { GetMatchedTransactions } from './GetMatchedTransactions'; -import { MatchBankTransactions } from './MatchTransactions'; -import { UnmatchMatchedBankTransaction } from './UnmatchMatchedTransaction'; -import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types'; - -@Service() -export class MatchBankTransactionsApplication { - @Inject() - private getMatchedTransactionsService: GetMatchedTransactions; - - @Inject() - private matchTransactionService: MatchBankTransactions; - - @Inject() - private unmatchMatchedTransactionService: UnmatchMatchedBankTransaction; - - /** - * Retrieves the matched transactions. - * @param {number} tenantId - - * @param {GetMatchedTransactionsFilter} filter - - * @returns - */ - public getMatchedTransactions( - tenantId: number, - uncategorizedTransactionsIds: Array, - filter: GetMatchedTransactionsFilter - ) { - return this.getMatchedTransactionsService.getMatchedTransactions( - tenantId, - uncategorizedTransactionsIds, - filter - ); - } - - /** - * Matches the given uncategorized transaction with the given system transaction. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - * @param {IMatchTransactionDTO} matchTransactionsDTO - * @returns {Promise} - */ - public matchTransaction( - tenantId: number, - uncategorizedTransactionId: number | Array, - matchedTransactions: Array - ): Promise { - return this.matchTransactionService.matchTransaction( - tenantId, - uncategorizedTransactionId, - matchedTransactions - ); - } - - /** - * Unmatch the given matched transaction. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - * @returns {Promise} - */ - public unmatchMatchedTransaction( - tenantId: number, - uncategorizedTransactionId: number - ) { - return this.unmatchMatchedTransactionService.unmatchMatchedTransaction( - tenantId, - uncategorizedTransactionId - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/MatchTransactions.ts b/packages/server/src/services/Banking/Matching/MatchTransactions.ts deleted file mode 100644 index 5a28dd0b1..000000000 --- a/packages/server/src/services/Banking/Matching/MatchTransactions.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { castArray } from 'lodash'; -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { PromisePool } from '@supercharge/promise-pool'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { - ERRORS, - IBankTransactionMatchedEventPayload, - IBankTransactionMatchingEventPayload, - IMatchTransactionDTO, -} from './types'; -import { MatchTransactionsTypes } from './MatchTransactionsTypes'; -import { ServiceError } from '@/exceptions'; -import { - sumMatchTranasctions, - sumUncategorizedTransactions, - validateUncategorizedTransactionsExcluded, - validateUncategorizedTransactionsNotMatched, -} from './_utils'; - -@Service() -export class MatchBankTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private matchedBankTransactions: MatchTransactionsTypes; - - /** - * Validates the match bank transactions DTO. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - * @param {IMatchTransactionsDTO} matchTransactionsDTO - * @returns {Promise} - */ - async validate( - tenantId: number, - uncategorizedTransactionId: number | Array, - matchedTransactions: Array - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - const uncategorizedTransactionIds = castArray(uncategorizedTransactionId); - - // Validates the uncategorized transaction existance. - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query() - .whereIn('id', uncategorizedTransactionIds) - .withGraphFetched('matchedBankTransactions') - .throwIfNotFound(); - - // Validates the uncategorized transaction is not already matched. - validateUncategorizedTransactionsNotMatched(uncategorizedTransactions); - - // Validate the uncategorized transaction is not excluded. - validateUncategorizedTransactionsExcluded(uncategorizedTransactions); - - // Validates the given matched transaction. - const validateMatchedTransaction = async (matchedTransaction) => { - const getMatchedTransactionsService = - this.matchedBankTransactions.registry.get( - matchedTransaction.referenceType - ); - if (!getMatchedTransactionsService) { - throw new ServiceError( - ERRORS.RESOURCE_TYPE_MATCHING_TRANSACTION_INVALID - ); - } - const foundMatchedTransaction = - await getMatchedTransactionsService.getMatchedTransaction( - tenantId, - matchedTransaction.referenceId - ); - if (!foundMatchedTransaction) { - throw new ServiceError(ERRORS.RESOURCE_ID_MATCHING_TRANSACTION_INVALID); - } - return foundMatchedTransaction; - }; - // Matches the given transactions under promise pool concurrency controlling. - const validatationResult = await PromisePool.withConcurrency(10) - .for(matchedTransactions) - .process(validateMatchedTransaction); - - if (validatationResult.errors?.length > 0) { - const error = validatationResult.errors.map((er) => er.raw)[0]; - throw new ServiceError(error); - } - // Calculate the total given matching transactions. - const totalMatchedTranasctions = sumMatchTranasctions( - validatationResult.results - ); - const totalUncategorizedTransactions = sumUncategorizedTransactions( - uncategorizedTransactions - ); - // Validates the total given matching transcations whether is not equal - // uncategorized transaction amount. - if (totalUncategorizedTransactions !== totalMatchedTranasctions) { - throw new ServiceError(ERRORS.TOTAL_MATCHING_TRANSACTIONS_INVALID); - } - } - - /** - * Matches the given uncategorized transaction to the given references. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - * @returns {Promise} - */ - public async matchTransaction( - tenantId: number, - uncategorizedTransactionId: number | Array, - matchedTransactions: Array - ): Promise { - const uncategorizedTransactionIds = castArray(uncategorizedTransactionId); - - // Validates the given matching transactions DTO. - await this.validate( - tenantId, - uncategorizedTransactionIds, - matchedTransactions - ); - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers the event `onBankTransactionMatching`. - await this.eventPublisher.emitAsync(events.bankMatch.onMatching, { - tenantId, - uncategorizedTransactionIds, - matchedTransactions, - trx, - } as IBankTransactionMatchingEventPayload); - - // Matches the given transactions under promise pool concurrency controlling. - await PromisePool.withConcurrency(10) - .for(matchedTransactions) - .process(async (matchedTransaction) => { - const getMatchedTransactionsService = - this.matchedBankTransactions.registry.get( - matchedTransaction.referenceType - ); - await getMatchedTransactionsService.createMatchedTransaction( - tenantId, - uncategorizedTransactionIds, - matchedTransaction, - trx - ); - }); - // Triggers the event `onBankTransactionMatched`. - await this.eventPublisher.emitAsync(events.bankMatch.onMatched, { - tenantId, - uncategorizedTransactionIds, - matchedTransactions, - trx, - } as IBankTransactionMatchedEventPayload); - }); - } -} diff --git a/packages/server/src/services/Banking/Matching/MatchTransactionsTypes.ts b/packages/server/src/services/Banking/Matching/MatchTransactionsTypes.ts deleted file mode 100644 index d90db1a36..000000000 --- a/packages/server/src/services/Banking/Matching/MatchTransactionsTypes.ts +++ /dev/null @@ -1,63 +0,0 @@ -import Container, { Service } from 'typedi'; -import { GetMatchedTransactionsByExpenses } from './GetMatchedTransactionsByExpenses'; -import { GetMatchedTransactionsByBills } from './GetMatchedTransactionsByBills'; -import { GetMatchedTransactionsByManualJournals } from './GetMatchedTransactionsByManualJournals'; -import { MatchTransactionsTypesRegistry } from './MatchTransactionsTypesRegistry'; -import { GetMatchedTransactionsByInvoices } from './GetMatchedTransactionsByInvoices'; -import { GetMatchedTransactionCashflowTransformer } from './GetMatchedTransactionCashflowTransformer'; -import { GetMatchedTransactionsByCashflow } from './GetMatchedTransactionsByCashflow'; - -@Service() -export class MatchTransactionsTypes { - private static registry: MatchTransactionsTypesRegistry; - - /** - * Consttuctor method. - */ - constructor() { - this.boot(); - } - - get registered() { - return [ - { type: 'SaleInvoice', service: GetMatchedTransactionsByInvoices }, - { type: 'Bill', service: GetMatchedTransactionsByBills }, - { type: 'Expense', service: GetMatchedTransactionsByExpenses }, - { - type: 'ManualJournal', - service: GetMatchedTransactionsByManualJournals, - }, - { - type: 'CashflowTransaction', - service: GetMatchedTransactionsByCashflow, - }, - ]; - } - - /** - * Importable instances. - */ - private types = []; - - /** - * - */ - public get registry() { - return MatchTransactionsTypes.registry; - } - - /** - * Boots all the registered importables. - */ - public boot() { - if (!MatchTransactionsTypes.registry) { - const instance = MatchTransactionsTypesRegistry.getInstance(); - - this.registered.forEach((registered) => { - const serviceInstanace = Container.get(registered.service); - instance.register(registered.type, serviceInstanace); - }); - MatchTransactionsTypes.registry = instance; - } - } -} diff --git a/packages/server/src/services/Banking/Matching/MatchTransactionsTypesRegistry.ts b/packages/server/src/services/Banking/Matching/MatchTransactionsTypesRegistry.ts deleted file mode 100644 index a64ff0d6b..000000000 --- a/packages/server/src/services/Banking/Matching/MatchTransactionsTypesRegistry.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { camelCase, upperFirst } from 'lodash'; -import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; - -export class MatchTransactionsTypesRegistry { - private static instance: MatchTransactionsTypesRegistry; - private importables: Record; - - constructor() { - this.importables = {}; - } - - /** - * Gets singleton instance of registry. - * @returns {MatchTransactionsTypesRegistry} - */ - public static getInstance(): MatchTransactionsTypesRegistry { - if (!MatchTransactionsTypesRegistry.instance) { - MatchTransactionsTypesRegistry.instance = - new MatchTransactionsTypesRegistry(); - } - return MatchTransactionsTypesRegistry.instance; - } - - /** - * Registers the given importable service. - * @param {string} resource - * @param {GetMatchedTransactionsByType} importable - */ - public register( - resource: string, - importable: GetMatchedTransactionsByType - ): void { - const _resource = this.sanitizeResourceName(resource); - this.importables[_resource] = importable; - } - - /** - * Retrieves the importable service instance of the given resource name. - * @param {string} name - * @returns {GetMatchedTransactionsByType} - */ - public get(name: string): GetMatchedTransactionsByType { - const _name = this.sanitizeResourceName(name); - return this.importables[_name]; - } - - private sanitizeResourceName(resource: string) { - return upperFirst(camelCase(resource)); - } -} diff --git a/packages/server/src/services/Banking/Matching/UnmatchMatchedTransaction.ts b/packages/server/src/services/Banking/Matching/UnmatchMatchedTransaction.ts deleted file mode 100644 index e51fc7cbd..000000000 --- a/packages/server/src/services/Banking/Matching/UnmatchMatchedTransaction.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { IBankTransactionUnmatchingEventPayload } from './types'; - -@Service() -export class UnmatchMatchedBankTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Unmatch the matched the given uncategorized bank transaction. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - * @returns {Promise} - */ - public unmatchMatchedTransaction( - tenantId: number, - uncategorizedTransactionId: number - ): Promise { - const { MatchedBankTransaction } = this.tenancy.models(tenantId); - - return this.uow.withTransaction(tenantId, async (trx) => { - await this.eventPublisher.emitAsync(events.bankMatch.onUnmatching, { - tenantId, - uncategorizedTransactionId, - trx, - } as IBankTransactionUnmatchingEventPayload); - - await MatchedBankTransaction.query(trx) - .where('uncategorizedTransactionId', uncategorizedTransactionId) - .delete(); - - await this.eventPublisher.emitAsync(events.bankMatch.onUnmatched, { - tenantId, - uncategorizedTransactionId, - trx, - } as IBankTransactionUnmatchingEventPayload); - }); - } -} diff --git a/packages/server/src/services/Banking/Matching/ValidateTransactionsMatched.ts b/packages/server/src/services/Banking/Matching/ValidateTransactionsMatched.ts deleted file mode 100644 index 5938c9820..000000000 --- a/packages/server/src/services/Banking/Matching/ValidateTransactionsMatched.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './types'; - -@Service() -export class ValidateTransactionMatched { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validate the given transaction whether is matched with bank transactions. - * @param {number} tenantId - * @param {string} referenceType - Transaction reference type. - * @param {number} referenceId - Transaction reference id. - * @returns {Promise} - */ - public async validateTransactionNoMatchLinking( - tenantId: number, - referenceType: string, - referenceId: number, - trx?: Knex.Transaction - ) { - const { MatchedBankTransaction } = this.tenancy.models(tenantId); - - const foundMatchedTransaction = - await MatchedBankTransaction.query(trx).findOne({ - referenceType, - referenceId, - }); - if (foundMatchedTransaction) { - throw new ServiceError(ERRORS.CANNOT_DELETE_TRANSACTION_MATCHED); - } - } -} diff --git a/packages/server/src/services/Banking/Matching/_utils.ts b/packages/server/src/services/Banking/Matching/_utils.ts deleted file mode 100644 index 46a31729c..000000000 --- a/packages/server/src/services/Banking/Matching/_utils.ts +++ /dev/null @@ -1,65 +0,0 @@ -import moment from 'moment'; -import * as R from 'ramda'; -import UncategorizedCashflowTransaction from '@/models/UncategorizedCashflowTransaction'; -import { ERRORS, MatchedTransactionPOJO } from './types'; -import { isEmpty, sumBy } from 'lodash'; -import { ServiceError } from '@/exceptions'; - -export const sortClosestMatchTransactions = ( - amount: number, - date: Date, - matches: MatchedTransactionPOJO[] -) => { - return R.sortWith([ - // Sort by amount difference (closest to uncategorized transaction amount first) - R.ascend((match: MatchedTransactionPOJO) => - Math.abs(match.amount - amount) - ), - // Sort by date difference (closest to uncategorized transaction date first) - R.ascend((match: MatchedTransactionPOJO) => - Math.abs(moment(match.date).diff(moment(date), 'days')) - ), - ])(matches); -}; - -export const sumMatchTranasctions = (transactions: Array) => { - return transactions.reduce( - (total, item) => - total + - (item.transactionNormal === 'debit' ? 1 : -1) * parseFloat(item.amount), - 0 - ); -}; - -export const sumUncategorizedTransactions = ( - uncategorizedTransactions: Array -) => { - return sumBy(uncategorizedTransactions, 'amount'); -}; - -export const validateUncategorizedTransactionsNotMatched = ( - uncategorizedTransactions: any -) => { - const matchedTransactions = uncategorizedTransactions.filter( - (trans) => !isEmpty(trans.matchedBankTransactions) - ); - // - if (matchedTransactions.length > 0) { - throw new ServiceError(ERRORS.TRANSACTION_ALREADY_MATCHED, '', { - matchedTransactionsIds: matchedTransactions?.map((m) => m.id), - }); - } -}; - -export const validateUncategorizedTransactionsExcluded = ( - uncategorizedTransactions: any -) => { - const excludedTransactions = uncategorizedTransactions.filter( - (trans) => trans.excluded - ); - if (excludedTransactions.length > 0) { - throw new ServiceError(ERRORS.CANNOT_MATCH_EXCLUDED_TRANSACTION, '', { - excludedTransactionsIds: excludedTransactions.map((e) => e.id), - }); - } -}; diff --git a/packages/server/src/services/Banking/Matching/events/DecrementUncategorizedTransactionsOnMatch.ts b/packages/server/src/services/Banking/Matching/events/DecrementUncategorizedTransactionsOnMatch.ts deleted file mode 100644 index 5e37d71d1..000000000 --- a/packages/server/src/services/Banking/Matching/events/DecrementUncategorizedTransactionsOnMatch.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IBankTransactionMatchedEventPayload, - IBankTransactionUnmatchedEventPayload, -} from '../types'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import PromisePool from '@supercharge/promise-pool'; - -@Service() -export class DecrementUncategorizedTransactionOnMatching { - @Inject() - private tenancy: HasTenancyService; - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.bankMatch.onMatched, - this.decrementUnCategorizedTransactionsOnMatching.bind(this) - ); - bus.subscribe( - events.bankMatch.onUnmatched, - this.incrementUnCategorizedTransactionsOnUnmatching.bind(this) - ); - } - - /** - * Validates the cashflow transaction whether matched with bank transaction on deleting. - * @param {IManualJournalDeletingPayload} - */ - public async decrementUnCategorizedTransactionsOnMatching({ - tenantId, - uncategorizedTransactionIds, - trx, - }: IBankTransactionMatchedEventPayload) { - const { UncategorizedCashflowTransaction, Account } = - this.tenancy.models(tenantId); - - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query().whereIn( - 'id', - uncategorizedTransactionIds - ); - await PromisePool.withConcurrency(1) - .for(uncategorizedTransactions) - .process(async (transaction) => { - await Account.query(trx) - .findById(transaction.accountId) - .decrement('uncategorizedTransactions', 1); - }); - } - - /** - * Validates the cashflow transaction whether matched with bank transaction on deleting. - * @param {IManualJournalDeletingPayload} - */ - public async incrementUnCategorizedTransactionsOnUnmatching({ - tenantId, - uncategorizedTransactionId, - trx, - }: IBankTransactionUnmatchedEventPayload) { - const { UncategorizedCashflowTransaction, Account } = - this.tenancy.models(tenantId); - - const transaction = await UncategorizedCashflowTransaction.query().findById( - uncategorizedTransactionId - ); - await Account.query(trx) - .findById(transaction.accountId) - .increment('uncategorizedTransactions', 1); - } -} diff --git a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnCashflowDelete.ts b/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnCashflowDelete.ts deleted file mode 100644 index 3e205c4ba..000000000 --- a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnCashflowDelete.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICommandCashflowDeletingPayload, IManualJournalDeletingPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { ValidateTransactionMatched } from '../ValidateTransactionsMatched'; - -@Service() -export class ValidateMatchingOnCashflowDelete { - @Inject() - private validateNoMatchingLinkedService: ValidateTransactionMatched; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.cashflow.onTransactionDeleting, - this.validateMatchingOnCashflowDeleting.bind(this) - ); - } - - /** - * Validates the cashflow transaction whether matched with bank transaction on deleting. - * @param {IManualJournalDeletingPayload} - */ - public async validateMatchingOnCashflowDeleting({ - tenantId, - oldCashflowTransaction, - trx, - }: ICommandCashflowDeletingPayload) { - await this.validateNoMatchingLinkedService.validateTransactionNoMatchLinking( - tenantId, - 'CashflowTransaction', - oldCashflowTransaction.id, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnExpenseDelete.ts b/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnExpenseDelete.ts deleted file mode 100644 index eb5fda3b4..000000000 --- a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnExpenseDelete.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IExpenseEventDeletePayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { ValidateTransactionMatched } from '../ValidateTransactionsMatched'; - -@Service() -export class ValidateMatchingOnExpenseDelete { - @Inject() - private validateNoMatchingLinkedService: ValidateTransactionMatched; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.expenses.onDeleting, - this.validateMatchingOnExpenseDeleting.bind(this) - ); - } - - /** - * Validates the expense transaction whether matched with bank transaction on deleting. - * @param {IExpenseEventDeletePayload} - */ - public async validateMatchingOnExpenseDeleting({ - tenantId, - oldExpense, - trx, - }: IExpenseEventDeletePayload) { - await this.validateNoMatchingLinkedService.validateTransactionNoMatchLinking( - tenantId, - 'Expense', - oldExpense.id, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnManualJournalDelete.ts b/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnManualJournalDelete.ts deleted file mode 100644 index 61132db86..000000000 --- a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnManualJournalDelete.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IManualJournalDeletingPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { ValidateTransactionMatched } from '../ValidateTransactionsMatched'; - -@Service() -export class ValidateMatchingOnManualJournalDelete { - @Inject() - private validateNoMatchingLinkedService: ValidateTransactionMatched; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.manualJournals.onDeleting, - this.validateMatchingOnManualJournalDeleting.bind(this) - ); - } - - /** - * Validates the manual journal transaction whether matched with bank transaction on deleting. - * @param {IManualJournalDeletingPayload} - */ - public async validateMatchingOnManualJournalDeleting({ - tenantId, - oldManualJournal, - trx, - }: IManualJournalDeletingPayload) { - await this.validateNoMatchingLinkedService.validateTransactionNoMatchLinking( - tenantId, - 'ManualJournal', - oldManualJournal.id, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentMadeDelete.ts b/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentMadeDelete.ts deleted file mode 100644 index e0f3572e8..000000000 --- a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentMadeDelete.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IBillPaymentEventDeletedPayload, - IPaymentReceivedDeletedPayload, -} from '@/interfaces'; -import { ValidateTransactionMatched } from '../ValidateTransactionsMatched'; -import events from '@/subscribers/events'; - -@Service() -export class ValidateMatchingOnPaymentMadeDelete { - @Inject() - private validateNoMatchingLinkedService: ValidateTransactionMatched; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.billPayment.onDeleting, - this.validateMatchingOnPaymentMadeDeleting.bind(this) - ); - } - - /** - * Validates the payment made transaction whether matched with bank transaction on deleting. - * @param {IPaymentReceivedDeletedPayload} - */ - public async validateMatchingOnPaymentMadeDeleting({ - tenantId, - oldBillPayment, - trx, - }: IBillPaymentEventDeletedPayload) { - await this.validateNoMatchingLinkedService.validateTransactionNoMatchLinking( - tenantId, - 'PaymentMade', - oldBillPayment.id, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentReceivedDelete.ts b/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentReceivedDelete.ts deleted file mode 100644 index 385f55512..000000000 --- a/packages/server/src/services/Banking/Matching/events/ValidateMatchingOnPaymentReceivedDelete.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IPaymentReceivedDeletedPayload } from '@/interfaces'; -import { ValidateTransactionMatched } from '../ValidateTransactionsMatched'; -import events from '@/subscribers/events'; - -@Service() -export class ValidateMatchingOnPaymentReceivedDelete { - @Inject() - private validateNoMatchingLinkedService: ValidateTransactionMatched; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onDeleting, - this.validateMatchingOnPaymentReceivedDeleting.bind(this) - ); - } - - /** - * Validates the payment received transaction whether matched with bank transaction on deleting. - * @param {IPaymentReceivedDeletedPayload} - */ - public async validateMatchingOnPaymentReceivedDeleting({ - tenantId, - oldPaymentReceive, - trx, - }: IPaymentReceivedDeletedPayload) { - await this.validateNoMatchingLinkedService.validateTransactionNoMatchLinking( - tenantId, - 'PaymentReceive', - oldPaymentReceive.id, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/Matching/types.ts b/packages/server/src/services/Banking/Matching/types.ts deleted file mode 100644 index 707c0fe0c..000000000 --- a/packages/server/src/services/Banking/Matching/types.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Knex } from 'knex'; - -export interface IBankTransactionMatchingEventPayload { - tenantId: number; - uncategorizedTransactionIds: Array; - matchedTransactions: Array; - trx?: Knex.Transaction; -} - -export interface IBankTransactionMatchedEventPayload { - tenantId: number; - uncategorizedTransactionIds: Array; - matchedTransactions: Array; - trx?: Knex.Transaction; -} - -export interface IBankTransactionUnmatchingEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - trx?: Knex.Transaction; -} - -export interface IBankTransactionUnmatchedEventPayload { - tenantId: number; - uncategorizedTransactionId: number; - trx?: Knex.Transaction; -} - -export interface IMatchTransactionDTO { - referenceType: string; - referenceId: number; -} - -export interface IMatchTransactionsDTO { - uncategorizedTransactionIds: Array; - matchedTransactions: Array; -} - -export interface GetMatchedTransactionsFilter { - fromDate: string; - toDate: string; - minAmount: number; - maxAmount: number; - transactionType: string; -} - -export interface MatchedTransactionPOJO { - amount: number; - amountFormatted: string; - date: string; - dateFormatted: string; - referenceNo: string; - transactionNo: string; - transactionId: number; - transactionType: string; -} - -export type MatchedTransactionsPOJO = { - perfectMatches: Array; - possibleMatches: Array; - totalPending: number; -}; - -export const ERRORS = { - RESOURCE_TYPE_MATCHING_TRANSACTION_INVALID: - 'RESOURCE_TYPE_MATCHING_TRANSACTION_INVALID', - RESOURCE_ID_MATCHING_TRANSACTION_INVALID: - 'RESOURCE_ID_MATCHING_TRANSACTION_INVALID', - TOTAL_MATCHING_TRANSACTIONS_INVALID: 'TOTAL_MATCHING_TRANSACTIONS_INVALID', - TRANSACTION_ALREADY_MATCHED: 'TRANSACTION_ALREADY_MATCHED', - CANNOT_MATCH_EXCLUDED_TRANSACTION: 'CANNOT_MATCH_EXCLUDED_TRANSACTION', - CANNOT_DELETE_TRANSACTION_MATCHED: 'CANNOT_DELETE_TRANSACTION_MATCHED', -}; diff --git a/packages/server/src/services/Banking/Plaid/PlaidApplication.ts b/packages/server/src/services/Banking/Plaid/PlaidApplication.ts deleted file mode 100644 index 5b6b5d827..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidApplication.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { PlaidLinkTokenService } from './PlaidLinkToken'; -import { PlaidItemService } from './PlaidItem'; -import { PlaidItemDTO } from '@/interfaces'; -import { PlaidWebooks } from './PlaidWebhooks'; - -@Service() -export class PlaidApplication { - @Inject() - private getLinkTokenService: PlaidLinkTokenService; - - @Inject() - private plaidItemService: PlaidItemService; - - @Inject() - private plaidWebhooks: PlaidWebooks; - - /** - * Retrieves the Plaid link token. - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public getLinkToken(tenantId: number) { - return this.getLinkTokenService.getLinkToken(tenantId); - } - - /** - * Exchanges the Plaid access token. - * @param {number} tenantId - * @param {PlaidItemDTO} itemDTO - * @returns - */ - public exchangeToken(tenantId: number, itemDTO: PlaidItemDTO): Promise { - return this.plaidItemService.item(tenantId, itemDTO); - } - - /** - * Listens to Plaid webhooks - * @param {number} tenantId - * @param {string} webhookType - * @param {string} plaidItemId - * @param {string} webhookCode - * @returns - */ - public webhooks( - tenantId: number, - plaidItemId: string, - webhookType: string, - webhookCode: string - ) { - return this.plaidWebhooks.webhooks( - tenantId, - plaidItemId, - webhookType, - webhookCode - ); - } -} diff --git a/packages/server/src/services/Banking/Plaid/PlaidFetchTransactionsJob.ts b/packages/server/src/services/Banking/Plaid/PlaidFetchTransactionsJob.ts deleted file mode 100644 index a397037c2..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidFetchTransactionsJob.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Container, { Service } from 'typedi'; -import { PlaidUpdateTransactions } from './PlaidUpdateTransactions'; -import { IPlaidItemCreatedEventPayload } from '@/interfaces'; - -@Service() -export class PlaidFetchTransactionsJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'plaid-update-account-transactions', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers the function. - */ - private handler = async (job, done: Function) => { - const { tenantId, plaidItemId } = job.attrs - .data as IPlaidItemCreatedEventPayload; - - const plaidFetchTransactionsService = Container.get( - PlaidUpdateTransactions - ); - const io = Container.get('socket'); - - try { - await plaidFetchTransactionsService.updateTransactions( - tenantId, - plaidItemId - ); - // Notify the frontend to reflect the new transactions changes. - io.emit('NEW_TRANSACTIONS_DATA', { plaidItemId }); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Banking/Plaid/PlaidItem.ts b/packages/server/src/services/Banking/Plaid/PlaidItem.ts deleted file mode 100644 index 138d523c6..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidItem.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { PlaidClientWrapper } from '@/lib/Plaid'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { - IPlaidItemCreatedEventPayload, - PlaidItemDTO, -} from '@/interfaces/Plaid'; -import SystemPlaidItem from '@/system/models/SystemPlaidItem'; - -@Service() -export class PlaidItemService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Exchanges the public token to get access token and item id and then creates - * a new Plaid item. - * @param {number} tenantId - * @param {PlaidItemDTO} itemDTO - * @returns {Promise} - */ - public async item(tenantId: number, itemDTO: PlaidItemDTO): Promise { - const { PlaidItem } = this.tenancy.models(tenantId); - const { publicToken, institutionId } = itemDTO; - - const plaidInstance = PlaidClientWrapper.getClient(); - - // Exchange the public token for a private access token and store with the item. - const response = await plaidInstance.itemPublicTokenExchange({ - public_token: publicToken, - }); - const plaidAccessToken = response.data.access_token; - const plaidItemId = response.data.item_id; - - // Store the Plaid item metadata on tenant scope. - const plaidItem = await PlaidItem.query().insertAndFetch({ - tenantId, - plaidAccessToken, - plaidItemId, - plaidInstitutionId: institutionId, - }); - // Stores the Plaid item id on system scope. - await SystemPlaidItem.query().insert({ tenantId, plaidItemId }); - - // Triggers `onPlaidItemCreated` event. - await this.eventPublisher.emitAsync(events.plaid.onItemCreated, { - tenantId, - plaidAccessToken, - plaidItemId, - plaidInstitutionId: institutionId, - } as IPlaidItemCreatedEventPayload); - } -} diff --git a/packages/server/src/services/Banking/Plaid/PlaidLinkToken.ts b/packages/server/src/services/Banking/Plaid/PlaidLinkToken.ts deleted file mode 100644 index 003181505..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidLinkToken.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { PlaidClientWrapper } from '@/lib/Plaid'; -import { Service } from 'typedi'; -import config from '@/config'; - -@Service() -export class PlaidLinkTokenService { - /** - * Retrieves the plaid link token. - * @param {number} tenantId - * @returns - */ - async getLinkToken(tenantId: number) { - const accessToken = null; - - // Must include transactions in order to receive transactions webhooks - const products = ['transactions']; - const linkTokenParams = { - user: { - // This should correspond to a unique id for the current user. - client_user_id: 'uniqueId' + tenantId, - }, - client_name: 'Pattern', - products, - country_codes: ['US'], - language: 'en', - webhook: config.plaid.linkWebhook, - access_token: accessToken, - }; - const plaidInstance = PlaidClientWrapper.getClient(); - const createResponse = await plaidInstance.linkTokenCreate(linkTokenParams); - - return createResponse.data; - } -} diff --git a/packages/server/src/services/Banking/Plaid/PlaidSyncDB.ts b/packages/server/src/services/Banking/Plaid/PlaidSyncDB.ts deleted file mode 100644 index 4c1973f8b..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidSyncDB.ts +++ /dev/null @@ -1,270 +0,0 @@ -import * as R from 'ramda'; -import { Inject, Service } from 'typedi'; -import bluebird from 'bluebird'; -import { entries, groupBy } from 'lodash'; -import { - AccountBase as PlaidAccountBase, - Item as PlaidItem, - Institution as PlaidInstitution, -} from 'plaid'; -import { CreateAccount } from '@/services/Accounts/CreateAccount'; -import { - IAccountCreateDTO, - IPlaidTransactionsSyncedEventPayload, - PlaidAccount, - PlaidTransaction, -} from '@/interfaces'; -import { - transformPlaidAccountToCreateAccount, - transformPlaidTrxsToCashflowCreate, -} from './utils'; -import { DeleteCashflowTransaction } from '@/services/Cashflow/DeleteCashflowTransactionService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CashflowApplication } from '@/services/Cashflow/CashflowApplication'; -import { Knex } from 'knex'; -import uniqid from 'uniqid'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { RemovePendingUncategorizedTransaction } from '@/services/Cashflow/RemovePendingUncategorizedTransaction'; - -const CONCURRENCY_ASYNC = 10; - -@Service() -export class PlaidSyncDb { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private createAccountService: CreateAccount; - - @Inject() - private cashflowApp: CashflowApplication; - - @Inject() - private removePendingTransaction: RemovePendingUncategorizedTransaction; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Syncs the Plaid bank account. - * @param {number} tenantId - * @param {IAccountCreateDTO} createBankAccountDTO - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public async syncBankAccount( - tenantId: number, - createBankAccountDTO: IAccountCreateDTO, - trx?: Knex.Transaction - ) { - const { Account } = this.tenancy.models(tenantId); - - const plaidAccount = await Account.query().findOne( - 'plaidAccountId', - createBankAccountDTO.plaidAccountId - ); - // Can't continue if the Plaid account is already created. - if (plaidAccount) { - return; - } - await this.createAccountService.createAccount( - tenantId, - createBankAccountDTO, - trx, - { ignoreUniqueName: true } - ); - } - - /** - * Syncs the plaid accounts to the system accounts. - * @param {number} tenantId Tenant ID. - * @param {PlaidAccount[]} plaidAccounts - * @returns {Promise} - */ - public async syncBankAccounts( - tenantId: number, - plaidAccounts: PlaidAccountBase[], - institution: PlaidInstitution, - item: PlaidItem, - trx?: Knex.Transaction - ): Promise { - const transformToPlaidAccounts = transformPlaidAccountToCreateAccount( - item, - institution - ); - const accountCreateDTOs = R.map(transformToPlaidAccounts)(plaidAccounts); - - await bluebird.map( - accountCreateDTOs, - (createAccountDTO: any) => - this.syncBankAccount(tenantId, createAccountDTO, trx), - { concurrency: CONCURRENCY_ASYNC } - ); - } - - /** - * Synsc the Plaid transactions to the system GL entries. - * @param {number} tenantId - Tenant ID. - * @param {number} plaidAccountId - Plaid account ID. - * @param {PlaidTransaction[]} plaidTranasctions - Plaid transactions - * @return {Promise} - */ - public async syncAccountTranactions( - tenantId: number, - plaidAccountId: number, - plaidTranasctions: PlaidTransaction[], - trx?: Knex.Transaction - ): Promise { - const { Account } = this.tenancy.models(tenantId); - - const batch = uniqid(); - const cashflowAccount = await Account.query(trx) - .findOne({ plaidAccountId }) - .throwIfNotFound(); - - // Transformes the Plaid transactions to cashflow create DTOs. - const transformTransaction = transformPlaidTrxsToCashflowCreate( - cashflowAccount.id - ); - const uncategorizedTransDTOs = - R.map(transformTransaction)(plaidTranasctions); - - // Creating account transaction queue. - await bluebird.map( - uncategorizedTransDTOs, - (uncategoriedDTO) => - this.cashflowApp.createUncategorizedTransaction( - tenantId, - { ...uncategoriedDTO, batch }, - trx - ), - { concurrency: 1 } - ); - // Triggers `onPlaidTransactionsSynced` event. - await this.eventPublisher.emitAsync(events.plaid.onTransactionsSynced, { - tenantId, - plaidAccountId, - batch, - } as IPlaidTransactionsSyncedEventPayload); - } - - /** - * Syncs the accounts transactions in paraller under controlled concurrency. - * @param {number} tenantId - * @param {PlaidTransaction[]} plaidTransactions - * @return {Promise} - */ - public async syncAccountsTransactions( - tenantId: number, - plaidAccountsTransactions: PlaidTransaction[], - trx?: Knex.Transaction - ): Promise { - const groupedTrnsxByAccountId = entries( - groupBy(plaidAccountsTransactions, 'account_id') - ); - await bluebird.map( - groupedTrnsxByAccountId, - ([plaidAccountId, plaidTransactions]: [number, PlaidTransaction[]]) => { - return this.syncAccountTranactions( - tenantId, - plaidAccountId, - plaidTransactions, - trx - ); - }, - { concurrency: CONCURRENCY_ASYNC } - ); - } - - /** - * Syncs the removed Plaid transactions ids from the cashflow system transactions. - * @param {string[]} plaidTransactionsIds - Plaid Transactions IDs. - */ - public async syncRemoveTransactions( - tenantId: number, - plaidTransactionsIds: string[], - trx?: Knex.Transaction - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query(trx).whereIn( - 'plaidTransactionId', - plaidTransactionsIds - ); - const uncategorizedTransactionsIds = uncategorizedTransactions.map( - (trans) => trans.id - ); - await bluebird.map( - uncategorizedTransactionsIds, - (uncategorizedTransactionId: number) => - this.removePendingTransaction.removePendingTransaction( - tenantId, - uncategorizedTransactionId, - trx - ), - { concurrency: CONCURRENCY_ASYNC } - ); - } - - /** - * Syncs the Plaid item last transaction cursor. - * @param {number} tenantId - Tenant ID. - * @param {string} itemId - Plaid item ID. - * @param {string} lastCursor - Last transaction cursor. - * @return {Promise} - */ - public async syncTransactionsCursor( - tenantId: number, - plaidItemId: string, - lastCursor: string, - trx?: Knex.Transaction - ): Promise { - const { PlaidItem } = this.tenancy.models(tenantId); - - await PlaidItem.query(trx).findOne({ plaidItemId }).patch({ lastCursor }); - } - - /** - * Updates the last feeds updated at of the given Plaid accounts ids. - * @param {number} tenantId - * @param {string[]} plaidAccountIds - * @return {Promise} - */ - public async updateLastFeedsUpdatedAt( - tenantId: number, - plaidAccountIds: string[], - trx?: Knex.Transaction - ): Promise { - const { Account } = this.tenancy.models(tenantId); - - await Account.query(trx) - .whereIn('plaid_account_id', plaidAccountIds) - .patch({ - lastFeedsUpdatedAt: new Date(), - }); - } - - /** - * Updates the accounts feed active status of the given Plaid accounts ids. - * @param {number} tenantId - * @param {number[]} plaidAccountIds - * @param {boolean} isFeedsActive - * @returns {Promise} - */ - public async updateAccountsFeedsActive( - tenantId: number, - plaidAccountIds: string[], - isFeedsActive: boolean = true, - trx?: Knex.Transaction - ): Promise { - const { Account } = this.tenancy.models(tenantId); - - await Account.query(trx) - .whereIn('plaid_account_id', plaidAccountIds) - .patch({ - isFeedsActive, - }); - } -} diff --git a/packages/server/src/services/Banking/Plaid/PlaidUpdateTransactions.ts b/packages/server/src/services/Banking/Plaid/PlaidUpdateTransactions.ts deleted file mode 100644 index c987dd84f..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidUpdateTransactions.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { PlaidClientWrapper } from '@/lib/Plaid/Plaid'; -import { PlaidSyncDb } from './PlaidSyncDB'; -import { PlaidFetchedTransactionsUpdates } from '@/interfaces'; -import UnitOfWork from '@/services/UnitOfWork'; - -@Service() -export class PlaidUpdateTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private plaidSync: PlaidSyncDb; - - @Inject() - private uow: UnitOfWork; - - /** - * Handles sync the Plaid item to Bigcaptial under UOW. - * @param {number} tenantId - Tenant id. - * @param {number} plaidItemId - Plaid item id. - * @returns {Promise<{ addedCount: number; modifiedCount: number; removedCount: number; }>} - */ - public async updateTransactions(tenantId: number, plaidItemId: string) { - return this.uow.withTransaction(tenantId, (trx: Knex.Transaction) => { - return this.updateTransactionsWork(tenantId, plaidItemId, trx); - }); - } - - /** - * Handles the fetching and storing the following: - * - New, modified, or removed transactions. - * - New bank accounts. - * - Last accounts feeds updated at. - * - Turn on the accounts feed flag. - * @param {number} tenantId - Tenant ID. - * @param {string} plaidItemId - The Plaid ID for the item. - * @returns {Promise<{ addedCount: number; modifiedCount: number; removedCount: number; }>} - */ - public async updateTransactionsWork( - tenantId: number, - plaidItemId: string, - trx?: Knex.Transaction - ): Promise<{ - addedCount: number; - modifiedCount: number; - removedCount: number; - }> { - // Fetch new transactions from plaid api. - const { added, modified, removed, cursor, accessToken } = - await this.fetchTransactionUpdates(tenantId, plaidItemId); - - const request = { access_token: accessToken }; - const plaidInstance = PlaidClientWrapper.getClient(); - const { - data: { accounts, item }, - } = await plaidInstance.accountsGet(request); - - const plaidAccountsIds = accounts.map((a) => a.account_id); - const { - data: { institution }, - } = await plaidInstance.institutionsGetById({ - institution_id: item.institution_id, - country_codes: ['US', 'UK'], - }); - // Sync bank accounts. - await this.plaidSync.syncBankAccounts( - tenantId, - accounts, - institution, - item, - trx - ); - // Sync removed transactions. - await this.plaidSync.syncRemoveTransactions( - tenantId, - removed?.map((r) => r.transaction_id), - trx - ); - // Sync bank account transactions. - await this.plaidSync.syncAccountsTransactions( - tenantId, - added.concat(modified), - trx - ); - // Sync transactions cursor. - await this.plaidSync.syncTransactionsCursor( - tenantId, - plaidItemId, - cursor, - trx - ); - // Update the last feeds updated at of the updated accounts. - await this.plaidSync.updateLastFeedsUpdatedAt( - tenantId, - plaidAccountsIds, - trx - ); - // Turn on the accounts feeds flag. - await this.plaidSync.updateAccountsFeedsActive( - tenantId, - plaidAccountsIds, - true, - trx - ); - return { - addedCount: added.length, - modifiedCount: modified.length, - removedCount: removed.length, - }; - } - - /** - * Fetches transactions from the `Plaid API` for a given item. - * @param {number} tenantId - Tenant ID. - * @param {string} plaidItemId - The Plaid ID for the item. - * @returns {Promise} - */ - private async fetchTransactionUpdates( - tenantId: number, - plaidItemId: string - ): Promise { - // the transactions endpoint is paginated, so we may need to hit it multiple times to - // retrieve all available transactions. - const { PlaidItem } = this.tenancy.models(tenantId); - - const plaidItem = await PlaidItem.query().findOne( - 'plaidItemId', - plaidItemId - ); - if (!plaidItem) { - throw new Error('The given Plaid item id is not found.'); - } - const { plaidAccessToken, lastCursor } = plaidItem; - let cursor = lastCursor; - - // New transaction updates since "cursor" - let added = []; - let modified = []; - // Removed transaction ids - let removed = []; - let hasMore = true; - - const batchSize = 100; - try { - // Iterate through each page of new transaction updates for item - /* eslint-disable no-await-in-loop */ - while (hasMore) { - const request = { - access_token: plaidAccessToken, - cursor: cursor, - count: batchSize, - }; - const plaidInstance = PlaidClientWrapper.getClient(); - const response = await plaidInstance.transactionsSync(request); - const data = response.data; - // Add this page of results - added = added.concat(data.added); - modified = modified.concat(data.modified); - removed = removed.concat(data.removed); - hasMore = data.has_more; - // Update cursor to the next cursor - cursor = data.next_cursor; - } - } catch (err) { - console.error(`Error fetching transactions: ${err.message}`); - cursor = lastCursor; - } - return { added, modified, removed, cursor, accessToken: plaidAccessToken }; - } -} diff --git a/packages/server/src/services/Banking/Plaid/PlaidWebhookTenantBootMiddleware.ts b/packages/server/src/services/Banking/Plaid/PlaidWebhookTenantBootMiddleware.ts deleted file mode 100644 index 6a1c177ba..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidWebhookTenantBootMiddleware.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { SystemPlaidItem, Tenant } from '@/system/models'; -import tenantDependencyInjection from '@/api/middleware/TenantDependencyInjection'; - -export const PlaidWebhookTenantBootMiddleware = async ( - req: Request, - res: Response, - next: NextFunction -) => { - const { item_id: plaidItemId } = req.body; - const plaidItem = await SystemPlaidItem.query().findOne({ plaidItemId }); - - const notFoundOrganization = () => { - return res.boom.unauthorized('Organization identication not found.', { - errors: [{ type: 'ORGANIZATION.ID.NOT.FOUND', code: 100 }], - }); - }; - // In case the given organization not found. - if (!plaidItem) { - return notFoundOrganization(); - } - const tenant = await Tenant.query() - .findById(plaidItem.tenantId) - .withGraphFetched('metadata'); - - // When the given organization id not found on the system storage. - if (!tenant) { - return notFoundOrganization(); - } - tenantDependencyInjection(req, tenant); - next(); -}; diff --git a/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts b/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts deleted file mode 100644 index bebf29671..000000000 --- a/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { PlaidUpdateTransactions } from './PlaidUpdateTransactions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class PlaidWebooks { - @Inject() - private updateTransactionsService: PlaidUpdateTransactions; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Listens to Plaid webhooks - * @param {number} tenantId - Tenant Id. - * @param {string} webhookType - Webhook type. - * @param {string} plaidItemId - Plaid item Id. - * @param {string} webhookCode - webhook code. - */ - public async webhooks( - tenantId: number, - plaidItemId: string, - webhookType: string, - webhookCode: string - ): Promise { - const _webhookType = webhookType.toLowerCase(); - - // There are five types of webhooks: AUTH, TRANSACTIONS, ITEM, INCOME, and ASSETS. - // @TODO implement handling for remaining webhook types. - const webhookHandlerMap = { - transactions: this.handleTransactionsWebooks.bind(this), - item: this.itemsHandler.bind(this), - }; - const webhookHandler = - webhookHandlerMap[_webhookType] || this.unhandledWebhook; - - await webhookHandler(tenantId, plaidItemId, webhookCode); - } - - /** - * Handles all unhandled/not yet implemented webhook events. - * @param {string} webhookType - * @param {string} webhookCode - * @param {string} plaidItemId - */ - private async unhandledWebhook( - webhookType: string, - webhookCode: string, - plaidItemId: string - ): Promise { - console.log( - `UNHANDLED ${webhookType} WEBHOOK: ${webhookCode}: Plaid item id ${plaidItemId}: unhandled webhook type received.` - ); - } - - /** - * Logs to console and emits to socket - * @param {string} additionalInfo - * @param {string} webhookCode - * @param {string} plaidItemId - */ - private serverLogAndEmitSocket( - additionalInfo: string, - webhookCode: string, - plaidItemId: string - ): void { - console.log( - `PLAID WEBHOOK: TRANSACTIONS: ${webhookCode}: Plaid_item_id ${plaidItemId}: ${additionalInfo}` - ); - } - - /** - * Handles all transaction webhook events. The transaction webhook notifies - * you that a single item has new transactions available. - * @param {number} tenantId - * @param {string} plaidItemId - * @param {string} webhookCode - * @returns {Promise} - */ - public async handleTransactionsWebooks( - tenantId: number, - plaidItemId: string, - webhookCode: string - ): Promise { - const { PlaidItem } = this.tenancy.models(tenantId); - - const plaidItem = await PlaidItem.query() - .findOne({ plaidItemId }) - .throwIfNotFound(); - - switch (webhookCode) { - case 'SYNC_UPDATES_AVAILABLE': { - if (plaidItem.isPaused) { - this.serverLogAndEmitSocket( - 'Plaid item syncing is paused.', - webhookCode, - plaidItemId - ); - return; - } - // Fired when new transactions data becomes available. - const { addedCount, modifiedCount, removedCount } = - await this.updateTransactionsService.updateTransactions( - tenantId, - plaidItemId - ); - this.serverLogAndEmitSocket( - `Transactions: ${addedCount} added, ${modifiedCount} modified, ${removedCount} removed`, - webhookCode, - plaidItemId - ); - break; - } - case 'DEFAULT_UPDATE': - case 'INITIAL_UPDATE': - case 'HISTORICAL_UPDATE': - /* ignore - not needed if using sync endpoint + webhook */ - break; - default: - this.serverLogAndEmitSocket( - `unhandled webhook type received.`, - webhookCode, - plaidItemId - ); - } - } - - /** - * Handles all Item webhook events. - * @param {number} tenantId - Tenant ID - * @param {string} webhookCode - The webhook code - * @param {string} plaidItemId - The Plaid ID for the item - * @returns {Promise} - */ - public async itemsHandler( - tenantId: number, - plaidItemId: string, - webhookCode: string - ): Promise { - switch (webhookCode) { - case 'WEBHOOK_UPDATE_ACKNOWLEDGED': - this.serverLogAndEmitSocket('is updated', plaidItemId, error); - break; - case 'ERROR': { - break; - } - case 'PENDING_EXPIRATION': { - break; - } - default: - this.serverLogAndEmitSocket( - 'unhandled webhook type received.', - webhookCode, - plaidItemId - ); - } - } -} diff --git a/packages/server/src/services/Banking/Plaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts b/packages/server/src/services/Banking/Plaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts deleted file mode 100644 index 216eae2f2..000000000 --- a/packages/server/src/services/Banking/Plaid/subscribers/PlaidUpdateTransactionsOnItemCreatedSubscriber.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { IPlaidItemCreatedEventPayload } from '@/interfaces/Plaid'; -import events from '@/subscribers/events'; - -@Service() -export class PlaidUpdateTransactionsOnItemCreatedSubscriber extends EventSubscriber { - @Inject('agenda') - private agenda: any; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.plaid.onItemCreated, - this.handleUpdateTransactionsOnItemCreated - ); - } - - /** - * Updates the Plaid item transactions - * @param {IPlaidItemCreatedEventPayload} payload - Event payload. - */ - private handleUpdateTransactionsOnItemCreated = async ({ - tenantId, - plaidItemId, - plaidAccessToken, - plaidInstitutionId, - }: IPlaidItemCreatedEventPayload) => { - const payload = { tenantId, plaidItemId }; - await this.agenda.now('plaid-update-account-transactions', payload); - }; -} diff --git a/packages/server/src/services/Banking/Plaid/subscribers/RecognizeSyncedBankTransactions.ts b/packages/server/src/services/Banking/Plaid/subscribers/RecognizeSyncedBankTransactions.ts deleted file mode 100644 index e68aecffe..000000000 --- a/packages/server/src/services/Banking/Plaid/subscribers/RecognizeSyncedBankTransactions.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IPlaidItemCreatedEventPayload, - IPlaidTransactionsSyncedEventPayload, -} from '@/interfaces/Plaid'; -import events from '@/subscribers/events'; -import { RecognizeTranasctionsService } from '../../RegonizeTranasctions/RecognizeTranasctionsService'; -import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks'; - -@Service() -export class RecognizeSyncedBankTranasctions extends EventSubscriber { - @Inject() - private recognizeTranasctionsService: RecognizeTranasctionsService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.plaid.onTransactionsSynced, - this.handleRecognizeSyncedBankTransactions.bind(this) - ); - } - - /** - * Updates the Plaid item transactions - * @param {IPlaidItemCreatedEventPayload} payload - Event payload. - */ - private handleRecognizeSyncedBankTransactions = async ({ - tenantId, - batch, - trx, - }: IPlaidTransactionsSyncedEventPayload) => { - runAfterTransaction(trx, async () => { - await this.recognizeTranasctionsService.recognizeTransactions( - tenantId, - null, - { batch } - ); - }); - }; -} diff --git a/packages/server/src/services/Banking/Plaid/utils.ts b/packages/server/src/services/Banking/Plaid/utils.ts deleted file mode 100644 index 3700e37ab..000000000 --- a/packages/server/src/services/Banking/Plaid/utils.ts +++ /dev/null @@ -1,87 +0,0 @@ -import * as R from 'ramda'; -import { - Item as PlaidItem, - Institution as PlaidInstitution, - AccountBase as PlaidAccount, - TransactionBase as PlaidTransactionBase, - AccountType as PlaidAccountType, -} from 'plaid'; -import { - CreateUncategorizedTransactionDTO, - IAccountCreateDTO, -} from '@/interfaces'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -/** - * Retrieves the system account type from the given Plaid account type. - * @param {PlaidAccountType} plaidAccountType - * @returns {string} - */ -const getAccountTypeFromPlaidAccountType = ( - plaidAccountType: PlaidAccountType -) => { - if (plaidAccountType === PlaidAccountType.Credit) { - return ACCOUNT_TYPE.CREDIT_CARD; - } - return ACCOUNT_TYPE.BANK; -}; - -/** - * Transformes the Plaid account to create cashflow account DTO. - * @param {PlaidItem} item - - * @param {PlaidInstitution} institution - - * @param {PlaidAccount} plaidAccount - - * @returns {IAccountCreateDTO} - */ -export const transformPlaidAccountToCreateAccount = R.curry( - ( - item: PlaidItem, - institution: PlaidInstitution, - plaidAccount: PlaidAccount - ): IAccountCreateDTO => { - return { - name: `${institution.name} - ${plaidAccount.name}`, - code: '', - description: plaidAccount.official_name, - currencyCode: plaidAccount.balances.iso_currency_code, - accountType: getAccountTypeFromPlaidAccountType(plaidAccount.type), - active: true, - bankBalance: plaidAccount.balances.current, - accountMask: plaidAccount.mask, - plaidAccountId: plaidAccount.account_id, - plaidItemId: item.item_id, - }; - } -); - -/** - * Transformes the plaid transaction to cashflow create DTO. - * @param {number} cashflowAccountId - Cashflow account ID. - * @param {number} creditAccountId - Credit account ID. - * @param {PlaidTransaction} plaidTranasction - Plaid transaction. - * @returns {CreateUncategorizedTransactionDTO} - */ -export const transformPlaidTrxsToCashflowCreate = R.curry( - ( - cashflowAccountId: number, - plaidTranasction: PlaidTransactionBase - ): CreateUncategorizedTransactionDTO => { - return { - date: plaidTranasction.date, - - // Plaid: Positive values when money moves out of the account; negative values - // when money moves in. For example, debit card purchases are positive; - // credit card payments, direct deposits, and refunds are negative. - amount: -1 * plaidTranasction.amount, - - description: plaidTranasction.name, - payee: plaidTranasction.payment_meta?.payee, - currencyCode: plaidTranasction.iso_currency_code, - accountId: cashflowAccountId, - referenceNo: plaidTranasction.payment_meta?.reference_number, - plaidTransactionId: plaidTranasction.transaction_id, - pending: plaidTranasction.pending, - pendingPlaidTransactionId: plaidTranasction.pending_transaction_id, - }; - } -); diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransaction.ts b/packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransaction.ts deleted file mode 100644 index e31402fad..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransaction.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { castArray, first, uniq } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetAutofillCategorizeTransctionTransformer } from './GetAutofillCategorizeTransactionTransformer'; - -@Service() -export class GetAutofillCategorizeTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the autofill values of categorize transactions form. - * @param {number} tenantId - Tenant id. - * @param {Array | number} uncategorizeTransactionsId - Uncategorized transactions ids. - */ - public async getAutofillCategorizeTransaction( - tenantId: number, - uncategorizeTransactionsId: Array | number - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - const uncategorizeTransactionsIds = uniq( - castArray(uncategorizeTransactionsId) - ); - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query() - .whereIn('id', uncategorizeTransactionsIds) - .withGraphFetched('recognizedTransaction.assignAccount') - .withGraphFetched('recognizedTransaction.bankRule') - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - {}, - new GetAutofillCategorizeTransctionTransformer(), - { - uncategorizedTransactions, - firstUncategorizedTransaction: first(uncategorizedTransactions), - } - ); - } -} diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransactionTransformer.ts b/packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransactionTransformer.ts deleted file mode 100644 index af6950261..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/GetAutofillCategorizeTransactionTransformer.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { sumBy } from 'lodash'; - -export class GetAutofillCategorizeTransctionTransformer extends Transformer { - /** - * Included attributes to the object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'amount', - 'formattedAmount', - 'isRecognized', - 'date', - 'formattedDate', - 'creditAccountId', - 'debitAccountId', - 'referenceNo', - 'transactionType', - 'recognizedByRuleId', - 'recognizedByRuleName', - 'isWithdrawalTransaction', - 'isDepositTransaction', - ]; - }; - - /** - * Detarmines whether the transaction is recognized. - * @returns {boolean} - */ - public isRecognized() { - return !!this.options.firstUncategorizedTransaction?.recognizedTransaction; - } - - /** - * Retrieves the total amount of uncategorized transactions. - * @returns {number} - */ - public amount() { - return sumBy(this.options.uncategorizedTransactions, 'amount'); - } - - /** - * Retrieves the formatted total amount of uncategorized transactions. - * @returns {string} - */ - public formattedAmount() { - return this.formatNumber(this.amount(), { - currencyCode: 'USD', - money: true, - }); - } - - /** - * Detarmines whether the transaction is deposit. - * @returns {boolean} - */ - public isDepositTransaction() { - const amount = this.amount(); - - return amount > 0; - } - - /** - * Detarmines whether the transaction is withdrawal. - * @returns {boolean} - */ - public isWithdrawalTransaction() { - const amount = this.amount(); - - return amount < 0; - } - - /** - * - * @param {string} - */ - public date() { - return this.options.firstUncategorizedTransaction?.date || null; - } - - /** - * Retrieves the formatted date of uncategorized transaction. - * @returns {string} - */ - public formattedDate() { - return this.formatDate(this.date()); - } - - /** - * - * @param {string} - */ - public referenceNo() { - return this.options.firstUncategorizedTransaction?.referenceNo || null; - } - - /** - * - * @returns {number} - */ - public creditAccountId() { - return ( - this.options.firstUncategorizedTransaction?.recognizedTransaction - ?.assignedAccountId || null - ); - } - - /** - * - * @returns {number} - */ - public debitAccountId() { - return this.options.firstUncategorizedTransaction?.accountId || null; - } - - /** - * Retrieves the assigned category of recognized transaction, if is not recognized - * returns the default transaction type depends on the transaction normal. - * @returns {string} - */ - public transactionType() { - const assignedCategory = - this.options.firstUncategorizedTransaction?.recognizedTransaction - ?.assignedCategory; - - return ( - assignedCategory || - (this.isDepositTransaction() ? 'other_income' : 'other_expense') - ); - } - - /** - * - * @returns {string} - */ - public payee() { - return ( - this.options.firstUncategorizedTransaction?.recognizedTransaction - ?.assignedPayee || null - ); - } - - /** - * - * @returns {string} - */ - public memo() { - return ( - this.options.firstUncategorizedTransaction?.recognizedTransaction - ?.assignedMemo || null - ); - } - - /** - * Retrieves the rule id the transaction recongized by. - * @returns {string} - */ - public recognizedByRuleId() { - return ( - this.options.firstUncategorizedTransaction?.recognizedTransaction - ?.bankRuleId || null - ); - } - - /** - * Retrieves the rule name the transaction recongized by. - * @returns {string} - */ - public recognizedByRuleName() { - return ( - this.options.firstUncategorizedTransaction?.recognizedTransaction - ?.bankRule?.name || null - ); - } -} diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/RecognizeTranasctionsService.ts b/packages/server/src/services/Banking/RegonizeTranasctions/RecognizeTranasctionsService.ts deleted file mode 100644 index d176a3c1b..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/RecognizeTranasctionsService.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { castArray, isEmpty } from 'lodash'; -import UncategorizedCashflowTransaction from '@/models/UncategorizedCashflowTransaction'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { transformToMapBy } from '@/utils'; -import { PromisePool } from '@supercharge/promise-pool'; -import { BankRule } from '@/models/BankRule'; -import { bankRulesMatchTransaction } from './_utils'; -import { RecognizeTransactionsCriteria } from './_types'; - -@Service() -export class RecognizeTranasctionsService { - @Inject() - private tenancy: HasTenancyService; - - /** - * Marks the uncategorized transaction as recognized from the given bank rule. - * @param {number} tenantId - - * @param {BankRule} bankRule - - * @param {UncategorizedCashflowTransaction} transaction - - * @param {Knex.Transaction} trx - - */ - private markBankRuleAsRecognized = async ( - tenantId: number, - bankRule: BankRule, - transaction: UncategorizedCashflowTransaction, - trx?: Knex.Transaction - ) => { - const { RecognizedBankTransaction, UncategorizedCashflowTransaction } = - this.tenancy.models(tenantId); - - const recognizedTransaction = await RecognizedBankTransaction.query( - trx - ).insert({ - bankRuleId: bankRule.id, - uncategorizedTransactionId: transaction.id, - assignedCategory: bankRule.assignCategory, - assignedAccountId: bankRule.assignAccountId, - assignedPayee: bankRule.assignPayee, - assignedMemo: bankRule.assignMemo, - }); - await UncategorizedCashflowTransaction.query(trx) - .findById(transaction.id) - .patch({ - recognizedTransactionId: recognizedTransaction.id, - }); - }; - - /** - * Regonized the uncategorized transactions. - * @param {number} tenantId - - * @param {number|Array} ruleId - The target rule id/ids. - * @param {RecognizeTransactionsCriteria} - * @param {Knex.Transaction} trx - - */ - public async recognizeTransactions( - tenantId: number, - ruleId?: number | Array, - transactionsCriteria?: RecognizeTransactionsCriteria, - trx?: Knex.Transaction - ) { - const { UncategorizedCashflowTransaction, BankRule } = - this.tenancy.models(tenantId); - - const uncategorizedTranasctions = - await UncategorizedCashflowTransaction.query(trx).onBuild((query) => { - query.modify('notRecognized'); - query.modify('notCategorized'); - - // Filter the transactions based on the given criteria. - if (transactionsCriteria?.batch) { - query.where('batch', transactionsCriteria.batch); - } - if (transactionsCriteria?.accountId) { - query.where('accountId', transactionsCriteria.accountId); - } - }); - - const bankRules = await BankRule.query(trx).onBuild((q) => { - const rulesIds = !isEmpty(ruleId) ? castArray(ruleId) : []; - - if (rulesIds?.length > 0) { - q.whereIn('id', rulesIds); - } - q.withGraphFetched('conditions'); - }); - - const bankRulesByAccountId = transformToMapBy( - bankRules, - 'applyIfAccountId' - ); - // Try to recognize the transaction. - const regonizeTransaction = async ( - transaction: UncategorizedCashflowTransaction - ) => { - const allAccountsBankRules = bankRulesByAccountId.get(`null`); - const accountBankRules = bankRulesByAccountId.get( - `${transaction.accountId}` - ); - const recognizedBankRule = bankRulesMatchTransaction( - transaction, - accountBankRules - ); - if (recognizedBankRule) { - await this.markBankRuleAsRecognized( - tenantId, - recognizedBankRule, - transaction, - trx - ); - } - }; - const result = await PromisePool.withConcurrency(MIGRATION_CONCURRENCY) - .for(uncategorizedTranasctions) - .process((transaction: UncategorizedCashflowTransaction, index, pool) => { - return regonizeTransaction(transaction); - }); - } - - /** - * - * @param {number} uncategorizedTransaction - */ - public async regonizeTransaction( - uncategorizedTransaction: UncategorizedCashflowTransaction - ) {} -} - -const MIGRATION_CONCURRENCY = 10; diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/RevertRecognizedTransactions.ts b/packages/server/src/services/Banking/RegonizeTranasctions/RevertRecognizedTransactions.ts deleted file mode 100644 index 2d8247506..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/RevertRecognizedTransactions.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { castArray } from 'lodash'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { RevertRecognizedTransactionsCriteria } from './_types'; - -@Service() -export class RevertRecognizedTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - /** - * Revert and unlinks the recognized transactions based on the given bank rule - * and transactions criteria.. - * @param {number} tenantId - Tenant id. - * @param {number|Array} bankRuleId - Bank rule id. - * @param {RevertRecognizedTransactionsCriteria} transactionsCriteria - - * @param {Knex.Transaction} trx - Knex transaction. - * @returns {Promise} - */ - public async revertRecognizedTransactions( - tenantId: number, - ruleId?: number | Array, - transactionsCriteria?: RevertRecognizedTransactionsCriteria, - trx?: Knex.Transaction - ): Promise { - const { UncategorizedCashflowTransaction, RecognizedBankTransaction } = - this.tenancy.models(tenantId); - - const rulesIds = castArray(ruleId); - - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Retrieves all the recognized transactions of the banbk rule. - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query(trx).onBuild((q) => { - q.withGraphJoined('recognizedTransaction'); - q.whereNotNull('recognizedTransaction.id'); - - if (rulesIds.length > 0) { - q.whereIn('recognizedTransaction.bankRuleId', rulesIds); - } - if (transactionsCriteria?.accountId) { - q.where('accountId', transactionsCriteria.accountId); - } - if (transactionsCriteria?.batch) { - q.where('batch', transactionsCriteria.batch); - } - }); - const uncategorizedTransactionIds = uncategorizedTransactions.map( - (r) => r.id - ); - // Unlink the recongized transactions out of uncategorized transactions. - await UncategorizedCashflowTransaction.query(trx) - .whereIn('id', uncategorizedTransactionIds) - .patch({ - recognizedTransactionId: null, - }); - // Delete the recognized bank transactions that assocaited to bank rule. - await RecognizedBankTransaction.query(trx) - .whereIn('uncategorizedTransactionId', uncategorizedTransactionIds) - .delete(); - }, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/_types.ts b/packages/server/src/services/Banking/RegonizeTranasctions/_types.ts deleted file mode 100644 index 92f394b0a..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/_types.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface RevertRecognizedTransactionsCriteria { - batch?: string; - accountId?: number; -} - - -export interface RecognizeTransactionsCriteria { - batch?: string; - accountId?: number; -} - diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/_utils.ts b/packages/server/src/services/Banking/RegonizeTranasctions/_utils.ts deleted file mode 100644 index 4ca0d8b9f..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/_utils.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { lowerCase } from 'lodash'; -import UncategorizedCashflowTransaction from '@/models/UncategorizedCashflowTransaction'; -import { - BankRuleApplyIfTransactionType, - BankRuleConditionComparator, - BankRuleConditionType, - IBankRule, - IBankRuleCondition, -} from '../Rules/types'; -import { BankRule } from '@/models/BankRule'; - -const conditionsMatch = ( - transaction: UncategorizedCashflowTransaction, - conditions: IBankRuleCondition[], - conditionsType: BankRuleConditionType = BankRuleConditionType.And -) => { - const method = - conditionsType === BankRuleConditionType.And ? 'every' : 'some'; - - return conditions[method]((condition) => { - switch (determineFieldType(condition.field)) { - case 'number': - return matchNumberCondition(transaction, condition); - case 'text': - return matchTextCondition(transaction, condition); - default: - return false; - } - }); -}; - -const matchNumberCondition = ( - transaction: UncategorizedCashflowTransaction, - condition: IBankRuleCondition -) => { - const conditionValue = parseFloat(condition.value); - const transactionAmount = - condition.field === 'amount' - ? Math.abs(transaction[condition.field]) - : (transaction[condition.field] as unknown as number); - - switch (condition.comparator) { - case BankRuleConditionComparator.Equals: - case BankRuleConditionComparator.Equal: - return transactionAmount === conditionValue; - - case BankRuleConditionComparator.BiggerOrEqual: - return transactionAmount >= conditionValue; - - case BankRuleConditionComparator.Bigger: - return transactionAmount > conditionValue; - - case BankRuleConditionComparator.Smaller: - return transactionAmount < conditionValue; - - case BankRuleConditionComparator.SmallerOrEqual: - return transactionAmount <= conditionValue; - - default: - return false; - } -}; - -const matchTextCondition = ( - transaction: UncategorizedCashflowTransaction, - condition: IBankRuleCondition -): boolean => { - const transactionValue = transaction[condition.field] as string; - - switch (condition.comparator) { - case BankRuleConditionComparator.Equals: - case BankRuleConditionComparator.Equal: - return transactionValue === condition.value; - case BankRuleConditionComparator.Contains: - const fieldValue = lowerCase(transactionValue); - const conditionValue = lowerCase(condition.value); - - return fieldValue.includes(conditionValue); - case BankRuleConditionComparator.NotContain: - return !transactionValue?.includes(condition.value.toString()); - default: - return false; - } -}; - -const matchTransactionType = ( - bankRule: BankRule, - transaction: UncategorizedCashflowTransaction -): boolean => { - return ( - (transaction.isDepositTransaction && - bankRule.applyIfTransactionType === - BankRuleApplyIfTransactionType.Deposit) || - (transaction.isWithdrawalTransaction && - bankRule.applyIfTransactionType === - BankRuleApplyIfTransactionType.Withdrawal) - ); -}; - -export const bankRulesMatchTransaction = ( - transaction: UncategorizedCashflowTransaction, - bankRules: IBankRule[] -) => { - return bankRules.find((rule) => { - return ( - matchTransactionType(rule, transaction) && - conditionsMatch(transaction, rule.conditions, rule.conditionsType) - ); - }); -}; - -const determineFieldType = (field: string): string => { - switch (field) { - case 'amount': - return 'number'; - case 'description': - case 'payee': - default: - return 'text'; - } -}; diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/events/TriggerRecognizedTransactions.ts b/packages/server/src/services/Banking/RegonizeTranasctions/events/TriggerRecognizedTransactions.ts deleted file mode 100644 index 7220be765..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/events/TriggerRecognizedTransactions.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEqual, omit } from 'lodash'; -import events from '@/subscribers/events'; -import { - IBankRuleEventCreatedPayload, - IBankRuleEventDeletedPayload, - IBankRuleEventEditedPayload, -} from '../../Rules/types'; -import { IImportFileCommitedEventPayload } from '@/interfaces/Import'; -import { Import } from '@/system/models'; - -@Service() -export class TriggerRecognizedTransactions { - @Inject('agenda') - private agenda: any; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.bankRules.onCreated, - this.recognizedTransactionsOnRuleCreated.bind(this) - ); - bus.subscribe( - events.bankRules.onEdited, - this.recognizedTransactionsOnRuleEdited.bind(this) - ); - bus.subscribe( - events.bankRules.onDeleted, - this.recognizedTransactionsOnRuleDeleted.bind(this) - ); - bus.subscribe( - events.import.onImportCommitted, - this.triggerRecognizeTransactionsOnImportCommitted.bind(this) - ); - } - - /** - * Triggers the recognize uncategorized transactions job on rule created. - * @param {IBankRuleEventCreatedPayload} payload - - */ - private async recognizedTransactionsOnRuleCreated({ - tenantId, - bankRule, - }: IBankRuleEventCreatedPayload) { - const payload = { tenantId, ruleId: bankRule.id }; - - await this.agenda.now('recognize-uncategorized-transactions-job', payload); - } - - /** - * Triggers the recognize uncategorized transactions job on rule edited. - * @param {IBankRuleEventEditedPayload} payload - - */ - private async recognizedTransactionsOnRuleEdited({ - tenantId, - editRuleDTO, - oldBankRule, - bankRule, - ruleId, - }: IBankRuleEventEditedPayload) { - const payload = { tenantId, ruleId }; - - // Cannot continue if the new and old bank rule values are the same, - // after excluding `createdAt` and `updatedAt` dates. - if ( - isEqual( - omit(bankRule, ['createdAt', 'updatedAt']), - omit(oldBankRule, ['createdAt', 'updatedAt']) - ) - ) { - return; - } - await this.agenda.now( - 'rerecognize-uncategorized-transactions-job', - payload - ); - } - - /** - * Triggers the recognize uncategorized transactions job on rule deleted. - * @param {IBankRuleEventDeletedPayload} payload - - */ - private async recognizedTransactionsOnRuleDeleted({ - tenantId, - ruleId, - }: IBankRuleEventDeletedPayload) { - const payload = { tenantId, ruleId }; - await this.agenda.now( - 'revert-recognized-uncategorized-transactions-job', - payload - ); - } - - /** - * Triggers the recognize bank transactions once the imported file commit. - * @param {IImportFileCommitedEventPayload} payload - - */ - private async triggerRecognizeTransactionsOnImportCommitted({ - tenantId, - importId, - }: IImportFileCommitedEventPayload) { - const importFile = await Import.query().findOne({ importId }); - const batch = importFile.paramsParsed.batch; - const payload = { tenantId, transactionsCriteria: { batch } }; - - // Cannot continue if the imported resource is not bank account transactions. - if (importFile.resource !== 'UncategorizedCashflowTransaction') return; - - await this.agenda.now('recognize-uncategorized-transactions-job', payload); - } -} diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RecognizeTransactionsJob.ts b/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RecognizeTransactionsJob.ts deleted file mode 100644 index 319ec8a10..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RecognizeTransactionsJob.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Container, { Service } from 'typedi'; -import { RecognizeTranasctionsService } from '../RecognizeTranasctionsService'; - -@Service() -export class RegonizeTransactionsJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'recognize-uncategorized-transactions-job', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, ruleId, transactionsCriteria } = job.attrs.data; - const regonizeTransactions = Container.get(RecognizeTranasctionsService); - - try { - await regonizeTransactions.recognizeTransactions( - tenantId, - ruleId, - transactionsCriteria - ); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RerecognizeTransactionsJob.ts b/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RerecognizeTransactionsJob.ts deleted file mode 100644 index 1c50a1f81..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RerecognizeTransactionsJob.ts +++ /dev/null @@ -1,45 +0,0 @@ -import Container, { Service } from 'typedi'; -import { RecognizeTranasctionsService } from '../RecognizeTranasctionsService'; -import { RevertRecognizedTransactions } from '../RevertRecognizedTransactions'; - -@Service() -export class ReregonizeTransactionsJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'rerecognize-uncategorized-transactions-job', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, ruleId, transactionsCriteria } = job.attrs.data; - const regonizeTransactions = Container.get(RecognizeTranasctionsService); - const revertRegonizedTransactions = Container.get( - RevertRecognizedTransactions - ); - - try { - await revertRegonizedTransactions.revertRecognizedTransactions( - tenantId, - ruleId, - transactionsCriteria - ); - await regonizeTransactions.recognizeTransactions( - tenantId, - ruleId, - transactionsCriteria - ); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RevertRecognizedTransactionsJob.ts b/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RevertRecognizedTransactionsJob.ts deleted file mode 100644 index a1d378675..000000000 --- a/packages/server/src/services/Banking/RegonizeTranasctions/jobs/RevertRecognizedTransactionsJob.ts +++ /dev/null @@ -1,38 +0,0 @@ -import Container, { Service } from 'typedi'; -import { RevertRecognizedTransactions } from '../RevertRecognizedTransactions'; - -@Service() -export class RevertRegonizeTransactionsJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'revert-recognized-uncategorized-transactions-job', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, ruleId, transactionsCriteria } = job.attrs.data; - const revertRegonizedTransactions = Container.get( - RevertRecognizedTransactions - ); - - try { - await revertRegonizedTransactions.revertRecognizedTransactions( - tenantId, - ruleId, - transactionsCriteria - ); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Banking/Rules/BankRulesApplication.ts b/packages/server/src/services/Banking/Rules/BankRulesApplication.ts deleted file mode 100644 index 7beb5e1f4..000000000 --- a/packages/server/src/services/Banking/Rules/BankRulesApplication.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CreateBankRuleService } from './CreateBankRule'; -import { DeleteBankRuleSerivce } from './DeleteBankRule'; -import { EditBankRuleService } from './EditBankRule'; -import { GetBankRuleService } from './GetBankRule'; -import { GetBankRulesService } from './GetBankRules'; -import { ICreateBankRuleDTO, IEditBankRuleDTO } from './types'; - -@Service() -export class BankRulesApplication { - @Inject() - private createBankRuleService: CreateBankRuleService; - - @Inject() - private editBankRuleService: EditBankRuleService; - - @Inject() - private deleteBankRuleService: DeleteBankRuleSerivce; - - @Inject() - private getBankRuleService: GetBankRuleService; - - @Inject() - private getBankRulesService: GetBankRulesService; - - /** - * Creates new bank rule. - * @param {number} tenantId - * @param {ICreateBankRuleDTO} createRuleDTO - * @returns {Promise} - */ - public createBankRule( - tenantId: number, - createRuleDTO: ICreateBankRuleDTO - ): Promise { - return this.createBankRuleService.createBankRule(tenantId, createRuleDTO); - } - - /** - * Edits the given bank rule. - * @param {number} tenantId - * @param {IEditBankRuleDTO} editRuleDTO - * @returns {Promise} - */ - public editBankRule( - tenantId: number, - ruleId: number, - editRuleDTO: IEditBankRuleDTO - ): Promise { - return this.editBankRuleService.editBankRule(tenantId, ruleId, editRuleDTO); - } - - /** - * Deletes the given bank rule. - * @param {number} tenantId - * @param {number} ruleId - * @returns {Promise} - */ - public deleteBankRule(tenantId: number, ruleId: number): Promise { - return this.deleteBankRuleService.deleteBankRule(tenantId, ruleId); - } - - /** - * Retrieves the given bank rule. - * @param {number} tenantId - * @param {number} ruleId - * @returns {Promise} - */ - public getBankRule(tenantId: number, ruleId: number): Promise { - return this.getBankRuleService.getBankRule(tenantId, ruleId); - } - - /** - * Retrieves the bank rules of the given account. - * @param {number} tenantId - * @param {number} accountId - * @returns {Promise} - */ - public getBankRules(tenantId: number): Promise { - return this.getBankRulesService.getBankRules(tenantId); - } -} diff --git a/packages/server/src/services/Banking/Rules/CreateBankRule.ts b/packages/server/src/services/Banking/Rules/CreateBankRule.ts deleted file mode 100644 index 1ca3a99e6..000000000 --- a/packages/server/src/services/Banking/Rules/CreateBankRule.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { - IBankRuleEventCreatedPayload, - IBankRuleEventCreatingPayload, - ICreateBankRuleDTO, -} from './types'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; - -@Service() -export class CreateBankRuleService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Transformes the DTO to model. - * @param {ICreateBankRuleDTO} createDTO - * @returns - */ - private transformDTO(createDTO: ICreateBankRuleDTO) { - return { - ...createDTO, - }; - } - - /** - * Creates a new bank rule. - * @param {number} tenantId - * @param {ICreateBankRuleDTO} createRuleDTO - * @returns {Promise} - */ - public createBankRule( - tenantId: number, - createRuleDTO: ICreateBankRuleDTO - ): Promise { - const { BankRule } = this.tenancy.models(tenantId); - - const transformDTO = this.transformDTO(createRuleDTO); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBankRuleCreating` event. - await this.eventPublisher.emitAsync(events.bankRules.onCreating, { - tenantId, - createRuleDTO, - trx, - } as IBankRuleEventCreatingPayload); - - const bankRule = await BankRule.query(trx).upsertGraph({ - ...transformDTO, - }); - - // Triggers `onBankRuleCreated` event. - await this.eventPublisher.emitAsync(events.bankRules.onCreated, { - tenantId, - createRuleDTO, - bankRule, - trx, - } as IBankRuleEventCreatedPayload); - - return bankRule; - }); - } -} diff --git a/packages/server/src/services/Banking/Rules/DeleteBankRule.ts b/packages/server/src/services/Banking/Rules/DeleteBankRule.ts deleted file mode 100644 index 3981059c9..000000000 --- a/packages/server/src/services/Banking/Rules/DeleteBankRule.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { - IBankRuleEventDeletedPayload, - IBankRuleEventDeletingPayload, -} from './types'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class DeleteBankRuleSerivce { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Deletes the given bank rule. - * @param {number} tenantId - * @param {number} ruleId - * @returns {Promise} - */ - public async deleteBankRule( - tenantId: number, - ruleId: number, - trx?: Knex.Transaction - ): Promise { - const { BankRule, BankRuleCondition } = this.tenancy.models(tenantId); - - const oldBankRule = await BankRule.query() - .findById(ruleId) - .throwIfNotFound(); - - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onBankRuleDeleting` event. - await this.eventPublisher.emitAsync(events.bankRules.onDeleting, { - tenantId, - oldBankRule, - ruleId, - trx, - } as IBankRuleEventDeletingPayload); - - await BankRuleCondition.query(trx).where('ruleId', ruleId).delete() - await BankRule.query(trx).findById(ruleId).delete(); - - // Triggers `onBankRuleDeleted` event. - await await this.eventPublisher.emitAsync(events.bankRules.onDeleted, { - tenantId, - ruleId, - trx, - } as IBankRuleEventDeletedPayload); - }, - trx - ); - } -} diff --git a/packages/server/src/services/Banking/Rules/DeleteBankRules.ts b/packages/server/src/services/Banking/Rules/DeleteBankRules.ts deleted file mode 100644 index 98d17e9cd..000000000 --- a/packages/server/src/services/Banking/Rules/DeleteBankRules.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import PromisePool from '@supercharge/promise-pool'; -import { castArray, uniq } from 'lodash'; -import { DeleteBankRuleSerivce } from './DeleteBankRule'; - -@Service() -export class DeleteBankRulesService { - @Inject() - private deleteBankRuleService: DeleteBankRuleSerivce; - - /** - * Delete bank rules. - * @param {number} tenantId - * @param {number | Array} bankRuleId - */ - async deleteBankRules( - tenantId: number, - bankRuleId: number | Array, - trx?: Knex.Transaction - ) { - const bankRulesIds = uniq(castArray(bankRuleId)); - - const results = await PromisePool.withConcurrency(1) - .for(bankRulesIds) - .process(async (bankRuleId: number) => { - await this.deleteBankRuleService.deleteBankRule( - tenantId, - bankRuleId, - trx - ); - }); - } -} diff --git a/packages/server/src/services/Banking/Rules/EditBankRule.ts b/packages/server/src/services/Banking/Rules/EditBankRule.ts deleted file mode 100644 index 67536ab82..000000000 --- a/packages/server/src/services/Banking/Rules/EditBankRule.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { - IBankRuleEventEditedPayload, - IBankRuleEventEditingPayload, - IEditBankRuleDTO, -} from './types'; - -@Service() -export class EditBankRuleService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * - * @param createDTO - * @returns - */ - private transformDTO(createDTO: IEditBankRuleDTO) { - return { - ...createDTO, - }; - } - - /** - * Edits the given bank rule. - * @param {number} tenantId - * @param {number} ruleId - - * @param {IEditBankRuleDTO} editBankDTO - */ - public async editBankRule( - tenantId: number, - ruleId: number, - editRuleDTO: IEditBankRuleDTO - ) { - const { BankRule } = this.tenancy.models(tenantId); - - const oldBankRule = await BankRule.query() - .findById(ruleId) - .withGraphFetched('conditions') - .throwIfNotFound(); - - const tranformDTO = this.transformDTO(editRuleDTO); - - return this.uow.withTransaction( - tenantId, - async (trx?: Knex.Transaction) => { - // Triggers `onBankRuleEditing` event. - await this.eventPublisher.emitAsync(events.bankRules.onEditing, { - tenantId, - oldBankRule, - ruleId, - editRuleDTO, - trx, - } as IBankRuleEventEditingPayload); - - // Updates the given bank rule. - const bankRule = await BankRule.query(trx).upsertGraphAndFetch({ - ...tranformDTO, - id: ruleId, - }); - // Triggers `onBankRuleEdited` event. - await this.eventPublisher.emitAsync(events.bankRules.onEdited, { - tenantId, - oldBankRule, - bankRule, - ruleId, - editRuleDTO, - trx, - } as IBankRuleEventEditedPayload); - } - ); - } -} diff --git a/packages/server/src/services/Banking/Rules/GetBankRule.ts b/packages/server/src/services/Banking/Rules/GetBankRule.ts deleted file mode 100644 index b06b4f15d..000000000 --- a/packages/server/src/services/Banking/Rules/GetBankRule.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { BankRule } from '@/models/BankRule'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { GetBankRuleTransformer } from './GetBankRuleTransformer'; - -@Service() -export class GetBankRuleService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the bank rule. - * @param {number} tenantId - * @param {number} ruleId - * @returns {Promise} - */ - async getBankRule(tenantId: number, ruleId: number): Promise { - const { BankRule } = this.tenancy.models(tenantId); - - const bankRule = await BankRule.query() - .findById(ruleId) - .withGraphFetched('conditions') - .withGraphFetched('assignAccount'); - - return this.transformer.transform( - tenantId, - bankRule, - new GetBankRuleTransformer() - ); - } -} diff --git a/packages/server/src/services/Banking/Rules/GetBankRuleTransformer.ts b/packages/server/src/services/Banking/Rules/GetBankRuleTransformer.ts deleted file mode 100644 index 93cb6cab5..000000000 --- a/packages/server/src/services/Banking/Rules/GetBankRuleTransformer.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetBankRuleTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return []; - }; -} diff --git a/packages/server/src/services/Banking/Rules/GetBankRules.ts b/packages/server/src/services/Banking/Rules/GetBankRules.ts deleted file mode 100644 index fdf34fb2c..000000000 --- a/packages/server/src/services/Banking/Rules/GetBankRules.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { GetBankRulesTransformer } from './GetBankRulesTransformer'; - -@Service() -export class GetBankRulesService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the bank rules of the given account. - * @param {number} tenantId - * @param {number} accountId - * @returns {Promise} - */ - public async getBankRules(tenantId: number): Promise { - const { BankRule } = this.tenancy.models(tenantId); - - const bankRule = await BankRule.query() - .withGraphFetched('conditions') - .withGraphFetched('assignAccount'); - - return this.transformer.transform( - tenantId, - bankRule, - new GetBankRulesTransformer() - ); - } -} diff --git a/packages/server/src/services/Banking/Rules/GetBankRulesTransformer.ts b/packages/server/src/services/Banking/Rules/GetBankRulesTransformer.ts deleted file mode 100644 index 0a5767652..000000000 --- a/packages/server/src/services/Banking/Rules/GetBankRulesTransformer.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { getCashflowTransactionFormattedType } from '@/utils/transactions-types'; - -export class GetBankRulesTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'assignAccountName', - 'assignCategoryFormatted', - 'conditionsFormatted', - ]; - }; - - /** - * Get the assign account name. - * @param bankRule - * @returns {string} - */ - protected assignAccountName(bankRule: any) { - return bankRule.assignAccount.name; - } - - /** - * Assigned category formatted. - * @returns {string} - */ - protected assignCategoryFormatted(bankRule: any) { - return getCashflowTransactionFormattedType(bankRule.assignCategory); - } - - /** - * Get the bank rule formatted conditions. - * @param bankRule - * @returns {string} - */ - protected conditionsFormatted(bankRule: any) { - return bankRule.conditions - .map((condition) => { - const field = - condition.field.charAt(0).toUpperCase() + condition.field.slice(1); - - return `${field} ${condition.comparator} ${condition.value}`; - }) - .join(bankRule.conditionsType === 'and' ? ' and ' : ' or '); - } -} diff --git a/packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts b/packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts deleted file mode 100644 index 42778e968..000000000 --- a/packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IBankRuleEventDeletingPayload } from '../types'; -import { RevertRecognizedTransactions } from '../../RegonizeTranasctions/RevertRecognizedTransactions'; - -@Service() -export class UnlinkBankRuleOnDeleteBankRule { - @Inject() - private revertRecognizedTransactionsService: RevertRecognizedTransactions; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.bankRules.onDeleting, - this.unlinkBankRuleOutRecognizedTransactionsOnRuleDeleting.bind(this) - ); - } - - /** - * Unlinks the bank rule out of recognized transactions. - * @param {IBankRuleEventDeletingPayload} payload - - */ - private async unlinkBankRuleOutRecognizedTransactionsOnRuleDeleting({ - tenantId, - ruleId, - }: IBankRuleEventDeletingPayload) { - await this.revertRecognizedTransactionsService.revertRecognizedTransactions( - tenantId, - ruleId - ); - } -} diff --git a/packages/server/src/services/Banking/Rules/types.ts b/packages/server/src/services/Banking/Rules/types.ts deleted file mode 100644 index 49e71abf5..000000000 --- a/packages/server/src/services/Banking/Rules/types.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Knex } from 'knex'; - -export enum BankRuleConditionField { - Amount = 'amount', - Description = 'description', - Payee = 'payee', -} - -export enum BankRuleConditionComparator { - Contains = 'contains', - Equals = 'equals', - Equal = 'equal', - NotContain = 'not_contain', - Bigger = 'bigger', - BiggerOrEqual = 'bigger_or_equal', - Smaller = 'smaller', - SmallerOrEqual = 'smaller_or_equal', -} - -export interface IBankRuleCondition { - id?: number; - field: BankRuleConditionField; - comparator: BankRuleConditionComparator; - value: string; -} - -export enum BankRuleConditionType { - Or = 'or', - And = 'and', -} - -export enum BankRuleApplyIfTransactionType { - Deposit = 'deposit', - Withdrawal = 'withdrawal', -} - -export interface IBankRule { - id?: number; - name: string; - order?: number; - applyIfAccountId: number; - applyIfTransactionType: BankRuleApplyIfTransactionType; - - conditionsType: BankRuleConditionType; - conditions: IBankRuleCondition[]; - - assignCategory: BankRuleAssignCategory; - assignAccountId: number; - assignPayee?: string; - assignMemo?: string; -} - -export enum BankRuleAssignCategory { - InterestIncome = 'InterestIncome', - OtherIncome = 'OtherIncome', - Deposit = 'Deposit', - Expense = 'Expense', - OwnerDrawings = 'OwnerDrawings', -} - -export interface IBankRuleConditionDTO { - id?: number; - field: string; - comparator: - | 'contains' - | 'equals' - | 'not_contains' - | 'equal' - | 'bigger' - | 'bigger_or_equal' - | 'smaller' - | 'smaller_or_equal'; - value: number; -} - -export interface IBankRuleCommonDTO { - name: string; - order?: number; - applyIfAccountId: number; - applyIfTransactionType: string; - - conditions: IBankRuleConditionDTO[]; - - assignCategory: BankRuleAssignCategory; - assignAccountId: number; - assignPayee?: string; - assignMemo?: string; -} - -export interface ICreateBankRuleDTO extends IBankRuleCommonDTO {} -export interface IEditBankRuleDTO extends IBankRuleCommonDTO {} - -export interface IBankRuleEventCreatingPayload { - tenantId: number; - createRuleDTO: ICreateBankRuleDTO; - trx?: Knex.Transaction; -} -export interface IBankRuleEventCreatedPayload { - tenantId: number; - createRuleDTO: ICreateBankRuleDTO; - bankRule: IBankRule; - trx?: Knex.Transaction; -} - -export interface IBankRuleEventEditingPayload { - tenantId: number; - ruleId: number; - oldBankRule: any; - editRuleDTO: IEditBankRuleDTO; - trx?: Knex.Transaction; -} -export interface IBankRuleEventEditedPayload { - tenantId: number; - ruleId: number; - oldBankRule: IBankRule; - bankRule: IBankRule; - editRuleDTO: IEditBankRuleDTO; - trx?: Knex.Transaction; -} - -export interface IBankRuleEventDeletingPayload { - tenantId: number; - oldBankRule: any; - ruleId: number; - trx?: Knex.Transaction; -} -export interface IBankRuleEventDeletedPayload { - tenantId: number; - ruleId: number; - trx?: Knex.Transaction; -} diff --git a/packages/server/src/services/Branches/ActivateBranches.ts b/packages/server/src/services/Branches/ActivateBranches.ts deleted file mode 100644 index b642ab359..000000000 --- a/packages/server/src/services/Branches/ActivateBranches.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IBranchesActivatedPayload, - IBranchesActivatePayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { CreateBranch } from './CreateBranch'; -import { BranchesSettings } from './BranchesSettings'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ActivateBranches { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private createBranch: CreateBranch; - - @Inject() - private branchesSettings: BranchesSettings; - - /** - * Throws service error if multi-branches feature is already activated. - * @param {boolean} isActivated - */ - private throwIfMultiBranchesActivated = (isActivated: boolean) => { - if (isActivated) { - throw new ServiceError(ERRORS.MUTLI_BRANCHES_ALREADY_ACTIVATED); - } - }; - - /** - * Creates a new initial branch. - * @param {number} tenantId - */ - private createInitialBranch = (tenantId: number) => { - const { __ } = this.tenancy.i18n(tenantId); - - return this.createBranch.createBranch(tenantId, { - name: __('branches.head_branch'), - code: '10001', - primary: true, - }); - }; - - /** - * Activate multi-branches feature. - * @param {number} tenantId - * @returns {Promise} - */ - public activateBranches = (tenantId: number): Promise => { - const isActivated = this.branchesSettings.isMultiBranchesActive(tenantId); - - // Throw error if mutli-branches is already activated. - this.throwIfMultiBranchesActivated(isActivated); - - // Activate multi-branches under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBranchActivate` branch. - await this.eventPublisher.emitAsync(events.branch.onActivate, { - tenantId, - trx, - } as IBranchesActivatePayload); - - // Create a new branch as primary branch. - const primaryBranch = await this.createInitialBranch(tenantId); - - // Mark the mutli-branches is activated. - await this.branchesSettings.markMultiBranchesAsActivated(tenantId); - - // Triggers `onBranchActivated` branch. - await this.eventPublisher.emitAsync(events.branch.onActivated, { - tenantId, - primaryBranch, - trx, - } as IBranchesActivatedPayload); - }); - }; -} diff --git a/packages/server/src/services/Branches/BranchIntegrationErrorsMiddleware.ts b/packages/server/src/services/Branches/BranchIntegrationErrorsMiddleware.ts deleted file mode 100644 index 96a35bf43..000000000 --- a/packages/server/src/services/Branches/BranchIntegrationErrorsMiddleware.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import { ServiceError } from '@/exceptions'; - -/** - * Handles branches integration service errors. - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ -export function BranchIntegrationErrorsMiddleware( - error: Error, - req: Request, - res: Response, - next: NextFunction -) { - if (error instanceof ServiceError) { - if (error.errorType === 'WAREHOUSE_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'WAREHOUSE_ID_NOT_FOUND', code: 5000 }], - }); - } - if (error.errorType === 'BRANCH_ID_REQUIRED') { - return res.boom.badRequest(null, { - errors: [{ type: 'BRANCH_ID_REQUIRED', code: 5100 }], - }); - } - if (error.errorType === 'BRANCH_ID_NOT_FOUND') { - return res.boom.badRequest(null, { - errors: [{ type: 'BRANCH_ID_NOT_FOUND', code: 5300 }], - }); - } - } - next(error); -} diff --git a/packages/server/src/services/Branches/BranchValidate.ts b/packages/server/src/services/Branches/BranchValidate.ts deleted file mode 100644 index 836787525..000000000 --- a/packages/server/src/services/Branches/BranchValidate.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -@Service() -export class BranchValidator { - @Inject() - tenancy: HasTenancyService; - - public validateBranchNotOnlyWarehouse = async ( - tenantId: number, - branchId: number - ) => { - const { Branch } = this.tenancy.models(tenantId); - - const warehouses = await Branch.query().whereNot('id', branchId); - - if (warehouses.length === 0) { - throw new ServiceError(ERRORS.COULD_NOT_DELETE_ONLY_BRANCH); - } - }; - - /** - * Validates the given branch whether is unique. - * @param {number} tenantId - * @param {string} code - * @param {number} exceptBranchId - */ - public validateBranchCodeUnique = async ( - tenantId: number, - code: string, - exceptBranchId?: number - ): Promise => { - const { Branch } = this.tenancy.models(tenantId); - - const branch = await Branch.query() - .onBuild((query) => { - query.select(['id']); - query.where('code', code); - - if (exceptBranchId) { - query.whereNot('id', exceptBranchId); - } - }) - .first(); - - if (branch) { - throw new ServiceError(ERRORS.BRANCH_CODE_NOT_UNIQUE); - } - }; -} diff --git a/packages/server/src/services/Branches/BranchesApplication.ts b/packages/server/src/services/Branches/BranchesApplication.ts deleted file mode 100644 index 247a444c8..000000000 --- a/packages/server/src/services/Branches/BranchesApplication.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { IBranch, ICreateBranchDTO, IEditBranchDTO } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import { ActivateBranches } from './ActivateBranches'; -import { CreateBranch } from './CreateBranch'; -import { DeleteBranch } from './DeleteBranch'; -import { EditBranch } from './EditBranch'; -import { GetBranch } from './GetBranch'; -import { GetBranches } from './GetBranches'; -import { MarkBranchAsPrimary } from './MarkBranchAsPrimary'; - -@Service() -export class BranchesApplication { - @Inject() - private deleteBranchService: DeleteBranch; - - @Inject() - private createBranchService: CreateBranch; - - @Inject() - private getBranchService: GetBranch; - - @Inject() - private editBranchService: EditBranch; - - @Inject() - private getBranchesService: GetBranches; - - @Inject() - private activateBranchesService: ActivateBranches; - - @Inject() - private markBranchAsPrimaryService: MarkBranchAsPrimary; - - /** - * Retrieves branches list. - * @param {number} tenantId - * @returns {IBranch} - */ - public getBranches = (tenantId: number): Promise => { - return this.getBranchesService.getBranches(tenantId); - }; - - /** - * Retrieves the given branch details. - * @param {number} tenantId - Tenant id. - * @param {number} branchId - Branch id. - * @returns {Promise} - */ - public getBranch = (tenantId: number, branchId: number): Promise => { - return this.getBranchService.getBranch(tenantId, branchId); - }; - - /** - * Creates a new branch. - * @param {number} tenantId - - * @param {ICreateBranchDTO} createBranchDTO - * @returns {Promise} - */ - public createBranch = ( - tenantId: number, - createBranchDTO: ICreateBranchDTO - ): Promise => { - return this.createBranchService.createBranch(tenantId, createBranchDTO); - }; - - /** - * Edits the given branch. - * @param {number} tenantId - Tenant id. - * @param {number} branchId - Branch id. - * @param {IEditBranchDTO} editBranchDTO - Edit branch DTO. - * @returns {Promise} - */ - public editBranch = ( - tenantId: number, - branchId: number, - editBranchDTO: IEditBranchDTO - ): Promise => { - return this.editBranchService.editBranch(tenantId, branchId, editBranchDTO); - }; - - /** - * Deletes the given branch. - * @param {number} tenantId - Tenant id. - * @param {number} branchId - Branch id. - * @returns {Promise} - */ - public deleteBranch = (tenantId: number, branchId: number): Promise => { - return this.deleteBranchService.deleteBranch(tenantId, branchId); - }; - - /** - * Activates the given branches. - * @param {number} tenantId - Tenant id. - * @returns {Promise} - */ - public activateBranches = (tenantId: number): Promise => { - return this.activateBranchesService.activateBranches(tenantId); - }; - - /** - * Marks the given branch as primary. - * @param {number} tenantId - * @param {number} branchId - * @returns {Promise} - */ - public markBranchAsPrimary = async ( - tenantId: number, - branchId: number - ): Promise => { - return this.markBranchAsPrimaryService.markAsPrimary(tenantId, branchId); - }; -} diff --git a/packages/server/src/services/Branches/BranchesSettings.ts b/packages/server/src/services/Branches/BranchesSettings.ts deleted file mode 100644 index ee1d6c1b9..000000000 --- a/packages/server/src/services/Branches/BranchesSettings.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Features } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class BranchesSettings { - @Inject() - private tenancy: HasTenancyService; - - /** - * Marks multi-branches as activated. - * @param {number} tenantId - - */ - public markMultiBranchesAsActivated = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); - - settings.set({ group: 'features', key: Features.BRANCHES, value: 1 }); - }; - - /** - * Retrieves whether multi-branches is active. - * @param {number} tenantId - */ - public isMultiBranchesActive = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); - - return settings.get({ group: 'features', key: Features.BRANCHES }); - }; -} diff --git a/packages/server/src/services/Branches/CRUDBranch.ts b/packages/server/src/services/Branches/CRUDBranch.ts deleted file mode 100644 index 3895c5eae..000000000 --- a/packages/server/src/services/Branches/CRUDBranch.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject } from "typedi"; -import { ServiceError } from "exceptions"; -import HasTenancyService from "services/Tenancy/TenancyService"; -import { ERRORS } from "./constants"; - -export class CURDBranch { - @Inject() - tenancy: HasTenancyService; - - /** - * - * @param branch - */ - throwIfBranchNotFound = (branch) => { - if (!branch) { - throw new ServiceError(ERRORS.BRANCH_NOT_FOUND); - } - } - - getBranchOrThrowNotFound = async (tenantId: number, branchId: number) => { - const { Branch } = this.tenancy.models(tenantId); - - const foundBranch = await Branch.query().findById(branchId); - - if (!foundBranch) { - throw new ServiceError(ERRORS.BRANCH_NOT_FOUND); - } - return foundBranch; - } -} \ No newline at end of file diff --git a/packages/server/src/services/Branches/CreateBranch.ts b/packages/server/src/services/Branches/CreateBranch.ts deleted file mode 100644 index 5de58aaa5..000000000 --- a/packages/server/src/services/Branches/CreateBranch.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - IBranch, - IBranchCreatedPayload, - IBranchCreatePayload, - ICreateBranchDTO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { BranchValidator } from './BranchValidate'; - -@Service() -export class CreateBranch { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private validator: BranchValidator; - - /** - * Creates a new branch. - * @param {number} tenantId - * @param {ICreateBranchDTO} createBranchDTO - * @returns {Promise} - */ - public createBranch = ( - tenantId: number, - createBranchDTO: ICreateBranchDTO - ): Promise => { - const { Branch } = this.tenancy.models(tenantId); - - // Creates a new branch under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBranchCreate` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdit, { - tenantId, - createBranchDTO, - trx, - } as IBranchCreatePayload); - - const branch = await Branch.query().insertAndFetch({ - ...createBranchDTO, - }); - // Triggers `onBranchCreated` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdited, { - tenantId, - createBranchDTO, - branch, - trx, - } as IBranchCreatedPayload); - - return branch; - }); - }; -} diff --git a/packages/server/src/services/Branches/DeleteBranch.ts b/packages/server/src/services/Branches/DeleteBranch.ts deleted file mode 100644 index 738cf297e..000000000 --- a/packages/server/src/services/Branches/DeleteBranch.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { IBranchDeletedPayload, IBranchDeletePayload } from '@/interfaces'; -import { CURDBranch } from './CRUDBranch'; -import { BranchValidator } from './BranchValidate'; -import { ERRORS } from './constants'; - -@Service() -export class DeleteBranch extends CURDBranch { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private validator: BranchValidator; - - /** - * Validates the branch deleteing. - * @param {number} tenantId - * @param {number} branchId - * @returns {Promise} - */ - private authorize = async (tenantId: number, branchId: number) => { - await this.validator.validateBranchNotOnlyWarehouse(tenantId, branchId); - }; - - /** - * Deletes branch. - * @param {number} tenantId - * @param {number} branchId - * @returns {Promise} - */ - public deleteBranch = async ( - tenantId: number, - branchId: number - ): Promise => { - const { Branch } = this.tenancy.models(tenantId); - - // Retrieves the old branch or throw not found service error. - const oldBranch = await Branch.query() - .findById(branchId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.BRANCH_HAS_ASSOCIATED_TRANSACTIONS, - }); - // Authorize the branch before deleting. - await this.authorize(tenantId, branchId); - - // Deletes branch under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBranchCreate` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdit, { - tenantId, - oldBranch, - trx, - } as IBranchDeletePayload); - - await Branch.query().findById(branchId).delete(); - - // Triggers `onBranchCreate` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdited, { - tenantId, - oldBranch, - trx, - } as IBranchDeletedPayload); - }); - }; -} diff --git a/packages/server/src/services/Branches/EditBranch.ts b/packages/server/src/services/Branches/EditBranch.ts deleted file mode 100644 index e59f6cd8a..000000000 --- a/packages/server/src/services/Branches/EditBranch.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - IBranchEditedPayload, - IBranchEditPayload, - IEditBranchDTO, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { CURDBranch } from './CRUDBranch'; -import events from '@/subscribers/events'; - -@Service() -export class EditBranch extends CURDBranch { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Edits branch. - * @param {number} tenantId - * @param {number} branchId - * @param editBranchDTO - */ - public editBranch = async ( - tenantId: number, - branchId: number, - editBranchDTO: IEditBranchDTO - ) => { - const { Branch } = this.tenancy.models(tenantId); - - // Retrieves the old branch or throw not found service error. - const oldBranch = await this.getBranchOrThrowNotFound(tenantId, branchId); - - // Deletes branch under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBranchEdit` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdit, { - tenantId, - oldBranch, - trx, - } as IBranchEditPayload); - - // Edits the branch on the storage. - const branch = await Branch.query().patchAndFetchById(branchId, { - ...editBranchDTO, - }); - // Triggers `onBranchEdited` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdited, { - tenantId, - oldBranch, - branch, - trx, - } as IBranchEditedPayload); - - return branch; - }); - }; -} diff --git a/packages/server/src/services/Branches/EventsProvider.ts b/packages/server/src/services/Branches/EventsProvider.ts deleted file mode 100644 index e86d03b62..000000000 --- a/packages/server/src/services/Branches/EventsProvider.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - CreditNoteActivateBranchesSubscriber, - PaymentReceiveActivateBranchesSubscriber, - SaleEstimatesActivateBranchesSubscriber, - SaleInvoicesActivateBranchesSubscriber, - PaymentMadeActivateBranchesSubscriber, - SaleReceiptsActivateBranchesSubscriber, -} from './Subscribers/Activate'; -import { - BillBranchValidateSubscriber, - VendorCreditBranchValidateSubscriber, - PaymentMadeBranchValidateSubscriber, - SaleEstimateBranchValidateSubscriber, - CreditNoteBranchValidateSubscriber, - ExpenseBranchValidateSubscriber, - SaleReceiptBranchValidateSubscriber, - ManualJournalBranchValidateSubscriber, - PaymentReceiveBranchValidateSubscriber, - CreditNoteRefundBranchValidateSubscriber, - CashflowBranchDTOValidatorSubscriber, - VendorCreditRefundBranchValidateSubscriber, - InvoiceBranchValidateSubscriber, - ContactBranchValidateSubscriber, - InventoryAdjustmentBranchValidateSubscriber -} from './Subscribers/Validators'; - -export default () => [ - BillBranchValidateSubscriber, - CreditNoteBranchValidateSubscriber, - ExpenseBranchValidateSubscriber, - PaymentMadeBranchValidateSubscriber, - SaleReceiptBranchValidateSubscriber, - VendorCreditBranchValidateSubscriber, - SaleEstimateBranchValidateSubscriber, - ManualJournalBranchValidateSubscriber, - PaymentReceiveBranchValidateSubscriber, - CreditNoteRefundBranchValidateSubscriber, - VendorCreditRefundBranchValidateSubscriber, - - CreditNoteActivateBranchesSubscriber, - PaymentReceiveActivateBranchesSubscriber, - SaleEstimatesActivateBranchesSubscriber, - SaleInvoicesActivateBranchesSubscriber, - PaymentMadeActivateBranchesSubscriber, - SaleReceiptsActivateBranchesSubscriber, - CashflowBranchDTOValidatorSubscriber, - InvoiceBranchValidateSubscriber, - ContactBranchValidateSubscriber, - InventoryAdjustmentBranchValidateSubscriber -]; diff --git a/packages/server/src/services/Branches/GetBranch.ts b/packages/server/src/services/Branches/GetBranch.ts deleted file mode 100644 index 777947361..000000000 --- a/packages/server/src/services/Branches/GetBranch.ts +++ /dev/null @@ -1,26 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import { CURDBranch } from './CRUDBranch'; - -@Service() -export class GetBranch extends CURDBranch{ - @Inject() - tenancy: HasTenancyService; - - /** - * - * @param {number} tenantId - * @param {number} branchId - * @returns - */ - public getBranch = async (tenantId: number, branchId: number) => { - const { Branch } = this.tenancy.models(tenantId); - - const branch = await Branch.query().findById(branchId); - - // Throw not found service error if the branch not found. - this.throwIfBranchNotFound(branch); - - return branch; - }; -} diff --git a/packages/server/src/services/Branches/GetBranches.ts b/packages/server/src/services/Branches/GetBranches.ts deleted file mode 100644 index 33ccb8d8c..000000000 --- a/packages/server/src/services/Branches/GetBranches.ts +++ /dev/null @@ -1,22 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; - -@Service() -export class GetBranches { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieves branches list. - * @param {number} tenantId - * @param {number} branchId - * @returns - */ - public getBranches = async (tenantId: number) => { - const { Branch } = this.tenancy.models(tenantId); - - const branches = await Branch.query().orderBy('name', 'DESC'); - - return branches; - }; -} diff --git a/packages/server/src/services/Branches/Integrations/BranchTransactionDTOTransform.ts b/packages/server/src/services/Branches/Integrations/BranchTransactionDTOTransform.ts deleted file mode 100644 index 57f5f5a71..000000000 --- a/packages/server/src/services/Branches/Integrations/BranchTransactionDTOTransform.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit } from 'lodash'; -import { BranchesSettings } from '../BranchesSettings'; - -@Service() -export class BranchTransactionDTOTransform { - @Inject() - branchesSettings: BranchesSettings; - - /** - * Excludes DTO branch id when mutli-warehouses feature is inactive. - * @param {number} tenantId - * @returns {any} - */ - private excludeDTOBranchIdWhenInactive = ( - tenantId: number, - DTO: T - ): Omit | T => { - const isActive = this.branchesSettings.isMultiBranchesActive(tenantId); - - return !isActive ? omit(DTO, ['branchId']) : DTO; - }; - - /** - * Transformes the input DTO for branches feature. - * @param {number} tenantId - - * @param {T} DTO - - * @returns {Omit | T} - */ - public transformDTO = - (tenantId: number) => - (DTO: T): Omit | T => { - return this.excludeDTOBranchIdWhenInactive(tenantId, DTO); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Cashflow/CashflowActivateBranches.ts b/packages/server/src/services/Branches/Integrations/Cashflow/CashflowActivateBranches.ts deleted file mode 100644 index 9f1c148aa..000000000 --- a/packages/server/src/services/Branches/Integrations/Cashflow/CashflowActivateBranches.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class CashflowTransactionsActivateBranches { - @Inject() - private tenancy: HasTenancyService; - - /** - * Updates all cashflow transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateCashflowTransactionsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { CashflowTransaction } = this.tenancy.models(tenantId); - - // Updates the cashflow transactions with primary branch. - await CashflowTransaction.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Expense/ExpensesActivateBranches.ts b/packages/server/src/services/Branches/Integrations/Expense/ExpensesActivateBranches.ts deleted file mode 100644 index 6601235d3..000000000 --- a/packages/server/src/services/Branches/Integrations/Expense/ExpensesActivateBranches.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ExpensesActivateBranches { - @Inject() - private tenancy: HasTenancyService; - - /** - * Updates all expenses transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateExpensesWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { Expense } = this.tenancy.models(tenantId); - - // Updates the expenses with primary branch. - await Expense.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalBranchesActivate.ts deleted file mode 100644 index 5113b25d9..000000000 --- a/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class ManualJournalsActivateBranches { - @Inject() - private tenancy: HasTenancyService; - - /** - * Updates all manual journals transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateManualJournalsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { ManualJournal } = this.tenancy.models(tenantId); - - // Updates the manual journal with primary branch. - await ManualJournal.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer.ts b/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer.ts deleted file mode 100644 index a6f3cab4a..000000000 --- a/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { omit } from 'lodash'; -import { Inject, Service } from 'typedi'; -import { IManualJournal } from '@/interfaces'; -import { BranchesSettings } from '../../BranchesSettings'; - -@Service() -export class ManualJournalBranchesDTOTransformer { - @Inject() - branchesSettings: BranchesSettings; - - private excludeDTOBranchIdWhenInactive = ( - tenantId: number, - DTO: IManualJournal - ): IManualJournal => { - const isActive = this.branchesSettings.isMultiBranchesActive(tenantId); - - if (isActive) return DTO; - - return { - ...DTO, - entries: DTO.entries.map((e) => omit(e, ['branchId'])), - }; - }; - /** - * - */ - public transformDTO = - (tenantId: number) => - (DTO: IManualJournal): IManualJournal => { - return this.excludeDTOBranchIdWhenInactive(tenantId, DTO); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalsBranchesValidator.ts b/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalsBranchesValidator.ts deleted file mode 100644 index ed3628d50..000000000 --- a/packages/server/src/services/Branches/Integrations/ManualJournals/ManualJournalsBranchesValidator.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { IManualJournalDTO, IManualJournalEntryDTO } from '@/interfaces'; -import { ERRORS } from './constants'; - -@Service() -export class ManualJournalBranchesValidator { - /** - * Validates the DTO entries should have branch id. - * @param {IManualJournalDTO} manualJournalDTO - */ - public validateEntriesHasBranchId = async ( - manualJournalDTO: IManualJournalDTO - ) => { - const hasNoIdEntries = manualJournalDTO.entries.filter( - (entry: IManualJournalEntryDTO) => - !entry.branchId && !manualJournalDTO.branchId - ); - if (hasNoIdEntries.length > 0) { - throw new ServiceError(ERRORS.MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID); - } - }; -} diff --git a/packages/server/src/services/Branches/Integrations/ManualJournals/constants.ts b/packages/server/src/services/Branches/Integrations/ManualJournals/constants.ts deleted file mode 100644 index 46e4327e5..000000000 --- a/packages/server/src/services/Branches/Integrations/ManualJournals/constants.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const ERRORS = { - MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID: - 'MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID', -}; diff --git a/packages/server/src/services/Branches/Integrations/Purchases/BillBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Purchases/BillBranchesActivate.ts deleted file mode 100644 index 81af0a4a5..000000000 --- a/packages/server/src/services/Branches/Integrations/Purchases/BillBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class BillActivateBranches { - @Inject() - private tenancy: HasTenancyService; - - /** - * Updates all bills transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateBillsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { Bill } = this.tenancy.models(tenantId); - - // Updates the sale invoice with primary branch. - await Bill.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Purchases/PaymentMadeBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Purchases/PaymentMadeBranchesActivate.ts deleted file mode 100644 index 1c9173966..000000000 --- a/packages/server/src/services/Branches/Integrations/Purchases/PaymentMadeBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class BillPaymentsActivateBranches { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all bills payments transcations with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateBillPaymentsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { BillPayment } = this.tenancy.models(tenantId); - - // Updates the bill payments with primary branch. - await BillPayment.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Purchases/VendorCreditBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Purchases/VendorCreditBranchesActivate.ts deleted file mode 100644 index cd4638723..000000000 --- a/packages/server/src/services/Branches/Integrations/Purchases/VendorCreditBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class VendorCreditActivateBranches { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all vendor credits transcations with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateVendorCreditsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { VendorCredit } = this.tenancy.models(tenantId); - - // Updates the vendors credits with primary branch. - await VendorCredit.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Sales/CreditNoteBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Sales/CreditNoteBranchesActivate.ts deleted file mode 100644 index 7bc115156..000000000 --- a/packages/server/src/services/Branches/Integrations/Sales/CreditNoteBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class CreditNoteActivateBranches { - @Inject() - private tenancy: HasTenancyService; - - /** - * Updates all creidt notes transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateCreditsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { CreditNote } = this.tenancy.models(tenantId); - - // Updates the sale invoice with primary branch. - await CreditNote.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Sales/PaymentReceiveBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Sales/PaymentReceiveBranchesActivate.ts deleted file mode 100644 index c5c8a5f68..000000000 --- a/packages/server/src/services/Branches/Integrations/Sales/PaymentReceiveBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class PaymentReceiveActivateBranches { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all creidt notes transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updatePaymentsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { PaymentReceive } = this.tenancy.models(tenantId); - - // Updates the sale invoice with primary branch. - await PaymentReceive.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Sales/SaleEstimatesBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Sales/SaleEstimatesBranchesActivate.ts deleted file mode 100644 index 269cd82b5..000000000 --- a/packages/server/src/services/Branches/Integrations/Sales/SaleEstimatesBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class SaleEstimateActivateBranches { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all sale estimates transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateEstimatesWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { PaymentReceive } = this.tenancy.models(tenantId); - - // Updates the sale invoice with primary branch. - await PaymentReceive.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Sales/SaleInvoiceBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Sales/SaleInvoiceBranchesActivate.ts deleted file mode 100644 index 243d60c62..000000000 --- a/packages/server/src/services/Branches/Integrations/Sales/SaleInvoiceBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class SaleInvoiceActivateBranches { - @Inject() - private tenancy: HasTenancyService; - - /** - * Updates all sale invoices transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateInvoicesWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Updates the sale invoice with primary branch. - await SaleInvoice.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/Sales/SaleReceiptBranchesActivate.ts b/packages/server/src/services/Branches/Integrations/Sales/SaleReceiptBranchesActivate.ts deleted file mode 100644 index fb487696a..000000000 --- a/packages/server/src/services/Branches/Integrations/Sales/SaleReceiptBranchesActivate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class SaleReceiptActivateBranches { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all sale receipts transactions with the primary branch. - * @param {number} tenantId - * @param {number} primaryBranchId - * @returns {Promise} - */ - public updateReceiptsWithBranch = async ( - tenantId: number, - primaryBranchId: number, - trx?: Knex.Transaction - ) => { - const { SaleReceipt } = this.tenancy.models(tenantId); - - // Updates the sale receipt with primary branch. - await SaleReceipt.query(trx).update({ branchId: primaryBranchId }); - }; -} diff --git a/packages/server/src/services/Branches/Integrations/ValidateBranchExistance.ts b/packages/server/src/services/Branches/Integrations/ValidateBranchExistance.ts deleted file mode 100644 index 9b5d5b1f0..000000000 --- a/packages/server/src/services/Branches/Integrations/ValidateBranchExistance.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import { BranchesSettings } from '../BranchesSettings'; -import { ERRORS } from './constants'; - -@Service() -export class ValidateBranchExistance { - @Inject() - tenancy: HasTenancyService; - - @Inject() - branchesSettings: BranchesSettings; - - /** - * Validate transaction branch id when the feature is active. - * @param {number} tenantId - * @param {number} branchId - * @returns {Promise} - */ - public validateTransactionBranchWhenActive = async ( - tenantId: number, - branchId: number | null - ) => { - const isActive = this.branchesSettings.isMultiBranchesActive(tenantId); - - // Can't continue if the multi-warehouses feature is inactive. - if (!isActive) return; - - return this.validateTransactionBranch(tenantId, branchId); - }; - - /** - * Validate transaction branch id existance. - * @param {number} tenantId - * @param {number} branchId - * @return {Promise} - */ - public validateTransactionBranch = async ( - tenantId: number, - branchId: number | null - ) => { - this.validateBranchIdExistance(branchId); - - await this.validateBranchExistance(tenantId, branchId); - }; - - /** - * - * @param branchId - */ - public validateBranchIdExistance = (branchId: number | null) => { - if (!branchId) { - throw new ServiceError(ERRORS.BRANCH_ID_REQUIRED); - } - }; - - /** - * - * @param tenantId - * @param branchId - */ - public validateBranchExistance = async ( - tenantId: number, - branchId: number - ) => { - const { Branch } = this.tenancy.models(tenantId); - - const branch = await Branch.query().findById(branchId); - - if (!branch) { - throw new ServiceError(ERRORS.BRANCH_ID_NOT_FOUND); - } - }; -} diff --git a/packages/server/src/services/Branches/Integrations/constants.ts b/packages/server/src/services/Branches/Integrations/constants.ts deleted file mode 100644 index af66f6dae..000000000 --- a/packages/server/src/services/Branches/Integrations/constants.ts +++ /dev/null @@ -1,6 +0,0 @@ - - -export const ERRORS = { - BRANCH_ID_REQUIRED: 'BRANCH_ID_REQUIRED', - BRANCH_ID_NOT_FOUND: 'BRANCH_ID_NOT_FOUND' -} \ No newline at end of file diff --git a/packages/server/src/services/Branches/MarkBranchAsPrimary.ts b/packages/server/src/services/Branches/MarkBranchAsPrimary.ts deleted file mode 100644 index 03e733c8f..000000000 --- a/packages/server/src/services/Branches/MarkBranchAsPrimary.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { CURDBranch } from './CRUDBranch'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { - IBranch, - IBranchMarkAsPrimaryPayload, - IBranchMarkedAsPrimaryPayload, -} from '@/interfaces'; - -@Service() -export class MarkBranchAsPrimary extends CURDBranch { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Marks the given branch as primary. - * @param {number} tenantId - * @param {number} branchId - * @returns {Promise} - */ - public markAsPrimary = async ( - tenantId: number, - branchId: number - ): Promise => { - const { Branch } = this.tenancy.models(tenantId); - - // Retrieves the old branch or throw not found service error. - const oldBranch = await this.getBranchOrThrowNotFound(tenantId, branchId); - - // Updates the branches under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBranchMarkPrimary` event. - await this.eventPublisher.emitAsync(events.branch.onMarkPrimary, { - tenantId, - oldBranch, - trx, - } as IBranchMarkAsPrimaryPayload); - - // Updates all branches as not primary. - await Branch.query(trx).update({ primary: false }); - - // Updates the given branch as primary. - const markedBranch = await Branch.query(trx).patchAndFetchById(branchId, { - primary: true, - }); - // Triggers `onBranchMarkedPrimary` event. - await this.eventPublisher.emitAsync(events.branch.onMarkedPrimary, { - tenantId, - markedBranch, - oldBranch, - trx, - } as IBranchMarkedAsPrimaryPayload); - - return markedBranch; - }); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/CashflowBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/CashflowBranchesActivateSubscriber.ts deleted file mode 100644 index 05e27810c..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/CashflowBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { CashflowTransactionsActivateBranches } from '../../Integrations/Cashflow/CashflowActivateBranches'; - -@Service() -export class CreditNoteActivateBranchesSubscriber { - @Inject() - private cashflowActivateBranches: CashflowTransactionsActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateCashflowWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateCashflowWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.cashflowActivateBranches.updateCashflowTransactionsWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts deleted file mode 100644 index 046a806b2..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/CreditNoteBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import { CreditNoteActivateBranches } from '../../Integrations/Sales/CreditNoteBranchesActivate'; -import events from '@/subscribers/events'; - -@Service() -export class CreditNoteActivateBranchesSubscriber { - @Inject() - private creditNotesActivateBranches: CreditNoteActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateCreditNoteWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateCreditNoteWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.creditNotesActivateBranches.updateCreditsWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/ExpenseBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/ExpenseBranchesActivateSubscriber.ts deleted file mode 100644 index 378490801..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/ExpenseBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { ExpensesActivateBranches } from '../../Integrations/Expense/ExpensesActivateBranches'; - -@Service() -export class ExpenseActivateBranchesSubscriber { - @Inject() - private expensesActivateBranches: ExpensesActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateExpensesWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateExpensesWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.expensesActivateBranches.updateExpensesWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts deleted file mode 100644 index 334cff548..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/PaymentMadeBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { BillPaymentsActivateBranches } from '../../Integrations/Purchases/PaymentMadeBranchesActivate'; - -@Service() -export class PaymentMadeActivateBranchesSubscriber { - @Inject() - private paymentsActivateBranches: BillPaymentsActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updatePaymentsWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updatePaymentsWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.paymentsActivateBranches.updateBillPaymentsWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts deleted file mode 100644 index 287abf627..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/PaymentReceiveBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { PaymentReceiveActivateBranches } from '../../Integrations/Sales/PaymentReceiveBranchesActivate'; - -@Service() -export class PaymentReceiveActivateBranchesSubscriber { - @Inject() - private paymentsActivateBranches: PaymentReceiveActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateCreditNoteWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateCreditNoteWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.paymentsActivateBranches.updatePaymentsWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts deleted file mode 100644 index d01b7e235..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/SaleEstiamtesBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleEstimateActivateBranches } from '../../Integrations/Sales/SaleEstimatesBranchesActivate'; - -@Service() -export class SaleEstimatesActivateBranchesSubscriber { - @Inject() - private estimatesActivateBranches: SaleEstimateActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateEstimatesWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateEstimatesWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.estimatesActivateBranches.updateEstimatesWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts deleted file mode 100644 index 89a3ced33..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/SaleInvoiceBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleInvoiceActivateBranches } from '../../Integrations/Sales/SaleInvoiceBranchesActivate'; - -@Service() -export class SaleInvoicesActivateBranchesSubscriber { - @Inject() - private invoicesActivateBranches: SaleInvoiceActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateInvoicesWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateInvoicesWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.invoicesActivateBranches.updateInvoicesWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts deleted file mode 100644 index 95238d98f..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/SaleReceiptsBranchesActivateSubscriber.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IBranchesActivatedPayload } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleReceiptActivateBranches } from '../../Integrations/Sales/SaleReceiptBranchesActivate'; - -@Service() -export class SaleReceiptsActivateBranchesSubscriber { - @Inject() - private receiptsActivateBranches: SaleReceiptActivateBranches; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.branch.onActivated, - this.updateReceiptsWithBranchOnActivated - ); - return bus; - } - - /** - * Updates accounts transactions with the primary branch once - * the multi-branches is activated. - * @param {IBranchesActivatedPayload} - */ - private updateReceiptsWithBranchOnActivated = async ({ - tenantId, - primaryBranch, - trx, - }: IBranchesActivatedPayload) => { - await this.receiptsActivateBranches.updateReceiptsWithBranch( - tenantId, - primaryBranch.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Activate/index.ts b/packages/server/src/services/Branches/Subscribers/Activate/index.ts deleted file mode 100644 index 97aeadcee..000000000 --- a/packages/server/src/services/Branches/Subscribers/Activate/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './CashflowBranchesActivateSubscriber'; -export * from './CreditNoteBranchesActivateSubscriber'; -export * from './PaymentMadeBranchesActivateSubscriber'; -export * from './PaymentReceiveBranchesActivateSubscriber'; -export * from './SaleReceiptsBranchesActivateSubscriber'; -export * from './SaleEstiamtesBranchesActivateSubscriber'; -export * from './SaleInvoiceBranchesActivateSubscriber'; -export * from './ExpenseBranchesActivateSubscriber'; \ No newline at end of file diff --git a/packages/server/src/services/Branches/Subscribers/Validators/BillBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/BillBranchSubscriber.ts deleted file mode 100644 index 898557107..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/BillBranchSubscriber.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IBillCreatingPayload, IBillEditingPayload } from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class BillBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.bill.onCreating, - this.validateBranchExistanceOnBillCreating - ); - bus.subscribe( - events.bill.onEditing, - this.validateBranchExistanceOnBillEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {ISaleEstimateCreatedPayload} payload - */ - private validateBranchExistanceOnBillCreating = async ({ - tenantId, - billDTO, - }: IBillCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - billDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnBillEditing = async ({ - billDTO, - tenantId, - }: IBillEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - billDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts deleted file mode 100644 index 5b8f20bd2..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/CashflowBranchDTOValidatorSubscriber.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { ICommandCashflowCreatingPayload } from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class CashflowBranchDTOValidatorSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.cashflow.onTransactionCreating, - this.validateBranchExistanceOnCashflowTransactionCreating - ); - return bus; - }; - - /** - * Validate branch existance once cashflow transaction creating. - * @param {ICommandCashflowCreatingPayload} payload - */ - private validateBranchExistanceOnCashflowTransactionCreating = async ({ - tenantId, - newTransactionDTO, - }: ICommandCashflowCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - newTransactionDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts deleted file mode 100644 index 6d663ea55..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/ContactOpeningBalanceBranchSubscriber.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ICustomerEventCreatingPayload, - ICustomerOpeningBalanceEditingPayload, - IVendorEventCreatingPayload, - IVendorOpeningBalanceEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class ContactBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.customers.onCreating, - this.validateBranchExistanceOnCustomerCreating - ); - bus.subscribe( - events.customers.onOpeningBalanceChanging, - this.validateBranchExistanceOnCustomerOpeningBalanceEditing - ); - bus.subscribe( - events.vendors.onCreating, - this.validateBranchExistanceonVendorCreating - ); - bus.subscribe( - events.vendors.onOpeningBalanceChanging, - this.validateBranchExistanceOnVendorOpeningBalanceEditing - ); - return bus; - }; - - /** - * Validate branch existance on customer creating. - * @param {ICustomerEventCreatingPayload} payload - */ - private validateBranchExistanceOnCustomerCreating = async ({ - tenantId, - customerDTO, - }: ICustomerEventCreatingPayload) => { - // Can't continue if the customer opening balance is zero. - if (!customerDTO.openingBalance) return; - - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - customerDTO.openingBalanceBranchId - ); - }; - - /** - * Validate branch existance once customer opening balance editing. - * @param {ICustomerOpeningBalanceEditingPayload} payload - */ - private validateBranchExistanceOnCustomerOpeningBalanceEditing = async ({ - openingBalanceEditDTO, - tenantId, - }: ICustomerOpeningBalanceEditingPayload) => { - if (!openingBalanceEditDTO.openingBalance) return; - - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - openingBalanceEditDTO.openingBalanceBranchId - ); - }; - - /** - * Validates the branch existance on vendor creating. - * @param {IVendorEventCreatingPayload} payload - - */ - private validateBranchExistanceonVendorCreating = async ({ - vendorDTO, - tenantId, - }: IVendorEventCreatingPayload) => { - // Can't continue if the customer opening balance is zero. - if (!vendorDTO.openingBalance) return; - - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - vendorDTO.openingBalanceBranchId - ); - }; - - /** - * Validate branch existance once the vendor opening balance editing. - * @param {IVendorOpeningBalanceEditingPayload} - */ - private validateBranchExistanceOnVendorOpeningBalanceEditing = async ({ - tenantId, - openingBalanceEditDTO, - }: IVendorOpeningBalanceEditingPayload) => { - if (!openingBalanceEditDTO.openingBalance) return; - - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - openingBalanceEditDTO.openingBalanceBranchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/CreditNoteBranchesSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/CreditNoteBranchesSubscriber.ts deleted file mode 100644 index a6a07d719..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/CreditNoteBranchesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ICreditNoteCreatingPayload, - ICreditNoteEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class CreditNoteBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.creditNote.onCreating, - this.validateBranchExistanceOnCreditCreating - ); - bus.subscribe( - events.creditNote.onEditing, - this.validateBranchExistanceOnCreditEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {ICreditNoteCreatingPayload} payload - */ - private validateBranchExistanceOnCreditCreating = async ({ - tenantId, - creditNoteDTO, - }: ICreditNoteCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - creditNoteDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnCreditEditing = async ({ - creditNoteEditDTO, - tenantId, - }: ICreditNoteEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - creditNoteEditDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/CreditNoteRefundBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/CreditNoteRefundBranchSubscriber.ts deleted file mode 100644 index 85181b38b..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/CreditNoteRefundBranchSubscriber.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IRefundCreditNoteCreatingPayload } from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class CreditNoteRefundBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.creditNote.onRefundCreating, - this.validateBranchExistanceOnCreditRefundCreating - ); - return bus; - }; - - /** - * Validate branch existance on refund credit note creating. - * @param {ICreditNoteCreatingPayload} payload - */ - private validateBranchExistanceOnCreditRefundCreating = async ({ - tenantId, - newCreditNoteDTO, - }: IRefundCreditNoteCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - newCreditNoteDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/ExpenseBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/ExpenseBranchSubscriber.ts deleted file mode 100644 index afac67563..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/ExpenseBranchSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IExpenseCreatingPayload, - IExpenseEventEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class ExpenseBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.expenses.onCreating, - this.validateBranchExistanceOnExpenseCreating - ); - bus.subscribe( - events.expenses.onEditing, - this.validateBranchExistanceOnExpenseEditing - ); - return bus; - }; - - /** - * Validate branch existance once expense transaction creating. - * @param {ISaleEstimateCreatedPayload} payload - */ - private validateBranchExistanceOnExpenseCreating = async ({ - tenantId, - expenseDTO, - }: IExpenseCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - expenseDTO.branchId - ); - }; - - /** - * Validate branch existance once expense transaction editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnExpenseEditing = async ({ - expenseDTO, - tenantId, - }: IExpenseEventEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - expenseDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts deleted file mode 100644 index f2d8ae206..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/InventoryAdjustmentBranchValidatorSubscriber.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IInventoryAdjustmentCreatingPayload } from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class InventoryAdjustmentBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.inventoryAdjustment.onQuickCreating, - this.validateBranchExistanceOnInventoryCreating - ); - return bus; - }; - - /** - * Validate branch existance on invoice creating. - * @param {ISaleInvoiceCreatingPaylaod} payload - */ - private validateBranchExistanceOnInventoryCreating = async ({ - tenantId, - quickAdjustmentDTO, - }: IInventoryAdjustmentCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - quickAdjustmentDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/InvoiceBranchValidatorSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/InvoiceBranchValidatorSubscriber.ts deleted file mode 100644 index 4dc4d9368..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/InvoiceBranchValidatorSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatingPaylaod, - ISaleInvoiceEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class InvoiceBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.saleInvoice.onCreating, - this.validateBranchExistanceOnInvoiceCreating - ); - bus.subscribe( - events.saleInvoice.onEditing, - this.validateBranchExistanceOnInvoiceEditing - ); - return bus; - }; - - /** - * Validate branch existance on invoice creating. - * @param {ISaleInvoiceCreatingPaylaod} payload - */ - private validateBranchExistanceOnInvoiceCreating = async ({ - tenantId, - saleInvoiceDTO, - }: ISaleInvoiceCreatingPaylaod) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - saleInvoiceDTO.branchId - ); - }; - - /** - * Validate branch existance once invoice editing. - * @param {ISaleInvoiceEditingPayload} payload - */ - private validateBranchExistanceOnInvoiceEditing = async ({ - saleInvoiceDTO, - tenantId, - }: ISaleInvoiceEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - saleInvoiceDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/ManualJournalBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/ManualJournalBranchSubscriber.ts deleted file mode 100644 index dbfab37d1..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/ManualJournalBranchSubscriber.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - Features, - IManualJournalCreatingPayload, - IManualJournalEditingPayload, -} from '@/interfaces'; -import { ManualJournalBranchesValidator } from '../../Integrations/ManualJournals/ManualJournalsBranchesValidator'; -import { FeaturesManager } from '@/services/Features/FeaturesManager'; - -@Service() -export class ManualJournalBranchValidateSubscriber { - @Inject() - private validateManualJournalBranch: ManualJournalBranchesValidator; - - @Inject() - private featuresManager: FeaturesManager; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.manualJournals.onCreating, - this.validateBranchExistanceOnBillCreating - ); - bus.subscribe( - events.manualJournals.onEditing, - this.validateBranchExistanceOnBillEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {IManualJournalCreatingPayload} payload - */ - private validateBranchExistanceOnBillCreating = async ({ - manualJournalDTO, - tenantId, - }: IManualJournalCreatingPayload) => { - // Detarmines whether the multi-branches is accessible by tenant. - const isAccessible = await this.featuresManager.accessible( - tenantId, - Features.BRANCHES - ); - // Can't continue if the multi-branches feature is inactive. - if (!isAccessible) return; - - // Validates the entries whether have branch id. - await this.validateManualJournalBranch.validateEntriesHasBranchId( - manualJournalDTO - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnBillEditing = async ({ - tenantId, - manualJournalDTO, - }: IManualJournalEditingPayload) => { - // Detarmines whether the multi-branches is accessible by tenant. - const isAccessible = await this.featuresManager.accessible( - tenantId, - Features.BRANCHES - ); - // Can't continue if the multi-branches feature is inactive. - if (!isAccessible) return; - - await this.validateManualJournalBranch.validateEntriesHasBranchId( - manualJournalDTO - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/PaymentMadeBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/PaymentMadeBranchSubscriber.ts deleted file mode 100644 index ef76dc320..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/PaymentMadeBranchSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IBillPaymentCreatingPayload, - IBillPaymentEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class PaymentMadeBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.billPayment.onCreating, - this.validateBranchExistanceOnPaymentCreating - ); - bus.subscribe( - events.billPayment.onEditing, - this.validateBranchExistanceOnPaymentEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {ISaleEstimateCreatedPayload} payload - */ - private validateBranchExistanceOnPaymentCreating = async ({ - tenantId, - billPaymentDTO, - }: IBillPaymentCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - billPaymentDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnPaymentEditing = async ({ - billPaymentDTO, - tenantId, - }: IBillPaymentEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - billPaymentDTO.branchId - ); - }; -} \ No newline at end of file diff --git a/packages/server/src/services/Branches/Subscribers/Validators/PaymentReceiveBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/PaymentReceiveBranchSubscriber.ts deleted file mode 100644 index 8aa9b5d6e..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/PaymentReceiveBranchSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IPaymentReceivedCreatingPayload, - IPaymentReceivedEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class PaymentReceiveBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.paymentReceive.onCreating, - this.validateBranchExistanceOnPaymentCreating - ); - bus.subscribe( - events.paymentReceive.onEditing, - this.validateBranchExistanceOnPaymentEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {IPaymentReceivedCreatingPayload} payload - */ - private validateBranchExistanceOnPaymentCreating = async ({ - tenantId, - paymentReceiveDTO, - }: IPaymentReceivedCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - paymentReceiveDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {IPaymentReceivedEditingPayload} payload - */ - private validateBranchExistanceOnPaymentEditing = async ({ - paymentReceiveDTO, - tenantId, - }: IPaymentReceivedEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - paymentReceiveDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts deleted file mode 100644 index 0513ba755..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/SaleEstimateMultiBranchesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleEstimateCreatingPayload, - ISaleEstimateEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class SaleEstimateBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.saleEstimate.onCreating, - this.validateBranchExistanceOnEstimateCreating - ); - bus.subscribe( - events.saleEstimate.onEditing, - this.validateBranchExistanceOnEstimateEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {ISaleEstimateCreatedPayload} payload - */ - private validateBranchExistanceOnEstimateCreating = async ({ - tenantId, - estimateDTO, - }: ISaleEstimateCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - estimateDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnEstimateEditing = async ({ - estimateDTO, - tenantId, - }: ISaleEstimateEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - estimateDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/SaleReceiptBranchesSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/SaleReceiptBranchesSubscriber.ts deleted file mode 100644 index 0cee5987f..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/SaleReceiptBranchesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleReceiptCreatingPayload, - ISaleReceiptEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class SaleReceiptBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.saleReceipt.onCreating, - this.validateBranchExistanceOnInvoiceCreating - ); - bus.subscribe( - events.saleReceipt.onEditing, - this.validateBranchExistanceOnInvoiceEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {ISaleReceiptCreatingPayload} payload - */ - private validateBranchExistanceOnInvoiceCreating = async ({ - tenantId, - saleReceiptDTO, - }: ISaleReceiptCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - saleReceiptDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleReceiptEditingPayload} payload - */ - private validateBranchExistanceOnInvoiceEditing = async ({ - saleReceiptDTO, - tenantId, - }: ISaleReceiptEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - saleReceiptDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/VendorCreditBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/VendorCreditBranchSubscriber.ts deleted file mode 100644 index daea8bc93..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/VendorCreditBranchSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IVendorCreditCreatingPayload, - IVendorCreditEditingPayload, -} from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class VendorCreditBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.vendorCredit.onCreating, - this.validateBranchExistanceOnCreditCreating - ); - bus.subscribe( - events.vendorCredit.onEditing, - this.validateBranchExistanceOnCreditEditing - ); - return bus; - }; - - /** - * Validate branch existance on estimate creating. - * @param {ISaleEstimateCreatedPayload} payload - */ - private validateBranchExistanceOnCreditCreating = async ({ - tenantId, - vendorCreditCreateDTO, - }: IVendorCreditCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - vendorCreditCreateDTO.branchId - ); - }; - - /** - * Validate branch existance once estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private validateBranchExistanceOnCreditEditing = async ({ - vendorCreditDTO, - tenantId, - }: IVendorCreditEditingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - vendorCreditDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/VendorCreditRefundBranchSubscriber.ts b/packages/server/src/services/Branches/Subscribers/Validators/VendorCreditRefundBranchSubscriber.ts deleted file mode 100644 index d191f0353..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/VendorCreditRefundBranchSubscriber.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IRefundVendorCreditCreatingPayload } from '@/interfaces'; -import { ValidateBranchExistance } from '../../Integrations/ValidateBranchExistance'; - -@Service() -export class VendorCreditRefundBranchValidateSubscriber { - @Inject() - private validateBranchExistance: ValidateBranchExistance; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.vendorCredit.onRefundCreating, - this.validateBranchExistanceOnCreditRefundCreating - ); - return bus; - }; - - /** - * Validate branch existance on refund credit note creating. - * @param {IRefundVendorCreditCreatingPayload} payload - */ - private validateBranchExistanceOnCreditRefundCreating = async ({ - tenantId, - refundVendorCreditDTO, - }: IRefundVendorCreditCreatingPayload) => { - await this.validateBranchExistance.validateTransactionBranchWhenActive( - tenantId, - refundVendorCreditDTO.branchId - ); - }; -} diff --git a/packages/server/src/services/Branches/Subscribers/Validators/index.ts b/packages/server/src/services/Branches/Subscribers/Validators/index.ts deleted file mode 100644 index 8865dbfcb..000000000 --- a/packages/server/src/services/Branches/Subscribers/Validators/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export * from './BillBranchSubscriber'; -export * from './CashflowBranchDTOValidatorSubscriber'; -export * from './CreditNoteBranchesSubscriber'; -export * from './CreditNoteRefundBranchSubscriber'; -export * from './ExpenseBranchSubscriber'; -export * from './ManualJournalBranchSubscriber'; -export * from './PaymentMadeBranchSubscriber'; -export * from './PaymentReceiveBranchSubscriber'; -export * from './SaleEstimateMultiBranchesSubscriber'; -export * from './SaleReceiptBranchesSubscriber'; -export * from './VendorCreditBranchSubscriber'; -export * from './VendorCreditRefundBranchSubscriber'; -export * from './InvoiceBranchValidatorSubscriber'; -export * from './ContactOpeningBalanceBranchSubscriber'; -export * from './InventoryAdjustmentBranchValidatorSubscriber'; \ No newline at end of file diff --git a/packages/server/src/services/Branches/constants.ts b/packages/server/src/services/Branches/constants.ts deleted file mode 100644 index e0d80f876..000000000 --- a/packages/server/src/services/Branches/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const ERRORS = { - BRANCH_NOT_FOUND: 'BRANCH_NOT_FOUND', - MUTLI_BRANCHES_ALREADY_ACTIVATED: 'MUTLI_BRANCHES_ALREADY_ACTIVATED', - COULD_NOT_DELETE_ONLY_BRANCH: 'COULD_NOT_DELETE_ONLY_BRANCH', - BRANCH_CODE_NOT_UNIQUE: 'BRANCH_CODE_NOT_UNIQUE', - BRANCH_HAS_ASSOCIATED_TRANSACTIONS: 'BRANCH_HAS_ASSOCIATED_TRANSACTIONS' -}; diff --git a/packages/server/src/services/Cache/index.ts b/packages/server/src/services/Cache/index.ts deleted file mode 100644 index 31c3355f0..000000000 --- a/packages/server/src/services/Cache/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import NodeCache from 'node-cache'; - -export default class Cache { - cache: NodeCache; - - constructor(config?: object) { - this.cache = new NodeCache({ - useClones: false, - ...config, - }); - } - - get(key: string, storeFunction: () => Promise) { - const value = this.cache.get(key); - - if (value) { - return Promise.resolve(value); - } - return storeFunction().then((result) => { - this.cache.set(key, result); - return result; - }); - } - - set(key: string, results: any) { - this.cache.set(key, results); - } - - del(keys: string) { - this.cache.del(keys); - } - - delStartWith(startStr = '') { - if (!startStr) { - return; - } - - const keys = this.cache.keys(); - for (const key of keys) { - if (key.indexOf(startStr) === 0) { - this.del(key); - } - } - } - - flush() { - this.cache.flushAll(); - } -} \ No newline at end of file diff --git a/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts b/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts deleted file mode 100644 index c78730041..000000000 --- a/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { IAccount } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class CashflowAccountTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'lastFeedsUpdatedAt', - 'lastFeedsUpdatedAtFormatted', - 'lastFeedsUpdatedFromNow', - ]; - }; - - /** - * Exclude these attributes to sale invoice object. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return [ - 'predefined', - 'index', - 'accountRootType', - 'accountTypeLabel', - 'accountParentType', - 'isBalanceSheetAccount', - 'isPlSheet', - ]; - }; - - /** - * Retrieve formatted account amount. - * @param {IAccount} invoice - * @returns {string} - */ - protected formattedAmount = (account: IAccount): string => { - return formatNumber(account.amount, { - currencyCode: account.currencyCode, - }); - }; - - /** - * Retrieves the last feeds update at formatted date. - * @param {IAccount} account - * @returns {string} - */ - protected lastFeedsUpdatedAtFormatted(account: IAccount): string { - return this.formatDate(account.lastFeedsUpdatedAt); - } - - /** - * Retrieves the last feeds updated from now. - * @param {IAccount} account - * @returns {string} - */ - protected lastFeedsUpdatedFromNow(account: IAccount): string { - return this.formatDateFromNow(account.lastFeedsUpdatedAt); - } -} diff --git a/packages/server/src/services/Cashflow/CashflowApplication.ts b/packages/server/src/services/Cashflow/CashflowApplication.ts deleted file mode 100644 index 5773c1ee1..000000000 --- a/packages/server/src/services/Cashflow/CashflowApplication.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { DeleteCashflowTransaction } from './DeleteCashflowTransactionService'; -import { UncategorizeCashflowTransaction } from './UncategorizeCashflowTransaction'; -import { CategorizeCashflowTransaction } from './CategorizeCashflowTransaction'; -import { - CategorizeTransactionAsExpenseDTO, - CreateUncategorizedTransactionDTO, - ICashflowAccountsFilter, - ICashflowNewCommandDTO, - ICategorizeCashflowTransactioDTO, - IGetRecognizedTransactionsQuery, - IGetUncategorizedTransactionsQuery, -} from '@/interfaces'; -import { CategorizeTransactionAsExpense } from './CategorizeTransactionAsExpense'; -import { GetUncategorizedTransactions } from './GetUncategorizedTransactions'; -import { CreateUncategorizedTransaction } from './CreateUncategorizedTransaction'; -import { GetUncategorizedTransaction } from './GetUncategorizedTransaction'; -import NewCashflowTransactionService from './NewCashflowTransactionService'; -import GetCashflowAccountsService from './GetCashflowAccountsService'; -import { GetCashflowTransactionService } from './GetCashflowTransactionsService'; -import { GetRecognizedTransactionsService } from './GetRecongizedTransactions'; -import { GetRecognizedTransactionService } from './GetRecognizedTransaction'; -import { UncategorizeCashflowTransactionsBulk } from './UncategorizeCashflowTransactionsBulk'; - -@Service() -export class CashflowApplication { - @Inject() - private createTransactionService: NewCashflowTransactionService; - - @Inject() - private deleteTransactionService: DeleteCashflowTransaction; - - @Inject() - private getCashflowAccountsService: GetCashflowAccountsService; - - @Inject() - private getCashflowTransactionService: GetCashflowTransactionService; - - @Inject() - private uncategorizeTransactionService: UncategorizeCashflowTransaction; - - @Inject() - private uncategorizeTransasctionsService: UncategorizeCashflowTransactionsBulk; - - @Inject() - private categorizeTransactionService: CategorizeCashflowTransaction; - - @Inject() - private categorizeAsExpenseService: CategorizeTransactionAsExpense; - - @Inject() - private getUncategorizedTransactionsService: GetUncategorizedTransactions; - - @Inject() - private getUncategorizedTransactionService: GetUncategorizedTransaction; - - @Inject() - private createUncategorizedTransactionService: CreateUncategorizedTransaction; - - @Inject() - private getRecognizedTranasctionsService: GetRecognizedTransactionsService; - - @Inject() - private getRecognizedTransactionService: GetRecognizedTransactionService; - - /** - * Creates a new cashflow transaction. - * @param {number} tenantId - * @param {ICashflowNewCommandDTO} transactionDTO - * @param {number} userId - * @returns - */ - public createTransaction( - tenantId: number, - transactionDTO: ICashflowNewCommandDTO, - userId?: number - ) { - return this.createTransactionService.newCashflowTransaction( - tenantId, - transactionDTO, - userId - ); - } - - /** - * Deletes the given cashflow transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @returns - */ - public deleteTransaction(tenantId: number, cashflowTransactionId: number) { - return this.deleteTransactionService.deleteCashflowTransaction( - tenantId, - cashflowTransactionId - ); - } - - /** - * Retrieves specific cashflow transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @returns - */ - public getTransaction(tenantId: number, cashflowTransactionId: number) { - return this.getCashflowTransactionService.getCashflowTransaction( - tenantId, - cashflowTransactionId - ); - } - - /** - * Retrieves the cashflow accounts. - * @param {number} tenantId - * @param {ICashflowAccountsFilter} filterDTO - * @returns - */ - public getCashflowAccounts( - tenantId: number, - filterDTO: ICashflowAccountsFilter - ) { - return this.getCashflowAccountsService.getCashflowAccounts( - tenantId, - filterDTO - ); - } - - /** - * Creates a new uncategorized cash transaction. - * @param {number} tenantId - * @param {CreateUncategorizedTransactionDTO} createUncategorizedTransactionDTO - * @returns {IUncategorizedCashflowTransaction} - */ - public createUncategorizedTransaction( - tenantId: number, - createUncategorizedTransactionDTO: CreateUncategorizedTransactionDTO, - trx?: Knex.Transaction - ) { - return this.createUncategorizedTransactionService.create( - tenantId, - createUncategorizedTransactionDTO, - trx - ); - } - - /** - * Uncategorize the given cashflow transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @returns - */ - public uncategorizeTransaction( - tenantId: number, - cashflowTransactionId: number - ) { - return this.uncategorizeTransactionService.uncategorize( - tenantId, - cashflowTransactionId - ); - } - - /** - * Uncategorize the given transactions in bulk. - * @param {number} tenantId - * @param {number | Array} transactionId - * @returns - */ - public uncategorizeTransactions( - tenantId: number, - transactionId: number | Array - ) { - return this.uncategorizeTransasctionsService.uncategorizeBulk( - tenantId, - transactionId - ); - } - - /** - * Categorize the given cashflow transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @param {ICategorizeCashflowTransactioDTO} categorizeDTO - * @returns - */ - public categorizeTransaction( - tenantId: number, - uncategorizeTransactionIds: Array, - categorizeDTO: ICategorizeCashflowTransactioDTO - ) { - return this.categorizeTransactionService.categorize( - tenantId, - uncategorizeTransactionIds, - categorizeDTO - ); - } - - /** - * Categorizes the given cashflow transaction as expense transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @param {CategorizeTransactionAsExpenseDTO} transactionDTO - */ - public categorizeAsExpense( - tenantId: number, - cashflowTransactionId: number, - transactionDTO: CategorizeTransactionAsExpenseDTO - ) { - return this.categorizeAsExpenseService.categorize( - tenantId, - cashflowTransactionId, - transactionDTO - ); - } - - /** - * Retrieves the uncategorized cashflow transactions. - * @param {number} tenantId - */ - public getUncategorizedTransactions( - tenantId: number, - accountId: number, - query: IGetUncategorizedTransactionsQuery - ) { - return this.getUncategorizedTransactionsService.getTransactions( - tenantId, - accountId, - query - ); - } - - /** - * Retrieves specific uncategorized transaction. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - */ - public getUncategorizedTransaction( - tenantId: number, - uncategorizedTransactionId: number - ) { - return this.getUncategorizedTransactionService.getTransaction( - tenantId, - uncategorizedTransactionId - ); - } - - /** - * Retrieves the recognized bank transactions. - * @param {number} tenantId - * @param {number} accountId - * @returns - */ - public getRecognizedTransactions( - tenantId: number, - filter?: IGetRecognizedTransactionsQuery - ) { - return this.getRecognizedTranasctionsService.getRecognizedTranactions( - tenantId, - filter - ); - } - - /** - * Retrieves the recognized transaction of the given uncategorized transaction. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - * @returns - */ - public getRecognizedTransaction( - tenantId: number, - uncategorizedTransactionId: number - ) { - return this.getRecognizedTransactionService.getRecognizedTransaction( - tenantId, - uncategorizedTransactionId - ); - } -} diff --git a/packages/server/src/services/Cashflow/CashflowDeleteAccount.ts b/packages/server/src/services/Cashflow/CashflowDeleteAccount.ts deleted file mode 100644 index bdc90641a..000000000 --- a/packages/server/src/services/Cashflow/CashflowDeleteAccount.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; - -@Service() -export default class CashflowDeleteAccount { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validate the account has no associated cashflow transactions. - * @param {number} tenantId - * @param {number} accountId - */ - public validateAccountHasNoCashflowEntries = async ( - tenantId: number, - accountId: number - ) => { - const { CashflowTransactionLine } = this.tenancy.models(tenantId); - - const associatedLines = await CashflowTransactionLine.query() - .where('creditAccountId', accountId) - .orWhere('cashflowAccountId', accountId); - - if (associatedLines.length > 0) { - throw new ServiceError(ERRORS.ACCOUNT_HAS_ASSOCIATED_TRANSACTIONS) - } - }; -} diff --git a/packages/server/src/services/Cashflow/CashflowTransactionAutoIncrement.ts b/packages/server/src/services/Cashflow/CashflowTransactionAutoIncrement.ts deleted file mode 100644 index 58eef54bd..000000000 --- a/packages/server/src/services/Cashflow/CashflowTransactionAutoIncrement.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Service, Inject } from 'typedi'; -import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService'; - -@Service() -export class CashflowTransactionAutoIncrement { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - /** - * Retrieve the next unique invoice number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - public getNextTransactionNumber = (tenantId: number): string => { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'cashflow' - ); - }; - - /** - * Increment the invoice next number. - * @param {number} tenantId - - */ - public incrementNextTransactionNumber = (tenantId: number) => { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'cashflow' - ); - }; -} diff --git a/packages/server/src/services/Cashflow/CashflowTransactionJournalEntries.ts b/packages/server/src/services/Cashflow/CashflowTransactionJournalEntries.ts deleted file mode 100644 index 62bf35992..000000000 --- a/packages/server/src/services/Cashflow/CashflowTransactionJournalEntries.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ILedgerEntry, ICashflowTransaction } from '../../interfaces'; -import { transformCashflowTransactionType } from './utils'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import Ledger from '@/services/Accounting/Ledger'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class CashflowTransactionJournalEntries { - @Inject() - private ledgerStorage: LedgerStorageService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the common entry of cashflow transaction. - * @param {ICashflowTransaction} cashflowTransaction - * @returns {Partial} - */ - private getCommonEntry = (cashflowTransaction: ICashflowTransaction) => { - const { entries, ...transaction } = cashflowTransaction; - - return { - date: transaction.date, - currencyCode: transaction.currencyCode, - exchangeRate: transaction.exchangeRate, - - transactionType: 'CashflowTransaction', - transactionId: transaction.id, - transactionNumber: transaction.transactionNumber, - transactionSubType: transformCashflowTransactionType( - transaction.transactionType - ), - referenceNumber: transaction.referenceNo, - - note: transaction.description, - - branchId: cashflowTransaction.branchId, - userId: cashflowTransaction.userId, - }; - }; - - /** - * Retrieves the cashflow debit GL entry. - * @param {ICashflowTransaction} cashflowTransaction - * @param {ICashflowTransactionLine} entry - * @param {number} index - * @returns {ILedgerEntry} - */ - private getCashflowDebitGLEntry = ( - cashflowTransaction: ICashflowTransaction - ): ILedgerEntry => { - const commonEntry = this.getCommonEntry(cashflowTransaction); - - return { - ...commonEntry, - accountId: cashflowTransaction.cashflowAccountId, - credit: cashflowTransaction.isCashCredit - ? cashflowTransaction.localAmount - : 0, - debit: cashflowTransaction.isCashDebit - ? cashflowTransaction.localAmount - : 0, - accountNormal: cashflowTransaction?.cashflowAccount?.accountNormal, - index: 1, - }; - }; - - /** - * Retrieves the cashflow credit GL entry. - * @param {ICashflowTransaction} cashflowTransaction - * @param {ICashflowTransactionLine} entry - * @param {number} index - * @returns {ILedgerEntry} - */ - private getCashflowCreditGLEntry = ( - cashflowTransaction: ICashflowTransaction - ): ILedgerEntry => { - const commonEntry = this.getCommonEntry(cashflowTransaction); - - return { - ...commonEntry, - credit: cashflowTransaction.isCashDebit - ? cashflowTransaction.localAmount - : 0, - debit: cashflowTransaction.isCashCredit - ? cashflowTransaction.localAmount - : 0, - accountId: cashflowTransaction.creditAccountId, - accountNormal: cashflowTransaction.creditAccount.accountNormal, - index: 2, - }; - }; - - /** - * Retrieves the cashflow transaction GL entry. - * @param {ICashflowTransaction} cashflowTransaction - * @param {ICashflowTransactionLine} entry - * @param {number} index - * @returns {ILedgerEntry[]} - */ - private getJournalEntries = ( - cashflowTransaction: ICashflowTransaction - ): ILedgerEntry[] => { - const debitEntry = this.getCashflowDebitGLEntry(cashflowTransaction); - const creditEntry = this.getCashflowCreditGLEntry(cashflowTransaction); - - return [debitEntry, creditEntry]; - }; - - /** - * Retrieves the cashflow GL ledger. - * @param {ICashflowTransaction} cashflowTransaction - * @returns {Ledger} - */ - private getCashflowLedger = (cashflowTransaction: ICashflowTransaction) => { - const entries = this.getJournalEntries(cashflowTransaction); - return new Ledger(entries); - }; - - /** - * Write the journal entries of the given cashflow transaction. - * @param {number} tenantId - * @param {ICashflowTransaction} cashflowTransaction - * @return {Promise} - */ - public writeJournalEntries = async ( - tenantId: number, - cashflowTransactionId: number, - trx?: Knex.Transaction - ): Promise => { - const { CashflowTransaction } = this.tenancy.models(tenantId); - - // Retrieves the cashflow transactions with associated entries. - const transaction = await CashflowTransaction.query(trx) - .findById(cashflowTransactionId) - .withGraphFetched('cashflowAccount') - .withGraphFetched('creditAccount'); - - // Retrieves the cashflow transaction ledger. - const ledger = this.getCashflowLedger(transaction); - - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Delete the journal entries. - * @param {number} tenantId - Tenant id. - * @param {number} cashflowTransactionId - Cashflow transaction id. - * @return {Promise} - */ - public revertJournalEntries = async ( - tenantId: number, - cashflowTransactionId: number, - trx?: Knex.Transaction - ): Promise => { - await this.ledgerStorage.deleteByReference( - tenantId, - cashflowTransactionId, - 'CashflowTransaction', - trx - ); - }; -} diff --git a/packages/server/src/services/Cashflow/CashflowTransactionSubscriber.ts b/packages/server/src/services/Cashflow/CashflowTransactionSubscriber.ts deleted file mode 100644 index 91adb30ea..000000000 --- a/packages/server/src/services/Cashflow/CashflowTransactionSubscriber.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import CashflowTransactionJournalEntries from './CashflowTransactionJournalEntries'; -import { - ICommandCashflowCreatedPayload, - ICommandCashflowDeletedPayload, -} from '@/interfaces'; -import { CashflowTransactionAutoIncrement } from './CashflowTransactionAutoIncrement'; - -@Service() -export default class CashflowTransactionSubscriber { - @Inject() - private cashflowTransactionEntries: CashflowTransactionJournalEntries; - - @Inject() - private cashflowTransactionAutoIncrement: CashflowTransactionAutoIncrement; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe( - events.cashflow.onTransactionCreated, - this.writeJournalEntriesOnceTransactionCreated - ); - bus.subscribe( - events.cashflow.onTransactionCreated, - this.incrementTransactionNumberOnceTransactionCreated - ); - bus.subscribe( - events.cashflow.onTransactionDeleted, - this.revertGLEntriesOnceTransactionDeleted - ); - return bus; - } - - /** - * Writes the journal entries once the cashflow transaction create. - * @param {ICommandCashflowCreatedPayload} payload - - */ - private writeJournalEntriesOnceTransactionCreated = async ({ - tenantId, - cashflowTransaction, - trx, - }: ICommandCashflowCreatedPayload) => { - // Can't write GL entries if the transaction not published yet. - if (!cashflowTransaction.isPublished) return; - - await this.cashflowTransactionEntries.writeJournalEntries( - tenantId, - cashflowTransaction.id, - trx - ); - }; - - /** - * Increment the cashflow transaction number once the transaction created. - * @param {ICommandCashflowCreatedPayload} payload - - */ - private incrementTransactionNumberOnceTransactionCreated = async ({ - tenantId, - }: ICommandCashflowCreatedPayload) => { - this.cashflowTransactionAutoIncrement.incrementNextTransactionNumber( - tenantId - ); - }; - - /** - * Deletes the GL entries once the cashflow transaction deleted. - * @param {ICommandCashflowDeletedPayload} payload - - */ - private revertGLEntriesOnceTransactionDeleted = async ({ - tenantId, - cashflowTransactionId, - trx, - }: ICommandCashflowDeletedPayload) => { - await this.cashflowTransactionEntries.revertJournalEntries( - tenantId, - cashflowTransactionId, - trx - ); - }; -} diff --git a/packages/server/src/services/Cashflow/CashflowTransactionTransformer.ts b/packages/server/src/services/Cashflow/CashflowTransactionTransformer.ts deleted file mode 100644 index f6b9e288b..000000000 --- a/packages/server/src/services/Cashflow/CashflowTransactionTransformer.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class CashflowTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'transactionTypeFormatted', - 'formattedDate', - 'formattedCreatedAt', - ]; - }; - - /** - * Formatted amount. - * @param {} transaction - * @returns {string} - */ - protected formattedAmount = (transaction) => { - return formatNumber(transaction.amount, { - currencyCode: transaction.currencyCode, - excerptZero: true, - }); - }; - - /** - * Formatted transaction type. - * @param transaction - * @returns {string} - */ - protected transactionTypeFormatted = (transaction) => { - return this.context.i18n.__(transaction.transactionTypeFormatted); - }; - - /** - * Retrieve the formatted transaction date. - * @param invoice - * @returns {string} - */ - protected formattedDate = (invoice): string => { - return this.formatDate(invoice.date); - }; - - /** - * Retrieve the formatted created at date. - * @param invoice - * @returns {string} - */ - protected formattedCreatedAt = (invoice): string => { - return this.formatDate(invoice.createdAt); - }; -} diff --git a/packages/server/src/services/Cashflow/CashflowTransactionsTransformer.ts b/packages/server/src/services/Cashflow/CashflowTransactionsTransformer.ts deleted file mode 100644 index a95d79588..000000000 --- a/packages/server/src/services/Cashflow/CashflowTransactionsTransformer.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class CashflowTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {string[]} - */ - protected includeAttributes = (): string[] => { - return ['deposit', 'withdrawal', 'formattedDeposit', 'formattedWithdrawal']; - }; - - /** - * Exclude these attributes. - * @returns {string[]} - */ - protected excludeAttributes = (): string[] => { - return [ - 'credit', - 'debit', - 'index', - 'index_group', - 'item_id', - 'item_quantity', - 'contact_type', - 'contact_id', - ]; - }; - - /** - * Deposit amount attribute. - * @param transaction - * @returns - */ - protected deposit = (transaction) => { - return transaction.debit; - }; - - /** - * Withdrawal amount attribute. - * @param transaction - * @returns - */ - protected withdrawal = (transaction) => { - return transaction.credit; - }; - - /** - * Formatted withdrawal amount. - * @param transaction - * @returns - */ - protected formattedWithdrawal = (transaction) => { - return formatNumber(transaction.credit, { - currencyCode: transaction.currencyCode, - excerptZero: true, - }); - }; - - /** - * Formatted deposit account. - * @param transaction - * @returns - */ - protected formattedDeposit = (transaction) => { - return formatNumber(transaction.debit, { - currencyCode: transaction.currencyCode, - excerptZero: true, - }); - }; -} diff --git a/packages/server/src/services/Cashflow/CashflowWithAccountSubscriber.ts b/packages/server/src/services/Cashflow/CashflowWithAccountSubscriber.ts deleted file mode 100644 index efa5100d1..000000000 --- a/packages/server/src/services/Cashflow/CashflowWithAccountSubscriber.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { IAccountEventDeletePayload } from '@/interfaces'; -import CashflowDeleteAccount from './CashflowDeleteAccount'; - -@Service() -export default class CashflowWithAccountSubscriber { - @Inject() - cashflowDeleteAccount: CashflowDeleteAccount; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.accounts.onDelete, - this.validateAccountHasNoCashflowTransactionsOnDelete - ); - }; - - /** - * Validate chart account has no associated cashflow transactions on delete. - * @param {IAccountEventDeletePayload} payload - - */ - private validateAccountHasNoCashflowTransactionsOnDelete = async ({ - tenantId, - oldAccount, - }: IAccountEventDeletePayload) => { - await this.cashflowDeleteAccount.validateAccountHasNoCashflowEntries( - tenantId, - oldAccount.id - ); - }; -} diff --git a/packages/server/src/services/Cashflow/CategorizeCashflowTransaction.ts b/packages/server/src/services/Cashflow/CategorizeCashflowTransaction.ts deleted file mode 100644 index 8a02556a3..000000000 --- a/packages/server/src/services/Cashflow/CategorizeCashflowTransaction.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { castArray } from 'lodash'; -import { Knex } from 'knex'; -import HasTenancyService from '../Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '../UnitOfWork'; -import { - ICashflowTransactionCategorizedPayload, - ICashflowTransactionUncategorizingPayload, - ICategorizeCashflowTransactioDTO, -} from '@/interfaces'; -import { - transformCategorizeTransToCashflow, - validateUncategorizedTransactionsNotExcluded, -} from './utils'; -import { CommandCashflowValidator } from './CommandCasflowValidator'; -import NewCashflowTransactionService from './NewCashflowTransactionService'; - -@Service() -export class CategorizeCashflowTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private commandValidators: CommandCashflowValidator; - - @Inject() - private createCashflow: NewCashflowTransactionService; - - /** - * Categorize the given cashflow transaction. - * @param {number} tenantId - * @param {ICategorizeCashflowTransactioDTO} categorizeDTO - */ - public async categorize( - tenantId: number, - uncategorizedTransactionId: number | Array, - categorizeDTO: ICategorizeCashflowTransactioDTO - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - const uncategorizedTransactionIds = castArray(uncategorizedTransactionId); - - // Retrieves the uncategorized transaction or throw an error. - const oldUncategorizedTransactions = - await UncategorizedCashflowTransaction.query() - .whereIn('id', uncategorizedTransactionIds) - .throwIfNotFound(); - - // Validate cannot categorize excluded transaction. - validateUncategorizedTransactionsNotExcluded(oldUncategorizedTransactions); - - // Validates the transaction shouldn't be categorized before. - this.commandValidators.validateTransactionsShouldNotCategorized( - oldUncategorizedTransactions - ); - // Validate the uncateogirzed transaction if it's deposit the transaction direction - // should `IN` and the same thing if it's withdrawal the direction should be OUT. - this.commandValidators.validateUncategorizeTransactionType( - oldUncategorizedTransactions, - categorizeDTO.transactionType - ); - // Edits the cashflow transaction under UOW env. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTransactionCategorizing` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionCategorizing, - { - tenantId, - oldUncategorizedTransactions, - trx, - } as ICashflowTransactionUncategorizingPayload - ); - // Transformes the categorize DTO to the cashflow transaction. - const cashflowTransactionDTO = transformCategorizeTransToCashflow( - oldUncategorizedTransactions, - categorizeDTO - ); - // Creates a new cashflow transaction. - const cashflowTransaction = - await this.createCashflow.newCashflowTransaction( - tenantId, - cashflowTransactionDTO - ); - - // Updates the uncategorized transaction as categorized. - await UncategorizedCashflowTransaction.query(trx) - .whereIn('id', uncategorizedTransactionIds) - .patch({ - categorized: true, - categorizeRefType: 'CashflowTransaction', - categorizeRefId: cashflowTransaction.id, - }); - // Fetch the new updated uncategorized transactions. - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query(trx).whereIn( - 'id', - uncategorizedTransactionIds - ); - // Triggers `onCashflowTransactionCategorized` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionCategorized, - { - tenantId, - cashflowTransaction, - uncategorizedTransactions, - oldUncategorizedTransactions, - categorizeDTO, - trx, - } as ICashflowTransactionCategorizedPayload - ); - }); - } -} diff --git a/packages/server/src/services/Cashflow/CategorizeRecognizedTransaction.ts b/packages/server/src/services/Cashflow/CategorizeRecognizedTransaction.ts deleted file mode 100644 index 68c2e7fac..000000000 --- a/packages/server/src/services/Cashflow/CategorizeRecognizedTransaction.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Service } from "typedi"; - - -@Service() -export class CategorizeRecognizedTransactionService { - - -} \ No newline at end of file diff --git a/packages/server/src/services/Cashflow/CategorizeTransactionAsExpense.ts b/packages/server/src/services/Cashflow/CategorizeTransactionAsExpense.ts deleted file mode 100644 index 119f0cc7b..000000000 --- a/packages/server/src/services/Cashflow/CategorizeTransactionAsExpense.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - CategorizeTransactionAsExpenseDTO, - ICashflowTransactionCategorizedPayload, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import UnitOfWork from '../UnitOfWork'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { Knex } from 'knex'; -import { CreateExpense } from '../Expenses/CRUD/CreateExpense'; - -@Service() -export class CategorizeTransactionAsExpense { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private createExpenseService: CreateExpense; - - /** - * Categorize the transaction as expense transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @param {CategorizeTransactionAsExpenseDTO} transactionDTO - */ - public async categorize( - tenantId: number, - cashflowTransactionId: number, - transactionDTO: CategorizeTransactionAsExpenseDTO - ) { - const { CashflowTransaction } = this.tenancy.models(tenantId); - - const transaction = await CashflowTransaction.query() - .findById(cashflowTransactionId) - .throwIfNotFound(); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTransactionUncategorizing` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionCategorizingAsExpense, - { - tenantId, - trx, - } as ICashflowTransactionCategorizedPayload - ); - // Creates a new expense transaction. - const expenseTransaction = await this.createExpenseService.newExpense( - tenantId, - { - - }, - 1 - ); - // Updates the item on the storage and fetches the updated once. - const cashflowTransaction = await CashflowTransaction.query( - trx - ).patchAndFetchById(cashflowTransactionId, { - categorizeRefType: 'Expense', - categorizeRefId: expenseTransaction.id, - uncategorized: true, - }); - // Triggers `onTransactionUncategorized` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionCategorizedAsExpense, - { - tenantId, - cashflowTransaction, - trx, - } as ICashflowTransactionUncategorizedPayload - ); - }); - } -} diff --git a/packages/server/src/services/Cashflow/CommandCasflowValidator.ts b/packages/server/src/services/Cashflow/CommandCasflowValidator.ts deleted file mode 100644 index fc2871c28..000000000 --- a/packages/server/src/services/Cashflow/CommandCasflowValidator.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { Service } from 'typedi'; -import { includes, camelCase, upperFirst, sumBy } from 'lodash'; -import { IAccount, IUncategorizedCashflowTransaction } from '@/interfaces'; -import { getCashflowTransactionType } from './utils'; -import { ServiceError } from '@/exceptions'; -import { - CASHFLOW_DIRECTION, - CASHFLOW_TRANSACTION_TYPE, - ERRORS, -} from './constants'; -import CashflowTransaction from '@/models/CashflowTransaction'; - -@Service() -export class CommandCashflowValidator { - /** - * Validates the lines accounts type should be cash or bank account. - * @param {IAccount} accounts - - */ - public validateCreditAccountWithCashflowType = ( - creditAccount: IAccount, - cashflowTransactionType: CASHFLOW_TRANSACTION_TYPE - ): void => { - const transactionTypeMeta = getCashflowTransactionType( - cashflowTransactionType - ); - const noneCashflowAccount = !includes( - transactionTypeMeta.creditType, - creditAccount.accountType - ); - if (noneCashflowAccount) { - throw new ServiceError(ERRORS.CREDIT_ACCOUNTS_HAS_INVALID_TYPE); - } - }; - - /** - * Validates the cashflow transaction type. - * @param {string} transactionType - * @returns {string} - */ - public validateCashflowTransactionType = (transactionType: string) => { - const transformedType = upperFirst( - camelCase(transactionType) - ) as CASHFLOW_TRANSACTION_TYPE; - - // Retrieve the given transaction type meta. - const transactionTypeMeta = getCashflowTransactionType(transformedType); - - // Throw service error in case not the found the given transaction type. - if (!transactionTypeMeta) { - throw new ServiceError(ERRORS.CASHFLOW_TRANSACTION_TYPE_INVALID); - } - return transformedType; - }; - - /** - * Validate the given transaction should be categorized. - * @param {CashflowTransaction} cashflowTransaction - */ - public validateTransactionShouldCategorized( - cashflowTransaction: CashflowTransaction - ) { - if (!cashflowTransaction.uncategorize) { - throw new ServiceError(ERRORS.TRANSACTION_ALREADY_CATEGORIZED); - } - } - - /** - * Validate the given transcation shouldn't be categorized. - * @param {CashflowTransaction} cashflowTransaction - */ - public validateTransactionsShouldNotCategorized( - cashflowTransactions: Array - ) { - const categorized = cashflowTransactions.filter((t) => t.categorized); - - if (categorized?.length > 0) { - throw new ServiceError(ERRORS.TRANSACTION_ALREADY_CATEGORIZED, '', { - ids: categorized.map((t) => t.id), - }); - } - } - - /** - * - * @param {uncategorizeTransaction} - * @param {string} transactionType - * @throws {ServiceError(ERRORS.UNCATEGORIZED_TRANSACTION_TYPE_INVALID)} - */ - public validateUncategorizeTransactionType( - uncategorizeTransactions: Array, - transactionType: string - ) { - const amount = sumBy(uncategorizeTransactions, 'amount'); - const isDepositTransaction = amount > 0; - const isWithdrawalTransaction = amount <= 0; - - const type = getCashflowTransactionType( - transactionType as CASHFLOW_TRANSACTION_TYPE - ); - if ( - (type.direction === CASHFLOW_DIRECTION.IN && isDepositTransaction) || - (type.direction === CASHFLOW_DIRECTION.OUT && isWithdrawalTransaction) - ) { - return; - } - throw new ServiceError(ERRORS.UNCATEGORIZED_TRANSACTION_TYPE_INVALID); - } -} diff --git a/packages/server/src/services/Cashflow/CreateUncategorizedTransaction.ts b/packages/server/src/services/Cashflow/CreateUncategorizedTransaction.ts deleted file mode 100644 index e2cbdf977..000000000 --- a/packages/server/src/services/Cashflow/CreateUncategorizedTransaction.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { - CreateUncategorizedTransactionDTO, - IUncategorizedTransactionCreatedEventPayload, - IUncategorizedTransactionCreatingEventPayload, -} from '@/interfaces'; - -@Service() -export class CreateUncategorizedTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates an uncategorized cashflow transaction. - * @param {number} tenantId - * @param {CreateUncategorizedTransactionDTO} createDTO - */ - public create( - tenantId: number, - createUncategorizedTransactionDTO: CreateUncategorizedTransactionDTO, - trx?: Knex.Transaction - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionUncategorizedCreating, - { - tenantId, - createUncategorizedTransactionDTO, - trx, - } as IUncategorizedTransactionCreatingEventPayload - ); - - const uncategorizedTransaction = - await UncategorizedCashflowTransaction.query(trx).insertAndFetch({ - ...createUncategorizedTransactionDTO, - }); - - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionUncategorizedCreated, - { - tenantId, - uncategorizedTransaction, - createUncategorizedTransactionDTO, - trx, - } as IUncategorizedTransactionCreatedEventPayload - ); - return uncategorizedTransaction; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Cashflow/DeleteCashflowTransactionService.ts b/packages/server/src/services/Cashflow/DeleteCashflowTransactionService.ts deleted file mode 100644 index dacf60c6f..000000000 --- a/packages/server/src/services/Cashflow/DeleteCashflowTransactionService.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - ICashflowTransaction, - ICommandCashflowDeletedPayload, - ICommandCashflowDeletingPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class DeleteCashflowTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the cashflow transaction with associated journal entries. - * @param {number} tenantId - - * @param {number} userId - User id. - */ - public deleteCashflowTransaction = async ( - tenantId: number, - cashflowTransactionId: number, - trx?: Knex.Transaction - ): Promise<{ oldCashflowTransaction: ICashflowTransaction }> => { - const { CashflowTransaction, CashflowTransactionLine } = - this.tenancy.models(tenantId); - - // Retrieve the cashflow transaction. - const oldCashflowTransaction = await CashflowTransaction.query().findById( - cashflowTransactionId - ); - // Throw not found error if the given transaction id not found. - this.throwErrorIfTransactionNotFound(oldCashflowTransaction); - - // Starting database transaction. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onCashflowTransactionDelete` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionDeleting, - { - trx, - tenantId, - oldCashflowTransaction, - } as ICommandCashflowDeletingPayload - ); - - // Delete cashflow transaction associated lines first. - await CashflowTransactionLine.query(trx) - .where('cashflow_transaction_id', cashflowTransactionId) - .delete(); - - // Delete cashflow transaction. - await CashflowTransaction.query(trx) - .findById(cashflowTransactionId) - .delete(); - - // Triggers `onCashflowTransactionDeleted` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionDeleted, - { - trx, - tenantId, - cashflowTransactionId, - oldCashflowTransaction, - } as ICommandCashflowDeletedPayload - ); - - return { oldCashflowTransaction }; - }, - trx - ); - }; - - /** - * Throw not found error if the given transaction id not found. - * @param transaction - */ - private throwErrorIfTransactionNotFound(transaction) { - if (!transaction) { - throw new ServiceError(ERRORS.CASHFLOW_TRANSACTION_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Cashflow/GetCashflowAccountsService.ts b/packages/server/src/services/Cashflow/GetCashflowAccountsService.ts deleted file mode 100644 index 0c608816b..000000000 --- a/packages/server/src/services/Cashflow/GetCashflowAccountsService.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ICashflowAccount, ICashflowAccountsFilter } from '@/interfaces'; -import { CashflowAccountTransformer } from './CashflowAccountTransformer'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -@Service() -export default class GetCashflowAccountsService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the cash flow accounts. - * @param {number} tenantId - Tenant id. - * @param {ICashflowAccountsFilter} filterDTO - Filter DTO. - * @returns {ICashflowAccount[]} - */ - public async getCashflowAccounts( - tenantId: number, - filterDTO: ICashflowAccountsFilter - ): Promise<{ cashflowAccounts: ICashflowAccount[] }> { - const { CashflowAccount } = this.tenancy.models(tenantId); - - // Parsees accounts list filter DTO. - const filter = this.dynamicListService.parseStringifiedFilter(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - CashflowAccount, - filter - ); - // Retrieve accounts model based on the given query. - const accounts = await CashflowAccount.query().onBuild((builder) => { - dynamicList.buildQuery()(builder); - - builder.whereIn('account_type', [ - ACCOUNT_TYPE.BANK, - ACCOUNT_TYPE.CASH, - ACCOUNT_TYPE.CREDIT_CARD, - ]); - builder.modify('inactiveMode', filter.inactiveMode); - }); - // Retrieves the transformed accounts. - const transformed = await this.transformer.transform( - tenantId, - accounts, - new CashflowAccountTransformer() - ); - - return transformed; - } -} diff --git a/packages/server/src/services/Cashflow/GetCashflowTransactionsService.ts b/packages/server/src/services/Cashflow/GetCashflowTransactionsService.ts deleted file mode 100644 index 919eca70d..000000000 --- a/packages/server/src/services/Cashflow/GetCashflowTransactionsService.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CashflowTransactionTransformer } from './CashflowTransactionTransformer'; -import { ERRORS } from './constants'; -import { ICashflowTransaction } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetCashflowTransactionService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the given cashflow transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @returns - */ - public getCashflowTransaction = async ( - tenantId: number, - cashflowTransactionId: number - ) => { - const { CashflowTransaction } = this.tenancy.models(tenantId); - - const cashflowTransaction = await CashflowTransaction.query() - .findById(cashflowTransactionId) - .withGraphFetched('entries.cashflowAccount') - .withGraphFetched('entries.creditAccount') - .withGraphFetched('transactions.account') - .orderBy('date', 'DESC') - .throwIfNotFound(); - - this.throwErrorCashflowTranscationNotFound(cashflowTransaction); - - // Transformes the cashflow transaction model to POJO. - return this.transformer.transform( - tenantId, - cashflowTransaction, - new CashflowTransactionTransformer() - ); - }; - - /** - * Throw not found error if the given cashflow undefined. - * @param {ICashflowTransaction} cashflowTransaction - - */ - private throwErrorCashflowTranscationNotFound = ( - cashflowTransaction: ICashflowTransaction - ) => { - if (!cashflowTransaction) { - throw new ServiceError(ERRORS.CASHFLOW_TRANSACTION_NOT_FOUND); - } - }; -} diff --git a/packages/server/src/services/Cashflow/GetPendingBankAccountTransaction.ts b/packages/server/src/services/Cashflow/GetPendingBankAccountTransaction.ts deleted file mode 100644 index 7f19af6a1..000000000 --- a/packages/server/src/services/Cashflow/GetPendingBankAccountTransaction.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Inject } from 'typedi'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { GetPendingBankAccountTransactionTransformer } from './GetPendingBankAccountTransactionTransformer'; - -export class GetPendingBankAccountTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the given bank accounts pending transaction. - * @param {number} tenantId - Tenant id. - * @param {GetPendingTransactionsQuery} filter - Pending transactions query. - */ - async getPendingTransactions( - tenantId: number, - filter?: GetPendingTransactionsQuery - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const _filter = { - page: 1, - pageSize: 20, - ...filter, - }; - const { results, pagination } = - await UncategorizedCashflowTransaction.query() - .onBuild((q) => { - q.modify('pending'); - - if (_filter?.accountId) { - q.where('accountId', _filter.accountId); - } - }) - .pagination(_filter.page - 1, _filter.pageSize); - - const data = await this.transformer.transform( - tenantId, - results, - new GetPendingBankAccountTransactionTransformer() - ); - return { data, pagination }; - } -} - -interface GetPendingTransactionsQuery { - page?: number; - pageSize?: number; - accountId?: number; -} diff --git a/packages/server/src/services/Cashflow/GetPendingBankAccountTransactionTransformer.ts b/packages/server/src/services/Cashflow/GetPendingBankAccountTransactionTransformer.ts deleted file mode 100644 index d388546a4..000000000 --- a/packages/server/src/services/Cashflow/GetPendingBankAccountTransactionTransformer.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from '@/utils'; - -export class GetPendingBankAccountTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedDate', - 'formattedDepositAmount', - 'formattedWithdrawalAmount', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return []; - }; - - /** - * Formattes the transaction date. - * @param transaction - * @returns {string} - */ - public formattedDate(transaction) { - return this.formatDate(transaction.date); - } - - /** - * Formatted amount. - * @param transaction - * @returns {string} - */ - public formattedAmount(transaction) { - return formatNumber(transaction.amount, { - currencyCode: transaction.currencyCode, - }); - } - - /** - * Formatted deposit amount. - * @param transaction - * @returns {string} - */ - protected formattedDepositAmount(transaction) { - if (transaction.isDepositTransaction) { - return formatNumber(transaction.deposit, { - currencyCode: transaction.currencyCode, - }); - } - return ''; - } - - /** - * Formatted withdrawal amount. - * @param transaction - * @returns {string} - */ - protected formattedWithdrawalAmount(transaction) { - if (transaction.isWithdrawalTransaction) { - return formatNumber(transaction.withdrawal, { - currencyCode: transaction.currencyCode, - }); - } - return ''; - } -} diff --git a/packages/server/src/services/Cashflow/GetRecognizedTransaction.ts b/packages/server/src/services/Cashflow/GetRecognizedTransaction.ts deleted file mode 100644 index 5ac725084..000000000 --- a/packages/server/src/services/Cashflow/GetRecognizedTransaction.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { GetRecognizedTransactionTransformer } from './GetRecognizedTransactionTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetRecognizedTransactionService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the recognized transaction of the given uncategorized transaction. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - */ - public async getRecognizedTransaction( - tenantId: number, - uncategorizedTransactionId: number - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const uncategorizedTransaction = - await UncategorizedCashflowTransaction.query() - .findById(uncategorizedTransactionId) - .withGraphFetched('matchedBankTransactions') - .withGraphFetched('recognizedTransaction.assignAccount') - .withGraphFetched('recognizedTransaction.bankRule') - .withGraphFetched('account') - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - uncategorizedTransaction, - new GetRecognizedTransactionTransformer() - ); - } -} diff --git a/packages/server/src/services/Cashflow/GetRecognizedTransactionTransformer.ts b/packages/server/src/services/Cashflow/GetRecognizedTransactionTransformer.ts deleted file mode 100644 index dc4ecaf00..000000000 --- a/packages/server/src/services/Cashflow/GetRecognizedTransactionTransformer.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from '@/utils'; - -export class GetRecognizedTransactionTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'uncategorizedTransactionId', - 'referenceNo', - 'description', - 'payee', - 'amount', - 'formattedAmount', - 'date', - 'formattedDate', - 'assignedAccountId', - 'assignedAccountName', - 'assignedAccountCode', - 'assignedPayee', - 'assignedMemo', - 'assignedCategory', - 'assignedCategoryFormatted', - 'withdrawal', - 'deposit', - 'isDepositTransaction', - 'isWithdrawalTransaction', - 'formattedDepositAmount', - 'formattedWithdrawalAmount', - 'bankRuleId', - 'bankRuleName', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Get the uncategorized transaction id. - * @param transaction - * @returns {number} - */ - public uncategorizedTransactionId = (transaction): number => { - return transaction.id; - } - - /** - * Get the reference number of the transaction. - * @param {object} transaction - * @returns {string} - */ - public referenceNo(transaction: any): string { - return transaction.referenceNo; - } - - /** - * Get the description of the transaction. - * @param {object} transaction - * @returns {string} - */ - public description(transaction: any): string { - return transaction.description; - } - - /** - * Get the payee of the transaction. - * @param {object} transaction - * @returns {string} - */ - public payee(transaction: any): string { - return transaction.payee; - } - - /** - * Get the amount of the transaction. - * @param {object} transaction - * @returns {number} - */ - public amount(transaction: any): number { - return transaction.amount; - } - - /** - * Get the formatted amount of the transaction. - * @param {object} transaction - * @returns {string} - */ - public formattedAmount(transaction: any): string { - return this.formatNumber(transaction.formattedAmount, { - money: true, - }); - } - - /** - * Get the date of the transaction. - * @param {object} transaction - * @returns {string} - */ - public date(transaction: any): string { - return transaction.date; - } - - /** - * Get the formatted date of the transaction. - * @param {object} transaction - * @returns {string} - */ - public formattedDate(transaction: any): string { - return this.formatDate(transaction.date); - } - - /** - * Get the assigned account ID of the transaction. - * @param {object} transaction - * @returns {number} - */ - public assignedAccountId(transaction: any): number { - return transaction.recognizedTransaction.assignedAccountId; - } - - /** - * Get the assigned account name of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedAccountName(transaction: any): string { - return transaction.recognizedTransaction.assignAccount.name; - } - - /** - * Get the assigned account code of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedAccountCode(transaction: any): string { - return transaction.recognizedTransaction.assignAccount.code; - } - - /** - * Get the assigned payee of the transaction. - * @param {object} transaction - * @returns {string} - */ - public getAssignedPayee(transaction: any): string { - return transaction.recognizedTransaction.assignedPayee; - } - - /** - * Get the assigned memo of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedMemo(transaction: any): string { - return transaction.recognizedTransaction.assignedMemo; - } - - /** - * Get the assigned category of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedCategory(transaction: any): string { - return transaction.recognizedTransaction.assignedCategory; - } - - /** - * - * @returns {string} - */ - public assignedCategoryFormatted() { - return 'Other Income' - } - - /** - * Check if the transaction is a withdrawal. - * @param {object} transaction - * @returns {boolean} - */ - public isWithdrawal(transaction: any): boolean { - return transaction.withdrawal; - } - - /** - * Check if the transaction is a deposit. - * @param {object} transaction - * @returns {boolean} - */ - public isDeposit(transaction: any): boolean { - return transaction.deposit; - } - - /** - * Check if the transaction is a deposit transaction. - * @param {object} transaction - * @returns {boolean} - */ - public isDepositTransaction(transaction: any): boolean { - return transaction.isDepositTransaction; - } - - /** - * Check if the transaction is a withdrawal transaction. - * @param {object} transaction - * @returns {boolean} - */ - public isWithdrawalTransaction(transaction: any): boolean { - return transaction.isWithdrawalTransaction; - } - - /** - * Get formatted deposit amount. - * @param {any} transaction - * @returns {string} - */ - protected formattedDepositAmount(transaction) { - if (transaction.isDepositTransaction) { - return formatNumber(transaction.deposit, { - currencyCode: transaction.currencyCode, - }); - } - return ''; - } - - /** - * Get formatted withdrawal amount. - * @param transaction - * @returns {string} - */ - protected formattedWithdrawalAmount(transaction) { - if (transaction.isWithdrawalTransaction) { - return formatNumber(transaction.withdrawal, { - currencyCode: transaction.currencyCode, - }); - } - return ''; - } - - /** - * Get the transaction bank rule id. - * @param transaction - * @returns {string} - */ - protected bankRuleId(transaction) { - return transaction.recognizedTransaction.bankRuleId; - } - - /** - * Get the transaction bank rule name. - * @param transaction - * @returns {string} - */ - protected bankRuleName(transaction) { - return transaction.recognizedTransaction.bankRule.name; - } -} diff --git a/packages/server/src/services/Cashflow/GetRecongizedTransactions.ts b/packages/server/src/services/Cashflow/GetRecongizedTransactions.ts deleted file mode 100644 index 7665180d0..000000000 --- a/packages/server/src/services/Cashflow/GetRecongizedTransactions.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetRecognizedTransactionTransformer } from './GetRecognizedTransactionTransformer'; -import { IGetRecognizedTransactionsQuery } from '@/interfaces'; - -@Service() -export class GetRecognizedTransactionsService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the recognized transactions of the given account. - * @param {number} tenantId - * @param {IGetRecognizedTransactionsQuery} filter - - */ - async getRecognizedTranactions( - tenantId: number, - filter?: IGetRecognizedTransactionsQuery - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const _query = { - page: 1, - pageSize: 20, - ...filter, - }; - const { results, pagination } = - await UncategorizedCashflowTransaction.query() - .onBuild((q) => { - q.withGraphFetched('recognizedTransaction.assignAccount'); - q.withGraphFetched('recognizedTransaction.bankRule'); - q.whereNotNull('recognizedTransactionId'); - - // Exclude the excluded transactions. - q.modify('notExcluded'); - - // Exclude the pending transactions. - q.modify('notPending'); - - if (_query.accountId) { - q.where('accountId', _query.accountId); - } - if (_query.minDate) { - q.modify('fromDate', _query.minDate); - } - if (_query.maxDate) { - q.modify('toDate', _query.maxDate); - } - if (_query.minAmount) { - q.modify('minAmount', _query.minAmount); - } - if (_query.maxAmount) { - q.modify('maxAmount', _query.maxAmount); - } - if (_query.accountId) { - q.where('accountId', _query.accountId); - } - }) - .pagination(_query.page - 1, _query.pageSize); - - const data = await this.transformer.transform( - tenantId, - results, - new GetRecognizedTransactionTransformer() - ); - return { data, pagination }; - } -} diff --git a/packages/server/src/services/Cashflow/GetUncategorizedTransaction.ts b/packages/server/src/services/Cashflow/GetUncategorizedTransaction.ts deleted file mode 100644 index 82cf531a8..000000000 --- a/packages/server/src/services/Cashflow/GetUncategorizedTransaction.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { UncategorizedTransactionTransformer } from './UncategorizedTransactionTransformer'; - -@Service() -export class GetUncategorizedTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves specific uncategorized cashflow transaction. - * @param {number} tenantId - Tenant id. - * @param {number} uncategorizedTransactionId - Uncategorized transaction id. - */ - public async getTransaction( - tenantId: number, - uncategorizedTransactionId: number - ) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const transaction = await UncategorizedCashflowTransaction.query() - .findById(uncategorizedTransactionId) - .withGraphFetched('account') - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - transaction, - new UncategorizedTransactionTransformer() - ); - } -} diff --git a/packages/server/src/services/Cashflow/GetUncategorizedTransactions.ts b/packages/server/src/services/Cashflow/GetUncategorizedTransactions.ts deleted file mode 100644 index afc2d058b..000000000 --- a/packages/server/src/services/Cashflow/GetUncategorizedTransactions.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initialize } from 'objection'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { UncategorizedTransactionTransformer } from './UncategorizedTransactionTransformer'; -import { IGetUncategorizedTransactionsQuery } from '@/interfaces'; - -@Service() -export class GetUncategorizedTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the uncategorized cashflow transactions. - * @param {number} tenantId - Tenant id. - * @param {number} accountId - Account Id. - */ - public async getTransactions( - tenantId: number, - accountId: number, - query: IGetUncategorizedTransactionsQuery - ) { - const { - UncategorizedCashflowTransaction, - RecognizedBankTransaction, - MatchedBankTransaction, - Account, - } = this.tenancy.models(tenantId); - const knex = this.tenancy.knex(tenantId); - - // Parsed query with default values. - const _query = { - page: 1, - pageSize: 20, - ...query, - }; - - // Initialize the ORM models metadata. - await initialize(knex, [ - UncategorizedCashflowTransaction, - MatchedBankTransaction, - RecognizedBankTransaction, - Account, - ]); - - const { results, pagination } = - await UncategorizedCashflowTransaction.query() - .onBuild((q) => { - q.where('accountId', accountId); - q.where('categorized', false); - - q.modify('notExcluded'); - q.modify('notPending'); - - q.withGraphFetched('account'); - q.withGraphFetched('recognizedTransaction.assignAccount'); - - q.withGraphJoined('matchedBankTransactions'); - - q.whereNull('matchedBankTransactions.id'); - q.orderBy('date', 'DESC'); - - if (_query.minDate) { - q.modify('fromDate', _query.minDate); - } - if (_query.maxDate) { - q.modify('toDate', _query.maxDate); - } - if (_query.minAmount) { - q.modify('minAmount', _query.minAmount); - } - if (_query.maxAmount) { - q.modify('maxAmount', _query.maxAmount); - } - }) - .pagination(_query.page - 1, _query.pageSize); - - const data = await this.transformer.transform( - tenantId, - results, - new UncategorizedTransactionTransformer() - ); - return { - data, - pagination, - }; - } -} diff --git a/packages/server/src/services/Cashflow/NewCashflowTransactionService.ts b/packages/server/src/services/Cashflow/NewCashflowTransactionService.ts deleted file mode 100644 index 43a8a692f..000000000 --- a/packages/server/src/services/Cashflow/NewCashflowTransactionService.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { pick } from 'lodash'; -import { Knex } from 'knex'; -import * as R from 'ramda'; -import { - ICashflowNewCommandDTO, - ICashflowTransaction, - ICommandCashflowCreatedPayload, - ICommandCashflowCreatingPayload, - ICashflowTransactionInput, - IAccount, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CASHFLOW_TRANSACTION_TYPE } from './constants'; -import { transformCashflowTransactionType } from './utils'; -import events from '@/subscribers/events'; -import { CommandCashflowValidator } from './CommandCasflowValidator'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CashflowTransactionAutoIncrement } from './CashflowTransactionAutoIncrement'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; - -@Service() -export default class NewCashflowTransactionService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validator: CommandCashflowValidator; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private autoIncrement: CashflowTransactionAutoIncrement; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - /** - * Authorize the cashflow creating transaction. - * @param {number} tenantId - * @param {ICashflowNewCommandDTO} newCashflowTransactionDTO - */ - public authorize = async ( - tenantId: number, - newCashflowTransactionDTO: ICashflowNewCommandDTO, - creditAccount: IAccount - ) => { - const transactionType = transformCashflowTransactionType( - newCashflowTransactionDTO.transactionType - ); - // Validates the cashflow transaction type. - this.validator.validateCashflowTransactionType(transactionType); - - // Retrieve accounts of the cashflow lines object. - this.validator.validateCreditAccountWithCashflowType( - creditAccount, - transactionType as CASHFLOW_TRANSACTION_TYPE - ); - }; - - /** - * Transformes owner contribution DTO to cashflow transaction. - * @param {ICashflowNewCommandDTO} newCashflowTransactionDTO - New transaction DTO. - * @returns {ICashflowTransaction} - Cashflow transaction object. - */ - private transformCashflowTransactionDTO = ( - tenantId: number, - newCashflowTransactionDTO: ICashflowNewCommandDTO, - cashflowAccount: IAccount, - userId: number - ): ICashflowTransactionInput => { - const amount = newCashflowTransactionDTO.amount; - - const fromDTO = pick(newCashflowTransactionDTO, [ - 'date', - 'referenceNo', - 'description', - 'transactionType', - 'exchangeRate', - 'cashflowAccountId', - 'creditAccountId', - 'branchId', - 'plaidTransactionId', - 'uncategorizedTransactionId', - ]); - // Retreive the next invoice number. - const autoNextNumber = - this.autoIncrement.getNextTransactionNumber(tenantId); - - // Retrieve the transaction number. - const transactionNumber = - newCashflowTransactionDTO.transactionNumber || autoNextNumber; - - const initialDTO = { - amount, - ...fromDTO, - transactionNumber, - currencyCode: cashflowAccount.currencyCode, - exchangeRate: fromDTO?.exchangeRate || 1, - transactionType: transformCashflowTransactionType( - fromDTO.transactionType - ), - userId, - ...(newCashflowTransactionDTO.publish - ? { - publishedAt: new Date(), - } - : {}), - }; - return R.compose( - this.branchDTOTransform.transformDTO(tenantId) - )(initialDTO); - }; - - /** - * Owner contribution money in. - * @param {number} tenantId - - * @param {ICashflowOwnerContributionDTO} ownerContributionDTO - * @param {number} userId - User id. - * @returns {Promise} - */ - public newCashflowTransaction = async ( - tenantId: number, - newTransactionDTO: ICashflowNewCommandDTO, - userId?: number - ): Promise => { - const { CashflowTransaction, Account } = this.tenancy.models(tenantId); - - // Retrieves the cashflow account or throw not found error. - const cashflowAccount = await Account.query() - .findById(newTransactionDTO.cashflowAccountId) - .throwIfNotFound(); - - // Retrieves the credit account or throw not found error. - const creditAccount = await Account.query() - .findById(newTransactionDTO.creditAccountId) - .throwIfNotFound(); - - // Authorize before creating cashflow transaction. - await this.authorize(tenantId, newTransactionDTO, creditAccount); - - // Transformes owner contribution DTO to cashflow transaction. - const cashflowTransactionObj = this.transformCashflowTransactionDTO( - tenantId, - newTransactionDTO, - cashflowAccount, - userId - ); - // Creates a new cashflow transaction under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCashflowTransactionCreate` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionCreating, - { - trx, - tenantId, - newTransactionDTO, - } as ICommandCashflowCreatingPayload - ); - // Inserts cashflow owner contribution transaction. - const cashflowTransaction = await CashflowTransaction.query( - trx - ).upsertGraph(cashflowTransactionObj); - - // Triggers `onCashflowTransactionCreated` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionCreated, - { - tenantId, - newTransactionDTO, - cashflowTransaction, - trx, - } as ICommandCashflowCreatedPayload - ); - return cashflowTransaction; - }); - }; -} diff --git a/packages/server/src/services/Cashflow/RemovePendingUncategorizedTransaction.ts b/packages/server/src/services/Cashflow/RemovePendingUncategorizedTransaction.ts deleted file mode 100644 index 101a914cf..000000000 --- a/packages/server/src/services/Cashflow/RemovePendingUncategorizedTransaction.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import { - IPendingTransactionRemovedEventPayload, - IPendingTransactionRemovingEventPayload, -} from '@/interfaces'; - -@Service() -export class RemovePendingUncategorizedTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * REmoves the pending uncategorized transaction. - * @param {number} tenantId - - * @param {number} uncategorizedTransactionId - - * @param {Knex.Transaction} trx - - * @returns {Promise} - */ - public async removePendingTransaction( - tenantId: number, - uncategorizedTransactionId: number, - trx?: Knex.Transaction - ): Promise { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const pendingTransaction = await UncategorizedCashflowTransaction.query(trx) - .findById(uncategorizedTransactionId) - .throwIfNotFound(); - - if (!pendingTransaction.isPending) { - throw new ServiceError(ERRORS.TRANSACTION_NOT_PENDING); - } - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - await this.eventPublisher.emitAsync( - events.bankTransactions.onPendingRemoving, - { - tenantId, - uncategorizedTransactionId, - pendingTransaction, - trx, - } as IPendingTransactionRemovingEventPayload - ); - // Removes the pending uncategorized transaction. - await UncategorizedCashflowTransaction.query(trx) - .findById(uncategorizedTransactionId) - .delete(); - - await this.eventPublisher.emitAsync( - events.bankTransactions.onPendingRemoved, - { - tenantId, - uncategorizedTransactionId, - pendingTransaction, - trx, - } as IPendingTransactionRemovedEventPayload - ); - }); - } -} diff --git a/packages/server/src/services/Cashflow/UncategorizeCashflowTransaction.ts b/packages/server/src/services/Cashflow/UncategorizeCashflowTransaction.ts deleted file mode 100644 index 285398b6d..000000000 --- a/packages/server/src/services/Cashflow/UncategorizeCashflowTransaction.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { - ICashflowTransactionUncategorizedPayload, - ICashflowTransactionUncategorizingPayload, -} from '@/interfaces'; -import { validateTransactionShouldBeCategorized } from './utils'; - -@Service() -export class UncategorizeCashflowTransaction { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Uncategorizes the given cashflow transaction. - * @param {number} tenantId - * @param {number} cashflowTransactionId - * @returns {Promise>} - */ - public async uncategorize( - tenantId: number, - uncategorizedTransactionId: number - ): Promise> { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - - const oldMainUncategorizedTransaction = - await UncategorizedCashflowTransaction.query() - .findById(uncategorizedTransactionId) - .throwIfNotFound(); - - validateTransactionShouldBeCategorized(oldMainUncategorizedTransaction); - - const associatedUncategorizedTransactions = - await UncategorizedCashflowTransaction.query() - .where('categorizeRefId', oldMainUncategorizedTransaction.categorizeRefId) - .where( - 'categorizeRefType', - oldMainUncategorizedTransaction.categorizeRefType - ) - // Exclude the main transaction. - .whereNot('id', uncategorizedTransactionId); - - const oldUncategorizedTransactions = [ - oldMainUncategorizedTransaction, - ...associatedUncategorizedTransactions, - ]; - const oldUncategoirzedTransactionsIds = oldUncategorizedTransactions.map( - (t) => t.id - ); - // Updates the transaction under UOW. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTransactionUncategorizing` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionUncategorizing, - { - tenantId, - uncategorizedTransactionId, - oldUncategorizedTransactions, - trx, - } as ICashflowTransactionUncategorizingPayload - ); - // Removes the ref relation with the related transaction. - await UncategorizedCashflowTransaction.query(trx) - .whereIn('id', oldUncategoirzedTransactionsIds) - .patch({ - categorized: false, - categorizeRefId: null, - categorizeRefType: null, - }); - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query(trx).whereIn( - 'id', - oldUncategoirzedTransactionsIds - ); - // Triggers `onTransactionUncategorized` event. - await this.eventPublisher.emitAsync( - events.cashflow.onTransactionUncategorized, - { - tenantId, - uncategorizedTransactionId, - oldMainUncategorizedTransaction, - uncategorizedTransactions, - oldUncategorizedTransactions, - trx, - } as ICashflowTransactionUncategorizedPayload - ); - return oldUncategoirzedTransactionsIds; - }); - } -} diff --git a/packages/server/src/services/Cashflow/UncategorizeCashflowTransactionsBulk.ts b/packages/server/src/services/Cashflow/UncategorizeCashflowTransactionsBulk.ts deleted file mode 100644 index e5f9ceee2..000000000 --- a/packages/server/src/services/Cashflow/UncategorizeCashflowTransactionsBulk.ts +++ /dev/null @@ -1,37 +0,0 @@ -import PromisePool from '@supercharge/promise-pool'; -import { castArray } from 'lodash'; -import { Service, Inject } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { UncategorizeCashflowTransaction } from './UncategorizeCashflowTransaction'; - -@Service() -export class UncategorizeCashflowTransactionsBulk { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uncategorizeTransaction: UncategorizeCashflowTransaction; - - /** - * Uncategorize the given bank transactions in bulk. - * @param {number} tenantId - * @param {number} uncategorizedTransactionId - */ - public async uncategorizeBulk( - tenantId: number, - uncategorizedTransactionId: number | Array - ) { - const uncategorizedTransactionIds = castArray(uncategorizedTransactionId); - - const result = await PromisePool.withConcurrency(MIGRATION_CONCURRENCY) - .for(uncategorizedTransactionIds) - .process(async (_uncategorizedTransactionId: number, index, pool) => { - await this.uncategorizeTransaction.uncategorize( - tenantId, - _uncategorizedTransactionId - ); - }); - } -} - -const MIGRATION_CONCURRENCY = 1; diff --git a/packages/server/src/services/Cashflow/UncategorizedTransactionTransformer.ts b/packages/server/src/services/Cashflow/UncategorizedTransactionTransformer.ts deleted file mode 100644 index 83fe13e5e..000000000 --- a/packages/server/src/services/Cashflow/UncategorizedTransactionTransformer.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from '@/utils'; - -export class UncategorizedTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedDate', - 'formattedDepositAmount', - 'formattedWithdrawalAmount', - - 'assignedAccountId', - 'assignedAccountName', - 'assignedAccountCode', - 'assignedPayee', - 'assignedMemo', - 'assignedCategory', - 'assignedCategoryFormatted', - ]; - }; - - /** - * Exclude all attributes. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['recognizedTransaction']; - }; - - /** - * Formattes the transaction date. - * @param transaction - * @returns {string} - */ - public formattedDate(transaction) { - return this.formatDate(transaction.date); - } - - /** - * Formatted amount. - * @param transaction - * @returns {string} - */ - public formattedAmount(transaction) { - return formatNumber(transaction.amount, { - currencyCode: transaction.currencyCode, - }); - } - - /** - * Formatted deposit amount. - * @param transaction - * @returns {string} - */ - protected formattedDepositAmount(transaction) { - if (transaction.isDepositTransaction) { - return formatNumber(transaction.deposit, { - currencyCode: transaction.currencyCode, - }); - } - return ''; - } - - /** - * Formatted withdrawal amount. - * @param transaction - * @returns {string} - */ - protected formattedWithdrawalAmount(transaction) { - if (transaction.isWithdrawalTransaction) { - return formatNumber(transaction.withdrawal, { - currencyCode: transaction.currencyCode, - }); - } - return ''; - } - - // -------------------------------------------------------- - // # Recgonized transaction - // -------------------------------------------------------- - /** - * Get the assigned account ID of the transaction. - * @param {object} transaction - * @returns {number} - */ - public assignedAccountId(transaction: any): number { - return transaction.recognizedTransaction?.assignedAccountId; - } - - /** - * Get the assigned account name of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedAccountName(transaction: any): string { - return transaction.recognizedTransaction?.assignAccount?.name; - } - - /** - * Get the assigned account code of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedAccountCode(transaction: any): string { - return transaction.recognizedTransaction?.assignAccount?.code; - } - - /** - * Get the assigned payee of the transaction. - * @param {object} transaction - * @returns {string} - */ - public getAssignedPayee(transaction: any): string { - return transaction.recognizedTransaction?.assignedPayee; - } - - /** - * Get the assigned memo of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedMemo(transaction: any): string { - return transaction.recognizedTransaction?.assignedMemo; - } - - /** - * Get the assigned category of the transaction. - * @param {object} transaction - * @returns {string} - */ - public assignedCategory(transaction: any): string { - return transaction.recognizedTransaction?.assignedCategory; - } - - /** - * Get the assigned formatted category. - * @returns {string} - */ - public assignedCategoryFormatted() { - return 'Other Income'; - } -} diff --git a/packages/server/src/services/Cashflow/UncategorizedTransactionsImportable.ts b/packages/server/src/services/Cashflow/UncategorizedTransactionsImportable.ts deleted file mode 100644 index 243affa24..000000000 --- a/packages/server/src/services/Cashflow/UncategorizedTransactionsImportable.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import * as yup from 'yup'; -import uniqid from 'uniqid'; -import { Importable } from '../Import/Importable'; -import { CreateUncategorizedTransaction } from './CreateUncategorizedTransaction'; -import { CreateUncategorizedTransactionDTO } from '@/interfaces'; -import { ImportableContext } from '../Import/interfaces'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { BankTransactionsSampleData } from './constants'; - -@Service() -export class UncategorizedTransactionsImportable extends Importable { - @Inject() - private createUncategorizedTransaction: CreateUncategorizedTransaction; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Passing the sheet DTO to create uncategorized transaction. - * @param {number} tenantId - * @param {number} tenantId - * @param {any} createDTO - * @param {Knex.Transaction} trx - */ - public async importable( - tenantId: number, - createDTO: CreateUncategorizedTransactionDTO, - trx?: Knex.Transaction - ) { - return this.createUncategorizedTransaction.create(tenantId, createDTO, trx); - } - - /** - * Transformes the DTO before validating and importing. - * @param {CreateUncategorizedTransactionDTO} createDTO - * @param {ImportableContext} context - * @returns {CreateUncategorizedTransactionDTO} - */ - public transform( - createDTO: CreateUncategorizedTransactionDTO, - context?: ImportableContext - ): CreateUncategorizedTransactionDTO { - return { - ...createDTO, - accountId: context.import.paramsParsed.accountId, - batch: context.import.paramsParsed.batch, - }; - } - - /** - * Sample data used to download sample sheet. - * @returns {Record[]} - */ - public sampleData(): Record[] { - return BankTransactionsSampleData; - } - - // ------------------ - // # Params - // ------------------ - /** - * Params validation schema. - * @returns {ValidationSchema[]} - */ - public paramsValidationSchema() { - return yup.object().shape({ - accountId: yup.number().required(), - }); - } - - /** - * Validates the params existance asyncly. - * @param {number} tenantId - - * @param {Record} params - - */ - public async validateParams( - tenantId: number, - params: Record - ): Promise { - const { Account } = this.tenancy.models(tenantId); - - if (params.accountId) { - await Account.query().findById(params.accountId).throwIfNotFound({}); - } - } - - /** - * Transforms the import params before storing them. - * @param {Record} parmas - */ - public transformParams(parmas: Record) { - const batch = uniqid(); - - return { - ...parmas, - batch, - }; - } -} diff --git a/packages/server/src/services/Cashflow/constants.ts b/packages/server/src/services/Cashflow/constants.ts deleted file mode 100644 index 50b35526a..000000000 --- a/packages/server/src/services/Cashflow/constants.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -export const ERRORS = { - CASHFLOW_TRANSACTION_TYPE_INVALID: 'CASHFLOW_TRANSACTION_TYPE_INVALID', - CASHFLOW_ACCOUNTS_HAS_INVALID_TYPE: 'CASHFLOW_ACCOUNTS_HAS_INVALID_TYPE', - CASHFLOW_TRANSACTION_NOT_FOUND: 'CASHFLOW_TRANSACTION_NOT_FOUND', - CASHFLOW_ACCOUNTS_IDS_NOT_FOUND: 'CASHFLOW_ACCOUNTS_IDS_NOT_FOUND', - CREDIT_ACCOUNTS_IDS_NOT_FOUND: 'CREDIT_ACCOUNTS_IDS_NOT_FOUND', - CREDIT_ACCOUNTS_HAS_INVALID_TYPE: 'CREDIT_ACCOUNTS_HAS_INVALID_TYPE', - ACCOUNT_ID_HAS_INVALID_TYPE: 'ACCOUNT_ID_HAS_INVALID_TYPE', - ACCOUNT_HAS_ASSOCIATED_TRANSACTIONS: 'account_has_associated_transactions', - TRANSACTION_ALREADY_CATEGORIZED: 'TRANSACTION_ALREADY_CATEGORIZED', - TRANSACTION_ALREADY_UNCATEGORIZED: 'TRANSACTION_ALREADY_UNCATEGORIZED', - UNCATEGORIZED_TRANSACTION_TYPE_INVALID: - 'UNCATEGORIZED_TRANSACTION_TYPE_INVALID', - CANNOT_DELETE_TRANSACTION_CONVERTED_FROM_UNCATEGORIZED: - 'CANNOT_DELETE_TRANSACTION_CONVERTED_FROM_UNCATEGORIZED', - CANNOT_CATEGORIZE_EXCLUDED_TRANSACTION: - 'CANNOT_CATEGORIZE_EXCLUDED_TRANSACTION', - TRANSACTION_NOT_CATEGORIZED: 'TRANSACTION_NOT_CATEGORIZED', - TRANSACTION_NOT_PENDING: 'TRANSACTION_NOT_PENDING', -}; - -export enum CASHFLOW_DIRECTION { - IN = 'In', - OUT = 'Out', -} - -export enum CASHFLOW_TRANSACTION_TYPE { - ONWERS_DRAWING = 'OwnerDrawing', - OWNER_CONTRIBUTION = 'OwnerContribution', - OTHER_INCOME = 'OtherIncome', - TRANSFER_FROM_ACCOUNT = 'TransferFromAccount', - TRANSFER_TO_ACCOUNT = 'TransferToAccount', - OTHER_EXPENSE = 'OtherExpense', -} - -export const CASHFLOW_TRANSACTION_TYPE_META = { - [`${CASHFLOW_TRANSACTION_TYPE.ONWERS_DRAWING}`]: { - type: 'OwnerDrawing', - direction: CASHFLOW_DIRECTION.OUT, - creditType: [ACCOUNT_TYPE.EQUITY], - }, - [`${CASHFLOW_TRANSACTION_TYPE.OWNER_CONTRIBUTION}`]: { - type: 'OwnerContribution', - direction: CASHFLOW_DIRECTION.IN, - creditType: [ACCOUNT_TYPE.EQUITY], - }, - [`${CASHFLOW_TRANSACTION_TYPE.OTHER_INCOME}`]: { - type: 'OtherIncome', - direction: CASHFLOW_DIRECTION.IN, - creditType: [ACCOUNT_TYPE.INCOME, ACCOUNT_TYPE.OTHER_INCOME], - }, - [`${CASHFLOW_TRANSACTION_TYPE.TRANSFER_FROM_ACCOUNT}`]: { - type: 'TransferFromAccount', - direction: CASHFLOW_DIRECTION.IN, - creditType: [ - ACCOUNT_TYPE.CASH, - ACCOUNT_TYPE.BANK, - ACCOUNT_TYPE.CREDIT_CARD, - ], - }, - [`${CASHFLOW_TRANSACTION_TYPE.TRANSFER_TO_ACCOUNT}`]: { - type: 'TransferToAccount', - direction: CASHFLOW_DIRECTION.OUT, - creditType: [ - ACCOUNT_TYPE.CASH, - ACCOUNT_TYPE.BANK, - ACCOUNT_TYPE.CREDIT_CARD, - ], - }, - [`${CASHFLOW_TRANSACTION_TYPE.OTHER_EXPENSE}`]: { - type: 'OtherExpense', - direction: CASHFLOW_DIRECTION.OUT, - creditType: [ - ACCOUNT_TYPE.EXPENSE, - ACCOUNT_TYPE.OTHER_EXPENSE, - ACCOUNT_TYPE.COST_OF_GOODS_SOLD, - ], - }, -}; - -export interface ICashflowTransactionTypeMeta { - type: string; - direction: CASHFLOW_DIRECTION; - creditType: string[]; -} - -export const BankTransactionsSampleData = [ - { - Amount: '6,410.19', - Date: '2024-03-26', - Payee: 'MacGyver and Sons', - 'Reference No.': 'REF-1', - Description: 'Commodi quo labore.', - }, - { - Amount: '8,914.17', - Date: '2024-01-05', - Payee: 'Eichmann - Bergnaum', - 'Reference No.': 'REF-1', - Description: 'Quia enim et.', - }, - { - Amount: '6,200.88', - Date: '2024-02-17', - Payee: 'Luettgen, Mraz and Legros', - 'Reference No.': 'REF-1', - Description: 'Occaecati consequuntur cum impedit illo.', - }, -]; diff --git a/packages/server/src/services/Cashflow/subscribers/DecrementUncategorizedTransactionOnCategorize.ts b/packages/server/src/services/Cashflow/subscribers/DecrementUncategorizedTransactionOnCategorize.ts deleted file mode 100644 index bd008967b..000000000 --- a/packages/server/src/services/Cashflow/subscribers/DecrementUncategorizedTransactionOnCategorize.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Inject, Service } from 'typedi'; -import PromisePool from '@supercharge/promise-pool'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - ICashflowTransactionCategorizedPayload, - ICashflowTransactionUncategorizedPayload, -} from '@/interfaces'; - -@Service() -export class DecrementUncategorizedTransactionOnCategorize { - @Inject() - private tenancy: HasTenancyService; - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.cashflow.onTransactionCategorized, - this.decrementUnCategorizedTransactionsOnCategorized.bind(this) - ); - bus.subscribe( - events.cashflow.onTransactionUncategorized, - this.incrementUnCategorizedTransactionsOnUncategorized.bind(this) - ); - bus.subscribe( - events.cashflow.onTransactionUncategorizedCreated, - this.incrementUncategoirzedTransactionsOnCreated.bind(this) - ); - } - - /** - * Decrement the uncategoirzed transactions on the account once categorizing. - * @param {ICashflowTransactionCategorizedPayload} - */ - public async decrementUnCategorizedTransactionsOnCategorized({ - tenantId, - uncategorizedTransactions, - trx, - }: ICashflowTransactionCategorizedPayload) { - const { Account } = this.tenancy.models(tenantId); - - await PromisePool.withConcurrency(1) - .for(uncategorizedTransactions) - .process(async (uncategorizedTransaction) => { - // Cannot continue if the transaction is still pending. - if (uncategorizedTransaction.isPending) { - return; - } - await Account.query(trx) - .findById(uncategorizedTransaction.accountId) - .decrement('uncategorizedTransactions', 1); - }); - } - - /** - * Increment the uncategorized transaction on the given account on uncategorizing. - * @param {IManualJournalDeletingPayload} - */ - public async incrementUnCategorizedTransactionsOnUncategorized({ - tenantId, - uncategorizedTransactions, - trx, - }: ICashflowTransactionUncategorizedPayload) { - const { Account } = this.tenancy.models(tenantId); - - await PromisePool.withConcurrency(1) - .for(uncategorizedTransactions) - .process(async (uncategorizedTransaction) => { - // Cannot continue if the transaction is still pending. - if (uncategorizedTransaction.isPending) { - return; - } - await Account.query(trx) - .findById(uncategorizedTransaction.accountId) - .increment('uncategorizedTransactions', 1); - }); - } - - /** - * Increments uncategorized transactions count once creating a new transaction. - * @param {ICommandCashflowCreatedPayload} payload - - */ - public async incrementUncategoirzedTransactionsOnCreated({ - tenantId, - uncategorizedTransaction, - trx, - }: any) { - const { Account } = this.tenancy.models(tenantId); - - if (!uncategorizedTransaction.accountId) return; - - // Cannot continue if the transaction is still pending. - if (uncategorizedTransaction.isPending) return; - - await Account.query(trx) - .findById(uncategorizedTransaction.accountId) - .increment('uncategorizedTransactions', 1); - } -} diff --git a/packages/server/src/services/Cashflow/subscribers/DeleteCashflowTransactionOnUncategorize.ts b/packages/server/src/services/Cashflow/subscribers/DeleteCashflowTransactionOnUncategorize.ts deleted file mode 100644 index 42f69050b..000000000 --- a/packages/server/src/services/Cashflow/subscribers/DeleteCashflowTransactionOnUncategorize.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { PromisePool } from '@supercharge/promise-pool'; -import events from '@/subscribers/events'; -import { ICashflowTransactionUncategorizedPayload } from '@/interfaces'; -import { DeleteCashflowTransaction } from '../DeleteCashflowTransactionService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; - -@Service() -export class DeleteCashflowTransactionOnUncategorize { - @Inject() - private deleteCashflowTransactionService: DeleteCashflowTransaction; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.cashflow.onTransactionUncategorized, - this.deleteCashflowTransactionOnUncategorize.bind(this) - ); - }; - - /** - * Deletes the cashflow transaction once uncategorize the bank transaction. - * @param {ICashflowTransactionUncategorizedPayload} payload - */ - public async deleteCashflowTransactionOnUncategorize({ - tenantId, - oldMainUncategorizedTransaction, - trx, - }: ICashflowTransactionUncategorizedPayload) { - // Cannot continue if the main transaction does not reference to cashflow type. - if ( - oldMainUncategorizedTransaction.categorizeRefType !== - 'CashflowTransaction' - ) { - return; - } - await this.deleteCashflowTransactionService.deleteCashflowTransaction( - tenantId, - oldMainUncategorizedTransaction.categorizeRefId, - trx - ); - } -} diff --git a/packages/server/src/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete.ts b/packages/server/src/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete.ts deleted file mode 100644 index e45404461..000000000 --- a/packages/server/src/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { ICommandCashflowDeletingPayload } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from '../constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class PreventDeleteTransactionOnDelete { - @Inject() - private tenancy: HasTenancyService; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.cashflow.onTransactionDeleting, - this.preventDeleteCashflowTransactionHasUncategorizedTransaction.bind( - this - ) - ); - }; - - /** - * Prevent delete cashflow transaction has converted from uncategorized transaction. - * @param {ICommandCashflowDeletingPayload} payload - */ - public async preventDeleteCashflowTransactionHasUncategorizedTransaction({ - tenantId, - oldCashflowTransaction, - trx, - }: ICommandCashflowDeletingPayload) { - const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId); - if (oldCashflowTransaction.uncategorizedTransactionId) { - const foundTransactions = await UncategorizedCashflowTransaction.query( - trx - ).where({ - categorized: true, - categorizeRefId: oldCashflowTransaction.id, - categorizeRefType: 'CashflowTransaction', - }); - // Throw the error if the cashflow transaction still linked to uncategorized transaction. - if (foundTransactions.length > 0) { - throw new ServiceError( - ERRORS.CANNOT_DELETE_TRANSACTION_CONVERTED_FROM_UNCATEGORIZED, - 'Cannot delete cashflow transaction converted from uncategorized transaction.' - ); - } - } - } -} diff --git a/packages/server/src/services/Cashflow/utils.ts b/packages/server/src/services/Cashflow/utils.ts deleted file mode 100644 index 98918de9b..000000000 --- a/packages/server/src/services/Cashflow/utils.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { upperFirst, camelCase, first, sum, sumBy } from 'lodash'; -import { - CASHFLOW_TRANSACTION_TYPE, - CASHFLOW_TRANSACTION_TYPE_META, - ERRORS, - ICashflowTransactionTypeMeta, -} from './constants'; -import { - ICashflowNewCommandDTO, - ICategorizeCashflowTransactioDTO, - IUncategorizedCashflowTransaction, -} from '@/interfaces'; -import { UncategorizeCashflowTransaction } from './UncategorizeCashflowTransaction'; -import { ServiceError } from '@/exceptions'; - -/** - * Ensures the given transaction type to transformed to appropriate format. - * @param {string} type - * @returns {string} - */ -export const transformCashflowTransactionType = (type) => { - return upperFirst(camelCase(type)); -}; - -/** - * Retrieve the cashflow transaction type meta. - * @param {CASHFLOW_TRANSACTION_TYPE} transactionType - * @returns {ICashflowTransactionTypeMeta} - */ -export function getCashflowTransactionType( - transactionType: CASHFLOW_TRANSACTION_TYPE -): ICashflowTransactionTypeMeta { - const _transactionType = transformCashflowTransactionType(transactionType); - - return CASHFLOW_TRANSACTION_TYPE_META[_transactionType]; -} - -/** - * Retrieve cashflow accounts transactions types - * @returns {string} - */ -export const getCashflowAccountTransactionsTypes = () => { - return Object.values(CASHFLOW_TRANSACTION_TYPE_META).map((meta) => meta.type); -}; - -/** - * Tranasformes the given uncategorized transaction and categorized DTO - * to cashflow create DTO. - * @param {IUncategorizedCashflowTransaction} uncategorizeModel - * @param {ICategorizeCashflowTransactioDTO} categorizeDTO - * @returns {ICashflowNewCommandDTO} - */ -export const transformCategorizeTransToCashflow = ( - uncategorizeTransactions: Array, - categorizeDTO: ICategorizeCashflowTransactioDTO -): ICashflowNewCommandDTO => { - const uncategorizeTransaction = first(uncategorizeTransactions); - const amount = sumBy(uncategorizeTransactions, 'amount'); - const amountAbs = Math.abs(amount); - - return { - date: categorizeDTO.date, - referenceNo: categorizeDTO.referenceNo, - description: categorizeDTO.description, - cashflowAccountId: uncategorizeTransaction.accountId, - creditAccountId: categorizeDTO.creditAccountId, - exchangeRate: categorizeDTO.exchangeRate || 1, - currencyCode: categorizeDTO.currencyCode, - amount: amountAbs, - transactionNumber: categorizeDTO.transactionNumber, - transactionType: categorizeDTO.transactionType, - branchId: categorizeDTO?.branchId, - publish: true, - }; -}; - -export const validateUncategorizedTransactionsNotExcluded = ( - transactions: Array -) => { - const excluded = transactions.filter((tran) => tran.excluded); - - if (excluded?.length > 0) { - throw new ServiceError(ERRORS.CANNOT_CATEGORIZE_EXCLUDED_TRANSACTION, '', { - ids: excluded.map((t) => t.id), - }); - } -}; - - -export const validateTransactionShouldBeCategorized = ( - uncategorizedTransaction: any -) => { - if (!uncategorizedTransaction.categorized) { - throw new ServiceError(ERRORS.TRANSACTION_NOT_CATEGORIZED); - } -}; diff --git a/packages/server/src/services/ChromiumlyTenancy/ChromiumlyHtmlConvert.ts b/packages/server/src/services/ChromiumlyTenancy/ChromiumlyHtmlConvert.ts deleted file mode 100644 index 51cf77f7c..000000000 --- a/packages/server/src/services/ChromiumlyTenancy/ChromiumlyHtmlConvert.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Inject, Service } from 'typedi'; -import path from 'path'; -import { promises as fs } from 'fs'; -import { PageProperties, PdfFormat } from '@/lib/Chromiumly/_types'; -import { UrlConverter } from '@/lib/Chromiumly/UrlConvert'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { Chromiumly } from '@/lib/Chromiumly/Chromiumly'; -import { - PDF_FILE_EXPIRE_IN, - getPdfFilePath, - getPdfFilesStorageDir, -} from './utils'; - -@Service() -export class ChromiumlyHtmlConvert { - @Inject() - private tenancy: HasTenancyService; - - /** - * Write HTML content to temporary file. - * @param {number} tenantId - Tenant id. - * @param {string} content - HTML content. - * @returns {Promise<[string, () => Promise]>} - */ - async writeTempHtmlFile( - tenantId: number, - content: string - ): Promise<[string, () => Promise]> { - const { Document } = this.tenancy.models(tenantId); - - const filename = `document-print-${Date.now()}.html`; - const filePath = getPdfFilePath(filename); - - await fs.writeFile(filePath, content); - await Document.query().insert({ key: filename, mimeType: 'text/html' }); - const cleanup = async () => { - await fs.unlink(filePath); - await Document.query().where('key', filename).delete(); - }; - return [filename, cleanup]; - } - - /** - * Converts the given HTML content to PDF. - * @param {string} html - * @param {PageProperties} properties - * @param {PdfFormat} pdfFormat - * @returns {Array} - */ - async convert( - tenantId: number, - html: string, - properties?: PageProperties, - pdfFormat?: PdfFormat - ): Promise { - const [filename, cleanupTempFile] = await this.writeTempHtmlFile( - tenantId, - html - ); - const fileDir = getPdfFilesStorageDir(filename); - - const url = path.join(Chromiumly.GOTENBERG_DOCS_ENDPOINT, fileDir); - const urlConverter = new UrlConverter(); - - const buffer = await urlConverter.convert({ - url, - properties, - pdfFormat, - }); - await cleanupTempFile(); - - return buffer; - } -} diff --git a/packages/server/src/services/ChromiumlyTenancy/ChromiumlyTenancy.ts b/packages/server/src/services/ChromiumlyTenancy/ChromiumlyTenancy.ts deleted file mode 100644 index 3e8a37daf..000000000 --- a/packages/server/src/services/ChromiumlyTenancy/ChromiumlyTenancy.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { PageProperties, PdfFormat } from '@/lib/Chromiumly/_types'; -import { ChromiumlyHtmlConvert } from './ChromiumlyHtmlConvert'; - -@Service() -export class ChromiumlyTenancy { - @Inject() - private htmlConvert: ChromiumlyHtmlConvert; - - /** - * Converts the given HTML content to PDF. - * @param {string} content - * @param {PageProperties} properties - * @param {PdfFormat} pdfFormat - * @returns {Promise} - */ - public convertHtmlContent( - tenantId: number, - content: string, - properties?: PageProperties, - pdfFormat?: PdfFormat - ) { - const parsedProperties = { - margins: { top: 0, bottom: 0, left: 0, right: 0 }, - ...properties, - } - return this.htmlConvert.convert(tenantId, content, parsedProperties, pdfFormat); - } -} diff --git a/packages/server/src/services/ChromiumlyTenancy/utils.ts b/packages/server/src/services/ChromiumlyTenancy/utils.ts deleted file mode 100644 index fd7bf7bce..000000000 --- a/packages/server/src/services/ChromiumlyTenancy/utils.ts +++ /dev/null @@ -1,14 +0,0 @@ -import path from 'path'; - -export const PDF_FILE_SUB_DIR = '/pdf'; -export const PDF_FILE_EXPIRE_IN = 40; // ms - -export const getPdfFilesStorageDir = (filename: string) => { - return path.join(PDF_FILE_SUB_DIR, filename); -}; - -export const getPdfFilePath = (filename: string) => { - const storageDir = getPdfFilesStorageDir(filename); - - return path.join(global.__storage_dir, storageDir); -}; diff --git a/packages/server/src/services/Contacts/ContactTransformer.ts b/packages/server/src/services/Contacts/ContactTransformer.ts deleted file mode 100644 index ceaeeec6c..000000000 --- a/packages/server/src/services/Contacts/ContactTransformer.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { isNull } from 'lodash'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { IContact } from '@/interfaces'; - -export default class ContactTransfromer extends Transformer { - /** - * Retrieve formatted expense amount. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedBalance = (contact: IContact): string => { - return formatNumber(contact.balance, { - currencyCode: contact.currencyCode, - }); - }; - - /** - * Retrieve formatted expense landed cost amount. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedOpeningBalance = (contact: IContact): string => { - return !isNull(contact.openingBalance) - ? formatNumber(contact.openingBalance, { - currencyCode: contact.currencyCode, - }) - : ''; - }; - - /** - * Retriecve fromatted date. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedOpeningBalanceAt = (contact: IContact): string => { - return !isNull(contact.openingBalanceAt) - ? this.formatDate(contact.openingBalanceAt) - : ''; - }; -} diff --git a/packages/server/src/services/Contacts/ContactsService.ts b/packages/server/src/services/Contacts/ContactsService.ts deleted file mode 100644 index a71d57b5b..000000000 --- a/packages/server/src/services/Contacts/ContactsService.ts +++ /dev/null @@ -1,378 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { difference, upperFirst, omit } from 'lodash'; -import moment from 'moment'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { ServiceError } from '@/exceptions'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { - IContact, - IContactNewDTO, - IContactEditDTO, - IContactsAutoCompleteFilter, -} from '@/interfaces'; -import JournalPoster from '../Accounting/JournalPoster'; -import { ERRORS } from './constants'; - -type TContactService = 'customer' | 'vendor'; - -@Service() -export default class ContactsService { - @Inject() - tenancy: TenancyService; - - @Inject() - dynamicListService: DynamicListingService; - - @Inject('logger') - logger: any; - - /** - * Get the given contact or throw not found contact. - * @param {number} tenantId - * @param {number} contactId - * @param {TContactService} contactService - * @return {Promise} - */ - public async getContactByIdOrThrowError( - tenantId: number, - contactId: number, - contactService?: TContactService - ) { - const { contactRepository } = this.tenancy.repositories(tenantId); - - const contact = await contactRepository.findOne({ - id: contactId, - ...(contactService && { contactService }), - }); - - if (!contact) { - throw new ServiceError('contact_not_found'); - } - return contact; - } - - /** - * Converts contact DTO object to model object attributes to insert or update. - * @param {IContactNewDTO | IContactEditDTO} contactDTO - */ - private commonTransformContactObj( - contactDTO: IContactNewDTO | IContactEditDTO - ) { - return { - ...omit(contactDTO, [ - 'billingAddress1', - 'billingAddress2', - 'shippingAddress1', - 'shippingAddress2', - ]), - billing_address_1: contactDTO?.billingAddress1, - billing_address_2: contactDTO?.billingAddress2, - shipping_address_1: contactDTO?.shippingAddress1, - shipping_address_2: contactDTO?.shippingAddress2, - }; - } - - /** - * Transforms contact new DTO object to model object to insert to the storage. - * @param {IContactNewDTO} contactDTO - */ - private transformNewContactDTO(contactDTO: IContactNewDTO) { - const baseCurrency = 'USD'; - const currencyCode = - typeof contactDTO.currencyCode !== 'undefined' - ? contactDTO.currencyCode - : baseCurrency; - - return { - ...this.commonTransformContactObj(contactDTO), - ...(currencyCode ? { currencyCode } : {}), - }; - } - - /** - * Transforms contact edit DTO object to model object to update to the storage. - * @param {IContactEditDTO} contactDTO - */ - private transformEditContactDTO(contactDTO: IContactEditDTO) { - return { - ...this.commonTransformContactObj(contactDTO), - }; - } - - /** - * Creates a new contact on the storage. - * @param {number} tenantId - * @param {TContactService} contactService - * @param {IContactDTO} contactDTO - */ - async newContact( - tenantId: number, - contactDTO: IContactNewDTO, - contactService: TContactService, - trx?: Knex.Transaction - ) { - const { contactRepository } = this.tenancy.repositories(tenantId); - const contactObj = this.transformNewContactDTO(contactDTO); - - const contact = await contactRepository.create( - { - contactService, - ...contactObj, - }, - trx - ); - return contact; - } - - /** - * Edit details of the given on the storage. - * @param {number} tenantId - * @param {number} contactId - * @param {TContactService} contactService - * @param {IContactDTO} contactDTO - */ - async editContact( - tenantId: number, - contactId: number, - contactDTO: IContactEditDTO, - contactService: TContactService, - trx?: Knex.Transaction - ) { - const { contactRepository } = this.tenancy.repositories(tenantId); - const contactObj = this.transformEditContactDTO(contactDTO); - - // Retrieve the given contact by id or throw not found service error. - const contact = await this.getContactByIdOrThrowError( - tenantId, - contactId, - contactService - ); - return contactRepository.update({ ...contactObj }, { id: contactId }, trx); - } - - /** - * Deletes the given contact from the storage. - * @param {number} tenantId - * @param {number} contactId - * @param {TContactService} contactService - * @return {Promise} - */ - async deleteContact( - tenantId: number, - contactId: number, - contactService: TContactService, - trx?: Knex.Transaction - ) { - const { contactRepository } = this.tenancy.repositories(tenantId); - - const contact = await this.getContactByIdOrThrowError( - tenantId, - contactId, - contactService - ); - // Deletes contact of the given id. - await contactRepository.deleteById(contactId, trx); - } - - /** - * Get contact details of the given contact id. - * @param {number} tenantId - * @param {number} contactId - * @param {TContactService} contactService - * @returns {Promise} - */ - async getContact( - tenantId: number, - contactId: number, - contactService?: TContactService - ) { - return this.getContactByIdOrThrowError(tenantId, contactId, contactService); - } - - /** - * Parsees accounts list filter DTO. - * @param filterDTO - */ - private parseAutocompleteListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } - - /** - * Retrieve auto-complete contacts list. - * @param {number} tenantId - - * @param {IContactsAutoCompleteFilter} contactsFilter - - * @return {IContactAutoCompleteItem} - */ - async autocompleteContacts( - tenantId: number, - query: IContactsAutoCompleteFilter - ) { - const { Contact } = this.tenancy.models(tenantId); - - // Parses auto-complete list filter DTO. - const filter = this.parseAutocompleteListFilterDTO(query); - - // Dynamic list. - // const dynamicList = await this.dynamicListService.dynamicList( - // tenantId, - // Contact, - // filter - // ); - // Retrieve contacts list by the given query. - const contacts = await Contact.query().onBuild((builder) => { - if (filter.keyword) { - builder.where('display_name', 'LIKE', `%${filter.keyword}%`); - } - // dynamicList.buildQuery()(builder); - builder.limit(filter.limit); - }); - return contacts; - } - - /** - * Retrieve contacts or throw not found error if one of ids were not found - * on the storage. - * @param {number} tenantId - * @param {number[]} contactsIds - * @param {TContactService} contactService - * @return {Promise} - */ - async getContactsOrThrowErrorNotFound( - tenantId: number, - contactsIds: number[], - contactService: TContactService - ) { - const { Contact } = this.tenancy.models(tenantId); - const contacts = await Contact.query() - .whereIn('id', contactsIds) - .where('contact_service', contactService); - - const storedContactsIds = contacts.map((contact: IContact) => contact.id); - const notFoundCustomers = difference(contactsIds, storedContactsIds); - - if (notFoundCustomers.length > 0) { - throw new ServiceError('contacts_not_found'); - } - return contacts; - } - - /** - * Deletes the given contacts in bulk. - * @param {number} tenantId - * @param {number[]} contactsIds - * @param {TContactService} contactService - * @return {Promise} - */ - async deleteBulkContacts( - tenantId: number, - contactsIds: number[], - contactService: TContactService - ) { - const { contactRepository } = this.tenancy.repositories(tenantId); - - // Retrieve the given contacts or throw not found service error. - this.getContactsOrThrowErrorNotFound(tenantId, contactsIds, contactService); - - await contactRepository.deleteWhereIdIn(contactsIds); - } - - /** - * Reverts journal entries of the given contacts. - * @param {number} tenantId - * @param {number[]} contactsIds - * @param {TContactService} contactService - */ - async revertJEntriesContactsOpeningBalance( - tenantId: number, - contactsIds: number[], - contactService: TContactService, - trx?: Knex.Transaction - ) { - const { AccountTransaction } = this.tenancy.models(tenantId); - const journal = new JournalPoster(tenantId, null, trx); - - // Loads the contact opening balance journal transactions. - const contactsTransactions = await AccountTransaction.query() - .whereIn('reference_id', contactsIds) - .where('reference_type', `${upperFirst(contactService)}OpeningBalance`); - - journal.fromTransactions(contactsTransactions); - journal.removeEntries(); - - await Promise.all([journal.saveBalance(), journal.deleteEntries()]); - } - - /** - * Chanages the opening balance of the given contact. - * @param {number} tenantId - * @param {number} contactId - * @param {ICustomerChangeOpeningBalanceDTO} changeOpeningBalance - * @return {Promise} - */ - public async changeOpeningBalance( - tenantId: number, - contactId: number, - contactService: string, - openingBalance: number, - openingBalanceAt?: Date | string - ): Promise { - const { contactRepository } = this.tenancy.repositories(tenantId); - - // Retrieve the given contact details or throw not found service error. - const contact = await this.getContactByIdOrThrowError( - tenantId, - contactId, - contactService - ); - // Should the opening balance date be required. - if (!contact.openingBalanceAt && !openingBalanceAt) { - throw new ServiceError(ERRORS.OPENING_BALANCE_DATE_REQUIRED); - } - // Changes the customer the opening balance and opening balance date. - await contactRepository.update( - { - openingBalance: openingBalance, - - ...(openingBalanceAt && { - openingBalanceAt: moment(openingBalanceAt).toMySqlDateTime(), - }), - }, - { - id: contactId, - contactService, - } - ); - } - - /** - * Inactive the given contact. - * @param {number} tenantId - Tenant id. - * @param {number} contactId - Contact id. - */ - async inactivateContact(tenantId: number, contactId: number): Promise { - const { Contact } = this.tenancy.models(tenantId); - const contact = await this.getContactByIdOrThrowError(tenantId, contactId); - - if (!contact.active) { - throw new ServiceError(ERRORS.CONTACT_ALREADY_INACTIVE); - } - await Contact.query().findById(contactId).update({ active: false }); - } - - /** - * Inactive the given contact. - * @param {number} tenantId - Tenant id. - * @param {number} contactId - Contact id. - */ - async activateContact(tenantId: number, contactId: number): Promise { - const { Contact } = this.tenancy.models(tenantId); - const contact = await this.getContactByIdOrThrowError(tenantId, contactId); - - if (contact.active) { - throw new ServiceError(ERRORS.CONTACT_ALREADY_ACTIVE); - } - await Contact.query().findById(contactId).update({ active: true }); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/ActivateCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/ActivateCustomer.ts deleted file mode 100644 index d87ef42cf..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/ActivateCustomer.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { CustomerValidators } from './CustomerValidators'; -import { - ICustomerActivatingPayload, - ICustomerActivatedPayload, -} from '@/interfaces'; - -@Service() -export class ActivateCustomer { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: CustomerValidators; - - /** - * Inactive the given contact. - * @param {number} tenantId - Tenant id. - * @param {number} contactId - Contact id. - * @returns {Promise} - */ - public async activateCustomer( - tenantId: number, - customerId: number - ): Promise { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieves the customer or throw not found error. - const oldCustomer = await Contact.query() - .findById(customerId) - .modify('customer') - .throwIfNotFound(); - - this.validators.validateNotAlreadyPublished(oldCustomer); - - // Edits the given customer with associated transactions on unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCustomerActivating` event. - await this.eventPublisher.emitAsync(events.customers.onActivating, { - tenantId, - trx, - oldCustomer, - } as ICustomerActivatingPayload); - - // Update the given customer details. - const customer = await Contact.query(trx) - .findById(customerId) - .update({ active: true }); - - // Triggers `onCustomerActivated` event. - await this.eventPublisher.emitAsync(events.customers.onActivated, { - tenantId, - trx, - oldCustomer, - customer, - } as ICustomerActivatedPayload); - }); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts deleted file mode 100644 index aaa32f540..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/CreateCustomer.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - ICustomer, - ICustomerEventCreatedPayload, - ICustomerEventCreatingPayload, - ICustomerNewDTO, - ISystemUser, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { CreateEditCustomerDTO } from './CreateEditCustomerDTO'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class CreateCustomer { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private customerDTO: CreateEditCustomerDTO; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Creates a new customer. - * @param {number} tenantId - * @param {ICustomerNewDTO} customerDTO - * @return {Promise} - */ - public async createCustomer( - tenantId: number, - customerDTO: ICustomerNewDTO, - trx?: Knex.Transaction - ): Promise { - const { Contact } = this.tenancy.models(tenantId); - - // Transformes the customer DTO to customer object. - const customerObj = await this.customerDTO.transformCreateDTO( - tenantId, - customerDTO - ); - // Creates a new customer under unit-of-work envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onCustomerCreating` event. - await this.eventPublisher.emitAsync(events.customers.onCreating, { - tenantId, - customerDTO, - trx, - } as ICustomerEventCreatingPayload); - - // Creates a new contact as customer. - const customer = await Contact.query(trx).insertAndFetch({ - ...customerObj, - }); - // Triggers `onCustomerCreated` event. - await this.eventPublisher.emitAsync(events.customers.onCreated, { - customer, - tenantId, - customerId: customer.id, - trx, - } as ICustomerEventCreatedPayload); - - return customer; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/CreateEditCustomerDTO.ts b/packages/server/src/services/Contacts/Customers/CRUD/CreateEditCustomerDTO.ts deleted file mode 100644 index a9178e69a..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/CreateEditCustomerDTO.ts +++ /dev/null @@ -1,73 +0,0 @@ -import moment from 'moment'; -import { defaultTo, omit, isEmpty } from 'lodash'; -import { Service } from 'typedi'; -import { - ContactService, - ICustomer, - ICustomerEditDTO, - ICustomerNewDTO, -} from '@/interfaces'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class CreateEditCustomerDTO { - /** - * Transformes the create/edit DTO. - * @param {ICustomerNewDTO | ICustomerEditDTO} customerDTO - * @returns - */ - private transformCommonDTO = ( - customerDTO: ICustomerNewDTO | ICustomerEditDTO - ): Partial => { - return { - ...omit(customerDTO, ['customerType']), - contactType: customerDTO.customerType, - }; - }; - - /** - * Transformes the create DTO. - * @param {ICustomerNewDTO} customerDTO - * @returns {} - */ - public transformCreateDTO = async ( - tenantId: number, - customerDTO: ICustomerNewDTO - ) => { - const commonDTO = this.transformCommonDTO(customerDTO); - - // Retrieves the tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - return { - ...commonDTO, - currencyCode: commonDTO.currencyCode || tenantMeta?.baseCurrency, - active: defaultTo(customerDTO.active, true), - contactService: ContactService.Customer, - ...(!isEmpty(customerDTO.openingBalanceAt) - ? { - openingBalanceAt: moment( - customerDTO?.openingBalanceAt - ).toMySqlDateTime(), - } - : {}), - openingBalanceExchangeRate: defaultTo( - customerDTO.openingBalanceExchangeRate, - 1 - ), - }; - }; - - /** - * Transformes the edit DTO. - * @param {ICustomerEditDTO} customerDTO - * @returns - */ - public transformEditDTO = (customerDTO: ICustomerEditDTO) => { - const commonDTO = this.transformCommonDTO(customerDTO); - - return { - ...commonDTO, - }; - }; -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/CustomerValidators.ts b/packages/server/src/services/Contacts/Customers/CRUD/CustomerValidators.ts deleted file mode 100644 index 81bde6ebb..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/CustomerValidators.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { Service, Inject } from 'typedi'; -import { ERRORS } from '../constants'; - -@Service() -export class CustomerValidators { - /** - * Validates the given customer is not already published. - * @param {ICustomer} customer - */ - public validateNotAlreadyPublished = (customer) => { - if (customer.active) { - throw new ServiceError(ERRORS.CUSTOMER_ALREADY_ACTIVE); - } - }; -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/DeleteCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/DeleteCustomer.ts deleted file mode 100644 index ad4f197de..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/DeleteCustomer.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - ICustomerDeletingPayload, - ICustomerEventDeletedPayload, - ISystemUser, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from '../constants'; - -@Service() -export class DeleteCustomer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes the given customer from the storage. - * @param {number} tenantId - * @param {number} customerId - * @return {Promise} - */ - public async deleteCustomer( - tenantId: number, - customerId: number, - authorizedUser: ISystemUser - ): Promise { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieve the customer of throw not found service error. - const oldCustomer = await Contact.query() - .findById(customerId) - .modify('customer') - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.CUSTOMER_HAS_TRANSACTIONS, - }); - - // Triggers `onCustomerDeleting` event. - await this.eventPublisher.emitAsync(events.customers.onDeleting, { - tenantId, - customerId, - oldCustomer, - } as ICustomerDeletingPayload); - - // Deletes the customer and associated entities under UOW transaction. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Delete the customer from the storage. - await Contact.query(trx).findById(customerId).delete(); - - // Throws `onCustomerDeleted` event. - await this.eventPublisher.emitAsync(events.customers.onDeleted, { - tenantId, - customerId, - oldCustomer, - authorizedUser, - trx, - } as ICustomerEventDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/EditCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/EditCustomer.ts deleted file mode 100644 index 410eec884..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/EditCustomer.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Knex } from 'knex'; -import { - ICustomer, - ICustomerEditDTO, - ICustomerEventEditedPayload, - ICustomerEventEditingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CreateEditCustomerDTO } from './CreateEditCustomerDTO'; - -@Service() -export class EditCustomer { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private customerDTO: CreateEditCustomerDTO; - - /** - * Edits details of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {ICustomerEditDTO} customerDTO - * @return {Promise} - */ - public async editCustomer( - tenantId: number, - customerId: number, - customerDTO: ICustomerEditDTO - ): Promise { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieve the vendor or throw not found error. - const oldCustomer = await Contact.query() - .findById(customerId) - .modify('customer') - .throwIfNotFound(); - - // Transformes the given customer DTO to object. - const customerObj = this.customerDTO.transformEditDTO(customerDTO); - - // Edits the given customer under unit-of-work evnirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCustomerEditing` event. - await this.eventPublisher.emitAsync(events.customers.onEditing, { - tenantId, - customerDTO, - customerId, - trx, - } as ICustomerEventEditingPayload); - - // Edits the customer details on the storage. - const customer = await Contact.query().updateAndFetchById(customerId, { - ...customerObj, - }); - // Triggers `onCustomerEdited` event. - await this.eventPublisher.emitAsync(events.customers.onEdited, { - tenantId, - customerId, - customer, - trx, - } as ICustomerEventEditedPayload); - - return customer; - }); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/EditOpeningBalanceCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/EditOpeningBalanceCustomer.ts deleted file mode 100644 index c8145d6c9..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/EditOpeningBalanceCustomer.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ICustomer, - ICustomerOpeningBalanceEditDTO, - ICustomerOpeningBalanceEditedPayload, - ICustomerOpeningBalanceEditingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; - -@Service() -export class EditOpeningBalanceCustomer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Changes the opening balance of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {number} openingBalance - * @param {string|Date} openingBalanceAt - */ - public async changeOpeningBalance( - tenantId: number, - customerId: number, - openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO - ): Promise { - const { Customer } = this.tenancy.models(tenantId); - - // Retrieves the old customer or throw not found error. - const oldCustomer = await Customer.query() - .findById(customerId) - .throwIfNotFound(); - - // Mutates the customer opening balance under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCustomerOpeningBalanceChanging` event. - await this.eventPublisher.emitAsync( - events.customers.onOpeningBalanceChanging, - { - tenantId, - oldCustomer, - openingBalanceEditDTO, - trx, - } as ICustomerOpeningBalanceEditingPayload - ); - // Mutates the customer on the storage. - const customer = await Customer.query().patchAndFetchById(customerId, { - ...openingBalanceEditDTO, - }); - // Triggers `onCustomerOpeingBalanceChanged` event. - await this.eventPublisher.emitAsync( - events.customers.onOpeningBalanceChanged, - { - tenantId, - customer, - oldCustomer, - openingBalanceEditDTO, - trx, - } as ICustomerOpeningBalanceEditedPayload - ); - return customer; - }); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/GetCustomer.ts b/packages/server/src/services/Contacts/Customers/CRUD/GetCustomer.ts deleted file mode 100644 index 47d7e08c8..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/GetCustomer.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import I18nService from '@/services/I18n/I18nService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import CustomerTransfromer from '../CustomerTransformer'; - -@Service() -export class GetCustomer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the given customer details. - * @param {number} tenantId - * @param {number} customerId - */ - public async getCustomer(tenantId: number, customerId: number) { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieve the customer model or throw not found error. - const customer = await Contact.query() - .modify('customer') - .findById(customerId) - .throwIfNotFound(); - - // Retrieves the transformered customers. - return this.transformer.transform( - tenantId, - customer, - new CustomerTransfromer() - ); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CRUD/GetCustomers.ts b/packages/server/src/services/Contacts/Customers/CRUD/GetCustomers.ts deleted file mode 100644 index 569207871..000000000 --- a/packages/server/src/services/Contacts/Customers/CRUD/GetCustomers.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { - ICustomer, - ICustomersFilter, - IFilterMeta, - IPaginationMeta, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import CustomerTransfromer from '../CustomerTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetCustomers { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Parses customers list filter DTO. - * @param filterDTO - - */ - private parseCustomersListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } - - /** - * Retrieve customers paginated list. - * @param {number} tenantId - Tenant id. - * @param {ICustomersFilter} filter - Cusotmers filter. - */ - public async getCustomersList( - tenantId: number, - filterDTO: ICustomersFilter - ): Promise<{ - customers: ICustomer[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { Customer } = this.tenancy.models(tenantId); - - // Parses customers list filter DTO. - const filter = this.parseCustomersListFilterDTO(filterDTO); - - // Dynamic list. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - Customer, - filter - ); - // Customers. - const { results, pagination } = await Customer.query() - .onBuild((builder) => { - dynamicList.buildQuery()(builder); - builder.modify('inactiveMode', filter.inactiveMode); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Retrieves the transformed customers. - const customers = await this.transformer.transform( - tenantId, - results, - new CustomerTransfromer() - ); - return { - customers, - pagination, - filterMeta: dynamicList.getResponseMeta(), - }; - } -} diff --git a/packages/server/src/services/Contacts/Customers/CustomerGLEntries.ts b/packages/server/src/services/Contacts/Customers/CustomerGLEntries.ts deleted file mode 100644 index f5c382f94..000000000 --- a/packages/server/src/services/Contacts/Customers/CustomerGLEntries.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { AccountNormal, ICustomer, ILedgerEntry } from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export class CustomerGLEntries { - /** - * Retrieves the customer opening balance common entry attributes. - * @param {ICustomer} customer - */ - private getCustomerOpeningGLCommonEntry = (customer: ICustomer) => { - return { - exchangeRate: customer.openingBalanceExchangeRate, - currencyCode: customer.currencyCode, - - transactionType: 'CustomerOpeningBalance', - transactionId: customer.id, - - date: customer.openingBalanceAt, - userId: customer.userId, - contactId: customer.id, - - credit: 0, - debit: 0, - - branchId: customer.openingBalanceBranchId, - }; - }; - - /** - * Retrieves the customer opening GL credit entry. - * @param {number} ARAccountId - * @param {ICustomer} customer - * @returns {ILedgerEntry} - */ - private getCustomerOpeningGLCreditEntry = ( - ARAccountId: number, - customer: ICustomer - ): ILedgerEntry => { - const commonEntry = this.getCustomerOpeningGLCommonEntry(customer); - - return { - ...commonEntry, - credit: 0, - debit: customer.localOpeningBalance, - accountId: ARAccountId, - accountNormal: AccountNormal.DEBIT, - index: 1, - }; - }; - - /** - * Retrieves the customer opening GL debit entry. - * @param {number} incomeAccountId - * @param {ICustomer} customer - * @returns {ILedgerEntry} - */ - private getCustomerOpeningGLDebitEntry = ( - incomeAccountId: number, - customer: ICustomer - ): ILedgerEntry => { - const commonEntry = this.getCustomerOpeningGLCommonEntry(customer); - - return { - ...commonEntry, - credit: customer.localOpeningBalance, - debit: 0, - accountId: incomeAccountId, - accountNormal: AccountNormal.CREDIT, - - index: 2, - }; - }; - - /** - * Retrieves the customer opening GL entries. - * @param {number} ARAccountId - * @param {number} incomeAccountId - * @param {ICustomer} customer - * @returns {ILedgerEntry[]} - */ - public getCustomerOpeningGLEntries = ( - ARAccountId: number, - incomeAccountId: number, - customer: ICustomer - ) => { - const debitEntry = this.getCustomerOpeningGLDebitEntry( - incomeAccountId, - customer - ); - const creditEntry = this.getCustomerOpeningGLCreditEntry( - ARAccountId, - customer - ); - return [debitEntry, creditEntry]; - }; - - /** - * Retrieves the customer opening balance ledger. - * @param {number} ARAccountId - * @param {number} incomeAccountId - * @param {ICustomer} customer - * @returns {ILedger} - */ - public getCustomerOpeningLedger = ( - ARAccountId: number, - incomeAccountId: number, - customer: ICustomer - ) => { - const entries = this.getCustomerOpeningGLEntries( - ARAccountId, - incomeAccountId, - customer - ); - return new Ledger(entries); - }; -} diff --git a/packages/server/src/services/Contacts/Customers/CustomerGLEntriesStorage.ts b/packages/server/src/services/Contacts/Customers/CustomerGLEntriesStorage.ts deleted file mode 100644 index b2f2aef8c..000000000 --- a/packages/server/src/services/Contacts/Customers/CustomerGLEntriesStorage.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Knex } from 'knex'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import { CustomerGLEntries } from './CustomerGLEntries'; - -@Service() -export class CustomerGLEntriesStorage { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledegrRepository: LedgerStorageService; - - @Inject() - private customerGLEntries: CustomerGLEntries; - - /** - * Customer opening balance journals. - * @param {number} tenantId - * @param {number} customerId - * @param {Knex.Transaction} trx - */ - public writeCustomerOpeningBalance = async ( - tenantId: number, - customerId: number, - trx?: Knex.Transaction - ) => { - const { Customer } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - const customer = await Customer.query(trx).findById(customerId); - - // Finds the income account. - const incomeAccount = await accountRepository.findOne({ - slug: 'other-income', - }); - // Find or create the A/R account. - const ARAccount = await accountRepository.findOrCreateAccountReceivable( - customer.currencyCode, - {}, - trx - ); - // Retrieves the customer opening balance ledger. - const ledger = this.customerGLEntries.getCustomerOpeningLedger( - ARAccount.id, - incomeAccount.id, - customer - ); - // Commits the ledger entries to the storage. - await this.ledegrRepository.commit(tenantId, ledger, trx); - }; - - /** - * Reverts the customer opening balance GL entries. - * @param {number} tenantId - * @param {number} customerId - * @param {Knex.Transaction} trx - */ - public revertCustomerOpeningBalance = async ( - tenantId: number, - customerId: number, - trx?: Knex.Transaction - ) => { - await this.ledegrRepository.deleteByReference( - tenantId, - customerId, - 'CustomerOpeningBalance', - trx - ); - }; - - /** - * Writes the customer opening balance GL entries. - * @param {number} tenantId - * @param {number} customerId - * @param {Knex.Transaction} trx - */ - public rewriteCustomerOpeningBalance = async ( - tenantId: number, - customerId: number, - trx?: Knex.Transaction - ) => { - // Reverts the customer opening balance entries. - await this.revertCustomerOpeningBalance(tenantId, customerId, trx); - - // Write the customer opening balance entries. - await this.writeCustomerOpeningBalance(tenantId, customerId, trx); - }; -} diff --git a/packages/server/src/services/Contacts/Customers/CustomerTransformer.ts b/packages/server/src/services/Contacts/Customers/CustomerTransformer.ts deleted file mode 100644 index 497430c0e..000000000 --- a/packages/server/src/services/Contacts/Customers/CustomerTransformer.ts +++ /dev/null @@ -1,38 +0,0 @@ -import ContactTransfromer from '../ContactTransformer'; - -export default class CustomerTransfromer extends ContactTransfromer { - /** - * Include these attributes to expense object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedBalance', - 'formattedOpeningBalance', - 'formattedOpeningBalanceAt', - 'customerType', - 'formattedCustomerType', - ]; - }; - - /** - * Retrieve customer type. - * @returns {string} - */ - protected customerType = (customer): string => { - return customer.contactType; - }; - - /** - * Retrieve the formatted customer type. - * @param customer - * @returns {string} - */ - protected formattedCustomerType = (customer): string => { - const keywords = { - individual: 'customer.type.individual', - business: 'customer.type.business', - }; - return this.context.i18n.__(keywords[customer.contactType] || ''); - }; -} diff --git a/packages/server/src/services/Contacts/Customers/CustomersApplication.ts b/packages/server/src/services/Contacts/Customers/CustomersApplication.ts deleted file mode 100644 index ac3b1dd3b..000000000 --- a/packages/server/src/services/Contacts/Customers/CustomersApplication.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { - ICustomer, - ICustomerEditDTO, - ICustomerNewDTO, - ICustomerOpeningBalanceEditDTO, - ICustomersFilter, - ISystemUser, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { CreateCustomer } from './CRUD/CreateCustomer'; -import { DeleteCustomer } from './CRUD/DeleteCustomer'; -import { EditCustomer } from './CRUD/EditCustomer'; -import { EditOpeningBalanceCustomer } from './CRUD/EditOpeningBalanceCustomer'; -import { GetCustomer } from './CRUD/GetCustomer'; -import { GetCustomers } from './CRUD/GetCustomers'; - -@Service() -export class CustomersApplication { - @Inject() - private getCustomerService: GetCustomer; - - @Inject() - private createCustomerService: CreateCustomer; - - @Inject() - private editCustomerService: EditCustomer; - - @Inject() - private deleteCustomerService: DeleteCustomer; - - @Inject() - private editOpeningBalanceService: EditOpeningBalanceCustomer; - - @Inject() - private getCustomersService: GetCustomers; - - /** - * Retrieves the given customer details. - * @param {number} tenantId - * @param {number} customerId - */ - public getCustomer = (tenantId: number, customerId: number) => { - return this.getCustomerService.getCustomer(tenantId, customerId); - }; - - /** - * Creates a new customer. - * @param {number} tenantId - * @param {ICustomerNewDTO} customerDTO - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public createCustomer = (tenantId: number, customerDTO: ICustomerNewDTO) => { - return this.createCustomerService.createCustomer(tenantId, customerDTO); - }; - - /** - * Edits details of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {ICustomerEditDTO} customerDTO - * @return {Promise} - */ - public editCustomer = ( - tenantId: number, - customerId: number, - customerDTO: ICustomerEditDTO - ) => { - return this.editCustomerService.editCustomer( - tenantId, - customerId, - customerDTO - ); - }; - - /** - * Deletes the given customer and associated transactions. - * @param {number} tenantId - * @param {number} customerId - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public deleteCustomer = ( - tenantId: number, - customerId: number, - authorizedUser: ISystemUser - ) => { - return this.deleteCustomerService.deleteCustomer( - tenantId, - customerId, - authorizedUser - ); - }; - - /** - * Changes the opening balance of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {Date|string} openingBalanceEditDTO - * @returns {Promise} - */ - public editOpeningBalance = ( - tenantId: number, - customerId: number, - openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO - ): Promise => { - return this.editOpeningBalanceService.changeOpeningBalance( - tenantId, - customerId, - openingBalanceEditDTO - ); - }; - - /** - * Retrieve customers paginated list. - * @param {number} tenantId - Tenant id. - * @param {ICustomersFilter} filter - Cusotmers filter. - */ - public getCustomers = (tenantId: number, filterDTO: ICustomersFilter) => { - return this.getCustomersService.getCustomersList(tenantId, filterDTO); - }; -} diff --git a/packages/server/src/services/Contacts/Customers/CustomersExportable.ts b/packages/server/src/services/Contacts/Customers/CustomersExportable.ts deleted file mode 100644 index 78eb51767..000000000 --- a/packages/server/src/services/Contacts/Customers/CustomersExportable.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IItemsFilter } from '@/interfaces'; -import { CustomersApplication } from './CustomersApplication'; -import { Exportable } from '@/services/Export/Exportable'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class CustomersExportable extends Exportable { - @Inject() - private customersApplication: CustomersApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IItemsFilter) { - const parsedQuery = { - sortOrder: 'DESC', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - } as IItemsFilter; - - return this.customersApplication - .getCustomers(tenantId, parsedQuery) - .then((output) => output.customers); - } -} diff --git a/packages/server/src/services/Contacts/Customers/CustomersImportable.ts b/packages/server/src/services/Contacts/Customers/CustomersImportable.ts deleted file mode 100644 index 599cfaf83..000000000 --- a/packages/server/src/services/Contacts/Customers/CustomersImportable.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Importable } from '@/services/Import/Importable'; -import { CreateCustomer } from './CRUD/CreateCustomer'; -import { Knex } from 'knex'; -import { ICustomer, ICustomerNewDTO } from '@/interfaces'; -import { CustomersSampleData } from './_SampleData'; - -@Service() -export class CustomersImportable extends Importable { - @Inject() - private createCustomerService: CreateCustomer; - - /** - * Mapps the imported data to create a new customer service. - * @param {number} tenantId - * @param {ICustomerNewDTO} createDTO - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public async importable( - tenantId: number, - createDTO: ICustomerNewDTO, - trx?: Knex.Transaction - ): Promise { - await this.createCustomerService.createCustomer(tenantId, createDTO, trx); - } - - /** - * Retrieves the sample data of customers used to download sample sheet. - */ - public sampleData(): any[] { - return CustomersSampleData; - } -} diff --git a/packages/server/src/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber.ts b/packages/server/src/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber.ts deleted file mode 100644 index 825b10dc6..000000000 --- a/packages/server/src/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - ICustomerEventCreatedPayload, - ICustomerEventDeletedPayload, - ICustomerOpeningBalanceEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { CustomerGLEntriesStorage } from '../CustomerGLEntriesStorage'; - -@Service() -export class CustomerWriteGLOpeningBalanceSubscriber { - @Inject() - private customerGLEntries: CustomerGLEntriesStorage; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.customers.onCreated, - this.handleWriteOpenBalanceEntries - ); - bus.subscribe( - events.customers.onDeleted, - this.handleRevertOpeningBalanceEntries - ); - bus.subscribe( - events.customers.onOpeningBalanceChanged, - this.handleRewriteOpeningEntriesOnChanged - ); - } - - /** - * Handles the writing opening balance journal entries once the customer created. - * @param {ICustomerEventCreatedPayload} payload - - */ - private handleWriteOpenBalanceEntries = async ({ - tenantId, - customer, - trx, - }: ICustomerEventCreatedPayload) => { - // Writes the customer opening balance journal entries. - if (customer.openingBalance) { - await this.customerGLEntries.writeCustomerOpeningBalance( - tenantId, - customer.id, - trx - ); - } - }; - - /** - * Handles the deleting opeing balance journal entrise once the customer deleted. - * @param {ICustomerEventDeletedPayload} payload - - */ - private handleRevertOpeningBalanceEntries = async ({ - tenantId, - customerId, - trx, - }: ICustomerEventDeletedPayload) => { - await this.customerGLEntries.revertCustomerOpeningBalance( - tenantId, - customerId, - trx - ); - }; - - /** - * Handles the rewrite opening balance entries once opening balnace changed. - * @param {ICustomerOpeningBalanceEditedPayload} payload - - */ - private handleRewriteOpeningEntriesOnChanged = async ({ - tenantId, - customer, - trx, - }: ICustomerOpeningBalanceEditedPayload) => { - if (customer.openingBalance) { - await this.customerGLEntries.rewriteCustomerOpeningBalance( - tenantId, - customer.id, - trx - ); - } else { - await this.customerGLEntries.revertCustomerOpeningBalance( - tenantId, - customer.id, - trx - ); - } - }; -} diff --git a/packages/server/src/services/Contacts/Customers/_SampleData.ts b/packages/server/src/services/Contacts/Customers/_SampleData.ts deleted file mode 100644 index 601d845d5..000000000 --- a/packages/server/src/services/Contacts/Customers/_SampleData.ts +++ /dev/null @@ -1,158 +0,0 @@ - -export const CustomersSampleData = [ - { - "Customer Type": "Business", - "First Name": "Nicolette", - "Last Name": "Schamberger", - "Company Name": "Homenick - Hane", - "Display Name": "Rowland Rowe", - "Email": "cicero86@yahoo.com", - "Personal Phone Number": "811-603-2235", - "Work Phone Number": "906-993-5190", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "F", - "Note": "Doloribus autem optio temporibus dolores mollitia sit.", - "Billing Address 1": "862 Jessika Well", - "Billing Address 2": "1091 Dorthy Mount", - "Billing Address City": "Deckowfort", - "Billing Address Country": "Ghana", - "Billing Address Phone": "825-011-5207", - "Billing Address Postcode": "38228", - "Billing Address State": "Oregon", - "Shipping Address 1": "37626 Thiel Villages", - "Shipping Address 2": "132 Batz Avenue", - "Shipping Address City": "Pagacburgh", - "Shipping Address Country": "Albania", - "Shipping Address Phone": "171-546-3701", - "Shipping Address Postcode": "13709", - "Shipping Address State": "Georgia" - }, - { - "Customer Type": "Business", - "First Name": "Hermann", - "Last Name": "Crooks", - "Company Name": "Veum - Schaefer", - "Display Name": "Harley Veum", - "Email": "immanuel56@hotmail.com", - "Personal Phone Number": "449-780-9999", - "Work Phone Number": "970-473-5785", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "T", - "Note": "Doloribus dolore dolor dicta vitae in fugit nisi quibusdam.", - "Billing Address 1": "532 Simonis Spring", - "Billing Address 2": "3122 Nicolas Inlet", - "Billing Address City": "East Matteofort", - "Billing Address Country": "Holy See (Vatican City State)", - "Billing Address Phone": "366-084-8629", - "Billing Address Postcode": "41607", - "Billing Address State": "Montana", - "Shipping Address 1": "2889 Tremblay Plaza", - "Shipping Address 2": "71355 Kutch Isle", - "Shipping Address City": "D'Amorehaven", - "Shipping Address Country": "Monaco", - "Shipping Address Phone": "614-189-3328", - "Shipping Address Postcode": "09634-0435", - "Shipping Address State": "Nevada" - }, - { - "Customer Type": "Business", - "First Name": "Nellie", - "Last Name": "Gulgowski", - "Company Name": "Boyle, Heller and Jones", - "Display Name": "Randall Kohler", - "Email": "anibal_frami@yahoo.com", - "Personal Phone Number": "498-578-0740", - "Work Phone Number": "394-550-6827", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "T", - "Note": "Vero quibusdam rem fugit aperiam est modi.", - "Billing Address 1": "214 Sauer Villages", - "Billing Address 2": "30687 Kacey Square", - "Billing Address City": "Jayceborough", - "Billing Address Country": "Benin", - "Billing Address Phone": "332-820-1127", - "Billing Address Postcode": "16425-3887", - "Billing Address State": "Mississippi", - "Shipping Address 1": "562 Diamond Loaf", - "Shipping Address 2": "9595 Satterfield Trafficway", - "Shipping Address City": "Alexandrinefort", - "Shipping Address Country": "Puerto Rico", - "Shipping Address Phone": "776-500-8456", - "Shipping Address Postcode": "30258", - "Shipping Address State": "South Dakota" - }, - { - "Customer Type": "Business", - "First Name": "Stone", - "Last Name": "Jerde", - "Company Name": "Cassin, Casper and Maggio", - "Display Name": "Clint McLaughlin", - "Email": "nathanael22@yahoo.com", - "Personal Phone Number": "562-790-6059", - "Work Phone Number": "686-838-0027", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "F", - "Note": "Quis cumque molestias rerum.", - "Billing Address 1": "22590 Cathy Harbor", - "Billing Address 2": "24493 Brycen Brooks", - "Billing Address City": "Elnorashire", - "Billing Address Country": "Andorra", - "Billing Address Phone": "701-852-8005", - "Billing Address Postcode": "5680", - "Billing Address State": "Nevada", - "Shipping Address 1": "5355 Erdman Bridge", - "Shipping Address 2": "421 Jeanette Camp", - "Shipping Address City": "East Philip", - "Shipping Address Country": "Venezuela", - "Shipping Address Phone": "426-119-0858", - "Shipping Address Postcode": "34929-0501", - "Shipping Address State": "Tennessee" - }, - { - "Customer Type": "Individual", - "First Name": "Lempi", - "Last Name": "Kling", - "Company Name": "Schamberger, O'Connell and Bechtelar", - "Display Name": "Alexie Barton", - "Email": "eulah.kreiger@hotmail.com", - "Personal Phone Number": "745-756-1063", - "Work Phone Number": "965-150-1945", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "F", - "Note": "Maxime laboriosam hic voluptate maiores est officia.", - "Billing Address 1": "0851 Jones Flat", - "Billing Address 2": "845 Bailee Drives", - "Billing Address City": "Kamrenport", - "Billing Address Country": "Niger", - "Billing Address Phone": "220-125-0608", - "Billing Address Postcode": "30311", - "Billing Address State": "Delaware", - "Shipping Address 1": "929 Ferry Row", - "Shipping Address 2": "020 Adam Plaza", - "Shipping Address City": "West Carmellaside", - "Shipping Address Country": "Ghana", - "Shipping Address Phone": "053-333-6679", - "Shipping Address Postcode": "79221-4681", - "Shipping Address State": "Illinois" - } -] diff --git a/packages/server/src/services/Contacts/Customers/constants.ts b/packages/server/src/services/Contacts/Customers/constants.ts deleted file mode 100644 index d14770903..000000000 --- a/packages/server/src/services/Contacts/Customers/constants.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const DEFAULT_VIEW_COLUMNS = []; - -export const DEFAULT_VIEWS = [ - { - name: 'Overdue', - slug: 'overdue', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'overdue' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Unpaid', - slug: 'unpaid', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'unpaid' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const ERRORS = { - CUSTOMER_HAS_TRANSACTIONS: 'CUSTOMER_HAS_TRANSACTIONS', - CUSTOMER_ALREADY_ACTIVE: 'CUSTOMER_ALREADY_ACTIVE', -}; diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/ActivateVendor.ts b/packages/server/src/services/Contacts/Vendors/CRUD/ActivateVendor.ts deleted file mode 100644 index 19dea6ee2..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/ActivateVendor.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { VendorValidators } from './VendorValidators'; -import { IVendorActivatedPayload } from '@/interfaces'; - -@Service() -export class ActivateVendor { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: VendorValidators; - - /** - * Inactive the given contact. - * @param {number} tenantId - Tenant id. - * @param {number} contactId - Contact id. - * @returns {Promise} - */ - public async activateVendor( - tenantId: number, - vendorId: number - ): Promise { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieves the old vendor or throw not found error. - const oldVendor = await Contact.query() - .findById(vendorId) - .modify('vendor') - .throwIfNotFound(); - - // Validate whether the vendor is already published. - this.validators.validateNotAlreadyPublished(oldVendor); - - // Edits the vendor with associated transactions on unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onVendorActivating` event. - await this.eventPublisher.emitAsync(events.vendors.onActivating, { - tenantId, - trx, - oldVendor, - } as IVendorActivatedPayload); - - // Updates the vendor on the storage. - const vendor = await Contact.query(trx).updateAndFetchById(vendorId, { - active: true, - }); - // Triggers `onVendorActivated` event. - await this.eventPublisher.emitAsync(events.vendors.onActivated, { - tenantId, - trx, - oldVendor, - vendor, - } as IVendorActivatedPayload); - }); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/CreateEditVendorDTO.ts b/packages/server/src/services/Contacts/Vendors/CRUD/CreateEditVendorDTO.ts deleted file mode 100644 index 69faa8d7f..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/CreateEditVendorDTO.ts +++ /dev/null @@ -1,71 +0,0 @@ -import moment from 'moment'; -import { defaultTo, isEmpty } from 'lodash'; -import { Service } from 'typedi'; -import { - ContactService, - IVendor, - IVendorEditDTO, - IVendorNewDTO, -} from '@/interfaces'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class CreateEditVendorDTO { - /** - * - * @param {IVendorNewDTO | IVendorEditDTO} vendorDTO - * @returns - */ - private transformCommonDTO = (vendorDTO: IVendorNewDTO | IVendorEditDTO) => { - return { - ...vendorDTO, - }; - }; - - /** - * Transformes the create vendor DTO. - * @param {IVendorNewDTO} vendorDTO - - * @returns {} - */ - public transformCreateDTO = async ( - tenantId: number, - vendorDTO: IVendorNewDTO - ) => { - const commonDTO = this.transformCommonDTO(vendorDTO); - - // Retrieves the tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - return { - ...commonDTO, - currencyCode: vendorDTO.currencyCode || tenantMeta.baseCurrency, - active: defaultTo(vendorDTO.active, true), - contactService: ContactService.Vendor, - - ...(!isEmpty(vendorDTO.openingBalanceAt) - ? { - openingBalanceAt: moment( - vendorDTO?.openingBalanceAt - ).toMySqlDateTime(), - } - : {}), - openingBalanceExchangeRate: defaultTo( - vendorDTO.openingBalanceExchangeRate, - 1 - ), - }; - }; - - /** - * Transformes the edit vendor DTO. - * @param {IVendorEditDTO} vendorDTO - * @returns - */ - public transformEditDTO = (vendorDTO: IVendorEditDTO) => { - const commonDTO = this.transformCommonDTO(vendorDTO); - - return { - ...commonDTO, - }; - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/CreateVendor.ts b/packages/server/src/services/Contacts/Vendors/CRUD/CreateVendor.ts deleted file mode 100644 index 6e396ab25..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/CreateVendor.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - ISystemUser, - IVendorEventCreatedPayload, - IVendorEventCreatingPayload, - IVendorNewDTO, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CreateEditVendorDTO } from './CreateEditVendorDTO'; - -@Service() -export class CreateVendor { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformDTO: CreateEditVendorDTO; - - /** - * Creates a new vendor. - * @param {number} tenantId - * @param {IVendorNewDTO} vendorDTO - * @return {Promise} - */ - public async createVendor( - tenantId: number, - vendorDTO: IVendorNewDTO, - trx?: Knex.Transaction - ) { - const { Contact } = this.tenancy.models(tenantId); - - // Transformes create DTO to customer object. - const vendorObject = await this.transformDTO.transformCreateDTO( - tenantId, - vendorDTO - ); - // Creates vendor contact under unit-of-work evnirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onVendorCreating` event. - await this.eventPublisher.emitAsync(events.vendors.onCreating, { - tenantId, - vendorDTO, - trx, - } as IVendorEventCreatingPayload); - - // Creates a new contact as vendor. - const vendor = await Contact.query(trx).insertAndFetch({ - ...vendorObject, - }); - // Triggers `onVendorCreated` event. - await this.eventPublisher.emitAsync(events.vendors.onCreated, { - tenantId, - vendorId: vendor.id, - vendor, - trx, - } as IVendorEventCreatedPayload); - - return vendor; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/DeleteVendor.ts b/packages/server/src/services/Contacts/Vendors/CRUD/DeleteVendor.ts deleted file mode 100644 index b2e212883..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/DeleteVendor.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ISystemUser, - IVendorEventDeletedPayload, - IVendorEventDeletingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { ERRORS } from '../constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class DeleteVendor { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the given vendor. - * @param {number} tenantId - * @param {number} vendorId - * @return {Promise} - */ - public async deleteVendor( - tenantId: number, - vendorId: number, - authorizedUser: ISystemUser - ) { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieves the old vendor or throw not found service error. - const oldVendor = await Contact.query() - .modify('vendor') - .findById(vendorId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.VENDOR_HAS_TRANSACTIONS, - }); - // Triggers `onVendorDeleting` event. - await this.eventPublisher.emitAsync(events.vendors.onDeleting, { - tenantId, - vendorId, - oldVendor, - } as IVendorEventDeletingPayload); - - // Deletes vendor contact under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Deletes the vendor contact from the storage. - await Contact.query(trx).findById(vendorId).delete(); - - // Triggers `onVendorDeleted` event. - await this.eventPublisher.emitAsync(events.vendors.onDeleted, { - tenantId, - vendorId, - authorizedUser, - oldVendor, - trx, - } as IVendorEventDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/EditOpeningBalanceVendor.ts b/packages/server/src/services/Contacts/Vendors/CRUD/EditOpeningBalanceVendor.ts deleted file mode 100644 index 3767470fa..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/EditOpeningBalanceVendor.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IVendorOpeningBalanceEditDTO, - IVendorOpeningBalanceEditedPayload, - IVendorOpeningBalanceEditingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class EditOpeningBalanceVendor { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Changes the opening balance of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {number} openingBalance - * @param {string|Date} openingBalanceAt - * @returns {Promise} - */ - public async editOpeningBalance( - tenantId: number, - vendorId: number, - openingBalanceEditDTO: IVendorOpeningBalanceEditDTO - ) { - const { Vendor } = this.tenancy.models(tenantId); - - // Retrieves the old vendor or throw not found error. - const oldVendor = await Vendor.query().findById(vendorId).throwIfNotFound(); - - // Mutates the customer opening balance under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onVendorOpeingBalanceChanging` event. - await this.eventPublisher.emitAsync( - events.vendors.onOpeningBalanceChanging, - { - tenantId, - oldVendor, - openingBalanceEditDTO, - trx, - } as IVendorOpeningBalanceEditingPayload - ); - // Mutates the vendor on the storage. - const vendor = await Vendor.query().patchAndFetchById(vendorId, { - ...openingBalanceEditDTO, - }); - // Triggers `onVendorOpeingBalanceChanged` event. - await this.eventPublisher.emitAsync( - events.vendors.onOpeningBalanceChanged, - { - tenantId, - vendor, - oldVendor, - openingBalanceEditDTO, - trx, - } as IVendorOpeningBalanceEditedPayload - ); - return vendor; - }); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/EditVendor.ts b/packages/server/src/services/Contacts/Vendors/CRUD/EditVendor.ts deleted file mode 100644 index 398bed078..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/EditVendor.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { - ISystemUser, - IVendorEditDTO, - IVendorEventEditedPayload, - IVendorEventEditingPayload, -} from '@/interfaces'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; -import { CreateEditVendorDTO } from './CreateEditVendorDTO'; - -@Service() -export class EditVendor { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private transformDTO: CreateEditVendorDTO; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Edits details of the given vendor. - * @param {number} tenantId - - * @param {number} vendorId - - * @param {IVendorEditDTO} vendorDTO - - * @returns {Promise} - */ - public async editVendor( - tenantId: number, - vendorId: number, - vendorDTO: IVendorEditDTO, - authorizedUser: ISystemUser - ) { - const { Contact } = this.tenancy.models(tenantId); - - // Retrieve the vendor or throw not found error. - const oldVendor = await Contact.query() - .findById(vendorId) - .modify('vendor') - .throwIfNotFound(); - - // Transformes vendor DTO to object. - const vendorObj = this.transformDTO.transformEditDTO(vendorDTO); - - // Edits vendor contact under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onVendorEditing` event. - await this.eventPublisher.emitAsync(events.vendors.onEditing, { - trx, - tenantId, - vendorDTO, - } as IVendorEventEditingPayload); - - // Edits the vendor contact. - const vendor = await Contact.query().updateAndFetchById(vendorId, { - ...vendorObj, - }); - // Triggers `onVendorEdited` event. - await this.eventPublisher.emitAsync(events.vendors.onEdited, { - tenantId, - vendorId, - vendor, - authorizedUser, - trx, - } as IVendorEventEditedPayload); - - return vendor; - }); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/GetVendor.ts b/packages/server/src/services/Contacts/Vendors/CRUD/GetVendor.ts deleted file mode 100644 index c90de4616..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/GetVendor.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import VendorTransfromer from '../VendorTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetVendor { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the given vendor details. - * @param {number} tenantId - * @param {number} vendorId - */ - public async getVendor(tenantId: number, vendorId: number) { - const { Contact } = this.tenancy.models(tenantId); - - const vendor = await Contact.query() - .findById(vendorId) - .modify('vendor') - .throwIfNotFound(); - - // Transformes the vendor. - return this.transformer.transform( - tenantId, - vendor, - new VendorTransfromer() - ); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/GetVendors.ts b/packages/server/src/services/Contacts/Vendors/CRUD/GetVendors.ts deleted file mode 100644 index ec5f124d9..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/GetVendors.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as R from 'ramda'; -import { Service, Inject } from 'typedi'; -import { - IFilterMeta, - IPaginationMeta, - IVendor, - IVendorsFilter, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import VendorTransfromer from '../VendorTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetVendors { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve vendors datatable list. - * @param {number} tenantId - Tenant id. - * @param {IVendorsFilter} vendorsFilter - Vendors filter. - */ - public async getVendorsList( - tenantId: number, - filterDTO: IVendorsFilter - ): Promise<{ - vendors: IVendor[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { Vendor } = this.tenancy.models(tenantId); - - // Parses vendors list filter DTO. - const filter = this.parseVendorsListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - Vendor, - filter - ); - // Vendors list. - const { results, pagination } = await Vendor.query() - .onBuild((builder) => { - dynamicList.buildQuery()(builder); - - // Switches between active/inactive modes. - builder.modify('inactiveMode', filter.inactiveMode); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transform the vendors. - const transformedVendors = await this.transformer.transform( - tenantId, - results, - new VendorTransfromer() - ); - return { - vendors: transformedVendors, - pagination, - filterMeta: dynamicList.getResponseMeta(), - }; - } - - /** - * - * @param filterDTO - * @returns - */ - private parseVendorsListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/CRUD/VendorValidators.ts b/packages/server/src/services/Contacts/Vendors/CRUD/VendorValidators.ts deleted file mode 100644 index 739af10ed..000000000 --- a/packages/server/src/services/Contacts/Vendors/CRUD/VendorValidators.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { Service, Inject } from 'typedi'; -import { ERRORS } from '../constants'; - -@Service() -export class VendorValidators { - /** - * Validates the given vendor is not already activated. - * @param {IVendor} vendor - */ - public validateNotAlreadyPublished = (vendor) => { - if (vendor.active) { - throw new ServiceError(ERRORS.VENDOR_ALREADY_ACTIVE); - } - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber.ts b/packages/server/src/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber.ts deleted file mode 100644 index ad50b7387..000000000 --- a/packages/server/src/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { VendorGLEntriesStorage } from '../VendorGLEntriesStorage'; -import { - IVendorEventCreatedPayload, - IVendorEventDeletedPayload, - IVendorOpeningBalanceEditedPayload, -} from '@/interfaces'; - -@Service() -export class VendorsWriteGLOpeningSubscriber { - @Inject() - private vendorGLEntriesStorage: VendorGLEntriesStorage; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.vendors.onCreated, - this.handleWriteOpeningBalanceEntries - ); - bus.subscribe( - events.vendors.onDeleted, - this.handleRevertOpeningBalanceEntries - ); - bus.subscribe( - events.vendors.onOpeningBalanceChanged, - this.handleRewriteOpeningEntriesOnChanged - ); - } - - /** - * Writes the open balance journal entries once the vendor created. - * @param {IVendorEventCreatedPayload} payload - - */ - private handleWriteOpeningBalanceEntries = async ({ - tenantId, - vendor, - trx, - }: IVendorEventCreatedPayload) => { - // Writes the vendor opening balance journal entries. - if (vendor.openingBalance) { - await this.vendorGLEntriesStorage.writeVendorOpeningBalance( - tenantId, - vendor.id, - trx - ); - } - }; - - /** - * Revert the opening balance journal entries once the vendor deleted. - * @param {IVendorEventDeletedPayload} payload - - */ - private handleRevertOpeningBalanceEntries = async ({ - tenantId, - vendorId, - trx, - }: IVendorEventDeletedPayload) => { - await this.vendorGLEntriesStorage.revertVendorOpeningBalance( - tenantId, - vendorId, - trx - ); - }; - - /** - * Handles the rewrite opening balance entries once opening balnace changed. - * @param {ICustomerOpeningBalanceEditedPayload} payload - - */ - private handleRewriteOpeningEntriesOnChanged = async ({ - tenantId, - vendor, - trx, - }: IVendorOpeningBalanceEditedPayload) => { - if (vendor.openingBalance) { - await this.vendorGLEntriesStorage.rewriteVendorOpeningBalance( - tenantId, - vendor.id, - trx - ); - } else { - await this.vendorGLEntriesStorage.revertVendorOpeningBalance( - tenantId, - vendor.id, - trx - ); - } - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/VendorGLEntries.ts b/packages/server/src/services/Contacts/Vendors/VendorGLEntries.ts deleted file mode 100644 index f238fde20..000000000 --- a/packages/server/src/services/Contacts/Vendors/VendorGLEntries.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Service } from 'typedi'; -import { IVendor, AccountNormal, ILedgerEntry } from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export class VendorGLEntries { - /** - * Retrieves the opening balance GL common entry. - * @param {IVendor} vendor - - */ - private getOpeningBalanceGLCommonEntry = (vendor: IVendor) => { - return { - exchangeRate: vendor.openingBalanceExchangeRate, - currencyCode: vendor.currencyCode, - - transactionType: 'VendorOpeningBalance', - transactionId: vendor.id, - - date: vendor.openingBalanceAt, - userId: vendor.userId, - contactId: vendor.id, - - credit: 0, - debit: 0, - - branchId: vendor.openingBalanceBranchId, - }; - }; - - /** - * Retrieves the opening balance GL debit entry. - * @param {number} costAccountId - - * @param {IVendor} vendor - * @returns {ILedgerEntry} - */ - private getOpeningBalanceGLDebitEntry = ( - costAccountId: number, - vendor: IVendor - ): ILedgerEntry => { - const commonEntry = this.getOpeningBalanceGLCommonEntry(vendor); - - return { - ...commonEntry, - accountId: costAccountId, - accountNormal: AccountNormal.DEBIT, - debit: vendor.localOpeningBalance, - credit: 0, - index: 2, - }; - }; - - /** - * Retrieves the opening balance GL credit entry. - * @param {number} APAccountId - * @param {IVendor} vendor - * @returns {ILedgerEntry} - */ - private getOpeningBalanceGLCreditEntry = ( - APAccountId: number, - vendor: IVendor - ): ILedgerEntry => { - const commonEntry = this.getOpeningBalanceGLCommonEntry(vendor); - - return { - ...commonEntry, - accountId: APAccountId, - accountNormal: AccountNormal.CREDIT, - credit: vendor.localOpeningBalance, - index: 1, - }; - }; - - /** - * Retrieves the opening balance GL entries. - * @param {number} APAccountId - * @param {number} costAccountId - - * @param {IVendor} vendor - * @returns {ILedgerEntry[]} - */ - public getOpeningBalanceGLEntries = ( - APAccountId: number, - costAccountId: number, - vendor: IVendor - ): ILedgerEntry[] => { - const debitEntry = this.getOpeningBalanceGLDebitEntry( - costAccountId, - vendor - ); - const creditEntry = this.getOpeningBalanceGLCreditEntry( - APAccountId, - vendor - ); - return [debitEntry, creditEntry]; - }; - - /** - * Retrieves the opening balance ledger. - * @param {number} APAccountId - * @param {number} costAccountId - - * @param {IVendor} vendor - * @returns {Ledger} - */ - public getOpeningBalanceLedger = ( - APAccountId: number, - costAccountId: number, - vendor: IVendor - ) => { - const entries = this.getOpeningBalanceGLEntries( - APAccountId, - costAccountId, - vendor - ); - return new Ledger(entries); - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/VendorGLEntriesStorage.ts b/packages/server/src/services/Contacts/Vendors/VendorGLEntriesStorage.ts deleted file mode 100644 index a8bde60fe..000000000 --- a/packages/server/src/services/Contacts/Vendors/VendorGLEntriesStorage.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { VendorGLEntries } from './VendorGLEntries'; - -@Service() -export class VendorGLEntriesStorage { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledegrRepository: LedgerStorageService; - - @Inject() - private vendorGLEntries: VendorGLEntries; - - /** - * Vendor opening balance journals. - * @param {number} tenantId - * @param {number} vendorId - * @param {Knex.Transaction} trx - */ - public writeVendorOpeningBalance = async ( - tenantId: number, - vendorId: number, - trx?: Knex.Transaction - ) => { - const { Vendor } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - const vendor = await Vendor.query(trx).findById(vendorId); - - // Finds the expense account. - const expenseAccount = await accountRepository.findOne({ - slug: 'other-expenses', - }); - // Find or create the A/P account. - const APAccount = await accountRepository.findOrCreateAccountsPayable( - vendor.currencyCode, - {}, - trx - ); - // Retrieves the vendor opening balance ledger. - const ledger = this.vendorGLEntries.getOpeningBalanceLedger( - APAccount.id, - expenseAccount.id, - vendor - ); - // Commits the ledger entries to the storage. - await this.ledegrRepository.commit(tenantId, ledger, trx); - }; - - /** - * Reverts the vendor opening balance GL entries. - * @param {number} tenantId - * @param {number} vendorId - * @param {Knex.Transaction} trx - */ - public revertVendorOpeningBalance = async ( - tenantId: number, - vendorId: number, - trx?: Knex.Transaction - ) => { - await this.ledegrRepository.deleteByReference( - tenantId, - vendorId, - 'VendorOpeningBalance', - trx - ); - }; - - /** - * Writes the vendor opening balance GL entries. - * @param {number} tenantId - * @param {number} vendorId - * @param {Knex.Transaction} trx - */ - public rewriteVendorOpeningBalance = async ( - tenantId: number, - vendorId: number, - trx?: Knex.Transaction - ) => { - await this.writeVendorOpeningBalance(tenantId, vendorId, trx); - - await this.revertVendorOpeningBalance(tenantId, vendorId, trx); - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/VendorTransformer.ts b/packages/server/src/services/Contacts/Vendors/VendorTransformer.ts deleted file mode 100644 index 0514392a8..000000000 --- a/packages/server/src/services/Contacts/Vendors/VendorTransformer.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Service } from 'typedi'; -import ContactTransfromer from '../ContactTransformer'; - -export default class VendorTransfromer extends ContactTransfromer { - /** - * Include these attributes to expense object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedBalance', - 'formattedOpeningBalance', - 'formattedOpeningBalanceAt' - ]; - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/VendorsApplication.ts b/packages/server/src/services/Contacts/Vendors/VendorsApplication.ts deleted file mode 100644 index 45dc64384..000000000 --- a/packages/server/src/services/Contacts/Vendors/VendorsApplication.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ISystemUser, - IVendorEditDTO, - IVendorNewDTO, - IVendorOpeningBalanceEditDTO, - IVendorsFilter, -} from '@/interfaces'; -import { CreateVendor } from './CRUD/CreateVendor'; -import { DeleteVendor } from './CRUD/DeleteVendor'; -import { EditOpeningBalanceVendor } from './CRUD/EditOpeningBalanceVendor'; -import { EditVendor } from './CRUD/EditVendor'; -import { GetVendor } from './CRUD/GetVendor'; -import { GetVendors } from './CRUD/GetVendors'; - -@Service() -export class VendorsApplication { - @Inject() - private createVendorService: CreateVendor; - - @Inject() - private editVendorService: EditVendor; - - @Inject() - private deleteVendorService: DeleteVendor; - - @Inject() - private editOpeningBalanceService: EditOpeningBalanceVendor; - - @Inject() - private getVendorService: GetVendor; - - @Inject() - private getVendorsService: GetVendors; - - /** - * Creates a new vendor. - * @param {number} tenantId - * @param {IVendorNewDTO} vendorDTO - * @return {Promise} - */ - public createVendor = ( - tenantId: number, - vendorDTO: IVendorNewDTO, - trx?: Knex.Transaction - ) => { - return this.createVendorService.createVendor(tenantId, vendorDTO, trx); - }; - - /** - * Edits details of the given vendor. - * @param {number} tenantId - - * @param {number} vendorId - - * @param {IVendorEditDTO} vendorDTO - - * @returns {Promise} - */ - public editVendor = ( - tenantId: number, - vendorId: number, - vendorDTO: IVendorEditDTO, - authorizedUser: ISystemUser - ) => { - return this.editVendorService.editVendor( - tenantId, - vendorId, - vendorDTO, - authorizedUser - ); - }; - - /** - * Deletes the given vendor. - * @param {number} tenantId - * @param {number} vendorId - * @return {Promise} - */ - public deleteVendor = ( - tenantId: number, - vendorId: number, - authorizedUser: ISystemUser - ) => { - return this.deleteVendorService.deleteVendor( - tenantId, - vendorId, - authorizedUser - ); - }; - - /** - * Changes the opening balance of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {number} openingBalance - * @param {string|Date} openingBalanceAt - * @returns {Promise} - */ - public editOpeningBalance = ( - tenantId: number, - vendorId: number, - openingBalanceEditDTO: IVendorOpeningBalanceEditDTO - ) => { - return this.editOpeningBalanceService.editOpeningBalance( - tenantId, - vendorId, - openingBalanceEditDTO - ); - }; - - /** - * Retrieves the vendor details. - * @param {number} tenantId - * @param {number} vendorId - * @returns - */ - public getVendor = (tenantId: number, vendorId: number) => { - return this.getVendorService.getVendor(tenantId, vendorId); - }; - - /** - * Retrieves the vendors paginated list. - * @param {number} tenantId - * @param {IVendorsFilter} filterDTO - * @returns - */ - public getVendors = (tenantId: number, filterDTO: IVendorsFilter) => { - return this.getVendorsService.getVendorsList(tenantId, filterDTO); - }; -} diff --git a/packages/server/src/services/Contacts/Vendors/VendorsExportable.ts b/packages/server/src/services/Contacts/Vendors/VendorsExportable.ts deleted file mode 100644 index 88c7194eb..000000000 --- a/packages/server/src/services/Contacts/Vendors/VendorsExportable.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IItemsFilter } from '@/interfaces'; -import { Exportable } from '@/services/Export/Exportable'; -import { VendorsApplication } from './VendorsApplication'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class VendorsExportable extends Exportable { - @Inject() - private vendorsApplication: VendorsApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IItemsFilter) { - const parsedQuery = { - sortOrder: 'DESC', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - } as IItemsFilter; - - return this.vendorsApplication - .getVendors(tenantId, parsedQuery) - .then((output) => output.vendors); - } -} diff --git a/packages/server/src/services/Contacts/Vendors/VendorsImportable.ts b/packages/server/src/services/Contacts/Vendors/VendorsImportable.ts deleted file mode 100644 index 67b4a57af..000000000 --- a/packages/server/src/services/Contacts/Vendors/VendorsImportable.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Importable } from '@/services/Import/Importable'; -import { CreateVendor } from './CRUD/CreateVendor'; -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { VendorsSampleData } from './_SampleData'; - -@Service() -export class VendorsImportable extends Importable { - @Inject() - private createVendorService: CreateVendor; - - /** - * Maps the imported data to create a new vendor service. - * @param {number} tenantId - * @param {} createDTO - * @param {Knex.Transaction} trx - */ - public async importable( - tenantId: number, - createDTO: any, - trx?: Knex.Transaction - ): Promise { - await this.createVendorService.createVendor(tenantId, createDTO, trx); - } - - /** - * Retrieves the sample data of vendors sample sheet. - */ - public sampleData(): any[] { - return VendorsSampleData; - } -} diff --git a/packages/server/src/services/Contacts/Vendors/_SampleData.ts b/packages/server/src/services/Contacts/Vendors/_SampleData.ts deleted file mode 100644 index 5e6e4edda..000000000 --- a/packages/server/src/services/Contacts/Vendors/_SampleData.ts +++ /dev/null @@ -1,122 +0,0 @@ -export const VendorsSampleData = [ - { - "First Name": "Nicolette", - "Last Name": "Schamberger", - "Company Name": "Homenick - Hane", - "Display Name": "Rowland Rowe", - "Email": "cicero86@yahoo.com", - "Personal Phone Number": "811-603-2235", - "Work Phone Number": "906-993-5190", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "T", - "Note": "Doloribus autem optio temporibus dolores mollitia sit.", - "Billing Address 1": "862 Jessika Well", - "Billing Address 2": "1091 Dorthy Mount", - "Billing Address City": "Deckowfort", - "Billing Address Country": "Ghana", - "Billing Address Phone": "825-011-5207", - "Billing Address Postcode": "38228", - "Billing Address State": "Oregon", - "Shipping Address 1": "37626 Thiel Villages", - "Shipping Address 2": "132 Batz Avenue", - "Shipping Address City": "Pagacburgh", - "Shipping Address Country": "Albania", - "Shipping Address Phone": "171-546-3701", - "Shipping Address Postcode": "13709", - "Shipping Address State": "Georgia" - }, - { - "First Name": "Hermann", - "Last Name": "Crooks", - "Company Name": "Veum - Schaefer", - "Display Name": "Harley Veum", - "Email": "immanuel56@hotmail.com", - "Personal Phone Number": "449-780-9999", - "Work Phone Number": "970-473-5785", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "T", - "Note": "Doloribus dolore dolor dicta vitae in fugit nisi quibusdam.", - "Billing Address 1": "532 Simonis Spring", - "Billing Address 2": "3122 Nicolas Inlet", - "Billing Address City": "East Matteofort", - "Billing Address Country": "Holy See (Vatican City State)", - "Billing Address Phone": "366-084-8629", - "Billing Address Postcode": "41607", - "Billing Address State": "Montana", - "Shipping Address 1": "2889 Tremblay Plaza", - "Shipping Address 2": "71355 Kutch Isle", - "Shipping Address City": "D'Amorehaven", - "Shipping Address Country": "Monaco", - "Shipping Address Phone": "614-189-3328", - "Shipping Address Postcode": "09634-0435", - "Shipping Address State": "Nevada" - }, - { - "First Name": "Nellie", - "Last Name": "Gulgowski", - "Company Name": "Boyle, Heller and Jones", - "Display Name": "Randall Kohler", - "Email": "anibal_frami@yahoo.com", - "Personal Phone Number": "498-578-0740", - "Work Phone Number": "394-550-6827", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "T", - "Note": "Vero quibusdam rem fugit aperiam est modi.", - "Billing Address 1": "214 Sauer Villages", - "Billing Address 2": "30687 Kacey Square", - "Billing Address City": "Jayceborough", - "Billing Address Country": "Benin", - "Billing Address Phone": "332-820-1127", - "Billing Address Postcode": "16425-3887", - "Billing Address State": "Mississippi", - "Shipping Address 1": "562 Diamond Loaf", - "Shipping Address 2": "9595 Satterfield Trafficway", - "Shipping Address City": "Alexandrinefort", - "Shipping Address Country": "Puerto Rico", - "Shipping Address Phone": "776-500-8456", - "Shipping Address Postcode": "30258", - "Shipping Address State": "South Dakota" - }, - { - "First Name": "Stone", - "Last Name": "Jerde", - "Company Name": "Cassin, Casper and Maggio", - "Display Name": "Clint McLaughlin", - "Email": "nathanael22@yahoo.com", - "Personal Phone Number": "562-790-6059", - "Work Phone Number": "686-838-0027", - "Website": "http://google.com", - "Opening Balance": 54302.23, - "Opening Balance At": "2022-02-02", - "Opening Balance Ex. Rate": 2, - "Currency": "LYD", - "Active": "T", - "Note": "Quis cumque molestias rerum.", - "Billing Address 1": "22590 Cathy Harbor", - "Billing Address 2": "24493 Brycen Brooks", - "Billing Address City": "Elnorashire", - "Billing Address Country": "Andorra", - "Billing Address Phone": "701-852-8005", - "Billing Address Postcode": "5680", - "Billing Address State": "Nevada", - "Shipping Address 1": "5355 Erdman Bridge", - "Shipping Address 2": "421 Jeanette Camp", - "Shipping Address City": "East Philip", - "Shipping Address Country": "Venezuela", - "Shipping Address Phone": "426-119-0858", - "Shipping Address Postcode": "34929-0501", - "Shipping Address State": "Tennessee" - } -] diff --git a/packages/server/src/services/Contacts/Vendors/constants.ts b/packages/server/src/services/Contacts/Vendors/constants.ts deleted file mode 100644 index 25f31f36a..000000000 --- a/packages/server/src/services/Contacts/Vendors/constants.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const DEFAULT_VIEW_COLUMNS = []; - -export const DEFAULT_VIEWS = [ - { - name: 'Overdue', - slug: 'overdue', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'overdue' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Unpaid', - slug: 'unpaid', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'unpaid' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const ERRORS = { - VENDOR_HAS_TRANSACTIONS: 'VENDOR_HAS_TRANSACTIONS', - VENDOR_ALREADY_ACTIVE: 'VENDOR_ALREADY_ACTIVE', -}; diff --git a/packages/server/src/services/Contacts/constants.ts b/packages/server/src/services/Contacts/constants.ts deleted file mode 100644 index 3bfb8771e..000000000 --- a/packages/server/src/services/Contacts/constants.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const DEFAULT_VIEW_COLUMNS = []; - -export const DEFAULT_VIEWS = [ - { - name: 'Overdue', - slug: 'overdue', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'overdue' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Unpaid', - slug: 'unpaid', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'unpaid' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - - -export const ERRORS = { - OPENING_BALANCE_DATE_REQUIRED: 'OPENING_BALANCE_DATE_REQUIRED', - CONTACT_ALREADY_INACTIVE: 'CONTACT_ALREADY_INACTIVE', - CONTACT_ALREADY_ACTIVE: 'CONTACT_ALREADY_ACTIVE' -}; diff --git a/packages/server/src/services/CreditNotes/CreateCreditNote.ts b/packages/server/src/services/CreditNotes/CreateCreditNote.ts deleted file mode 100644 index d48a1371f..000000000 --- a/packages/server/src/services/CreditNotes/CreateCreditNote.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - ICreditNoteCreatedPayload, - ICreditNoteCreatingPayload, - ICreditNoteNewDTO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import BaseCreditNotes from './CreditNotes'; - -@Service() -export default class CreateCreditNote extends BaseCreditNotes { - @Inject() - private uow: UnitOfWork; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates a new credit note. - * @param creditNoteDTO - */ - public newCreditNote = async ( - tenantId: number, - creditNoteDTO: ICreditNoteNewDTO, - trx?: Knex.Transaction - ) => { - const { CreditNote, Contact } = this.tenancy.models(tenantId); - - // Triggers `onCreditNoteCreate` event. - await this.eventPublisher.emitAsync(events.creditNote.onCreate, { - tenantId, - creditNoteDTO, - }); - // Validate customer existance. - const customer = await Contact.query() - .modify('customer') - .findById(creditNoteDTO.customerId) - .throwIfNotFound(); - - // Validate items ids existance. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - creditNoteDTO.entries - ); - // Validate items should be sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - creditNoteDTO.entries - ); - // Transformes the given DTO to storage layer data. - const creditNoteModel = await this.transformCreateEditDTOToModel( - tenantId, - creditNoteDTO, - customer.currencyCode - ); - // Creates a new credit card transactions under unit-of-work envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onCreditNoteCreating` event. - await this.eventPublisher.emitAsync(events.creditNote.onCreating, { - tenantId, - creditNoteDTO, - trx, - } as ICreditNoteCreatingPayload); - - // Upsert the credit note graph. - const creditNote = await CreditNote.query(trx).upsertGraph({ - ...creditNoteModel, - }); - // Triggers `onCreditNoteCreated` event. - await this.eventPublisher.emitAsync(events.creditNote.onCreated, { - tenantId, - creditNoteDTO, - creditNote, - creditNoteId: creditNote.id, - trx, - } as ICreditNoteCreatedPayload); - - return creditNote; - }, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreateRefundCreditNote.ts b/packages/server/src/services/CreditNotes/CreateRefundCreditNote.ts deleted file mode 100644 index 7e556ce41..000000000 --- a/packages/server/src/services/CreditNotes/CreateRefundCreditNote.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { - ICreditNote, - ICreditNoteRefundDTO, - IRefundCreditNote, - IRefundCreditNoteCreatedPayload, - IRefundCreditNoteCreatingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import RefundCreditNote from './RefundCreditNote'; - -@Service() -export default class CreateRefundCreditNote extends RefundCreditNote { - @Inject() - tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public createCreditNoteRefund = async ( - tenantId: number, - creditNoteId: number, - newCreditNoteDTO: ICreditNoteRefundDTO - ): Promise => { - const { RefundCreditNote, Account } = this.tenancy.models(tenantId); - - // Retrieve the credit note or throw not found service error. - const creditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - // Retrieve the withdrawal account or throw not found service error. - const fromAccount = await Account.query() - .findById(newCreditNoteDTO.fromAccountId) - .throwIfNotFound(); - - // Validate the credit note remaining amount. - this.validateCreditRemainingAmount(creditNote, newCreditNoteDTO.amount); - - // Validate the refund withdrawal account type. - this.validateRefundWithdrawwalAccountType(fromAccount); - - // Creates a refund credit note transaction. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCreditNoteRefundCreating` event. - await this.eventPublisher.emitAsync(events.creditNote.onRefundCreating, { - trx, - creditNote, - tenantId, - newCreditNoteDTO, - } as IRefundCreditNoteCreatingPayload); - - // Stores the refund credit note graph to the storage layer. - const refundCreditNote = await RefundCreditNote.query(trx).insertAndFetch( - { - ...this.transformDTOToModel(creditNote, newCreditNoteDTO), - } - ); - // Triggers `onCreditNoteRefundCreated` event. - await this.eventPublisher.emitAsync(events.creditNote.onRefundCreated, { - trx, - refundCreditNote, - creditNote, - tenantId, - } as IRefundCreditNoteCreatedPayload); - - return refundCreditNote; - }); - }; - - /** - * Transformes the refund credit note DTO to model. - * @param {number} creditNoteId - * @param {ICreditNoteRefundDTO} creditNoteDTO - * @returns {ICreditNote} - */ - private transformDTOToModel = ( - creditNote: ICreditNote, - creditNoteDTO: ICreditNoteRefundDTO - ): IRefundCreditNote => { - return { - creditNoteId: creditNote.id, - currencyCode: creditNote.currencyCode, - ...creditNoteDTO, - exchangeRate: creditNoteDTO.exchangeRate || 1, - }; - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteAppliedInvoiceTransformer.ts b/packages/server/src/services/CreditNotes/CreditNoteAppliedInvoiceTransformer.ts deleted file mode 100644 index 0f3df3806..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteAppliedInvoiceTransformer.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class CreditNoteAppliedInvoiceTransformer extends Transformer { - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'formttedAmount', - 'creditNoteNumber', - 'creditNoteDate', - 'invoiceNumber', - 'invoiceReferenceNo', - 'formattedCreditNoteDate', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['saleInvoice', 'creditNote']; - }; - - formttedAmount = (item) => { - return formatNumber(item.amount, { - currencyCode: item.creditNote.currencyCode, - }); - }; - - creditNoteNumber = (item) => { - return item.creditNote.creditNoteNumber; - }; - - creditNoteDate = (item) => { - return item.creditNote.creditNoteDate; - }; - - invoiceNumber = (item) => { - return item.saleInvoice.invoiceNo; - }; - - invoiceReferenceNo = (item) => { - return item.saleInvoice.referenceNo; - }; - - formattedCreditNoteDate = (item) => { - return this.formatDate(item.creditNote.creditNoteDate); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteApplySyncCredit.ts b/packages/server/src/services/CreditNotes/CreditNoteApplySyncCredit.ts deleted file mode 100644 index 8444c7909..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteApplySyncCredit.ts +++ /dev/null @@ -1,47 +0,0 @@ -import Knex from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; - -@Service() -export default class CreditNoteApplySyncCredit { - @Inject() - tenancy: HasTenancyService; - - /** - * Increment credit note invoiced amount. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {number} invoicesAppliedAmount - */ - public incrementCreditNoteInvoicedAmount = async ( - tenantId: number, - creditNoteId: number, - invoicesAppliedAmount: number, - trx?: Knex.Transaction - ) => { - const { CreditNote } = this.tenancy.models(tenantId); - - await CreditNote.query(trx) - .findById(creditNoteId) - .increment('invoicesAmount', invoicesAppliedAmount); - }; - - /** - * Decrement credit note invoiced amount. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {number} invoicesAppliedAmount - */ - public decrementCreditNoteInvoicedAmount = async ( - tenantId: number, - creditNoteId: number, - invoicesAppliedAmount: number, - trx?: Knex.Transaction - ) => { - const { CreditNote } = this.tenancy.models(tenantId); - - await CreditNote.query(trx) - .findById(creditNoteId) - .decrement('invoicesAmount', invoicesAppliedAmount); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteApplySyncCreditSubscriber.ts b/packages/server/src/services/CreditNotes/CreditNoteApplySyncCreditSubscriber.ts deleted file mode 100644 index c2354e665..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteApplySyncCreditSubscriber.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { sumBy } from 'lodash'; -import events from '@/subscribers/events'; -import { - IApplyCreditToInvoicesCreatedPayload, - IApplyCreditToInvoicesDeletedPayload, -} from '@/interfaces'; -import CreditNoteApplySyncCredit from './CreditNoteApplySyncCredit'; - -@Service() -export default class CreditNoteApplySyncCreditSubscriber { - @Inject() - syncInvoicedAmountWithCredit: CreditNoteApplySyncCredit; - - /** - * - * @param bus - */ - attach(bus) { - bus.subscribe( - events.creditNote.onApplyToInvoicesCreated, - this.incrementCreditedAmountOnceApplyToInvoicesCreated - ); - bus.subscribe( - events.creditNote.onApplyToInvoicesDeleted, - this.decrementCreditedAmountOnceApplyToInvoicesDeleted - ); - } - - /** - * Increment credited amount of credit note transaction once the transaction created. - * @param {IApplyCreditToInvoicesCreatedPayload} payload - - */ - private incrementCreditedAmountOnceApplyToInvoicesCreated = async ({ - trx, - creditNote, - tenantId, - creditNoteAppliedInvoices, - }: IApplyCreditToInvoicesCreatedPayload) => { - const totalCredited = sumBy(creditNoteAppliedInvoices, 'amount'); - - await this.syncInvoicedAmountWithCredit.incrementCreditNoteInvoicedAmount( - tenantId, - creditNote.id, - totalCredited, - trx - ); - }; - - /** - * Decrement credited amount of credit note transaction once the transaction deleted. - * @param {IApplyCreditToInvoicesDeletedPayload} payload - - */ - private decrementCreditedAmountOnceApplyToInvoicesDeleted = async ({ - tenantId, - creditNote, - creditNoteAppliedToInvoice, - trx, - }: IApplyCreditToInvoicesDeletedPayload) => { - await this.syncInvoicedAmountWithCredit.decrementCreditNoteInvoicedAmount( - tenantId, - creditNote.id, - creditNoteAppliedToInvoice.amount, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoices.ts b/packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoices.ts deleted file mode 100644 index 13c5f8143..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoices.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Knex from 'knex'; -import Bluebird from 'bluebird'; -import { ICreditNoteAppliedToInvoice } from '@/interfaces'; - -@Service() -export default class CreditNoteApplySyncInvoicesCreditedAmount { - @Inject() - tenancy: HasTenancyService; - - /** - * Increment invoices credited amount. - * @param {number} tenantId - - * @param {ICreditNoteAppliedToInvoice[]} creditNoteAppliedInvoices - - * @param {Knex.Transaction} trx - - */ - public incrementInvoicesCreditedAmount = async ( - tenantId, - creditNoteAppliedInvoices: ICreditNoteAppliedToInvoice[], - trx?: Knex.Transaction - ) => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - await Bluebird.each( - creditNoteAppliedInvoices, - (creditNoteAppliedInvoice: ICreditNoteAppliedToInvoice) => { - return SaleInvoice.query(trx) - .where('id', creditNoteAppliedInvoice.invoiceId) - .increment('creditedAmount', creditNoteAppliedInvoice.amount); - } - ); - }; - - /** - * - * @param tenantId - * @param invoicesIds - * @param amount - */ - public decrementInvoiceCreditedAmount = async ( - tenantId: number, - invoiceId: number, - amount: number, - trx?: Knex.Transaction - ) => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - await SaleInvoice.query(trx) - .findById(invoiceId) - .decrement('creditedAmount', amount); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoicesSubscriber.ts b/packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoicesSubscriber.ts deleted file mode 100644 index f22a6c03e..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteApplySyncInvoicesSubscriber.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - IApplyCreditToInvoicesCreatedPayload, - IApplyCreditToInvoicesDeletedPayload, -} from '@/interfaces'; -import CreditNoteApplySyncInvoicesCreditedAmount from './CreditNoteApplySyncInvoices'; - -@Service() -export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber { - @Inject() - private syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.creditNote.onApplyToInvoicesCreated, - this.incrementAppliedInvoicesOnceCreditCreated - ); - bus.subscribe( - events.creditNote.onApplyToInvoicesDeleted, - this.decrementAppliedInvoicesOnceCreditDeleted - ); - } - - /** - * Increment invoices credited amount once the credit note apply to invoices transaction - * @param {IApplyCreditToInvoicesCreatedPayload} payload - - */ - private incrementAppliedInvoicesOnceCreditCreated = async ({ - trx, - tenantId, - creditNoteAppliedInvoices, - }: IApplyCreditToInvoicesCreatedPayload) => { - await this.syncInvoicesWithCreditNote.incrementInvoicesCreditedAmount( - tenantId, - creditNoteAppliedInvoices, - trx - ); - }; - - /** - * - * @param {IApplyCreditToInvoicesDeletedPayload} payload - - */ - private decrementAppliedInvoicesOnceCreditDeleted = async ({ - trx, - creditNoteAppliedToInvoice, - tenantId, - }: IApplyCreditToInvoicesDeletedPayload) => { - // Decrement invoice credited amount. - await this.syncInvoicesWithCreditNote.decrementInvoiceCreditedAmount( - tenantId, - creditNoteAppliedToInvoice.invoiceId, - creditNoteAppliedToInvoice.amount, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteApplyToInvoices.ts b/packages/server/src/services/CreditNotes/CreditNoteApplyToInvoices.ts deleted file mode 100644 index 12ffc95b3..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteApplyToInvoices.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { sumBy } from 'lodash'; -import { - ICreditNote, - ICreditNoteAppliedToInvoice, - ICreditNoteAppliedToInvoiceModel, - ISaleInvoice, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { PaymentReceivedValidators } from '../Sales/PaymentReceived/PaymentReceivedValidators'; -import BaseCreditNotes from './CreditNotes'; -import { - IApplyCreditToInvoicesDTO, - IApplyCreditToInvoicesCreatedPayload, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import events from '@/subscribers/events'; -import { ERRORS } from './constants'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export default class CreditNoteApplyToInvoices extends BaseCreditNotes { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private paymentReceiveValidators: PaymentReceivedValidators; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Apply credit note to the given invoices. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO - */ - public applyCreditNoteToInvoices = async ( - tenantId: number, - creditNoteId: number, - applyCreditToInvoicesDTO: IApplyCreditToInvoicesDTO - ): Promise => { - const { CreditNoteAppliedInvoice } = this.tenancy.models(tenantId); - - // Saves the credit note or throw not found service error. - const creditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - // Retrieve the applied invoices that associated to the credit note customer. - const appliedInvoicesEntries = - await this.paymentReceiveValidators.validateInvoicesIDsExistance( - tenantId, - creditNote.customerId, - applyCreditToInvoicesDTO.entries - ); - // Transformes apply DTO to model. - const creditNoteAppliedModel = this.transformApplyDTOToModel( - applyCreditToInvoicesDTO, - creditNote - ); - // Validate invoices has remaining amount to apply. - this.validateInvoicesRemainingAmount( - appliedInvoicesEntries, - creditNoteAppliedModel.amount - ); - // Validate the credit note remaining amount. - this.validateCreditRemainingAmount( - creditNote, - creditNoteAppliedModel.amount - ); - // Creates credit note apply to invoice transaction. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Saves the credit note apply to invoice graph to the storage layer. - const creditNoteAppliedInvoices = - await CreditNoteAppliedInvoice.query().insertGraph( - creditNoteAppliedModel.entries - ); - // Triggers `onCreditNoteApplyToInvoiceCreated` event. - await this.eventPublisher.emitAsync( - events.creditNote.onApplyToInvoicesCreated, - { - tenantId, - creditNote, - creditNoteAppliedInvoices, - trx, - } as IApplyCreditToInvoicesCreatedPayload - ); - return creditNoteAppliedInvoices; - }); - }; - - /** - * Transformes apply DTO to model. - * @param {IApplyCreditToInvoicesDTO} applyDTO - * @param {ICreditNote} creditNote - * @returns - */ - private transformApplyDTOToModel = ( - applyDTO: IApplyCreditToInvoicesDTO, - creditNote: ICreditNote - ): ICreditNoteAppliedToInvoiceModel => { - const entries = applyDTO.entries.map((entry) => ({ - invoiceId: entry.invoiceId, - amount: entry.amount, - creditNoteId: creditNote.id, - })); - return { - amount: sumBy(entries, 'amount'), - entries, - }; - }; - - /** - * Validate the invoice remaining amount. - * @param {ISaleInvoice[]} invoices - * @param {number} amount - */ - private validateInvoicesRemainingAmount = ( - invoices: ISaleInvoice[], - amount: number - ) => { - const invalidInvoices = invoices.filter( - (invoice) => invoice.dueAmount < amount - ); - if (invalidInvoices.length > 0) { - throw new ServiceError(ERRORS.INVOICES_HAS_NO_REMAINING_AMOUNT); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteAutoSerialSubscriber.ts b/packages/server/src/services/CreditNotes/CreditNoteAutoSerialSubscriber.ts deleted file mode 100644 index 64b69d40d..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteAutoSerialSubscriber.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import BaseCreditNotes from './CreditNotes'; -import { ICreditNoteCreatedPayload } from '@/interfaces'; - -@Service() -export default class CreditNoteAutoSerialSubscriber { - @Inject() - creditNotesService: BaseCreditNotes; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.creditNote.onCreated, - this.autoSerialIncrementOnceCreated - ); - } - - /** - * Auto serial increment once credit note created. - * @param {ICreditNoteCreatedPayload} payload - - */ - private autoSerialIncrementOnceCreated = async ({ - tenantId, - }: ICreditNoteCreatedPayload) => { - await this.creditNotesService.incrementSerialNumber(tenantId); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts b/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts deleted file mode 100644 index ef0150747..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Inject } from 'typedi'; -import { GetPdfTemplate } from '../PdfTemplate/GetPdfTemplate'; -import { defaultCreditNoteBrandingAttributes } from './constants'; -import { mergePdfTemplateWithDefaultAttributes } from '../Sales/Invoices/utils'; -import { GetOrganizationBrandingAttributes } from '../PdfTemplate/GetOrganizationBrandingAttributes'; - -export class CreditNoteBrandingTemplate { - @Inject() - private getPdfTemplateService: GetPdfTemplate; - - @Inject() - private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; - - /** - * Retrieves the credit note branding template. - * @param {number} tenantId - * @param {number} templateId - * @returns {} - */ - public async getCreditNoteBrandingTemplate( - tenantId: number, - templateId: number - ) { - const template = await this.getPdfTemplateService.getPdfTemplate( - tenantId, - templateId - ); - // Retrieves the organization branding attributes. - const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes( - tenantId - ); - // Merges the default branding attributes with common organization branding attrs. - const organizationBrandingAttrs = { - ...defaultCreditNoteBrandingAttributes, - ...commonOrgBrandingAttrs, - }; - const brandingTemplateAttrs = { - ...template.attributes, - companyLogoUri: template.companyLogoUri, - }; - const attributes = mergePdfTemplateWithDefaultAttributes( - brandingTemplateAttrs, - organizationBrandingAttrs - ); - return { - ...template, - attributes, - }; - } -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteGLEntries.ts b/packages/server/src/services/CreditNotes/CreditNoteGLEntries.ts deleted file mode 100644 index 78bf7884f..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteGLEntries.ts +++ /dev/null @@ -1,297 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import * as R from 'ramda'; -import { - AccountNormal, - IItemEntry, - ILedgerEntry, - ICreditNote, - ILedger, - ICreditNoteGLCommonEntry, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import { SaleReceipt } from '@/models'; - -@Service() -export default class CreditNoteGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Retrieves the credit note GL. - * @param {ICreditNote} creditNote - * @param {number} receivableAccount - * @returns {Ledger} - */ - private getCreditNoteGLedger = ( - creditNote: ICreditNote, - receivableAccount: number, - discountAccount: number, - adjustmentAccount: number - ): Ledger => { - const ledgerEntries = this.getCreditNoteGLEntries( - creditNote, - receivableAccount, - discountAccount, - adjustmentAccount - ); - return new Ledger(ledgerEntries); - }; - - /** - * Saves credit note GL entries. - * @param {number} tenantId - - * @param {ICreditNote} creditNote - Credit note model. - * @param {number} payableAccount - Payable account id. - * @param {Knex.Transaction} trx - */ - public saveCreditNoteGLEntries = async ( - tenantId: number, - creditNote: ICreditNote, - payableAccount: number, - discountAccount: number, - adjustmentAccount: number, - trx?: Knex.Transaction - ): Promise => { - const ledger = this.getCreditNoteGLedger( - creditNote, - payableAccount, - discountAccount, - adjustmentAccount - ); - - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Reverts the credit note associated GL entries. - * @param {number} tenantId - * @param {number} vendorCreditId - * @param {Knex.Transaction} trx - */ - public revertVendorCreditGLEntries = async ( - tenantId: number, - creditNoteId: number, - trx?: Knex.Transaction - ): Promise => { - await this.ledgerStorage.deleteByReference( - tenantId, - creditNoteId, - 'CreditNote', - trx - ); - }; - - /** - * Writes vendor credit associated GL entries. - * @param {number} tenantId - Tenant id. - * @param {number} creditNoteId - Credit note id. - * @param {Knex.Transaction} trx - Knex transactions. - */ - public createVendorCreditGLEntries = async ( - tenantId: number, - creditNoteId: number, - trx?: Knex.Transaction - ): Promise => { - const { CreditNote } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Retrieve the credit note with associated entries and items. - const creditNoteWithItems = await CreditNote.query(trx) - .findById(creditNoteId) - .withGraphFetched('entries.item'); - - // Retreive the the `accounts receivable` account based on the given currency. - const ARAccount = await accountRepository.findOrCreateAccountReceivable( - creditNoteWithItems.currencyCode - ); - const discountAccount = await accountRepository.findOrCreateDiscountAccount( - {} - ); - const adjustmentAccount = - await accountRepository.findOrCreateOtherChargesAccount({}); - // Saves the credit note GL entries. - await this.saveCreditNoteGLEntries( - tenantId, - creditNoteWithItems, - ARAccount.id, - discountAccount.id, - adjustmentAccount.id, - trx - ); - }; - - /** - * Edits vendor credit associated GL entries. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {Knex.Transaction} trx - */ - public editVendorCreditGLEntries = async ( - tenantId: number, - creditNoteId: number, - trx?: Knex.Transaction - ): Promise => { - // Reverts vendor credit GL entries. - await this.revertVendorCreditGLEntries(tenantId, creditNoteId, trx); - - // Creates vendor credit Gl entries. - await this.createVendorCreditGLEntries(tenantId, creditNoteId, trx); - }; - - /** - * Retrieve the credit note common entry. - * @param {ICreditNote} creditNote - - * @returns {ICreditNoteGLCommonEntry} - */ - private getCreditNoteCommonEntry = ( - creditNote: ICreditNote - ): ICreditNoteGLCommonEntry => { - return { - date: creditNote.creditNoteDate, - userId: creditNote.userId, - currencyCode: creditNote.currencyCode, - exchangeRate: creditNote.exchangeRate, - - transactionType: 'CreditNote', - transactionId: creditNote.id, - - transactionNumber: creditNote.creditNoteNumber, - referenceNumber: creditNote.referenceNo, - - createdAt: creditNote.createdAt, - indexGroup: 10, - - credit: 0, - debit: 0, - - branchId: creditNote.branchId, - }; - }; - - /** - * Retrieves the creidt note A/R entry. - * @param {ICreditNote} creditNote - - * @param {number} ARAccountId - - * @returns {ILedgerEntry} - */ - private getCreditNoteAREntry = ( - creditNote: ICreditNote, - ARAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getCreditNoteCommonEntry(creditNote); - - return { - ...commonEntry, - credit: creditNote.totalLocal, - accountId: ARAccountId, - contactId: creditNote.customerId, - index: 1, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieve the credit note item entry. - * @param {ICreditNote} creditNote - * @param {IItemEntry} entry - * @param {number} index - * @returns {ILedgerEntry} - */ - private getCreditNoteItemEntry = R.curry( - ( - creditNote: ICreditNote, - entry: IItemEntry, - index: number - ): ILedgerEntry => { - const commonEntry = this.getCreditNoteCommonEntry(creditNote); - const totalLocal = entry.totalExcludingTax * creditNote.exchangeRate; - - return { - ...commonEntry, - debit: totalLocal, - accountId: entry.sellAccountId || entry.item.sellAccountId, - note: entry.description, - index: index + 2, - itemId: entry.itemId, - itemQuantity: entry.quantity, - accountNormal: AccountNormal.CREDIT, - }; - } - ); - - /** - * Retrieves the credit note discount entry. - * @param {ICreditNote} creditNote - * @param {number} discountAccountId - * @returns {ILedgerEntry} - */ - private getDiscountEntry = ( - creditNote: ICreditNote, - discountAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getCreditNoteCommonEntry(creditNote); - - return { - ...commonEntry, - credit: creditNote.discountAmountLocal, - accountId: discountAccountId, - index: 1, - accountNormal: AccountNormal.CREDIT, - }; - }; - - /** - * Retrieves the credit note adjustment entry. - * @param {ICreditNote} creditNote - * @param {number} adjustmentAccountId - * @returns {ILedgerEntry} - */ - private getAdjustmentEntry = ( - creditNote: ICreditNote, - adjustmentAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getCreditNoteCommonEntry(creditNote); - const adjustmentAmount = Math.abs(creditNote.adjustmentLocal); - - return { - ...commonEntry, - credit: creditNote.adjustmentLocal < 0 ? adjustmentAmount : 0, - debit: creditNote.adjustmentLocal > 0 ? adjustmentAmount : 0, - accountId: adjustmentAccountId, - accountNormal: AccountNormal.CREDIT, - index: 1, - }; - }; - - /** - * Retrieve the credit note GL entries. - * @param {ICreditNote} creditNote - Credit note. - * @param {IAccount} receivableAccount - Receviable account. - * @returns {ILedgerEntry[]} - Ledger entries. - */ - public getCreditNoteGLEntries = ( - creditNote: ICreditNote, - ARAccountId: number, - discountAccountId: number, - adjustmentAccountId: number - ): ILedgerEntry[] => { - const AREntry = this.getCreditNoteAREntry(creditNote, ARAccountId); - - const getItemEntry = this.getCreditNoteItemEntry(creditNote); - const itemsEntries = creditNote.entries.map(getItemEntry); - - const discountEntry = this.getDiscountEntry(creditNote, discountAccountId); - const adjustmentEntry = this.getAdjustmentEntry( - creditNote, - adjustmentAccountId - ); - - return [AREntry, discountEntry, adjustmentEntry, ...itemsEntries]; - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteGLEntriesSubscriber.ts b/packages/server/src/services/CreditNotes/CreditNoteGLEntriesSubscriber.ts deleted file mode 100644 index 8ca4b088f..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteGLEntriesSubscriber.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - ICreditNoteCreatedPayload, - ICreditNoteDeletedPayload, - ICreditNoteEditedPayload, - ICreditNoteOpenedPayload, -} from '@/interfaces'; -import CreditNoteGLEntries from './CreditNoteGLEntries'; - -@Service() -export default class CreditNoteGLEntriesSubscriber { - @Inject() - private creditNoteGLEntries: CreditNoteGLEntries; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.creditNote.onCreated, - this.writeGlEntriesOnceCreditNoteCreated - ); - bus.subscribe( - events.creditNote.onOpened, - this.writeGLEntriesOnceCreditNoteOpened - ); - bus.subscribe( - events.creditNote.onEdited, - this.editVendorCreditGLEntriesOnceEdited - ); - bus.subscribe( - events.creditNote.onDeleted, - this.revertGLEntriesOnceCreditNoteDeleted - ); - } - - /** - * Writes the GL entries once the credit note transaction created or open. - * @private - * @param {ICreditNoteCreatedPayload|ICreditNoteOpenedPayload} payload - - */ - private writeGlEntriesOnceCreditNoteCreated = async ({ - tenantId, - creditNote, - creditNoteId, - trx, - }: ICreditNoteCreatedPayload | ICreditNoteOpenedPayload) => { - // Can't continue if the credit note is not published yet. - if (!creditNote.isPublished) return; - - await this.creditNoteGLEntries.createVendorCreditGLEntries( - tenantId, - creditNoteId, - trx - ); - }; - - /** - * Writes the GL entries once the vendor credit transaction opened. - * @param {ICreditNoteOpenedPayload} payload - */ - private writeGLEntriesOnceCreditNoteOpened = async ({ - tenantId, - creditNoteId, - trx, - }: ICreditNoteOpenedPayload) => { - await this.creditNoteGLEntries.createVendorCreditGLEntries( - tenantId, - creditNoteId, - trx - ); - }; - - /** - * Reverts GL entries once credit note deleted. - */ - private revertGLEntriesOnceCreditNoteDeleted = async ({ - tenantId, - oldCreditNote, - creditNoteId, - trx, - }: ICreditNoteDeletedPayload) => { - // Can't continue if the credit note is not published yet. - if (!oldCreditNote.isPublished) return; - - await this.creditNoteGLEntries.revertVendorCreditGLEntries( - tenantId, - creditNoteId - ); - }; - - /** - * Edits vendor credit associated GL entries once the transaction edited. - * @param {ICreditNoteEditedPayload} payload - - */ - private editVendorCreditGLEntriesOnceEdited = async ({ - tenantId, - creditNote, - creditNoteId, - trx, - }: ICreditNoteEditedPayload) => { - // Can't continue if the credit note is not published yet. - if (!creditNote.isPublished) return; - - await this.creditNoteGLEntries.editVendorCreditGLEntries( - tenantId, - creditNoteId, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteInventoryTransactionsSubscriber.ts b/packages/server/src/services/CreditNotes/CreditNoteInventoryTransactionsSubscriber.ts deleted file mode 100644 index 54b702bea..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteInventoryTransactionsSubscriber.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import CreditNoteInventoryTransactions from './CreditNotesInventoryTransactions'; -import { - ICreditNoteCreatedPayload, - ICreditNoteDeletedPayload, - ICreditNoteEditedPayload, -} from '@/interfaces'; - -@Service() -export default class CreditNoteInventoryTransactionsSubscriber { - @Inject() - inventoryTransactions: CreditNoteInventoryTransactions; - - /** - * Attaches events with publisher. - */ - public attach(bus) { - bus.subscribe( - events.creditNote.onCreated, - this.writeInventoryTranscationsOnceCreated - ); - bus.subscribe( - events.creditNote.onEdited, - this.rewriteInventoryTransactionsOnceEdited - ); - bus.subscribe( - events.creditNote.onDeleted, - this.revertInventoryTransactionsOnceDeleted - ); - bus.subscribe( - events.creditNote.onOpened, - this.writeInventoryTranscationsOnceCreated - ); - } - - /** - * Writes inventory transactions once credit note created. - * @param {ICreditNoteCreatedPayload} payload - - * @returns {Promise} - */ - public writeInventoryTranscationsOnceCreated = async ({ - tenantId, - creditNote, - trx, - }: ICreditNoteCreatedPayload) => { - // Can't continue if the credit note is open yet. - if (!creditNote.isOpen) return; - - await this.inventoryTransactions.createInventoryTransactions( - tenantId, - creditNote, - trx - ); - }; - - /** - * Rewrites inventory transactions once credit note edited. - * @param {ICreditNoteEditedPayload} payload - - * @returns {Promise} - */ - public rewriteInventoryTransactionsOnceEdited = async ({ - tenantId, - creditNoteId, - creditNote, - trx, - }: ICreditNoteEditedPayload) => { - // Can't continue if the credit note is open yet. - if (!creditNote.isOpen) return; - - await this.inventoryTransactions.editInventoryTransactions( - tenantId, - creditNoteId, - creditNote, - trx - ); - }; - - /** - * Reverts inventory transactions once credit note deleted. - * @param {ICreditNoteDeletedPayload} payload - - */ - public revertInventoryTransactionsOnceDeleted = async ({ - tenantId, - creditNoteId, - oldCreditNote, - trx, - }: ICreditNoteDeletedPayload) => { - // Can't continue if the credit note is open yet. - if (!oldCreditNote.isOpen) return; - - await this.inventoryTransactions.deleteInventoryTransactions( - tenantId, - creditNoteId, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteTransformer.ts b/packages/server/src/services/CreditNotes/CreditNoteTransformer.ts deleted file mode 100644 index 86e84681d..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteTransformer.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { ItemEntryTransformer } from '../Sales/Invoices/ItemEntryTransformer'; -import { ICreditNote } from '@/interfaces'; -import { AttachmentTransformer } from '../Attachments/AttachmentTransformer'; - -export class CreditNoteTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedCreditsRemaining', - 'formattedCreditNoteDate', - 'formattedCreatedAt', - 'formattedCreatedAt', - 'formattedAmount', - 'formattedCreditsUsed', - 'formattedSubtotal', - - 'discountAmountFormatted', - 'discountAmountLocalFormatted', - - 'discountPercentageFormatted', - - 'adjustmentFormatted', - 'adjustmentLocalFormatted', - - 'totalFormatted', - 'totalLocalFormatted', - - 'entries', - 'attachments', - ]; - }; - - /** - * Retrieve formatted credit note date. - * @param {ICreditNote} credit - * @returns {String} - */ - protected formattedCreditNoteDate = (credit): string => { - return this.formatDate(credit.creditNoteDate); - }; - - /** - * Retrieve formatted created at date. - * @param credit - * @returns {string} - */ - protected formattedCreatedAt = (credit): string => { - return this.formatDate(credit.createdAt); - }; - - /** - * Retrieve formatted invoice amount. - * @param {ICreditNote} credit - * @returns {string} - */ - protected formattedAmount = (credit): string => { - return formatNumber(credit.amount, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieve formatted credits remaining. - * @param {ICreditNote} credit - * @returns {string} - */ - protected formattedCreditsRemaining = (credit) => { - return formatNumber(credit.creditsRemaining, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieve formatted credits used. - * @param {ICreditNote} credit - * @returns {string} - */ - protected formattedCreditsUsed = (credit) => { - return formatNumber(credit.creditsUsed, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieves the formatted subtotal. - * @param {ICreditNote} credit - * @returns {string} - */ - protected formattedSubtotal = (credit): string => { - return formatNumber(credit.amount, { money: false }); - }; - - /** - * Retrieves formatted discount amount. - * @param credit - * @returns {string} - */ - protected discountAmountFormatted = (credit): string => { - return formatNumber(credit.discountAmount, { - currencyCode: credit.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted discount amount in local currency. - * @param {ICreditNote} credit - * @returns {string} - */ - protected discountAmountLocalFormatted = (credit): string => { - return formatNumber(credit.discountAmountLocal, { - currencyCode: credit.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves formatted discount percentage. - * @param credit - * @returns {string} - */ - protected discountPercentageFormatted = (credit): string => { - return credit.discountPercentage ? `${credit.discountPercentage}%` : ''; - }; - - /** - * Retrieves formatted adjustment amount. - * @param credit - * @returns {string} - */ - protected adjustmentFormatted = (credit): string => { - return this.formatMoney(credit.adjustment, { - currencyCode: credit.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted adjustment amount in local currency. - * @param {ICreditNote} credit - * @returns {string} - */ - protected adjustmentLocalFormatted = (credit): string => { - return formatNumber(credit.adjustmentLocal, { - currencyCode: this.context.organization.baseCurrency, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted total. - * @param credit - * @returns {string} - */ - protected totalFormatted = (credit): string => { - return formatNumber(credit.total, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieves the formatted total in local currency. - * @param credit - * @returns {string} - */ - protected totalLocalFormatted = (credit): string => { - return formatNumber(credit.totalLocal, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieves the entries of the credit note. - * @param {ICreditNote} credit - * @returns {} - */ - protected entries = (credit) => { - return this.item(credit.entries, new ItemEntryTransformer(), { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieves the credit note attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (creditNote) => { - return this.item(creditNote.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNoteWithInvoicesToApplyTransformer.ts b/packages/server/src/services/CreditNotes/CreditNoteWithInvoicesToApplyTransformer.ts deleted file mode 100644 index 9a2f5c222..000000000 --- a/packages/server/src/services/CreditNotes/CreditNoteWithInvoicesToApplyTransformer.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class CreditNoteWithInvoicesToApplyTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedInvoiceDate', - 'formattedDueDate', - 'formattedAmount', - 'formattedDueAmount', - 'formattedPaymentAmount', - ]; - }; - - /** - * Retrieve formatted invoice date. - * @param {ISaleInvoice} invoice - * @returns {String} - */ - protected formattedInvoiceDate = (invoice): string => { - return this.formatDate(invoice.invoiceDate); - }; - - /** - * Retrieve formatted due date. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected formattedDueDate = (invoice): string => { - return this.formatDate(invoice.dueDate); - }; - - /** - * Retrieve formatted invoice amount. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected formattedAmount = (invoice): string => { - return formatNumber(invoice.balance, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieve formatted invoice due amount. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected formattedDueAmount = (invoice): string => { - return formatNumber(invoice.dueAmount, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieve formatted payment amount. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected formattedPaymentAmount = (invoice): string => { - return formatNumber(invoice.paymentAmount, { - currencyCode: invoice.currencyCode, - }); - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNotes.ts b/packages/server/src/services/CreditNotes/CreditNotes.ts deleted file mode 100644 index 5f3a57a0d..000000000 --- a/packages/server/src/services/CreditNotes/CreditNotes.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { omit } from 'lodash'; -import * as R from 'ramda'; -import composeAsync from 'async/compose'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { - ICreditNote, - ICreditNoteEditDTO, - ICreditNoteEntryNewDTO, - ICreditNoteNewDTO, -} from '@/interfaces'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { assocItemEntriesDefaultIndex } from '../Items/utils'; -import { BrandingTemplateDTOTransformer } from '../PdfTemplate/BrandingTemplateDTOTransformer'; - -@Service() -export default class BaseCreditNotes { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - @Inject() - private brandingTemplatesTransformer: BrandingTemplateDTOTransformer; - - /** - * Transformes the credit/edit DTO to model. - * @param {ICreditNoteNewDTO | ICreditNoteEditDTO} creditNoteDTO - * @param {string} customerCurrencyCode - - */ - protected transformCreateEditDTOToModel = async ( - tenantId: number, - creditNoteDTO: ICreditNoteNewDTO | ICreditNoteEditDTO, - customerCurrencyCode: string, - oldCreditNote?: ICreditNote - ): Promise => { - // Retrieve the total amount of the given items entries. - const amount = this.itemsEntriesService.getTotalItemsEntries( - creditNoteDTO.entries - ); - const entries = R.compose( - // Associate the default index to each item entry. - assocItemEntriesDefaultIndex, - - // Associate the reference type to credit note entries. - R.map((entry: ICreditNoteEntryNewDTO) => ({ - ...entry, - referenceType: 'CreditNote', - })) - )(creditNoteDTO.entries); - - // Retreive the next credit note number. - const autoNextNumber = this.getNextCreditNumber(tenantId); - - // Detarmines the credit note number. - const creditNoteNumber = - creditNoteDTO.creditNoteNumber || - oldCreditNote?.creditNoteNumber || - autoNextNumber; - - const initialDTO = { - ...omit(creditNoteDTO, ['open', 'attachments']), - creditNoteNumber, - amount, - currencyCode: customerCurrencyCode, - exchangeRate: creditNoteDTO.exchangeRate || 1, - entries, - ...(creditNoteDTO.open && - !oldCreditNote?.openedAt && { - openedAt: moment().toMySqlDateTime(), - }), - refundedAmount: 0, - invoicesAmount: 0, - }; - const initialAsyncDTO = await composeAsync( - // Assigns the default branding template id to the invoice DTO. - this.brandingTemplatesTransformer.assocDefaultBrandingTemplate( - tenantId, - 'CreditNote' - ) - )(initialDTO); - - return R.compose( - this.branchDTOTransform.transformDTO(tenantId), - this.warehouseDTOTransform.transformDTO(tenantId) - )(initialAsyncDTO); - }; - - /** - * Retrieve the given credit note or throw not found service error. - * @param {number} tenantId - - * @param {number} creditNoteId - - */ - protected getCreditNoteOrThrowError = async ( - tenantId: number, - creditNoteId: number - ) => { - const { CreditNote } = this.tenancy.models(tenantId); - - const creditNote = await CreditNote.query().findById(creditNoteId); - - if (!creditNote) { - throw new ServiceError(ERRORS.CREDIT_NOTE_NOT_FOUND); - } - return creditNote; - }; - - /** - * Retrieve the next unique credit number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - private getNextCreditNumber = (tenantId: number): string => { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'credit_note' - ); - }; - - /** - * Increment the credit note serial next number. - * @param {number} tenantId - - */ - public incrementSerialNumber = (tenantId: number) => { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'credit_note' - ); - }; - - /** - * Validate the credit note remaining amount. - * @param {ICreditNote} creditNote - * @param {number} amount - */ - public validateCreditRemainingAmount = ( - creditNote: ICreditNote, - amount: number - ) => { - if (creditNote.creditsRemaining < amount) { - throw new ServiceError(ERRORS.CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/CreditNotesExportable.ts b/packages/server/src/services/CreditNotes/CreditNotesExportable.ts deleted file mode 100644 index f461b3b40..000000000 --- a/packages/server/src/services/CreditNotes/CreditNotesExportable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICreditNotesQueryDTO } from '@/interfaces'; -import { Exportable } from '@/services/Export/Exportable'; -import ListCreditNotes from './ListCreditNotes'; - -@Service() -export class CreditNotesExportable extends Exportable { - @Inject() - private getCreditNotes: ListCreditNotes; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - - * @param {IVendorCreditsQueryDTO} query - - * @returns {} - */ - public exportable(tenantId: number, query: ICreditNotesQueryDTO) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - query.withGraphFetched('warehouse'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: 12000, - filterQuery, - } as ICreditNotesQueryDTO; - - return this.getCreditNotes - .getCreditNotesList(tenantId, parsedQuery) - .then((output) => output.creditNotes); - } -} diff --git a/packages/server/src/services/CreditNotes/CreditNotesImportable.ts b/packages/server/src/services/CreditNotes/CreditNotesImportable.ts deleted file mode 100644 index 86388aad3..000000000 --- a/packages/server/src/services/CreditNotes/CreditNotesImportable.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ICreditNoteNewDTO } from '@/interfaces'; -import { Importable } from '../Import/Importable'; -import CreateCreditNote from './CreateCreditNote'; - -@Service() -export class CreditNotesImportable extends Importable { - @Inject() - private createCreditNoteImportable: CreateCreditNote; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: ICreditNoteNewDTO, - trx?: Knex.Transaction - ) { - return this.createCreditNoteImportable.newCreditNote( - tenantId, - createAccountDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return []; - } -} diff --git a/packages/server/src/services/CreditNotes/CreditNotesInventoryTransactions.ts b/packages/server/src/services/CreditNotes/CreditNotesInventoryTransactions.ts deleted file mode 100644 index 857f5fc89..000000000 --- a/packages/server/src/services/CreditNotes/CreditNotesInventoryTransactions.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ICreditNote } from '@/interfaces'; -import InventoryService from '@/services/Inventory/Inventory'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; - -@Service() -export default class CreditNoteInventoryTransactions { - @Inject() - inventoryService: InventoryService; - - @Inject() - itemsEntriesService: ItemsEntriesService; - - /** - * Creates credit note inventory transactions. - * @param {number} tenantId - * @param {ICreditNote} creditNote - */ - public createInventoryTransactions = async ( - tenantId: number, - creditNote: ICreditNote, - trx?: Knex.Transaction - ): Promise => { - // Loads the inventory items entries of the given sale invoice. - const inventoryEntries = - await this.itemsEntriesService.filterInventoryEntries( - tenantId, - creditNote.entries - ); - const transaction = { - transactionId: creditNote.id, - transactionType: 'CreditNote', - transactionNumber: creditNote.creditNoteNumber, - exchangeRate: creditNote.exchangeRate, - date: creditNote.creditNoteDate, - direction: 'IN', - entries: inventoryEntries, - createdAt: creditNote.createdAt, - warehouseId: creditNote.warehouseId, - }; - // Writes inventory tranactions. - await this.inventoryService.recordInventoryTransactionsFromItemsEntries( - tenantId, - transaction, - false, - trx - ); - }; - - /** - * Edits vendor credit associated inventory transactions. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {ICreditNote} creditNote - * @param {Knex.Transactions} trx - */ - public editInventoryTransactions = async ( - tenantId: number, - creditNoteId: number, - creditNote: ICreditNote, - trx?: Knex.Transaction - ): Promise => { - // Deletes inventory transactions. - await this.deleteInventoryTransactions(tenantId, creditNoteId, trx); - - // Re-write inventory transactions. - await this.createInventoryTransactions(tenantId, creditNote, trx); - }; - - /** - * Deletes credit note associated inventory transactions. - * @param {number} tenantId - Tenant id. - * @param {number} creditNoteId - Credit note id. - * @param {Knex.Transaction} trx - - */ - public deleteInventoryTransactions = async ( - tenantId: number, - creditNoteId: number, - trx?: Knex.Transaction - ): Promise => { - // Deletes the inventory transactions by the given reference id and type. - await this.inventoryService.deleteInventoryTransactions( - tenantId, - creditNoteId, - 'CreditNote', - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/DeleteCreditNote.ts b/packages/server/src/services/CreditNotes/DeleteCreditNote.ts deleted file mode 100644 index db53474ca..000000000 --- a/packages/server/src/services/CreditNotes/DeleteCreditNote.ts +++ /dev/null @@ -1,119 +0,0 @@ -import Knex from 'knex'; -import { Inject, Service } from 'typedi'; -import UnitOfWork from '@/services/UnitOfWork'; -import BaseCreditNotes from './CreditNotes'; -import { ICreditNoteDeletedPayload, ICreditNoteDeletingPayload } from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import RefundCreditNote from './RefundCreditNote'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -@Service() -export default class DeleteCreditNote extends BaseCreditNotes { - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - refundCreditNote: RefundCreditNote; - - /** - * Deletes the given credit note transactions. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public deleteCreditNote = async ( - tenantId: number, - creditNoteId: number - ): Promise => { - const { CreditNote, ItemEntry } = this.tenancy.models(tenantId); - - // Retrieve the credit note or throw not found service error. - const oldCreditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - // Validate credit note has no refund transactions. - await this.validateCreditNoteHasNoRefundTransactions( - tenantId, - creditNoteId - ); - // Validate credit note has no applied invoices transactions. - await this.validateCreditNoteHasNoApplyInvoiceTransactions( - tenantId, - creditNoteId - ); - // Deletes the credit note transactions under unit-of-work transaction. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCreditNoteDeleting` event. - await this.eventPublisher.emitAsync(events.creditNote.onDeleting, { - trx, - tenantId, - oldCreditNote - } as ICreditNoteDeletingPayload); - - // Delets the associated credit note entries. - await ItemEntry.query(trx) - .where('reference_id', creditNoteId) - .where('reference_type', 'CreditNote') - .delete(); - - // Deletes the credit note transaction. - await CreditNote.query(trx).findById(creditNoteId).delete(); - - // Triggers `onCreditNoteDeleted` event. - await this.eventPublisher.emitAsync(events.creditNote.onDeleted, { - tenantId, - oldCreditNote, - creditNoteId, - trx, - } as ICreditNoteDeletedPayload); - }); - }; - - /** - * Validates credit note has no associated refund transactions. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - private validateCreditNoteHasNoRefundTransactions = async ( - tenantId: number, - creditNoteId: number - ): Promise => { - const { RefundCreditNote } = this.tenancy.models(tenantId); - - const refundTransactions = await RefundCreditNote.query().where( - 'creditNoteId', - creditNoteId - ); - if (refundTransactions.length > 0) { - throw new ServiceError(ERRORS.CREDIT_NOTE_HAS_REFUNDS_TRANSACTIONS); - } - }; - - /** - * Validate credit note has no associated applied invoices transactions. - * @param {number} tenantId - Tenant id. - * @param {number} creditNoteId - Credit note id. - * @returns {Promise} - */ - private validateCreditNoteHasNoApplyInvoiceTransactions = async ( - tenantId: number, - creditNoteId: number - ) => { - const { CreditNoteAppliedInvoice } = this.tenancy.models(tenantId); - - const appliedTransactions = await CreditNoteAppliedInvoice.query().where( - 'creditNoteId', - creditNoteId - ); - if (appliedTransactions.length > 0) { - throw new ServiceError(ERRORS.CREDIT_NOTE_HAS_APPLIED_INVOICES); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/DeleteCreditNoteApplyToInvoices.ts b/packages/server/src/services/CreditNotes/DeleteCreditNoteApplyToInvoices.ts deleted file mode 100644 index 281cc3d88..000000000 --- a/packages/server/src/services/CreditNotes/DeleteCreditNoteApplyToInvoices.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { IApplyCreditToInvoicesDeletedPayload } from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import BaseCreditNotes from './CreditNotes'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export default class DeletreCreditNoteApplyToInvoices extends BaseCreditNotes { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Apply credit note to the given invoices. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO - */ - public deleteApplyCreditNoteToInvoices = async ( - tenantId: number, - applyCreditToInvoicesId: number - ): Promise => { - const { CreditNoteAppliedInvoice } = this.tenancy.models(tenantId); - - const creditNoteAppliedToInvoice = - await CreditNoteAppliedInvoice.query().findById(applyCreditToInvoicesId); - - if (!creditNoteAppliedToInvoice) { - throw new ServiceError(ERRORS.CREDIT_NOTE_APPLY_TO_INVOICES_NOT_FOUND); - } - // Retrieve the credit note or throw not found service error. - const creditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteAppliedToInvoice.creditNoteId - ); - // Creates credit note apply to invoice transaction. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Delete credit note applied to invoices. - await CreditNoteAppliedInvoice.query(trx) - .findById(applyCreditToInvoicesId) - .delete(); - - // Triggers `onCreditNoteApplyToInvoiceDeleted` event. - await this.eventPublisher.emitAsync( - events.creditNote.onApplyToInvoicesDeleted, - { - trx, - creditNote, - creditNoteAppliedToInvoice, - tenantId, - } as IApplyCreditToInvoicesDeletedPayload - ); - }); - }; -} diff --git a/packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditNote.ts b/packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditNote.ts deleted file mode 100644 index cb4d75007..000000000 --- a/packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditNote.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; - -@Service() -export default class DeleteCustomerLinkedCreidtNote { - @Inject() - tenancy: TenancyService; - - /** - * Validate the given customer has no linked credit note transactions. - * @param {number} tenantId - * @param {number} creditNoteId - */ - public validateCustomerHasNoCreditTransaction = async ( - tenantId: number, - customerId: number - ) => { - const { CreditNote } = this.tenancy.models(tenantId); - - const associatedCredits = await CreditNote.query().where( - 'customerId', - customerId - ); - if (associatedCredits.length > 0) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_LINKED_CREDIT_NOTES); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditSubscriber.ts b/packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditSubscriber.ts deleted file mode 100644 index 4f1fb3e9d..000000000 --- a/packages/server/src/services/CreditNotes/DeleteCustomerLinkedCreditSubscriber.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { ICustomerDeletingPayload } from '@/interfaces'; -import DeleteCustomerLinkedCreidtNote from './DeleteCustomerLinkedCreditNote'; - -const ERRORS = { - CUSTOMER_HAS_TRANSACTIONS: 'CUSTOMER_HAS_TRANSACTIONS', -}; - -@Service() -export default class DeleteCustomerLinkedCreditSubscriber { - @Inject() - tenancy: TenancyService; - - @Inject() - deleteCustomerLinkedCredit: DeleteCustomerLinkedCreidtNote; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach = (bus) => { - bus.subscribe( - events.customers.onDeleting, - this.validateCustomerHasNoLinkedCreditsOnDeleting - ); - }; - - /** - * Validate vendor has no associated credit transaction once the vendor deleting. - * @param {IVendorEventDeletingPayload} payload - - */ - public validateCustomerHasNoLinkedCreditsOnDeleting = async ({ - tenantId, - customerId, - }: ICustomerDeletingPayload) => { - try { - await this.deleteCustomerLinkedCredit.validateCustomerHasNoCreditTransaction( - tenantId, - customerId - ); - } catch (error) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_TRANSACTIONS); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/DeleteRefundCreditNote.ts b/packages/server/src/services/CreditNotes/DeleteRefundCreditNote.ts deleted file mode 100644 index adc2c6fa6..000000000 --- a/packages/server/src/services/CreditNotes/DeleteRefundCreditNote.ts +++ /dev/null @@ -1,73 +0,0 @@ -import Knex from 'knex'; -import { - IRefundCreditNoteDeletedPayload, - IRefundCreditNoteDeletingPayload, - IRefundVendorCreditDeletedPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; -import RefundCreditNote from './RefundCreditNote'; - -@Service() -export default class DeleteRefundCreditNote extends RefundCreditNote { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns - */ - public deleteCreditNoteRefund = async ( - tenantId: number, - refundCreditId: number - ) => { - const { RefundCreditNote } = this.tenancy.models(tenantId); - - // Retrieve the old credit note or throw not found service error. - const oldRefundCredit = await this.getCreditNoteRefundOrThrowError( - tenantId, - refundCreditId - ); - // Triggers `onCreditNoteRefundDeleted` event. - await this.eventPublisher.emitAsync(events.creditNote.onRefundDelete, { - refundCreditId, - oldRefundCredit, - tenantId, - } as IRefundCreditNoteDeletedPayload); - - // Deletes refund credit note transactions with associated entries. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - trx, - refundCreditId, - oldRefundCredit, - tenantId, - } as IRefundCreditNoteDeletedPayload | IRefundCreditNoteDeletingPayload; - - // Triggers `onCreditNoteRefundDeleting` event. - await this.eventPublisher.emitAsync( - events.creditNote.onRefundDeleting, - eventPayload - ); - // Deletes the refund credit note graph from the storage. - await RefundCreditNote.query(trx).findById(refundCreditId).delete(); - - // Triggers `onCreditNoteRefundDeleted` event. - await this.eventPublisher.emitAsync( - events.creditNote.onRefundDeleted, - eventPayload as IRefundVendorCreditDeletedPayload - ); - }); - }; -} diff --git a/packages/server/src/services/CreditNotes/EditCreditNote.ts b/packages/server/src/services/CreditNotes/EditCreditNote.ts deleted file mode 100644 index cbeed9ab2..000000000 --- a/packages/server/src/services/CreditNotes/EditCreditNote.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { - ICreditNoteEditDTO, - ICreditNoteEditedPayload, - ICreditNoteEditingPayload, -} from '@/interfaces'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; -import BaseCreditNotes from './CreditNotes'; - -@Service() -export default class EditCreditNote extends BaseCreditNotes { - @Inject() - itemsEntriesService: ItemsEntriesService; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - uow: UnitOfWork; - - /** - * Edits the given credit note. - * @param {number} tenantId - - * @param {ICreditNoteEditDTO} creditNoteEditDTO - - */ - public editCreditNote = async ( - tenantId: number, - creditNoteId: number, - creditNoteEditDTO: ICreditNoteEditDTO - ) => { - const { CreditNote, Contact } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const oldCreditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - // Validate customer existance. - const customer = await Contact.query() - .modify('customer') - .findById(creditNoteEditDTO.customerId) - .throwIfNotFound(); - - // Validate items ids existance. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - creditNoteEditDTO.entries - ); - // Validate non-sellable entries items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - creditNoteEditDTO.entries - ); - // Validate the items entries existance. - await this.itemsEntriesService.validateEntriesIdsExistance( - tenantId, - creditNoteId, - 'CreditNote', - creditNoteEditDTO.entries - ); - // Transformes the given DTO to storage layer data. - const creditNoteModel = await this.transformCreateEditDTOToModel( - tenantId, - creditNoteEditDTO, - customer.currencyCode, - oldCreditNote - ); - // Sales the credit note transactions with associated entries. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onCreditNoteEditing` event. - await this.eventPublisher.emitAsync(events.creditNote.onEditing, { - creditNoteEditDTO, - oldCreditNote, - trx, - tenantId, - } as ICreditNoteEditingPayload); - - // Saves the credit note graph to the storage. - const creditNote = await CreditNote.query(trx).upsertGraphAndFetch({ - id: creditNoteId, - ...creditNoteModel, - }); - // Triggers `onCreditNoteEdited` event. - await this.eventPublisher.emitAsync(events.creditNote.onEdited, { - trx, - oldCreditNote, - creditNoteId, - creditNote, - creditNoteEditDTO, - tenantId, - } as ICreditNoteEditedPayload); - - return creditNote; - }); - }; -} diff --git a/packages/server/src/services/CreditNotes/GetCreditNote.ts b/packages/server/src/services/CreditNotes/GetCreditNote.ts deleted file mode 100644 index 8f9484b8f..000000000 --- a/packages/server/src/services/CreditNotes/GetCreditNote.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ERRORS } from './constants'; -import BaseCreditNotes from './CreditNotes'; -import { CreditNoteTransformer } from './CreditNoteTransformer'; - -@Service() -export default class GetCreditNote extends BaseCreditNotes { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns - */ - public getCreditNote = async (tenantId: number, creditNoteId: number) => { - const { CreditNote } = this.tenancy.models(tenantId); - - // Retrieve the vendor credit model graph. - const creditNote = await CreditNote.query() - .findById(creditNoteId) - .withGraphFetched('entries.item') - .withGraphFetched('customer') - .withGraphFetched('branch') - .withGraphFetched('attachments'); - - if (!creditNote) { - throw new ServiceError(ERRORS.CREDIT_NOTE_NOT_FOUND); - } - // Transforms the credit note model to POJO. - return this.transformer.transform( - tenantId, - creditNote, - new CreditNoteTransformer(), - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices.ts b/packages/server/src/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices.ts deleted file mode 100644 index 925dc4c92..000000000 --- a/packages/server/src/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISaleInvoice } from '@/interfaces'; -import BaseCreditNotes from './CreditNotes'; -import { CreditNoteAppliedInvoiceTransformer } from './CreditNoteAppliedInvoiceTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class GetCreditNoteAssociatedAppliedInvoices extends BaseCreditNotes { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve credit note associated invoices to apply. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getCreditAssociatedAppliedInvoices = async ( - tenantId: number, - creditNoteId: number - ): Promise => { - const { CreditNoteAppliedInvoice } = this.tenancy.models(tenantId); - - // Retireve credit note or throw not found service error. - const creditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - const appliedToInvoices = await CreditNoteAppliedInvoice.query() - .where('credit_note_id', creditNoteId) - .withGraphFetched('saleInvoice') - .withGraphFetched('creditNote'); - - // Transformes credit note applied to invoices. - return this.transformer.transform( - tenantId, - appliedToInvoices, - new CreditNoteAppliedInvoiceTransformer() - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/GetCreditNoteAssociatedInvoicesToApply.ts b/packages/server/src/services/CreditNotes/GetCreditNoteAssociatedInvoicesToApply.ts deleted file mode 100644 index 30b44a23f..000000000 --- a/packages/server/src/services/CreditNotes/GetCreditNoteAssociatedInvoicesToApply.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Service, Inject } from 'typedi'; -import BaseCreditNotes from './CreditNotes'; -import { ISaleInvoice } from '@/interfaces'; -import { CreditNoteWithInvoicesToApplyTransformer } from './CreditNoteWithInvoicesToApplyTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class GetCreditNoteAssociatedInvoicesToApply extends BaseCreditNotes { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve credit note associated invoices to apply. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getCreditAssociatedInvoicesToApply = async ( - tenantId: number, - creditNoteId: number - ): Promise => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Retireve credit note or throw not found service error. - const creditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - // Retrieves the published due invoices that associated to the given customer. - const saleInvoices = await SaleInvoice.query() - .where('customerId', creditNote.customerId) - .modify('dueInvoices') - .modify('published'); - - // Transformes the sale invoices models to POJO. - return this.transformer.transform( - tenantId, - saleInvoices, - new CreditNoteWithInvoicesToApplyTransformer() - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts b/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts deleted file mode 100644 index d4a77c902..000000000 --- a/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy'; -import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable'; -import GetCreditNote from './GetCreditNote'; -import { CreditNoteBrandingTemplate } from './CreditNoteBrandingTemplate'; -import { CreditNotePdfTemplateAttributes } from '@/interfaces'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { transformCreditNoteToPdfTemplate } from './utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export default class GetCreditNotePdf { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - @Inject() - private templateInjectable: TemplateInjectable; - - @Inject() - private getCreditNoteService: GetCreditNote; - - @Inject() - private creditNoteBrandingTemplate: CreditNoteBrandingTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieves sale invoice pdf content. - * @param {number} tenantId - Tenant id. - * @param {number} creditNoteId - Credit note id. - * @returns {Promise<[Buffer, string]>} - */ - public async getCreditNotePdf( - tenantId: number, - creditNoteId: number - ): Promise<[Buffer, string]> { - const brandingAttributes = await this.getCreditNoteBrandingAttributes( - tenantId, - creditNoteId - ); - const htmlContent = await this.templateInjectable.render( - tenantId, - 'modules/credit-note-standard', - brandingAttributes - ); - const filename = await this.getCreditNoteFilename(tenantId, creditNoteId); - - const document = await this.chromiumlyTenancy.convertHtmlContent( - tenantId, - htmlContent - ); - const eventPayload = { tenantId, creditNoteId }; - - // Triggers the `onCreditNotePdfViewed` event. - await this.eventPublisher.emitAsync( - events.creditNote.onPdfViewed, - eventPayload - ); - return [document, filename]; - } - - /** - * Retrieves the filename pdf document of the given credit note. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public async getCreditNoteFilename( - tenantId: number, - creditNoteId: number - ): Promise { - const { CreditNote } = this.tenancy.models(tenantId); - - const creditNote = await CreditNote.query().findById(creditNoteId); - - return `Credit-${creditNote.creditNoteNumber}`; - } - - /** - * Retrieves credit note branding attributes. - * @param {number} tenantId - The ID of the tenant. - * @param {number} creditNoteId - The ID of the credit note. - * @returns {Promise} The credit note branding attributes. - */ - public async getCreditNoteBrandingAttributes( - tenantId: number, - creditNoteId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - const creditNote = await this.getCreditNoteService.getCreditNote( - tenantId, - creditNoteId - ); - // Retrieve the invoice template id of not found get the default template id. - const templateId = - creditNote.pdfTemplateId ?? - ( - await PdfTemplate.query().findOne({ - resource: 'CreditNote', - default: true, - }) - )?.id; - // Retrieves the credit note branding template. - const brandingTemplate = - await this.creditNoteBrandingTemplate.getCreditNoteBrandingTemplate( - tenantId, - templateId - ); - return { - ...brandingTemplate.attributes, - ...transformCreditNoteToPdfTemplate(creditNote), - }; - } -} diff --git a/packages/server/src/services/CreditNotes/GetCreditNoteState.ts b/packages/server/src/services/CreditNotes/GetCreditNoteState.ts deleted file mode 100644 index 24075a635..000000000 --- a/packages/server/src/services/CreditNotes/GetCreditNoteState.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICreditNoteState } from '@/interfaces'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export class GetCreditNoteState { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the create/edit initial state of the payment received. - * @param {Number} saleInvoiceId - - * @return {Promise} - */ - public async getCreditNoteState(tenantId: number): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const defaultPdfTemplate = await PdfTemplate.query() - .findOne({ resource: 'CreditNote' }) - .modify('default'); - - return { - defaultTemplateId: defaultPdfTemplate?.id, - }; - } -} diff --git a/packages/server/src/services/CreditNotes/GetRefundCreditNoteTransaction.ts b/packages/server/src/services/CreditNotes/GetRefundCreditNoteTransaction.ts deleted file mode 100644 index 8ffbaba6b..000000000 --- a/packages/server/src/services/CreditNotes/GetRefundCreditNoteTransaction.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IRefundCreditNote } from '@/interfaces'; -import RefundCreditNote from './RefundCreditNote'; -import RefundCreditNoteTransformer from './RefundCreditNoteTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class getRefundCreditNoteTransaction extends RefundCreditNote { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve credit note associated invoices to apply. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getRefundCreditTransaction = async ( - tenantId: number, - refundCreditId: number - ): Promise => { - const { RefundCreditNote } = this.tenancy.models(tenantId); - - await this.getCreditNoteRefundOrThrowError(tenantId, refundCreditId); - - const refundCreditNote = await RefundCreditNote.query() - .findById(refundCreditId) - .withGraphFetched('fromAccount') - .withGraphFetched('creditNote'); - - return this.transformer.transform( - tenantId, - refundCreditNote, - new RefundCreditNoteTransformer() - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/ListCreditNoteRefunds.ts b/packages/server/src/services/CreditNotes/ListCreditNoteRefunds.ts deleted file mode 100644 index 0c99c6808..000000000 --- a/packages/server/src/services/CreditNotes/ListCreditNoteRefunds.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { IRefundCreditNotePOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import BaseCreditNotes from './CreditNotes'; -import RefundCreditNoteTransformer from './RefundCreditNoteTransformer'; - -@Service() -export default class ListCreditNoteRefunds extends BaseCreditNotes { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getCreditNoteRefunds = async ( - tenantId: number, - creditNoteId: number - ): Promise => { - const { RefundCreditNote } = this.tenancy.models(tenantId); - - // Retrieve refund credit notes associated to the given credit note. - const refundCreditTransactions = await RefundCreditNote.query() - .where('creditNoteId', creditNoteId) - .withGraphFetched('creditNote') - .withGraphFetched('fromAccount'); - - // Transformes refund credit note models to POJO objects. - return this.transformer.transform( - tenantId, - refundCreditTransactions, - new RefundCreditNoteTransformer() - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/ListCreditNotes.ts b/packages/server/src/services/CreditNotes/ListCreditNotes.ts deleted file mode 100644 index 5eb5753e3..000000000 --- a/packages/server/src/services/CreditNotes/ListCreditNotes.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { ICreditNotesQueryDTO } from '@/interfaces'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import BaseCreditNotes from './CreditNotes'; -import { CreditNoteTransformer } from './CreditNoteTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class ListCreditNotes extends BaseCreditNotes { - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Parses the sale invoice list filter DTO. - * @param filterDTO - * @returns - */ - private parseListFilterDTO = (filterDTO) => { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - }; - - /** - * Retrieves the paginated and filterable credit notes list. - * @param {number} tenantId - - * @param {ICreditNotesQueryDTO} creditNotesQuery - - */ - public getCreditNotesList = async ( - tenantId: number, - creditNotesQuery: ICreditNotesQueryDTO - ) => { - const { CreditNote } = this.tenancy.models(tenantId); - - // Parses stringified filter roles. - const filter = this.parseListFilterDTO(creditNotesQuery); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - CreditNote, - filter - ); - const { results, pagination } = await CreditNote.query() - .onBuild((builder) => { - builder.withGraphFetched('entries.item'); - builder.withGraphFetched('customer'); - dynamicFilter.buildQuery()(builder); - creditNotesQuery?.filterQuery && creditNotesQuery?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transforomes the credit notes to POJO. - const creditNotes = await this.transformer.transform( - tenantId, - results, - new CreditNoteTransformer() - ); - - return { - creditNotes, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - }; -} diff --git a/packages/server/src/services/CreditNotes/OpenCreditNote.ts b/packages/server/src/services/CreditNotes/OpenCreditNote.ts deleted file mode 100644 index 7efd4430c..000000000 --- a/packages/server/src/services/CreditNotes/OpenCreditNote.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { - ICreditNote, - ICreditNoteOpenedPayload, - ICreditNoteOpeningPayload, -} from '@/interfaces'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; -import BaseCreditNotes from './CreditNotes'; -import { ERRORS } from './constants'; - -@Service() -export default class OpenCreditNote extends BaseCreditNotes { - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Opens the given credit note. - * @param {number} tenantId - - * @param {ICreditNoteEditDTO} creditNoteEditDTO - - * @returns {Promise} - */ - public openCreditNote = async ( - tenantId: number, - creditNoteId: number - ): Promise => { - const { CreditNote } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const oldCreditNote = await this.getCreditNoteOrThrowError( - tenantId, - creditNoteId - ); - // Throw service error if the credit note is already open. - this.throwErrorIfAlreadyOpen(oldCreditNote); - - // Triggers `onCreditNoteOpen` event. - this.eventPublisher.emitAsync(events.creditNote.onOpen, { - tenantId, - creditNoteId, - oldCreditNote, - }); - // Sales the credit note transactions with associated entries. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - tenantId, - creditNoteId, - oldCreditNote, - trx, - } as ICreditNoteOpeningPayload; - - // Triggers `onCreditNoteOpening` event. - await this.eventPublisher.emitAsync( - events.creditNote.onOpening, - eventPayload - ); - // Saves the credit note graph to the storage. - const creditNote = await CreditNote.query(trx) - .findById(creditNoteId) - .update({ - openedAt: new Date(), - }); - // Triggers `onCreditNoteOpened` event. - await this.eventPublisher.emitAsync(events.creditNote.onOpened, { - ...eventPayload, - creditNote, - } as ICreditNoteOpenedPayload); - - return creditNote; - }); - }; - - /** - * - * @param creditNote - */ - public throwErrorIfAlreadyOpen = (creditNote) => { - if (creditNote.openedAt) { - throw new ServiceError(ERRORS.CREDIT_NOTE_ALREADY_OPENED); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/RefundCreditNote.ts b/packages/server/src/services/CreditNotes/RefundCreditNote.ts deleted file mode 100644 index 395103dba..000000000 --- a/packages/server/src/services/CreditNotes/RefundCreditNote.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { IAccount, IRefundCreditNote } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import BaseCreditNotes from './CreditNotes'; -import { ERRORS } from './constants'; - -@Service() -export default class RefundCreditNote extends BaseCreditNotes { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - * @param {number} refundCreditId - * @returns {Promise} - */ - public getCreditNoteRefundOrThrowError = async ( - tenantId: number, - refundCreditId: number - ): Promise => { - const { RefundCreditNote } = this.tenancy.models(tenantId); - - const refundCreditNote = await RefundCreditNote.query().findById( - refundCreditId - ); - if (!refundCreditNote) { - throw new ServiceError(ERRORS.REFUND_CREDIT_NOTE_NOT_FOUND); - } - return refundCreditNote; - }; - - /** - * Validate the refund account type. - * @param {IAccount} account - */ - public validateRefundWithdrawwalAccountType = (account: IAccount): void => { - const supportedTypes = ['bank', 'cash', 'fixed-asset']; - - if (supportedTypes.indexOf(account.accountType) === -1) { - throw new ServiceError(ERRORS.ACCOUNT_INVALID_TYPE); - } - }; -} diff --git a/packages/server/src/services/CreditNotes/RefundCreditNoteGLEntries.ts b/packages/server/src/services/CreditNotes/RefundCreditNoteGLEntries.ts deleted file mode 100644 index 4cee87a0c..000000000 --- a/packages/server/src/services/CreditNotes/RefundCreditNoteGLEntries.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { AccountNormal, ILedgerEntry, IRefundCreditNote } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export default class RefundCreditNoteGLEntries { - @Inject() - ledgerStorage: LedgerStorageService; - - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieves the refund credit common GL entry. - * @param {IRefundCreditNote} refundCreditNote - * @returns - */ - private getRefundCreditCommonGLEntry = ( - refundCreditNote: IRefundCreditNote - ) => { - return { - currencyCode: refundCreditNote.currencyCode, - exchangeRate: refundCreditNote.exchangeRate, - - transactionType: 'RefundCreditNote', - transactionId: refundCreditNote.id, - date: refundCreditNote.date, - userId: refundCreditNote.userId, - - referenceNumber: refundCreditNote.referenceNo, - - createdAt: refundCreditNote.createdAt, - indexGroup: 10, - - credit: 0, - debit: 0, - - note: refundCreditNote.description, - branchId: refundCreditNote.branchId, - }; - }; - - /** - * Retrieves the refudn credit receivable GL entry. - * @param {IRefundCreditNote} refundCreditNote - * @param {number} ARAccountId - * @returns {ILedgerEntry} - */ - private getRefundCreditGLReceivableEntry = ( - refundCreditNote: IRefundCreditNote, - ARAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote); - - return { - ...commonEntry, - debit: refundCreditNote.amount, - accountId: ARAccountId, - contactId: refundCreditNote.creditNote.customerId, - index: 1, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieves the refund credit withdrawal GL entry. - * @param {number} refundCreditNote - * @returns {ILedgerEntry} - */ - private getRefundCreditGLWithdrawalEntry = ( - refundCreditNote: IRefundCreditNote - ): ILedgerEntry => { - const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote); - - return { - ...commonEntry, - credit: refundCreditNote.amount, - accountId: refundCreditNote.fromAccountId, - index: 2, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieve the refund credit note GL entries. - * @param {IRefundCreditNote} refundCreditNote - * @param {number} receivableAccount - * @returns {ILedgerEntry[]} - */ - public getRefundCreditGLEntries( - refundCreditNote: IRefundCreditNote, - ARAccountId: number - ): ILedgerEntry[] { - const receivableEntry = this.getRefundCreditGLReceivableEntry( - refundCreditNote, - ARAccountId - ); - const withdrawalEntry = - this.getRefundCreditGLWithdrawalEntry(refundCreditNote); - - return [receivableEntry, withdrawalEntry]; - } - - /** - * Creates refund credit GL entries. - * @param {number} tenantId - * @param {IRefundCreditNote} refundCreditNote - * @param {Knex.Transaction} trx - */ - public createRefundCreditGLEntries = async ( - tenantId: number, - refundCreditNoteId: number, - trx?: Knex.Transaction - ) => { - const { Account, RefundCreditNote } = this.tenancy.models(tenantId); - - // Retrieve the refund with associated credit note. - const refundCreditNote = await RefundCreditNote.query(trx) - .findById(refundCreditNoteId) - .withGraphFetched('creditNote'); - - // Receivable account A/R. - const receivableAccount = await Account.query().findOne( - 'slug', - 'accounts-receivable' - ); - // Retrieve refund credit GL entries. - const refundGLEntries = this.getRefundCreditGLEntries( - refundCreditNote, - receivableAccount.id - ); - const ledger = new Ledger(refundGLEntries); - - // Saves refund ledger entries. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Reverts refund credit note GL entries. - * @param {number} tenantId - * @param {number} refundCreditNoteId - * @param {number} receivableAccount - * @param {Knex.Transaction} trx - */ - public revertRefundCreditGLEntries = async ( - tenantId: number, - refundCreditNoteId: number, - trx?: Knex.Transaction - ) => { - await this.ledgerStorage.deleteByReference( - tenantId, - refundCreditNoteId, - 'RefundCreditNote', - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/RefundCreditNoteGLEntriesSubscriber.ts b/packages/server/src/services/CreditNotes/RefundCreditNoteGLEntriesSubscriber.ts deleted file mode 100644 index d075c4c85..000000000 --- a/packages/server/src/services/CreditNotes/RefundCreditNoteGLEntriesSubscriber.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import RefundCreditNoteGLEntries from './RefundCreditNoteGLEntries'; -import { - IRefundCreditNoteCreatedPayload, - IRefundCreditNoteDeletedPayload, -} from '@/interfaces'; - -@Service() -export default class RefundCreditNoteGLEntriesSubscriber { - @Inject() - refundCreditGLEntries: RefundCreditNoteGLEntries; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.creditNote.onRefundCreated, - this.writeRefundCreditGLEntriesOnceCreated - ); - bus.subscribe( - events.creditNote.onRefundDeleted, - this.revertRefundCreditGLEntriesOnceDeleted - ); - }; - - /** - * Writes refund credit note GL entries once the transaction created. - * @param {IRefundCreditNoteCreatedPayload} payload - - */ - private writeRefundCreditGLEntriesOnceCreated = async ({ - trx, - refundCreditNote, - creditNote, - tenantId, - }: IRefundCreditNoteCreatedPayload) => { - await this.refundCreditGLEntries.createRefundCreditGLEntries( - tenantId, - refundCreditNote.id, - trx - ); - }; - - /** - * Reverts refund credit note GL entries once the transaction deleted. - * @param {IRefundCreditNoteDeletedPayload} payload - - */ - private revertRefundCreditGLEntriesOnceDeleted = async ({ - trx, - refundCreditId, - oldRefundCredit, - tenantId, - }: IRefundCreditNoteDeletedPayload) => { - await this.refundCreditGLEntries.revertRefundCreditGLEntries( - tenantId, - refundCreditId, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/RefundCreditNoteTransformer.ts b/packages/server/src/services/CreditNotes/RefundCreditNoteTransformer.ts deleted file mode 100644 index 73602de0c..000000000 --- a/packages/server/src/services/CreditNotes/RefundCreditNoteTransformer.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export default class RefundCreditNoteTransformer extends Transformer { - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return ['formttedAmount', 'formattedDate']; - }; - - /** - * Formatted amount. - * @returns {string} - */ - protected formttedAmount = (item) => { - return formatNumber(item.amount, { - currencyCode: item.currencyCode, - }); - }; - - /** - * Formatted date. - * @returns {string} - */ - protected formattedDate = (item) => { - return this.formatDate(item.date); - }; -} diff --git a/packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalance.ts b/packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalance.ts deleted file mode 100644 index 17f21209f..000000000 --- a/packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalance.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class RefundSyncCreditNoteBalance { - @Inject() - tenancy: HasTenancyService; - - /** - * - * @param {number} tenantId - * @param {IRefundCreditNote} refundCreditNote - * @param {Knex.Transaction} trx - */ - public incrementCreditNoteRefundAmount = async ( - tenantId: number, - creditNoteId: number, - amount: number, - trx?: Knex.Transaction - ): Promise => { - const { CreditNote } = this.tenancy.models(tenantId); - - await CreditNote.query(trx) - .findById(creditNoteId) - .increment('refunded_amount', amount); - }; - - /** - * - * @param {number} tenantId - * @param {IRefundCreditNote} refundCreditNote - * @param {Knex.Transaction} trx - */ - public decrementCreditNoteRefundAmount = async ( - tenantId: number, - creditNoteId: number, - amount: number, - trx?: Knex.Transaction - ): Promise => { - const { CreditNote } = this.tenancy.models(tenantId); - - await CreditNote.query(trx) - .findById(creditNoteId) - .decrement('refunded_amount', amount); - }; -} diff --git a/packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalanceSubscriber.ts b/packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalanceSubscriber.ts deleted file mode 100644 index d82b44bff..000000000 --- a/packages/server/src/services/CreditNotes/RefundSyncCreditNoteBalanceSubscriber.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IRefundCreditNoteCreatedPayload, - IRefundCreditNoteDeletedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import RefundSyncCreditNoteBalance from './RefundSyncCreditNoteBalance'; - -@Service() -export default class RefundSyncCreditNoteBalanceSubscriber { - @Inject() - refundSyncCreditBalance: RefundSyncCreditNoteBalance; - - /** - * Attaches events with handlers. - */ - attach(bus) { - bus.subscribe( - events.creditNote.onRefundCreated, - this.incrementRefundedAmountOnceRefundCreated - ); - bus.subscribe( - events.creditNote.onRefundDeleted, - this.decrementRefundedAmountOnceRefundDeleted - ); - return bus; - } - - /** - * Increment credit note refunded amount once associated refund transaction created. - * @param {IRefundCreditNoteCreatedPayload} payload - - */ - private incrementRefundedAmountOnceRefundCreated = async ({ - trx, - refundCreditNote, - tenantId, - }: IRefundCreditNoteCreatedPayload) => { - await this.refundSyncCreditBalance.incrementCreditNoteRefundAmount( - tenantId, - refundCreditNote.creditNoteId, - refundCreditNote.amount, - trx - ); - }; - - /** - * Decrement credit note refunded amount once associated refuned transaction deleted. - * @param {IRefundCreditNoteDeletedPayload} payload - - */ - private decrementRefundedAmountOnceRefundDeleted = async ({ - trx, - oldRefundCredit, - tenantId, - }: IRefundCreditNoteDeletedPayload) => { - await this.refundSyncCreditBalance.decrementCreditNoteRefundAmount( - tenantId, - oldRefundCredit.creditNoteId, - oldRefundCredit.amount, - trx - ); - }; -} diff --git a/packages/server/src/services/CreditNotes/constants.ts b/packages/server/src/services/CreditNotes/constants.ts deleted file mode 100644 index 4f1d51d30..000000000 --- a/packages/server/src/services/CreditNotes/constants.ts +++ /dev/null @@ -1,132 +0,0 @@ -export const ERRORS = { - CREDIT_NOTE_NOT_FOUND: 'CREDIT_NOTE_NOT_FOUND', - REFUND_CREDIT_NOTE_NOT_FOUND: 'REFUND_CREDIT_NOTE_NOT_FOUND', - CREDIT_NOTE_ALREADY_OPENED: 'CREDIT_NOTE_ALREADY_OPENED', - ACCOUNT_INVALID_TYPE: 'ACCOUNT_INVALID_TYPE', - CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT: 'CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT', - INVOICES_HAS_NO_REMAINING_AMOUNT: 'INVOICES_HAS_NO_REMAINING_AMOUNT', - CREDIT_NOTE_APPLY_TO_INVOICES_NOT_FOUND: - 'CREDIT_NOTE_APPLY_TO_INVOICES_NOT_FOUND', - CREDIT_NOTE_HAS_REFUNDS_TRANSACTIONS: 'CREDIT_NOTE_HAS_REFUNDS_TRANSACTIONS', - CREDIT_NOTE_HAS_APPLIED_INVOICES: 'CREDIT_NOTE_HAS_APPLIED_INVOICES', - CUSTOMER_HAS_LINKED_CREDIT_NOTES: 'CUSTOMER_HAS_LINKED_CREDIT_NOTES', -}; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'credit_note.view.draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'credit_note.view.published', - slug: 'published', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'published', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'credit_note.view.open', - slug: 'open', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'open', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'credit_note.view.closed', - slug: 'closed', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'closed', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const defaultCreditNoteBrandingAttributes = { - // # Colors - primaryColor: '', - secondaryColor: '', - - // # Company logo - showCompanyLogo: true, - companyLogoKey: '', - companyLogoUri: '', - - // # Company name - companyName: 'Bigcapital Technology, Inc.', - - // # Customer address - showCustomerAddress: true, - customerAddress: '', - - // # Company address - showCompanyAddress: true, - companyAddress: '', - billedToLabel: 'Billed To', - - // Total - total: '$1000.00', - totalLabel: 'Total', - showTotal: true, - - // Subtotal - subtotal: '1000/00', - subtotalLabel: 'Subtotal', - showSubtotal: true, - - // Customer note - showCustomerNote: true, - customerNote: - 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.', - customerNoteLabel: 'Customer Note', - - // Terms & conditions - showTermsConditions: true, - termsConditions: - 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.', - termsConditionsLabel: 'Terms & Conditions', - - lines: [ - { - item: 'Simply dummy text', - description: 'Simply dummy text of the printing and typesetting', - rate: '1', - quantity: '1000', - total: '$1000.00', - }, - ], - // Credit note number. - showCreditNoteNumber: true, - creditNoteNumberLabel: 'Credit Note Number', - creditNoteNumebr: '346D3D40-0001', - - // Credit note date. - creditNoteDate: 'September 3, 2024', - showCreditNoteDate: true, - creditNoteDateLabel: 'Credit Note Date', -}; diff --git a/packages/server/src/services/CreditNotes/utils.ts b/packages/server/src/services/CreditNotes/utils.ts deleted file mode 100644 index 8936f922c..000000000 --- a/packages/server/src/services/CreditNotes/utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { CreditNotePdfTemplateAttributes, ICreditNote } from '@/interfaces'; -import { contactAddressTextFormat } from '@/utils/address-text-format'; - -export const transformCreditNoteToPdfTemplate = ( - creditNote: ICreditNote -): Partial => { - return { - creditNoteDate: creditNote.formattedCreditNoteDate, - creditNoteNumebr: creditNote.creditNoteNumber, - - total: creditNote.formattedAmount, - subtotal: creditNote.formattedSubtotal, - - lines: creditNote.entries?.map((entry) => ({ - item: entry.item.name, - description: entry.description, - rate: entry.rateFormatted, - quantity: entry.quantityFormatted, - total: entry.totalFormatted, - })), - customerNote: creditNote.note, - termsConditions: creditNote.termsConditions, - customerAddress: contactAddressTextFormat(creditNote.customer), - }; -}; diff --git a/packages/server/src/services/Currencies/CurrenciesService.ts b/packages/server/src/services/Currencies/CurrenciesService.ts deleted file mode 100644 index 97cdae4e8..000000000 --- a/packages/server/src/services/Currencies/CurrenciesService.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ICurrencyEditDTO, - ICurrencyDTO, - ICurrenciesService, - ICurrency, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { Tenant } from '@/system/models'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { CurrencyTransformer } from './CurrencyTransformer'; - -const ERRORS = { - CURRENCY_NOT_FOUND: 'currency_not_found', - CURRENCY_CODE_EXISTS: 'currency_code_exists', - BASE_CURRENCY_INVALID: 'BASE_CURRENCY_INVALID', - CANNOT_DELETE_BASE_CURRENCY: 'CANNOT_DELETE_BASE_CURRENCY', -}; - -@Service() -export default class CurrenciesService implements ICurrenciesService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve currency by given currency code or throw not found error. - * @param {number} tenantId - * @param {string} currencyCode - * @param {number} currencyId - */ - private async validateCurrencyCodeUniquiness( - tenantId: number, - currencyCode: string, - currencyId?: number - ) { - const { Currency } = this.tenancy.models(tenantId); - - const foundCurrency = await Currency.query().onBuild((query) => { - query.findOne('currency_code', currencyCode); - - if (currencyId) { - query.whereNot('id', currencyId); - } - }); - if (foundCurrency) { - throw new ServiceError(ERRORS.CURRENCY_CODE_EXISTS); - } - } - - /** - * Retrieve currency by the given currency code or throw service error. - * @param {number} tenantId - * @param {string} currencyCode - */ - private async getCurrencyByCodeOrThrowError( - tenantId: number, - currencyCode: string - ) { - const { Currency } = this.tenancy.models(tenantId); - - const foundCurrency = await Currency.query().findOne( - 'currency_code', - currencyCode - ); - - if (!foundCurrency) { - throw new ServiceError(ERRORS.CURRENCY_NOT_FOUND); - } - return foundCurrency; - } - - /** - * Retrieve currency by given id or throw not found error. - * @param {number} tenantId - * @param {number} currencyId - */ - private async getCurrencyIdOrThrowError( - tenantId: number, - currencyId: number - ) { - const { Currency } = this.tenancy.models(tenantId); - - const foundCurrency = await Currency.query().findOne('id', currencyId); - - if (!foundCurrency) { - throw new ServiceError(ERRORS.CURRENCY_NOT_FOUND); - } - return foundCurrency; - } - - /** - * Creates a new currency. - * @param {number} tenantId - * @param {ICurrencyDTO} currencyDTO - */ - public async newCurrency(tenantId: number, currencyDTO: ICurrencyDTO) { - const { Currency } = this.tenancy.models(tenantId); - - // Validate currency code uniquiness. - await this.validateCurrencyCodeUniquiness( - tenantId, - currencyDTO.currencyCode - ); - - await Currency.query().insert({ ...currencyDTO }); - } - - /** - * Edit details of the given currency. - * @param {number} tenantId - * @param {number} currencyId - * @param {ICurrencyDTO} currencyDTO - */ - public async editCurrency( - tenantId: number, - currencyId: number, - currencyDTO: ICurrencyEditDTO - ): Promise { - const { Currency } = this.tenancy.models(tenantId); - - await this.getCurrencyIdOrThrowError(tenantId, currencyId); - - const currency = await Currency.query().patchAndFetchById(currencyId, { - ...currencyDTO, - }); - return currency; - } - - /** - * Validate cannot delete base currency. - * @param {number} tenantId - * @param {string} currencyCode - */ - private async validateCannotDeleteBaseCurrency( - tenantId: number, - currencyCode: string - ) { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - if (tenant.metadata.baseCurrency === currencyCode) { - throw new ServiceError(ERRORS.CANNOT_DELETE_BASE_CURRENCY); - } - } - - /** - * Delete the given currency code. - * @param {number} tenantId - * @param {string} currencyCode - * @return {Promise} - */ - public async deleteCurrency( - tenantId: number, - currencyCode: string - ): Promise { - const { Currency } = this.tenancy.models(tenantId); - - await this.getCurrencyByCodeOrThrowError(tenantId, currencyCode); - - // Validate currency code not equals base currency. - await this.validateCannotDeleteBaseCurrency(tenantId, currencyCode); - - await Currency.query().where('currency_code', currencyCode).delete(); - } - - /** - * Listing currencies. - * @param {number} tenantId - * @return {Promise} - */ - public async listCurrencies(tenantId: number): Promise { - const { Currency } = this.tenancy.models(tenantId); - - const currencies = await Currency.query().onBuild((query) => { - query.orderBy('createdAt', 'ASC'); - }); - return this.transformer.transform( - tenantId, - currencies, - new CurrencyTransformer() - ); - } -} diff --git a/packages/server/src/services/Currencies/CurrencyTransformer.ts b/packages/server/src/services/Currencies/CurrencyTransformer.ts deleted file mode 100644 index c29704cac..000000000 --- a/packages/server/src/services/Currencies/CurrencyTransformer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class CurrencyTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['isBaseCurrency']; - }; - - /** - * Detarmines whether the currency is base currency. - * @returns {boolean} - */ - public isBaseCurrency(currency): boolean { - return this.context.organization.baseCurrency === currency.currencyCode; - } -} diff --git a/packages/server/src/services/Currencies/InitialCurrenciesSeed.ts b/packages/server/src/services/Currencies/InitialCurrenciesSeed.ts deleted file mode 100644 index b77c988a8..000000000 --- a/packages/server/src/services/Currencies/InitialCurrenciesSeed.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { uniq } from 'lodash'; -import Currencies from 'js-money/lib/currency'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { InitialCurrencies } from './constants'; - -@Service() -export class InitialCurrenciesSeed { - @Inject() - private tenancy: HasTenancyService; - - /** - * Seeds the given base currency to the currencies list. - * @param {number} tenantId - * @param {string} baseCurrency - */ - public seedCurrencyByCode = async ( - tenantId: number, - currencyCode: string - ): Promise => { - const { Currency } = this.tenancy.models(tenantId); - const currencyMeta = Currencies[currencyCode]; - - const foundBaseCurrency = await Currency.query().findOne( - 'currency_code', - currencyCode - ); - if (!foundBaseCurrency) { - await Currency.query().insert({ - currency_code: currencyMeta.code, - currency_name: currencyMeta.name, - currency_sign: currencyMeta.symbol, - }); - } - }; - - /** - * Seeds initial currencies to the organization. - * @param {number} tenantId - * @param {string} baseCurrency - */ - public seedInitialCurrencies = async ( - tenantId: number, - baseCurrency: string - ): Promise => { - const initialCurrencies = uniq([...InitialCurrencies, baseCurrency]); - // Seed currency opers. - const seedCurrencyOpers = initialCurrencies.map((currencyCode) => { - return this.seedCurrencyByCode(tenantId, currencyCode); - }); - await Promise.all(seedCurrencyOpers); - }; -} diff --git a/packages/server/src/services/Currencies/constants.ts b/packages/server/src/services/Currencies/constants.ts deleted file mode 100644 index 702150303..000000000 --- a/packages/server/src/services/Currencies/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -// eslint-disable-next-line import/prefer-default-export -export const InitialCurrencies = [ - 'USD', - 'CAD', - 'EUR', - 'LYD', - 'GBP', - 'CNY', - 'AUD', - 'INR', -]; diff --git a/packages/server/src/services/Currencies/subscribers/SeedInitialCurrenciesOnSetupSubscriber.ts b/packages/server/src/services/Currencies/subscribers/SeedInitialCurrenciesOnSetupSubscriber.ts deleted file mode 100644 index 28419f024..000000000 --- a/packages/server/src/services/Currencies/subscribers/SeedInitialCurrenciesOnSetupSubscriber.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { IOrganizationBuildEventPayload } from '@/interfaces'; -import { InitialCurrenciesSeed } from '../InitialCurrenciesSeed'; - -@Service() -export class SeedInitialCurrenciesOnSetupSubsriber { - @Inject() - seedInitialCurrencies: InitialCurrenciesSeed; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe(events.organization.build, this.seedInitialCurrenciesOnBuild); - } - - /** - * Seed initial currencies once organization build. - * @param {IOrganizationBuildEventPayload} - */ - private seedInitialCurrenciesOnBuild = async ({ - systemUser, - buildDTO, - tenantId, - }: IOrganizationBuildEventPayload) => { - await this.seedInitialCurrencies.seedInitialCurrencies( - tenantId, - buildDTO.baseCurrency - ); - }; -} diff --git a/packages/server/src/services/Dashboard/DashboardService.ts b/packages/server/src/services/Dashboard/DashboardService.ts deleted file mode 100644 index e8411b1bf..000000000 --- a/packages/server/src/services/Dashboard/DashboardService.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IFeatureAllItem, ISystemUser } from '@/interfaces'; -import { FeaturesManager } from '@/services/Features/FeaturesManager'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import config from '@/config'; - -interface IRoleAbility { - subject: string; - ability: string; -} - -interface IDashboardBootMeta { - abilities: IRoleAbility[]; - features: IFeatureAllItem[]; - isBigcapitalCloud: boolean; -} - -@Service() -export default class DashboardService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private featuresManager: FeaturesManager; - - /** - * Retrieve dashboard meta. - * @param {number} tenantId - * @param {number} authorizedUser - */ - public getBootMeta = async ( - tenantId: number, - authorizedUser: ISystemUser - ): Promise => { - // Retrieves all orgnaization abilities. - const abilities = await this.getBootAbilities(tenantId, authorizedUser.id); - - // Retrieves all organization features. - const features = await this.featuresManager.all(tenantId); - - return { - abilities, - features, - isBigcapitalCloud: config.hostedOnBigcapitalCloud - }; - }; - - /** - * Transformes role permissions to abilities. - */ - transformRoleAbility = (permissions) => { - return permissions - .filter((permission) => permission.value) - .map((permission) => ({ - subject: permission.subject, - action: permission.ability, - })); - }; - - /** - * Retrieve the boot abilities. - * @returns - */ - private getBootAbilities = async ( - tenantId: number, - systemUserId: number - ): Promise => { - const { User } = this.tenancy.models(tenantId); - - const tenantUser = await User.query() - .findOne('systemUserId', systemUserId) - .withGraphFetched('role.permissions'); - - return tenantUser.role.slug === 'admin' - ? [{ subject: 'all', action: 'manage' }] - : this.transformRoleAbility(tenantUser.role.permissions); - }; -} diff --git a/packages/server/src/services/DynamicListing/DynamicListAbstract.ts b/packages/server/src/services/DynamicListing/DynamicListAbstract.ts deleted file mode 100644 index 216ace346..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListAbstract.ts +++ /dev/null @@ -1,6 +0,0 @@ - - - -export default class DynamicListAbstract { - -} \ No newline at end of file diff --git a/packages/server/src/services/DynamicListing/DynamicListCustomView.ts b/packages/server/src/services/DynamicListing/DynamicListCustomView.ts deleted file mode 100644 index a46f6ee98..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListCustomView.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import DynamicListAbstract from './DynamicListAbstract'; -import DynamicFilterViews from '@/lib/DynamicFilter/DynamicFilterViews'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { IModel } from '@/interfaces'; - -@Service() -export default class DynamicListCustomView extends DynamicListAbstract { - @Inject() - tenancy: HasTenancyService; - - /** - * Retreive custom view or throws error not found. - * @param {number} tenantId - * @param {number} viewId - * @return {Promise} - */ - private getCustomViewOrThrowError = async ( - tenantId: number, - viewSlug: string, - model: IModel - ) => { - const { View } = this.tenancy.models(tenantId); - - // Finds the default view by the given view slug. - const defaultView = model.getDefaultViewBySlug(viewSlug); - - if (!defaultView) { - throw new ServiceError(ERRORS.VIEW_NOT_FOUND); - } - return defaultView; - }; - - /** - * Dynamic list custom view. - * @param {IModel} model - * @param {number} customViewId - * @returns - */ - public dynamicListCustomView = async ( - dynamicFilter: any, - customViewSlug: string, - tenantId: number - ) => { - const model = dynamicFilter.getModel(); - - // Retrieve the custom view or throw not found. - const view = await this.getCustomViewOrThrowError( - tenantId, - customViewSlug, - model, - ); - return new DynamicFilterViews(view); - }; -} diff --git a/packages/server/src/services/DynamicListing/DynamicListFilterRoles.ts b/packages/server/src/services/DynamicListing/DynamicListFilterRoles.ts deleted file mode 100644 index 8f8485036..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListFilterRoles.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Service } from 'typedi'; -import * as R from 'ramda'; -import validator from 'is-my-json-valid'; -import { IFilterRole, IModel } from '@/interfaces'; -import DynamicListAbstract from './DynamicListAbstract'; -import DynamicFilterAdvancedFilter from '@/lib/DynamicFilter/DynamicFilterAdvancedFilter'; -import { ERRORS } from './constants'; -import { ServiceError } from '@/exceptions'; - -@Service() -export default class DynamicListFilterRoles extends DynamicListAbstract { - /** - * Validates filter roles schema. - * @param {IFilterRole[]} filterRoles - Filter roles. - */ - private validateFilterRolesSchema = (filterRoles: IFilterRole[]) => { - const validate = validator({ - required: true, - type: 'object', - properties: { - condition: { type: 'string' }, - fieldKey: { required: true, type: 'string' }, - value: { required: true }, - }, - }); - const invalidFields = filterRoles.filter((filterRole) => { - return !validate(filterRole); - }); - if (invalidFields.length > 0) { - throw new ServiceError(ERRORS.STRINGIFIED_FILTER_ROLES_INVALID); - } - }; - - /** - * Retrieve filter roles fields key that not exists on the given model. - * @param {IModel} model - * @param {IFilterRole} filterRoles - * @returns {string[]} - */ - private getFilterRolesFieldsNotExist = ( - model, - filterRoles: IFilterRole[] - ): string[] => { - return filterRoles - .filter((filterRole) => !model.getField(filterRole.fieldKey)) - .map((filterRole) => filterRole.fieldKey); - }; - - /** - * Validates existance the fields of filter roles. - * @param {IModel} model - * @param {IFilterRole[]} filterRoles - * @throws {ServiceError} - */ - private validateFilterRolesFieldsExistance = ( - model: IModel, - filterRoles: IFilterRole[] - ) => { - const invalidFieldsKeys = this.getFilterRolesFieldsNotExist( - model, - filterRoles - ); - if (invalidFieldsKeys.length > 0) { - throw new ServiceError(ERRORS.FILTER_ROLES_FIELDS_NOT_FOUND); - } - }; - - /** - * Associate index to filter roles. - * @param {IFilterRole[]} filterRoles - * @returns {IFilterRole[]} - */ - private incrementFilterRolesIndex = ( - filterRoles: IFilterRole[] - ): IFilterRole[] => { - return filterRoles.map((filterRole, index) => ({ - ...filterRole, - index: index + 1, - })); - }; - - /** - * Dynamic list filter roles. - * @param {IModel} model - * @param {IFilterRole[]} filterRoles - * @returns {DynamicFilterFilterRoles} - */ - public dynamicList = ( - model: IModel, - filterRoles: IFilterRole[] - ): DynamicFilterAdvancedFilter => { - const filterRolesParsed = R.compose(this.incrementFilterRolesIndex)( - filterRoles - ); - // Validate filter roles json schema. - this.validateFilterRolesSchema(filterRolesParsed); - - // Validate the model resource fields. - this.validateFilterRolesFieldsExistance(model, filterRoles); - - return new DynamicFilterAdvancedFilter(filterRolesParsed); - }; -} diff --git a/packages/server/src/services/DynamicListing/DynamicListSearch.ts b/packages/server/src/services/DynamicListing/DynamicListSearch.ts deleted file mode 100644 index 7dadaa897..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListSearch.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Service } from 'typedi'; -import { IFilterRole, IModel } from '@/interfaces'; -import DynamicListAbstract from './DynamicListAbstract'; -import DynamicFilterFilterRoles from '@/lib/DynamicFilter/DynamicFilterFilterRoles'; -import DynamicFilterSearch from '@/lib/DynamicFilter/DynamicFilterSearch'; - -@Service() -export default class DynamicListSearch extends DynamicListAbstract { - /** - * Dynamic list filter roles. - * @param {IModel} model - * @param {IFilterRole[]} filterRoles - * @returns {DynamicFilterFilterRoles} - */ - public dynamicSearch = (model: IModel, searchKeyword: string) => { - return new DynamicFilterSearch(searchKeyword); - }; -} diff --git a/packages/server/src/services/DynamicListing/DynamicListService.ts b/packages/server/src/services/DynamicListing/DynamicListService.ts deleted file mode 100644 index 5bd3c5d01..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListService.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Request, Response, NextFunction } from 'express'; -import { castArray, isEmpty } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import { DynamicFilter } from '@/lib/DynamicFilter'; -import { - IDynamicListFilter, - IDynamicListService, - IFilterRole, - IModel, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListFilterRoles from './DynamicListFilterRoles'; -import DynamicListSortBy from './DynamicListSortBy'; -import DynamicListCustomView from './DynamicListCustomView'; -import DynamicListSearch from './DynamicListSearch'; - -@Service() -export default class DynamicListService implements IDynamicListService { - @Inject() - tenancy: TenancyService; - - @Inject() - dynamicListFilterRoles: DynamicListFilterRoles; - - @Inject() - dynamicListSortBy: DynamicListSortBy; - - @Inject() - dynamicListView: DynamicListCustomView; - - @Inject() - dynamicListSearch: DynamicListSearch; - - /** - * Parses filter DTO. - * @param {IMode} model - - * @param {} filterDTO - - */ - private parseFilterObject = (model, filterDTO) => { - return { - // Merges the default properties with filter object. - ...(model.defaultSort - ? { - sortOrder: model.defaultSort.sortOrder, - columnSortBy: model.defaultSort.sortOrder, - } - : {}), - ...filterDTO, - }; - }; - - /** - * Dynamic listing. - * @param {number} tenantId - Tenant id. - * @param {IModel} model - Model. - * @param {IDynamicListFilter} filter - Dynamic filter DTO. - */ - public dynamicList = async ( - tenantId: number, - model: IModel, - filter: IDynamicListFilter - ) => { - const dynamicFilter = new DynamicFilter(model); - - // Parses the filter object. - const parsedFilter = this.parseFilterObject(model, filter); - - // Search by keyword. - if (filter.searchKeyword) { - const dynamicListSearch = this.dynamicListSearch.dynamicSearch( - model, - filter.searchKeyword - ); - dynamicFilter.setFilter(dynamicListSearch); - } - // Custom view filter roles. - if (filter.viewSlug) { - const dynamicListCustomView = - await this.dynamicListView.dynamicListCustomView( - dynamicFilter, - filter.viewSlug, - tenantId - ); - dynamicFilter.setFilter(dynamicListCustomView); - } - // Sort by the given column. - if (parsedFilter.columnSortBy) { - const dynmaicListSortBy = this.dynamicListSortBy.dynamicSortBy( - model, - parsedFilter.columnSortBy, - parsedFilter.sortOrder - ); - dynamicFilter.setFilter(dynmaicListSortBy); - } - // Filter roles. - if (!isEmpty(parsedFilter.filterRoles)) { - const dynamicFilterRoles = this.dynamicListFilterRoles.dynamicList( - model, - parsedFilter.filterRoles - ); - dynamicFilter.setFilter(dynamicFilterRoles); - } - return dynamicFilter; - }; - - /** - * Middleware to catch services errors - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public handlerErrorsToResponse( - error: Error, - req: Request, - res: Response, - next: NextFunction - ) { - if (error instanceof ServiceError) { - if (error.errorType === 'sort_column_not_found') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'SORT.COLUMN.NOT.FOUND', - message: 'Sort column not found.', - code: 200, - }, - ], - }); - } - if (error.errorType === 'view_not_found') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'CUSTOM.VIEW.NOT.FOUND', - message: 'Custom view not found.', - code: 100, - }, - ], - }); - } - if (error.errorType === 'filter_roles_fields_not_found') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'FILTER.ROLES.FIELDS.NOT.FOUND', - message: 'Filter roles fields not found.', - code: 300, - }, - ], - }); - } - if (error.errorType === 'stringified_filter_roles_invalid') { - return res.boom.badRequest(null, { - errors: [ - { - type: 'STRINGIFIED_FILTER_ROLES_INVALID', - message: 'Stringified filter roles json invalid.', - code: 400, - }, - ], - }); - } - } - next(error); - } - - /** - * Parses stringified filter roles. - * @param {string} stringifiedFilterRoles - Stringified filter roles. - */ - public parseStringifiedFilter = (filterRoles: IDynamicListFilter) => { - return { - ...filterRoles, - filterRoles: filterRoles.stringifiedFilterRoles - ? castArray(JSON.parse(filterRoles.stringifiedFilterRoles)) - : [], - }; - }; -} diff --git a/packages/server/src/services/DynamicListing/DynamicListSortBy.ts b/packages/server/src/services/DynamicListing/DynamicListSortBy.ts deleted file mode 100644 index 0e236edb0..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListSortBy.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Service } from 'typedi'; -import DynamicListAbstract from './DynamicListAbstract'; -import DynamicFilterSortBy from '@/lib/DynamicFilter/DynamicFilterSortBy'; -import { IModel, ISortOrder } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -@Service() -export default class DynamicListSortBy extends DynamicListAbstract { - /** - * Dynamic list sort by. - * @param {IModel} model - * @param {string} columnSortBy - * @param {ISortOrder} sortOrder - * @returns {DynamicFilterSortBy} - */ - public dynamicSortBy( - model: IModel, - columnSortBy: string, - sortOrder: ISortOrder - ) { - this.validateSortColumnExistance(model, columnSortBy); - - return new DynamicFilterSortBy(columnSortBy, sortOrder); - } - - /** - * Validates the sort column whether exists. - * @param {IModel} model - Model. - * @param {string} columnSortBy - Sort column - * @throws {ServiceError} - */ - private validateSortColumnExistance(model: any, columnSortBy: string) { - const field = model.getField(columnSortBy); - - if (!field) { - throw new ServiceError(ERRORS.SORT_COLUMN_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/DynamicListing/DynamicListing.types.ts b/packages/server/src/services/DynamicListing/DynamicListing.types.ts deleted file mode 100644 index 175d155c7..000000000 --- a/packages/server/src/services/DynamicListing/DynamicListing.types.ts +++ /dev/null @@ -1,31 +0,0 @@ -// import { IModel, ISortOrder } from "./Model"; - -import { ISortOrder } from "@/interfaces"; - -// export interface IDynamicFilter { -// setModel(model: IModel): void; -// buildQuery(): void; -// getResponseMeta(); -// } - -export interface IFilterRole { - fieldKey: string; - value: string; - condition?: string; - index?: number; - comparator?: string; -} -export interface IDynamicListFilter { - customViewId?: number; - filterRoles?: IFilterRole[]; - columnSortBy: ISortOrder; - sortOrder: string; - stringifiedFilterRoles: string; - searchKeyword?: string; -} - -// Search role. -export interface ISearchRole { - fieldKey: string; - comparator: string; -} \ No newline at end of file diff --git a/packages/server/src/services/DynamicListing/constants.ts b/packages/server/src/services/DynamicListing/constants.ts deleted file mode 100644 index 414de46ac..000000000 --- a/packages/server/src/services/DynamicListing/constants.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const ERRORS = { - STRINGIFIED_FILTER_ROLES_INVALID: 'stringified_filter_roles_invalid', - VIEW_NOT_FOUND: 'view_not_found', - SORT_COLUMN_NOT_FOUND: 'sort_column_not_found', - FILTER_ROLES_FIELDS_NOT_FOUND: 'filter_roles_fields_not_found', -}; diff --git a/packages/server/src/services/DynamicListing/validators.ts b/packages/server/src/services/DynamicListing/validators.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/src/services/Entries/index.ts b/packages/server/src/services/Entries/index.ts deleted file mode 100644 index 1a9de20e5..000000000 --- a/packages/server/src/services/Entries/index.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { transformToMap } from 'utils'; -import { - ICommonLandedCostEntry, - ICommonLandedCostEntryDTO -} from '@/interfaces'; - -const ERRORS = { - ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED: - 'ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED', - LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES: - 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES', -}; - -@Service() -export default class EntriesService { - /** - * Validates bill entries that has allocated landed cost amount not deleted. - * @param {IItemEntry[]} oldCommonEntries - - * @param {IItemEntry[]} newBillEntries - - */ - public getLandedCostEntriesDeleted( - oldCommonEntries: ICommonLandedCostEntry[], - newCommonEntriesDTO: ICommonLandedCostEntryDTO[] - ): ICommonLandedCostEntry[] { - const newBillEntriesById = transformToMap(newCommonEntriesDTO, 'id'); - - return oldCommonEntries.filter((entry) => { - const newEntry = newBillEntriesById.get(entry.id); - - if (entry.allocatedCostAmount > 0 && typeof newEntry === 'undefined') { - return true; - } - return false; - }); - } - - /** - * Validates the bill entries that have located cost amount should not be deleted. - * @param {IItemEntry[]} oldCommonEntries - Old bill entries. - * @param {IItemEntryDTO[]} newBillEntries - New DTO bill entries. - */ - public validateLandedCostEntriesNotDeleted( - oldCommonEntries: ICommonLandedCostEntry[], - newCommonEntriesDTO: ICommonLandedCostEntryDTO[] - ): void { - const entriesDeleted = this.getLandedCostEntriesDeleted( - oldCommonEntries, - newCommonEntriesDTO - ); - if (entriesDeleted.length > 0) { - throw new ServiceError(ERRORS.ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED); - } - } - - /** - * Validate allocated cost amount entries should be smaller than new entries amount. - * @param {IItemEntry[]} oldCommonEntries - Old bill entries. - * @param {IItemEntryDTO[]} newBillEntries - New DTO bill entries. - */ - public validateLocatedCostEntriesSmallerThanNewEntries( - oldCommonEntries: ICommonLandedCostEntry[], - newCommonEntriesDTO: ICommonLandedCostEntryDTO[] - ): void { - const oldBillEntriesById = transformToMap(oldCommonEntries, 'id'); - - newCommonEntriesDTO.forEach((entry) => { - const oldEntry = oldBillEntriesById.get(entry.id); - - if (oldEntry && oldEntry.allocatedCostAmount > entry.amount) { - throw new ServiceError( - ERRORS.LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES - ); - } - }); - } -} diff --git a/packages/server/src/services/EventsTracker/PostHog.ts b/packages/server/src/services/EventsTracker/PostHog.ts deleted file mode 100644 index ef4d46b9e..000000000 --- a/packages/server/src/services/EventsTracker/PostHog.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { PostHog } from 'posthog-node'; -import { Service } from 'typedi'; -import { EventMessage } from 'posthog-node/src/types'; -import config from '@/config'; - -@Service() -export class PosthogService { - public posthog: PostHog; - - constructor() { - if (config.posthog.apiKey && config.posthog.host) { - this.posthog = new PostHog(config.posthog.apiKey, { - host: config.posthog.host, - }); - } - } - - public trackEvent(event: EventMessage) { - // Cannot continue if the Posthog not configured. - if (!this.posthog) return; - - this.posthog.capture(event); - } -} diff --git a/packages/server/src/services/EventsTracker/events/AccountEventsTracker.ts b/packages/server/src/services/EventsTracker/events/AccountEventsTracker.ts deleted file mode 100644 index 3f2dff8dd..000000000 --- a/packages/server/src/services/EventsTracker/events/AccountEventsTracker.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IAccountEventCreatedPayload, - IAccountEventEditedPayload, - IAccountEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - ACCOUNT_CREATED, - ACCOUNT_EDITED, - ACCOUNT_DELETED, - ACCOUNT_VIEWED, -} from '@/constants/event-tracker'; - -@Service() -export class AccountEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.accounts.onCreated, - this.handleTrackAccountCreatedEvent - ); - bus.subscribe(events.accounts.onEdited, this.handleTrackEditedAccountEvent); - bus.subscribe( - events.accounts.onDeleted, - this.handleTrackDeletedAccountEvent - ); - bus.subscribe(events.accounts.onViewed, this.handleTrackAccountViewedEvent); - } - - private handleTrackAccountCreatedEvent = ({ - tenantId, - }: IAccountEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ACCOUNT_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedAccountEvent = ({ - tenantId, - }: IAccountEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ACCOUNT_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedAccountEvent = ({ - tenantId, - }: IAccountEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ACCOUNT_DELETED, - properties: {}, - }); - }; - - private handleTrackAccountViewedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ACCOUNT_VIEWED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/AuthenticationEventsTracker.ts b/packages/server/src/services/EventsTracker/events/AuthenticationEventsTracker.ts deleted file mode 100644 index cce7495fe..000000000 --- a/packages/server/src/services/EventsTracker/events/AuthenticationEventsTracker.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { IAuthSignedUpEventPayload } from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import { AUTH_SIGNED_UP } from '@/constants/event-tracker'; -import events from '@/subscribers/events'; - -@Service() -export class AuthenticationEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe(events.auth.signUp, this.handleTrackSignUpEvent); - } - - private handleTrackSignUpEvent = ({ - signupDTO, - user, - tenant, - }: IAuthSignedUpEventPayload) => { - this.posthog.trackEvent({ - distinctId: user.email, - event: AUTH_SIGNED_UP, - properties: { - firstName: user.firstName, - lastName: user.lastName, - email: user.email, - }, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/BankRuleEventsTracker.ts b/packages/server/src/services/EventsTracker/events/BankRuleEventsTracker.ts deleted file mode 100644 index 5b12e1d91..000000000 --- a/packages/server/src/services/EventsTracker/events/BankRuleEventsTracker.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IBankRuleEventCreatedPayload, - IBankRuleEventEditedPayload, - IBankRuleEventDeletedPayload, -} from '@/services/Banking/Rules/types'; // Updated import path for interfaces -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - BANK_RULE_CREATED, - BANK_RULE_EDITED, - BANK_RULE_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class BankRuleEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.bankRules.onCreated, - this.handleTrackBankRuleCreatedEvent - ); - bus.subscribe( - events.bankRules.onEdited, - this.handleTrackEditedBankRuleEvent - ); - bus.subscribe( - events.bankRules.onDeleted, - this.handleTrackDeletedBankRuleEvent - ); - } - - private handleTrackBankRuleCreatedEvent = ({ - tenantId, - }: IBankRuleEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_RULE_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedBankRuleEvent = ({ - tenantId, - }: IBankRuleEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_RULE_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedBankRuleEvent = ({ - tenantId, - }: IBankRuleEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_RULE_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/BankTransactionEventsTracker.ts b/packages/server/src/services/EventsTracker/events/BankTransactionEventsTracker.ts deleted file mode 100644 index f19615eb4..000000000 --- a/packages/server/src/services/EventsTracker/events/BankTransactionEventsTracker.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - BANK_TRANSACTION_MATCHED, - BANK_TRANSACTION_EXCLUDED, - BANK_TRANSACTION_CATEGORIZED, - BANK_TRANSACTION_UNCATEGORIZED, - BANK_ACCOUNT_DISCONNECTED, -} from '@/constants/event-tracker'; -import { IBankTransactionMatchedEventPayload } from '@/services/Banking/Matching/types'; -import { IBankAccountDisconnectedEventPayload } from '@/services/Banking/BankAccounts/types'; -import { - ICashflowTransactionCategorizedPayload, - ICashflowTransactionUncategorizedPayload, -} from '@/interfaces'; -import { IBankTransactionExcludedEventPayload } from '@/services/Banking/Exclude/_types'; - -@Service() -export class BankTransactionEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - public attach(bus) { - bus.subscribe( - events.bankMatch.onMatched, - this.handleTrackBankTransactionMatchedEvent - ); - bus.subscribe( - events.bankTransactions.onExcluded, - this.handleTrackBankTransactionExcludedEvent - ); - bus.subscribe( - events.cashflow.onTransactionCategorized, - this.handleTrackBankTransactionCategorizedEvent - ); - bus.subscribe( - events.cashflow.onTransactionUncategorized, - this.handleTrackBankTransactionUncategorizedEvent - ); - bus.subscribe( - events.bankAccount.onDisconnected, - this.handleTrackBankAccountDisconnectedEvent - ); - } - - private handleTrackBankTransactionMatchedEvent = ({ - tenantId, - }: IBankTransactionMatchedEventPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_TRANSACTION_MATCHED, - properties: {}, - }); - }; - - private handleTrackBankTransactionExcludedEvent = ({ - tenantId, - }: IBankTransactionExcludedEventPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_TRANSACTION_EXCLUDED, - properties: {}, - }); - }; - - private handleTrackBankTransactionCategorizedEvent = ({ - tenantId, - }: ICashflowTransactionCategorizedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_TRANSACTION_CATEGORIZED, - properties: {}, - }); - }; - - private handleTrackBankTransactionUncategorizedEvent = ({ - tenantId, - }: ICashflowTransactionUncategorizedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_TRANSACTION_UNCATEGORIZED, - properties: {}, - }); - }; - - private handleTrackBankAccountDisconnectedEvent = ({ - tenantId, - }: IBankAccountDisconnectedEventPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BANK_ACCOUNT_DISCONNECTED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/BillEventsTracker.ts b/packages/server/src/services/EventsTracker/events/BillEventsTracker.ts deleted file mode 100644 index dceb01bd8..000000000 --- a/packages/server/src/services/EventsTracker/events/BillEventsTracker.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IBillPaymentEventCreatedPayload, - IBillPaymentEventEditedPayload, - IBillPaymentEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - BILL_CREATED, - BILL_EDITED, - BILL_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class BillEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe(events.bill.onCreated, this.handleTrackBillCreatedEvent); - bus.subscribe(events.bill.onEdited, this.handleTrackEditedBillEvent); - bus.subscribe(events.bill.onDeleted, this.handleTrackDeletedBillEvent); - } - - private handleTrackBillCreatedEvent = ({ - tenantId, - }: IBillPaymentEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BILL_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedBillEvent = ({ - tenantId, - }: IBillPaymentEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BILL_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedBillEvent = ({ - tenantId, - }: IBillPaymentEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BILL_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/CustomerEventsTracker.ts b/packages/server/src/services/EventsTracker/events/CustomerEventsTracker.ts deleted file mode 100644 index 85527bb17..000000000 --- a/packages/server/src/services/EventsTracker/events/CustomerEventsTracker.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - ICustomerEventCreatedPayload, - ICustomerEventEditedPayload, - ICustomerEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - CUSTOMER_CREATED, - CUSTOMER_EDITED, - CUSTOMER_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class CustomerEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - public attach(bus) { - bus.subscribe( - events.customers.onCreated, - this.handleTrackCustomerCreatedEvent - ); - bus.subscribe( - events.customers.onEdited, - this.handleTrackEditedCustomerEvent - ); - bus.subscribe( - events.customers.onDeleted, - this.handleTrackDeletedCustomerEvent - ); - } - - private handleTrackCustomerCreatedEvent = ({ - tenantId, - }: ICustomerEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: CUSTOMER_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedCustomerEvent = ({ - tenantId, - }: ICustomerEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: CUSTOMER_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedCustomerEvent = ({ - tenantId, - }: ICustomerEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: CUSTOMER_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/ExpenseEventsTracker.ts b/packages/server/src/services/EventsTracker/events/ExpenseEventsTracker.ts deleted file mode 100644 index d766bbb10..000000000 --- a/packages/server/src/services/EventsTracker/events/ExpenseEventsTracker.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IExpenseCreatedPayload, - IExpenseEventEditPayload, - IExpenseEventDeletePayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - EXPENSE_CREATED, - EXPENSE_EDITED, - EXPENSE_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class ExpenseEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.expenses.onCreated, - this.handleTrackExpenseCreatedEvent - ); - bus.subscribe(events.expenses.onEdited, this.handleTrackEditedExpenseEvent); - bus.subscribe( - events.expenses.onDeleted, - this.handleTrackDeletedExpenseEvent - ); - } - - private handleTrackExpenseCreatedEvent = ({ - tenantId, - }: IExpenseCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: EXPENSE_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedExpenseEvent = ({ - tenantId, - }: IExpenseEventEditPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: EXPENSE_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedExpenseEvent = ({ - tenantId, - }: IExpenseEventDeletePayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: EXPENSE_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/ItemEventsTracker.ts b/packages/server/src/services/EventsTracker/events/ItemEventsTracker.ts deleted file mode 100644 index d4d52f8dc..000000000 --- a/packages/server/src/services/EventsTracker/events/ItemEventsTracker.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IItemEventCreatedPayload, - IItemEventEditedPayload, - IItemEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - ITEM_EVENT_CREATED, - ITEM_EVENT_EDITED, - ITEM_EVENT_DELETED, - ITEM_EVENT_VIEWED, -} from '@/constants/event-tracker'; - -@Service() -export class ItemEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe(events.item.onCreated, this.handleTrackItemCreatedEvent); - bus.subscribe(events.item.onEdited, this.handleTrackEditedItemEvent); - bus.subscribe(events.item.onDeleted, this.handleTrackDeletedItemEvent); - bus.subscribe(events.item.onViewed, this.handleTrackViewedItemEvent); - } - - private handleTrackItemCreatedEvent = ({ - tenantId, - }: IItemEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ITEM_EVENT_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedItemEvent = ({ - tenantId, - }: IItemEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ITEM_EVENT_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedItemEvent = ({ - tenantId, - }: IItemEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ITEM_EVENT_DELETED, - properties: {}, - }); - }; - - private handleTrackViewedItemEvent = ({ - tenantId, - }: IItemEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: ITEM_EVENT_VIEWED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/ManualJournalEventsTracker.ts b/packages/server/src/services/EventsTracker/events/ManualJournalEventsTracker.ts deleted file mode 100644 index 119553b88..000000000 --- a/packages/server/src/services/EventsTracker/events/ManualJournalEventsTracker.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IManualJournalEventCreatedPayload, - IManualJournalEventEditedPayload, - IManualJournalEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - MANUAL_JOURNAL_CREATED, - MANUAL_JOURNAL_EDITED, - MANUAL_JOURNAL_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class ManualJournalEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.manualJournals.onCreated, - this.handleTrackManualJournalCreatedEvent - ); - bus.subscribe( - events.manualJournals.onEdited, - this.handleTrackEditedManualJournalEvent - ); - bus.subscribe( - events.manualJournals.onDeleted, - this.handleTrackDeletedManualJournalEvent - ); - } - - private handleTrackManualJournalCreatedEvent = ({ - tenantId, - }: IManualJournalEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: MANUAL_JOURNAL_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedManualJournalEvent = ({ - tenantId, - }: IManualJournalEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: MANUAL_JOURNAL_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedManualJournalEvent = ({ - tenantId, - }: IManualJournalEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: MANUAL_JOURNAL_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/PaymentLinkEventsTracker.ts b/packages/server/src/services/EventsTracker/events/PaymentLinkEventsTracker.ts deleted file mode 100644 index 399a4fb3f..000000000 --- a/packages/server/src/services/EventsTracker/events/PaymentLinkEventsTracker.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { PosthogService } from '../PostHog'; -import { INVOICE_PAYMENT_LINK_GENERATED } from '@/constants/event-tracker'; -import events from '@/subscribers/events'; - -@Service() -export class PaymentLinkEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onPublicLinkGenerated, - this.handleTrackInvoicePublicLinkGeneratedEvent - ); - } - - public handleTrackInvoicePublicLinkGeneratedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: INVOICE_PAYMENT_LINK_GENERATED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/PaymentMadeEventsTracker.ts b/packages/server/src/services/EventsTracker/events/PaymentMadeEventsTracker.ts deleted file mode 100644 index 0f17989b8..000000000 --- a/packages/server/src/services/EventsTracker/events/PaymentMadeEventsTracker.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IBillPaymentEventCreatedPayload, - IBillPaymentEditingPayload, - IBillPaymentEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - PAYMENT_MADE_CREATED, - PAYMENT_MADE_EDITED, - PAYMENT_MADE_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class PaymentMadeEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.billPayment.onCreated, - this.handleTrackPaymentMadeCreatedEvent - ); - bus.subscribe( - events.billPayment.onEdited, - this.handleTrackEditedPaymentMadeEvent - ); - bus.subscribe( - events.billPayment.onDeleted, - this.handleTrackDeletedPaymentMadeEvent - ); - } - - private handleTrackPaymentMadeCreatedEvent = ({ - tenantId, - }: IBillPaymentEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_MADE_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedPaymentMadeEvent = ({ - tenantId, - }: IBillPaymentEditingPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_MADE_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedPaymentMadeEvent = ({ - tenantId, - }: IBillPaymentEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_MADE_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/PaymentMethodEventsTracker.ts b/packages/server/src/services/EventsTracker/events/PaymentMethodEventsTracker.ts deleted file mode 100644 index a82081846..000000000 --- a/packages/server/src/services/EventsTracker/events/PaymentMethodEventsTracker.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - PAYMENT_METHOD_EDITED, - PAYMENT_METHOD_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class PaymentMethodEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.paymentMethod.onEdited, - this.handleTrackPaymentMethodEditedEvent - ); - bus.subscribe( - events.paymentMethod.onDeleted, - this.handleTrackPaymentMethodDeletedEvent - ); - } - - private handleTrackPaymentMethodEditedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_METHOD_EDITED, - properties: {}, - }); - }; - - private handleTrackPaymentMethodDeletedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_METHOD_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/PaymentReceivedEventsTracker.ts b/packages/server/src/services/EventsTracker/events/PaymentReceivedEventsTracker.ts deleted file mode 100644 index 9d45c3dde..000000000 --- a/packages/server/src/services/EventsTracker/events/PaymentReceivedEventsTracker.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IPaymentReceivedCreatedPayload, - IPaymentReceivedEditedPayload, - IPaymentReceivedDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - PAYMENT_RECEIVED_CREATED, - PAYMENT_RECEIVED_EDITED, - PAYMENT_RECEIVED_DELETED, - PAYMENT_RECEIVED_PDF_VIEWED, - PAYMENT_RECEIVED_MAIL_SENT, -} from '@/constants/event-tracker'; - -@Service() -export class PaymentReceivedEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onCreated, - this.handleTrackPaymentReceivedCreatedEvent - ); - bus.subscribe( - events.paymentReceive.onEdited, - this.handleTrackEditedPaymentReceivedEvent - ); - bus.subscribe( - events.paymentReceive.onDeleted, - this.handleTrackDeletedPaymentReceivedEvent - ); - bus.subscribe( - events.paymentReceive.onPdfViewed, - this.handleTrackPdfViewedPaymentReceivedEvent - ); - bus.subscribe( - events.paymentReceive.onMailSent, - this.handleTrackMailSentPaymentReceivedEvent - ); - } - - private handleTrackPaymentReceivedCreatedEvent = ({ - tenantId, - }: IPaymentReceivedCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_RECEIVED_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedPaymentReceivedEvent = ({ - tenantId, - }: IPaymentReceivedEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_RECEIVED_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedPaymentReceivedEvent = ({ - tenantId, - }: IPaymentReceivedDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_RECEIVED_DELETED, - properties: {}, - }); - }; - - private handleTrackPdfViewedPaymentReceivedEvent = ({ - tenantId, - }: IPaymentReceivedDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_RECEIVED_PDF_VIEWED, - properties: {}, - }); - }; - - private handleTrackMailSentPaymentReceivedEvent = ({ - tenantId, - }: IPaymentReceivedDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYMENT_RECEIVED_MAIL_SENT, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/PdfTemplateEventsTracker.ts b/packages/server/src/services/EventsTracker/events/PdfTemplateEventsTracker.ts deleted file mode 100644 index 68ced58a0..000000000 --- a/packages/server/src/services/EventsTracker/events/PdfTemplateEventsTracker.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - PDF_TEMPLATE_CREATED, - PDF_TEMPLATE_EDITED, - PDF_TEMPLATE_DELETED, - PDF_TEMPLATE_ASSIGNED_DEFAULT, -} from '@/constants/event-tracker'; -import { PosthogService } from '../PostHog'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class PdfTemplateEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - public attach(bus) { - bus.subscribe( - events.pdfTemplate.onCreated, - this.handleTrackPdfTemplateCreatedEvent - ); - bus.subscribe( - events.pdfTemplate.onEdited, - this.handleTrackEditedPdfTemplateEvent - ); - bus.subscribe( - events.pdfTemplate.onDeleted, - this.handleTrackDeletedPdfTemplateEvent - ); - bus.subscribe( - events.pdfTemplate.onAssignedDefault, - this.handleTrackAssignedAsDefaultPdfTemplateEvent - ); - } - - private handleTrackPdfTemplateCreatedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PDF_TEMPLATE_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedPdfTemplateEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PDF_TEMPLATE_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedPdfTemplateEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PDF_TEMPLATE_DELETED, - properties: {}, - }); - }; - - private handleTrackAssignedAsDefaultPdfTemplateEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PDF_TEMPLATE_ASSIGNED_DEFAULT, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/ReportsEventsTracker.ts b/packages/server/src/services/EventsTracker/events/ReportsEventsTracker.ts deleted file mode 100644 index 4a3b857d1..000000000 --- a/packages/server/src/services/EventsTracker/events/ReportsEventsTracker.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { ReportsEvents } from '@/constants/event-tracker'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - BALANCE_SHEET_VIEWED, - TRIAL_BALANCE_SHEET_VIEWED, - PROFIT_LOSS_SHEET_VIEWED, - CASHFLOW_STATEMENT_VIEWED, - GENERAL_LEDGER_VIEWED, - JOURNAL_VIEWED, - RECEIVABLE_AGING_VIEWED, - PAYABLE_AGING_VIEWED, - CUSTOMER_BALANCE_SUMMARY_VIEWED, - VENDOR_BALANCE_SUMMARY_VIEWED, - INVENTORY_VALUATION_VIEWED, - CUSTOMER_TRANSACTIONS_VIEWED, - VENDOR_TRANSACTIONS_VIEWED, - SALES_BY_ITEM_VIEWED, - PURCHASES_BY_ITEM_VIEWED, -} from '@/constants/event-tracker'; - -@Service() -export class ReportsEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.reports.onBalanceSheetViewed, - this.handleTrackBalanceSheetViewedEvent - ); - bus.subscribe( - events.reports.onTrialBalanceSheetView, - this.handleTrackTrialBalanceSheetViewedEvent - ); - bus.subscribe( - events.reports.onProfitLossSheetViewed, - this.handleTrackProfitLossSheetViewedEvent - ); - bus.subscribe( - events.reports.onCashflowStatementViewed, - this.handleTrackCashflowStatementViewedEvent - ); - bus.subscribe( - events.reports.onGeneralLedgerViewed, - this.handleTrackGeneralLedgerViewedEvent - ); - bus.subscribe( - events.reports.onJournalViewed, - this.handleTrackJournalViewedEvent - ); - bus.subscribe( - events.reports.onReceivableAgingViewed, - this.handleTrackReceivableAgingViewedEvent - ); - bus.subscribe( - events.reports.onPayableAgingViewed, - this.handleTrackPayableAgingViewedEvent - ); - bus.subscribe( - events.reports.onCustomerBalanceSummaryViewed, - this.handleTrackCustomerBalanceSummaryViewedEvent - ); - bus.subscribe( - events.reports.onVendorBalanceSummaryViewed, - this.handleTrackVendorBalanceSummaryViewedEvent - ); - bus.subscribe( - events.reports.onInventoryValuationViewed, - this.handleTrackInventoryValuationViewedEvent - ); - bus.subscribe( - events.reports.onCustomerTransactionsViewed, - this.handleTrackCustomerTransactionsViewedEvent - ); - bus.subscribe( - events.reports.onVendorTransactionsViewed, - this.handleTrackVendorTransactionsViewedEvent - ); - bus.subscribe( - events.reports.onSalesByItemViewed, - this.handleTrackSalesByItemViewedEvent - ); - bus.subscribe( - events.reports.onPurchasesByItemViewed, - this.handleTrackPurchasesByItemViewedEvent - ); - } - - private handleTrackBalanceSheetViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: BALANCE_SHEET_VIEWED, - properties: {}, - }); - }; - - private handleTrackTrialBalanceSheetViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: TRIAL_BALANCE_SHEET_VIEWED, - properties: {}, - }); - }; - - private handleTrackProfitLossSheetViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PROFIT_LOSS_SHEET_VIEWED, - properties: {}, - }); - }; - - private handleTrackCashflowStatementViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: CASHFLOW_STATEMENT_VIEWED, - properties: {}, - }); - }; - - private handleTrackGeneralLedgerViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: GENERAL_LEDGER_VIEWED, - properties: {}, - }); - }; - - private handleTrackJournalViewedEvent = ({ tenantId }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: JOURNAL_VIEWED, - properties: {}, - }); - }; - - private handleTrackReceivableAgingViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: RECEIVABLE_AGING_VIEWED, - properties: {}, - }); - }; - - private handleTrackPayableAgingViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PAYABLE_AGING_VIEWED, - properties: {}, - }); - }; - - private handleTrackCustomerBalanceSummaryViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: CUSTOMER_BALANCE_SUMMARY_VIEWED, - properties: {}, - }); - }; - - private handleTrackVendorBalanceSummaryViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: VENDOR_BALANCE_SUMMARY_VIEWED, - properties: {}, - }); - }; - - private handleTrackInventoryValuationViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: INVENTORY_VALUATION_VIEWED, - properties: {}, - }); - }; - - private handleTrackCustomerTransactionsViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: CUSTOMER_TRANSACTIONS_VIEWED, - properties: {}, - }); - }; - - private handleTrackVendorTransactionsViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: VENDOR_TRANSACTIONS_VIEWED, - properties: {}, - }); - }; - - private handleTrackSalesByItemViewedEvent = ({ tenantId }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALES_BY_ITEM_VIEWED, - properties: {}, - }); - }; - - private handleTrackPurchasesByItemViewedEvent = ({ - tenantId, - }: ReportsEvents) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: PURCHASES_BY_ITEM_VIEWED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/SaleEstimateEventsTracker.ts b/packages/server/src/services/EventsTracker/events/SaleEstimateEventsTracker.ts deleted file mode 100644 index 25c97e4a3..000000000 --- a/packages/server/src/services/EventsTracker/events/SaleEstimateEventsTracker.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - ISaleEstimateCreatedPayload, - ISaleEstimateEditedPayload, - ISaleEstimateDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - SALE_ESTIMATE_CREATED, - SALE_ESTIMATE_EDITED, - SALE_ESTIMATE_DELETED, - SALE_ESTIMATE_PDF_VIEWED, - SALE_ESTIMATE_VIEWED, - SALE_ESTIMATE_MAIL_SENT, -} from '@/constants/event-tracker'; - -@Service() -export class SaleEstimateEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleEstimate.onCreated, - this.handleTrackEstimateCreatedEvent - ); - bus.subscribe( - events.saleEstimate.onEdited, - this.handleTrackEditedEstimateEvent - ); - bus.subscribe( - events.saleEstimate.onDeleted, - this.handleTrackDeletedEstimateEvent - ); - bus.subscribe( - events.saleEstimate.onPdfViewed, - this.handleTrackPdfViewedEstimateEvent - ); - bus.subscribe( - events.saleEstimate.onViewed, - this.handleTrackViewedEstimateEvent - ); - bus.subscribe( - events.saleEstimate.onMailSent, - this.handleTrackMailSentEstimateEvent - ); - } - - private handleTrackEstimateCreatedEvent = ({ - tenantId, - }: ISaleEstimateCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_ESTIMATE_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedEstimateEvent = ({ - tenantId, - }: ISaleEstimateEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_ESTIMATE_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedEstimateEvent = ({ - tenantId, - }: ISaleEstimateDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_ESTIMATE_DELETED, - properties: {}, - }); - }; - - private handleTrackPdfViewedEstimateEvent = ({ - tenantId, - }: ISaleEstimateDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_ESTIMATE_PDF_VIEWED, - properties: {}, - }); - }; - - private handleTrackViewedEstimateEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_ESTIMATE_VIEWED, - properties: {}, - }); - }; - - private handleTrackMailSentEstimateEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_ESTIMATE_MAIL_SENT, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/SaleInvoicesEventsTracker.ts b/packages/server/src/services/EventsTracker/events/SaleInvoicesEventsTracker.ts deleted file mode 100644 index ca05a2478..000000000 --- a/packages/server/src/services/EventsTracker/events/SaleInvoicesEventsTracker.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - SALE_INVOICE_CREATED, - SALE_INVOICE_DELETED, - SALE_INVOICE_EDITED, - SALE_INVOICE_MAIL_SENT, - SALE_INVOICE_PDF_VIEWED, - SALE_INVOICE_VIEWED, -} from '@/constants/event-tracker'; - -@Service() -export class SaleInvoiceEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleTrackInvoiceCreatedEvent - ); - bus.subscribe( - events.saleInvoice.onEdited, - this.handleTrackEditedInvoiceEvent - ); - bus.subscribe( - events.saleInvoice.onDeleted, - this.handleTrackDeletedInvoiceEvent - ); - bus.subscribe( - events.saleInvoice.onViewed, - this.handleTrackViewedInvoiceEvent - ); - bus.subscribe( - events.saleInvoice.onPdfViewed, - this.handleTrackPdfViewedInvoiceEvent - ); - bus.subscribe( - events.saleInvoice.onMailSent, - this.handleTrackMailSentInvoiceEvent - ); - } - - private handleTrackInvoiceCreatedEvent = ({ - tenantId, - }: ISaleInvoiceCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_INVOICE_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedInvoiceEvent = ({ - tenantId, - }: ISaleInvoiceEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_INVOICE_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedInvoiceEvent = ({ - tenantId, - }: ISaleInvoiceEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_INVOICE_DELETED, - properties: {}, - }); - }; - - private handleTrackViewedInvoiceEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_INVOICE_VIEWED, - properties: {}, - }); - }; - - private handleTrackPdfViewedInvoiceEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_INVOICE_PDF_VIEWED, - properties: {}, - }); - }; - - private handleTrackMailSentInvoiceEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SALE_INVOICE_MAIL_SENT, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/StripeIntegrationEventsTracker.ts b/packages/server/src/services/EventsTracker/events/StripeIntegrationEventsTracker.ts deleted file mode 100644 index e99e7aa4c..000000000 --- a/packages/server/src/services/EventsTracker/events/StripeIntegrationEventsTracker.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { ISaleInvoiceCreatedPayload } from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import { STRIPE_INTEGRAION_CONNECTED } from '@/constants/event-tracker'; -import events from '@/subscribers/events'; - -@Service() -export class StripeIntegrationEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.stripeIntegration.onOAuthCodeGranted, - this.handleTrackOAuthCodeGrantedTrackEvent - ); - } - - private handleTrackOAuthCodeGrantedTrackEvent = ({ - tenantId, - }: ISaleInvoiceCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: STRIPE_INTEGRAION_CONNECTED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/SubscriptionEventsTracker.ts b/packages/server/src/services/EventsTracker/events/SubscriptionEventsTracker.ts deleted file mode 100644 index 5f547efb9..000000000 --- a/packages/server/src/services/EventsTracker/events/SubscriptionEventsTracker.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { ITransactionsLockingPartialUnlocked } from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import { - TRANSACTIONS_LOCKING_LOCKED, - TRANSACTIONS_LOCKING_LOCKING_CANCELLED, - TRANSACTIONS_LOCKING_PARTIALLY_UNLOCK_CANCELLED, - TRANSACTIONS_LOCKING_PARTIALLY_UNLOCKED, -} from '@/constants/event-tracker'; -import events from '@/subscribers/events'; - -@Service() -export class TransactionsLockingEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - public attach(bus) { - bus.subscribe( - events.transactionsLocking.locked, - this.handleTransactionsLockingLockedEvent - ); - bus.subscribe( - events.transactionsLocking.lockCanceled, - this.handleTransactionsLockingCancelledEvent - ); - bus.subscribe( - events.transactionsLocking.partialUnlocked, - this.handleTransactionsLockingPartiallyUnlockedEvent - ); - bus.subscribe( - events.transactionsLocking.partialUnlockCanceled, - this.handleTransactionsLockingPartiallyUnlockCancelledEvent - ); - } - - private handleTransactionsLockingLockedEvent = ({ - tenantId, - }: ITransactionsLockingPartialUnlocked) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: TRANSACTIONS_LOCKING_LOCKED, - properties: {}, - }); - }; - - private handleTransactionsLockingCancelledEvent = ({ - tenantId, - }: ITransactionsLockingPartialUnlocked) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: TRANSACTIONS_LOCKING_LOCKING_CANCELLED, - properties: {}, - }); - }; - - private handleTransactionsLockingPartiallyUnlockedEvent = ({ - tenantId, - }: ITransactionsLockingPartialUnlocked) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: TRANSACTIONS_LOCKING_PARTIALLY_UNLOCKED, - properties: {}, - }); - }; - - private handleTransactionsLockingPartiallyUnlockCancelledEvent = ({ - tenantId, - }: ITransactionsLockingPartialUnlocked) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: TRANSACTIONS_LOCKING_PARTIALLY_UNLOCK_CANCELLED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/TransactionsLockingEventsTracker.ts b/packages/server/src/services/EventsTracker/events/TransactionsLockingEventsTracker.ts deleted file mode 100644 index 47d3069af..000000000 --- a/packages/server/src/services/EventsTracker/events/TransactionsLockingEventsTracker.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { ITransactionsLockingPartialUnlocked } from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import { - SUBSCRIPTION_CANCELLED, - SUBSCRIPTION_PAYMENT_FAILED, - SUBSCRIPTION_PAYMENT_SUCCEED, - SUBSCRIPTION_PLAN_CHANGED, - SUBSCRIPTION_RESUMED, -} from '@/constants/event-tracker'; -import events from '@/subscribers/events'; - -@Service() -export class TransactionsLockingEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - public attach(bus) { - bus.subscribe( - events.subscription.onSubscriptionResumed, - this.handleSubscriptionResumedEvent - ); - bus.subscribe( - events.subscription.onSubscriptionCancelled, - this.handleSubscriptionCancelledEvent - ); - bus.subscribe( - events.subscription.onSubscriptionPlanChanged, - this.handleSubscriptionPlanChangedEvent - ); - bus.subscribe( - events.subscription.onSubscriptionPaymentSucceed, - this.handleSubscriptionPaymentFailedEvent - ); - bus.subscribe( - events.subscription.onSubscriptionPaymentFailed, - this.handleSubscriptionPaymentSucceed - ); - } - - private handleSubscriptionResumedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SUBSCRIPTION_RESUMED, - properties: {}, - }); - }; - - private handleSubscriptionCancelledEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SUBSCRIPTION_CANCELLED, - properties: {}, - }); - }; - - private handleSubscriptionPlanChangedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SUBSCRIPTION_PLAN_CHANGED, - properties: {}, - }); - }; - - private handleSubscriptionPaymentFailedEvent = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SUBSCRIPTION_PAYMENT_FAILED, - properties: {}, - }); - }; - - private handleSubscriptionPaymentSucceed = ({ tenantId }) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: SUBSCRIPTION_PAYMENT_SUCCEED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/VendorEventsTracker.ts b/packages/server/src/services/EventsTracker/events/VendorEventsTracker.ts deleted file mode 100644 index 968589eb4..000000000 --- a/packages/server/src/services/EventsTracker/events/VendorEventsTracker.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { - IVendorEventCreatedPayload, - IVendorEventEditedPayload, - IVendorEventDeletedPayload, -} from '@/interfaces'; -import { PosthogService } from '../PostHog'; -import events from '@/subscribers/events'; -import { - VENDOR_CREATED, - VENDOR_EDITED, - VENDOR_DELETED, -} from '@/constants/event-tracker'; - -@Service() -export class VendorEventsTracker extends EventSubscriber { - @Inject() - private posthog: PosthogService; - - public attach(bus) { - bus.subscribe(events.vendors.onCreated, this.handleTrackVendorCreatedEvent); - bus.subscribe(events.vendors.onEdited, this.handleTrackEditedVendorEvent); - bus.subscribe(events.vendors.onDeleted, this.handleTrackDeletedVendorEvent); - } - - private handleTrackVendorCreatedEvent = ({ - tenantId, - }: IVendorEventCreatedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: VENDOR_CREATED, - properties: {}, - }); - }; - - private handleTrackEditedVendorEvent = ({ - tenantId, - }: IVendorEventEditedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: VENDOR_EDITED, - properties: {}, - }); - }; - - private handleTrackDeletedVendorEvent = ({ - tenantId, - }: IVendorEventDeletedPayload) => { - this.posthog.trackEvent({ - distinctId: `tenant-${tenantId}`, - event: VENDOR_DELETED, - properties: {}, - }); - }; -} diff --git a/packages/server/src/services/EventsTracker/events/events.ts b/packages/server/src/services/EventsTracker/events/events.ts deleted file mode 100644 index 9e23d18a7..000000000 --- a/packages/server/src/services/EventsTracker/events/events.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { SaleInvoiceEventsTracker } from './SaleInvoicesEventsTracker'; -import { SaleEstimateEventsTracker } from './SaleEstimateEventsTracker'; -import { PaymentMadeEventsTracker } from './PaymentMadeEventsTracker'; -import { PaymentReceivedEventsTracker } from './PaymentReceivedEventsTracker'; -import { BillEventsTracker } from './BillEventsTracker'; -import { ExpenseEventsTracker } from './ExpenseEventsTracker'; -import { AccountEventsTracker } from './AccountEventsTracker'; -import { AuthenticationEventsTracker } from './AuthenticationEventsTracker'; -import { ItemEventsTracker } from './ItemEventsTracker'; -import { BankTransactionEventsTracker } from './BankTransactionEventsTracker'; -import { CustomerEventsTracker } from './CustomerEventsTracker'; -import { VendorEventsTracker } from './VendorEventsTracker'; -import { ManualJournalEventsTracker } from './ManualJournalEventsTracker'; -import { BankRuleEventsTracker } from './BankRuleEventsTracker'; -import { PdfTemplateEventsTracker } from './PdfTemplateEventsTracker'; -import { PaymentMethodEventsTracker } from './PaymentMethodEventsTracker'; -import { PaymentLinkEventsTracker } from './PaymentLinkEventsTracker'; -import { StripeIntegrationEventsTracker } from './StripeIntegrationEventsTracker'; -import { ReportsEventsTracker } from './ReportsEventsTracker'; - -export const EventsTrackerListeners = [ - SaleInvoiceEventsTracker, - SaleEstimateEventsTracker, - PaymentMadeEventsTracker, - PaymentReceivedEventsTracker, - BillEventsTracker, - AccountEventsTracker, - ExpenseEventsTracker, - AuthenticationEventsTracker, - ItemEventsTracker, - BankTransactionEventsTracker, - CustomerEventsTracker, - VendorEventsTracker, - ManualJournalEventsTracker, - BankRuleEventsTracker, - PdfTemplateEventsTracker, - PaymentMethodEventsTracker, - PaymentLinkEventsTracker, - StripeIntegrationEventsTracker, - ReportsEventsTracker, -]; diff --git a/packages/server/src/services/ExchangeRates/ExchangeRateApplication.ts b/packages/server/src/services/ExchangeRates/ExchangeRateApplication.ts deleted file mode 100644 index 9e51c5d72..000000000 --- a/packages/server/src/services/ExchangeRates/ExchangeRateApplication.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Inject } from 'typedi'; -import { ExchangeRatesService } from './ExchangeRatesService'; -import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces'; - -export class ExchangeRateApplication { - @Inject() - private exchangeRateService: ExchangeRatesService; - - /** - * Gets the latest exchange rate. - * @param {number} tenantId - * @param {ExchangeRateLatestDTO} exchangeRateLatestDTO - * @returns {Promise} - */ - public latest( - tenantId: number, - exchangeRateLatestDTO: ExchangeRateLatestDTO - ): Promise { - return this.exchangeRateService.latest(tenantId, exchangeRateLatestDTO); - } -} diff --git a/packages/server/src/services/ExchangeRates/ExchangeRatesService.ts b/packages/server/src/services/ExchangeRates/ExchangeRatesService.ts deleted file mode 100644 index 4cde544ad..000000000 --- a/packages/server/src/services/ExchangeRates/ExchangeRatesService.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Service } from 'typedi'; -import { ExchangeRate } from '@/lib/ExchangeRate/ExchangeRate'; -import { ExchangeRateServiceType } from '@/lib/ExchangeRate/types'; -import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class ExchangeRatesService { - /** - * Gets the latest exchange rate. - * @param {number} tenantId - * @param {number} exchangeRateLatestDTO - * @returns {EchangeRateLatestPOJO} - */ - public async latest( - tenantId: number, - exchangeRateLatestDTO: ExchangeRateLatestDTO - ): Promise { - const organization = await TenantMetadata.query().findOne({ tenantId }); - - // Assign the organization base currency as a default currency - // if no currency is provided - const fromCurrency = - exchangeRateLatestDTO.fromCurrency || organization.baseCurrency; - const toCurrency = - exchangeRateLatestDTO.toCurrency || organization.baseCurrency; - - const exchange = new ExchangeRate(ExchangeRateServiceType.OpenExchangeRate); - const exchangeRate = await exchange.latest(fromCurrency, toCurrency); - - return { - baseCurrency: fromCurrency, - toCurrency: exchangeRateLatestDTO.toCurrency, - exchangeRate, - }; - } -} diff --git a/packages/server/src/services/Expenses/CRUD/CommandExpenseValidator.ts b/packages/server/src/services/Expenses/CRUD/CommandExpenseValidator.ts deleted file mode 100644 index ca3f74073..000000000 --- a/packages/server/src/services/Expenses/CRUD/CommandExpenseValidator.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { sumBy, difference } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import { ERRORS, SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES } from '../constants'; -import { - IAccount, - IExpense, - IExpenseCreateDTO, - IExpenseEditDTO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ACCOUNT_PARENT_TYPE, ACCOUNT_ROOT_TYPE } from '@/data/AccountTypes'; - -@Service() -export class CommandExpenseValidator { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates expense categories not equals zero. - * @param {IExpenseCreateDTO | IExpenseEditDTO} expenseDTO - * @throws {ServiceError} - */ - public validateCategoriesNotEqualZero = ( - expenseDTO: IExpenseCreateDTO | IExpenseEditDTO - ) => { - const totalAmount = sumBy(expenseDTO.categories, 'amount') || 0; - - if (totalAmount <= 0) { - throw new ServiceError(ERRORS.TOTAL_AMOUNT_EQUALS_ZERO); - } - }; - - /** - * Retrieve expense accounts or throw error in case one of the given accounts - * not found not the storage. - * @param {number} tenantId - * @param {number} expenseAccountsIds - * @throws {ServiceError} - * @returns {Promise} - */ - public validateExpensesAccountsExistance( - expenseAccounts: IAccount[], - DTOAccountsIds: number[] - ) { - const storedExpenseAccountsIds = expenseAccounts.map((a: IAccount) => a.id); - - const notStoredAccountsIds = difference( - DTOAccountsIds, - storedExpenseAccountsIds - ); - if (notStoredAccountsIds.length > 0) { - throw new ServiceError(ERRORS.SOME_ACCOUNTS_NOT_FOUND); - } - } - - /** - * Validate expenses accounts type. - * @param {number} tenantId - * @param {number[]} expensesAccountsIds - */ - public validateExpensesAccountsType = (expensesAccounts: IAccount[]) => { - const invalidExpenseAccounts: number[] = []; - - expensesAccounts.forEach((expenseAccount) => { - if (!expenseAccount.isRootType(ACCOUNT_ROOT_TYPE.EXPENSE)) { - invalidExpenseAccounts.push(expenseAccount.id); - } - }); - if (invalidExpenseAccounts.length > 0) { - throw new ServiceError(ERRORS.EXPENSES_ACCOUNT_HAS_INVALID_TYPE); - } - }; - - /** - * Validates payment account type in case has invalid type throws errors. - * @param {number} tenantId - * @param {number} paymentAccountId - * @throws {ServiceError} - */ - public validatePaymentAccountType = (paymentAccount: number[]) => { - if ( - !paymentAccount.isAccountType(SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES) - ) { - throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_HAS_INVALID_TYPE); - } - }; - - /** - * Validates the expense has not associated landed cost - * references to the given expense. - * @param {number} tenantId - * @param {number} expenseId - */ - public async validateNoAssociatedLandedCost( - tenantId: number, - expenseId: number - ) { - const { BillLandedCost } = this.tenancy.models(tenantId); - - const associatedLandedCosts = await BillLandedCost.query() - .where('fromTransactionType', 'Expense') - .where('fromTransactionId', expenseId); - - if (associatedLandedCosts.length > 0) { - throw new ServiceError(ERRORS.EXPENSE_HAS_ASSOCIATED_LANDED_COST); - } - } - - /** - * Validates expenses is not already published before. - * @param {IExpense} expense - */ - public validateExpenseIsNotPublished(expense: IExpense) { - if (expense.publishedAt) { - throw new ServiceError(ERRORS.EXPENSE_ALREADY_PUBLISHED); - } - } -} diff --git a/packages/server/src/services/Expenses/CRUD/CreateExpense.ts b/packages/server/src/services/Expenses/CRUD/CreateExpense.ts deleted file mode 100644 index f64eba1a2..000000000 --- a/packages/server/src/services/Expenses/CRUD/CreateExpense.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IExpense, - IExpenseCreateDTO, - ISystemUser, - IExpenseCreatedPayload, - IExpenseCreatingPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { CommandExpenseValidator } from './CommandExpenseValidator'; -import { ExpenseDTOTransformer } from './ExpenseDTOTransformer'; - -@Service() -export class CreateExpense { - @Inject() - private tenancy: HasTenancyService; - - @Inject() -private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandExpenseValidator; - - @Inject() - private transformDTO: ExpenseDTOTransformer; - - /** - * Authorize before create a new expense transaction. - * @param {number} tenantId - * @param {IExpenseDTO} expenseDTO - */ - private authorize = async ( - tenantId: number, - expenseDTO: IExpenseCreateDTO - ) => { - const { Account } = await this.tenancy.models(tenantId); - - // Validate payment account existance on the storage. - const paymentAccount = await Account.query() - .findById(expenseDTO.paymentAccountId) - .throwIfNotFound(); - - // Retrieves the DTO expense accounts ids. - const DTOExpenseAccountsIds = expenseDTO.categories.map( - (category) => category.expenseAccountId - ); - // Retrieves the expenses accounts. - const expenseAccounts = await Account.query().whereIn( - 'id', - DTOExpenseAccountsIds - ); - // Validate expense accounts exist on the storage. - this.validator.validateExpensesAccountsExistance( - expenseAccounts, - DTOExpenseAccountsIds - ); - // Validate payment account type. - this.validator.validatePaymentAccountType(paymentAccount); - - // Validate expenses accounts type. - this.validator.validateExpensesAccountsType(expenseAccounts); - - // Validate the given expense categories not equal zero. - this.validator.validateCategoriesNotEqualZero(expenseDTO); - }; - - /** - * Precedures. - * --------- - * 1. Validate payment account existance on the storage. - * 2. Validate expense accounts exist on the storage. - * 3. Validate payment account type. - * 4. Validate expenses accounts type. - * 5. Validate the expense payee contact id existance on storage. - * 6. Validate the given expense categories not equal zero. - * 7. Stores the expense to the storage. - * --------- - * @param {number} tenantId - * @param {IExpenseDTO} expenseDTO - */ - public newExpense = async ( - tenantId: number, - expenseDTO: IExpenseCreateDTO, - authorizedUser: ISystemUser, - trx?: Knex.Transaction - ): Promise => { - const { Expense } = await this.tenancy.models(tenantId); - - // Authorize before create a new expense. - await this.authorize(tenantId, expenseDTO); - - // Save the expense to the storage. - const expenseObj = await this.transformDTO.expenseCreateDTO( - tenantId, - expenseDTO, - authorizedUser - ); - // Writes the expense transaction with associated transactions under - // unit-of-work envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onExpenseCreating` event. - await this.eventPublisher.emitAsync(events.expenses.onCreating, { - trx, - tenantId, - expenseDTO, - } as IExpenseCreatingPayload); - - // Creates a new expense transaction graph. - const expense: IExpense = await Expense.query(trx).upsertGraph( - expenseObj - ); - // Triggers `onExpenseCreated` event. - await this.eventPublisher.emitAsync(events.expenses.onCreated, { - tenantId, - expenseId: expense.id, - authorizedUser, - expenseDTO, - expense, - trx, - } as IExpenseCreatedPayload); - - return expense; - }, - trx - ); - }; -} diff --git a/packages/server/src/services/Expenses/CRUD/DeleteExpense.ts b/packages/server/src/services/Expenses/CRUD/DeleteExpense.ts deleted file mode 100644 index 22e170dea..000000000 --- a/packages/server/src/services/Expenses/CRUD/DeleteExpense.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - ISystemUser, - IExpenseEventDeletePayload, - IExpenseDeletingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandExpenseValidator } from './CommandExpenseValidator'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class DeleteExpense { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandExpenseValidator; - - /** - * Deletes the given expense. - * @param {number} tenantId - * @param {number} expenseId - * @param {ISystemUser} authorizedUser - */ - public deleteExpense = async ( - tenantId: number, - expenseId: number, - authorizedUser: ISystemUser - ): Promise => { - const { Expense, ExpenseCategory } = this.tenancy.models(tenantId); - - // Retrieves the expense transaction with associated entries or - // throw not found error. - const oldExpense = await Expense.query() - .findById(expenseId) - .withGraphFetched('categories') - .throwIfNotFound(); - - // Validates the expense has no associated landed cost. - await this.validator.validateNoAssociatedLandedCost(tenantId, expenseId); - - // Deletes expense transactions with associated transactions under - // unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onExpenseDeleting` event. - await this.eventPublisher.emitAsync(events.expenses.onDeleting, { - trx, - tenantId, - oldExpense, - } as IExpenseDeletingPayload); - - // Deletes expense associated entries. - await ExpenseCategory.query(trx).where('expenseId', expenseId).delete(); - - // Deletes expense transactions. - await Expense.query(trx).findById(expenseId).delete(); - - // Triggers `onExpenseDeleted` event. - await this.eventPublisher.emitAsync(events.expenses.onDeleted, { - tenantId, - expenseId, - authorizedUser, - oldExpense, - trx, - } as IExpenseEventDeletePayload); - }); - }; -} diff --git a/packages/server/src/services/Expenses/CRUD/EditExpense.ts b/packages/server/src/services/Expenses/CRUD/EditExpense.ts deleted file mode 100644 index e3aeb06ce..000000000 --- a/packages/server/src/services/Expenses/CRUD/EditExpense.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - IExpense, - ISystemUser, - IExpenseEventEditPayload, - IExpenseEventEditingPayload, - IExpenseEditDTO, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandExpenseValidator } from './CommandExpenseValidator'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ExpenseDTOTransformer } from './ExpenseDTOTransformer'; -import EntriesService from '@/services/Entries'; - -@Service() -export class EditExpense { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandExpenseValidator; - - @Inject() - private transformDTO: ExpenseDTOTransformer; - - @Inject() - private entriesService: EntriesService; - - /** - * Authorize the DTO before editing expense transaction. - * @param {number} tenantId - * @param {number} expenseId - * @param {IExpenseEditDTO} expenseDTO - */ - public authorize = async ( - tenantId: number, - oldExpense: IExpense, - expenseDTO: IExpenseEditDTO - ) => { - const { Account } = this.tenancy.models(tenantId); - - // Validate payment account existance on the storage. - const paymentAccount = await Account.query() - .findById(expenseDTO.paymentAccountId) - .throwIfNotFound(); - - // Retrieves the DTO expense accounts ids. - const DTOExpenseAccountsIds = expenseDTO.categories.map( - (category) => category.expenseAccountId - ); - // Retrieves the expenses accounts. - const expenseAccounts = await Account.query().whereIn( - 'id', - DTOExpenseAccountsIds - ); - // Validate expense accounts exist on the storage. - this.validator.validateExpensesAccountsExistance( - expenseAccounts, - DTOExpenseAccountsIds - ); - // Validate payment account type. - await this.validator.validatePaymentAccountType(paymentAccount); - - // Validate expenses accounts type. - await this.validator.validateExpensesAccountsType(expenseAccounts); - // Validate the given expense categories not equal zero. - this.validator.validateCategoriesNotEqualZero(expenseDTO); - - // Validate expense entries that have allocated landed cost cannot be deleted. - this.entriesService.validateLandedCostEntriesNotDeleted( - oldExpense.categories, - expenseDTO.categories - ); - // Validate expense entries that have allocated cost amount should be bigger than amount. - this.entriesService.validateLocatedCostEntriesSmallerThanNewEntries( - oldExpense.categories, - expenseDTO.categories - ); - }; - - /** - * Precedures. - * --------- - * 1. Validate expense existance. - * 2. Validate payment account existance on the storage. - * 3. Validate expense accounts exist on the storage. - * 4. Validate payment account type. - * 5. Validate expenses accounts type. - * 6. Validate the given expense categories not equal zero. - * 7. Stores the expense to the storage. - * --------- - * @param {number} tenantId - * @param {number} expenseId - * @param {IExpenseDTO} expenseDTO - * @param {ISystemUser} authorizedUser - */ - public async editExpense( - tenantId: number, - expenseId: number, - expenseDTO: IExpenseEditDTO, - authorizedUser: ISystemUser - ): Promise { - const { Expense } = this.tenancy.models(tenantId); - - // Retrieves the expense model or throw not found error. - const oldExpense = await Expense.query() - .findById(expenseId) - .withGraphFetched('categories') - .throwIfNotFound(); - - // Authorize expense DTO before editing. - await this.authorize(tenantId, oldExpense, expenseDTO); - - // Update the expense on the storage. - const expenseObj = await this.transformDTO.expenseEditDTO( - tenantId, - expenseDTO - ); - // Edits expense transactions and associated transactions under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onExpenseEditing` event. - await this.eventPublisher.emitAsync(events.expenses.onEditing, { - tenantId, - oldExpense, - expenseDTO, - trx, - } as IExpenseEventEditingPayload); - - // Upsert the expense object with expense entries. - const expense: IExpense = await Expense.query(trx).upsertGraphAndFetch({ - id: expenseId, - ...expenseObj, - }); - // Triggers `onExpenseCreated` event. - await this.eventPublisher.emitAsync(events.expenses.onEdited, { - tenantId, - expenseId, - expense, - expenseDTO, - authorizedUser, - oldExpense, - trx, - } as IExpenseEventEditPayload); - - return expense; - }); - } -} diff --git a/packages/server/src/services/Expenses/CRUD/ExpenseCategoryTransformer.ts b/packages/server/src/services/Expenses/CRUD/ExpenseCategoryTransformer.ts deleted file mode 100644 index 3f8383c03..000000000 --- a/packages/server/src/services/Expenses/CRUD/ExpenseCategoryTransformer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { ExpenseCategory } from '@/models'; -import { formatNumber } from '@/utils'; - -export class ExpenseCategoryTransformer extends Transformer { - /** - * Include these attributes to expense object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['amountFormatted']; - }; - - /** - * Retrieves the formatted amount. - * @param {ExpenseCategory} category - * @returns {string} - */ - protected amountFormatted(category: ExpenseCategory) { - return formatNumber(category.amount, { - currencyCode: this.context.currencyCode, - money: false, - }); - } -} diff --git a/packages/server/src/services/Expenses/CRUD/ExpenseDTOTransformer.ts b/packages/server/src/services/Expenses/CRUD/ExpenseDTOTransformer.ts deleted file mode 100644 index bff0e1d24..000000000 --- a/packages/server/src/services/Expenses/CRUD/ExpenseDTOTransformer.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit, sumBy } from 'lodash'; -import moment from 'moment'; -import * as R from 'ramda'; -import { - IExpense, - IExpenseCreateDTO, - IExpenseDTO, - IExpenseEditDTO, - ISystemUser, -} from '@/interfaces'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { TenantMetadata } from '@/system/models'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; - -@Service() -export class ExpenseDTOTransformer { - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - /** - * Retrieve the expense landed cost amount. - * @param {IExpenseDTO} expenseDTO - * @return {number} - */ - private getExpenseLandedCostAmount = (expenseDTO: IExpenseDTO): number => { - const landedCostEntries = expenseDTO.categories.filter((entry) => { - return entry.landedCost === true; - }); - return this.getExpenseCategoriesTotal(landedCostEntries); - }; - - /** - * Retrieve the given expense categories total. - * @param {IExpenseCategory} categories - * @returns {number} - */ - private getExpenseCategoriesTotal = (categories): number => { - return sumBy(categories, 'amount'); - }; - - /** - * Mapping expense DTO to model. - * @param {IExpenseDTO} expenseDTO - * @param {ISystemUser} authorizedUser - * @return {IExpense} - */ - private expenseDTOToModel( - tenantId: number, - expenseDTO: IExpenseCreateDTO | IExpenseEditDTO, - user?: ISystemUser - ): IExpense { - const landedCostAmount = this.getExpenseLandedCostAmount(expenseDTO); - const totalAmount = this.getExpenseCategoriesTotal(expenseDTO.categories); - - const categories = R.compose( - // Associate the default index to categories lines. - assocItemEntriesDefaultIndex - )(expenseDTO.categories || []); - - const initialDTO = { - ...omit(expenseDTO, ['publish', 'attachments']), - categories, - totalAmount, - landedCostAmount, - paymentDate: moment(expenseDTO.paymentDate).toMySqlDateTime(), - ...(expenseDTO.publish - ? { - publishedAt: moment().toMySqlDateTime(), - } - : {}), - }; - return R.compose(this.branchDTOTransform.transformDTO(tenantId))( - initialDTO - ); - } - - /** - * Transformes the expense create DTO. - * @param {number} tenantId - * @param {IExpenseCreateDTO} expenseDTO - * @param {ISystemUser} user - * @returns {IExpense} - */ - public expenseCreateDTO = async ( - tenantId: number, - expenseDTO: IExpenseCreateDTO, - user?: ISystemUser - ): Promise => { - const initialDTO = this.expenseDTOToModel(tenantId, expenseDTO, user); - - // Retrieves the tenant metadata. - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - return { - ...initialDTO, - currencyCode: expenseDTO.currencyCode || tenantMetadata?.baseCurrency, - exchangeRate: expenseDTO.exchangeRate || 1, - ...(user - ? { - userId: user.id, - } - : {}), - }; - }; - - /** - * Transformes the expense edit DTO. - * @param {number} tenantId - * @param {IExpenseEditDTO} expenseDTO - * @param {ISystemUser} user - * @returns {IExpense} - */ - public expenseEditDTO = async ( - tenantId: number, - expenseDTO: IExpenseEditDTO, - user?: ISystemUser - ): Promise => { - return this.expenseDTOToModel(tenantId, expenseDTO, user); - }; -} diff --git a/packages/server/src/services/Expenses/CRUD/ExpenseTransformer.ts b/packages/server/src/services/Expenses/CRUD/ExpenseTransformer.ts deleted file mode 100644 index fa9bec75a..000000000 --- a/packages/server/src/services/Expenses/CRUD/ExpenseTransformer.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { IExpense } from '@/interfaces'; -import { ExpenseCategoryTransformer } from './ExpenseCategoryTransformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; - -export class ExpenseTransfromer extends Transformer { - /** - * Include these attributes to expense object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedLandedCostAmount', - 'formattedAllocatedCostAmount', - 'formattedDate', - 'formattedCreatedAt', - 'formattedPublishedAt', - 'categories', - 'attachments', - ]; - }; - - /** - * Retrieve formatted expense amount. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedAmount = (expense: IExpense): string => { - return formatNumber(expense.totalAmount, { - currencyCode: expense.currencyCode, - }); - }; - - /** - * Retrieve formatted expense landed cost amount. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedLandedCostAmount = (expense: IExpense): string => { - return formatNumber(expense.landedCostAmount, { - currencyCode: expense.currencyCode, - }); - }; - - /** - * Retrieve formatted allocated cost amount. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedAllocatedCostAmount = (expense: IExpense): string => { - return formatNumber(expense.allocatedCostAmount, { - currencyCode: expense.currencyCode, - }); - }; - - /** - * Retriecve fromatted date. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedDate = (expense: IExpense): string => { - return this.formatDate(expense.paymentDate); - }; - - /** - * Retrieve formatted created at date. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedCreatedAt = (expense: IExpense): string => { - return this.formatDate(expense.createdAt); - } - - /** - * Retrieves the transformed expense categories. - * @param {IExpense} expense - * @returns {} - */ - protected categories = (expense: IExpense) => { - return this.item(expense.categories, new ExpenseCategoryTransformer(), { - currencyCode: expense.currencyCode, - }); - }; - - /** - * Retrieves the sale invoice attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (expense: IExpense) => { - return this.item(expense.attachments, new AttachmentTransformer()); - }; - - /** - * Retrieve formatted published at date. - * @param {IExpense} expense - * @returns {string} - */ - protected formattedPublishedAt = (expense: IExpense): string => { - return this.formatDate(expense.publishedAt); - } -} diff --git a/packages/server/src/services/Expenses/CRUD/GetExpense.ts b/packages/server/src/services/Expenses/CRUD/GetExpense.ts deleted file mode 100644 index e8961ecca..000000000 --- a/packages/server/src/services/Expenses/CRUD/GetExpense.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { IExpense } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import { ExpenseTransfromer } from './ExpenseTransformer'; - -@Service() -export class GetExpense { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve expense details. - * @param {number} tenantId - * @param {number} expenseId - * @return {Promise} - */ - public async getExpense( - tenantId: number, - expenseId: number - ): Promise { - const { Expense } = this.tenancy.models(tenantId); - - const expense = await Expense.query() - .findById(expenseId) - .withGraphFetched('categories.expenseAccount') - .withGraphFetched('paymentAccount') - .withGraphFetched('branch') - .withGraphFetched('attachments') - .throwIfNotFound(); - - // Transformes expense model to POJO. - return this.transformer.transform( - tenantId, - expense, - new ExpenseTransfromer() - ); - } -} diff --git a/packages/server/src/services/Expenses/CRUD/GetExpenses.ts b/packages/server/src/services/Expenses/CRUD/GetExpenses.ts deleted file mode 100644 index a87b726f8..000000000 --- a/packages/server/src/services/Expenses/CRUD/GetExpenses.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { - IExpensesFilter, - IExpense, - IPaginationMeta, - IFilterMeta, -} from '@/interfaces'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ExpenseTransfromer } from './ExpenseTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetExpenses { - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve expenses paginated list. - * @param {number} tenantId - * @param {IExpensesFilter} expensesFilter - * @return {IExpense[]} - */ - public getExpensesList = async ( - tenantId: number, - filterDTO: IExpensesFilter - ): Promise<{ - expenses: IExpense[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> => { - const { Expense } = this.tenancy.models(tenantId); - - // Parses list filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - Expense, - filter - ); - // Retrieves the paginated results. - const { results, pagination } = await Expense.query() - .onBuild((builder) => { - builder.withGraphFetched('paymentAccount'); - builder.withGraphFetched('categories.expenseAccount'); - - dynamicList.buildQuery()(builder); - filterDTO?.filterQuery && filterDTO?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transformes the expenses models to POJO. - const expenses = await this.transformer.transform( - tenantId, - results, - new ExpenseTransfromer() - ); - return { - expenses, - pagination, - filterMeta: dynamicList.getResponseMeta(), - }; - }; - - /** - * Parses filter DTO of expenses list. - * @param filterDTO - - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Expenses/CRUD/PublishExpense.ts b/packages/server/src/services/Expenses/CRUD/PublishExpense.ts deleted file mode 100644 index 8962dbacd..000000000 --- a/packages/server/src/services/Expenses/CRUD/PublishExpense.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - ISystemUser, - IExpensePublishingPayload, - IExpenseEventPublishedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandExpenseValidator } from './CommandExpenseValidator'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Inject() -export class PublishExpense { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandExpenseValidator; - - /** - * Publish the given expense. - * @param {number} tenantId - * @param {number} expenseId - * @param {ISystemUser} authorizedUser - * @return {Promise} - */ - public async publishExpense( - tenantId: number, - expenseId: number, - authorizedUser: ISystemUser - ) { - const { Expense } = this.tenancy.models(tenantId); - - // Retrieves the old expense or throw not found error. - const oldExpense = await Expense.query() - .findById(expenseId) - .throwIfNotFound(); - - // Validate the expense whether is published before. - this.validator.validateExpenseIsNotPublished(oldExpense); - - // Publishes expense transactions with associated transactions - // under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Trigggers `onExpensePublishing` event. - await this.eventPublisher.emitAsync(events.expenses.onPublishing, { - trx, - oldExpense, - tenantId, - } as IExpensePublishingPayload); - - // Publish the given expense on the storage. - await Expense.query().findById(expenseId).modify('publish'); - - // Retrieve the new expense after modification. - const expense = await Expense.query() - .findById(expenseId) - .withGraphFetched('categories'); - - // Triggers `onExpensePublished` event. - await this.eventPublisher.emitAsync(events.expenses.onPublished, { - tenantId, - expenseId, - oldExpense, - expense, - authorizedUser, - trx, - } as IExpenseEventPublishedPayload); - }); - } -} diff --git a/packages/server/src/services/Expenses/ExpenseGL.ts b/packages/server/src/services/Expenses/ExpenseGL.ts deleted file mode 100644 index ba437af98..000000000 --- a/packages/server/src/services/Expenses/ExpenseGL.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as R from 'ramda'; -import { - AccountNormal, - IExpenseCategory, - ILedger, - ILedgerEntry, -} from '@/interfaces'; -import Ledger from '../Accounting/Ledger'; - -export class ExpenseGL { - private expense: any; - - /** - * Constructor method. - */ - constructor(expense: any) { - this.expense = expense; - } - - /** - * Retrieves the expense GL common entry. - * @param {IExpense} expense - * @returns {Partial} - */ - private getExpenseGLCommonEntry = (): Partial => { - return { - currencyCode: this.expense.currencyCode, - exchangeRate: this.expense.exchangeRate, - - transactionType: 'Expense', - transactionId: this.expense.id, - - date: this.expense.paymentDate, - userId: this.expense.userId, - - debit: 0, - credit: 0, - - branchId: this.expense.branchId, - }; - }; - - /** - * Retrieves the expense GL payment entry. - * @param {IExpense} expense - * @returns {ILedgerEntry} - */ - private getExpenseGLPaymentEntry = (): ILedgerEntry => { - const commonEntry = this.getExpenseGLCommonEntry(); - - return { - ...commonEntry, - credit: this.expense.localAmount, - accountId: this.expense.paymentAccountId, - accountNormal: - this.expense?.paymentAccount?.accountNormal === 'debit' - ? AccountNormal.DEBIT - : AccountNormal.CREDIT, - index: 1, - }; - }; - - /** - * Retrieves the expense GL category entry. - * @param {IExpense} expense - - * @param {IExpenseCategory} expenseCategory - - * @param {number} index - * @returns {ILedgerEntry} - */ - private getExpenseGLCategoryEntry = R.curry( - (category: IExpenseCategory, index: number): ILedgerEntry => { - const commonEntry = this.getExpenseGLCommonEntry(); - const localAmount = category.amount * this.expense.exchangeRate; - - return { - ...commonEntry, - accountId: category.expenseAccountId, - accountNormal: AccountNormal.DEBIT, - debit: localAmount, - note: category.description, - index: index + 2, - projectId: category.projectId, - }; - } - ); - - /** - * Retrieves the expense GL entries. - * @param {IExpense} expense - * @returns {ILedgerEntry[]} - */ - public getExpenseGLEntries = (): ILedgerEntry[] => { - const getCategoryEntry = this.getExpenseGLCategoryEntry(); - - const paymentEntry = this.getExpenseGLPaymentEntry(); - const categoryEntries = this.expense.categories.map(getCategoryEntry); - - return [paymentEntry, ...categoryEntries]; - }; - - /** - * Retrieves the given expense ledger. - * @param {IExpense} expense - * @returns {ILedger} - */ - public getExpenseLedger = (): ILedger => { - const entries = this.getExpenseGLEntries(); - - console.log(entries, 'entries'); - - return new Ledger(entries); - }; -} diff --git a/packages/server/src/services/Expenses/ExpenseGLEntriesService.ts b/packages/server/src/services/Expenses/ExpenseGLEntriesService.ts deleted file mode 100644 index 8502fb574..000000000 --- a/packages/server/src/services/Expenses/ExpenseGLEntriesService.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { IExpense, ILedger } from '@/interfaces'; -import { ExpenseGL } from './ExpenseGL'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export class ExpenseGLEntries { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the expense G/L of the given id. - * @param {number} tenantId - * @param {number} expenseId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public getExpenseLedgerById = async ( - tenantId: number, - expenseId: number, - trx?: Knex.Transaction - ): Promise => { - const { Expense } = await this.tenancy.models(tenantId); - - const expense = await Expense.query(trx) - .findById(expenseId) - .withGraphFetched('categories') - .withGraphFetched('paymentAccount') - .throwIfNotFound(); - - return this.getExpenseLedger(expense); - }; - - /** - * Retrieves the given expense ledger. - * @param {IExpense} expense - * @returns {ILedger} - */ - public getExpenseLedger = (expense: IExpense): ILedger => { - const expenseGL = new ExpenseGL(expense); - - return expenseGL.getExpenseLedger(); - }; -} diff --git a/packages/server/src/services/Expenses/ExpenseGLEntriesStorage.ts b/packages/server/src/services/Expenses/ExpenseGLEntriesStorage.ts deleted file mode 100644 index ac451a2e2..000000000 --- a/packages/server/src/services/Expenses/ExpenseGLEntriesStorage.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ExpenseGLEntries } from './ExpenseGLEntriesService'; - -@Service() -export class ExpenseGLEntriesStorage { - @Inject() - private expenseGLEntries: ExpenseGLEntries; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Writes the expense GL entries. - * @param {number} tenantId - * @param {number} expenseId - * @param {Knex.Transaction} trx - */ - public writeExpenseGLEntries = async ( - tenantId: number, - expenseId: number, - trx?: Knex.Transaction - ) => { - // Retrieves the given expense ledger. - const expenseLedger = await this.expenseGLEntries.getExpenseLedgerById( - tenantId, - expenseId, - trx - ); - // Commits the expense ledger entries. - await this.ledgerStorage.commit(tenantId, expenseLedger, trx); - }; - - /** - * Reverts the given expense GL entries. - * @param {number} tenantId - * @param {number} expenseId - * @param {Knex.Transaction} trx - */ - public revertExpenseGLEntries = async ( - tenantId: number, - expenseId: number, - trx?: Knex.Transaction - ) => { - await this.ledgerStorage.deleteByReference( - tenantId, - expenseId, - 'Expense', - trx - ); - }; - - /** - * Rewrites the expense GL entries. - * @param {number} tenantId - * @param {number} expenseId - * @param {Knex.Transaction} trx - */ - public rewriteExpenseGLEntries = async ( - tenantId: number, - expenseId: number, - trx?: Knex.Transaction - ) => { - // Reverts the expense GL entries. - await this.revertExpenseGLEntries(tenantId, expenseId, trx); - - // Writes the expense GL entries. - await this.writeExpenseGLEntries(tenantId, expenseId, trx); - }; -} diff --git a/packages/server/src/services/Expenses/ExpenseGLEntriesSubscriber.ts b/packages/server/src/services/Expenses/ExpenseGLEntriesSubscriber.ts deleted file mode 100644 index 4c69b7f04..000000000 --- a/packages/server/src/services/Expenses/ExpenseGLEntriesSubscriber.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - IExpenseCreatedPayload, - IExpenseEventDeletePayload, - IExpenseEventEditPayload, - IExpenseEventPublishedPayload, -} from '@/interfaces'; -import { ExpenseGLEntriesStorage } from './ExpenseGLEntriesStorage'; - -@Service() -export class ExpensesWriteGLSubscriber { - @Inject() - private tenancy: TenancyService; - - @Inject() - private expenseGLEntries: ExpenseGLEntriesStorage; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.expenses.onCreated, - this.handleWriteGLEntriesOnceCreated - ); - bus.subscribe( - events.expenses.onEdited, - this.handleRewriteGLEntriesOnceEdited - ); - bus.subscribe( - events.expenses.onDeleted, - this.handleRevertGLEntriesOnceDeleted - ); - bus.subscribe( - events.expenses.onPublished, - this.handleWriteGLEntriesOncePublished - ); - } - - /** - * Handles the writing journal entries once the expense created. - * @param {IExpenseCreatedPayload} payload - - */ - public handleWriteGLEntriesOnceCreated = async ({ - expense, - tenantId, - trx, - }: IExpenseCreatedPayload) => { - // In case expense published, write journal entries. - if (!expense.publishedAt) return; - - await this.expenseGLEntries.writeExpenseGLEntries( - tenantId, - expense.id, - trx - ); - }; - - /** - * Handle writing expense journal entries once the expense edited. - * @param {IExpenseEventEditPayload} payload - - */ - public handleRewriteGLEntriesOnceEdited = async ({ - expenseId, - tenantId, - expense, - authorizedUser, - trx, - }: IExpenseEventEditPayload) => { - // Cannot continue if the expense is not published. - if (!expense.publishedAt) return; - - await this.expenseGLEntries.rewriteExpenseGLEntries( - tenantId, - expense.id, - trx - ); - }; - - /** - * Reverts expense journal entries once the expense deleted. - * @param {IExpenseEventDeletePayload} payload - - */ - public handleRevertGLEntriesOnceDeleted = async ({ - expenseId, - tenantId, - trx, - }: IExpenseEventDeletePayload) => { - await this.expenseGLEntries.revertExpenseGLEntries( - tenantId, - expenseId, - trx - ); - }; - - /** - * Handles writing expense journal once the expense publish. - * @param {IExpenseEventPublishedPayload} payload - - */ - public handleWriteGLEntriesOncePublished = async ({ - tenantId, - expense, - trx, - }: IExpenseEventPublishedPayload) => { - // In case expense published, write journal entries. - if (!expense.publishedAt) return; - - await this.expenseGLEntries.rewriteExpenseGLEntries( - tenantId, - expense.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Expenses/ExpensesApplication.ts b/packages/server/src/services/Expenses/ExpensesApplication.ts deleted file mode 100644 index fbd502f90..000000000 --- a/packages/server/src/services/Expenses/ExpensesApplication.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { - IExpense, - IExpenseCreateDTO, - IExpenseEditDTO, - IExpensesFilter, - ISystemUser, -} from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import { CreateExpense } from './CRUD/CreateExpense'; -import { DeleteExpense } from './CRUD/DeleteExpense'; -import { EditExpense } from './CRUD/EditExpense'; -import { GetExpense } from './CRUD/GetExpense'; -import { GetExpenses } from './CRUD/GetExpenses'; -import { PublishExpense } from './CRUD/PublishExpense'; - -@Service() -export class ExpensesApplication { - @Inject() - private createExpenseService: CreateExpense; - - @Inject() - private editExpenseService: EditExpense; - - @Inject() - private deleteExpenseService: DeleteExpense; - - @Inject() - private publishExpenseService: PublishExpense; - - @Inject() - private getExpenseService: GetExpense; - - @Inject() - private getExpensesService: GetExpenses; - - /** - * Create a new expense transaction. - * @param {number} tenantId - * @param {IExpenseDTO} expenseDTO - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public createExpense = ( - tenantId: number, - expenseDTO: IExpenseCreateDTO, - authorizedUser: ISystemUser - ): Promise => { - return this.createExpenseService.newExpense( - tenantId, - expenseDTO, - authorizedUser - ); - }; - - /** - * Edits the given expense transaction. - * @param {number} tenantId - * @param {number} expenseId - * @param {IExpenseDTO} expenseDTO - * @param {ISystemUser} authorizedUser - */ - public editExpense = ( - tenantId: number, - expenseId: number, - expenseDTO: IExpenseEditDTO, - authorizedUser: ISystemUser - ) => { - return this.editExpenseService.editExpense( - tenantId, - expenseId, - expenseDTO, - authorizedUser - ); - }; - - /** - * Deletes the given expense. - * @param {number} tenantId - * @param {number} expenseId - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public deleteExpense = ( - tenantId: number, - expenseId: number, - authorizedUser: ISystemUser - ) => { - return this.deleteExpenseService.deleteExpense( - tenantId, - expenseId, - authorizedUser - ); - }; - - /** - * Publishes the given expense. - * @param {number} tenantId - * @param {number} expenseId - * @param {ISystemUser} authorizedUser - * @return {Promise} - */ - public publishExpense = ( - tenantId: number, - expenseId: number, - authorizedUser: ISystemUser - ) => { - return this.publishExpenseService.publishExpense( - tenantId, - expenseId, - authorizedUser - ); - }; - - /** - * Retrieve the given expense details. - * @param {number} tenantId - * @param {number} expenseId - * @return {Promise} - */ - public getExpense = (tenantId: number, expenseId: number) => { - return this.getExpenseService.getExpense(tenantId, expenseId); - }; - - /** - * Retrieve expenses paginated list. - * @param {number} tenantId - * @param {IExpensesFilter} expensesFilter - */ - public getExpenses = (tenantId: number, filterDTO: IExpensesFilter) => { - return this.getExpensesService.getExpensesList(tenantId, filterDTO); - }; -} diff --git a/packages/server/src/services/Expenses/ExpensesExportable.ts b/packages/server/src/services/Expenses/ExpensesExportable.ts deleted file mode 100644 index b5d6802ff..000000000 --- a/packages/server/src/services/Expenses/ExpensesExportable.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Exportable } from '../Export/Exportable'; -import { IExpensesFilter } from '@/interfaces'; -import { ExpensesApplication } from './ExpensesApplication'; -import { EXPORT_SIZE_LIMIT } from '../Export/constants'; - -@Service() -export class ExpensesExportable extends Exportable { - @Inject() - private expensesApplication: ExpensesApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IExpensesFilter) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery, - } as IExpensesFilter; - - return this.expensesApplication - .getExpenses(tenantId, parsedQuery) - .then((output) => output.expenses); - } -} diff --git a/packages/server/src/services/Expenses/ExpensesImportable.ts b/packages/server/src/services/Expenses/ExpensesImportable.ts deleted file mode 100644 index 28aee2c84..000000000 --- a/packages/server/src/services/Expenses/ExpensesImportable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IExpenseCreateDTO } from '@/interfaces'; -import { Importable } from '../Import/Importable'; -import { CreateExpense } from './CRUD/CreateExpense'; -import { ExpensesSampleData } from './constants'; - -@Service() -export class ExpensesImportable extends Importable { - @Inject() - private createExpenseService: CreateExpense; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: IExpenseCreateDTO, - trx?: Knex.Transaction - ) { - return this.createExpenseService.newExpense( - tenantId, - createAccountDTO, - {}, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return ExpensesSampleData; - } -} diff --git a/packages/server/src/services/Expenses/constants.ts b/packages/server/src/services/Expenses/constants.ts deleted file mode 100644 index 4067b7fd4..000000000 --- a/packages/server/src/services/Expenses/constants.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'Draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Published', - slug: 'published', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'published', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const ERRORS = { - EXPENSE_NOT_FOUND: 'expense_not_found', - EXPENSES_NOT_FOUND: 'EXPENSES_NOT_FOUND', - PAYMENT_ACCOUNT_NOT_FOUND: 'payment_account_not_found', - SOME_ACCOUNTS_NOT_FOUND: 'some_expenses_not_found', - TOTAL_AMOUNT_EQUALS_ZERO: 'total_amount_equals_zero', - PAYMENT_ACCOUNT_HAS_INVALID_TYPE: 'payment_account_has_invalid_type', - EXPENSES_ACCOUNT_HAS_INVALID_TYPE: 'expenses_account_has_invalid_type', - EXPENSE_ALREADY_PUBLISHED: 'expense_already_published', - EXPENSE_HAS_ASSOCIATED_LANDED_COST: 'EXPENSE_HAS_ASSOCIATED_LANDED_COST', -}; - -export const ExpensesSampleData = [ - { - 'Payment Date': '2024-03-01', - 'Reference No.': 'REF-1', - 'Payment Account': 'Petty Cash', - Description: 'Vel et dolorem architecto veniam.', - 'Currency Code': '', - 'Exchange Rate': '', - 'Expense Account': 'Utilities Expense', - Amount: 9000, - 'Line Description': 'Voluptates voluptas corporis vel.', - Publish: 'T', - }, - { - 'Payment Date': '2024-03-02', - 'Reference No.': 'REF-2', - 'Payment Account': 'Petty Cash', - Description: 'Id est molestias.', - 'Currency Code': '', - 'Exchange Rate': '', - 'Expense Account': 'Utilities Expense', - Amount: 9000, - 'Line Description': 'Eos voluptatem cumque et voluptate reiciendis.', - Publish: 'T', - }, - { - 'Payment Date': '2024-03-03', - 'Reference No.': 'REF-3', - 'Payment Account': 'Petty Cash', - Description: 'Quam cupiditate at nihil dicta dignissimos non fugit illo.', - 'Currency Code': '', - 'Exchange Rate': '', - 'Expense Account': 'Utilities Expense', - Amount: 9000, - 'Line Description': - 'Hic alias rerum sed commodi dolores sint animi perferendis.', - Publish: 'T', - }, -]; - -export const SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES = [ - ACCOUNT_TYPE.CASH, - ACCOUNT_TYPE.BANK, - ACCOUNT_TYPE.CREDIT_CARD, - ACCOUNT_TYPE.OTHER_CURRENT_ASSET, - ACCOUNT_TYPE.NON_CURRENT_ASSET, - ACCOUNT_TYPE.FIXED_ASSET, -]; diff --git a/packages/server/src/services/Export/ExportAls.ts b/packages/server/src/services/Export/ExportAls.ts deleted file mode 100644 index b24227009..000000000 --- a/packages/server/src/services/Export/ExportAls.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Service } from 'typedi'; -import { AsyncLocalStorage } from 'async_hooks'; - -@Service() -export class ExportAls { - private als: AsyncLocalStorage>; - - constructor() { - this.als = new AsyncLocalStorage(); - } - - /** - * Runs a callback function within the context of a new AsyncLocalStorage store. - * @param callback The function to be executed within the AsyncLocalStorage context. - * @returns The result of the callback function. - */ - public run(callback: () => T): T { - return this.als.run(new Map(), () => { - this.markAsExport(); - - return callback(); - }); - } - - /** - * Retrieves the current AsyncLocalStorage store. - * @returns The current store or undefined if not in a valid context. - */ - public getStore(): Map | undefined { - return this.als.getStore(); - } - - /** - * Marks the current context as an export operation. - * @param flag Boolean flag to set or unset the export status. Defaults to true. - */ - public markAsExport(flag: boolean = true): void { - const store = this.getStore(); - store?.set('isExport', flag); - } - /** - * Checks if the current context is an export operation. - * @returns {boolean} True if the context is an export operation, false otherwise. - */ - public get isExport(): boolean { - return !!this.getStore()?.get('isExport'); - } -} diff --git a/packages/server/src/services/Export/ExportApplication.ts b/packages/server/src/services/Export/ExportApplication.ts deleted file mode 100644 index 490c788d2..000000000 --- a/packages/server/src/services/Export/ExportApplication.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ExportResourceService } from './ExportService'; -import { ExportFormat } from './common'; - -@Service() -export class ExportApplication { - @Inject() - private exportResource: ExportResourceService; - - /** - * Exports the given resource to csv, xlsx or pdf format. - * @param {string} reosurce - * @param {ExportFormat} format - */ - public export(tenantId: number, resource: string, format: ExportFormat) { - return this.exportResource.export(tenantId, resource, format); - } -} diff --git a/packages/server/src/services/Export/ExportPdf.ts b/packages/server/src/services/Export/ExportPdf.ts deleted file mode 100644 index f6d2e1f27..000000000 --- a/packages/server/src/services/Export/ExportPdf.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy'; -import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable'; -import { mapPdfRows } from './utils'; - -@Service() -export class ExportPdf { - @Inject() - private templateInjectable: TemplateInjectable; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - /** - * Generates the pdf table sheet for the given data and columns. - * @param {number} tenantId - * @param {} columns - * @param {Record} data - * @param {string} sheetTitle - * @param {string} sheetDescription - * @returns - */ - public async pdf( - tenantId: number, - columns: { accessor: string }, - data: Record, - sheetTitle: string = '', - sheetDescription: string = '' - ) { - const rows = mapPdfRows(columns, data); - - const htmlContent = await this.templateInjectable.render( - tenantId, - 'modules/export-resource-table', - { - table: { rows, columns }, - sheetTitle, - sheetDescription, - } - ); - // Convert the HTML content to PDF - return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, { - margins: { top: 0.2, bottom: 0.2, left: 0.2, right: 0.2 }, - landscape: true, - }); - } -} diff --git a/packages/server/src/services/Export/ExportRegistery.ts b/packages/server/src/services/Export/ExportRegistery.ts deleted file mode 100644 index 33271f4ec..000000000 --- a/packages/server/src/services/Export/ExportRegistery.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { camelCase, upperFirst } from 'lodash'; -import { Exportable } from './Exportable'; - -export class ExportableRegistry { - private static instance: ExportableRegistry; - private exportables: Record; - - /** - * Constructor method. - */ - constructor() { - this.exportables = {}; - } - - /** - * Gets singleton instance of registry. - * @returns {ExportableRegistry} - */ - public static getInstance(): ExportableRegistry { - if (!ExportableRegistry.instance) { - ExportableRegistry.instance = new ExportableRegistry(); - } - return ExportableRegistry.instance; - } - - /** - * Registers the given importable service. - * @param {string} resource - * @param {Exportable} importable - */ - public registerExportable(resource: string, importable: Exportable): void { - const _resource = this.sanitizeResourceName(resource); - this.exportables[_resource] = importable; - } - - /** - * Retrieves the importable service instance of the given resource name. - * @param {string} name - * @returns {Exportable} - */ - public getExportable(name: string): Exportable { - const _name = this.sanitizeResourceName(name); - return this.exportables[_name]; - } - - private sanitizeResourceName(resource: string) { - return upperFirst(camelCase(resource)); - } -} diff --git a/packages/server/src/services/Export/ExportResources.ts b/packages/server/src/services/Export/ExportResources.ts deleted file mode 100644 index fd3fce276..000000000 --- a/packages/server/src/services/Export/ExportResources.ts +++ /dev/null @@ -1,74 +0,0 @@ -import Container, { Service } from 'typedi'; -import { AccountsExportable } from '../Accounts/AccountsExportable'; -import { ExportableRegistry } from './ExportRegistery'; -import { ItemsExportable } from '../Items/ItemsExportable'; -import { CustomersExportable } from '../Contacts/Customers/CustomersExportable'; -import { VendorsExportable } from '../Contacts/Vendors/VendorsExportable'; -import { ExpensesExportable } from '../Expenses/ExpensesExportable'; -import { SaleInvoicesExportable } from '../Sales/Invoices/SaleInvoicesExportable'; -import { SaleEstimatesExportable } from '../Sales/Estimates/SaleEstimatesExportable'; -import { SaleReceiptsExportable } from '../Sales/Receipts/SaleReceiptsExportable'; -import { BillsExportable } from '../Purchases/Bills/BillsExportable'; -import { PaymentsReceivedExportable } from '../Sales/PaymentReceived/PaymentsReceivedExportable'; -import { BillPaymentExportable } from '../Purchases/BillPayments/BillPaymentExportable'; -import { ManualJournalsExportable } from '../ManualJournals/ManualJournalExportable'; -import { CreditNotesExportable } from '../CreditNotes/CreditNotesExportable'; -import { VendorCreditsExportable } from '../Purchases/VendorCredits/VendorCreditsExportable'; -import { ItemCategoriesExportable } from '../ItemCategories/ItemCategoriesExportable'; -import { TaxRatesExportable } from '../TaxRates/TaxRatesExportable'; - -@Service() -export class ExportableResources { - private static registry: ExportableRegistry; - - /** - * Consttuctor method. - */ - constructor() { - this.boot(); - } - - /** - * Importable instances. - */ - private importables = [ - { resource: 'Account', exportable: AccountsExportable }, - { resource: 'Item', exportable: ItemsExportable }, - { resource: 'ItemCategory', exportable: ItemCategoriesExportable }, - { resource: 'Customer', exportable: CustomersExportable }, - { resource: 'Vendor', exportable: VendorsExportable }, - { resource: 'Expense', exportable: ExpensesExportable }, - { resource: 'SaleInvoice', exportable: SaleInvoicesExportable }, - { resource: 'SaleEstimate', exportable: SaleEstimatesExportable }, - { resource: 'SaleReceipt', exportable: SaleReceiptsExportable }, - { resource: 'Bill', exportable: BillsExportable }, - { resource: 'PaymentReceive', exportable: PaymentsReceivedExportable }, - { resource: 'BillPayment', exportable: BillPaymentExportable }, - { resource: 'ManualJournal', exportable: ManualJournalsExportable }, - { resource: 'CreditNote', exportable: CreditNotesExportable }, - { resource: 'VendorCredit', exportable: VendorCreditsExportable }, - { resource: 'TaxRate', exportable: TaxRatesExportable }, - ]; - - /** - * - */ - public get registry() { - return ExportableResources.registry; - } - - /** - * Boots all the registered importables. - */ - public boot() { - if (!ExportableResources.registry) { - const instance = ExportableRegistry.getInstance(); - - this.importables.forEach((importable) => { - const importableInstance = Container.get(importable.exportable); - instance.registerExportable(importable.resource, importableInstance); - }); - ExportableResources.registry = instance; - } - } -} diff --git a/packages/server/src/services/Export/ExportService.ts b/packages/server/src/services/Export/ExportService.ts deleted file mode 100644 index f3de3ffa5..000000000 --- a/packages/server/src/services/Export/ExportService.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { Inject, Service } from 'typedi'; -import xlsx from 'xlsx'; -import * as R from 'ramda'; -import { get } from 'lodash'; -import { sanitizeResourceName } from '../Import/_utils'; -import ResourceService from '../Resource/ResourceService'; -import { ExportableResources } from './ExportResources'; -import { ServiceError } from '@/exceptions'; -import { Errors, ExportFormat } from './common'; -import { IModelMeta, IModelMetaColumn } from '@/interfaces'; -import { flatDataCollections, getDataAccessor } from './utils'; -import { ExportPdf } from './ExportPdf'; -import { ExportAls } from './ExportAls'; - -@Service() -export class ExportResourceService { - @Inject() - private resourceService: ResourceService; - - @Inject() - private exportableResources: ExportableResources; - - @Inject() - private exportPdf: ExportPdf; - - @Inject() - private exportAls: ExportAls; - - /** - * - * @param {number} tenantId - * @param {string} resourceName - * @param {ExportFormat} format - * @returns - */ - public async export( - tenantId: number, - resourceName: string, - format: ExportFormat = ExportFormat.Csv - ) { - return this.exportAls.run(() => - this.exportAlsRun(tenantId, resourceName, format) - ); - } - - /** - * Exports the given resource data through csv, xlsx or pdf. - * @param {number} tenantId - Tenant id. - * @param {string} resourceName - Resource name. - * @param {ExportFormat} format - File format. - */ - public async exportAlsRun( - tenantId: number, - resourceName: string, - format: ExportFormat = ExportFormat.Csv - ) { - const resource = sanitizeResourceName(resourceName); - const resourceMeta = this.getResourceMeta(tenantId, resource); - const resourceColumns = this.resourceService.getResourceColumns( - tenantId, - resource - ); - this.validateResourceMeta(resourceMeta); - - const data = await this.getExportableData(tenantId, resource); - const transformed = this.transformExportedData(tenantId, resource, data); - - // Returns the csv, xlsx format. - if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) { - const exportableColumns = this.getExportableColumns(resourceColumns); - const workbook = this.createWorkbook(transformed, exportableColumns); - - return this.exportWorkbook(workbook, format); - // Returns the pdf format. - } else if (format === ExportFormat.Pdf) { - const printableColumns = this.getPrintableColumns(resourceMeta); - - return this.exportPdf.pdf( - tenantId, - printableColumns, - transformed, - resourceMeta?.print?.pageTitle - ); - } - } - - /** - * Retrieves metadata for a specific resource. - * @param {number} tenantId - The tenant identifier. - * @param {string} resource - The name of the resource. - * @returns The metadata of the resource. - */ - private getResourceMeta(tenantId: number, resource: string) { - return this.resourceService.getResourceMeta(tenantId, resource); - } - - /** - * Validates if the resource metadata is exportable. - * @param {any} resourceMeta - The metadata of the resource. - * @throws {ServiceError} If the resource is not exportable or lacks columns. - */ - private validateResourceMeta(resourceMeta: any) { - if (!resourceMeta.exportable || !resourceMeta.columns) { - throw new ServiceError(Errors.RESOURCE_NOT_EXPORTABLE); - } - } - - /** - * Transforms the exported data based on the resource metadata. - * If the resource metadata specifies a flattening attribute (`exportFlattenOn`), - * the data will be flattened based on this attribute using the `flatDataCollections` utility function. - * - * @param {number} tenantId - The tenant identifier. - * @param {string} resource - The name of the resource. - * @param {Array>} data - The original data to be transformed. - * @returns {Array>} - The transformed data. - */ - private transformExportedData( - tenantId: number, - resource: string, - data: Array> - ): Array> { - const resourceMeta = this.getResourceMeta(tenantId, resource); - - return R.when>, Array>>( - R.always(Boolean(resourceMeta.exportFlattenOn)), - (data) => flatDataCollections(data, resourceMeta.exportFlattenOn), - data - ); - } - /** - * Fetches exportable data for a given resource. - * @param {number} tenantId - The tenant identifier. - * @param {string} resource - The name of the resource. - * @returns A promise that resolves to the exportable data. - */ - private async getExportableData(tenantId: number, resource: string) { - const exportable = - this.exportableResources.registry.getExportable(resource); - - return exportable.exportable(tenantId, {}); - } - - /** - * Extracts columns that are marked as exportable from the resource metadata. - * @param {IModelMeta} resourceMeta - The metadata of the resource. - * @returns An array of exportable columns. - */ - private getExportableColumns(resourceColumns: any) { - const processColumns = ( - columns: { [key: string]: IModelMetaColumn }, - parent = '' - ) => { - return Object.entries(columns) - .filter(([_, value]) => value.exportable !== false) - .flatMap(([key, value]) => { - if (value.type === 'collection' && value.collectionOf === 'object') { - return processColumns(value.columns, key); - } else { - const group = parent; - return [ - { - name: value.name, - type: value.type || 'text', - accessor: value.accessor || key, - group, - }, - ]; - } - }); - }; - return processColumns(resourceColumns); - } - - private getPrintableColumns(resourceMeta: IModelMeta) { - const processColumns = ( - columns: { [key: string]: IModelMetaColumn }, - parent = '' - ) => { - return Object.entries(columns) - .filter(([_, value]) => value.printable !== false) - .flatMap(([key, value]) => { - if (value.type === 'collection' && value.collectionOf === 'object') { - return processColumns(value.columns, key); - } else { - const group = parent; - return [ - { - name: value.name, - type: value.type || 'text', - accessor: value.accessor || key, - group, - }, - ]; - } - }); - }; - return processColumns(resourceMeta.columns); - } - - /** - * Creates a workbook from the provided data and columns. - * @param {any[]} data - The data to be included in the workbook. - * @param {any[]} exportableColumns - The columns to be included in the workbook. - * @returns The created workbook. - */ - private createWorkbook(data: any[], exportableColumns: any[]) { - const workbook = xlsx.utils.book_new(); - const worksheetData = data.map((item) => - exportableColumns.map((col) => get(item, getDataAccessor(col))) - ); - worksheetData.unshift(exportableColumns.map((col) => col.name)); - - const worksheet = xlsx.utils.aoa_to_sheet(worksheetData); - xlsx.utils.book_append_sheet(workbook, worksheet, 'Exported Data'); - - return workbook; - } - - /** - * Exports the workbook in the specified format. - * @param {any} workbook - The workbook to be exported. - * @param {string} format - The format to export the workbook in. - * @returns The exported workbook data. - */ - private exportWorkbook(workbook: any, format: string) { - if (format.toLowerCase() === 'csv') { - return xlsx.write(workbook, { type: 'buffer', bookType: 'csv' }); - } else if (format.toLowerCase() === 'xlsx') { - return xlsx.write(workbook, { type: 'buffer', bookType: 'xlsx' }); - } - } -} diff --git a/packages/server/src/services/Export/Exportable.ts b/packages/server/src/services/Export/Exportable.ts deleted file mode 100644 index 0e8801678..000000000 --- a/packages/server/src/services/Export/Exportable.ts +++ /dev/null @@ -1,22 +0,0 @@ -export class Exportable { - /** - * - * @param tenantId - * @returns - */ - public async exportable( - tenantId: number, - query: Record - ): Promise>> { - return []; - } - - /** - * - * @param data - * @returns - */ - public transform(data: Record) { - return data; - } -} diff --git a/packages/server/src/services/Export/common.ts b/packages/server/src/services/Export/common.ts deleted file mode 100644 index 71f6ef281..000000000 --- a/packages/server/src/services/Export/common.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum Errors { - RESOURCE_NOT_EXPORTABLE = 'RESOURCE_NOT_EXPORTABLE', -} - -export enum ExportFormat { - Csv = 'csv', - Pdf = 'pdf', - Xlsx = 'xlsx', -} diff --git a/packages/server/src/services/Export/constants.ts b/packages/server/src/services/Export/constants.ts deleted file mode 100644 index b7723d38c..000000000 --- a/packages/server/src/services/Export/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const EXPORT_SIZE_LIMIT = 9999999; -export const EXPORT_DTE_FORMAT = 'YYYY-MM-DD'; diff --git a/packages/server/src/services/Export/utils.ts b/packages/server/src/services/Export/utils.ts deleted file mode 100644 index f21515c46..000000000 --- a/packages/server/src/services/Export/utils.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { flatMap, get } from 'lodash'; -/** - * Flattens the data based on a specified attribute. - * @param data - The data to be flattened. - * @param flattenAttr - The attribute to be flattened. - * @returns - The flattened data. - */ -export const flatDataCollections = ( - data: Record, - flattenAttr: string -): Record[] => { - return flatMap(data, (item) => - item[flattenAttr].map((entry) => ({ - ...item, - [flattenAttr]: entry, - })) - ); -}; - -/** - * Gets the data accessor for a given column. - * @param col - The column to get the data accessor for. - * @returns - The data accessor. - */ -export const getDataAccessor = (col: any) => { - return col.group ? `${col.group}.${col.accessor}` : col.accessor; -}; - -/** - * Maps the data retrieved from the service layer to the pdf document. - * @param {any} columns - * @param {Record} data - * @returns - */ -export const mapPdfRows = (columns: any, data: Record) => { - return data.map((item) => { - const cells = columns.map((column) => { - return { - key: column.accessor, - value: get(item, getDataAccessor(column)), - }; - }); - return { cells, classNames: '' }; - }); -}; diff --git a/packages/server/src/services/Features/FeaturesConfigureManager.ts b/packages/server/src/services/Features/FeaturesConfigureManager.ts deleted file mode 100644 index f19c733a3..000000000 --- a/packages/server/src/services/Features/FeaturesConfigureManager.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { get } from 'lodash'; -import { Service } from 'typedi'; -import { FeaturesConfigure } from './constants'; - -@Service() -export class FeaturesConfigureManager { - /** - * - * @param featureName - * @returns - */ - getFeatureConfigure = (featureName: string, accessor?: string) => { - const meta = FeaturesConfigure.find( - (feature) => feature.name === featureName - ); - return accessor ? get(meta, accessor) : meta; - }; -} diff --git a/packages/server/src/services/Features/FeaturesManager.ts b/packages/server/src/services/Features/FeaturesManager.ts deleted file mode 100644 index e355d1944..000000000 --- a/packages/server/src/services/Features/FeaturesManager.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { FeaturesSettingsDriver } from './FeaturesSettingsDriver'; -import { IFeatureAllItem } from '@/interfaces'; - -@Service() -export class FeaturesManager { - @Inject() - private drive: FeaturesSettingsDriver; - - /** - * Turns-on the given feature name. - * @param {number} tenantId - * @param {string} feature - * @returns {Promise} - */ - public turnOn(tenantId: number, feature: string) { - return this.drive.turnOn(tenantId, feature); - } - - /** - * Turns-off the given feature name. - * @param {number} tenantId - * @param {string} feature - * @returns {Promise} - */ - public turnOff(tenantId: number, feature: string) { - return this.drive.turnOff(tenantId, feature); - } - - /** - * Detarmines the given feature name is accessible. - * @param {number} tenantId - * @param {string} feature - * @returns {Promise} - */ - public async accessible(tenantId: number, feature: string) { - return this.drive.accessible(tenantId, feature); - } - - /** - * Retrieves the all features and their accessible value and default value. - * @param {number} tenantId - * @returns {Promise} - */ - public async all(tenantId: number): Promise { - return this.drive.all(tenantId); - } -} diff --git a/packages/server/src/services/Features/FeaturesSettingsDriver.ts b/packages/server/src/services/Features/FeaturesSettingsDriver.ts deleted file mode 100644 index cf4900d05..000000000 --- a/packages/server/src/services/Features/FeaturesSettingsDriver.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { FeaturesConfigure } from './constants'; -import { IFeatureAllItem } from '@/interfaces'; -import { FeaturesConfigureManager } from './FeaturesConfigureManager'; - -@Service() -export class FeaturesSettingsDriver { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private configure: FeaturesConfigureManager; - - /** - * Turns-on the given feature name. - * @param {number} tenantId - * @param {string} feature - * @returns {Promise} - */ - async turnOn(tenantId: number, feature: string) { - const settings = this.tenancy.settings(tenantId); - - settings.set({ group: 'features', key: feature, value: true }); - } - - /** - * Turns-off the given feature name. - * @param {number} tenantId - * @param {string} feature - * @returns {Promise} - */ - async turnOff(tenantId: number, feature: string) { - const settings = this.tenancy.settings(tenantId); - - settings.set({ group: 'features', key: feature, value: false }); - } - - /** - * Detarmines the given feature name is accessible. - * @param {number} tenantId - * @param {string} feature - * @returns {Promise} - */ - async accessible(tenantId: number, feature: string) { - const settings = this.tenancy.settings(tenantId); - - const defaultValue = this.configure.getFeatureConfigure( - feature, - 'defaultValue' - ); - const settingValue = settings.get( - { group: 'features', key: feature }, - defaultValue - ); - return settingValue; - } - - /** - * Retrieves the all features and their accessible value and default value. - * @param {number} tenantId - * @returns {Promise} - */ - async all(tenantId: number): Promise { - const mappedOpers = FeaturesConfigure.map(async (featureConfigure) => { - const { name, defaultValue } = featureConfigure; - const isAccessible = await this.accessible( - tenantId, - featureConfigure.name - ); - return { name, isAccessible, defaultAccessible: defaultValue }; - }); - return Promise.all(mappedOpers); - } -} diff --git a/packages/server/src/services/Features/constants.ts b/packages/server/src/services/Features/constants.ts deleted file mode 100644 index 2d8fb76e3..000000000 --- a/packages/server/src/services/Features/constants.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Features, IFeatureConfiugration } from '@/interfaces'; -import config from '@/config'; -import { defaultTo } from 'lodash'; - -export const FeaturesConfigure: IFeatureConfiugration[] = [ - { - name: Features.BRANCHES, - defaultValue: false, - }, - { - name: Features.WAREHOUSES, - defaultValue: false, - }, - { - name: Features.BankSyncing, - defaultValue: defaultTo(config.bankSync.enabled, false), - } -]; diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts deleted file mode 100644 index 52e6db251..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { APAgingSummaryExportInjectable } from './APAgingSummaryExportInjectable'; -import { APAgingSummaryTableInjectable } from './APAgingSummaryTableInjectable'; -import { IAPAgingSummaryQuery } from '@/interfaces'; -import { APAgingSummaryService } from './APAgingSummaryService'; -import { APAgingSummaryPdfInjectable } from './APAgingSummaryPdfInjectable'; - -@Service() -export class APAgingSummaryApplication { - @Inject() - private APAgingSummaryTable: APAgingSummaryTableInjectable; - - @Inject() - private APAgingSummaryExport: APAgingSummaryExportInjectable; - - @Inject() - private APAgingSummarySheet: APAgingSummaryService; - - @Inject() - private APAgingSumaryPdf: APAgingSummaryPdfInjectable; - - /** - * Retrieve the A/P aging summary in sheet format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public sheet(tenantId: number, query: IAPAgingSummaryQuery) { - return this.APAgingSummarySheet.APAgingSummary(tenantId, query); - } - - /** - * Retrieve the A/P aging summary in table format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public table(tenantId: number, query: IAPAgingSummaryQuery) { - return this.APAgingSummaryTable.table(tenantId, query); - } - - /** - * Retrieve the A/P aging summary in CSV format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public csv(tenantId: number, query: IAPAgingSummaryQuery) { - return this.APAgingSummaryExport.csv(tenantId, query); - } - - /** - * Retrieve the A/P aging summary in XLSX format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public xlsx(tenantId: number, query: IAPAgingSummaryQuery) { - return this.APAgingSummaryExport.xlsx(tenantId, query); - } - - /** - * Retrieves the A/P aging summary in pdf format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IAPAgingSummaryQuery) { - return this.APAgingSumaryPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryExportInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryExportInjectable.ts deleted file mode 100644 index 4561687e7..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryExportInjectable.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { APAgingSummaryTableInjectable } from './APAgingSummaryTableInjectable'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { IAPAgingSummaryQuery } from '@/interfaces'; - -@Service() -export class APAgingSummaryExportInjectable { - @Inject() - private APAgingSummaryTable: APAgingSummaryTableInjectable; - - /** - * Retrieves the A/P aging summary sheet in XLSX format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IAPAgingSummaryQuery) { - const table = await this.APAgingSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the A/P aging summary sheet in CSV format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IAPAgingSummaryQuery - ): Promise { - const table = await this.APAgingSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryMeta.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryMeta.ts deleted file mode 100644 index a32fe6457..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryMeta.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAgingSummaryMeta, IAgingSummaryQuery } from '@/interfaces'; -import { AgingSummaryMeta } from './AgingSummaryMeta'; - -@Service() -export class APAgingSummaryMeta { - @Inject() - private agingSummaryMeta: AgingSummaryMeta; - - /** - * Retrieve the aging summary meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IAgingSummaryQuery - ): Promise { - const commonMeta = await this.agingSummaryMeta.meta(tenantId, query); - - return { - ...commonMeta, - sheetName: 'A/P Aging Summary', - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts deleted file mode 100644 index 50ef588e8..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAPAgingSummaryQuery } from '@/interfaces'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { APAgingSummaryTableInjectable } from './APAgingSummaryTableInjectable'; -import { HtmlTableCss } from './_constants'; - -@Service() -export class APAgingSummaryPdfInjectable { - @Inject() - private APAgingSummaryTable: APAgingSummaryTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given A/P aging summary sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IAPAgingSummaryQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IAPAgingSummaryQuery - ): Promise { - const table = await this.APAgingSummaryTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedAsDate, - HtmlTableCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryService.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryService.ts deleted file mode 100644 index 17f60c59b..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryService.ts +++ /dev/null @@ -1,117 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { IAPAgingSummaryQuery, IAPAgingSummarySheet } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import APAgingSummarySheet from './APAgingSummarySheet'; -import { Tenant } from '@/system/models'; -import { APAgingSummaryMeta } from './APAgingSummaryMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class APAgingSummaryService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private APAgingSummaryMeta: APAgingSummaryMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Default report query. - */ - private get defaultQuery(): IAPAgingSummaryQuery { - return { - asDate: moment().format('YYYY-MM-DD'), - agingDaysBefore: 30, - agingPeriods: 3, - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - vendorsIds: [], - branchesIds: [], - noneZero: false, - }; - } - - /** - * Retrieve A/P aging summary report. - * @param {number} tenantId - - * @param {IAPAgingSummaryQuery} query - - * @returns {Promise} - */ - public async APAgingSummary( - tenantId: number, - query: IAPAgingSummaryQuery - ): Promise { - const { Bill } = this.tenancy.models(tenantId); - const { vendorRepository } = this.tenancy.repositories(tenantId); - - const filter = { - ...this.defaultQuery, - ...query, - }; - // Settings tenant service. - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Retrieve all vendors from the storage. - const vendors = - filter.vendorsIds.length > 0 - ? await vendorRepository.findWhereIn('id', filter.vendorsIds) - : await vendorRepository.all(); - - // Common query. - const commonQuery = (query) => { - if (!isEmpty(filter.branchesIds)) { - query.modify('filterByBranches', filter.branchesIds); - } - }; - // Retrieve all overdue vendors bills. - const overdueBills = await Bill.query() - .modify('overdueBillsFromDate', filter.asDate) - .onBuild(commonQuery); - - // Retrieve all due vendors bills. - const dueBills = await Bill.query() - .modify('dueBillsFromDate', filter.asDate) - .onBuild(commonQuery); - - // A/P aging summary report instance. - const APAgingSummaryReport = new APAgingSummarySheet( - tenantId, - filter, - vendors, - overdueBills, - dueBills, - tenant.metadata.baseCurrency - ); - // A/P aging summary report data and columns. - const data = APAgingSummaryReport.reportData(); - const columns = APAgingSummaryReport.reportColumns(); - - // Retrieve the aging summary report meta. - const meta = await this.APAgingSummaryMeta.meta(tenantId, filter); - - // Triggers `onPayableAgingViewed` event. - await this.eventPublisher.emitAsync(events.reports.onPayableAgingViewed, { - tenantId, - query, - }); - - return { - data, - columns, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummarySheet.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummarySheet.ts deleted file mode 100644 index ba42812ac..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummarySheet.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { groupBy, sum, isEmpty } from 'lodash'; -import * as R from 'ramda'; -import AgingSummaryReport from './AgingSummary'; -import { - IAPAgingSummaryQuery, - IAgingPeriod, - IBill, - IVendor, - IAPAgingSummaryData, - IAPAgingSummaryVendor, - IAPAgingSummaryColumns, - IAPAgingSummaryTotal, -} from '@/interfaces'; -import { Dictionary } from 'tsyringe/dist/typings/types'; -import { allPassedConditionsPass } from 'utils'; - -export default class APAgingSummarySheet extends AgingSummaryReport { - readonly tenantId: number; - readonly query: IAPAgingSummaryQuery; - readonly contacts: IVendor[]; - readonly unpaidBills: IBill[]; - readonly baseCurrency: string; - - readonly overdueInvoicesByContactId: Dictionary; - readonly currentInvoicesByContactId: Dictionary; - - readonly agingPeriods: IAgingPeriod[]; - - /** - * Constructor method. - * @param {number} tenantId - Tenant id. - * @param {IAPAgingSummaryQuery} query - Report query. - * @param {IVendor[]} vendors - Unpaid bills. - * @param {string} baseCurrency - Base currency of the organization. - */ - constructor( - tenantId: number, - query: IAPAgingSummaryQuery, - vendors: IVendor[], - overdueBills: IBill[], - unpaidBills: IBill[], - baseCurrency: string - ) { - super(); - - this.tenantId = tenantId; - this.query = query; - this.numberFormat = this.query.numberFormat; - this.contacts = vendors; - this.baseCurrency = baseCurrency; - - this.overdueInvoicesByContactId = groupBy(overdueBills, 'vendorId'); - this.currentInvoicesByContactId = groupBy(unpaidBills, 'vendorId'); - - // Initializes the aging periods. - this.agingPeriods = this.agingRangePeriods( - this.query.asDate, - this.query.agingDaysBefore, - this.query.agingPeriods - ); - } - - /** - * Retrieve the vendors aging and current total. - * @param {IAPAgingSummaryTotal} vendorsAgingPeriods - * @return {IAPAgingSummaryTotal} - */ - private getVendorsTotal = (vendorsAgingPeriods): IAPAgingSummaryTotal => { - const totalAgingPeriods = this.getTotalAgingPeriods(vendorsAgingPeriods); - const totalCurrent = this.getTotalCurrent(vendorsAgingPeriods); - const totalVendorsTotal = this.getTotalContactsTotals(vendorsAgingPeriods); - - return { - current: this.formatTotalAmount(totalCurrent), - aging: totalAgingPeriods, - total: this.formatTotalAmount(totalVendorsTotal), - }; - }; - - /** - * Retrieve the vendor section data. - * @param {IVendor} vendor - * @return {IAPAgingSummaryVendor} - */ - private vendorTransformer = (vendor: IVendor): IAPAgingSummaryVendor => { - const agingPeriods = this.getContactAgingPeriods(vendor.id); - const currentTotal = this.getContactCurrentTotal(vendor.id); - const agingPeriodsTotal = this.getAgingPeriodsTotal(agingPeriods); - - const amount = sum([agingPeriodsTotal, currentTotal]); - - return { - vendorName: vendor.displayName, - current: this.formatAmount(currentTotal), - aging: agingPeriods, - total: this.formatTotalAmount(amount), - }; - }; - - /** - * Mappes the given vendor objects to vendor report node. - * @param {IVendor[]} vendors - * @returns {IAPAgingSummaryVendor[]} - */ - private vendorsMapper = (vendors: IVendor[]): IAPAgingSummaryVendor[] => { - return vendors.map(this.vendorTransformer); - }; - - /** - * Detarmines whether the given vendor node is none zero. - * @param {IAPAgingSummaryVendor} vendorNode - * @returns {boolean} - */ - private filterNoneZeroVendorNode = ( - vendorNode: IAPAgingSummaryVendor - ): boolean => { - return vendorNode.total.amount !== 0; - }; - - /** - * Filters vendors report nodes based on the given report query. - * @param {IAPAgingSummaryVendor} vendorNode - * @returns {boolean} - */ - private vendorNodeFilter = (vendorNode: IAPAgingSummaryVendor): boolean => { - const { noneZero } = this.query; - - const conditions = [[noneZero, this.filterNoneZeroVendorNode]]; - - return allPassedConditionsPass(conditions)(vendorNode); - }; - - /** - * Filtesr the given report vendors nodes. - * @param {IAPAgingSummaryVendor[]} vendorNodes - * @returns {IAPAgingSummaryVendor[]} - */ - private vendorsFilter = ( - vendorNodes: IAPAgingSummaryVendor[] - ): IAPAgingSummaryVendor[] => { - return vendorNodes.filter(this.vendorNodeFilter); - }; - - /** - * Detarmines whether vendors nodes filter enabled. - * @returns {boolean} - */ - private isVendorNodesFilter = (): boolean => { - return isEmpty(this.query.vendorsIds); - }; - - /** - * Retrieve vendors aging periods. - * @return {IAPAgingSummaryVendor[]} - */ - private vendorsSection = (vendors: IVendor[]): IAPAgingSummaryVendor[] => { - return R.compose( - R.when(this.isVendorNodesFilter, this.vendorsFilter), - this.vendorsMapper - )(vendors); - }; - - /** - * Retrieve the A/P aging summary report data. - * @return {IAPAgingSummaryData} - */ - public reportData = (): IAPAgingSummaryData => { - const vendorsAgingPeriods = this.vendorsSection(this.contacts); - const vendorsTotal = this.getVendorsTotal(vendorsAgingPeriods); - - return { - vendors: vendorsAgingPeriods, - total: vendorsTotal, - }; - }; - - /** - * Retrieve the A/P aging summary report columns. - */ - public reportColumns = (): IAPAgingSummaryColumns => { - return this.agingPeriods; - }; -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTable.ts deleted file mode 100644 index b74e748d7..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - IAPAgingSummaryData, - IAgingSummaryQuery, - ITableColumn, - ITableColumnAccessor, - ITableRow, -} from '@/interfaces'; -import AgingSummaryTable from './AgingSummaryTable'; - -export default class APAgingSummaryTable extends AgingSummaryTable { - readonly report: IAPAgingSummaryData; - - /** - * Constructor method. - * @param {IARAgingSummaryData} data - * @param {IAgingSummaryQuery} query - * @param {any} i18n - */ - constructor(data: IAPAgingSummaryData, query: IAgingSummaryQuery, i18n: any) { - super(data, query, i18n); - } - - /** - * Retrieves the contacts table rows. - * @returns {ITableRow[]} - */ - get contactsRows(): ITableRow[] { - return this.contactsNodes(this.report.vendors); - } - - /** - * Contact name node accessor. - * @returns {ITableColumnAccessor} - */ - get contactNameNodeAccessor(): ITableColumnAccessor { - return { key: 'vendor_name', accessor: 'vendorName' }; - } - - /** - * Retrieves the contact name table column. - * @returns {ITableColumn} - */ - contactNameTableColumn = (): ITableColumn => { - return { label: 'Vendor name', key: 'vendor_name' }; - }; -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTableInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTableInjectable.ts deleted file mode 100644 index f9eda1613..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryTableInjectable.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAPAgingSummaryQuery, IAPAgingSummaryTable } from '@/interfaces'; -import { APAgingSummaryService } from './APAgingSummaryService'; -import APAgingSummaryTable from './APAgingSummaryTable'; - -@Service() -export class APAgingSummaryTableInjectable { - @Inject() - private APAgingSummarySheet: APAgingSummaryService; - - /** - * Retrieves A/P aging summary in table format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: IAPAgingSummaryQuery - ): Promise { - const report = await this.APAgingSummarySheet.APAgingSummary( - tenantId, - query - ); - const table = new APAgingSummaryTable(report.data, query, {}); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - meta: report.meta, - query: report.query, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts deleted file mode 100644 index f24932f13..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IARAgingSummaryQuery } from '@/interfaces'; -import { ARAgingSummaryTableInjectable } from './ARAgingSummaryTableInjectable'; -import { ARAgingSummaryExportInjectable } from './ARAgingSummaryExportInjectable'; -import ARAgingSummaryService from './ARAgingSummaryService'; -import { ARAgingSummaryPdfInjectable } from './ARAgingSummaryPdfInjectable'; - -@Service() -export class ARAgingSummaryApplication { - @Inject() - private ARAgingSummaryTable: ARAgingSummaryTableInjectable; - - @Inject() - private ARAgingSummaryExport: ARAgingSummaryExportInjectable; - - @Inject() - private ARAgingSummarySheet: ARAgingSummaryService; - - @Inject() - private ARAgingSummaryPdf: ARAgingSummaryPdfInjectable; - - /** - * Retrieve the A/R aging summary sheet. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public sheet(tenantId: number, query: IARAgingSummaryQuery) { - return this.ARAgingSummarySheet.ARAgingSummary(tenantId, query); - } - - /** - * Retrieve the A/R aging summary in table format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public table(tenantId: number, query: IARAgingSummaryQuery) { - return this.ARAgingSummaryTable.table(tenantId, query); - } - - /** - * Retrieve the A/R aging summary in XLSX format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public xlsx(tenantId: number, query: IARAgingSummaryQuery) { - return this.ARAgingSummaryExport.xlsx(tenantId, query); - } - - /** - * Retrieve the A/R aging summary in CSV format. - * @param {number} tenantId - * @param {IAPAgingSummaryQuery} query - */ - public csv(tenantId: number, query: IARAgingSummaryQuery) { - return this.ARAgingSummaryExport.csv(tenantId, query); - } - - /** - * Retrieves the A/R aging summary in pdf format. - * @param {number} tenantId - * @param {IARAgingSummaryQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IARAgingSummaryQuery) { - return this.ARAgingSummaryPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryExportInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryExportInjectable.ts deleted file mode 100644 index 25c3dd064..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryExportInjectable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { ARAgingSummaryTableInjectable } from './ARAgingSummaryTableInjectable'; -import { IARAgingSummaryQuery } from '@/interfaces'; - -@Service() -export class ARAgingSummaryExportInjectable { - @Inject() - private ARAgingSummaryTable: ARAgingSummaryTableInjectable; - - /** - * Retrieves the A/R aging summary sheet in XLSX format. - * @param {number} tenantId - * @param {IARAgingSummaryQuery} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: IARAgingSummaryQuery - ): Promise { - const table = await this.ARAgingSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the A/R aging summary sheet in CSV format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IARAgingSummaryQuery - ): Promise { - const table = await this.ARAgingSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryMeta.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryMeta.ts deleted file mode 100644 index dce2cb9d0..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryMeta.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAgingSummaryMeta, IAgingSummaryQuery } from '@/interfaces'; -import { AgingSummaryMeta } from './AgingSummaryMeta'; - -@Service() -export class ARAgingSummaryMeta { - @Inject() - private agingSummaryMeta: AgingSummaryMeta; - - /** - * Retrieve the aging summary meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IAgingSummaryQuery - ): Promise { - const commonMeta = await this.agingSummaryMeta.meta(tenantId, query); - - return { - ...commonMeta, - sheetName: 'A/R Aging Summary', - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts deleted file mode 100644 index a3b75f6d3..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IARAgingSummaryQuery } from '@/interfaces'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { ARAgingSummaryTableInjectable } from './ARAgingSummaryTableInjectable'; -import { HtmlTableCss } from './_constants'; - -@Service() -export class ARAgingSummaryPdfInjectable { - @Inject() - private ARAgingSummaryTable: ARAgingSummaryTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given balance sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IARAgingSummaryQuery - ): Promise { - const table = await this.ARAgingSummaryTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryService.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryService.ts deleted file mode 100644 index aa9a3cd9a..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryService.ts +++ /dev/null @@ -1,115 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { IARAgingSummaryQuery } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import ARAgingSummarySheet from './ARAgingSummarySheet'; -import { Tenant } from '@/system/models'; -import { ARAgingSummaryMeta } from './ARAgingSummaryMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export default class ARAgingSummaryService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private ARAgingSummaryMeta: ARAgingSummaryMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Default report query. - */ - get defaultQuery(): IARAgingSummaryQuery { - return { - asDate: moment().format('YYYY-MM-DD'), - agingDaysBefore: 30, - agingPeriods: 3, - numberFormat: { - divideOn1000: false, - negativeFormat: 'mines', - showZero: false, - formatMoney: 'total', - precision: 2, - }, - customersIds: [], - branchesIds: [], - noneZero: false, - }; - } - - /** - * Retrieve A/R aging summary report. - * @param {number} tenantId - Tenant id. - * @param {IARAgingSummaryQuery} query - - */ - async ARAgingSummary(tenantId: number, query: IARAgingSummaryQuery) { - const { SaleInvoice } = this.tenancy.models(tenantId); - const { customerRepository } = this.tenancy.repositories(tenantId); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Retrieve all customers from the storage. - const customers = - filter.customersIds.length > 0 - ? await customerRepository.findWhereIn('id', filter.customersIds) - : await customerRepository.all(); - - // Common query. - const commonQuery = (query) => { - if (!isEmpty(filter.branchesIds)) { - query.modify('filterByBranches', filter.branchesIds); - } - }; - // Retrieve all overdue sale invoices. - const overdueSaleInvoices = await SaleInvoice.query() - .modify('overdueInvoicesFromDate', filter.asDate) - .onBuild(commonQuery); - - // Retrieve all due sale invoices. - const currentInvoices = await SaleInvoice.query() - .modify('dueInvoicesFromDate', filter.asDate) - .onBuild(commonQuery); - - // AR aging summary report instance. - const ARAgingSummaryReport = new ARAgingSummarySheet( - tenantId, - filter, - customers, - overdueSaleInvoices, - currentInvoices, - tenant.metadata.baseCurrency - ); - // AR aging summary report data and columns. - const data = ARAgingSummaryReport.reportData(); - const columns = ARAgingSummaryReport.reportColumns(); - - // Retrieve the aging summary report meta. - const meta = await this.ARAgingSummaryMeta.meta(tenantId, filter); - - // Triggers `onReceivableAgingViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onReceivableAgingViewed, - { - tenantId, - query, - } - ); - - return { - data, - columns, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummarySheet.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummarySheet.ts deleted file mode 100644 index a9f1856c2..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummarySheet.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { Dictionary, groupBy, isEmpty, sum } from 'lodash'; -import * as R from 'ramda'; -import { - ICustomer, - IARAgingSummaryQuery, - IARAgingSummaryCustomer, - IAgingPeriod, - ISaleInvoice, - IARAgingSummaryData, - IARAgingSummaryColumns, - IARAgingSummaryTotal, -} from '@/interfaces'; -import AgingSummaryReport from './AgingSummary'; -import { allPassedConditionsPass } from '../../../utils'; - -export default class ARAgingSummarySheet extends AgingSummaryReport { - readonly tenantId: number; - readonly query: IARAgingSummaryQuery; - readonly contacts: ICustomer[]; - readonly agingPeriods: IAgingPeriod[]; - readonly baseCurrency: string; - - readonly overdueInvoicesByContactId: Dictionary; - readonly currentInvoicesByContactId: Dictionary; - - /** - * Constructor method. - * @param {number} tenantId - * @param {IARAgingSummaryQuery} query - * @param {ICustomer[]} customers - * @param {IJournalPoster} journal - */ - constructor( - tenantId: number, - query: IARAgingSummaryQuery, - customers: ICustomer[], - overdueSaleInvoices: ISaleInvoice[], - currentSaleInvoices: ISaleInvoice[], - baseCurrency: string - ) { - super(); - - this.tenantId = tenantId; - this.contacts = customers; - this.query = query; - this.baseCurrency = baseCurrency; - this.numberFormat = this.query.numberFormat; - - this.overdueInvoicesByContactId = groupBy( - overdueSaleInvoices, - 'customerId' - ); - this.currentInvoicesByContactId = groupBy( - currentSaleInvoices, - 'customerId' - ); - // Initializes the aging periods. - this.agingPeriods = this.agingRangePeriods( - this.query.asDate, - this.query.agingDaysBefore, - this.query.agingPeriods - ); - } - - /** - * Mapping aging customer. - * @param {ICustomer} customer - - * @return {IARAgingSummaryCustomer[]} - */ - private customerTransformer = ( - customer: ICustomer - ): IARAgingSummaryCustomer => { - const agingPeriods = this.getContactAgingPeriods(customer.id); - const currentTotal = this.getContactCurrentTotal(customer.id); - const agingPeriodsTotal = this.getAgingPeriodsTotal(agingPeriods); - const amount = sum([agingPeriodsTotal, currentTotal]); - - return { - customerName: customer.displayName, - current: this.formatAmount(currentTotal), - aging: agingPeriods, - total: this.formatTotalAmount(amount), - }; - }; - - /** - * Mappes the customers objects to report accounts nodes. - * @param {ICustomer[]} customers - * @returns {IARAgingSummaryCustomer[]} - */ - private customersMapper = ( - customers: ICustomer[] - ): IARAgingSummaryCustomer[] => { - return customers.map(this.customerTransformer); - }; - - /** - * Filters the none-zero account report node. - * @param {IARAgingSummaryCustomer} node - * @returns {boolean} - */ - private filterNoneZeroAccountNode = ( - node: IARAgingSummaryCustomer - ): boolean => { - return node.total.amount !== 0; - }; - - /** - * Filters customer report node based on the given report query. - * @param {IARAgingSummaryCustomer} customerNode - * @returns {boolean} - */ - private customerNodeFilter = ( - customerNode: IARAgingSummaryCustomer - ): boolean => { - const { noneZero } = this.query; - - const conditions = [[noneZero, this.filterNoneZeroAccountNode]]; - - return allPassedConditionsPass(conditions)(customerNode); - }; - - /** - * Filters customers report nodes. - * @param {IARAgingSummaryCustomer[]} customers - * @returns {IARAgingSummaryCustomer[]} - */ - private customersFilter = ( - customers: IARAgingSummaryCustomer[] - ): IARAgingSummaryCustomer[] => { - return customers.filter(this.customerNodeFilter); - }; - - /** - * Detarmines the customers nodes filter is enabled. - * @returns {boolean} - */ - private isCustomersFilterEnabled = (): boolean => { - return isEmpty(this.query.customersIds); - } - - /** - * Retrieve customers report. - * @param {ICustomer[]} customers - * @return {IARAgingSummaryCustomer[]} - */ - private customersWalker = ( - customers: ICustomer[] - ): IARAgingSummaryCustomer[] => { - return R.compose( - R.when(this.isCustomersFilterEnabled, this.customersFilter), - this.customersMapper - )(customers); - }; - - /** - * Retrieve the customers aging and current total. - * @param {IARAgingSummaryCustomer} customersAgingPeriods - */ - private getCustomersTotal = ( - customersAgingPeriods: IARAgingSummaryCustomer[] - ): IARAgingSummaryTotal => { - const totalAgingPeriods = this.getTotalAgingPeriods(customersAgingPeriods); - const totalCurrent = this.getTotalCurrent(customersAgingPeriods); - const totalCustomersTotal = this.getTotalContactsTotals( - customersAgingPeriods - ); - - return { - current: this.formatTotalAmount(totalCurrent), - aging: totalAgingPeriods, - total: this.formatTotalAmount(totalCustomersTotal), - }; - }; - - /** - * Retrieve A/R aging summary report data. - * @return {IARAgingSummaryData} - */ - public reportData = (): IARAgingSummaryData => { - const customersAgingPeriods = this.customersWalker(this.contacts); - const customersTotal = this.getCustomersTotal(customersAgingPeriods); - - return { - customers: customersAgingPeriods, - total: customersTotal, - }; - }; - - /** - * Retrieve A/R aging summary report columns. - * @return {IARAgingSummaryColumns} - */ - public reportColumns(): IARAgingSummaryColumns { - return this.agingPeriods; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTable.ts deleted file mode 100644 index 5e0ad88b3..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTable.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { - IARAgingSummaryData, - IAgingSummaryData, - IAgingSummaryQuery, - ITableColumnAccessor, - ITableRow, -} from '@/interfaces'; -import AgingSummaryTable from './AgingSummaryTable'; - -export default class ARAgingSummaryTable extends AgingSummaryTable { - readonly report: IARAgingSummaryData; - - /** - * Constructor method. - * @param {IARAgingSummaryData} data - * @param {IAgingSummaryQuery} query - * @param {any} i18n - */ - constructor(data: IARAgingSummaryData, query: IAgingSummaryQuery, i18n: any) { - super(data, query, i18n); - } - - /** - * Retrieves the contacts table rows. - * @returns {ITableRow[]} - */ - get contactsRows(): ITableRow[] { - return this.contactsNodes(this.report.customers); - } - - /** - * Contact name node accessor. - * @returns {ITableColumnAccessor} - */ - get contactNameNodeAccessor(): ITableColumnAccessor { - return { key: 'customer_name', accessor: 'customerName' }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTableInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTableInjectable.ts deleted file mode 100644 index 6f702cfe4..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryTableInjectable.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { IARAgingSummaryQuery, IARAgingSummaryTable } from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import ARAgingSummaryTable from './ARAgingSummaryTable'; -import ARAgingSummaryService from './ARAgingSummaryService'; - -@Service() -export class ARAgingSummaryTableInjectable { - @Inject() - private ARAgingSummarySheet: ARAgingSummaryService; - - /** - * Retrieves A/R aging summary in table format. - * @param {number} tenantId - * @param {IARAgingSummaryQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: IARAgingSummaryQuery - ): Promise { - const report = await this.ARAgingSummarySheet.ARAgingSummary( - - tenantId, - query - ); - const table = new ARAgingSummaryTable(report.data, query, {}); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - meta: report.meta, - query, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/AgingReport.ts b/packages/server/src/services/FinancialStatements/AgingSummary/AgingReport.ts deleted file mode 100644 index dbbe9119f..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/AgingReport.ts +++ /dev/null @@ -1,54 +0,0 @@ -import moment from 'moment'; -import { - IAgingPeriod, -} from '@/interfaces'; -import FinancialSheet from "../FinancialSheet"; - - -export default abstract class AgingReport extends FinancialSheet{ - /** - * Retrieve the aging periods range. - * @param {string} asDay - * @param {number} agingDaysBefore - * @param {number} agingPeriodsFreq - */ - agingRangePeriods( - asDay: Date|string, - agingDaysBefore: number, - agingPeriodsFreq: number - ): IAgingPeriod[] { - const totalAgingDays = agingDaysBefore * agingPeriodsFreq; - const startAging = moment(asDay).startOf('day'); - const endAging = startAging - .clone() - .subtract(totalAgingDays, 'days') - .endOf('day'); - - const agingPeriods: IAgingPeriod[] = []; - const startingAging = startAging.clone(); - - let beforeDays = 1; - let toDays = 0; - - while (startingAging > endAging) { - const currentAging = startingAging.clone(); - startingAging.subtract(agingDaysBefore, 'days').endOf('day'); - toDays += agingDaysBefore; - - agingPeriods.push({ - fromPeriod: moment(currentAging).format('YYYY-MM-DD'), - toPeriod: moment(startingAging).format('YYYY-MM-DD'), - beforeDays: beforeDays === 1 ? 0 : beforeDays, - toDays: toDays, - ...(startingAging.valueOf() === endAging.valueOf() - ? { - toPeriod: null, - toDays: null, - } - : {}), - }); - beforeDays += agingDaysBefore; - } - return agingPeriods; - } -} \ No newline at end of file diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummary.ts b/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummary.ts deleted file mode 100644 index 97cc8f186..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummary.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { defaultTo, sumBy, get } from 'lodash'; -import { - IAgingPeriod, - ISaleInvoice, - IBill, - IAgingPeriodTotal, - IARAgingSummaryCustomer, - IContact, - IARAgingSummaryQuery, - IFormatNumberSettings, - IAgingAmount, - IAgingSummaryContact, -} from '@/interfaces'; -import AgingReport from './AgingReport'; -import { Dictionary } from 'tsyringe/dist/typings/types'; - -export default abstract class AgingSummaryReport extends AgingReport { - protected readonly contacts: IContact[]; - protected readonly agingPeriods: IAgingPeriod[] = []; - protected readonly baseCurrency: string; - protected readonly query: IARAgingSummaryQuery; - protected readonly overdueInvoicesByContactId: Dictionary< - (ISaleInvoice | IBill)[] - >; - protected readonly currentInvoicesByContactId: Dictionary< - (ISaleInvoice | IBill)[] - >; - - /** - * Setes initial aging periods to the contact. - */ - protected getInitialAgingPeriodsTotal(): IAgingPeriodTotal[] { - return this.agingPeriods.map((agingPeriod) => ({ - ...agingPeriod, - total: this.formatAmount(0), - })); - } - - /** - * Calculates the given contact aging periods. - * @param {number} contactId - Contact id. - * @return {IAgingPeriodTotal[]} - */ - protected getContactAgingPeriods(contactId: number): IAgingPeriodTotal[] { - const unpaidInvoices = this.getUnpaidInvoicesByContactId(contactId); - const initialAgingPeriods = this.getInitialAgingPeriodsTotal(); - - return unpaidInvoices.reduce( - (agingPeriods: IAgingPeriodTotal[], unpaidInvoice) => { - const newAgingPeriods = this.getContactAgingDueAmount( - agingPeriods, - unpaidInvoice.dueAmount, - unpaidInvoice.overdueDays - ); - return newAgingPeriods; - }, - initialAgingPeriods - ); - } - - /** - * Sets the contact aging due amount to the table. - * @param {IAgingPeriodTotal} agingPeriods - Aging periods. - * @param {number} dueAmount - Due amount. - * @param {number} overdueDays - Overdue days. - * @return {IAgingPeriodTotal[]} - */ - protected getContactAgingDueAmount( - agingPeriods: IAgingPeriodTotal[], - dueAmount: number, - overdueDays: number - ): IAgingPeriodTotal[] { - const newAgingPeriods = agingPeriods.map((agingPeriod) => { - const isInAgingPeriod = - agingPeriod.beforeDays <= overdueDays && - (agingPeriod.toDays > overdueDays || !agingPeriod.toDays); - - const total: number = isInAgingPeriod - ? agingPeriod.total.amount + dueAmount - : agingPeriod.total.amount; - - return { - ...agingPeriod, - total: this.formatAmount(total), - }; - }); - return newAgingPeriods; - } - - /** - * Retrieve the aging period total object. - * @param {number} amount - * @param {IFormatNumberSettings} settings - Override the format number settings. - * @return {IAgingAmount} - */ - protected formatAmount( - amount: number, - settings: IFormatNumberSettings = {} - ): IAgingAmount { - return { - amount, - formattedAmount: this.formatNumber(amount, settings), - currencyCode: this.baseCurrency, - }; - } - - /** - * Retrieve the aging period total object. - * @param {number} amount - * @param {IFormatNumberSettings} settings - Override the format number settings. - * @return {IAgingPeriodTotal} - */ - protected formatTotalAmount( - amount: number, - settings: IFormatNumberSettings = {} - ): IAgingAmount { - return this.formatAmount(amount, { - money: true, - excerptZero: false, - ...settings, - }); - } - - /** - * Calculates the total of the aging period by the given index. - * @param {number} index - * @return {number} - */ - protected getTotalAgingPeriodByIndex( - contactsAgingPeriods: any, - index: number - ): number { - return this.contacts.reduce((acc, contact) => { - const totalPeriod = contactsAgingPeriods[index] - ? contactsAgingPeriods[index].total - : 0; - - return acc + totalPeriod; - }, 0); - } - - /** - * Retrieve the due invoices by the given contact id. - * @param {number} contactId - - * @return {(ISaleInvoice | IBill)[]} - */ - protected getUnpaidInvoicesByContactId( - contactId: number - ): (ISaleInvoice | IBill)[] { - return defaultTo(this.overdueInvoicesByContactId[contactId], []); - } - - /** - * Retrieve total aging periods of the report. - * @return {(IAgingPeriodTotal & IAgingPeriod)[]} - */ - protected getTotalAgingPeriods( - contactsAgingPeriods: IARAgingSummaryCustomer[] - ): IAgingPeriodTotal[] { - return this.agingPeriods.map((agingPeriod, index) => { - const total = sumBy( - contactsAgingPeriods, - (summary: IARAgingSummaryCustomer) => { - const aging = summary.aging[index]; - - if (!aging) { - return 0; - } - return aging.total.amount; - } - ); - - return { - ...agingPeriod, - total: this.formatTotalAmount(total), - }; - }); - } - - /** - * Retrieve the current invoices by the given contact id. - * @param {number} contactId - Specific contact id. - * @return {(ISaleInvoice | IBill)[]} - */ - protected getCurrentInvoicesByContactId( - contactId: number - ): (ISaleInvoice | IBill)[] { - return get(this.currentInvoicesByContactId, contactId, []); - } - - /** - * Retrieve the contact total due amount. - * @param {number} contactId - Specific contact id. - * @return {number} - */ - protected getContactCurrentTotal(contactId: number): number { - const currentInvoices = this.getCurrentInvoicesByContactId(contactId); - return sumBy(currentInvoices, (invoice) => invoice.dueAmount); - } - - /** - * Retrieve to total sumation of the given contacts summeries sections. - * @param {IARAgingSummaryCustomer[]} contactsSections - - * @return {number} - */ - protected getTotalCurrent(contactsSummaries: IAgingSummaryContact[]): number { - return sumBy(contactsSummaries, (summary) => summary.current.amount); - } - - /** - * Retrieve the total of the given aging periods. - * @param {IAgingPeriodTotal[]} agingPeriods - * @return {number} - */ - protected getAgingPeriodsTotal(agingPeriods: IAgingPeriodTotal[]): number { - return sumBy(agingPeriods, (period) => period.total.amount); - } - - /** - * Retrieve total of contacts totals. - * @param {IAgingSummaryContact[]} contactsSummaries - */ - protected getTotalContactsTotals( - contactsSummaries: IAgingSummaryContact[] - ): number { - return sumBy(contactsSummaries, (summary) => summary.total.amount); - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryMeta.ts b/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryMeta.ts deleted file mode 100644 index 5d3599997..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryMeta.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { IAgingSummaryMeta, IAgingSummaryQuery } from '@/interfaces'; -import moment from 'moment'; - -export class AgingSummaryMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the aging summary meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IAgingSummaryQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedAsDate = moment(query.asDate).format('YYYY/MM/DD'); - const formattedDateRange = `As ${formattedAsDate}`; - - return { - ...commonMeta, - sheetName: 'A/P Aging Summary', - formattedAsDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryTable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryTable.ts deleted file mode 100644 index 0b6c61cbd..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/AgingSummaryTable.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as R from 'ramda'; -import { - IAgingPeriod, - IAgingSummaryContact, - IAgingSummaryData, - IAgingSummaryQuery, - IAgingSummaryTotal, - ITableColumn, - ITableColumnAccessor, - ITableRow, -} from '@/interfaces'; -import { tableRowMapper } from '@/utils'; -import AgingReport from './AgingReport'; -import { AgingSummaryRowType } from './_constants'; -import { FinancialTable } from '../FinancialTable'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; - -export default abstract class AgingSummaryTable extends R.compose( - FinancialSheetStructure, - FinancialTable -)(AgingReport) { - protected readonly report: IAgingSummaryData; - protected readonly query: IAgingSummaryQuery; - protected readonly agingPeriods: IAgingPeriod[]; - protected readonly i18n: any; - - /** - * Constructor method. - * @param {IARAgingSummaryData} data - * @param {IAgingSummaryQuery} query - * @param {any} i18n - */ - constructor(data: IAgingSummaryData, query: IAgingSummaryQuery, i18n: any) { - super(); - - this.report = data; - this.i18n = i18n; - this.query = query; - - this.agingPeriods = this.agingRangePeriods( - this.query.asDate, - this.query.agingDaysBefore, - this.query.agingPeriods - ); - } - - // ------------------------- - // # Accessors. - // ------------------------- - /** - * Aging accessors of contact and total nodes. - * @param {IAgingSummaryContact | IAgingSummaryTotal} node - * @returns {ITableColumnAccessor[]} - */ - protected agingNodeAccessors = ( - node: IAgingSummaryContact | IAgingSummaryTotal - ): ITableColumnAccessor[] => { - return node.aging.map((aging, index) => ({ - key: 'aging_period', - accessor: `aging[${index}].total.formattedAmount`, - })); - }; - - /** - * Contact name node accessor. - * @returns {ITableColumnAccessor} - */ - protected get contactNameNodeAccessor(): ITableColumnAccessor { - return { key: 'customer_name', accessor: 'customerName' }; - } - - /** - * Retrieves the common columns for all report nodes. - * @param {IAgingSummaryContact} - * @returns {ITableColumnAccessor[]} - */ - protected contactNodeAccessors = ( - node: IAgingSummaryContact - ): ITableColumnAccessor[] => { - return R.compose( - R.concat([ - this.contactNameNodeAccessor, - { key: 'current', accessor: 'current.formattedAmount' }, - ...this.agingNodeAccessors(node), - { key: 'total', accessor: 'total.formattedAmount' }, - ]) - )([]); - }; - - /** - * Retrieves the contact name table row. - * @param {IAgingSummaryContact} node - - * @return {ITableRow} - */ - protected contactNameNode = (node: IAgingSummaryContact): ITableRow => { - const columns = this.contactNodeAccessors(node); - const meta = { - rowTypes: [AgingSummaryRowType.Contact], - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Maps the customers nodes to table rows. - * @param {IAgingSummaryContact[]} nodes - * @returns {ITableRow[]} - */ - protected contactsNodes = (nodes: IAgingSummaryContact[]): ITableRow[] => { - return nodes.map(this.contactNameNode); - }; - - /** - * Retrieves the common columns for all report nodes. - * @param {IAgingSummaryTotal} - * @returns {ITableColumnAccessor[]} - */ - protected totalNodeAccessors = ( - node: IAgingSummaryTotal - ): ITableColumnAccessor[] => { - return R.compose( - R.concat([ - { key: 'blank', value: '' }, - { key: 'current', accessor: 'current.formattedAmount' }, - ...this.agingNodeAccessors(node), - { key: 'total', accessor: 'total.formattedAmount' }, - ]) - )([]); - }; - - /** - * Retrieves the total row of the given report total node. - * @param {IAgingSummaryTotal} node - * @returns {ITableRow} - */ - protected totalNode = (node: IAgingSummaryTotal): ITableRow => { - const columns = this.totalNodeAccessors(node); - const meta = { - rowTypes: [AgingSummaryRowType.Total], - }; - return tableRowMapper(node, columns, meta); - }; - - // ------------------------- - // # Computed Rows. - // ------------------------- - /** - * Retrieves the contacts table rows. - * @returns {ITableRow[]} - */ - protected get contactsRows(): ITableRow[] { - return []; - } - - /** - * Table total row. - * @returns {ITableRow} - */ - protected get totalRow(): ITableRow { - return this.totalNode(this.report.total); - } - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return R.compose( - R.unless(R.isEmpty, R.append(this.totalRow)), - R.concat(this.contactsRows) - )([]); - }; - - // ------------------------- - // # Columns. - // ------------------------- - /** - * Retrieves the aging table columns. - * @returns {ITableColumn[]} - */ - protected agingTableColumns = (): ITableColumn[] => { - return this.agingPeriods.map((agingPeriod) => { - return { - label: `${agingPeriod.beforeDays} - ${ - agingPeriod.toDays || 'And Over' - }`, - key: 'aging_period', - }; - }); - }; - - /** - * Retrieves the contact name table column. - * @returns {ITableColumn} - */ - protected contactNameTableColumn = (): ITableColumn => { - return { label: 'Customer name', key: 'customer_name' }; - }; - - /** - * Retrieves the report columns. - * @returns {ITableColumn} - */ - public tableColumns = (): ITableColumn[] => { - return R.compose(this.tableColumnsCellIndexing)([ - this.contactNameTableColumn(), - { label: 'Current', key: 'current' }, - ...this.agingTableColumns(), - { label: 'Total', key: 'total' }, - ]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/_constants.ts b/packages/server/src/services/FinancialStatements/AgingSummary/_constants.ts deleted file mode 100644 index fd818e160..000000000 --- a/packages/server/src/services/FinancialStatements/AgingSummary/_constants.ts +++ /dev/null @@ -1,21 +0,0 @@ -export enum AgingSummaryRowType { - Contact = 'contact', - Total = 'total', -} - -export const HtmlTableCss = ` -table tr.row-type--total td{ - font-weight: 600; - border-top: 1px solid #bbb; - border-bottom: 3px double #333; -} - -table .column--current, -table .column--aging_period, -table .column--total, -table .cell--current, -table .cell--aging_period, -table .cell--total { - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts deleted file mode 100644 index e07b91dbf..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts +++ /dev/null @@ -1,108 +0,0 @@ -import * as R from 'ramda'; -import FinancialSheet from '../FinancialSheet'; -import { - IBalanceSheetQuery, - INumberFormatQuery, - IBalanceSheetSchemaNode, - IBalanceSheetDataNode, -} from '../../../interfaces'; -import { BalanceSheetSchema } from './BalanceSheetSchema'; -import { BalanceSheetPercentage } from './BalanceSheetPercentage'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { BalanceSheetDatePeriods } from './BalanceSheetDatePeriods'; -import { BalanceSheetBase } from './BalanceSheetBase'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import BalanceSheetRepository from './BalanceSheetRepository'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { BalanceSheetFiltering } from './BalanceSheetFiltering'; -import { BalanceSheetNetIncome } from './BalanceSheetNetIncome'; -import { BalanceSheetAggregators } from './BalanceSheetAggregators'; -import { BalanceSheetAccounts } from './BalanceSheetAccounts'; - -export default class BalanceSheet extends R.compose( - BalanceSheetAggregators, - BalanceSheetAccounts, - BalanceSheetNetIncome, - BalanceSheetFiltering, - BalanceSheetDatePeriods, - BalanceSheetComparsionPreviousPeriod, - BalanceSheetComparsionPreviousYear, - BalanceSheetPercentage, - BalanceSheetSchema, - BalanceSheetBase, - FinancialSheetStructure -)(FinancialSheet) { - /** - * Balance sheet query. - * @param {BalanceSheetQuery} - */ - readonly query: BalanceSheetQuery; - - /** - * Balance sheet number format query. - * @param {INumberFormatQuery} - */ - readonly numberFormat: INumberFormatQuery; - - /** - * Base currency of the organization. - * @param {string} - */ - readonly baseCurrency: string; - - /** - * Localization. - */ - readonly i18n: any; - - /** - * Constructor method. - * @param {IBalanceSheetQuery} query - - * @param {IAccount[]} accounts - - * @param {string} baseCurrency - - */ - constructor( - query: IBalanceSheetQuery, - repository: BalanceSheetRepository, - baseCurrency: string, - i18n - ) { - super(); - - this.query = new BalanceSheetQuery(query); - this.repository = repository; - this.baseCurrency = baseCurrency; - this.numberFormat = this.query.query.numberFormat; - this.i18n = i18n; - } - - /** - * Parses report schema nodes. - * @param {IBalanceSheetSchemaNode[]} schema - * @returns {IBalanceSheetDataNode[]} - */ - public parseSchemaNodes = ( - schema: IBalanceSheetSchemaNode[] - ): IBalanceSheetDataNode[] => { - return R.compose( - this.aggregatesSchemaParser, - this.netIncomeSchemaParser, - this.accountsSchemaParser - )(schema) as IBalanceSheetDataNode[]; - }; - - /** - * Retrieve the report statement data. - * @returns {IBalanceSheetDataNode[]} - */ - public reportData = () => { - const balanceSheetSchema = this.getSchema(); - - return R.compose( - this.reportFilterPlugin, - this.reportPercentageCompose, - this.parseSchemaNodes - )(balanceSheetSchema); - }; -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAccounts.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAccounts.ts deleted file mode 100644 index c4e85c76a..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAccounts.ts +++ /dev/null @@ -1,204 +0,0 @@ -import * as R from 'ramda'; -import { defaultTo, toArray } from 'lodash'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { - BALANCE_SHEET_SCHEMA_NODE_TYPE, - IAccount, - IBalanceSheetAccountNode, - IBalanceSheetAccountsNode, - IBalanceSheetDataNode, - IBalanceSheetSchemaAccountNode, - IBalanceSheetSchemaNode, - INumberFormatQuery, -} from '@/interfaces'; -import { BalanceSheetNetIncome } from './BalanceSheetNetIncome'; -import { BalanceSheetFiltering } from './BalanceSheetFiltering'; -import { BalanceSheetDatePeriods } from './BalanceSheetDatePeriods'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { BalanceSheetPercentage } from './BalanceSheetPercentage'; -import { BalanceSheetSchema } from './BalanceSheetSchema'; -import { BalanceSheetBase } from './BalanceSheetBase'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { flatToNestedArray } from '@/utils'; -import BalanceSheetRepository from './BalanceSheetRepository'; - -export const BalanceSheetAccounts = (Base: any) => - class extends R.compose( - BalanceSheetNetIncome, - BalanceSheetFiltering, - BalanceSheetDatePeriods, - BalanceSheetComparsionPreviousPeriod, - BalanceSheetComparsionPreviousYear, - BalanceSheetPercentage, - BalanceSheetSchema, - BalanceSheetBase, - FinancialSheetStructure - )(Base) { - /** - * Balance sheet query. - * @param {BalanceSheetQuery} - */ - readonly query: BalanceSheetQuery; - - /** - * Balance sheet number format query. - * @param {INumberFormatQuery} - */ - readonly numberFormat: INumberFormatQuery; - - /** - * Base currency of the organization. - * @param {string} - */ - readonly baseCurrency: string; - - /** - * Localization. - */ - readonly i18n: any; - - /** - * Balance sheet repository. - */ - readonly repository: BalanceSheetRepository; - - /** - * Retrieve the accounts node of accounts types. - * @param {string} accountsTypes - * @returns {IAccount[]} - */ - private getAccountsByAccountTypes = ( - accountsTypes: string[] - ): IAccount[] => { - const mapAccountsByTypes = R.map((accountType) => - defaultTo(this.repository.accountsByType.get(accountType), []) - ); - return R.compose(R.flatten, mapAccountsByTypes)(accountsTypes); - }; - - /** - * Mappes the account model to report account node. - * @param {IAccount} account - * @returns {IBalanceSheetAccountNode} - */ - private reportSchemaAccountNodeMapper = ( - account: IAccount - ): IBalanceSheetAccountNode => { - const childrenAccountsIds = this.repository.accountsGraph.dependenciesOf( - account.id - ); - const accountIds = R.uniq(R.append(account.id, childrenAccountsIds)); - const total = this.repository.totalAccountsLedger - .whereAccountsIds(accountIds) - .getClosingBalance(); - - return { - id: account.id, - index: account.index, - name: account.name, - code: account.code, - total: this.getAmountMeta(total), - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT, - }; - }; - - /** - * Mappes the given account model to the balance sheet account node. - * @param {IAccount} account - * @returns {IBalanceSheetAccountNode} - */ - private reportSchemaAccountNodeComposer = ( - account: IAccount - ): IBalanceSheetAccountNode => { - return R.compose( - R.when( - this.query.isPreviousYearActive, - this.previousYearAccountNodeComposer - ), - R.when( - this.query.isPreviousPeriodActive, - this.previousPeriodAccountNodeComposer - ), - R.when( - this.query.isDatePeriodsColumnsType, - this.assocAccountNodeDatePeriods - ), - this.reportSchemaAccountNodeMapper - )(account); - }; - - // ----------------------------- - // - Accounts Node Praser - // ----------------------------- - /** - * Retrieve the report accounts node by the given accounts types. - * @param {string[]} accountsTypes - * @returns {IBalanceSheetAccountNode[]} - */ - private getAccountsNodesByAccountTypes = ( - accountsTypes: string[] - ): IBalanceSheetAccountNode[] => { - // Retrieves accounts from the given defined node account types. - const accounts = this.getAccountsByAccountTypes(accountsTypes); - - // Converts the flatten accounts to tree. - const accountsTree = flatToNestedArray(accounts, { - id: 'id', - parentId: 'parentAccountId', - }); - // Maps over the accounts tree. - return this.mapNodesDeep( - accountsTree, - this.reportSchemaAccountNodeComposer - ); - }; - - /** - * Mappes the accounts schema node type. - * @param {IBalanceSheetSchemaNode} node - Schema node. - * @returns {IBalanceSheetAccountNode} - */ - private reportSchemaAccountsNodeMapper = ( - node: IBalanceSheetSchemaAccountNode - ): IBalanceSheetAccountsNode => { - const accounts = this.getAccountsNodesByAccountTypes(node.accountsTypes); - const children = toArray(node?.children); - - return { - id: node.id, - name: this.i18n.__(node.name), - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - children: [...accounts, ...children], - total: this.getTotalAmountMeta(0), - }; - }; - - /** - * Mappes the given report schema node. - * @param {IBalanceSheetSchemaNode | IBalanceSheetDataNode} node - Schema node. - * @return {IBalanceSheetSchemaNode | IBalanceSheetDataNode} - */ - private reportAccountSchemaParser = ( - node: IBalanceSheetSchemaNode | IBalanceSheetDataNode - ): IBalanceSheetSchemaNode | IBalanceSheetDataNode => { - return R.compose( - R.when( - this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS), - this.reportSchemaAccountsNodeMapper - ) - )(node); - }; - - /** - * Parses the report accounts schema nodes. - * @param {IBalanceSheetSchemaNode[]} nodes - - * @return {IBalanceSheetStructureSection[]} - */ - public accountsSchemaParser = ( - nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[] - ): (IBalanceSheetDataNode | IBalanceSheetSchemaNode)[] => { - return this.mapNodesDeepReverse(nodes, this.reportAccountSchemaParser); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAggregators.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAggregators.ts deleted file mode 100644 index c818ef3ab..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetAggregators.ts +++ /dev/null @@ -1,140 +0,0 @@ -import * as R from 'ramda'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { - BALANCE_SHEET_SCHEMA_NODE_TYPE, - IBalanceSheetAggregateNode, - IBalanceSheetDataNode, - IBalanceSheetSchemaAggregateNode, - IBalanceSheetSchemaNode, - INumberFormatQuery, -} from '@/interfaces'; -import { BalanceSheetDatePeriods } from './BalanceSheetDatePeriods'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { BalanceSheetPercentage } from './BalanceSheetPercentage'; -import { BalanceSheetSchema } from './BalanceSheetSchema'; -import { BalanceSheetBase } from './BalanceSheetBase'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; - -export const BalanceSheetAggregators = (Base: any) => - class extends R.compose( - BalanceSheetDatePeriods, - BalanceSheetComparsionPreviousPeriod, - BalanceSheetComparsionPreviousYear, - BalanceSheetPercentage, - BalanceSheetSchema, - BalanceSheetBase, - FinancialSheetStructure - )(Base) { - /** - * Balance sheet query. - * @param {BalanceSheetQuery} - */ - readonly query: BalanceSheetQuery; - - /** - * Balance sheet number format query. - * @param {INumberFormatQuery} - */ - readonly numberFormat: INumberFormatQuery; - - /** - * Base currency of the organization. - * @param {string} - */ - readonly baseCurrency: string; - - /** - * Localization. - */ - readonly i18n: any; - - /** - * Sets total amount that calculated from node children. - * @param {IBalanceSheetSection} node - * @returns {IBalanceSheetDataNode} - */ - private aggregateNodeTotalMapper = ( - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - return R.compose( - R.when( - this.query.isPreviousYearActive, - this.previousYearAggregateNodeComposer - ), - R.when( - this.query.isPreviousPeriodActive, - this.previousPeriodAggregateNodeComposer - ), - R.when( - this.query.isDatePeriodsColumnsType, - this.assocAggregateNodeDatePeriods - ) - )(node); - }; - - /** - * Mappes the aggregate schema node type. - * @param {IBalanceSheetSchemaAggregateNode} node - Schema node. - * @return {IBalanceSheetAggregateNode} - */ - private reportSchemaAggregateNodeMapper = ( - node: IBalanceSheetSchemaAggregateNode - ): IBalanceSheetAggregateNode => { - const total = this.getTotalOfNodes(node.children); - - return { - name: this.i18n.__(node.name), - id: node.id, - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE, - total: this.getTotalAmountMeta(total), - children: node.children, - }; - }; - - /** - * Compose shema aggregate node of balance sheet schema. - * @param {IBalanceSheetSchemaAggregateNode} node - * @returns {IBalanceSheetSchemaAggregateNode} - */ - private schemaAggregateNodeCompose = ( - node: IBalanceSheetSchemaAggregateNode - ) => { - return R.compose( - this.aggregateNodeTotalMapper, - this.reportSchemaAggregateNodeMapper - )(node); - }; - - /** - * Mappes the given report schema node. - * @param {IBalanceSheetSchemaNode} node - Schema node. - * @return {IBalanceSheetDataNode} - */ - private reportAggregateSchemaParser = ( - node: IBalanceSheetSchemaNode - ): IBalanceSheetDataNode => { - return R.compose( - R.when( - this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE), - this.schemaAggregateNodeCompose - ), - R.when( - this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS), - this.schemaAggregateNodeCompose - ) - )(node); - }; - - /** - * Mappes the report schema nodes. - * @param {IBalanceSheetSchemaNode[]} nodes - - * @return {IBalanceSheetStructureSection[]} - */ - public aggregatesSchemaParser = ( - nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[] - ): (IBalanceSheetDataNode | IBalanceSheetSchemaNode)[] => { - return this.mapNodesDeepReverse(nodes, this.reportAggregateSchemaParser); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts deleted file mode 100644 index 0c965a5f5..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IBalanceSheetQuery } from '@/interfaces'; -import { BalanceSheetExportInjectable } from './BalanceSheetExportInjectable'; -import { BalanceSheetTableInjectable } from './BalanceSheetTableInjectable'; -import BalanceSheetStatementService from './BalanceSheetInjectable'; - -@Service() -export class BalanceSheetApplication { - @Inject() - public balanceSheetExport: BalanceSheetExportInjectable; - - @Inject() - public balanceSheetTable: BalanceSheetTableInjectable; - - @Inject() - public balanceSheet: BalanceSheetStatementService; - - /** - * Retrieves the balnace sheet in json format. - * @param {numnber} tenantId - * @param {IBalanceSheetQuery} query - * @returns {Promise} - */ - public sheet(tenantId: number, query: IBalanceSheetQuery) { - return this.balanceSheet.balanceSheet(tenantId, query); - } - - /** - * Retrieves the balance sheet in table format. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @returns {Promise} - */ - public table(tenantId: number, query: IBalanceSheetQuery) { - return this.balanceSheetTable.table(tenantId, query); - } - - /** - * Retrieves the balance sheet in XLSX format. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @returns {Promise} - */ - public xlsx(tenantId: number, query: IBalanceSheetQuery) { - return this.balanceSheetExport.xlsx(tenantId, query); - } - - /** - * Retrieves the balance sheet in CSV format. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @returns {Promise} - */ - public csv(tenantId: number, query: IBalanceSheetQuery): Promise { - return this.balanceSheetExport.csv(tenantId, query); - } - - /** - * Retrieves the balance sheet in pdf format. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IBalanceSheetQuery) { - return this.balanceSheetExport.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetBase.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetBase.ts deleted file mode 100644 index 9089f0364..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetBase.ts +++ /dev/null @@ -1,32 +0,0 @@ -import * as R from 'ramda'; -import { IBalanceSheetDataNode, IBalanceSheetSchemaNode } from '@/interfaces'; - -export const BalanceSheetBase = (Base) => - class extends Base { - /** - * Detarmines the node type of the given schema node. - * @param {IBalanceSheetStructureSection} node - - * @param {string} type - - * @return {boolean} - */ - protected isSchemaNodeType = R.curry( - (type: string, node: IBalanceSheetSchemaNode): boolean => { - return node.type === type; - } - ); - - isNodeType = R.curry( - (type: string, node: IBalanceSheetDataNode): boolean => { - return node.nodeType === type; - } - ); - - /** - * Detarmines the given display columns by type. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - protected isDisplayColumnsBy = (displayColumnsBy: string): boolean => { - return this.query.displayColumnsType === displayColumnsBy; - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts deleted file mode 100644 index 951176b74..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousPeriod.ts +++ /dev/null @@ -1,268 +0,0 @@ -import * as R from 'ramda'; -import { sumBy } from 'lodash'; -import { - IBalanceSheetAccountNode, - IBalanceSheetDataNode, - IBalanceSheetAggregateNode, - IBalanceSheetTotal, - IBalanceSheetCommonNode, - IBalanceSheetComparsions, -} from '@/interfaces'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; - -export const BalanceSheetComparsionPreviousPeriod = (Base: any) => - class - extends R.compose(FinancialPreviousPeriod, FinancialHorizTotals)(Base) - implements IBalanceSheetComparsions - { - // ------------------------------ - // # Account - // ------------------------------ - /** - * Associates the previous period to account node. - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocPreviousPeriodAccountNode = ( - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - const total = this.repository.PPTotalAccountsLedger.whereAccountId( - node.id - ).getClosingBalance(); - - return R.assoc('previousPeriod', this.getAmountMeta(total), node); - }; - - /** - * Previous period account node composer. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected previousPeriodAccountNodeComposer = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreivousPeriodAccountHorizNodeComposer - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodChangeNode - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodAccountNode - ) - )(node); - }; - - // ------------------------------ - // # Aggregate - // ------------------------------ - /** - * Assoc previous period total to aggregate node. - * @param {IBalanceSheetAggregateNode} node - * @returns {IBalanceSheetAggregateNode} - */ - protected assocPreviousPeriodAggregateNode = ( - node: IBalanceSheetAggregateNode - ): IBalanceSheetAggregateNode => { - const total = sumBy(node.children, 'previousYear.amount'); - - return R.assoc('previousPeriod', this.getTotalAmountMeta(total), node); - }; - - /** - * Previous period aggregate node composer. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected previousPeriodAggregateNodeComposer = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousPeriodAggregateHorizNode - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodAggregateNode - ) - )(node); - }; - - // ------------------------------ - // # Horizontal Nodes - Account. - // ------------------------------ - /** - * Retrieve the given account total in the given period. - * @param {number} accountId - Account id. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @returns {number} - */ - private getAccountPPDatePeriodTotal = R.curry( - (accountId: number, fromDate: Date, toDate: Date): number => { - const PPPeriodsTotal = - this.repository.PPPeriodsAccountsLedger.whereAccountId(accountId) - .whereToDate(toDate) - .getClosingBalance(); - - const PPPeriodsOpeningTotal = - this.repository.PPPeriodsOpeningAccountLedger.whereAccountId( - accountId - ).getClosingBalance(); - - return PPPeriodsOpeningTotal + PPPeriodsTotal; - } - ); - - /** - * Assoc preivous period to account horizontal total node. - * @param {IBalanceSheetAccountNode} node - * @returns {} - */ - private assocPreviousPeriodAccountHorizTotal = R.curry( - (node: IBalanceSheetAccountNode, totalNode) => { - const total = this.getAccountPPDatePeriodTotal( - node.id, - totalNode.previousPeriodFromDate.date, - totalNode.previousPeriodToDate.date - ); - return R.assoc('previousPeriod', this.getAmountMeta(total), totalNode); - } - ); - - /** - * Previous year account horizontal node composer. - * @param {IBalanceSheetAccountNode} node - - * @param {IBalanceSheetTotal} - * @returns {IBalanceSheetTotal} - */ - private previousPeriodAccountHorizNodeCompose = R.curry( - ( - node: IBalanceSheetAccountNode, - horizontalTotalNode: IBalanceSheetTotal - ): IBalanceSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodChangeNode - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodAccountHorizTotal(node) - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodHorizNodeFromToDates( - this.query.displayColumnsBy - ) - ) - )(horizontalTotalNode); - } - ); - - /** - * - * @param {IBalanceSheetAccountNode} node - * @returns - */ - private assocPreivousPeriodAccountHorizNodeComposer = ( - node: IBalanceSheetAccountNode - ) => { - const horizontalTotals = R.map( - this.previousPeriodAccountHorizNodeCompose(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ------------------------------ - // # Horizontal Nodes - Aggregate - // ------------------------------ - /** - * Assoc previous year total to horizontal node. - * @param node - * @returns - */ - private assocPreviousPeriodAggregateHorizTotalNode = R.curry( - (node, index: number, totalNode) => { - const total = this.getPPHorizNodesTotalSumation(index, node); - - return R.assoc( - 'previousPeriod', - this.getTotalAmountMeta(total), - totalNode - ); - } - ); - - /** - * Compose previous period to aggregate horizontal nodes. - * @param {IBalanceSheetTotal} node - * @returns {IBalanceSheetTotal} - */ - private previousPeriodAggregateHorizNodeComposer = R.curry( - ( - node: IBalanceSheetCommonNode, - horiontalTotalNode: IBalanceSheetTotal, - index: number - ): IBalanceSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodAggregateHorizTotalNode(node, index) - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodHorizNodeFromToDates( - this.query.displayColumnsBy - ) - ) - )(horiontalTotalNode); - } - ); - - /** - * Assoc - * @param {IBalanceSheetCommonNode} node - * @returns {IBalanceSheetCommonNode} - */ - private assocPreviousPeriodAggregateHorizNode = ( - node: IBalanceSheetCommonNode - ) => { - const horizontalTotals = R.addIndex(R.map)( - this.previousPeriodAggregateHorizNodeComposer(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousYear.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousYear.ts deleted file mode 100644 index d48d44a6d..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetComparsionPreviousYear.ts +++ /dev/null @@ -1,266 +0,0 @@ -import * as R from 'ramda'; -import { sumBy, isEmpty } from 'lodash'; -import { - IBalanceSheetAccountNode, - IBalanceSheetCommonNode, - IBalanceSheetDataNode, - IBalanceSheetTotal, - ITableColumn, -} from '@/interfaces'; -import { FinancialPreviousYear } from '../FinancialPreviousYear'; - -export const BalanceSheetComparsionPreviousYear = (Base: any) => - class extends R.compose(FinancialPreviousYear)(Base) { - // ------------------------------ - // # Account - // ------------------------------ - /** - * Associates the previous year to account node. - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocPreviousYearAccountNode = ( - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - const closingBalance = - this.repository.PYTotalAccountsLedger.whereAccountId( - node.id - ).getClosingBalance(); - - return R.assoc('previousYear', this.getAmountMeta(closingBalance), node); - }; - - /** - * Assoc previous year attributes to account node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected previousYearAccountNodeComposer = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizontalTotals, - this.assocPreviousYearAccountHorizNodeComposer - ), - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearChangetNode - ), - this.assocPreviousYearAccountNode - )(node); - }; - - // ------------------------------ - // # Aggregate - // ------------------------------ - /** - * Assoc previous year on aggregate node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected assocPreviousYearAggregateNode = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetAccountNode => { - const total = sumBy(node.children, 'previousYear.amount'); - - return R.assoc('previousYear', this.getTotalAmountMeta(total), node); - }; - - /** - * Assoc previous year attributes to aggregate node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected previousYearAggregateNodeComposer = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetAccountNode => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - R.when( - this.isNodeHasHorizontalTotals, - this.assocPreviousYearAggregateHorizNode - ), - this.assocPreviousYearAggregateNode - )(node); - }; - - // ------------------------------ - // # Horizontal Nodes - Aggregate - // ------------------------------ - /** - * Assoc previous year total to horizontal node. - * @param node - * @returns - */ - private assocPreviousYearAggregateHorizTotalNode = R.curry( - (node, index, totalNode) => { - const total = this.getPYHorizNodesTotalSumation(index, node); - - return R.assoc( - 'previousYear', - this.getTotalAmountMeta(total), - totalNode - ); - } - ); - - /** - * Compose previous year to aggregate horizontal nodes. - * @param {IBalanceSheetTotal} node - * @returns {IBalanceSheetTotal} - */ - private previousYearAggregateHorizNodeComposer = R.curry( - ( - node: IBalanceSheetCommonNode, - horiontalTotalNode: IBalanceSheetTotal, - index: number - ): IBalanceSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearAggregateHorizTotalNode(node, index) - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearHorizNodeFromToDates - ) - )(horiontalTotalNode); - } - ); - - /** - * Assoc - * @param {IBalanceSheetCommonNode} node - * @returns {IBalanceSheetCommonNode} - */ - public assocPreviousYearAggregateHorizNode = ( - node: IBalanceSheetCommonNode - ): IBalanceSheetCommonNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousYearAggregateHorizNodeComposer(node), - node.horizontalTotals - ) as IBalanceSheetTotal[]; - - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ------------------------------ - // # Horizontal Nodes - Account. - // ------------------------------ - /** - * Retrieve the given account total in the given period. - * @param {number} accountId - Account id. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @returns {number} - */ - private getAccountPYDatePeriodTotal = R.curry( - (accountId: number, fromDate: Date, toDate: Date): number => { - const PYPeriodsTotal = - this.repository.PYPeriodsAccountsLedger.whereAccountId(accountId) - .whereToDate(toDate) - .getClosingBalance(); - - const PYPeriodsOpeningTotal = - this.repository.PYPeriodsOpeningAccountLedger.whereAccountId( - accountId - ).getClosingBalance(); - - return PYPeriodsOpeningTotal + PYPeriodsTotal; - } - ); - - /** - * Assoc preivous year to account horizontal total node. - * @param {IBalanceSheetAccountNode} node - * @returns {} - */ - private assocPreviousYearAccountHorizTotal = R.curry( - (node: IBalanceSheetAccountNode, totalNode) => { - const total = this.getAccountPYDatePeriodTotal( - node.id, - totalNode.previousYearFromDate.date, - totalNode.previousYearToDate.date - ); - return R.assoc('previousYear', this.getAmountMeta(total), totalNode); - } - ); - - /** - * Previous year account horizontal node composer. - * @param {IBalanceSheetAccountNode} node - - * @param {IBalanceSheetTotal} - * @returns {IBalanceSheetTotal} - */ - private previousYearAccountHorizNodeCompose = R.curry( - ( - node: IBalanceSheetAccountNode, - horizontalTotalNode: IBalanceSheetTotal - ): IBalanceSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearChangetNode - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearAccountHorizTotal(node) - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearHorizNodeFromToDates - ) - )(horizontalTotalNode); - } - ); - - /** - * Assoc previous year horizontal nodes to account node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - private assocPreviousYearAccountHorizNodeComposer = ( - node: IBalanceSheetAccountNode - ) => { - const horizontalTotals = R.map( - this.previousYearAccountHorizNodeCompose(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ------------------------------ - // # Horizontal Nodes - Aggregate. - // ------------------------------ - /** - * Detarmines whether the given node has horizontal totals. - * @param {IBalanceSheetCommonNode} node - * @returns {boolean} - */ - public isNodeHasHorizontalTotals = (node: IBalanceSheetCommonNode) => - !isEmpty(node.horizontalTotals); - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetDatePeriods.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetDatePeriods.ts deleted file mode 100644 index 9ac6af1ce..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetDatePeriods.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as R from 'ramda'; -import { sumBy } from 'lodash'; -import { - IBalanceSheetQuery, - IFormatNumberSettings, - IBalanceSheetDatePeriods, - IBalanceSheetAccountNode, - IBalanceSheetTotalPeriod, - IDateRange, - IBalanceSheetCommonNode, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; - -/** - * Balance sheet date periods. - */ -export const BalanceSheetDatePeriods = (Base: FinancialSheet) => - class - extends R.compose(FinancialDatePeriods)(Base) - implements IBalanceSheetDatePeriods - { - /** - * @param {IBalanceSheetQuery} - */ - readonly query: IBalanceSheetQuery; - - /** - * Retrieves the date periods based on the report query. - * @returns {IDateRange[]} - */ - get datePeriods(): IDateRange[] { - return this.getDateRanges( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy - ); - } - - /** - * Retrieves the date periods of the given node based on the report query. - * @param {IBalanceSheetCommonNode} node - * @param {Function} callback - * @returns {} - */ - protected getReportNodeDatePeriods = ( - node: IBalanceSheetCommonNode, - callback: ( - node: IBalanceSheetCommonNode, - fromDate: Date, - toDate: Date, - index: number - ) => any - ) => { - return this.getNodeDatePeriods( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy, - node, - callback - ); - }; - - /** - * Retrieve the date period meta. - * @param {number} total - Total amount. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - private getDatePeriodTotalMeta = ( - total: number, - fromDate: Date, - toDate: Date, - overrideSettings: IFormatNumberSettings = {} - ): IBalanceSheetTotalPeriod => { - return this.getDatePeriodMeta(total, fromDate, toDate, { - money: true, - ...overrideSettings, - }); - }; - - // -------------------------------- - // # Account - // -------------------------------- - /** - * Retrieve the given account date period total. - * @param {number} accountId - * @param {Date} toDate - * @returns {number} - */ - private getAccountDatePeriodTotal = ( - accountId: number, - toDate: Date - ): number => { - const periodTotalBetween = this.repository.periodsAccountsLedger - .whereAccountId(accountId) - .whereToDate(toDate) - .getClosingBalance(); - - const periodOpening = this.repository.periodsOpeningAccountLedger - .whereAccountId(accountId) - .getClosingBalance(); - - return periodOpening + periodTotalBetween; - }; - - /** - * - * @param {IBalanceSheetAccountNode} node - * @param {Date} fromDate - * @param {Date} toDate - * @returns {IBalanceSheetAccountNode} - */ - private getAccountNodeDatePeriod = ( - node: IBalanceSheetAccountNode, - fromDate: Date, - toDate: Date - ): IBalanceSheetTotalPeriod => { - const periodTotal = this.getAccountDatePeriodTotal(node.id, toDate); - - return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate); - }; - - /** - * Retrieve total date periods of the given account node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - private getAccountsNodeDatePeriods = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetTotalPeriod[] => { - return this.getReportNodeDatePeriods(node, this.getAccountNodeDatePeriod); - }; - - /** - * Assoc total date periods to account node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - public assocAccountNodeDatePeriods = ( - node: IBalanceSheetAccountNode - ): IBalanceSheetAccountNode => { - const datePeriods = this.getAccountsNodeDatePeriods(node); - - return R.assoc('horizontalTotals', datePeriods, node); - }; - - // -------------------------------- - // # Aggregate - // -------------------------------- - /** - * - * @param {} node - * @param {number} index - * @returns {number} - */ - private getAggregateDatePeriodIndexTotal = (node, index) => { - return sumBy(node.children, `horizontalTotals[${index}].total.amount`); - }; - - /** - * - * @param {IBalanceSheetAccountNode} node - * @param {Date} fromDate - * @param {Date} toDate - * @returns - */ - public getAggregateNodeDatePeriod = ( - node: IBalanceSheetAccountNode, - fromDate: Date, - toDate: Date, - index: number - ) => { - const periodTotal = this.getAggregateDatePeriodIndexTotal(node, index); - - return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate); - }; - - /** - * - * @param node - * @returns - */ - public getAggregateNodeDatePeriods = (node) => { - return this.getReportNodeDatePeriods( - node, - this.getAggregateNodeDatePeriod - ); - }; - - /** - * Assoc total date periods to aggregate node. - * @param node - * @returns {} - */ - public assocAggregateNodeDatePeriods = (node) => { - const datePeriods = this.getAggregateNodeDatePeriods(node); - - return R.assoc('horizontalTotals', datePeriods, node); - }; - - /** - * - * @param node - * @returns - */ - public assocAccountsNodeDatePeriods = (node) => { - return this.assocAggregateNodeDatePeriods(node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts deleted file mode 100644 index 9198d8536..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { BalanceSheetTableInjectable } from './BalanceSheetTableInjectable'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { IBalanceSheetQuery } from '@/interfaces'; -import { BalanceSheetPdfInjectable } from './BalanceSheetPdfInjectable'; - -@Service() -export class BalanceSheetExportInjectable { - @Inject() - private balanceSheetTable: BalanceSheetTableInjectable; - - @Inject() - private balanceSheetPdf: BalanceSheetPdfInjectable; - - /** - * Retrieves the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IBalanceSheetQuery) { - const table = await this.balanceSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IBalanceSheetQuery - ): Promise { - const table = await this.balanceSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } - - /** - * Retrieves the balance sheet in pdf format. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IBalanceSheetQuery - ): Promise { - return this.balanceSheetPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetFiltering.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetFiltering.ts deleted file mode 100644 index 6aa80d78a..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetFiltering.ts +++ /dev/null @@ -1,167 +0,0 @@ -import * as R from 'ramda'; -import { get } from 'lodash'; -import { - IBalanceSheetDataNode, - BALANCE_SHEET_NODE_TYPE, -} from '../../../interfaces'; -import { FinancialFilter } from '../FinancialFilter'; - -export const BalanceSheetFiltering = (Base) => - class extends R.compose(FinancialFilter)(Base) { - // ----------------------- - // # Account - // ----------------------- - /** - * Filter report node detarmine. - * @param {IBalanceSheetDataNode} node - Balance sheet node. - * @return {boolean} - */ - private accountNoneZeroNodesFilterDetarminer = ( - node: IBalanceSheetDataNode - ): boolean => { - return R.ifElse( - this.isNodeType(BALANCE_SHEET_NODE_TYPE.ACCOUNT), - this.isNodeNoneZero, - R.always(true) - )(node); - }; - - /** - * Detarmines account none-transactions node. - * @param {IBalanceSheetDataNode} node - * @returns {boolean} - */ - private accountNoneTransFilterDetarminer = ( - node: IBalanceSheetDataNode - ): boolean => { - return R.ifElse( - this.isNodeType(BALANCE_SHEET_NODE_TYPE.ACCOUNT), - this.isNodeNoneZero, - R.always(true) - )(node); - }; - - /** - * Report nodes filter. - * @param {IBalanceSheetSection[]} nodes - - * @return {IBalanceSheetSection[]} - */ - private accountsNoneZeroNodesFilter = ( - nodes: IBalanceSheetDataNode[] - ): IBalanceSheetDataNode[] => { - return this.filterNodesDeep( - nodes, - this.accountNoneZeroNodesFilterDetarminer - ); - }; - - /** - * Filters the accounts none-transactions nodes. - * @param {IBalanceSheetDataNode[]} nodes - * @returns {IBalanceSheetDataNode[]} - */ - private accountsNoneTransactionsNodesFilter = ( - nodes: IBalanceSheetDataNode[] - ) => { - return this.filterNodesDeep(nodes, this.accountNoneTransFilterDetarminer); - }; - - // ----------------------- - // # Aggregate/Accounts. - // ----------------------- - /** - * Detearmines aggregate none-children filtering. - * @param {IBalanceSheetDataNode} node - * @returns {boolean} - */ - private aggregateNoneChildrenFilterDetarminer = ( - node: IBalanceSheetDataNode - ): boolean => { - // Detarmines whether the given node is aggregate or accounts node. - const isAggregateOrAccounts = - this.isNodeType(BALANCE_SHEET_NODE_TYPE.AGGREGATE, node) || - this.isNodeType(BALANCE_SHEET_NODE_TYPE.ACCOUNTS, node); - - // Retrieve the schema node of the given id. - const schemaNode = this.getSchemaNodeById(node.id); - - // Detarmines if the schema node is always should show. - const isSchemaAlwaysShow = get(schemaNode, 'alwaysShow', false); - - return isAggregateOrAccounts && !isSchemaAlwaysShow - ? this.isNodeHasChildren(node) - : true; - }; - - /** - * Filters aggregate none-children nodes. - * @param {IBalanceSheetDataNode[]} nodes - * @returns {IBalanceSheetDataNode[]} - */ - private aggregateNoneChildrenFilter = ( - nodes: IBalanceSheetDataNode[] - ): IBalanceSheetDataNode[] => { - return this.filterNodesDeep2( - this.aggregateNoneChildrenFilterDetarminer, - nodes - ); - }; - - // ----------------------- - // # Composers. - // ----------------------- - /** - * Filters none-zero nodes. - * @param {IBalanceSheetDataNode[]} nodes - * @returns {IBalanceSheetDataNode[]} - */ - private filterNoneZeroNodesCompose = ( - nodes: IBalanceSheetDataNode[] - ): IBalanceSheetDataNode[] => { - return R.compose( - this.aggregateNoneChildrenFilter, - this.accountsNoneZeroNodesFilter - )(nodes); - }; - - /** - * Filters none-transactions nodes. - * @param {IBalanceSheetDataNode[]} nodes - * @returns {IBalanceSheetDataNode[]} - */ - private filterNoneTransNodesCompose = ( - nodes: IBalanceSheetDataNode[] - ): IBalanceSheetDataNode[] => { - return R.compose( - this.aggregateNoneChildrenFilter, - this.accountsNoneTransactionsNodesFilter - )(nodes); - }; - - /** - * Supress nodes when accounts transactions ledger is empty. - * @param {IBalanceSheetDataNode[]} nodes - * @returns {IBalanceSheetDataNode[]} - */ - private supressNodesWhenAccountsTransactionsEmpty = ( - nodes: IBalanceSheetDataNode[] - ): IBalanceSheetDataNode[] => { - return this.repository.totalAccountsLedger.isEmpty() ? [] : nodes; - }; - - /** - * Compose report nodes filtering. - * @param {IBalanceSheetDataNode[]} nodes - * @returns {IBalanceSheetDataNode[]} - */ - protected reportFilterPlugin = (nodes: IBalanceSheetDataNode[]) => { - return R.compose( - this.supressNodesWhenAccountsTransactionsEmpty, - R.when(R.always(this.query.noneZero), this.filterNoneZeroNodesCompose), - R.when( - R.always(this.query.noneTransactions), - this.filterNoneTransNodesCompose - ) - )(nodes); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetInjectable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetInjectable.ts deleted file mode 100644 index 1e5b845d6..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetInjectable.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { - IBalanceSheetStatementService, - IBalanceSheetQuery, - IBalanceSheetStatement, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import BalanceSheetStatement from './BalanceSheet'; -import { Tenant } from '@/system/models'; -import BalanceSheetRepository from './BalanceSheetRepository'; -import { BalanceSheetMetaInjectable } from './BalanceSheetMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export default class BalanceSheetStatementService - implements IBalanceSheetStatementService -{ - @Inject() - private tenancy: TenancyService; - - @Inject() - private balanceSheetMeta: BalanceSheetMetaInjectable; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - get defaultQuery(): IBalanceSheetQuery { - return { - displayColumnsType: 'total', - displayColumnsBy: 'month', - - fromDate: moment().startOf('year').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - noneZero: false, - noneTransactions: false, - - basis: 'cash', - accountIds: [], - - percentageOfColumn: false, - percentageOfRow: false, - - previousPeriod: false, - previousPeriodAmountChange: false, - previousPeriodPercentageChange: false, - - previousYear: false, - previousYearAmountChange: false, - previousYearPercentageChange: false, - }; - } - - /** - * Retrieve balance sheet statement. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @return {IBalanceSheetStatement} - */ - public async balanceSheet( - tenantId: number, - query: IBalanceSheetQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const models = this.tenancy.models(tenantId); - const balanceSheetRepo = new BalanceSheetRepository(models, filter); - - // Loads all resources. - await balanceSheetRepo.asyncInitialize(); - - // Balance sheet report instance. - const balanceSheetInstanace = new BalanceSheetStatement( - filter, - balanceSheetRepo, - tenant.metadata.baseCurrency, - i18n - ); - // Balance sheet data. - const data = balanceSheetInstanace.reportData(); - - // Balance sheet meta. - const meta = await this.balanceSheetMeta.meta(tenantId, filter); - - // Triggers `onBalanceSheetViewed` event. - await this.eventPublisher.emitAsync(events.reports.onBalanceSheetViewed, { - query, - }); - return { - query: filter, - data, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetMeta.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetMeta.ts deleted file mode 100644 index c7a3e87c0..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetMeta.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { IBalanceSheetMeta, IBalanceSheetQuery } from '@/interfaces'; -import moment from 'moment'; - -@Service() -export class BalanceSheetMetaInjectable { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the balance sheet meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IBalanceSheetQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedAsDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedDateRange = `As ${formattedAsDate}`; - const sheetName = 'Balance Sheet Statement'; - - return { - ...commonMeta, - sheetName, - formattedAsDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncome.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncome.ts deleted file mode 100644 index a6695b370..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncome.ts +++ /dev/null @@ -1,226 +0,0 @@ -import * as R from 'ramda'; -import { - BALANCE_SHEET_SCHEMA_NODE_TYPE, - IBalanceSheetDataNode, - IBalanceSheetNetIncomeNode, - IBalanceSheetSchemaNetIncomeNode, - IBalanceSheetSchemaNode, - IBalanceSheetTotalPeriod, -} from '@/interfaces'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; -import BalanceSheetRepository from './BalanceSheetRepository'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { BalanceSheetNetIncomePP } from './BalanceSheetNetIncomePP'; -import { BalanceSheetNetIncomePY } from './BalanceSheetNetIncomePY'; - -export const BalanceSheetNetIncome = (Base: any) => - class extends R.compose( - BalanceSheetNetIncomePP, - BalanceSheetNetIncomePY, - BalanceSheetComparsionPreviousYear, - BalanceSheetComparsionPreviousPeriod, - FinancialPreviousPeriod, - FinancialHorizTotals - )(Base) { - private repository: BalanceSheetRepository; - private query: BalanceSheetQuery; - - /** - * Retrieves the closing balance of income accounts. - * @returns {number} - */ - private getIncomeTotal = () => { - const closeingBalance = this.repository.incomeLedger.getClosingBalance(); - return closeingBalance; - }; - - /** - * Retrieves the closing balance of expenses accounts. - * @returns {number} - */ - private getExpensesTotal = () => { - const closingBalance = this.repository.expensesLedger.getClosingBalance(); - return closingBalance; - }; - - /** - * Retrieves the total net income. - * @returns {number} - */ - protected getNetIncomeTotal = () => { - const income = this.getIncomeTotal(); - const expenses = this.getExpensesTotal(); - - return income - expenses; - }; - - /** - * Mappes the aggregate schema node type. - * @param {IBalanceSheetSchemaNetIncomeNode} node - Schema node. - * @return {IBalanceSheetAggregateNode} - */ - protected schemaNetIncomeNodeMapper = ( - node: IBalanceSheetSchemaNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - const total = this.getNetIncomeTotal(); - - return { - id: node.id, - name: this.i18n.__(node.name), - nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME, - total: this.getTotalAmountMeta(total), - }; - }; - - /** - * Mapps the net income shcema node to report node. - * @param {IBalanceSheetSchemaNetIncomeNode} node - * @returns {IBalanceSheetNetIncomeNode} - */ - protected schemaNetIncomeNodeCompose = ( - node: IBalanceSheetSchemaNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - return R.compose( - R.when( - this.query.isPreviousYearActive, - this.previousYearNetIncomeNodeCompose - ), - R.when( - this.query.isPreviousPeriodActive, - this.previousPeriodNetIncomeNodeCompose - ), - R.when( - this.query.isDatePeriodsColumnsType, - this.assocNetIncomeDatePeriodsNode - ), - this.schemaNetIncomeNodeMapper - )(node); - }; - - // -------------------------------- - // # Date Periods - // -------------------------------- - /** - * Retreives total income of the given date period. - * @param {number} accountId - - * @param {Date} toDate - - * @returns {number} - */ - private getIncomeDatePeriodTotal = (toDate: Date): number => { - const periodTotalBetween = this.repository.incomePeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const periodOpening = - this.repository.incomePeriodsOpeningAccountsLedger.getClosingBalance(); - - return periodOpening + periodTotalBetween; - }; - - /** - * Retrieves total expense of the given date period. - * @param {number} accountId - - * @param {Date} toDate - - * @returns {number} - */ - private getExpensesDatePeriodTotal = (toDate: Date): number => { - const periodTotalBetween = this.repository.expensesPeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const periodOpening = - this.repository.expensesOpeningAccountLedger.getClosingBalance(); - - return periodOpening + periodTotalBetween; - }; - - /** - * Retrieve the given net income date period total. - * @param {number} accountId - * @param {Date} toDate - * @returns {number} - */ - private getNetIncomeDatePeriodTotal = (toDate: Date): number => { - const income = this.getIncomeDatePeriodTotal(toDate); - const expense = this.getExpensesDatePeriodTotal(toDate); - - return income - expense; - }; - - /** - * Retrieves the net income date period node. - * @param {IBalanceSheetNetIncomeNode} node - * @param {Date} fromDate - * @param {Date} toDate - * @returns {IBalanceSheetNetIncomeNode} - */ - private getNetIncomeDatePeriodNode = ( - node: IBalanceSheetNetIncomeNode, - fromDate: Date, - toDate: Date - ): IBalanceSheetTotalPeriod => { - const periodTotal = this.getNetIncomeDatePeriodTotal(toDate); - - return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate); - }; - - /** - * Retrieve total date periods of the given net income node. - * @param {IBalanceSheetNetIncomeNode} node - * @returns {IBalanceSheetNetIncomeNode} - */ - private getNetIncomeDatePeriodsNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetTotalPeriod[] => { - return this.getReportNodeDatePeriods( - node, - this.getNetIncomeDatePeriodNode - ); - }; - - /** - * Assoc total date periods to net income node. - * @param {IBalanceSheetNetIncomeNode} node - * @returns {IBalanceSheetNetIncomeNode} - */ - public assocNetIncomeDatePeriodsNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - const datePeriods = this.getNetIncomeDatePeriodsNode(node); - - return R.assoc('horizontalTotals', datePeriods, node); - }; - - // ----------------------------- - // - Net Income Nodes Praser - // ----------------------------- - /** - * Mappes the given report schema node. - * @param {IBalanceSheetSchemaNode} node - Schema node. - * @return {IBalanceSheetDataNode} - */ - private reportNetIncomeNodeSchemaParser = ( - schemaNode: IBalanceSheetSchemaNode - ): IBalanceSheetDataNode => { - return R.compose( - R.when( - this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME), - this.schemaNetIncomeNodeCompose - ) - )(schemaNode); - }; - - /** - * Parses the report net income schema nodes. - * @param {(IBalanceSheetSchemaNode | IBalanceSheetDataNode)[]} nodes - - * @return {IBalanceSheetDataNode[]} - */ - public netIncomeSchemaParser = ( - nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[] - ): IBalanceSheetDataNode[] => { - return this.mapNodesDeep(nodes, this.reportNetIncomeNodeSchemaParser); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts deleted file mode 100644 index 63bfa362a..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriods.ts +++ /dev/null @@ -1,120 +0,0 @@ -import * as R from 'ramda'; -import { - IBalanceSheetNetIncomeNode, - IBalanceSheetTotalPeriod, -} from '@/interfaces'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; -import BalanceSheetRepository from './BalanceSheetRepository'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { BalanceSheetNetIncomePP } from './BalanceSheetNetIncomePP'; -import { BalanceSheetNetIncomePY } from './BalanceSheetNetIncomePY'; - -export const BalanceSheetNetIncomeDatePeriods = (Base: any) => - class extends R.compose( - BalanceSheetNetIncomePP, - BalanceSheetNetIncomePY, - BalanceSheetComparsionPreviousYear, - BalanceSheetComparsionPreviousPeriod, - FinancialPreviousPeriod, - FinancialHorizTotals - )(Base) { - private repository: BalanceSheetRepository; - private query: BalanceSheetQuery; - - // -------------------------------- - // # Date Periods - // -------------------------------- - /** - * Retreives total income of the given date period. - * @param {number} accountId - - * @param {Date} toDate - - * @returns {number} - */ - private getIncomeDatePeriodTotal = (toDate: Date): number => { - const periodTotalBetween = this.repository.incomePeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const periodOpening = - this.repository.incomePeriodsOpeningAccountsLedger.getClosingBalance(); - - return periodOpening + periodTotalBetween; - }; - - /** - * Retrieves total expense of the given date period. - * @param {number} accountId - - * @param {Date} toDate - - * @returns {number} - */ - private getExpensesDatePeriodTotal = (toDate: Date): number => { - const periodTotalBetween = this.repository.expensesPeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const periodOpening = - this.repository.expensesOpeningAccountLedger.getClosingBalance(); - - return periodOpening + periodTotalBetween; - }; - - /** - * Retrieve the given net income date period total. - * @param {number} accountId - * @param {Date} toDate - * @returns {number} - */ - private getNetIncomeDatePeriodTotal = (toDate: Date): number => { - const income = this.getIncomeDatePeriodTotal(toDate); - const expense = this.getExpensesDatePeriodTotal(toDate); - - return income - expense; - }; - - /** - * Retrieves the net income date period node. - * @param {IBalanceSheetNetIncomeNode} node - * @param {Date} fromDate - * @param {Date} toDate - * @returns {IBalanceSheetNetIncomeNode} - */ - private getNetIncomeDatePeriodNode = ( - node: IBalanceSheetNetIncomeNode, - fromDate: Date, - toDate: Date - ): IBalanceSheetTotalPeriod => { - const periodTotal = this.getNetIncomeDatePeriodTotal(toDate); - - return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate); - }; - - /** - * Retrieve total date periods of the given net income node. - * @param {IBalanceSheetNetIncomeNode} node - * @returns {IBalanceSheetNetIncomeNode} - */ - private getNetIncomeDatePeriodsNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetTotalPeriod[] => { - return this.getReportNodeDatePeriods( - node, - this.getNetIncomeDatePeriodNode - ); - }; - - /** - * Assoc total date periods to net income node. - * @param {IBalanceSheetNetIncomeNode} node - * @returns {IBalanceSheetNetIncomeNode} - */ - public assocNetIncomeDatePeriodsNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - const datePeriods = this.getNetIncomeDatePeriodsNode(node); - - return R.assoc('horizontalTotals', datePeriods, node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts deleted file mode 100644 index 94038de38..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPP.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as R from 'ramda'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; -import { IBalanceSheetNetIncomeNode, IBalanceSheetTotal } from '@/interfaces'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import BalanceSheetRepository from './BalanceSheetRepository'; - -export const BalanceSheetNetIncomeDatePeriodsPP = (Base: any) => - class extends R.compose( - BalanceSheetComparsionPreviousPeriod, - FinancialPreviousPeriod, - FinancialHorizTotals - )(Base) { - query: BalanceSheetQuery; - repository: BalanceSheetRepository; - - /** - * Retrieves the PY total income of the given date period. - * @param {number} accountId - - * @param {Date} toDate - - * @return {number} - */ - private getPPIncomeDatePeriodTotal = R.curry((toDate: Date) => { - const PYPeriodsTotal = this.repository.incomePPPeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const PYPeriodsOpeningTotal = - this.repository.incomePPPeriodsOpeningAccountLedger.getClosingBalance(); - - return PYPeriodsOpeningTotal + PYPeriodsTotal; - }); - - /** - * Retrieves the PY total expense of the given date period. - * @param {number} accountId - - * @param {Date} toDate - - * @returns {number} - */ - private getPPExpenseDatePeriodTotal = R.curry((toDate: Date) => { - const PYPeriodsTotal = this.repository.expensePPPeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const PYPeriodsOpeningTotal = - this.repository.expensePPPeriodsOpeningAccountLedger.getClosingBalance(); - - return PYPeriodsOpeningTotal + PYPeriodsTotal; - }); - - /** - * Retrieve the given net income total of the given period. - * @param {number} accountId - Account id. - * @param {Date} toDate - To date. - * @returns {number} - */ - private getPPNetIncomeDatePeriodTotal = R.curry((toDate: Date) => { - const income = this.getPPIncomeDatePeriodTotal(toDate); - const expense = this.getPPExpenseDatePeriodTotal(toDate); - - return income - expense; - }); - - /** - * Assoc preivous period to account horizontal total node. - * @param {IBalanceSheetAccountNode} node - * @returns {} - */ - private assocPreviousPeriodNetIncomeHorizTotal = R.curry( - (node: IBalanceSheetNetIncomeNode, totalNode) => { - const total = this.getPPNetIncomeDatePeriodTotal( - totalNode.previousPeriodToDate.date - ); - return R.assoc('previousPeriod', this.getAmountMeta(total), totalNode); - } - ); - - /** - * Compose previous period to aggregate horizontal nodes. - * @param {IBalanceSheetTotal} node - * @returns {IBalanceSheetTotal} - */ - private previousPeriodNetIncomeHorizNodeComposer = R.curry( - ( - node: IBalanceSheetNetIncomeNode, - horiontalTotalNode: IBalanceSheetTotal - ): IBalanceSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodNetIncomeHorizTotal(node) - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodHorizNodeFromToDates( - this.query.displayColumnsBy - ) - ) - )(horiontalTotalNode); - } - ); - - /** - * Associate the PP to net income horizontal nodes. - * @param {IBalanceSheetCommonNode} node - * @returns {IBalanceSheetCommonNode} - */ - public assocPreviousPeriodNetIncomeHorizNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousPeriodNetIncomeHorizNodeComposer(node), - node.horizontalTotals - ) as IBalanceSheetTotal[]; - - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts deleted file mode 100644 index 3e4a289e9..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomeDatePeriodsPY.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as R from 'ramda'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; -import { IBalanceSheetNetIncomeNode, IBalanceSheetTotal } from '@/interfaces'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import BalanceSheetRepository from './BalanceSheetRepository'; - -export const BalanceSheetNetIncomeDatePeriodsPY = (Base: any) => - class extends R.compose( - BalanceSheetComparsionPreviousYear, - FinancialPreviousPeriod, - FinancialHorizTotals - )(Base) { - query: BalanceSheetQuery; - repository: BalanceSheetRepository; - - /** - * Retrieves the PY total income of the given date period. - * @param {Date} toDate - - * @return {number} - */ - private getPYIncomeDatePeriodTotal = R.curry((toDate: Date) => { - const PYPeriodsTotal = this.repository.incomePYPeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const PYPeriodsOpeningTotal = - this.repository.incomePYPeriodsOpeningAccountLedger.getClosingBalance(); - - return PYPeriodsOpeningTotal + PYPeriodsTotal; - }); - - /** - * Retrieves the PY total expense of the given date period. - * @param {Date} toDate - - * @returns {number} - */ - private getPYExpenseDatePeriodTotal = R.curry((toDate: Date) => { - const PYPeriodsTotal = this.repository.expensePYPeriodsAccountsLedger - .whereToDate(toDate) - .getClosingBalance(); - - const PYPeriodsOpeningTotal = - this.repository.expensePYPeriodsOpeningAccountLedger.getClosingBalance(); - - return PYPeriodsOpeningTotal + PYPeriodsTotal; - }); - - /** - * Retrieve the given net income total of the given period. - * @param {Date} toDate - To date. - * @returns {number} - */ - private getPYNetIncomeDatePeriodTotal = R.curry((toDate: Date) => { - const income = this.getPYIncomeDatePeriodTotal(toDate); - const expense = this.getPYExpenseDatePeriodTotal(toDate); - - return income - expense; - }); - - /** - * Assoc preivous year to account horizontal total node. - * @param {IBalanceSheetAccountNode} node - * @returns {} - */ - private assocPreviousYearNetIncomeHorizTotal = R.curry( - (node: IBalanceSheetNetIncomeNode, totalNode) => { - const total = this.getPYNetIncomeDatePeriodTotal( - totalNode.previousYearToDate.date - ); - return R.assoc('previousYear', this.getAmountMeta(total), totalNode); - } - ); - - /** - * Compose PY to net income horizontal nodes. - * @param {IBalanceSheetTotal} node - * @returns {IBalanceSheetTotal} - */ - private previousYearNetIncomeHorizNodeComposer = R.curry( - ( - node: IBalanceSheetNetIncomeNode, - horiontalTotalNode: IBalanceSheetTotal - ): IBalanceSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearNetIncomeHorizTotal(node) - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearHorizNodeFromToDates - ) - )(horiontalTotalNode); - } - ); - - /** - * Associate the PY to net income horizontal nodes. - * @param {IBalanceSheetCommonNode} node - * @returns {IBalanceSheetCommonNode} - */ - public assocPreviousYearNetIncomeHorizNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousYearNetIncomeHorizNodeComposer(node), - node.horizontalTotals - ) as IBalanceSheetTotal[]; - - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePP.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePP.ts deleted file mode 100644 index c377511a3..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePP.ts +++ /dev/null @@ -1,75 +0,0 @@ -import * as R from 'ramda'; -import { - IBalanceSheetDataNode, - IBalanceSheetNetIncomeNode, -} from '@/interfaces'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; -import BalanceSheetRepository from './BalanceSheetRepository'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { BalanceSheetNetIncomeDatePeriodsPP } from './BalanceSheetNetIncomeDatePeriodsPP'; - -export const BalanceSheetNetIncomePP = (Base: any) => - class extends R.compose( - BalanceSheetNetIncomeDatePeriodsPP, - BalanceSheetComparsionPreviousPeriod, - FinancialPreviousPeriod, - FinancialHorizTotals - )(Base) { - private repository: BalanceSheetRepository; - private query: BalanceSheetQuery; - - // ------------------------------- - // # Previous Period (PP) - // ------------------------------- - /** - * Retrieves the PP net income. - * @returns {} - */ - protected getPreviousPeriodNetIncome = () => { - const income = this.repository.incomePPAccountsLedger.getClosingBalance(); - const expense = - this.repository.expensePPAccountsLedger.getClosingBalance(); - - return income - expense; - }; - - /** - * Associates the previous period to account node. - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocPreviousPeriodNetIncomeNode = ( - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - const total = this.getPreviousPeriodNetIncome(); - - return R.assoc('previousPeriod', this.getAmountMeta(total), node); - }; - - /** - * Previous period account node composer. - * @param {IBalanceSheetNetIncomeNode} node - * @returns {IBalanceSheetNetIncomeNode} - */ - protected previousPeriodNetIncomeNodeCompose = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousPeriodNetIncomeHorizNode - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodChangeNode - ), - this.assocPreviousPeriodNetIncomeNode - )(node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePY.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePY.ts deleted file mode 100644 index 29d57813c..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetNetIncomePY.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as R from 'ramda'; -import { - IBalanceSheetDataNode, - IBalanceSheetNetIncomeNode, -} from '@/interfaces'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; -import BalanceSheetRepository from './BalanceSheetRepository'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { BalanceSheetNetIncomeDatePeriodsPY } from './BalanceSheetNetIncomeDatePeriodsPY'; - -export const BalanceSheetNetIncomePY = (Base: any) => - class extends R.compose( - BalanceSheetNetIncomeDatePeriodsPY, - BalanceSheetComparsionPreviousYear, - BalanceSheetComparsionPreviousPeriod, - FinancialPreviousPeriod, - FinancialHorizTotals - )(Base) { - private repository: BalanceSheetRepository; - private query: BalanceSheetQuery; - - // ------------------------------ - // # Previous Year (PY) - // ------------------------------ - /** - * Retrieves the previous year (PY) net income. - * @returns {number} - */ - protected getPreviousYearNetIncome = () => { - const income = - this.repository.incomePYTotalAccountsLedger.getClosingBalance(); - const expense = - this.repository.expensePYTotalAccountsLedger.getClosingBalance(); - - return income - expense; - }; - - /** - * Assoc previous year on aggregate node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected assocPreviousYearNetIncomeNode = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - const total = this.getPreviousYearNetIncome(); - - return R.assoc('previousYear', this.getTotalAmountMeta(total), node); - }; - - /** - * Assoc previous year attributes to aggregate node. - * @param {IBalanceSheetAccountNode} node - * @returns {IBalanceSheetAccountNode} - */ - protected previousYearNetIncomeNodeCompose = ( - node: IBalanceSheetNetIncomeNode - ): IBalanceSheetNetIncomeNode => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - // Associate the PY to date periods horizontal nodes. - R.when( - this.isNodeHasHorizontalTotals, - this.assocPreviousYearNetIncomeHorizNode - ), - this.assocPreviousYearNetIncomeNode - )(node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts deleted file mode 100644 index 4cbb43e8a..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IBalanceSheetQuery } from '@/interfaces'; -import { BalanceSheetTableInjectable } from './BalanceSheetTableInjectable'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class BalanceSheetPdfInjectable { - @Inject() - private balanceSheetTable: BalanceSheetTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given balance sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IBalanceSheetQuery - ): Promise { - const table = await this.balanceSheetTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPercentage.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPercentage.ts deleted file mode 100644 index ff87cec7b..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPercentage.ts +++ /dev/null @@ -1,225 +0,0 @@ -import * as R from 'ramda'; -import { get } from 'lodash'; -import { IBalanceSheetDataNode } from '@/interfaces'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; - -export const BalanceSheetPercentage = (Base: any) => - class extends Base { - readonly query: BalanceSheetQuery; - - /** - * Assoc percentage of column to report node. - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocReportNodeColumnPercentage = R.curry( - ( - parentTotal: number, - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - const percentage = this.getPercentageBasis( - parentTotal, - node.total.amount - ); - return R.assoc( - 'percentageColumn', - this.getPercentageAmountMeta(percentage), - node - ); - } - ); - - /** - * Assoc percentage of row to report node. - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocReportNodeRowPercentage = R.curry( - ( - parentTotal: number, - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - const percenatage = this.getPercentageBasis( - parentTotal, - node.total.amount - ); - return R.assoc( - 'percentageRow', - this.getPercentageAmountMeta(percenatage), - node - ); - } - ); - - /** - * Assoc percentage of row to horizontal total. - * @param {number} parentTotal - - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocRowPercentageHorizTotals = R.curry( - ( - parentTotal: number, - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - const assocRowPercen = this.assocReportNodeRowPercentage(parentTotal); - const horTotals = R.map(assocRowPercen)(node.horizontalTotals); - - return R.assoc('horizontalTotals', horTotals, node); - } - ); - - /** - * - * @param {} parentNode - - * @param {} horTotalNode - - * @param {number} index - - */ - private assocColumnPercentageHorizTotal = R.curry( - (parentNode, horTotalNode, index) => { - const parentTotal = get( - parentNode, - `horizontalTotals[${index}].total.amount`, - 0 - ); - return this.assocReportNodeColumnPercentage(parentTotal, horTotalNode); - } - ); - - /** - * Assoc column percentage to horizontal totals nodes. - * @param {IBalanceSheetDataNode} node - * @returns {IBalanceSheetDataNode} - */ - protected assocColumnPercentageHorizTotals = R.curry( - ( - parentNode: IBalanceSheetDataNode, - node: IBalanceSheetDataNode - ): IBalanceSheetDataNode => { - // Horizontal totals. - const assocColPerc = this.assocColumnPercentageHorizTotal(parentNode); - const horTotals = R.addIndex(R.map)(assocColPerc)( - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horTotals, node); - } - ); - - /** - * - * @param {number} parentTotal - - * @param {} node - * @returns - */ - protected reportNodeColumnPercentageComposer = R.curry( - (parentNode, node) => { - const parentTotal = parentNode.total.amount; - - return R.compose( - R.when( - this.isNodeHasHorizoTotals, - this.assocColumnPercentageHorizTotals(parentNode) - ), - this.assocReportNodeColumnPercentage(parentTotal) - )(node); - } - ); - - /** - * - * @param node - * @returns - */ - private reportNodeRowPercentageComposer = (node) => { - const total = node.total.amount; - - return R.compose( - R.when( - this.isNodeHasHorizoTotals, - this.assocRowPercentageHorizTotals(total) - ), - this.assocReportNodeRowPercentage(total) - )(node); - }; - - /** - * - */ - private assocNodeColumnPercentageChildren = (node) => { - const children = this.mapNodesDeep( - node.children, - this.reportNodeColumnPercentageComposer(node) - ); - return R.assoc('children', children, node); - }; - - /** - * - * @param node - * @returns - */ - private reportNodeColumnPercentageDeepMap = (node) => { - const parentTotal = node.total.amount; - const parentNode = node; - - return R.compose( - R.when( - this.isNodeHasHorizoTotals, - this.assocColumnPercentageHorizTotals(parentNode) - ), - this.assocReportNodeColumnPercentage(parentTotal), - this.assocNodeColumnPercentageChildren - )(node); - }; - - /** - * - * @param {IBalanceSheetDataNode[]} node - * @returns {IBalanceSheetDataNode[]} - */ - private reportColumnsPercentageMapper = ( - nodes: IBalanceSheetDataNode[] - ): IBalanceSheetDataNode[] => { - return R.map(this.reportNodeColumnPercentageDeepMap, nodes); - }; - - /** - * - * @param nodes - * @returns - */ - private reportRowsPercentageMapper = (nodes) => { - return this.mapNodesDeep(nodes, this.reportNodeRowPercentageComposer); - }; - - /** - * - * @param nodes - * @returns - */ - protected reportPercentageCompose = (nodes) => { - return R.compose( - R.when( - this.query.isColumnsPercentageActive, - this.reportColumnsPercentageMapper - ), - R.when( - this.query.isRowsPercentageActive, - this.reportRowsPercentageMapper - ) - )(nodes); - }; - - /** - * Detarmines whether the given node has horizontal total. - * @param {IBalanceSheetDataNode} node - * @returns {boolean} - */ - protected isNodeHasHorizoTotals = ( - node: IBalanceSheetDataNode - ): boolean => { - return ( - !R.isEmpty(node.horizontalTotals) && !R.isNil(node.horizontalTotals) - ); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetQuery.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetQuery.ts deleted file mode 100644 index 1a636952a..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetQuery.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { merge } from 'lodash'; -import * as R from 'ramda'; -import { IBalanceSheetQuery, IFinancialDatePeriodsUnit } from '@/interfaces'; -import { FinancialDateRanges } from '../FinancialDateRanges'; -import { DISPLAY_COLUMNS_BY } from './constants'; - -export class BalanceSheetQuery extends R.compose(FinancialDateRanges)( - class {} -) { - /** - * Balance sheet query. - * @param {IBalanceSheetQuery} - */ - public readonly query: IBalanceSheetQuery; - - /** - * Previous year to date. - * @param {Date} - */ - public readonly PYToDate: Date; - - /** - * Previous year from date. - * @param {Date} - */ - public readonly PYFromDate: Date; - - /** - * Previous period to date. - * @param {Date} - */ - public readonly PPToDate: Date; - - /** - * Previous period from date. - * @param {Date} - */ - public readonly PPFromDate: Date; - - /** - * Constructor method - * @param {IBalanceSheetQuery} query - */ - constructor(query: IBalanceSheetQuery) { - super(); - this.query = query; - - // Pervious Year (PY) Dates. - this.PYToDate = this.getPreviousYearDate(this.query.toDate); - this.PYFromDate = this.getPreviousYearDate(this.query.fromDate); - - // Previous Period (PP) Dates for Total column. - if (this.isTotalColumnType()) { - const { fromDate, toDate } = this.getPPTotalDateRange( - this.query.fromDate, - this.query.toDate - ); - this.PPToDate = toDate; - this.PPFromDate = fromDate; - // Previous Period (PP) Dates for Date period columns type. - } else if (this.isDatePeriodsColumnsType()) { - const { fromDate, toDate } = this.getPPDatePeriodDateRange( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy as IFinancialDatePeriodsUnit - ); - this.PPToDate = toDate; - this.PPFromDate = fromDate; - } - return merge(this, query); - } - - // --------------------------- - // # Columns Type/By. - // --------------------------- - /** - * Detarmines the given display columns type. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - public isDisplayColumnsBy = (displayColumnsBy: string): boolean => { - return this.query.displayColumnsBy === displayColumnsBy; - }; - - /** - * Detarmines the given display columns by type. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - public isDisplayColumnsType = (displayColumnsType: string): boolean => { - return this.query.displayColumnsType === displayColumnsType; - }; - - /** - * Detarmines whether the columns type is date periods. - * @returns {boolean} - */ - public isDatePeriodsColumnsType = (): boolean => { - return this.isDisplayColumnsType(DISPLAY_COLUMNS_BY.DATE_PERIODS); - }; - - /** - * Detarmines whether the columns type is total. - * @returns {boolean} - */ - public isTotalColumnType = (): boolean => { - return this.isDisplayColumnsType(DISPLAY_COLUMNS_BY.TOTAL); - }; - - // --------------------------- - // # Percentage column/row. - // --------------------------- - /** - * Detarmines whether the percentage of column active. - * @returns {boolean} - */ - public isColumnsPercentageActive = (): boolean => { - return this.query.percentageOfColumn; - }; - - /** - * Detarmines whether the percentage of row active. - * @returns {boolean} - */ - public isRowsPercentageActive = (): boolean => { - return this.query.percentageOfRow; - }; - - // --------------------------- - // # Previous Year (PY) - // --------------------------- - /** - * Detarmines the report query has previous year enabled. - * @returns {boolean} - */ - public isPreviousYearActive = (): boolean => { - return this.query.previousYear; - }; - - /** - * Detarmines the report query has previous year percentage change active. - * @returns {boolean} - */ - public isPreviousYearPercentageActive = (): boolean => { - return this.query.previousYearPercentageChange; - }; - - /** - * Detarmines the report query has previous year change active. - * @returns {boolean} - */ - public isPreviousYearChangeActive = (): boolean => { - return this.query.previousYearAmountChange; - }; - - // --------------------------- - // # Previous Period (PP). - // --------------------------- - /** - * Detarmines the report query has previous period enabled. - * @returns {boolean} - */ - public isPreviousPeriodActive = (): boolean => { - return this.query.previousPeriod; - }; - - /** - * Detarmines wether the preivous period percentage is active. - * @returns {boolean} - */ - public isPreviousPeriodPercentageActive = (): boolean => { - return this.query.previousPeriodPercentageChange; - }; - - /** - * Detarmines wether the previous period change is active. - * @returns {boolean} - */ - public isPreviousPeriodChangeActive = (): boolean => { - return this.query.previousPeriodAmountChange; - }; -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepository.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepository.ts deleted file mode 100644 index 75a257191..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepository.ts +++ /dev/null @@ -1,402 +0,0 @@ -import { Service } from 'typedi'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { isEmpty } from 'lodash'; -import { - IAccountTransactionsGroupBy, - IBalanceSheetQuery, - ILedger, -} from '@/interfaces'; -import { transformToMapBy } from 'utils'; -import Ledger from '@/services/Accounting/Ledger'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; -import { BalanceSheetRepositoryNetIncome } from './BalanceSheetRepositoryNetIncome'; - -@Service() -export default class BalanceSheetRepository extends R.compose( - BalanceSheetRepositoryNetIncome, - FinancialDatePeriods -)(class {}) { - /** - * - */ - private readonly models; - - /** - * @param {number} - */ - public readonly tenantId: number; - - /** - * @param {BalanceSheetQuery} - */ - public readonly query: BalanceSheetQuery; - - /** - * @param {} - */ - public accounts: any; - - /** - * @param {} - */ - public accountsGraph: any; - - /** - * - */ - public accountsByType: any; - - /** - * PY from date. - * @param {Date} - */ - public readonly PYFromDate: Date; - - /** - * PY to date. - * @param {Date} - */ - public readonly PYToDate: Date; - - /** - * PP to date. - * @param {Date} - */ - public readonly PPToDate: Date; - - /** - * PP from date. - * @param {Date} - */ - public readonly PPFromDate: Date; - - /** - * Total closing accounts ledger. - * @param {Ledger} - */ - public totalAccountsLedger: Ledger; - - /** - * Total income accounts ledger. - */ - public incomeLedger: Ledger; - - /** - * Total expense accounts ledger. - */ - public expensesLedger: Ledger; - - /** - * Transactions group type. - * @param {IAccountTransactionsGroupBy} - */ - public transactionsGroupType: IAccountTransactionsGroupBy = - IAccountTransactionsGroupBy.Month; - - // ----------------------- - // # Date Periods - // ----------------------- - /** - * @param {Ledger} - */ - public periodsAccountsLedger: Ledger; - - /** - * @param {Ledger} - */ - public periodsOpeningAccountLedger: Ledger; - - // ----------------------- - // # Previous Year (PY). - // ----------------------- - /** - * @param {Ledger} - */ - public PYPeriodsOpeningAccountLedger: Ledger; - - /** - * @param {Ledger} - */ - public PYPeriodsAccountsLedger: Ledger; - - /** - * @param {Ledger} - */ - public PYTotalAccountsLedger: ILedger; - - // ----------------------- - // # Previous Period (PP). - // ----------------------- - /** - * @param {Ledger} - */ - public PPTotalAccountsLedger: Ledger; - - /** - * @param {Ledger} - */ - public PPPeriodsAccountsLedger: ILedger; - - /** - * @param {Ledger} - */ - public PPPeriodsOpeningAccountLedger: ILedger; - - /** - * Constructor method. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - */ - constructor(models: any, query: IBalanceSheetQuery) { - super(); - - this.query = new BalanceSheetQuery(query); - this.models = models; - - this.transactionsGroupType = this.getGroupByFromDisplayColumnsBy( - this.query.displayColumnsBy - ); - } - - /** - * Async initialize. - * @returns {Promise} - */ - public asyncInitialize = async () => { - await this.initAccounts(); - await this.initAccountsGraph(); - - await this.initAccountsTotalLedger(); - - // Date periods. - if (this.query.isDatePeriodsColumnsType()) { - await this.initTotalDatePeriods(); - } - // Previous Year (PY). - if (this.query.isPreviousYearActive()) { - await this.initTotalPreviousYear(); - } - if ( - this.query.isPreviousYearActive() && - this.query.isDatePeriodsColumnsType() - ) { - await this.initPeriodsPreviousYear(); - } - // Previous Period (PP). - if (this.query.isPreviousPeriodActive()) { - await this.initTotalPreviousPeriod(); - } - if ( - this.query.isPreviousPeriodActive() && - this.query.isDatePeriodsColumnsType() - ) { - await this.initPeriodsPreviousPeriod(); - } - // - await this.asyncInitializeNetIncome(); - }; - - // ---------------------------- - // # Accounts - // ---------------------------- - public initAccounts = async () => { - const accounts = await this.getAccounts(); - - this.accounts = accounts; - this.accountsByType = transformToMapBy(accounts, 'accountType'); - this.accountsByParentType = transformToMapBy(accounts, 'accountParentType'); - }; - - /** - * Initialize accounts graph. - */ - public initAccountsGraph = async () => { - const { Account } = this.models; - - this.accountsGraph = Account.toDependencyGraph(this.accounts); - }; - - // ---------------------------- - // # Closing Total - // ---------------------------- - /** - * Initialize accounts closing total based on the given query. - * @returns {Promise} - */ - private initAccountsTotalLedger = async (): Promise => { - const totalByAccount = await this.closingAccountsTotal(this.query.toDate); - - // Inject to the repository. - this.totalAccountsLedger = Ledger.fromTransactions(totalByAccount); - }; - - // ---------------------------- - // # Date periods. - // ---------------------------- - /** - * Initialize date periods total. - * @returns {Promise} - */ - public initTotalDatePeriods = async (): Promise => { - // Retrieves grouped transactions by given date group. - const periodsByAccount = await this.accountsDatePeriods( - this.query.fromDate, - this.query.toDate, - this.transactionsGroupType - ); - // Retrieves opening balance of grouped transactions. - const periodsOpeningByAccount = await this.closingAccountsTotal( - this.query.fromDate - ); - // Inject to the repository. - this.periodsAccountsLedger = Ledger.fromTransactions(periodsByAccount); - this.periodsOpeningAccountLedger = Ledger.fromTransactions( - periodsOpeningByAccount - ); - }; - - // ---------------------------- - // # Previous Year (PY). - // ---------------------------- - /** - * Initialize total of previous year. - * @returns {Promise} - */ - private initTotalPreviousYear = async (): Promise => { - const PYTotalsByAccounts = await this.closingAccountsTotal( - this.query.PYToDate - ); - // Inject to the repository. - this.PYTotalAccountsLedger = Ledger.fromTransactions(PYTotalsByAccounts); - }; - - /** - * Initialize date periods of previous year. - * @returns {Promise} - */ - private initPeriodsPreviousYear = async (): Promise => { - const PYPeriodsBYAccounts = await this.accountsDatePeriods( - this.query.PYFromDate, - this.query.PYToDate, - this.transactionsGroupType - ); - // Retrieves opening balance of grouped transactions. - const periodsOpeningByAccount = await this.closingAccountsTotal( - this.query.PYFromDate - ); - // Inject to the repository. - this.PYPeriodsAccountsLedger = Ledger.fromTransactions(PYPeriodsBYAccounts); - this.PYPeriodsOpeningAccountLedger = Ledger.fromTransactions( - periodsOpeningByAccount - ); - }; - - // ---------------------------- - // # Previous Year (PP). - // ---------------------------- - /** - * Initialize total of previous year. - * @returns {Promise} - */ - private initTotalPreviousPeriod = async (): Promise => { - const PPTotalsByAccounts = await this.closingAccountsTotal( - this.query.PPToDate - ); - // Inject to the repository. - this.PPTotalAccountsLedger = Ledger.fromTransactions(PPTotalsByAccounts); - }; - - /** - * Initialize date periods of previous year. - * @returns {Promise} - */ - private initPeriodsPreviousPeriod = async (): Promise => { - const PPPeriodsBYAccounts = await this.accountsDatePeriods( - this.query.PPFromDate, - this.query.PPToDate, - this.transactionsGroupType - ); - // Retrieves opening balance of grouped transactions. - const periodsOpeningByAccount = await this.closingAccountsTotal( - this.query.PPFromDate - ); - // Inject to the repository. - this.PPPeriodsAccountsLedger = Ledger.fromTransactions(PPPeriodsBYAccounts); - this.PPPeriodsOpeningAccountLedger = Ledger.fromTransactions( - periodsOpeningByAccount - ); - }; - - // ---------------------------- - // # Utils - // ---------------------------- - /** - * Retrieve accounts of the report. - * @return {Promise} - */ - private getAccounts = () => { - const { Account } = this.models; - - return Account.query(); - }; - - /** - * Closing accounts date periods. - * @param {Date} fromDate - * @param {Date} toDate - * @param {string} datePeriodsType - * @returns - */ - public accountsDatePeriods = async ( - fromDate: Date, - toDate: Date, - datePeriodsType: string - ) => { - const { AccountTransaction } = this.models; - - return AccountTransaction.query().onBuild((query) => { - query.sum('credit as credit'); - query.sum('debit as debit'); - query.groupBy('accountId'); - query.select(['accountId']); - - query.modify('groupByDateFormat', datePeriodsType); - query.modify('filterDateRange', fromDate, toDate); - query.withGraphFetched('account'); - - this.commonFilterBranchesQuery(query); - }); - }; - - /** - * Retrieve the opening balance transactions of the report. - * @param {Date|string} openingDate - - */ - public closingAccountsTotal = async (openingDate: Date | string) => { - const { AccountTransaction } = this.models; - - return AccountTransaction.query().onBuild((query) => { - query.sum('credit as credit'); - query.sum('debit as debit'); - query.groupBy('accountId'); - query.select(['accountId']); - - query.modify('filterDateRange', null, openingDate); - query.withGraphFetched('account'); - - this.commonFilterBranchesQuery(query); - }); - }; - - /** - * Common branches filter query. - * @param {Knex.QueryBuilder} query - */ - private commonFilterBranchesQuery = (query: Knex.QueryBuilder) => { - if (!isEmpty(this.query.branchesIds)) { - query.modify('filterByBranches', this.query.branchesIds); - } - }; -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepositoryNetIncome.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepositoryNetIncome.ts deleted file mode 100644 index 74e21acd2..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetRepositoryNetIncome.ts +++ /dev/null @@ -1,222 +0,0 @@ -import * as R from 'ramda'; -import { IAccount, ILedger } from '@/interfaces'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; -import { ACCOUNT_PARENT_TYPE } from '@/data/AccountTypes'; - -export const BalanceSheetRepositoryNetIncome = (Base) => - class extends R.compose(FinancialDatePeriods)(Base) { - // ----------------------- - // # Net Income - // ----------------------- - public incomeAccounts: IAccount[]; - public incomeAccountsIds: number[]; - - public expenseAccounts: IAccount[]; - public expenseAccountsIds: number[]; - - public incomePeriodsAccountsLedger: ILedger; - public incomePeriodsOpeningAccountsLedger: ILedger; - public expensesPeriodsAccountsLedger: ILedger; - public expensesOpeningAccountLedger: ILedger; - - public incomePPAccountsLedger: ILedger; - public expensePPAccountsLedger: ILedger; - - public incomePPPeriodsAccountsLedger: ILedger; - public incomePPPeriodsOpeningAccountLedger: ILedger; - public expensePPPeriodsAccountsLedger: ILedger; - public expensePPPeriodsOpeningAccountLedger: ILedger; - - public incomePYTotalAccountsLedger: ILedger; - public expensePYTotalAccountsLedger: ILedger; - - public incomePYPeriodsAccountsLedger: ILedger; - public incomePYPeriodsOpeningAccountLedger: ILedger; - public expensePYPeriodsAccountsLedger: ILedger; - public expensePYPeriodsOpeningAccountLedger: ILedger; - - /** - * Async initialize. - * @returns {Promise} - */ - public asyncInitializeNetIncome = async () => { - await this.initAccounts(); - await this.initAccountsTotalLedger(); - - // Net Income - this.initIncomeAccounts(); - this.initExpenseAccounts(); - - this.initIncomeTotalLedger(); - this.initExpensesTotalLedger(); - - // Date periods - if (this.query.isDatePeriodsColumnsType()) { - this.initNetIncomeDatePeriods(); - } - // Previous Year (PY). - if (this.query.isPreviousYearActive()) { - this.initNetIncomePreviousYear(); - } - // Previous Period (PP). - if (this.query.isPreviousPeriodActive()) { - this.initNetIncomePreviousPeriod(); - } - // Previous Year (PY) / Date Periods. - if ( - this.query.isPreviousYearActive() && - this.query.isDatePeriodsColumnsType() - ) { - this.initNetIncomePeriodsPreviewYear(); - } - // Previous Period (PP) / Date Periods. - if ( - this.query.isPreviousPeriodActive() && - this.query.isDatePeriodsColumnsType() - ) { - this.initNetIncomePeriodsPreviousPeriod(); - } - }; - - // ---------------------------- - // # Net Income - // ---------------------------- - /** - * Initialize income accounts. - */ - private initIncomeAccounts = () => { - const incomeAccounts = this.accountsByParentType.get( - ACCOUNT_PARENT_TYPE.INCOME - ); - const incomeAccountsIds = incomeAccounts.map((a) => a.id); - - this.incomeAccounts = incomeAccounts; - this.incomeAccountsIds = incomeAccountsIds; - }; - - /** - * Initialize expense accounts. - */ - private initExpenseAccounts = () => { - const expensesAccounts = this.accountsByParentType.get( - ACCOUNT_PARENT_TYPE.EXPENSE - ); - const expensesAccountsIds = expensesAccounts.map((a) => a.id); - - this.expenseAccounts = expensesAccounts; - this.expenseAccountsIds = expensesAccountsIds; - }; - - /** - * Initialize the income total ledger. - */ - private initIncomeTotalLedger = (): void => { - // Inject to the repository. - this.incomeLedger = this.totalAccountsLedger.whereAccountsIds( - this.incomeAccountsIds - ); - }; - - /** - * Initialize the expenses total ledger. - */ - private initExpensesTotalLedger = (): void => { - this.expensesLedger = this.totalAccountsLedger.whereAccountsIds( - this.expenseAccountsIds - ); - }; - - // ---------------------------- - // # Net Income - Date Periods - // ---------------------------- - /** - * Initialize the net income date periods. - */ - public initNetIncomeDatePeriods = () => { - this.incomePeriodsAccountsLedger = - this.periodsAccountsLedger.whereAccountsIds(this.incomeAccountsIds); - - this.incomePeriodsOpeningAccountsLedger = - this.periodsOpeningAccountLedger.whereAccountsIds( - this.incomeAccountsIds - ); - - this.expensesPeriodsAccountsLedger = - this.periodsAccountsLedger.whereAccountsIds(this.expenseAccountsIds); - - this.expensesOpeningAccountLedger = - this.periodsOpeningAccountLedger.whereAccountsIds( - this.expenseAccountsIds - ); - }; - - // ---------------------------- - // # Net Income - Previous Period - // ---------------------------- - /** - * Initialize the total net income PP. - */ - public initNetIncomePreviousPeriod = () => { - this.incomePPAccountsLedger = this.PPTotalAccountsLedger.whereAccountsIds( - this.incomeAccountsIds - ); - this.expensePPAccountsLedger = - this.PPTotalAccountsLedger.whereAccountsIds(this.expenseAccountsIds); - }; - - /** - * Initialize the net income periods of previous period. - */ - public initNetIncomePeriodsPreviousPeriod = () => { - this.incomePPPeriodsAccountsLedger = - this.PPPeriodsAccountsLedger.whereAccountsIds(this.incomeAccountsIds); - - this.incomePPPeriodsOpeningAccountLedger = - this.PPPeriodsOpeningAccountLedger.whereAccountsIds( - this.incomeAccountsIds - ); - - this.expensePPPeriodsAccountsLedger = - this.PPPeriodsAccountsLedger.whereAccountsIds(this.expenseAccountsIds); - - this.expensePPPeriodsOpeningAccountLedger = - this.PPPeriodsOpeningAccountLedger.whereAccountsIds( - this.expenseAccountsIds - ); - }; - - // ---------------------------- - // # Net Income - Previous Year - // ---------------------------- - /** - * Initialize the net income PY total. - */ - public initNetIncomePreviousYear = () => { - this.incomePYTotalAccountsLedger = - this.PYTotalAccountsLedger.whereAccountsIds(this.incomeAccountsIds); - - this.expensePYTotalAccountsLedger = - this.PYTotalAccountsLedger.whereAccountsIds(this.expenseAccountsIds); - }; - - /** - * Initialize the net income PY periods. - */ - public initNetIncomePeriodsPreviewYear = () => { - this.incomePYPeriodsAccountsLedger = - this.PYPeriodsAccountsLedger.whereAccountsIds(this.incomeAccountsIds); - - this.incomePYPeriodsOpeningAccountLedger = - this.PYPeriodsOpeningAccountLedger.whereAccountsIds( - this.incomeAccountsIds - ); - - this.expensePYPeriodsAccountsLedger = - this.PYPeriodsAccountsLedger.whereAccountsIds(this.expenseAccountsIds); - - this.expensePYPeriodsOpeningAccountLedger = - this.PYPeriodsOpeningAccountLedger.whereAccountsIds( - this.expenseAccountsIds - ); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetSchema.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetSchema.ts deleted file mode 100644 index 5ef897506..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetSchema.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import * as R from 'ramda'; -import { - BALANCE_SHEET_SCHEMA_NODE_ID, - BALANCE_SHEET_SCHEMA_NODE_TYPE, -} from '@/interfaces'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; -import { FinancialSchema } from '../FinancialSchema'; - -export const BalanceSheetSchema = (Base) => - class extends R.compose(FinancialSchema)(Base) { - /** - * Retrieves the balance sheet schema. - * @returns - */ - getSchema = () => { - return getBalanceSheetSchema(); - }; - }; - -/** - * Retrieve the balance sheet report schema. - */ -export const getBalanceSheetSchema = () => [ - { - name: 'balance_sheet.assets', - id: BALANCE_SHEET_SCHEMA_NODE_ID.ASSETS, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE, - children: [ - { - name: 'balance_sheet.current_asset', - id: BALANCE_SHEET_SCHEMA_NODE_ID.CURRENT_ASSETS, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE, - children: [ - { - name: 'balance_sheet.cash_and_cash_equivalents', - id: BALANCE_SHEET_SCHEMA_NODE_ID.CASH_EQUIVALENTS, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.CASH, ACCOUNT_TYPE.BANK], - }, - { - name: 'balance_sheet.accounts_receivable', - id: BALANCE_SHEET_SCHEMA_NODE_ID.ACCOUNTS_RECEIVABLE, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE], - }, - { - name: 'balance_sheet.inventory', - id: BALANCE_SHEET_SCHEMA_NODE_ID.INVENTORY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.INVENTORY], - }, - { - name: 'balance_sheet.other_current_assets', - id: BALANCE_SHEET_SCHEMA_NODE_ID.OTHER_CURRENT_ASSET, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.OTHER_CURRENT_ASSET], - }, - ], - alwaysShow: true, - }, - { - name: 'balance_sheet.fixed_asset', - id: BALANCE_SHEET_SCHEMA_NODE_ID.FIXED_ASSET, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.FIXED_ASSET], - }, - { - name: 'balance_sheet.non_current_assets', - id: BALANCE_SHEET_SCHEMA_NODE_ID.NON_CURRENT_ASSET, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.NON_CURRENT_ASSET], - }, - ], - alwaysShow: true, - }, - { - name: 'balance_sheet.liabilities_and_equity', - id: BALANCE_SHEET_SCHEMA_NODE_ID.LIABILITY_EQUITY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE, - children: [ - { - name: 'balance_sheet.liabilities', - id: BALANCE_SHEET_SCHEMA_NODE_ID.LIABILITY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE, - children: [ - { - name: 'balance_sheet.current_liabilties', - id: BALANCE_SHEET_SCHEMA_NODE_ID.CURRENT_LIABILITY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ - ACCOUNT_TYPE.ACCOUNTS_PAYABLE, - ACCOUNT_TYPE.TAX_PAYABLE, - ACCOUNT_TYPE.CREDIT_CARD, - ACCOUNT_TYPE.OTHER_CURRENT_LIABILITY, - ], - }, - { - name: 'balance_sheet.long_term_liabilities', - id: BALANCE_SHEET_SCHEMA_NODE_ID.LOGN_TERM_LIABILITY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.LOGN_TERM_LIABILITY], - }, - { - name: 'balance_sheet.non_current_liabilities', - id: BALANCE_SHEET_SCHEMA_NODE_ID.NON_CURRENT_LIABILITY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.NON_CURRENT_LIABILITY], - }, - ], - }, - { - name: 'balance_sheet.equity', - id: BALANCE_SHEET_SCHEMA_NODE_ID.EQUITY, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.EQUITY], - children: [ - { - name: 'balance_sheet.net_income', - id: BALANCE_SHEET_SCHEMA_NODE_ID.NET_INCOME, - type: BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME, - }, - ], - }, - ], - alwaysShow: true, - }, -]; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts deleted file mode 100644 index 8e6a1f92b..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts +++ /dev/null @@ -1,278 +0,0 @@ -import * as R from 'ramda'; -import { - IBalanceSheetStatementData, - ITableColumnAccessor, - IBalanceSheetQuery, - ITableColumn, - ITableRow, - BALANCE_SHEET_SCHEMA_NODE_TYPE, - IBalanceSheetDataNode, - IBalanceSheetSchemaNode, - IBalanceSheetNetIncomeNode, - IBalanceSheetAccountNode, - IBalanceSheetAccountsNode, - IBalanceSheetAggregateNode, -} from '@/interfaces'; -import { tableRowMapper } from 'utils'; -import FinancialSheet from '../FinancialSheet'; -import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear'; -import { IROW_TYPE, DISPLAY_COLUMNS_BY } from './constants'; -import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod'; -import { BalanceSheetPercentage } from './BalanceSheetPercentage'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { BalanceSheetBase } from './BalanceSheetBase'; -import { BalanceSheetTablePercentage } from './BalanceSheetTablePercentage'; -import { BalanceSheetTablePreviousYear } from './BalanceSheetTablePreviousYear'; -import { BalanceSheetTablePreviousPeriod } from './BalanceSheetTablePreviousPeriod'; -import { FinancialTable } from '../FinancialTable'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { BalanceSheetTableDatePeriods } from './BalanceSheetTableDatePeriods'; - -export default class BalanceSheetTable extends R.compose( - BalanceSheetTablePreviousPeriod, - BalanceSheetTablePreviousYear, - BalanceSheetTableDatePeriods, - BalanceSheetTablePercentage, - BalanceSheetComparsionPreviousYear, - BalanceSheetComparsionPreviousPeriod, - BalanceSheetPercentage, - FinancialSheetStructure, - FinancialTable, - BalanceSheetBase -)(FinancialSheet) { - /** - * Balance sheet data. - * @param {IBalanceSheetStatementData} - */ - private reportData: IBalanceSheetStatementData; - - /** - * Balance sheet query. - * @parma {BalanceSheetQuery} - */ - private query: BalanceSheetQuery; - - /** - * Constructor method. - * @param {IBalanceSheetStatementData} reportData - - * @param {IBalanceSheetQuery} query - - */ - constructor( - reportData: IBalanceSheetStatementData, - query: IBalanceSheetQuery, - i18n: any - ) { - super(); - - this.reportData = reportData; - this.query = new BalanceSheetQuery(query); - this.i18n = i18n; - } - - /** - * Detarmines the node type of the given schema node. - * @param {IBalanceSheetStructureSection} node - - * @param {string} type - - * @return {boolean} - */ - protected isNodeType = R.curry( - (type: string, node: IBalanceSheetSchemaNode): boolean => { - return node.nodeType === type; - } - ); - - // ------------------------- - // # Accessors. - // ------------------------- - /** - * Retrieve the common columns for all report nodes. - * @param {ITableColumnAccessor[]} - */ - private commonColumnsAccessors = (): ITableColumnAccessor[] => { - return R.compose( - R.concat([{ key: 'name', accessor: 'name' }]), - R.ifElse( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - R.concat(this.datePeriodsColumnsAccessors()), - R.concat(this.totalColumnAccessor()) - ) - )([]); - }; - - /** - * Retrieve the total column accessor. - * @return {ITableColumnAccessor[]} - */ - private totalColumnAccessor = (): ITableColumnAccessor[] => { - return R.pipe( - R.concat(this.previousPeriodColumnAccessor()), - R.concat(this.previousYearColumnAccessor()), - R.concat(this.percentageColumnsAccessor()), - R.concat([{ key: 'total', accessor: 'total.formattedAmount' }]) - )([]); - }; - - /** - * Retrieves the table row from the given report aggregate node. - * @param {IBalanceSheetAggregateNode} node - * @returns {ITableRow} - */ - private aggregateNodeTableRowsMapper = ( - node: IBalanceSheetAggregateNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [IROW_TYPE.AGGREGATE], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Retrieves the table row from the given report accounts node. - * @param {IBalanceSheetAccountsNode} node - * @returns {ITableRow} - */ - private accountsNodeTableRowsMapper = ( - node: IBalanceSheetAccountsNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [IROW_TYPE.ACCOUNTS], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Retrieves the table row from the given report account node. - * @param {IBalanceSheetAccountNode} node - * @returns {ITableRow} - */ - private accountNodeTableRowsMapper = ( - node: IBalanceSheetAccountNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - - const meta = { - rowTypes: [IROW_TYPE.ACCOUNT], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Retrieves the table row from the given report net income node. - * @param {IBalanceSheetNetIncomeNode} node - * @returns {ITableRow} - */ - private netIncomeNodeTableRowsMapper = ( - node: IBalanceSheetNetIncomeNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [IROW_TYPE.NET_INCOME], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Mappes the given report node to table rows. - * @param {IBalanceSheetDataNode} node - - * @returns {ITableRow} - */ - private nodeToTableRowsMapper = (node: IBalanceSheetDataNode): ITableRow => { - return R.cond([ - [ - this.isNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE), - this.aggregateNodeTableRowsMapper, - ], - [ - this.isNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS), - this.accountsNodeTableRowsMapper, - ], - [ - this.isNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT), - this.accountNodeTableRowsMapper, - ], - [ - this.isNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME), - this.netIncomeNodeTableRowsMapper, - ], - ])(node); - }; - - /** - * Mappes the given report sections to table rows. - * @param {IBalanceSheetDataNode[]} nodes - - * @return {ITableRow} - */ - private nodesToTableRowsMapper = ( - nodes: IBalanceSheetDataNode[] - ): ITableRow[] => { - return this.mapNodesDeep(nodes, this.nodeToTableRowsMapper); - }; - - /** - * Retrieves the total children columns. - * @returns {ITableColumn[]} - */ - private totalColumnChildren = (): ITableColumn[] => { - return R.compose( - R.unless( - R.isEmpty, - R.concat([{ key: 'total', label: this.i18n.__('balance_sheet.total') }]) - ), - R.concat(this.percentageColumns()), - R.concat(this.getPreviousYearColumns()), - R.concat(this.previousPeriodColumns()) - )([]); - }; - - /** - * Retrieve the total column. - * @returns {ITableColumn[]} - */ - private totalColumn = (): ITableColumn[] => { - return [ - { - key: 'total', - label: this.i18n.__('balance_sheet.total'), - children: this.totalColumnChildren(), - }, - ]; - }; - - /** - * Retrieve the report table rows. - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return R.compose( - this.addTotalRows, - this.nodesToTableRowsMapper - )(this.reportData); - }; - - // ------------------------- - // # Columns. - // ------------------------- - /** - * Retrieve the report table columns. - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return R.compose( - this.tableColumnsCellIndexing, - R.concat([ - { key: 'name', label: this.i18n.__('balance_sheet.account_name') }, - ]), - R.ifElse( - this.query.isDatePeriodsColumnsType, - R.concat(this.datePeriodsColumns()), - R.concat(this.totalColumn()) - ) - )([]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableDatePeriods.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableDatePeriods.ts deleted file mode 100644 index 3e195aa24..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableDatePeriods.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as R from 'ramda'; -import moment from 'moment'; -import { - ITableColumn, - IDateRange, - ICashFlowDateRange, - ITableColumnAccessor, -} from '@/interfaces'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; - -export const BalanceSheetTableDatePeriods = (Base) => - class extends R.compose(FinancialDatePeriods)(Base) { - /** - * Retrieves the date periods based on the report query. - * @returns {IDateRange[]} - */ - get datePeriods() { - return this.getDateRanges( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy - ); - } - - /** - * Retrieve the formatted column label from the given date range. - * @param {ICashFlowDateRange} dateRange - - * @return {string} - */ - private formatColumnLabel = (dateRange: ICashFlowDateRange) => { - const monthFormat = (range) => moment(range.toDate).format('YYYY-MM'); - const yearFormat = (range) => moment(range.toDate).format('YYYY'); - const dayFormat = (range) => moment(range.toDate).format('YYYY-MM-DD'); - - const conditions = [ - ['month', monthFormat], - ['year', yearFormat], - ['day', dayFormat], - ['quarter', monthFormat], - ['week', dayFormat], - ]; - const conditionsPairs = R.map( - ([type, formatFn]) => [ - R.always(this.query.isDisplayColumnsBy(type)), - formatFn, - ], - conditions - ); - return R.compose(R.cond(conditionsPairs))(dateRange); - }; - - // ------------------------- - // # Accessors. - // ------------------------- - /** - * Date period columns accessor. - * @param {IDateRange} dateRange - - * @param {number} index - - */ - private datePeriodColumnsAccessor = R.curry( - (dateRange: IDateRange, index: number) => { - return R.pipe( - R.concat(this.previousPeriodHorizColumnAccessors(index)), - R.concat(this.previousYearHorizontalColumnAccessors(index)), - R.concat(this.percetangeDatePeriodColumnsAccessor(index)), - R.concat([ - { - key: `date-range-${index}`, - accessor: `horizontalTotals[${index}].total.formattedAmount`, - }, - ]) - )([]); - } - ); - - /** - * Retrieve the date periods columns accessors. - * @returns {ITableColumnAccessor[]} - */ - protected datePeriodsColumnsAccessors = (): ITableColumnAccessor[] => { - return R.compose( - R.flatten, - R.addIndex(R.map)(this.datePeriodColumnsAccessor) - )(this.datePeriods); - }; - - // ------------------------- - // # Columns. - // ------------------------- - /** - * - * @param {number} index - * @param {} dateRange - * @returns {} - */ - private datePeriodChildrenColumns = ( - index: number, - dateRange: IDateRange - ) => { - return R.compose( - R.unless( - R.isEmpty, - R.concat([ - { key: `total`, label: this.i18n.__('balance_sheet.total') }, - ]) - ), - R.concat(this.percentageColumns()), - R.concat(this.getPreviousYearHorizontalColumns(dateRange)), - R.concat(this.previousPeriodHorizontalColumns(dateRange)) - )([]); - }; - - /** - * - * @param dateRange - * @param index - * @returns - */ - private datePeriodColumn = ( - dateRange: IDateRange, - index: number - ): ITableColumn => { - return { - key: `date-range-${index}`, - label: this.formatColumnLabel(dateRange), - children: this.datePeriodChildrenColumns(index, dateRange), - }; - }; - - /** - * Date periods columns. - * @returns {ITableColumn[]} - */ - protected datePeriodsColumns = (): ITableColumn[] => { - return this.datePeriods.map(this.datePeriodColumn); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableInjectable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableInjectable.ts deleted file mode 100644 index 3eb769350..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTableInjectable.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Inject, Service } from 'typedi'; -import BalanceSheetStatementService from './BalanceSheetInjectable'; -import BalanceSheetTable from './BalanceSheetTable'; -import { IBalanceSheetQuery, IBalanceSheetTable } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class BalanceSheetTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private balanceSheetService: BalanceSheetStatementService; - - /** - * Retrieves the balance sheet in table format. - * @param {number} tenantId - * @param {number} query - * @returns {Promise} - */ - public async table( - tenantId: number, - filter: IBalanceSheetQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const { data, query, meta } = await this.balanceSheetService.balanceSheet( - tenantId, - filter - ); - const table = new BalanceSheetTable(data, query, i18n); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - query, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePercentage.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePercentage.ts deleted file mode 100644 index a7d3f82c4..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePercentage.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as R from 'ramda'; -import { ITableColumn } from '@/interfaces'; - -export const BalanceSheetTablePercentage = (Base) => - class extends Base { - // -------------------- - // # Columns - // -------------------- - /** - * Retrieve percentage of column/row columns. - * @returns {ITableColumn[]} - */ - protected percentageColumns = (): ITableColumn[] => { - return R.pipe( - R.when( - this.query.isColumnsPercentageActive, - R.append({ - key: 'percentage_of_column', - label: this.i18n.__('balance_sheet.percentage_of_column'), - }) - ), - R.when( - this.query.isRowsPercentageActive, - R.append({ - key: 'percentage_of_row', - label: this.i18n.__('balance_sheet.percentage_of_row'), - }) - ) - )([]); - }; - - // -------------------- - // # Accessors - // -------------------- - /** - * Retrieves percentage of column/row accessors. - * @returns {ITableColumn[]} - */ - protected percentageColumnsAccessor = (): ITableColumn[] => { - return R.pipe( - R.when( - this.query.isColumnsPercentageActive, - R.append({ - key: 'percentage_of_column', - accessor: 'percentageColumn.formattedAmount', - }) - ), - R.when( - this.query.isRowsPercentageActive, - R.append({ - key: 'percentage_of_row', - accessor: 'percentageRow.formattedAmount', - }) - ) - )([]); - }; - - /** - * Percentage columns accessors for date period columns. - * @param {number} index - * @returns {ITableColumn[]} - */ - protected percetangeDatePeriodColumnsAccessor = ( - index: number - ): ITableColumn[] => { - return R.pipe( - R.when( - this.query.isColumnsPercentageActive, - R.append({ - key: `percentage_of_column-${index}`, - accessor: `horizontalTotals[${index}].percentageColumn.formattedAmount`, - }) - ), - R.when( - this.query.isRowsPercentageActive, - R.append({ - key: `percentage_of_row-${index}`, - accessor: `horizontalTotals[${index}].percentageRow.formattedAmount`, - }) - ) - )([]); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousPeriod.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousPeriod.ts deleted file mode 100644 index 1541df9c2..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousPeriod.ts +++ /dev/null @@ -1,109 +0,0 @@ -import * as R from 'ramda'; -import { IDateRange, ITableColumn } from '@/interfaces'; -import { BalanceSheetQuery } from './BalanceSheetQuery'; -import { FinancialTablePreviousPeriod } from '../FinancialTablePreviousPeriod'; -import { FinancialDateRanges } from '../FinancialDateRanges'; - -export const BalanceSheetTablePreviousPeriod = (Base) => - class extends R.compose( - FinancialTablePreviousPeriod, - FinancialDateRanges - )(Base) { - readonly query: BalanceSheetQuery; - - // -------------------- - // # Columns - // -------------------- - /** - * Retrieves the previous period columns. - * @returns {ITableColumn[]} - */ - protected previousPeriodColumns = ( - dateRange?: IDateRange - ): ITableColumn[] => { - return R.pipe( - // Previous period columns. - R.when( - this.query.isPreviousPeriodActive, - R.append(this.getPreviousPeriodTotalColumn(dateRange)) - ), - R.when( - this.query.isPreviousPeriodChangeActive, - R.append(this.getPreviousPeriodChangeColumn()) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - R.append(this.getPreviousPeriodPercentageColumn()) - ) - )([]); - }; - - /** - * Previous period for date periods - * @param {IDateRange} dateRange - * @returns {ITableColumn} - */ - protected previousPeriodHorizontalColumns = ( - dateRange: IDateRange - ): ITableColumn[] => { - const PPDateRange = this.getPPDatePeriodDateRange( - dateRange.fromDate, - dateRange.toDate, - this.query.displayColumnsBy - ); - return this.previousPeriodColumns({ - fromDate: PPDateRange.fromDate, - toDate: PPDateRange.toDate, - }); - }; - - // -------------------- - // # Accessors - // -------------------- - /** - * Retrieves previous period columns accessors. - * @returns {ITableColumn[]} - */ - protected previousPeriodColumnAccessor = (): ITableColumn[] => { - return R.pipe( - // Previous period columns. - R.when( - this.query.isPreviousPeriodActive, - R.append(this.getPreviousPeriodTotalAccessor()) - ), - R.when( - this.query.isPreviousPeriodChangeActive, - R.append(this.getPreviousPeriodChangeAccessor()) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - R.append(this.getPreviousPeriodPercentageAccessor()) - ) - )([]); - }; - - /** - * - * @param {number} index - * @returns - */ - protected previousPeriodHorizColumnAccessors = ( - index: number - ): ITableColumn[] => { - return R.pipe( - // Previous period columns. - R.when( - this.query.isPreviousPeriodActive, - R.append(this.getPreviousPeriodTotalHorizAccessor(index)) - ), - R.when( - this.query.isPreviousPeriodChangeActive, - R.append(this.getPreviousPeriodChangeHorizAccessor(index)) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - R.append(this.getPreviousPeriodPercentageHorizAccessor(index)) - ) - )([]); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousYear.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousYear.ts deleted file mode 100644 index fdc51877b..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTablePreviousYear.ts +++ /dev/null @@ -1,97 +0,0 @@ -import * as R from 'ramda'; -import { IDateRange, ITableColumn } from '@/interfaces'; -import { FinancialTablePreviousYear } from '../FinancialTablePreviousYear'; -import { FinancialDateRanges } from '../FinancialDateRanges'; - -export const BalanceSheetTablePreviousYear = (Base) => - class extends R.compose(FinancialTablePreviousYear, FinancialDateRanges)(Base) { - // -------------------- - // # Columns. - // -------------------- - /** - * Retrieves pervious year comparison columns. - * @returns {ITableColumn[]} - */ - protected getPreviousYearColumns = ( - dateRange?: IDateRange - ): ITableColumn[] => { - return R.pipe( - // Previous year columns. - R.when( - this.query.isPreviousYearActive, - R.append(this.getPreviousYearTotalColumn(dateRange)) - ), - R.when( - this.query.isPreviousYearChangeActive, - R.append(this.getPreviousYearChangeColumn()) - ), - R.when( - this.query.isPreviousYearPercentageActive, - R.append(this.getPreviousYearPercentageColumn()) - ) - )([]); - }; - - /** - * - * @param {IDateRange} dateRange - * @returns - */ - protected getPreviousYearHorizontalColumns = (dateRange: IDateRange) => { - const PYDateRange = this.getPreviousYearDateRange( - dateRange.fromDate, - dateRange.toDate - ); - return this.getPreviousYearColumns(PYDateRange); - }; - - // -------------------- - // # Accessors. - // -------------------- - /** - * Retrieves previous year columns accessors. - * @returns {ITableColumn[]} - */ - protected previousYearColumnAccessor = (): ITableColumn[] => { - return R.pipe( - // Previous year columns. - R.when( - this.query.isPreviousYearActive, - R.append(this.getPreviousYearTotalAccessor()) - ), - R.when( - this.query.isPreviousYearChangeActive, - R.append(this.getPreviousYearChangeAccessor()) - ), - R.when( - this.query.isPreviousYearPercentageActive, - R.append(this.getPreviousYearPercentageAccessor()) - ) - )([]); - }; - - /** - * Previous year period column accessor. - * @param {number} index - * @returns {ITableColumn[]} - */ - protected previousYearHorizontalColumnAccessors = ( - index: number - ): ITableColumn[] => { - return R.pipe( - // Previous year columns. - R.when( - this.query.isPreviousYearActive, - R.append(this.getPreviousYearTotalHorizAccessor(index)) - ), - R.when( - this.query.isPreviousYearChangeActive, - R.append(this.getPreviousYearChangeHorizAccessor(index)) - ), - R.when( - this.query.isPreviousYearPercentageActive, - R.append(this.getPreviousYearPercentageHorizAccessor(index)) - ) - )([]); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTotal.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTotal.ts deleted file mode 100644 index c04fd6d7b..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTotal.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as R from 'ramda'; - -export const BalanceSheetTotal = (Base: any) => class extends Base {}; diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/constants.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/constants.ts deleted file mode 100644 index 2081d2859..000000000 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/constants.ts +++ /dev/null @@ -1,64 +0,0 @@ -export const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' }; - -export const DISPLAY_COLUMNS_BY = { - DATE_PERIODS: 'date_periods', - TOTAL: 'total', -}; - -export enum IROW_TYPE { - AGGREGATE = 'AGGREGATE', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', - NET_INCOME = 'NET_INCOME', - TOTAL = 'TOTAL', -} - -export const HtmlTableCustomCss = ` -table tr.row-type--total td { - font-weight: 600; - border-top: 1px solid #bbb; - color: #000; -} -table tr.row-type--total.row-id--assets td, -table tr.row-type--total.row-id--liability-equity td { - border-bottom: 3px double #000; -} -table .column--name, -table .cell--name { - width: 400px; -} - -table .column--total { - width: 25%; -} - -table td.cell--total, -table td.cell--previous_year, -table td.cell--previous_year_change, -table td.cell--previous_year_percentage, - -table td.cell--previous_period, -table td.cell--previous_period_change, -table td.cell--previous_period_percentage, - -table td.cell--percentage_of_row, -table td.cell--percentage_of_column, -table td[class*="cell--date-range"] { - text-align: right; -} - -table .column--total, -table .column--previous_year, -table .column--previous_year_change, -table .column--previous_year_percentage, - -table .column--previous_period, -table .column--previous_period_change, -table .column--previous_period_percentage, - -table .column--percentage_of_row, -table .column--percentage_of_column, -table [class*="column--date-range"] { - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashFlow.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashFlow.ts deleted file mode 100644 index 019b252ba..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashFlow.ts +++ /dev/null @@ -1,703 +0,0 @@ -import * as R from 'ramda'; -import { defaultTo, map, set, sumBy, isEmpty, mapValues, get } from 'lodash'; -import * as mathjs from 'mathjs'; -import moment from 'moment'; -import { compose } from 'lodash/fp'; -import { - IAccount, - ILedger, - INumberFormatQuery, - ICashFlowSchemaSection, - ICashFlowStatementQuery, - ICashFlowStatementNetIncomeSection, - ICashFlowStatementAccountSection, - ICashFlowSchemaSectionAccounts, - ICashFlowStatementAccountMeta, - ICashFlowSchemaAccountRelation, - ICashFlowStatementSectionType, - ICashFlowStatementData, - ICashFlowSchemaTotalSection, - ICashFlowStatementTotalSection, - ICashFlowStatementSection, - ICashFlowCashBeginningNode, - ICashFlowStatementAggregateSection, -} from '@/interfaces'; -import CASH_FLOW_SCHEMA from './schema'; -import FinancialSheet from '../FinancialSheet'; -import { transformToMapBy, accumSum } from 'utils'; -import { ACCOUNT_ROOT_TYPE } from '@/data/AccountTypes'; -import { CashFlowStatementDatePeriods } from './CashFlowDatePeriods'; -import I18nService from '@/services/I18n/I18nService'; -import { DISPLAY_COLUMNS_BY } from './constants'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; - -export default class CashFlowStatement extends compose( - CashFlowStatementDatePeriods, - FinancialSheetStructure -)(FinancialSheet) { - readonly baseCurrency: string; - readonly i18n: I18nService; - readonly sectionsByIds = {}; - readonly cashFlowSchemaMap: Map; - readonly cashFlowSchemaSeq: Array; - readonly accountByTypeMap: Map; - readonly accountsByRootType: Map; - readonly ledger: ILedger; - readonly cashLedger: ILedger; - readonly netIncomeLedger: ILedger; - readonly query: ICashFlowStatementQuery; - readonly numberFormat: INumberFormatQuery; - readonly comparatorDateType: string; - readonly dateRangeSet: { fromDate: Date; toDate: Date }[]; - - /** - * Constructor method. - * @constructor - */ - constructor( - accounts: IAccount[], - ledger: ILedger, - cashLedger: ILedger, - netIncomeLedger: ILedger, - query: ICashFlowStatementQuery, - baseCurrency: string, - i18n - ) { - super(); - - this.baseCurrency = baseCurrency; - this.i18n = i18n; - this.ledger = ledger; - this.cashLedger = cashLedger; - this.netIncomeLedger = netIncomeLedger; - this.accountByTypeMap = transformToMapBy(accounts, 'accountType'); - this.accountsByRootType = transformToMapBy(accounts, 'accountRootType'); - this.query = query; - this.numberFormat = this.query.numberFormat; - this.dateRangeSet = []; - this.comparatorDateType = - query.displayColumnsType === 'total' ? 'day' : query.displayColumnsBy; - - this.initDateRangeCollection(); - } - - // -------------------------------------------- - // # GENERAL UTILITIES - // -------------------------------------------- - /** - * Retrieve the expense accounts ids. - * @return {number[]} - */ - private getAccountsIdsByType = (accountType: string): number[] => { - const expenseAccounts = this.accountsByRootType.get(accountType); - const expenseAccountsIds = map(expenseAccounts, 'id'); - - return expenseAccountsIds; - }; - - /** - * Detarmines the given display columns by type. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - private isDisplayColumnsBy = (displayColumnsBy: string): boolean => { - return this.query.displayColumnsType === displayColumnsBy; - }; - - /** - * Adjustments the given amount. - * @param {string} direction - * @param {number} amount - - * @return {number} - */ - private amountAdjustment = (direction: 'mines' | 'plus', amount): number => { - return R.when( - R.always(R.equals(direction, 'mines')), - R.multiply(-1) - )(amount); - }; - - // -------------------------------------------- - // # NET INCOME NODE - // -------------------------------------------- - /** - * Retrieve the accounts net income. - * @returns {number} - Amount of net income. - */ - private getAccountsNetIncome(): number { - // Mapping income/expense accounts ids. - const incomeAccountsIds = this.getAccountsIdsByType( - ACCOUNT_ROOT_TYPE.INCOME - ); - const expenseAccountsIds = this.getAccountsIdsByType( - ACCOUNT_ROOT_TYPE.EXPENSE - ); - // Income closing balance. - const incomeClosingBalance = accumSum(incomeAccountsIds, (id) => - this.netIncomeLedger.whereAccountId(id).getClosingBalance() - ); - // Expense closing balance. - const expenseClosingBalance = accumSum(expenseAccountsIds, (id) => - this.netIncomeLedger.whereAccountId(id).getClosingBalance() - ); - // Net income = income - expenses. - const netIncome = incomeClosingBalance - expenseClosingBalance; - - return netIncome; - } - - /** - * Parses the net income section from the given section schema. - * @param {ICashFlowSchemaSection} nodeSchema - Report section schema. - * @returns {ICashFlowStatementNetIncomeSection} - */ - private netIncomeSectionMapper = ( - nodeSchema: ICashFlowSchemaSection - ): ICashFlowStatementNetIncomeSection => { - const netIncome = this.getAccountsNetIncome(); - - const node = { - id: nodeSchema.id, - label: this.i18n.__(nodeSchema.label), - total: this.getAmountMeta(netIncome), - sectionType: ICashFlowStatementSectionType.NET_INCOME, - }; - return R.compose( - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - this.assocPeriodsToNetIncomeNode - ) - )(node); - }; - - // -------------------------------------------- - // # ACCOUNT NODE - // -------------------------------------------- - /** - * Retrieve account meta. - * @param {ICashFlowSchemaAccountRelation} relation - Account relation. - * @param {IAccount} account - - * @returns {ICashFlowStatementAccountMeta} - */ - private accountMetaMapper = ( - relation: ICashFlowSchemaAccountRelation, - account: IAccount - ): ICashFlowStatementAccountMeta => { - // Retrieve the closing balance of the given account. - const getClosingBalance = (id) => - this.ledger.whereAccountId(id).getClosingBalance(); - - const closingBalance = R.compose( - // Multiplies the amount by -1 in case the relation in mines. - R.curry(this.amountAdjustment)(relation.direction) - )(getClosingBalance(account.id)); - - const node = { - id: account.id, - code: account.code, - label: account.name, - accountType: account.accountType, - adjustmentType: relation.direction, - total: this.getAmountMeta(closingBalance), - sectionType: ICashFlowStatementSectionType.ACCOUNT, - }; - return R.compose( - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - this.assocPeriodsToAccountNode - ) - )(node); - }; - - /** - * Retrieve accounts sections by the given schema relation. - * @param {ICashFlowSchemaAccountRelation} relation - * @returns {ICashFlowStatementAccountMeta[]} - */ - private getAccountsBySchemaRelation = ( - relation: ICashFlowSchemaAccountRelation - ): ICashFlowStatementAccountMeta[] => { - const accounts = defaultTo(this.accountByTypeMap.get(relation.type), []); - const accountMetaMapper = R.curry(this.accountMetaMapper)(relation); - return R.map(accountMetaMapper)(accounts); - }; - - /** - * Retrieve the accounts meta. - * @param {string[]} types - * @returns {ICashFlowStatementAccountMeta[]} - */ - private getAccountsBySchemaRelations = ( - relations: ICashFlowSchemaAccountRelation[] - ): ICashFlowStatementAccountMeta[] => { - return R.pipe( - R.append(R.map(this.getAccountsBySchemaRelation)(relations)), - R.flatten - )([]); - }; - - /** - * Calculates the accounts total - * @param {ICashFlowStatementAccountMeta[]} accounts - * @returns {number} - */ - private getAccountsMetaTotal = ( - accounts: ICashFlowStatementAccountMeta[] - ): number => { - return sumBy(accounts, 'total.amount'); - }; - - /** - * Retrieve the accounts section from the section schema. - * @param {ICashFlowSchemaSectionAccounts} sectionSchema - * @returns {ICashFlowStatementAccountSection} - */ - private accountsSectionParser = ( - sectionSchema: ICashFlowSchemaSectionAccounts - ): ICashFlowStatementAccountSection => { - const { accountsRelations } = sectionSchema; - - const accounts = this.getAccountsBySchemaRelations(accountsRelations); - const accountsTotal = this.getAccountsMetaTotal(accounts); - const total = this.getTotalAmountMeta(accountsTotal); - - const node = { - sectionType: ICashFlowStatementSectionType.ACCOUNTS, - id: sectionSchema.id, - label: this.i18n.__(sectionSchema.label), - footerLabel: this.i18n.__(sectionSchema.footerLabel), - children: accounts, - total, - }; - return R.compose( - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - this.assocPeriodsToAggregateNode - ) - )(node); - }; - - /** - * Detarmines the schema section type. - * @param {string} type - * @param {ICashFlowSchemaSection} section - * @returns {boolean} - */ - private isSchemaSectionType = R.curry( - (type: string, section: ICashFlowSchemaSection): boolean => { - return type === section.sectionType; - } - ); - - // -------------------------------------------- - // # AGGREGATE NODE - // -------------------------------------------- - /** - * Aggregate schema node parser to aggregate report node. - * @param {ICashFlowSchemaSection} schemaSection - * @returns {ICashFlowStatementAggregateSection} - */ - private regularSectionParser = R.curry( - ( - children, - schemaSection: ICashFlowSchemaSection - ): ICashFlowStatementAggregateSection => { - const node = { - id: schemaSection.id, - label: this.i18n.__(schemaSection.label), - footerLabel: this.i18n.__(schemaSection.footerLabel), - sectionType: ICashFlowStatementSectionType.AGGREGATE, - children, - }; - return R.compose( - R.when( - this.isSchemaSectionType(ICashFlowStatementSectionType.AGGREGATE), - this.assocRegularSectionTotal - ), - R.when( - this.isSchemaSectionType(ICashFlowStatementSectionType.AGGREGATE), - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - this.assocPeriodsToAggregateNode - ) - ) - )(node); - } - ); - - private transformSectionsToMap = (sections: ICashFlowSchemaSection[]) => { - return this.reduceNodesDeep( - sections, - (acc, section) => { - if (section.id) { - acc[`${section.id}`] = section; - } - return acc; - }, - {} - ); - }; - - // -------------------------------------------- - // # TOTAL EQUATION NODE - // -------------------------------------------- - - private sectionsMapToTotal = (mappedSections: { [key: number]: any }) => { - return mapValues(mappedSections, (node) => get(node, 'total.amount') || 0); - }; - - /** - * Evauluate equaation string with the given scope table. - * @param {string} equation - - * @param {{ [key: string]: number }} scope - - * @return {number} - */ - private evaluateEquation = ( - equation: string, - scope: { [key: string | number]: number } - ): number => { - return mathjs.evaluate(equation, scope); - }; - - /** - * Retrieve the total section from the eqauation parser. - * @param {ICashFlowSchemaTotalSection} sectionSchema - * @param {ICashFlowSchemaSection[]} accumulatedSections - * @returns {ICashFlowStatementTotalSection} - */ - private totalEquationSectionParser = ( - accumulatedSections: ICashFlowSchemaSection[], - sectionSchema: ICashFlowSchemaTotalSection - ): ICashFlowStatementTotalSection => { - const mappedSectionsById = this.transformSectionsToMap(accumulatedSections); - const nodesTotalById = this.sectionsMapToTotal(mappedSectionsById); - - const total = this.evaluateEquation(sectionSchema.equation, nodesTotalById); - - return R.compose( - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - R.curry(this.assocTotalEquationDatePeriods)( - mappedSectionsById, - sectionSchema.equation - ) - ) - )({ - sectionType: ICashFlowStatementSectionType.TOTAL, - id: sectionSchema.id, - label: this.i18n.__(sectionSchema.label), - total: this.getTotalAmountMeta(total), - }); - }; - - /** - * Retrieve the beginning cash from date. - * @param {Date|string} fromDate - - * @return {Date} - */ - private beginningCashFrom = (fromDate: string | Date): Date => { - return moment(fromDate).subtract(1, 'days').toDate(); - }; - - /** - * Retrieve account meta. - * @param {ICashFlowSchemaAccountRelation} relation - * @param {IAccount} account - * @returns {ICashFlowStatementAccountMeta} - */ - private cashAccountMetaMapper = ( - relation: ICashFlowSchemaAccountRelation, - account: IAccount - ): ICashFlowStatementAccountMeta => { - const cashToDate = this.beginningCashFrom(this.query.fromDate); - - const closingBalance = this.cashLedger - .whereToDate(cashToDate) - .whereAccountId(account.id) - .getClosingBalance(); - - const node = { - id: account.id, - code: account.code, - label: account.name, - accountType: account.accountType, - adjustmentType: relation.direction, - total: this.getAmountMeta(closingBalance), - sectionType: ICashFlowStatementSectionType.ACCOUNT, - }; - return R.compose( - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - this.assocCashAtBeginningAccountDatePeriods - ) - )(node); - }; - - /** - * Retrieve accounts sections by the given schema relation. - * @param {ICashFlowSchemaAccountRelation} relation - * @returns {ICashFlowStatementAccountMeta[]} - */ - private getCashAccountsBySchemaRelation = ( - relation: ICashFlowSchemaAccountRelation - ): ICashFlowStatementAccountMeta[] => { - const accounts = this.accountByTypeMap.get(relation.type) || []; - const accountMetaMapper = R.curry(this.cashAccountMetaMapper)(relation); - return accounts.map(accountMetaMapper); - }; - - /** - * Retrieve the accounts meta. - * @param {string[]} types - * @returns {ICashFlowStatementAccountMeta[]} - */ - private getCashAccountsBySchemaRelations = ( - relations: ICashFlowSchemaAccountRelation[] - ): ICashFlowStatementAccountMeta[] => { - return R.concat(...R.map(this.getCashAccountsBySchemaRelation)(relations)); - }; - - /** - * Parses the cash at beginning section. - * @param {ICashFlowSchemaTotalSection} sectionSchema - - * @return {ICashFlowCashBeginningNode} - */ - private cashAtBeginningSectionParser = ( - nodeSchema: ICashFlowSchemaSection - ): ICashFlowCashBeginningNode => { - const { accountsRelations } = nodeSchema; - const children = this.getCashAccountsBySchemaRelations(accountsRelations); - const total = this.getAccountsMetaTotal(children); - - const node = { - sectionType: ICashFlowStatementSectionType.CASH_AT_BEGINNING, - id: nodeSchema.id, - label: this.i18n.__(nodeSchema.label), - children, - total: this.getTotalAmountMeta(total), - }; - return R.compose( - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - this.assocCashAtBeginningDatePeriods - ) - )(node); - }; - - /** - * Parses the schema section. - * @param {ICashFlowSchemaSection} schemaNode - * @returns {ICashFlowSchemaSection} - */ - private schemaSectionParser = ( - schemaNode: ICashFlowSchemaSection, - children - ): ICashFlowSchemaSection | ICashFlowStatementSection => { - return R.compose( - // Accounts node. - R.when( - this.isSchemaSectionType(ICashFlowStatementSectionType.ACCOUNTS), - this.accountsSectionParser - ), - // Net income node. - R.when( - this.isSchemaSectionType(ICashFlowStatementSectionType.NET_INCOME), - this.netIncomeSectionMapper - ), - // Cash at beginning node. - R.when( - this.isSchemaSectionType( - ICashFlowStatementSectionType.CASH_AT_BEGINNING - ), - this.cashAtBeginningSectionParser - ), - // Aggregate node. (that has no section type). - R.when( - this.isSchemaSectionType(ICashFlowStatementSectionType.AGGREGATE), - this.regularSectionParser(children) - ) - )(schemaNode); - }; - - /** - * Parses the schema section. - * @param {ICashFlowSchemaSection | ICashFlowStatementSection} section - * @param {number} key - * @param {ICashFlowSchemaSection[]} parentValue - * @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} accumulatedSections - * @returns {ICashFlowSchemaSection} - */ - private schemaSectionTotalParser = ( - section: ICashFlowSchemaSection | ICashFlowStatementSection, - key: number, - parentValue: ICashFlowSchemaSection[], - context, - accumulatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[] - ): ICashFlowSchemaSection | ICashFlowStatementSection => { - return R.compose( - // Total equation section. - R.when( - this.isSchemaSectionType(ICashFlowStatementSectionType.TOTAL), - R.curry(this.totalEquationSectionParser)(accumulatedSections) - ) - )(section); - }; - - /** - * Schema sections parser. - * @param {ICashFlowSchemaSection[]}schema - * @returns {ICashFlowStatementSection[]} - */ - private schemaSectionsParser = ( - schema: ICashFlowSchemaSection[] - ): ICashFlowStatementSection[] => { - return this.mapNodesDeepReverse(schema, this.schemaSectionParser); - }; - - /** - * Writes the `total` property to the aggregate node. - * @param {ICashFlowStatementSection} section - * @return {ICashFlowStatementSection} - */ - private assocRegularSectionTotal = (section: ICashFlowStatementSection) => { - const total = this.getAccountsMetaTotal(section.children); - return R.assoc('total', this.getTotalAmountMeta(total), section); - }; - - /** - * Parses total schema nodes. - * @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} sections - * @returns {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} - */ - private totalSectionsParser = ( - sections: (ICashFlowSchemaSection | ICashFlowStatementSection)[] - ): (ICashFlowSchemaSection | ICashFlowStatementSection)[] => { - return this.reduceNodesDeep( - sections, - (acc, value, key, parentValue, context) => { - set( - acc, - context.path, - this.schemaSectionTotalParser(value, key, parentValue, context, acc) - ); - return acc; - }, - [] - ); - }; - - // -------------------------------------------- - // REPORT FILTERING - // -------------------------------------------- - /** - * Detarmines the given section has children and not empty. - * @param {ICashFlowStatementSection} section - * @returns {boolean} - */ - private isSectionHasChildren = ( - section: ICashFlowStatementSection - ): boolean => { - return !isEmpty(section.children); - }; - - /** - * Detarmines whether the section has no zero amount. - * @param {ICashFlowStatementSection} section - * @returns {boolean} - */ - private isSectionNoneZero = (section: ICashFlowStatementSection): boolean => { - return section.total.amount !== 0; - }; - - /** - * Detarmines whether the parent accounts sections has children. - * @param {ICashFlowStatementSection} section - * @returns {boolean} - */ - private isAccountsSectionHasChildren = ( - section: ICashFlowStatementSection[] - ): boolean => { - return R.ifElse( - this.isSchemaSectionType(ICashFlowStatementSectionType.ACCOUNTS), - this.isSectionHasChildren, - R.always(true) - )(section); - }; - - /** - * Detarmines the account section has no zero otherwise returns true. - * @param {ICashFlowStatementSection} section - * @returns {boolean} - */ - private isAccountLeafNoneZero = ( - section: ICashFlowStatementSection[] - ): boolean => { - return R.ifElse( - this.isSchemaSectionType(ICashFlowStatementSectionType.ACCOUNT), - this.isSectionNoneZero, - R.always(true) - )(section); - }; - - /** - * Deep filters the non-zero accounts leafs of the report sections. - * @param {ICashFlowStatementSection[]} sections - * @returns {ICashFlowStatementSection[]} - */ - private filterNoneZeroAccountsLeafs = ( - sections: ICashFlowStatementSection[] - ): ICashFlowStatementSection[] => { - return this.filterNodesDeep(sections, this.isAccountLeafNoneZero); - }; - - /** - * Deep filter the non-children sections of the report sections. - * @param {ICashFlowStatementSection[]} sections - * @returns {ICashFlowStatementSection[]} - */ - private filterNoneChildrenSections = ( - sections: ICashFlowStatementSection[] - ): ICashFlowStatementSection[] => { - return this.filterNodesDeep(sections, this.isAccountsSectionHasChildren); - }; - - /** - * Filters the report data. - * @param {ICashFlowStatementSection[]} sections - * @returns {ICashFlowStatementSection[]} - */ - private filterReportData = ( - sections: ICashFlowStatementSection[] - ): ICashFlowStatementSection[] => { - return R.compose( - this.filterNoneChildrenSections, - this.filterNoneZeroAccountsLeafs - )(sections); - }; - - /** - * Schema parser. - * @param {ICashFlowSchemaSection[]} schema - * @returns {ICashFlowSchemaSection[]} - */ - private schemaParser = ( - schema: ICashFlowSchemaSection[] - ): ICashFlowSchemaSection[] => { - return R.compose( - R.when( - R.always(this.query.noneTransactions || this.query.noneZero), - this.filterReportData - ), - this.totalSectionsParser, - this.schemaSectionsParser - )(schema); - }; - - /** - * Retrieve the cashflow statement data. - * @return {ICashFlowStatementData} - */ - public reportData = (): ICashFlowStatementData => { - return this.schemaParser(R.clone(CASH_FLOW_SCHEMA)); - }; -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowDatePeriods.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashFlowDatePeriods.ts deleted file mode 100644 index 7d493cc5d..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowDatePeriods.ts +++ /dev/null @@ -1,411 +0,0 @@ -import * as R from 'ramda'; -import { sumBy, mapValues, get } from 'lodash'; -import { ACCOUNT_ROOT_TYPE } from '@/data/AccountTypes'; -import { accumSum, dateRangeFromToCollection } from 'utils'; -import { - ICashFlowDatePeriod, - ICashFlowStatementNetIncomeSection, - ICashFlowStatementAccountSection, - ICashFlowStatementSection, - ICashFlowSchemaTotalSection, - IFormatNumberSettings, - ICashFlowStatementTotalSection, - IDateRange, - ICashFlowStatementQuery, -} from '@/interfaces'; - -export const CashFlowStatementDatePeriods = (Base) => - class extends Base { - dateRangeSet: IDateRange[]; - query: ICashFlowStatementQuery; - - /** - * Initialize date range set. - */ - private initDateRangeCollection() { - this.dateRangeSet = dateRangeFromToCollection( - this.query.fromDate, - this.query.toDate, - this.comparatorDateType - ); - } - - /** - * Retrieve the date period meta. - * @param {number} total - Total amount. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - private getDatePeriodTotalMeta = ( - total: number, - fromDate: Date, - toDate: Date, - overrideSettings: IFormatNumberSettings = {} - ): ICashFlowDatePeriod => { - return this.getDatePeriodMeta(total, fromDate, toDate, { - money: true, - ...overrideSettings, - }); - }; - - /** - * Retrieve the date period meta. - * @param {number} total - Total amount. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - private getDatePeriodMeta = ( - total: number, - fromDate: Date, - toDate: Date, - overrideSettings?: IFormatNumberSettings - ): ICashFlowDatePeriod => { - return { - fromDate: this.getDateMeta(fromDate), - toDate: this.getDateMeta(toDate), - total: this.getAmountMeta(total, overrideSettings), - }; - }; - - // Net income -------------------- - /** - * Retrieve the net income between the given date range. - * @param {Date} fromDate - * @param {Date} toDate - * @returns {number} - */ - private getNetIncomeDateRange = (fromDate: Date, toDate: Date) => { - // Mapping income/expense accounts ids. - const incomeAccountsIds = this.getAccountsIdsByType( - ACCOUNT_ROOT_TYPE.INCOME - ); - const expenseAccountsIds = this.getAccountsIdsByType( - ACCOUNT_ROOT_TYPE.EXPENSE - ); - // Income closing balance. - const incomeClosingBalance = accumSum(incomeAccountsIds, (id) => - this.netIncomeLedger - .whereFromDate(fromDate) - .whereToDate(toDate) - .whereAccountId(id) - .getClosingBalance() - ); - // Expense closing balance. - const expenseClosingBalance = accumSum(expenseAccountsIds, (id) => - this.netIncomeLedger - .whereToDate(toDate) - .whereFromDate(fromDate) - .whereAccountId(id) - .getClosingBalance() - ); - // Net income = income - expenses. - const netIncome = incomeClosingBalance - expenseClosingBalance; - - return netIncome; - }; - - /** - * Retrieve the net income of date period. - * @param {IDateRange} dateRange - - * @retrun {ICashFlowDatePeriod} - */ - private getNetIncomeDatePeriod = (dateRange): ICashFlowDatePeriod => { - const total = this.getNetIncomeDateRange( - dateRange.fromDate, - dateRange.toDate - ); - return this.getDatePeriodMeta( - total, - dateRange.fromDate, - dateRange.toDate - ); - }; - - /** - * Retrieve the net income node between the given date ranges. - * @param {Date} fromDate - * @param {Date} toDate - * @returns {ICashFlowDatePeriod[]} - */ - private getNetIncomeDatePeriods = ( - section: ICashFlowStatementNetIncomeSection - ): ICashFlowDatePeriod[] => { - return this.dateRangeSet.map(this.getNetIncomeDatePeriod.bind(this)); - }; - - /** - * Writes periods property to net income section. - * @param {ICashFlowStatementNetIncomeSection} section - * @returns {ICashFlowStatementNetIncomeSection} - */ - protected assocPeriodsToNetIncomeNode = ( - section: ICashFlowStatementNetIncomeSection - ): ICashFlowStatementNetIncomeSection => { - const incomeDatePeriods = this.getNetIncomeDatePeriods(section); - return R.assoc('periods', incomeDatePeriods, section); - }; - - // Account nodes -------------------- - /** - * Retrieve the account total between date range. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {number} - */ - private getAccountTotalDateRange = ( - node: ICashFlowStatementAccountSection, - fromDate: Date, - toDate: Date - ): number => { - const closingBalance = this.ledger - .whereFromDate(fromDate) - .whereToDate(toDate) - .whereAccountId(node.id) - .getClosingBalance(); - - return this.amountAdjustment(node.adjustmentType, closingBalance); - }; - - /** - * Retrieve the given account node total date period. - * @param {ICashFlowStatementAccountSection} node - - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - private getAccountTotalDatePeriod = ( - node: ICashFlowStatementAccountSection, - fromDate: Date, - toDate: Date - ): ICashFlowDatePeriod => { - const total = this.getAccountTotalDateRange(node, fromDate, toDate); - return this.getDatePeriodMeta(total, fromDate, toDate); - }; - - /** - * Retrieve the accounts date periods nodes of the give account node. - * @param {ICashFlowStatementAccountSection} node - - * @return {ICashFlowDatePeriod[]} - */ - private getAccountDatePeriods = ( - node: ICashFlowStatementAccountSection - ): ICashFlowDatePeriod[] => { - return this.getNodeDatePeriods( - node, - this.getAccountTotalDatePeriod.bind(this) - ); - } - - /** - * Writes `periods` property to account node. - * @param {ICashFlowStatementAccountSection} node - - * @return {ICashFlowStatementAccountSection} - */ - protected assocPeriodsToAccountNode = ( - node: ICashFlowStatementAccountSection - ): ICashFlowStatementAccountSection => { - const datePeriods = this.getAccountDatePeriods(node); - return R.assoc('periods', datePeriods, node); - } - - // Aggregate node ------------------------- - /** - * Retrieve total of the given period index for node that has children nodes. - * @return {number} - */ - private getChildrenTotalPeriodByIndex = ( - node: ICashFlowStatementSection, - index: number - ): number => { - return sumBy(node.children, `periods[${index}].total.amount`); - } - - /** - * Retrieve date period meta of the given node index. - * @param {ICashFlowStatementSection} node - - * @param {number} index - Loop index. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - */ - private getChildrenTotalPeriodMetaByIndex( - node: ICashFlowStatementSection, - index: number, - fromDate: Date, - toDate: Date - ) { - const total = this.getChildrenTotalPeriodByIndex(node, index); - return this.getDatePeriodTotalMeta(total, fromDate, toDate); - } - - /** - * Retrieve the date periods of aggregate node. - * @param {ICashFlowStatementSection} node - */ - private getAggregateNodeDatePeriods(node: ICashFlowStatementSection) { - const getChildrenTotalPeriodMetaByIndex = R.curry( - this.getChildrenTotalPeriodMetaByIndex.bind(this) - )(node); - - return this.dateRangeSet.map((dateRange, index) => - getChildrenTotalPeriodMetaByIndex( - index, - dateRange.fromDate, - dateRange.toDate - ) - ); - } - - /** - * Writes `periods` property to aggregate section node. - * @param {ICashFlowStatementSection} node - - * @return {ICashFlowStatementSection} - */ - protected assocPeriodsToAggregateNode = ( - node: ICashFlowStatementSection - ): ICashFlowStatementSection => { - const datePeriods = this.getAggregateNodeDatePeriods(node); - return R.assoc('periods', datePeriods, node); - }; - - // Total equation node -------------------- - - private sectionsMapToTotalPeriod = ( - mappedSections: { [key: number]: any }, - index - ) => { - return mapValues( - mappedSections, - (node) => get(node, `periods[${index}].total.amount`) || 0 - ); - }; - - /** - * Retrieve the date periods of the given total equation. - * @param {ICashFlowSchemaTotalSection} - * @param {string} equation - - * @return {ICashFlowDatePeriod[]} - */ - private getTotalEquationDatePeriods = ( - node: ICashFlowSchemaTotalSection, - equation: string, - nodesTable - ): ICashFlowDatePeriod[] => { - return this.getNodeDatePeriods(node, (node, fromDate, toDate, index) => { - const periodScope = this.sectionsMapToTotalPeriod(nodesTable, index); - const total = this.evaluateEquation(equation, periodScope); - - return this.getDatePeriodTotalMeta(total, fromDate, toDate); - }); - }; - - /** - * Associates the total periods of total equation to the ginve total node.. - * @param {ICashFlowSchemaTotalSection} totalSection - - * @return {ICashFlowStatementTotalSection} - */ - protected assocTotalEquationDatePeriods = ( - nodesTable: any, - equation: string, - node: ICashFlowSchemaTotalSection - ): ICashFlowStatementTotalSection => { - const datePeriods = this.getTotalEquationDatePeriods( - node, - equation, - nodesTable - ); - - return R.assoc('periods', datePeriods, node); - }; - - // Cash at beginning ---------------------- - - /** - * Retrieve the date preioods of the given node and accumulated function. - * @param {} node - * @param {} - * @return {} - */ - private getNodeDatePeriods = (node, callback) => { - const curriedCallback = R.curry(callback)(node); - - return this.dateRangeSet.map((dateRange, index) => { - return curriedCallback(dateRange.fromDate, dateRange.toDate, index); - }); - }; - - /** - * Retrieve the account total between date range. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {number} - */ - private getBeginningCashAccountDateRange = ( - node: ICashFlowStatementSection, - fromDate: Date, - toDate: Date - ) => { - const cashToDate = this.beginningCashFrom(fromDate); - - return this.cashLedger - .whereToDate(cashToDate) - .whereAccountId(node.id) - .getClosingBalance(); - }; - - /** - * Retrieve the beginning cash date period. - * @param {ICashFlowStatementSection} node - - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - private getBeginningCashDatePeriod = ( - node: ICashFlowStatementSection, - fromDate: Date, - toDate: Date - ) => { - const total = this.getBeginningCashAccountDateRange( - node, - fromDate, - toDate - ); - return this.getDatePeriodTotalMeta(total, fromDate, toDate); - }; - - /** - * Retrieve the beginning cash account periods. - * @param {ICashFlowStatementSection} node - * @return {ICashFlowDatePeriod} - */ - private getBeginningCashAccountPeriods = ( - node: ICashFlowStatementSection - ): ICashFlowDatePeriod => { - return this.getNodeDatePeriods(node, this.getBeginningCashDatePeriod); - }; - - /** - * Writes `periods` property to cash at beginning date periods. - * @param {ICashFlowStatementSection} section - - * @return {ICashFlowStatementSection} - */ - protected assocCashAtBeginningDatePeriods = ( - node: ICashFlowStatementSection - ): ICashFlowStatementSection => { - const datePeriods = this.getAggregateNodeDatePeriods(node); - return R.assoc('periods', datePeriods, node); - }; - - /** - * Associates `periods` propery to cash at beginning account node. - * @param {ICashFlowStatementSection} node - - * @return {ICashFlowStatementSection} - */ - protected assocCashAtBeginningAccountDatePeriods = ( - node: ICashFlowStatementSection - ): ICashFlowStatementSection => { - const datePeriods = this.getBeginningCashAccountPeriods(node); - return R.assoc('periods', datePeriods, node); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowRepository.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashFlowRepository.ts deleted file mode 100644 index d7e7532ac..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowRepository.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import { Knex } from 'knex'; -import { isEmpty } from 'lodash'; -import { - ICashFlowStatementQuery, - IAccountTransaction, - IAccount, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class CashFlowRepository { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve the group type from periods type. - * @param {string} displayType - * @returns {string} - */ - protected getGroupTypeFromPeriodsType(displayType: string) { - const displayTypes = { - year: 'year', - day: 'day', - month: 'month', - quarter: 'month', - week: 'day', - }; - return displayTypes[displayType] || 'month'; - } - - /** - * Retrieve the cashflow accounts. - * @returns {Promise} - */ - public async cashFlowAccounts(tenantId: number): Promise { - const { Account } = this.tenancy.models(tenantId); - - const accounts = await Account.query(); - - return accounts; - } - - /** - * Retrieve total of csah at beginning transactions. - * @param {number} tenantId - - * @param {ICashFlowStatementQuery} filter - - * @return {Promise} - */ - public cashAtBeginningTotalTransactions( - tenantId: number, - filter: ICashFlowStatementQuery - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - const cashBeginningPeriod = moment(filter.fromDate) - .subtract(1, 'day') - .toDate(); - - return AccountTransaction.query().onBuild((query) => { - query.modify('creditDebitSummation'); - - query.select('accountId'); - query.groupBy('accountId'); - - query.withGraphFetched('account'); - query.modify('filterDateRange', null, cashBeginningPeriod); - - this.commonFilterBranchesQuery(filter, query); - }); - } - - /** - * Retrieve accounts transactions. - * @param {number} tenantId - - * @param {ICashFlowStatementQuery} filter - * @return {Promise} - */ - public getAccountsTransactions( - tenantId: number, - filter: ICashFlowStatementQuery - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - const groupByDateType = this.getGroupTypeFromPeriodsType( - filter.displayColumnsBy - ); - - return AccountTransaction.query().onBuild((query) => { - query.modify('creditDebitSummation'); - query.modify('groupByDateFormat', groupByDateType); - - query.select('accountId'); - - query.groupBy('accountId'); - query.withGraphFetched('account'); - - query.modify('filterDateRange', filter.fromDate, filter.toDate); - - this.commonFilterBranchesQuery(filter, query); - }); - } - - /** - * Retrieve the net income tranasctions. - * @param {number} tenantId - - * @param {ICashFlowStatementQuery} query - - * @return {Promise} - */ - public getNetIncomeTransactions( - tenantId: number, - filter: ICashFlowStatementQuery - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - const groupByDateType = this.getGroupTypeFromPeriodsType( - filter.displayColumnsBy - ); - - return AccountTransaction.query().onBuild((query) => { - query.modify('creditDebitSummation'); - query.modify('groupByDateFormat', groupByDateType); - - query.select('accountId'); - query.groupBy('accountId'); - - query.withGraphFetched('account'); - query.modify('filterDateRange', filter.fromDate, filter.toDate); - - this.commonFilterBranchesQuery(filter, query); - }); - } - - /** - * Retrieve peridos of cash at beginning transactions. - * @param {number} tenantId - - * @param {ICashFlowStatementQuery} filter - - * @return {Promise} - */ - public cashAtBeginningPeriodTransactions( - tenantId: number, - filter: ICashFlowStatementQuery - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - const groupByDateType = this.getGroupTypeFromPeriodsType( - filter.displayColumnsBy - ); - - return AccountTransaction.query().onBuild((query) => { - query.modify('creditDebitSummation'); - query.modify('groupByDateFormat', groupByDateType); - - query.select('accountId'); - query.groupBy('accountId'); - - query.withGraphFetched('account'); - query.modify('filterDateRange', filter.fromDate, filter.toDate); - - this.commonFilterBranchesQuery(filter, query); - }); - } - - /** - * Common branches filter query. - * @param {Knex.QueryBuilder} query - */ - private commonFilterBranchesQuery = ( - query: ICashFlowStatementQuery, - knexQuery: Knex.QueryBuilder - ) => { - if (!isEmpty(query.branchesIds)) { - knexQuery.modify('filterByBranches', query.branchesIds); - } - }; -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowService.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashFlowService.ts deleted file mode 100644 index 201a31be4..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowService.ts +++ /dev/null @@ -1,154 +0,0 @@ -import moment from 'moment'; -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import FinancialSheet from '../FinancialSheet'; -import { - ICashFlowStatementService, - ICashFlowStatementQuery, - ICashFlowStatementDOO, - IAccountTransaction, - ICashFlowStatementMeta, -} from '@/interfaces'; -import CashFlowStatement from './CashFlow'; -import Ledger from '@/services/Accounting/Ledger'; -import CashFlowRepository from './CashFlowRepository'; -import InventoryService from '@/services/Inventory/Inventory'; -import { parseBoolean } from 'utils'; -import { Tenant } from '@/system/models'; -import { CashflowSheetMeta } from './CashflowSheetMeta'; - -@Service() -export default class CashFlowStatementService - extends FinancialSheet - implements ICashFlowStatementService -{ - @Inject() - tenancy: TenancyService; - - @Inject() - cashFlowRepo: CashFlowRepository; - - @Inject() - inventoryService: InventoryService; - - @Inject() - private cashflowSheetMeta: CashflowSheetMeta; - - /** - * Defaults balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - get defaultQuery(): ICashFlowStatementQuery { - return { - displayColumnsType: 'total', - displayColumnsBy: 'day', - fromDate: moment().startOf('year').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - noneZero: false, - noneTransactions: false, - basis: 'cash', - }; - } - - /** - * Retrieve cash at beginning transactions. - * @param {number} tenantId - - * @param {ICashFlowStatementQuery} filter - - * @retrun {Promise} - */ - private async cashAtBeginningTransactions( - tenantId: number, - filter: ICashFlowStatementQuery - ): Promise { - const appendPeriodsOperToChain = (trans) => - R.append( - this.cashFlowRepo.cashAtBeginningPeriodTransactions(tenantId, filter), - trans - ); - - const promisesChain = R.pipe( - R.append( - this.cashFlowRepo.cashAtBeginningTotalTransactions(tenantId, filter) - ), - R.when( - R.always(R.equals(filter.displayColumnsType, 'date_periods')), - appendPeriodsOperToChain - ) - )([]); - const promisesResults = await Promise.all(promisesChain); - const transactions = R.flatten(promisesResults); - - return transactions; - } - - /** - * Retrieve the cash flow sheet statement. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async cashFlow( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - // Retrieve all accounts on the storage. - const accounts = await this.cashFlowRepo.cashFlowAccounts(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - // Retrieve the accounts transactions. - const transactions = await this.cashFlowRepo.getAccountsTransactions( - tenantId, - filter - ); - // Retrieve the net income transactions. - const netIncome = await this.cashFlowRepo.getNetIncomeTransactions( - tenantId, - filter - ); - // Retrieve the cash at beginning transactions. - const cashAtBeginningTransactions = await this.cashAtBeginningTransactions( - tenantId, - filter - ); - // Transformes the transactions to ledgers. - const ledger = Ledger.fromTransactions(transactions); - const cashLedger = Ledger.fromTransactions(cashAtBeginningTransactions); - const netIncomeLedger = Ledger.fromTransactions(netIncome); - - // Cash flow statement. - const cashFlowInstance = new CashFlowStatement( - accounts, - ledger, - cashLedger, - netIncomeLedger, - filter, - tenant.metadata.baseCurrency, - i18n - ); - // Retrieve the cashflow sheet meta. - const meta = await this.cashflowSheetMeta.meta(tenantId, filter); - - return { - data: cashFlowInstance.reportData(), - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowTable.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashFlowTable.ts deleted file mode 100644 index 7b49a685c..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashFlowTable.ts +++ /dev/null @@ -1,373 +0,0 @@ -import * as R from 'ramda'; -import { isEmpty, times } from 'lodash'; -import moment from 'moment'; -import { - ICashFlowStatementSection, - ICashFlowStatementSectionType, - ICashFlowStatement, - ITableRow, - ITableColumn, - ICashFlowStatementQuery, - IDateRange, - ICashFlowStatementDOO, -} from '@/interfaces'; -import { dateRangeFromToCollection, tableRowMapper } from 'utils'; -import { mapValuesDeep } from 'utils/deepdash'; - -enum IROW_TYPE { - AGGREGATE = 'AGGREGATE', - NET_INCOME = 'NET_INCOME', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', - TOTAL = 'TOTAL', -} -const DEEP_CONFIG = { childrenPath: 'children', pathFormat: 'array' }; -const DISPLAY_COLUMNS_BY = { - DATE_PERIODS: 'date_periods', - TOTAL: 'total', -}; - -export default class CashFlowTable implements ICashFlowTable { - private report: ICashFlowStatementDOO; - private i18n; - private dateRangeSet: IDateRange[]; - - /** - * Constructor method. - * @param {ICashFlowStatement} reportStatement - */ - constructor(reportStatement: ICashFlowStatementDOO, i18n) { - this.report = reportStatement; - this.i18n = i18n; - this.dateRangeSet = []; - this.initDateRangeCollection(); - } - - /** - * Initialize date range set. - */ - private initDateRangeCollection() { - this.dateRangeSet = dateRangeFromToCollection( - this.report.query.fromDate, - this.report.query.toDate, - this.report.query.displayColumnsBy - ); - } - - /** - * Retrieve the date periods columns accessors. - */ - private datePeriodsColumnsAccessors = () => { - return this.dateRangeSet.map((dateRange: IDateRange, index) => ({ - key: `date-range-${index}`, - accessor: `periods[${index}].total.formattedAmount`, - })); - }; - - /** - * Retrieve the total column accessor. - */ - private totalColumnAccessor = () => { - return [{ key: 'total', accessor: 'total.formattedAmount' }]; - }; - - /** - * Retrieve the common columns for all report nodes. - */ - private commonColumns = () => { - return R.compose( - R.concat([{ key: 'name', accessor: 'label' }]), - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - R.concat(this.datePeriodsColumnsAccessors()) - ), - R.concat(this.totalColumnAccessor()) - )([]); - }; - - /** - * Retrieve the table rows of regular section. - * @param {ICashFlowStatementSection} section - * @returns {ITableRow[]} - */ - private regularSectionMapper = ( - section: ICashFlowStatementSection - ): ITableRow => { - const columns = this.commonColumns(); - - return tableRowMapper(section, columns, { - rowTypes: [IROW_TYPE.AGGREGATE], - id: section.id, - }); - }; - - /** - * Retrieve the net income table rows of the section. - * @param {ICashFlowStatementSection} section - * @returns {ITableRow} - */ - private netIncomeSectionMapper = ( - section: ICashFlowStatementSection - ): ITableRow => { - const columns = this.commonColumns(); - - return tableRowMapper(section, columns, { - rowTypes: [IROW_TYPE.NET_INCOME, IROW_TYPE.TOTAL], - id: section.id, - }); - }; - - /** - * Retrieve the accounts table rows of the section. - * @param {ICashFlowStatementSection} section - * @returns {ITableRow} - */ - private accountsSectionMapper = ( - section: ICashFlowStatementSection - ): ITableRow => { - const columns = this.commonColumns(); - - return tableRowMapper(section, columns, { - rowTypes: [IROW_TYPE.ACCOUNTS], - id: section.id, - }); - }; - - /** - * Retrieve the account table row of account section. - * @param {ICashFlowStatementSection} section - * @returns {ITableRow} - */ - private accountSectionMapper = ( - section: ICashFlowStatementSection - ): ITableRow => { - const columns = this.commonColumns(); - - return tableRowMapper(section, columns, { - rowTypes: [IROW_TYPE.ACCOUNT], - id: `account-${section.id}`, - }); - }; - - /** - * Retrieve the total table rows from the given total section. - * @param {ICashFlowStatementSection} section - * @returns {ITableRow} - */ - private totalSectionMapper = ( - section: ICashFlowStatementSection - ): ITableRow => { - const columns = this.commonColumns(); - - return tableRowMapper(section, columns, { - rowTypes: [IROW_TYPE.TOTAL], - id: section.id, - }); - }; - - /** - * Detarmines the schema section type. - * @param {string} type - * @param {ICashFlowSchemaSection} section - * @returns {boolean} - */ - private isSectionHasType = ( - type: string, - section: ICashFlowStatementSection - ): boolean => { - return type === section.sectionType; - }; - - /** - * The report section mapper. - * @param {ICashFlowStatementSection} section - * @returns {ITableRow} - */ - private sectionMapper = ( - section: ICashFlowStatementSection, - key: string, - parentSection: ICashFlowStatementSection - ): ITableRow => { - const isSectionHasType = R.curry(this.isSectionHasType); - - return R.pipe( - R.when( - isSectionHasType(ICashFlowStatementSectionType.AGGREGATE), - this.regularSectionMapper - ), - R.when( - isSectionHasType(ICashFlowStatementSectionType.CASH_AT_BEGINNING), - this.regularSectionMapper - ), - R.when( - isSectionHasType(ICashFlowStatementSectionType.NET_INCOME), - this.netIncomeSectionMapper - ), - R.when( - isSectionHasType(ICashFlowStatementSectionType.ACCOUNTS), - this.accountsSectionMapper - ), - R.when( - isSectionHasType(ICashFlowStatementSectionType.ACCOUNT), - this.accountSectionMapper - ), - R.when( - isSectionHasType(ICashFlowStatementSectionType.TOTAL), - this.totalSectionMapper - ) - )(section); - }; - - /** - * Mappes the sections to the table rows. - * @param {ICashFlowStatementSection[]} sections - * @returns {ITableRow[]} - */ - private mapSectionsToTableRows = ( - sections: ICashFlowStatementSection[] - ): ITableRow[] => { - return mapValuesDeep(sections, this.sectionMapper.bind(this), DEEP_CONFIG); - }; - - /** - * Appends the total to section's children. - * @param {ICashFlowStatementSection} section - * @returns {ICashFlowStatementSection} - */ - private appendTotalToSectionChildren = ( - section: ICashFlowStatementSection - ): ICashFlowStatementSection => { - const label = section.footerLabel - ? section.footerLabel - : this.i18n.__('Total {{accountName}}', { accountName: section.label }); - - section.children.push({ - sectionType: ICashFlowStatementSectionType.TOTAL, - label, - periods: section.periods, - total: section.total, - }); - return section; - }; - - /** - * - * @param {ICashFlowStatementSection} section - * @returns {ICashFlowStatementSection} - */ - private mapSectionsToAppendTotalChildren = ( - section: ICashFlowStatementSection - ): ICashFlowStatementSection => { - const isSectionHasChildren = (section) => !isEmpty(section.children); - - return R.compose( - R.when(isSectionHasChildren, this.appendTotalToSectionChildren.bind(this)) - )(section); - }; - - /** - * Appends total node to children section. - * @param {ICashFlowStatementSection[]} sections - * @returns {ICashFlowStatementSection[]} - */ - private appendTotalToChildren = (sections: ICashFlowStatementSection[]) => { - return mapValuesDeep( - sections, - this.mapSectionsToAppendTotalChildren.bind(this), - DEEP_CONFIG - ); - }; - - /** - * Retrieve the table rows of cash flow statement. - * @param {ICashFlowStatementSection[]} sections - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - const sections = this.report.data; - - return R.pipe( - this.appendTotalToChildren, - this.mapSectionsToTableRows - )(sections); - }; - - /** - * Retrieve the total columns. - * @returns {ITableColumn} - */ - private totalColumns = (): ITableColumn[] => { - return [{ key: 'total', label: this.i18n.__('Total') }]; - }; - - /** - * Retrieve the formatted column label from the given date range. - * @param {ICashFlowDateRange} dateRange - - * @return {string} - */ - private formatColumnLabel = (dateRange: ICashFlowDateRange) => { - const monthFormat = (range) => moment(range.toDate).format('YYYY-MM'); - const yearFormat = (range) => moment(range.toDate).format('YYYY'); - const dayFormat = (range) => moment(range.toDate).format('YYYY-MM-DD'); - - const conditions = [ - ['month', monthFormat], - ['year', yearFormat], - ['day', dayFormat], - ['quarter', monthFormat], - ['week', dayFormat], - ]; - const conditionsPairs = R.map( - ([type, formatFn]) => [ - R.always(this.isDisplayColumnsType(type)), - formatFn, - ], - conditions - ); - - return R.compose(R.cond(conditionsPairs))(dateRange); - }; - - /** - * Date periods columns. - * @returns {ITableColumn[]} - */ - private datePeriodsColumns = (): ITableColumn[] => { - return this.dateRangeSet.map((dateRange, index) => ({ - key: `date-range-${index}`, - label: this.formatColumnLabel(dateRange), - })); - }; - - /** - * Detarmines the given column type is the current. - * @reutrns {boolean} - */ - private isDisplayColumnsBy = (displayColumnsType: string): Boolean => { - return this.report.query.displayColumnsType === displayColumnsType; - }; - - /** - * Detarmines whether the given display columns type is the current. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - private isDisplayColumnsType = (displayColumnsBy: string): Boolean => { - return this.report.query.displayColumnsBy === displayColumnsBy; - }; - - /** - * Retrieve the table columns. - * @return {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return R.compose( - R.concat([{ key: 'name', label: this.i18n.__('Account name') }]), - R.when( - R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)), - R.concat(this.datePeriodsColumns()) - ), - R.concat(this.totalColumns()) - )([]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowExportInjectable.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowExportInjectable.ts deleted file mode 100644 index 8562cfbf5..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashflowExportInjectable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICashFlowStatementQuery } from '@/interfaces'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { CashflowTableInjectable } from './CashflowTableInjectable'; - -@Service() -export class CashflowExportInjectable { - @Inject() - private cashflowSheetTable: CashflowTableInjectable; - - /** - * Retrieves the cashflow sheet in XLSX format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const table = await this.cashflowSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the cashflow sheet in CSV format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const table = await this.cashflowSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts deleted file mode 100644 index 72a587f52..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CashflowExportInjectable } from './CashflowExportInjectable'; -import { ICashFlowStatementQuery } from '@/interfaces'; -import CashFlowStatementService from './CashFlowService'; -import { CashflowTableInjectable } from './CashflowTableInjectable'; -import { CashflowTablePdfInjectable } from './CashflowTablePdfInjectable'; - -@Service() -export class CashflowSheetApplication { - @Inject() - private cashflowExport: CashflowExportInjectable; - - @Inject() - private cashflowSheet: CashFlowStatementService; - - @Inject() - private cashflowTable: CashflowTableInjectable; - - @Inject() - private cashflowPdf: CashflowTablePdfInjectable; - - /** - * Retrieves the cashflow sheet - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - */ - public async sheet(tenantId: number, query: ICashFlowStatementQuery) { - return this.cashflowSheet.cashFlow(tenantId, query); - } - - /** - * Retrieves the cashflow sheet in table format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - */ - public async table(tenantId: number, query: ICashFlowStatementQuery) { - return this.cashflowTable.table(tenantId, query); - } - - /** - * Retrieves the cashflow sheet in XLSX format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: ICashFlowStatementQuery) { - return this.cashflowExport.xlsx(tenantId, query); - } - - /** - * Retrieves the cashflow sheet in CSV format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - return this.cashflowExport.csv(tenantId, query); - } - - /** - * Retrieves the cashflow sheet in pdf format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - return this.cashflowPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetMeta.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetMeta.ts deleted file mode 100644 index 3a1dd40dc..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetMeta.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import { ICashFlowStatementMeta, ICashFlowStatementQuery } from '@/interfaces'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; - -@Service() -export class CashflowSheetMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * CAshflow sheet meta. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async meta( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const meta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - const sheetName = 'Statement of Cash Flow'; - - return { - ...meta, - sheetName, - formattedToDate, - formattedFromDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowTableInjectable.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowTableInjectable.ts deleted file mode 100644 index 0a54071f2..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashflowTableInjectable.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from "typedi"; -import { ICashFlowStatementQuery, ICashFlowStatementTable } from "@/interfaces"; -import HasTenancyService from "@/services/Tenancy/TenancyService"; -import CashFlowTable from "./CashFlowTable"; -import CashFlowStatementService from "./CashFlowService"; - -@Service() -export class CashflowTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private cashflowSheet: CashFlowStatementService; - - /** - * Retrieves the cash flow table. - * @returns {Promise} - */ - public async table( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const cashflowDOO = await this.cashflowSheet.cashFlow(tenantId, query); - const cashflowTable = new CashFlowTable(cashflowDOO, i18n); - - return { - table: { - columns: cashflowTable.tableColumns(), - rows: cashflowTable.tableRows(), - }, - query: cashflowDOO.query, - meta: cashflowDOO.meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts deleted file mode 100644 index be7cb5382..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject } from 'typedi'; -import { CashflowTableInjectable } from './CashflowTableInjectable'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { ICashFlowStatementQuery } from '@/interfaces'; -import { HtmlTableCustomCss } from './constants'; - -export class CashflowTablePdfInjectable { - @Inject() - private cashflowTable: CashflowTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given cashflow sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const table = await this.cashflowTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/CashFlow/constants.ts b/packages/server/src/services/FinancialStatements/CashFlow/constants.ts deleted file mode 100644 index f3f1858fb..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/constants.ts +++ /dev/null @@ -1,33 +0,0 @@ -export const DISPLAY_COLUMNS_BY = { - DATE_PERIODS: 'date_periods', - TOTAL: 'total', -}; - -export const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' }; -export const HtmlTableCustomCss = ` -table tr.row-type--accounts td { - border-top: 1px solid #bbb; -} -table tr.row-id--cash-end-period td { - border-bottom: 3px double #333; -} -table tr.row-type--total { - font-weight: 600; -} -table tr.row-type--total td { - color: #000; -} -table tr.row-type--total:not(:first-child) td { - border-top: 1px solid #bbb; -} -table .column--name, -table .cell--name { - width: 400px; -} -table .column--total, -table .cell--total, -table [class*="column--date-range"], -table [class*="cell--date-range"] { - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/CashFlow/schema.ts b/packages/server/src/services/FinancialStatements/CashFlow/schema.ts deleted file mode 100644 index f12520e63..000000000 --- a/packages/server/src/services/FinancialStatements/CashFlow/schema.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ICashFlowSchemaSection, CASH_FLOW_SECTION_ID, ICashFlowStatementSectionType } from '@/interfaces'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -export default [ - { - id: CASH_FLOW_SECTION_ID.OPERATING, - label: 'OPERATING ACTIVITIES', - sectionType: ICashFlowStatementSectionType.AGGREGATE, - children: [ - { - id: CASH_FLOW_SECTION_ID.NET_INCOME, - label: 'Net income', - sectionType: ICashFlowStatementSectionType.NET_INCOME, - }, - { - id: CASH_FLOW_SECTION_ID.OPERATING_ACCOUNTS, - label: 'Adjustments net income by operating activities.', - sectionType: ICashFlowStatementSectionType.ACCOUNTS, - accountsRelations: [ - { type: ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE, direction: 'mines' }, - { type: ACCOUNT_TYPE.INVENTORY, direction: 'mines' }, - { type: ACCOUNT_TYPE.NON_CURRENT_ASSET, direction: 'mines' }, - { type: ACCOUNT_TYPE.ACCOUNTS_PAYABLE, direction: 'plus' }, - { type: ACCOUNT_TYPE.CREDIT_CARD, direction: 'plus' }, - { type: ACCOUNT_TYPE.TAX_PAYABLE, direction: 'plus' }, - { type: ACCOUNT_TYPE.OTHER_CURRENT_ASSET, direction: 'mines' }, - { type: ACCOUNT_TYPE.OTHER_CURRENT_LIABILITY, direction: 'plus' }, - { type: ACCOUNT_TYPE.NON_CURRENT_LIABILITY, direction: 'plus' }, - ], - showAlways: true, - }, - ], - footerLabel: 'Net cash provided by operating activities', - }, - { - id: CASH_FLOW_SECTION_ID.INVESTMENT, - sectionType: ICashFlowStatementSectionType.ACCOUNTS, - label: 'INVESTMENT ACTIVITIES', - accountsRelations: [ - { type: ACCOUNT_TYPE.FIXED_ASSET, direction: 'mines' } - ], - footerLabel: 'Net cash provided by investing activities', - }, - { - id: CASH_FLOW_SECTION_ID.FINANCIAL, - label: 'FINANCIAL ACTIVITIES', - sectionType: ICashFlowStatementSectionType.ACCOUNTS, - accountsRelations: [ - { type: ACCOUNT_TYPE.LOGN_TERM_LIABILITY, direction: 'plus' }, - { type: ACCOUNT_TYPE.EQUITY, direction: 'plus' }, - ], - footerLabel: 'Net cash provided by financing activities', - }, - { - id: CASH_FLOW_SECTION_ID.CASH_BEGINNING_PERIOD, - sectionType: ICashFlowStatementSectionType.CASH_AT_BEGINNING, - label: 'Cash at beginning of period', - accountsRelations: [ - { type: ACCOUNT_TYPE.CASH, direction: 'plus' }, - { type: ACCOUNT_TYPE.BANK, direction: 'plus' }, - ], - }, - { - id: CASH_FLOW_SECTION_ID.NET_CASH_INCREASE, - sectionType: ICashFlowStatementSectionType.TOTAL, - equation: 'OPERATING + INVESTMENT + FINANCIAL', - label: 'NET CASH INCREASE FOR PERIOD', - }, - { - id: CASH_FLOW_SECTION_ID.CASH_END_PERIOD, - label: 'CASH AT END OF PERIOD', - sectionType: ICashFlowStatementSectionType.TOTAL, - equation: 'NET_CASH_INCREASE + CASH_BEGINNING_PERIOD', - }, -] as ICashFlowSchemaSection[]; diff --git a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactions.ts b/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactions.ts deleted file mode 100644 index f287c0268..000000000 --- a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactions.ts +++ /dev/null @@ -1,200 +0,0 @@ -import R from 'ramda'; -import moment from 'moment'; -import { first, isEmpty } from 'lodash'; -import { - ICashflowAccountTransaction, - ICashflowAccountTransactionsQuery, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { runningAmount } from 'utils'; -import { CashflowAccountTransactionsRepo } from './CashflowAccountTransactionsRepo'; -import { BankTransactionStatus } from './constants'; -import { formatBankTransactionsStatus } from './utils'; - -export class CashflowAccountTransactionReport extends FinancialSheet { - private runningBalance: any; - private query: ICashflowAccountTransactionsQuery; - private repo: CashflowAccountTransactionsRepo; - - /** - * Constructor method. - * @param {IAccountTransaction[]} transactions - - * @param {number} openingBalance - - * @param {ICashflowAccountTransactionsQuery} query - - */ - constructor( - repo: CashflowAccountTransactionsRepo, - query: ICashflowAccountTransactionsQuery - ) { - super(); - - this.repo = repo; - this.query = query; - this.runningBalance = runningAmount(this.repo.openingBalance); - } - - /** - * Retrieves the transaction status. - * @param {} transaction - * @returns {BankTransactionStatus} - */ - private getTransactionStatus(transaction: any): BankTransactionStatus { - const categorizedTrans = this.repo.uncategorizedTransactionsMapByRef.get( - `${transaction.referenceType}-${transaction.referenceId}` - ); - const matchedTrans = this.repo.matchedBankTransactionsMapByRef.get( - `${transaction.referenceType}-${transaction.referenceId}` - ); - if (!isEmpty(categorizedTrans)) { - return BankTransactionStatus.Categorized; - } else if (!isEmpty(matchedTrans)) { - return BankTransactionStatus.Matched; - } else { - return BankTransactionStatus.Manual; - } - } - - /** - * Retrieves the uncategoized transaction id from the given transaction. - * @param transaction - * @returns {number|null} - */ - private getUncategorizedTransId(transaction: any): number { - // The given transaction would be categorized, matched or not, so we'd take a look at - // the categorized transaction first to get the id if not exist, then should look at the matched - // transaction if not exist too, so the given transaction has no uncategorized transaction id. - const categorizedTrans = this.repo.uncategorizedTransactionsMapByRef.get( - `${transaction.referenceType}-${transaction.referenceId}` - ); - const matchedTrans = this.repo.matchedBankTransactionsMapByRef.get( - `${transaction.referenceType}-${transaction.referenceId}` - ); - // Relation between the transaction and matching always been one-to-one. - const firstCategorizedTrans = first(categorizedTrans); - const firstMatchedTrans = first(matchedTrans); - - return ( - firstCategorizedTrans?.id || - firstMatchedTrans?.uncategorizedTransactionId || - null - ); - } - - /** - *Transformes the account transaction to to cashflow transaction node. - * @param {IAccountTransaction} transaction - * @returns {ICashflowAccountTransaction} - */ - private transactionNode = (transaction: any): ICashflowAccountTransaction => { - const status = this.getTransactionStatus(transaction); - const uncategorizedTransactionId = - this.getUncategorizedTransId(transaction); - - return { - date: transaction.date, - formattedDate: moment(transaction.date).format('YYYY-MM-DD'), - - withdrawal: transaction.credit, - deposit: transaction.debit, - - formattedDeposit: this.formatNumber(transaction.debit), - formattedWithdrawal: this.formatNumber(transaction.credit), - - referenceId: transaction.referenceId, - referenceType: transaction.referenceType, - - formattedTransactionType: transaction.referenceTypeFormatted, - - transactionNumber: transaction.transactionNumber, - referenceNumber: transaction.referenceNumber, - - runningBalance: this.runningBalance.amount(), - formattedRunningBalance: this.formatNumber(this.runningBalance.amount()), - - balance: 0, - formattedBalance: '', - status, - formattedStatus: formatBankTransactionsStatus(status), - uncategorizedTransactionId, - }; - }; - - /** - * Associate cashflow transaction node with running balance attribute. - * @param {IAccountTransaction} transaction - * @returns {ICashflowAccountTransaction} - */ - private transactionRunningBalance = ( - transaction: ICashflowAccountTransaction - ): ICashflowAccountTransaction => { - const amount = transaction.deposit - transaction.withdrawal; - - const biggerThanZero = R.lt(0, amount); - const lowerThanZero = R.gt(0, amount); - - const absAmount = Math.abs(amount); - - R.when(R.always(biggerThanZero), this.runningBalance.decrement)(absAmount); - R.when(R.always(lowerThanZero), this.runningBalance.increment)(absAmount); - - const runningBalance = this.runningBalance.amount(); - - return { - ...transaction, - runningBalance, - formattedRunningBalance: this.formatNumber(runningBalance), - }; - }; - - /** - * Associate to balance attribute to cashflow transaction node. - * @param {ICashflowAccountTransaction} transaction - * @returns {ICashflowAccountTransaction} - */ - private transactionBalance = ( - transaction: ICashflowAccountTransaction - ): ICashflowAccountTransaction => { - const balance = - transaction.runningBalance + - transaction.withdrawal * -1 + - transaction.deposit; - - return { - ...transaction, - balance, - formattedBalance: this.formatNumber(balance), - }; - }; - - /** - * Transformes the given account transaction to cashflow report transaction. - * @param {ICashflowAccountTransaction} transaction - * @returns {ICashflowAccountTransaction} - */ - private transactionTransformer = ( - transaction - ): ICashflowAccountTransaction => { - return R.compose( - this.transactionBalance, - this.transactionRunningBalance, - this.transactionNode - )(transaction); - }; - - /** - * Retrieve the report transactions node. - * @param {} transactions - * @returns {ICashflowAccountTransaction[]} - */ - private transactionsNode = (transactions): ICashflowAccountTransaction[] => { - return R.map(this.transactionTransformer)(transactions); - }; - - /** - * Retrieve the reprot data node. - * @returns {ICashflowAccountTransaction[]} - */ - public reportData(): ICashflowAccountTransaction[] { - return this.transactionsNode(this.repo.transactions); - } -} diff --git a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsRepo.ts b/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsRepo.ts deleted file mode 100644 index 7bb50373d..000000000 --- a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsRepo.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as R from 'ramda'; -import { ICashflowAccountTransactionsQuery } from '@/interfaces'; -import { - groupMatchedBankTransactions, - groupUncategorizedTransactions, -} from './utils'; - -export class CashflowAccountTransactionsRepo { - private models: any; - public query: ICashflowAccountTransactionsQuery; - public transactions: any; - public uncategorizedTransactions: any; - public uncategorizedTransactionsMapByRef: Map; - public matchedBankTransactions: any; - public matchedBankTransactionsMapByRef: Map; - public pagination: any; - public openingBalance: any; - - /** - * Constructor method. - * @param {any} models - * @param {ICashflowAccountTransactionsQuery} query - */ - constructor(models: any, query: ICashflowAccountTransactionsQuery) { - this.models = models; - this.query = query; - } - - /** - * Async initalize the resources. - */ - async asyncInit() { - await this.initCashflowAccountTransactions(); - await this.initCashflowAccountOpeningBalance(); - await this.initCategorizedTransactions(); - await this.initMatchedTransactions(); - } - - /** - * Retrieve the cashflow account transactions. - * @param {number} tenantId - - * @param {ICashflowAccountTransactionsQuery} query - - */ - async initCashflowAccountTransactions() { - const { AccountTransaction } = this.models; - - const { results, pagination } = await AccountTransaction.query() - .where('account_id', this.query.accountId) - .orderBy([ - { column: 'date', order: 'desc' }, - { column: 'created_at', order: 'desc' }, - ]) - .pagination(this.query.page - 1, this.query.pageSize); - - this.transactions = results; - this.pagination = pagination; - } - - /** - * Retrieve the cashflow account opening balance. - * @param {number} tenantId - * @param {number} accountId - * @param {IPaginationMeta} pagination - * @return {Promise} - */ - async initCashflowAccountOpeningBalance(): Promise { - const { AccountTransaction } = this.models; - - // Retrieve the opening balance of credit and debit balances. - const openingBalancesSubquery = AccountTransaction.query() - .where('account_id', this.query.accountId) - .orderBy([ - { column: 'date', order: 'desc' }, - { column: 'created_at', order: 'desc' }, - ]) - .limit(this.pagination.total) - .offset(this.pagination.pageSize * (this.pagination.page - 1)); - - // Sumation of credit and debit balance. - const openingBalances = await AccountTransaction.query() - .sum('credit as credit') - .sum('debit as debit') - .from(openingBalancesSubquery.as('T')) - .first(); - - const openingBalance = openingBalances.debit - openingBalances.credit; - - this.openingBalance = openingBalance; - } - - /** - * Initialize the uncategorized transactions of the bank account. - */ - async initCategorizedTransactions() { - const { UncategorizedCashflowTransaction } = this.models; - const refs = this.transactions.map((t) => [t.referenceType, t.referenceId]); - - const uncategorizedTransactions = - await UncategorizedCashflowTransaction.query().whereIn( - ['categorizeRefType', 'categorizeRefId'], - refs - ); - - this.uncategorizedTransactions = uncategorizedTransactions; - this.uncategorizedTransactionsMapByRef = groupUncategorizedTransactions( - uncategorizedTransactions - ); - } - - /** - * Initialize the matched bank transactions of the bank account. - */ - async initMatchedTransactions(): Promise { - const { MatchedBankTransaction } = this.models; - const refs = this.transactions.map((t) => [t.referenceType, t.referenceId]); - - const matchedBankTransactions = - await MatchedBankTransaction.query().whereIn( - ['referenceType', 'referenceId'], - refs - ); - this.matchedBankTransactions = matchedBankTransactions; - this.matchedBankTransactionsMapByRef = groupMatchedBankTransactions( - matchedBankTransactions - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsService.ts b/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsService.ts deleted file mode 100644 index adf4a519e..000000000 --- a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/CashflowAccountTransactionsService.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as qim from 'qim'; -import { ICashflowAccountTransactionsQuery, IAccount } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import FinancialSheet from '../FinancialSheet'; -import { CashflowAccountTransactionReport } from './CashflowAccountTransactions'; -import I18nService from '@/services/I18n/I18nService'; -import { CashflowAccountTransactionsRepo } from './CashflowAccountTransactionsRepo'; - -@Service() -export default class CashflowAccountTransactionsService extends FinancialSheet { - @Inject() - private tenancy: TenancyService; - - /** - * Defaults balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - private get defaultQuery(): Partial { - return { - pageSize: 50, - page: 1, - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - }; - } - - /** - * Retrieve the cashflow account transactions report data. - * @param {number} tenantId - - * @param {ICashflowAccountTransactionsQuery} query - - * @return {Promise} - */ - public async cashflowAccountTransactions( - tenantId: number, - query: ICashflowAccountTransactionsQuery - ) { - const models = this.tenancy.models(tenantId); - const parsedQuery = { ...this.defaultQuery, ...query }; - - // Initalize the bank transactions report repository. - const cashflowTransactionsRepo = new CashflowAccountTransactionsRepo( - models, - parsedQuery - ); - await cashflowTransactionsRepo.asyncInit(); - - // Retrieve the computed report. - const report = new CashflowAccountTransactionReport( - cashflowTransactionsRepo, - parsedQuery - ); - const transactions = report.reportData(); - const pagination = cashflowTransactionsRepo.pagination; - - return { transactions, pagination }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/constants.ts b/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/constants.ts deleted file mode 100644 index 298cbe801..000000000 --- a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const ERRORS = { - ACCOUNT_ID_HAS_INVALID_TYPE: 'ACCOUNT_ID_HAS_INVALID_TYPE', -}; - -export enum BankTransactionStatus { - Categorized = 'categorized', - Matched = 'matched', - Manual = 'manual', -} diff --git a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/utils.ts b/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/utils.ts deleted file mode 100644 index a1e47d4f4..000000000 --- a/packages/server/src/services/FinancialStatements/CashflowAccountTransactions/utils.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as R from 'ramda'; - -export const groupUncategorizedTransactions = ( - uncategorizedTransactions: any -): Map => { - return new Map( - R.toPairs( - R.groupBy( - (transaction) => - `${transaction.categorizeRefType}-${transaction.categorizeRefId}`, - uncategorizedTransactions - ) - ) - ); -}; - -export const groupMatchedBankTransactions = ( - uncategorizedTransactions: any -): Map => { - return new Map( - R.toPairs( - R.groupBy( - (transaction) => - `${transaction.referenceType}-${transaction.referenceId}`, - uncategorizedTransactions - ) - ) - ); -}; - -export const formatBankTransactionsStatus = (status) => { - switch (status) { - case 'categorized': - return 'Categorized'; - case 'matched': - return 'Matched'; - case 'manual': - return 'Manual'; - } -}; diff --git a/packages/server/src/services/FinancialStatements/ContactBalanceSummary/ContactBalanceSummary.ts b/packages/server/src/services/FinancialStatements/ContactBalanceSummary/ContactBalanceSummary.ts deleted file mode 100644 index dee1fbb5e..000000000 --- a/packages/server/src/services/FinancialStatements/ContactBalanceSummary/ContactBalanceSummary.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { sumBy, isEmpty } from 'lodash'; -import * as R from 'ramda'; -import FinancialSheet from '../FinancialSheet'; -import { - IContactBalanceSummaryContact, - IContactBalanceSummaryTotal, - IContactBalanceSummaryAmount, - IContactBalanceSummaryPercentage, - ILedger, - IContactBalanceSummaryQuery, -} from '@/interfaces'; -import { allPassedConditionsPass } from 'utils'; - -export class ContactBalanceSummaryReport extends FinancialSheet { - readonly baseCurrency: string; - readonly ledger: ILedger; - readonly filter: IContactBalanceSummaryQuery; - - /** - * Calculates the contact percentage of column. - * @param {number} customerBalance - Contact balance. - * @param {number} totalBalance - Total contacts balance. - * @returns {number} - */ - protected getContactPercentageOfColumn = ( - customerBalance: number, - totalBalance: number - ): number => { - return totalBalance / customerBalance; - }; - - /** - * Retrieve the contacts total. - * @param {IContactBalanceSummaryContact} contacts - * @returns {number} - */ - protected getContactsTotal = ( - contacts: IContactBalanceSummaryContact[] - ): number => { - return sumBy( - contacts, - (contact: IContactBalanceSummaryContact) => contact.total.amount - ); - }; - - /** - * Assoc total percentage of column. - * @param {IContactBalanceSummaryTotal} node - * @returns {IContactBalanceSummaryTotal} - */ - protected assocTotalPercentageOfColumn = ( - node: IContactBalanceSummaryTotal - ): IContactBalanceSummaryTotal => { - return R.assoc('percentageOfColumn', this.getPercentageMeta(1), node); - }; - - /** - * Retrieve the contacts total section. - * @param {IContactBalanceSummaryContact[]} contacts - * @returns {IContactBalanceSummaryTotal} - */ - protected getContactsTotalSection = ( - contacts: IContactBalanceSummaryContact[] - ): IContactBalanceSummaryTotal => { - const customersTotal = this.getContactsTotal(contacts); - const node = { - total: this.getTotalFormat(customersTotal), - }; - return R.compose( - R.when( - R.always(this.filter.percentageColumn), - this.assocTotalPercentageOfColumn - ) - )(node); - }; - - /** - * Retrieve the contact summary section with percentage of column. - * @param {number} total - * @param {IContactBalanceSummaryContact} contact - * @returns {IContactBalanceSummaryContact} - */ - private contactCamparsionPercentageOfColumnMapper = ( - total: number, - contact: IContactBalanceSummaryContact - ): IContactBalanceSummaryContact => { - const amount = this.getContactPercentageOfColumn( - total, - contact.total.amount - ); - return { - ...contact, - percentageOfColumn: this.getPercentageMeta(amount), - }; - }; - - /** - * Mappes the contacts summary sections with percentage of column. - * @param {IContactBalanceSummaryContact[]} contacts - - * @return {IContactBalanceSummaryContact[]} - */ - protected contactCamparsionPercentageOfColumn = ( - contacts: IContactBalanceSummaryContact[] - ): IContactBalanceSummaryContact[] => { - const customersTotal = this.getContactsTotal(contacts); - const camparsionPercentageOfColummn = R.curry( - this.contactCamparsionPercentageOfColumnMapper - )(customersTotal); - - return contacts.map(camparsionPercentageOfColummn); - }; - - /** - * Retrieve the contact total format. - * @param {number} amount - - * @return {IContactBalanceSummaryAmount} - */ - protected getContactTotalFormat = ( - amount: number - ): IContactBalanceSummaryAmount => { - return { - amount, - formattedAmount: this.formatNumber(amount, { money: true }), - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieve the total amount of contacts sections. - * @param {number} amount - * @returns {IContactBalanceSummaryAmount} - */ - protected getTotalFormat = (amount: number): IContactBalanceSummaryAmount => { - return { - amount, - formattedAmount: this.formatTotalNumber(amount, { money: true }), - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieve the percentage amount object. - * @param {number} amount - * @returns {IContactBalanceSummaryPercentage} - */ - protected getPercentageMeta = ( - amount: number - ): IContactBalanceSummaryPercentage => { - return { - amount, - formattedAmount: this.formatPercentage(amount), - }; - }; - - /** - * Filters customer has none transactions. - * @param {ICustomerBalanceSummaryCustomer} customer - - * @returns {boolean} - */ - private filterContactNoneTransactions = ( - contact: IContactBalanceSummaryContact - ): boolean => { - const entries = this.ledger.whereContactId(contact.id).getEntries(); - - return !isEmpty(entries); - }; - - /** - * Filters the customer that has zero total amount. - * @param {ICustomerBalanceSummaryCustomer} customer - * @returns {boolean} - */ - private filterContactNoneZero = ( - node: IContactBalanceSummaryContact - ): boolean => { - return node.total.amount !== 0; - }; - - /** - * Filters the given customer node; - * @param {ICustomerBalanceSummaryCustomer} customer - */ - private contactNodeFilter = (contact: IContactBalanceSummaryContact) => { - const { noneTransactions, noneZero } = this.filter; - - // Conditions pair filter detarminer. - const condsPairFilters = [ - [noneTransactions, this.filterContactNoneTransactions], - [noneZero, this.filterContactNoneZero], - ]; - return allPassedConditionsPass(condsPairFilters)(contact); - }; - - /** - * Filters the given customers nodes. - * @param {ICustomerBalanceSummaryCustomer[]} nodes - * @returns {ICustomerBalanceSummaryCustomer[]} - */ - protected contactsFilter = ( - nodes: IContactBalanceSummaryContact[] - ): IContactBalanceSummaryContact[] => { - return nodes.filter(this.contactNodeFilter); - }; -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummary.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummary.ts deleted file mode 100644 index 15eafb739..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummary.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { isEmpty } from 'lodash'; -import * as R from 'ramda'; -import { - ILedger, - ICustomer, - ICustomerBalanceSummaryCustomer, - ICustomerBalanceSummaryQuery, - ICustomerBalanceSummaryData, - INumberFormatQuery, -} from '@/interfaces'; -import { ContactBalanceSummaryReport } from '../ContactBalanceSummary/ContactBalanceSummary'; - -export class CustomerBalanceSummaryReport extends ContactBalanceSummaryReport { - readonly ledger: ILedger; - readonly baseCurrency: string; - readonly customers: ICustomer[]; - readonly filter: ICustomerBalanceSummaryQuery; - readonly numberFormat: INumberFormatQuery; - - /** - * Constructor method. - * @param {IJournalPoster} receivableLedger - * @param {ICustomer[]} customers - * @param {ICustomerBalanceSummaryQuery} filter - * @param {string} baseCurrency - */ - constructor( - ledger: ILedger, - customers: ICustomer[], - filter: ICustomerBalanceSummaryQuery, - baseCurrency: string - ) { - super(); - - this.ledger = ledger; - this.baseCurrency = baseCurrency; - this.customers = customers; - this.filter = filter; - this.numberFormat = this.filter.numberFormat; - } - - /** - * Customer section mapper. - * @param {ICustomer} customer - * @returns {ICustomerBalanceSummaryCustomer} - */ - private customerMapper = ( - customer: ICustomer - ): ICustomerBalanceSummaryCustomer => { - const closingBalance = this.ledger - .whereContactId(customer.id) - .getClosingBalance(); - - return { - id: customer.id, - customerName: customer.displayName, - total: this.getContactTotalFormat(closingBalance), - }; - }; - - /** - * Mappes the customer model object to customer balance summary section. - * @param {ICustomer[]} customers - Customers. - * @returns {ICustomerBalanceSummaryCustomer[]} - */ - private customersMapper = ( - customers: ICustomer[] - ): ICustomerBalanceSummaryCustomer[] => { - return customers.map(this.customerMapper); - }; - - /** - * Detarmines whether the customers post filter is active. - * @returns {boolean} - */ - private isCustomersPostFilter = () => { - return isEmpty(this.filter.customersIds); - }; - - /** - * Retrieve the customers sections of the report. - * @param {ICustomer} customers - * @returns {ICustomerBalanceSummaryCustomer[]} - */ - private getCustomersSection = ( - customers: ICustomer[] - ): ICustomerBalanceSummaryCustomer[] => { - return R.compose( - R.when(this.isCustomersPostFilter, this.contactsFilter), - R.when( - R.always(this.filter.percentageColumn), - this.contactCamparsionPercentageOfColumn - ), - this.customersMapper - )(customers); - }; - - /** - * Retrieve the report statement data. - * @returns {ICustomerBalanceSummaryData} - */ - public reportData = (): ICustomerBalanceSummaryData => { - const customersSections = this.getCustomersSection(this.customers); - const customersTotal = this.getContactsTotalSection(customersSections); - - return { - customers: customersSections, - total: customersTotal, - }; - }; -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts deleted file mode 100644 index 78c532d08..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CustomerBalanceSummaryExportInjectable } from './CustomerBalanceSummaryExportInjectable'; -import { CustomerBalanceSummaryTableInjectable } from './CustomerBalanceSummaryTableInjectable'; -import { ICustomerBalanceSummaryQuery } from '@/interfaces'; -import { CustomerBalanceSummaryService } from './CustomerBalanceSummaryService'; -import { CustomerBalanceSummaryPdf } from './CustomerBalanceSummaryPdf'; - -@Service() -export class CustomerBalanceSummaryApplication { - @Inject() - private customerBalanceSummaryTable: CustomerBalanceSummaryTableInjectable; - - @Inject() - private customerBalanceSummaryExport: CustomerBalanceSummaryExportInjectable; - - @Inject() - private customerBalanceSummarySheet: CustomerBalanceSummaryService; - - @Inject() - private customerBalanceSummaryPdf: CustomerBalanceSummaryPdf; - - /** - * Retrieves the customer balance sheet in json format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public sheet(tenantId: number, query: ICustomerBalanceSummaryQuery) { - return this.customerBalanceSummarySheet.customerBalanceSummary( - tenantId, - query - ); - } - - /** - * Retrieves the customer balance sheet in json format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public table(tenantId: number, query: ICustomerBalanceSummaryQuery) { - return this.customerBalanceSummaryTable.table(tenantId, query); - } - - /** - * Retrieves the customer balance sheet in XLSX format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public xlsx(tenantId: number, query: ICustomerBalanceSummaryQuery) { - return this.customerBalanceSummaryExport.xlsx(tenantId, query); - } - - /** - * Retrieves the customer balance sheet in CSV format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public csv(tenantId: number, query: ICustomerBalanceSummaryQuery) { - return this.customerBalanceSummaryExport.csv(tenantId, query); - } - - /** - * Retrieves the customer balance sheet in PDF format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: ICustomerBalanceSummaryQuery) { - return this.customerBalanceSummaryPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts deleted file mode 100644 index 97fec14d8..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryExportInjectable.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICustomerBalanceSummaryQuery } from '@/interfaces'; -import { CustomerBalanceSummaryTableInjectable } from './CustomerBalanceSummaryTableInjectable'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; - -@Service() -export class CustomerBalanceSummaryExportInjectable { - @Inject() - private customerBalanceSummaryTable: CustomerBalanceSummaryTableInjectable; - - /** - * Retrieves the cashflow sheet in XLSX format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: ICustomerBalanceSummaryQuery) { - const table = await this.customerBalanceSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the cashflow sheet in CSV format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ICustomerBalanceSummaryQuery - ): Promise { - const table = await this.customerBalanceSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts deleted file mode 100644 index 7639e8c4f..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryMeta.ts +++ /dev/null @@ -1,35 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { - ICustomerBalanceSummaryMeta, - ICustomerBalanceSummaryQuery, -} from '@/interfaces'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; - -@Service() -export class CustomerBalanceSummaryMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the customer balance summary meta. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @returns {Promise} - */ - async meta( - tenantId: number, - query: ICustomerBalanceSummaryQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedAsDate = moment(query.asDate).format('YYYY/MM/DD'); - const formattedDateRange = `As ${formattedAsDate}`; - - return { - ...commonMeta, - sheetName: 'Customer Balance Summary', - formattedAsDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts deleted file mode 100644 index 38d36fd48..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICustomerBalanceSummaryQuery } from '@/interfaces'; - -import { TableSheetPdf } from '../TableSheetPdf'; -import { CustomerBalanceSummaryTableInjectable } from './CustomerBalanceSummaryTableInjectable'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class CustomerBalanceSummaryPdf { - @Inject() - private customerBalanceSummaryTable: CustomerBalanceSummaryTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given customer balance summary sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IAPAgingSummaryQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ICustomerBalanceSummaryQuery - ): Promise { - const table = await this.customerBalanceSummaryTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts deleted file mode 100644 index 6de7bf54d..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryRepository.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { map, isEmpty } from 'lodash'; -import { ICustomer, IAccount } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -@Service() -export default class CustomerBalanceSummaryRepository { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve the report customers. - * @param {number} tenantId - * @param {number[]} customersIds - * @returns {ICustomer[]} - */ - public getCustomers(tenantId: number, customersIds: number[]): ICustomer[] { - const { Customer } = this.tenancy.models(tenantId); - - return Customer.query() - .orderBy('displayName') - .onBuild((query) => { - if (!isEmpty(customersIds)) { - query.whereIn('id', customersIds); - } - }); - } - - /** - * Retrieve the A/R accounts. - * @param {number} tenantId - * @returns {Promise} - */ - public getReceivableAccounts(tenantId: number): Promise { - const { Account } = this.tenancy.models(tenantId); - - return Account.query().where( - 'accountType', - ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE - ); - } - - /** - * Retrieve the customers credit/debit totals - * @param {number} tenantId - * @returns - */ - public async getCustomersTransactions(tenantId: number, asDate: any) { - const { AccountTransaction } = this.tenancy.models(tenantId); - - // Retrieve the receivable accounts A/R. - const receivableAccounts = await this.getReceivableAccounts(tenantId); - const receivableAccountsIds = map(receivableAccounts, 'id'); - - // Retrieve the customers transactions of A/R accounts. - const customersTranasctions = await AccountTransaction.query().onBuild( - (query) => { - query.whereIn('accountId', receivableAccountsIds); - query.modify('filterDateRange', null, asDate); - query.groupBy('contactId'); - query.sum('credit as credit'); - query.sum('debit as debit'); - query.select('contactId'); - } - ); - return customersTranasctions; - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryService.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryService.ts deleted file mode 100644 index a5636594b..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryService.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import * as R from 'ramda'; -import { - ICustomerBalanceSummaryService, - ICustomerBalanceSummaryQuery, - ICustomerBalanceSummaryStatement, - ICustomer, - ILedgerEntry, -} from '@/interfaces'; -import { CustomerBalanceSummaryReport } from './CustomerBalanceSummary'; -import Ledger from '@/services/Accounting/Ledger'; -import CustomerBalanceSummaryRepository from './CustomerBalanceSummaryRepository'; -import { Tenant } from '@/system/models'; -import { CustomerBalanceSummaryMeta } from './CustomerBalanceSummaryMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class CustomerBalanceSummaryService - implements ICustomerBalanceSummaryService -{ - @Inject() - private reportRepository: CustomerBalanceSummaryRepository; - - @Inject() - private customerBalanceSummaryMeta: CustomerBalanceSummaryMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {ICustomerBalanceSummaryQuery} - */ - private get defaultQuery(): ICustomerBalanceSummaryQuery { - return { - asDate: moment().format('YYYY-MM-DD'), - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - percentageColumn: false, - - noneZero: false, - noneTransactions: true, - }; - } - - /** - * Retrieve the customers ledger entries mapped from accounts transactions. - * @param {number} tenantId - * @param {Date|string} asDate - * @returns {Promise} - */ - private async getReportCustomersEntries( - tenantId: number, - asDate: Date | string - ): Promise { - const transactions = await this.reportRepository.getCustomersTransactions( - tenantId, - asDate - ); - const commonProps = { accountNormal: 'debit', date: asDate }; - - return R.map(R.merge(commonProps))(transactions); - } - - /** - * Retrieve the statment of customer balance summary report. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} query - * @return {Promise} - */ - public async customerBalanceSummary( - tenantId: number, - query: ICustomerBalanceSummaryQuery - ): Promise { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Merges the default query and request query. - const filter = { ...this.defaultQuery, ...query }; - - // Retrieve the customers list ordered by the display name. - const customers = await this.reportRepository.getCustomers( - tenantId, - query.customersIds - ); - // Retrieve the customers debit/credit totals. - const customersEntries = await this.getReportCustomersEntries( - tenantId, - filter.asDate - ); - // Ledger query. - const ledger = new Ledger(customersEntries); - - // Report instance. - const report = new CustomerBalanceSummaryReport( - ledger, - customers, - filter, - tenant.metadata.baseCurrency - ); - // Retrieve the customer balance summary meta. - const meta = await this.customerBalanceSummaryMeta.meta(tenantId, filter); - - // Triggers `onCustomerBalanceSummaryViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onCustomerBalanceSummaryViewed, - { - tenant, - query, - } - ); - - return { - data: report.reportData(), - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts deleted file mode 100644 index ec5a9c021..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableInjectable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CustomerBalanceSummaryService } from './CustomerBalanceSummaryService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - ICustomerBalanceSummaryQuery, - ICustomerBalanceSummaryTable, -} from '@/interfaces'; -import { CustomerBalanceSummaryTable } from './CustomerBalanceSummaryTableRows'; - -@Service() -export class CustomerBalanceSummaryTableInjectable { - @Inject() - private customerBalanceSummaryService: CustomerBalanceSummaryService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the customer balance sheet in table format. - * @param {number} tenantId - * @param {ICustomerBalanceSummaryQuery} filter - * @returns {Promise} - */ - public async table( - tenantId: number, - filter: ICustomerBalanceSummaryQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - const { data, query, meta } = - await this.customerBalanceSummaryService.customerBalanceSummary( - tenantId, - filter - ); - const table = new CustomerBalanceSummaryTable(data, filter, i18n); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - query, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts deleted file mode 100644 index e4ed687a4..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryTableRows.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as R from 'ramda'; -import { - ICustomerBalanceSummaryData, - ICustomerBalanceSummaryCustomer, - ICustomerBalanceSummaryTotal, - ITableRow, - IColumnMapperMeta, - ICustomerBalanceSummaryQuery, - ITableColumn, -} from '@/interfaces'; -import { tableMapper, tableRowMapper } from 'utils'; - -enum TABLE_ROWS_TYPES { - CUSTOMER = 'CUSTOMER', - TOTAL = 'TOTAL', -} - -export class CustomerBalanceSummaryTable { - report: ICustomerBalanceSummaryData; - query: ICustomerBalanceSummaryQuery; - i18n: any; - - /** - * Constructor method. - */ - constructor( - report: ICustomerBalanceSummaryData, - query: ICustomerBalanceSummaryQuery, - i18n - ) { - this.report = report; - this.i18n = i18n; - this.query = query; - } - - /** - * Retrieve percentage columns accessor. - * @returns {IColumnMapperMeta[]} - */ - private getPercentageColumnsAccessor = (): IColumnMapperMeta[] => { - return [ - { - key: 'percentageOfColumn', - accessor: 'percentageOfColumn.formattedAmount', - }, - ]; - }; - - /** - * Retrieve customer node columns accessor. - * @returns {IColumnMapperMeta[]} - */ - private getCustomerColumnsAccessor = (): IColumnMapperMeta[] => { - const columns = [ - { key: 'name', accessor: 'customerName' }, - { key: 'total', accessor: 'total.formattedAmount' }, - ]; - return R.compose( - R.concat(columns), - R.when( - R.always(this.query.percentageColumn), - R.concat(this.getPercentageColumnsAccessor()) - ) - )([]); - }; - - /** - * Transformes the customers to table rows. - * @param {ICustomerBalanceSummaryCustomer[]} customers - * @returns {ITableRow[]} - */ - private customersTransformer( - customers: ICustomerBalanceSummaryCustomer[] - ): ITableRow[] { - const columns = this.getCustomerColumnsAccessor(); - - return tableMapper(customers, columns, { - rowTypes: [TABLE_ROWS_TYPES.CUSTOMER], - }); - } - - /** - * Retrieve total node columns accessor. - * @returns {IColumnMapperMeta[]} - */ - private getTotalColumnsAccessor = (): IColumnMapperMeta[] => { - const columns = [ - { key: 'name', value: this.i18n.__('Total') }, - { key: 'total', accessor: 'total.formattedAmount' }, - ]; - return R.compose( - R.concat(columns), - R.when( - R.always(this.query.percentageColumn), - R.concat(this.getPercentageColumnsAccessor()) - ) - )([]); - }; - - /** - * Transformes the total to table row. - * @param {ICustomerBalanceSummaryTotal} total - * @returns {ITableRow} - */ - private totalTransformer = ( - total: ICustomerBalanceSummaryTotal - ): ITableRow => { - const columns = this.getTotalColumnsAccessor(); - - return tableRowMapper(total, columns, { - rowTypes: [TABLE_ROWS_TYPES.TOTAL], - }); - }; - - /** - * Transformes the customer balance summary to table rows. - * @param {ICustomerBalanceSummaryData} customerBalanceSummary - * @returns {ITableRow[]} - */ - public tableRows(): ITableRow[] { - const customers = this.customersTransformer(this.report.customers); - const total = this.totalTransformer(this.report.total); - - return customers.length > 0 ? [...customers, total] : []; - } - - /** - * Retrieve the report statement columns - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - const columns = [ - { - key: 'name', - label: this.i18n.__('contact_summary_balance.account_name'), - }, - { key: 'total', label: this.i18n.__('contact_summary_balance.total') }, - ]; - return R.compose( - R.when( - R.always(this.query.percentageColumn), - R.append({ - key: 'percentage_of_column', - label: this.i18n.__('contact_summary_balance.percentage_column'), - }) - ), - R.concat(columns) - )([]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/constants.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/constants.ts deleted file mode 100644 index 513a3dcdb..000000000 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/constants.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const HtmlTableCustomCss = ` -table tr.row-type--total td { - font-weight: 600; - border-top: 1px solid #bbb; - border-bottom: 3px double #333; -} -table .column--name { - width: 65%; -} -table .column--total, -table .cell--total { - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/FinancialDatePeriods.ts b/packages/server/src/services/FinancialStatements/FinancialDatePeriods.ts deleted file mode 100644 index cc79aa74d..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialDatePeriods.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as R from 'ramda'; -import { memoize } from 'lodash'; -import { compose } from 'lodash/fp'; -import { - IAccountTransactionsGroupBy, - IFinancialDatePeriodsUnit, - IFinancialSheetTotalPeriod, - IFormatNumberSettings, -} from '@/interfaces'; -import { dateRangeFromToCollection } from 'utils'; -import { FinancialDateRanges } from './FinancialDateRanges'; - -export const FinancialDatePeriods = (Base) => - class extends compose(FinancialDateRanges)(Base) { - /** - * - * @param {Date} fromDate - - * @param {Date} toDate - * @param {string} unit - */ - protected getDateRanges = memoize( - (fromDate: Date, toDate: Date, unit: string) => { - return dateRangeFromToCollection(fromDate, toDate, unit); - } - ); - - /** - * Retrieve the date period meta. - * @param {number} total - Total amount. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - protected getDatePeriodMeta = ( - total: number, - fromDate: Date, - toDate: Date, - overrideSettings?: IFormatNumberSettings - ): IFinancialSheetTotalPeriod => { - return { - fromDate: this.getDateMeta(fromDate), - toDate: this.getDateMeta(toDate), - total: this.getAmountMeta(total, overrideSettings), - }; - }; - - /** - * Retrieve the date period meta. - * @param {number} total - Total amount. - * @param {Date} fromDate - From date. - * @param {Date} toDate - To date. - * @return {ICashFlowDatePeriod} - */ - protected getDatePeriodTotalMeta = ( - total: number, - fromDate: Date, - toDate: Date, - overrideSettings: IFormatNumberSettings = {} - ) => { - return this.getDatePeriodMeta(total, fromDate, toDate, { - money: true, - ...overrideSettings, - }); - }; - - /** - * Retrieve the date preioods of the given node and accumulated function. - * @param {IBalanceSheetAccountNode} node - * @param {(fromDate: Date, toDate: Date, index: number) => any} - * @return {} - */ - protected getNodeDatePeriods = R.curry( - ( - fromDate: Date, - toDate: Date, - periodsUnit: string, - node: any, - callback: ( - node: any, - fromDate: Date, - toDate: Date, - index: number - ) => any - ) => { - const curriedCallback = R.curry(callback)(node); - - // Retrieves memorized date ranges. - const dateRanges = this.getDateRanges(fromDate, toDate, periodsUnit); - - return dateRanges.map((dateRange, index) => { - return curriedCallback(dateRange.fromDate, dateRange.toDate, index); - }); - } - ); - - /** - * Retrieve the accounts transactions group type from display columns by. - * @param {IAccountTransactionsGroupBy} columnsBy - * @returns {IAccountTransactionsGroupBy} - */ - protected getGroupByFromDisplayColumnsBy = ( - columnsBy: IFinancialDatePeriodsUnit - ): IAccountTransactionsGroupBy => { - const paris = { - week: IAccountTransactionsGroupBy.Day, - quarter: IAccountTransactionsGroupBy.Month, - year: IAccountTransactionsGroupBy.Year, - month: IAccountTransactionsGroupBy.Month, - day: IAccountTransactionsGroupBy.Day, - }; - return paris[columnsBy]; - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialDateRanges.ts b/packages/server/src/services/FinancialStatements/FinancialDateRanges.ts deleted file mode 100644 index f6c419605..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialDateRanges.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { IDateRange, IFinancialDatePeriodsUnit } from '@/interfaces'; -import moment from 'moment'; - -export const FinancialDateRanges = (Base) => - class extends Base { - /** - * Retrieve previous period (PP) date of the given date. - * @param {Date} fromDate - - * @param {Date} toDate - - * @param {IFinancialDatePeriodsUnit} unit - - * @returns {Date} - */ - protected getPreviousPeriodDate = ( - date: Date, - value: number = 1, - unit: IFinancialDatePeriodsUnit = IFinancialDatePeriodsUnit.Day - ): Date => { - return moment(date).subtract(value, unit).toDate(); - }; - - /** - * Retrieves the different - * @param {Date} fromDate - * @param {Date} toDate - * @returns - */ - protected getPreviousPeriodDiff = (fromDate: Date, toDate: Date) => { - return moment(toDate).diff(fromDate, 'days') + 1; - }; - - /** - * Retrieves the periods period dates. - * @param {Date} fromDate - - * @param {Date} toDate - - */ - protected getPreviousPeriodDateRange = ( - fromDate: Date, - toDate: Date, - unit: IFinancialDatePeriodsUnit, - amount: number = 1 - ): IDateRange => { - const PPToDate = this.getPreviousPeriodDate(toDate, amount, unit); - const PPFromDate = this.getPreviousPeriodDate(fromDate, amount, unit); - - return { toDate: PPToDate, fromDate: PPFromDate }; - }; - - /** - * Retrieves the previous period (PP) date range of total column. - * @param {Date} fromDate - * @param {Date} toDate - * @returns {IDateRange} - */ - protected getPPTotalDateRange = ( - fromDate: Date, - toDate: Date - ): IDateRange => { - const unit = this.getPreviousPeriodDiff(fromDate, toDate); - - return this.getPreviousPeriodDateRange( - fromDate, - toDate, - IFinancialDatePeriodsUnit.Day, - unit - ); - }; - - /** - * Retrieves the previous period (PP) date range of date periods columns. - * @param {Date} fromDate - - * @param {Date} toDate - - * @param {IFinancialDatePeriodsUnit} - * @returns {IDateRange} - */ - protected getPPDatePeriodDateRange = ( - fromDate: Date, - toDate: Date, - unit: IFinancialDatePeriodsUnit - ): IDateRange => { - return this.getPreviousPeriodDateRange(fromDate, toDate, unit, 1); - }; - - // ------------------------ - // Previous Year (PY). - // ------------------------ - /** - * Retrieve the previous year of the given date. - * @params {Date} date - * @returns {Date} - */ - getPreviousYearDate = (date: Date) => { - return moment(date).subtract(1, 'years').toDate(); - }; - - /** - * Retrieves previous year date range. - * @param {Date} fromDate - * @param {Date} toDate - * @returns {IDateRange} - */ - protected getPreviousYearDateRange = ( - fromDate: Date, - toDate: Date - ): IDateRange => { - const PYFromDate = this.getPreviousYearDate(fromDate); - const PYToDate = this.getPreviousYearDate(toDate); - - return { fromDate: PYFromDate, toDate: PYToDate }; - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialEvaluateEquation.ts b/packages/server/src/services/FinancialStatements/FinancialEvaluateEquation.ts deleted file mode 100644 index 230dc7209..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialEvaluateEquation.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as mathjs from 'mathjs'; -import * as R from 'ramda'; -import { compose } from 'lodash/fp'; -import { omit, get, mapValues } from 'lodash'; -import { FinancialSheetStructure } from './FinancialSheetStructure'; - -export const FinancialEvaluateEquation = (Base) => - class extends compose(FinancialSheetStructure)(Base) { - /** - * Evauluate equaation string with the given scope table. - * @param {string} equation - - * @param {{ [key: string]: number }} scope - - * @return {number} - */ - protected evaluateEquation = ( - equation: string, - scope: { [key: string | number]: number } - ): number => { - return mathjs.evaluate(equation, scope); - }; - - /** - * Transformes the given nodes nested array to object key/value by id. - * @param nodes - * @returns - */ - private transformNodesToMap = (nodes: any[]) => { - return this.mapAccNodesDeep( - nodes, - (node, key, parentValue, acc, context) => { - if (node.id) { - acc[`${node.id}`] = omit(node, ['children']); - } - return acc; - }, - {} - ); - }; - - /** - * - * @param nodesById - * @returns - */ - private mapNodesToTotal = R.curry( - (path: string, nodesById: { [key: number]: any }) => { - return mapValues(nodesById, (node) => get(node, path, 0)); - } - ); - - /** - * - */ - protected getNodesTableForEvaluating = R.curry( - (path = 'total.amount', nodes) => { - return R.compose( - this.mapNodesToTotal(path), - this.transformNodesToMap - )(nodes); - } - ); - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialFilter.ts b/packages/server/src/services/FinancialStatements/FinancialFilter.ts deleted file mode 100644 index daf90d949..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialFilter.ts +++ /dev/null @@ -1,22 +0,0 @@ - -import { isEmpty } from 'lodash'; - -export const FinancialFilter = (Base) => - class extends Base { - /** - * Detarmines whether the given node has children. - * @param {IBalanceSheetCommonNode} node - * @returns {boolean} - */ - protected isNodeHasChildren = (node: IBalanceSheetCommonNode): boolean => - !isEmpty(node.children); - - /** - * Detarmines whether the given node has no zero amount. - * @param {IBalanceSheetCommonNode} node - * @returns {boolean} - */ - public isNodeNoneZero = (node) =>{ - return node.total.amount !== 0; - } - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialHorizTotals.ts b/packages/server/src/services/FinancialStatements/FinancialHorizTotals.ts deleted file mode 100644 index b7ab8d987..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialHorizTotals.ts +++ /dev/null @@ -1,96 +0,0 @@ -import * as R from 'ramda'; -import { get, isEmpty } from 'lodash'; - -export const FinancialHorizTotals = (Base) => - class extends Base { - /** - * - */ - protected assocNodePercentage = R.curry( - (assocPath, parentTotal: number, node: any) => { - const percentage = this.getPercentageBasis( - parentTotal, - node.total.amount - ); - return R.assoc( - assocPath, - this.getPercentageAmountMeta(percentage), - node - ); - } - ); - - /** - * - * @param {} parentNode - - * @param {} horTotalNode - - * @param {number} index - - */ - protected assocPercentageHorizTotal = R.curry( - (assocPercentagePath: string, parentNode, horTotalNode, index) => { - const parentTotal = get( - parentNode, - `horizontalTotals[${index}].total.amount`, - 0 - ); - return this.assocNodePercentage( - assocPercentagePath, - parentTotal, - horTotalNode - ); - } - ); - - /** - * - * @param assocPercentagePath - * @param parentNode - * @param node - * @returns - */ - protected assocPercentageHorizTotals = R.curry( - (assocPercentagePath: string, parentNode, node) => { - const assocColPerc = this.assocPercentageHorizTotal( - assocPercentagePath, - parentNode - ); - return R.addIndex(R.map)(assocColPerc)(node.horizontalTotals); - } - ); - - /** - * - */ - assocRowPercentageHorizTotal = R.curry( - (assocPercentagePath: string, node, horizTotalNode) => { - return this.assocNodePercentage( - assocPercentagePath, - node.total.amount, - horizTotalNode - ); - } - ); - - /** - * - */ - protected assocHorizontalPercentageTotals = R.curry( - (assocPercentagePath: string, node) => { - const assocColPerc = this.assocRowPercentageHorizTotal( - assocPercentagePath, - node - ); - - return R.map(assocColPerc)(node.horizontalTotals); - } - ); - - /** - * - * @param node - * @returns - */ - protected isNodeHasHorizTotals = (node) => { - return !isEmpty(node.horizontalTotals); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialPreviousPeriod.ts b/packages/server/src/services/FinancialStatements/FinancialPreviousPeriod.ts deleted file mode 100644 index c0406a9b3..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialPreviousPeriod.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { sumBy } from 'lodash'; -import { - IFinancialDatePeriodsUnit, - IFinancialNodeWithPreviousPeriod, -} from '@/interfaces'; -import * as R from 'ramda'; - -export const FinancialPreviousPeriod = (Base) => - class extends Base { - // --------------------------- - // # Common Node. - // --------------------------- - /** - * Assoc previous period percentage attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IFinancialNodeWithPreviousPeriod} - */ - protected assocPreviousPeriodPercentageNode = ( - accountNode: IProfitLossSheetAccountNode - ): IFinancialNodeWithPreviousPeriod => { - const percentage = this.getPercentageBasis( - accountNode.previousPeriod.amount, - accountNode.previousPeriodChange.amount - ); - return R.assoc( - 'previousPeriodPercentage', - this.getPercentageAmountMeta(percentage), - accountNode - ); - }; - - /** - * Assoc previous period total attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IFinancialNodeWithPreviousPeriod} - */ - protected assocPreviousPeriodChangeNode = ( - accountNode: IProfitLossSheetAccountNode - ): IFinancialNodeWithPreviousPeriod => { - const change = this.getAmountChange( - accountNode.total.amount, - accountNode.previousPeriod.amount - ); - return R.assoc( - 'previousPeriodChange', - this.getAmountMeta(change), - accountNode - ); - }; - - /** - * Assoc previous period percentage attribute to account node. - * - * % change = Change ÷ Original Number × 100. - * - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IFinancialNodeWithPreviousPeriod} - */ - protected assocPreviousPeriodTotalPercentageNode = ( - accountNode: IProfitLossSheetAccountNode - ): IFinancialNodeWithPreviousPeriod => { - const percentage = this.getPercentageBasis( - accountNode.previousPeriod.amount, - accountNode.previousPeriodChange.amount - ); - return R.assoc( - 'previousPeriodPercentage', - this.getPercentageTotalAmountMeta(percentage), - accountNode - ); - }; - - /** - * Assoc previous period total attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IFinancialNodeWithPreviousPeriod} - */ - protected assocPreviousPeriodTotalChangeNode = ( - accountNode: any - ): IFinancialNodeWithPreviousPeriod => { - const change = this.getAmountChange( - accountNode.total.amount, - accountNode.previousPeriod.amount - ); - return R.assoc( - 'previousPeriodChange', - this.getTotalAmountMeta(change), - accountNode - ); - }; - - /** - * Assoc previous year from/to date to horizontal nodes. - * @param horizNode - * @returns {IFinancialNodeWithPreviousPeriod} - */ - protected assocPreviousPeriodHorizNodeFromToDates = R.curry( - ( - periodUnit: IFinancialDatePeriodsUnit, - horizNode: any - ): IFinancialNodeWithPreviousPeriod => { - const { fromDate: PPFromDate, toDate: PPToDate } = - this.getPreviousPeriodDateRange( - horizNode.fromDate.date, - horizNode.toDate.date, - periodUnit - ); - return R.compose( - R.assoc('previousPeriodToDate', this.getDateMeta(PPToDate)), - R.assoc('previousPeriodFromDate', this.getDateMeta(PPFromDate)) - )(horizNode); - } - ); - - /** - * Retrieves PP total sumation of the given horiz index node. - * @param {number} index - * @param node - * @returns {number} - */ - protected getPPHorizNodesTotalSumation = (index: number, node): number => { - return sumBy( - node.children, - `horizontalTotals[${index}].previousPeriod.amount` - ); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialPreviousYear.ts b/packages/server/src/services/FinancialStatements/FinancialPreviousYear.ts deleted file mode 100644 index a55b7cb47..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialPreviousYear.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as R from 'ramda'; -import { sumBy } from 'lodash' -import { - IFinancialCommonHorizDatePeriodNode, - IFinancialCommonNode, - IFinancialNodeWithPreviousYear, -} from '@/interfaces'; - -export const FinancialPreviousYear = (Base) => - class extends Base { - // --------------------------- - // # Common Node - // --------------------------- - /** - * Assoc previous year change attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected assocPreviousYearChangetNode = ( - node: IFinancialCommonNode & IFinancialNodeWithPreviousYear - ): IFinancialNodeWithPreviousYear => { - const change = this.getAmountChange( - node.total.amount, - node.previousYear.amount - ); - return R.assoc('previousYearChange', this.getAmountMeta(change), node); - }; - - /** - * Assoc previous year percentage attribute to account node. - * - * % increase = Increase ÷ Original Number × 100. - * - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected assocPreviousYearPercentageNode = ( - node: IFinancialCommonNode & IFinancialNodeWithPreviousYear - ): IFinancialNodeWithPreviousYear => { - const percentage = this.getPercentageBasis( - node.previousYear.amount, - node.previousYearChange.amount - ); - return R.assoc( - 'previousYearPercentage', - this.getPercentageAmountMeta(percentage), - node - ); - }; - - /** - * Assoc previous year change attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected assocPreviousYearTotalChangeNode = ( - node: IFinancialCommonNode & IFinancialNodeWithPreviousYear - ): IFinancialNodeWithPreviousYear => { - const change = this.getAmountChange( - node.total.amount, - node.previousYear.amount - ); - return R.assoc( - 'previousYearChange', - this.getTotalAmountMeta(change), - node - ); - }; - - /** - * Assoc previous year percentage attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected assocPreviousYearTotalPercentageNode = ( - node: IFinancialCommonNode & IFinancialNodeWithPreviousYear - ): IFinancialNodeWithPreviousYear => { - const percentage = this.getPercentageBasis( - node.previousYear.amount, - node.previousYearChange.amount - ); - return R.assoc( - 'previousYearPercentage', - this.getPercentageTotalAmountMeta(percentage), - node - ); - }; - - /** - * Assoc previous year from/to date to horizontal nodes. - * @param horizNode - * @returns - */ - protected assocPreviousYearHorizNodeFromToDates = ( - horizNode: IFinancialCommonHorizDatePeriodNode - ) => { - const PYFromDate = this.getPreviousYearDate(horizNode.fromDate.date); - const PYToDate = this.getPreviousYearDate(horizNode.toDate.date); - - return R.compose( - R.assoc('previousYearToDate', this.getDateMeta(PYToDate)), - R.assoc('previousYearFromDate', this.getDateMeta(PYFromDate)) - )(horizNode); - }; - - /** - * Retrieves PP total sumation of the given horiz index node. - * @param {number} index - * @param {} node - * @returns {number} - */ - protected getPYHorizNodesTotalSumation = (index: number, node): number => { - return sumBy( - node.children, - `horizontalTotals[${index}].previousYear.amount` - ) - } - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialReportService.ts b/packages/server/src/services/FinancialStatements/FinancialReportService.ts deleted file mode 100644 index ad05715ff..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialReportService.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default class FinancialReportService { - transformOrganizationMeta(tenant) { - return { - organizationName: tenant.metadata?.name, - baseCurrency: tenant.metadata?.baseCurrency, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/FinancialSchema.ts b/packages/server/src/services/FinancialStatements/FinancialSchema.ts deleted file mode 100644 index 6d676ce28..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialSchema.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as R from 'ramda'; -import { FinancialSheetStructure } from './FinancialSheetStructure'; - -export const FinancialSchema = (Base) => - class extends R.compose(FinancialSheetStructure)(Base) { - /** - * - * @returns - */ - getSchema() { - return []; - } - - /** - * - * @param {string|number} id - * @returns - */ - getSchemaNodeById = (id: string | number) => { - const schema = this.getSchema(); - - return this.findNodeDeep(schema, (node) => node.id === id); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialSheet.ts b/packages/server/src/services/FinancialStatements/FinancialSheet.ts deleted file mode 100644 index 682804bb1..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialSheet.ts +++ /dev/null @@ -1,177 +0,0 @@ -import moment from 'moment'; -import { - ICashFlowStatementTotal, - IFormatNumberSettings, - INumberFormatQuery, -} from '@/interfaces'; -import { formatNumber } from 'utils'; - -export default class FinancialSheet { - readonly numberFormat: INumberFormatQuery = { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }; - readonly baseCurrency: string; - - /** - * Transformes the number format query to settings - */ - protected transfromFormatQueryToSettings(): IFormatNumberSettings { - const { numberFormat } = this; - - return { - precision: numberFormat.precision, - divideOn1000: numberFormat.divideOn1000, - excerptZero: !numberFormat.showZero, - negativeFormat: numberFormat.negativeFormat, - money: numberFormat.formatMoney === 'always', - currencyCode: this.baseCurrency, - }; - } - - /** - * Formating amount based on the given report query. - * @param {number} number - - * @param {IFormatNumberSettings} overrideSettings - - * @return {string} - */ - protected formatNumber( - number, - overrideSettings: IFormatNumberSettings = {} - ): string { - const settings = { - ...this.transfromFormatQueryToSettings(), - ...overrideSettings, - }; - return formatNumber(number, settings); - } - - /** - * Formatting full amount with different format settings. - * @param {number} amount - - * @param {IFormatNumberSettings} settings - - */ - protected formatTotalNumber = ( - amount: number, - settings: IFormatNumberSettings = {} - ): string => { - const { numberFormat } = this; - - return this.formatNumber(amount, { - money: numberFormat.formatMoney === 'none' ? false : true, - excerptZero: false, - ...settings, - }); - }; - - /** - * Formates the amount to the percentage string. - * @param {number} amount - * @returns {string} - */ - protected formatPercentage = ( - amount: number, - overrideSettings: IFormatNumberSettings = {} - ): string => { - const percentage = amount * 100; - const settings = { - excerptZero: true, - ...overrideSettings, - symbol: '%', - money: false, - }; - return formatNumber(percentage, settings); - }; - - /** - * Format the given total percentage. - * @param {number} amount - - * @param {IFormatNumberSettings} settings - - */ - protected formatTotalPercentage = ( - amount: number, - settings: IFormatNumberSettings = {} - ): string => { - return this.formatPercentage(amount, { - ...settings, - excerptZero: false, - }); - }; - - /** - * Retrieve the amount meta object. - * @param {number} amount - * @returns {ICashFlowStatementTotal} - */ - protected getAmountMeta( - amount: number, - overrideSettings?: IFormatNumberSettings - ): ICashFlowStatementTotal { - return { - amount, - formattedAmount: this.formatNumber(amount, overrideSettings), - currencyCode: this.baseCurrency, - }; - } - - /** - * Retrieve the total amount meta object. - * @param {number} amount - * @returns {ICashFlowStatementTotal} - */ - protected getTotalAmountMeta( - amount: number, - title?: string - ): ICashFlowStatementTotal { - return { - ...(title ? { title } : {}), - amount, - formattedAmount: this.formatTotalNumber(amount), - currencyCode: this.baseCurrency, - }; - } - - /** - * Retrieve the date meta. - * @param {Date} date - * @param {string} format - * @returns - */ - protected getDateMeta(date: Date, format = 'YYYY-MM-DD') { - return { - formattedDate: moment(date).format(format), - date: moment(date).toDate(), - }; - } - - getPercentageBasis = (base, amount) => { - return base ? amount / base : 0; - }; - - getAmountChange = (base, amount) => { - return base - amount; - }; - - protected getPercentageAmountMeta = (amount) => { - const formattedAmount = this.formatPercentage(amount); - - return { - amount, - formattedAmount, - }; - }; - - /** - * Re - * @param {number} amount - * @returns - */ - protected getPercentageTotalAmountMeta = (amount: number) => { - const formattedAmount = this.formatTotalPercentage(amount); - - return { amount, formattedAmount }; - }; -} diff --git a/packages/server/src/services/FinancialStatements/FinancialSheetMeta.ts b/packages/server/src/services/FinancialStatements/FinancialSheetMeta.ts deleted file mode 100644 index 130f3caaa..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialSheetMeta.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { TenantMetadata } from '@/system/models'; -import { Inject, Service } from 'typedi'; -import InventoryService from '../Inventory/Inventory'; -import { IFinancialSheetCommonMeta } from '@/interfaces'; - -@Service() -export class FinancialSheetMeta { - @Inject() - private inventoryService: InventoryService; - - /** - * Retrieves the common meta data of the financial sheet. - * @param {number} tenantId - * @returns {Promise} - */ - async meta(tenantId: number): Promise { - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - const organizationName = tenantMetadata.name; - const baseCurrency = tenantMetadata.baseCurrency; - const dateFormat = tenantMetadata.dateFormat; - - const isCostComputeRunning = - this.inventoryService.isItemsCostComputeRunning(tenantId); - - return { - organizationName, - baseCurrency, - dateFormat, - isCostComputeRunning, - sheetName: '', - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/FinancialSheetStructure.ts b/packages/server/src/services/FinancialStatements/FinancialSheetStructure.ts deleted file mode 100644 index 5e2fbba55..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialSheetStructure.ts +++ /dev/null @@ -1,107 +0,0 @@ -import * as R from 'ramda'; -import { set, sumBy } from 'lodash'; -import { - mapValuesDeepReverse, - mapValuesDeep, - mapValues, - condense, - filterDeep, - reduceDeep, - findValueDeep, - filterNodesDeep, -} from 'utils/deepdash'; - -export const FinancialSheetStructure = (Base: Class) => - class extends Base { - /** - * - * @param nodes - * @param callback - * @returns - */ - public mapNodesDeepReverse = (nodes, callback) => { - return mapValuesDeepReverse(nodes, callback, { - childrenPath: 'children', - pathFormat: 'array', - }); - }; - - /** - * - * @param nodes - * @param callback - * @returns - */ - public mapNodesDeep = (nodes, callback) => { - return mapValuesDeep(nodes, callback, { - childrenPath: 'children', - pathFormat: 'array', - }); - }; - - public mapNodes = (nodes, callback) => { - return mapValues(nodes, callback, { - childrenPath: 'children', - pathFormat: 'array', - }); - }; - - public filterNodesDeep2 = R.curry((predicate, nodes) => { - return filterNodesDeep(predicate, nodes); - }); - - /** - * - * @param - */ - public filterNodesDeep = (nodes, callback) => { - return filterDeep(nodes, callback, { - childrenPath: 'children', - pathFormat: 'array', - }); - }; - - public findNodeDeep = (nodes, callback) => { - return findValueDeep(nodes, callback, { - childrenPath: 'children', - pathFormat: 'array', - }); - }; - - public mapAccNodesDeep = (nodes, callback) => { - return reduceDeep( - nodes, - (acc, value, key, parentValue, context) => { - set( - acc, - context.path, - callback(value, key, parentValue, acc, context) - ); - return acc; - }, - [], - { - childrenPath: 'children', - pathFormat: 'array', - } - ); - }; - - /** - * - */ - public reduceNodesDeep = (nodes, iteratee, accumulator) => { - return reduceDeep(nodes, iteratee, accumulator, { - childrenPath: 'children', - pathFormat: 'array', - }); - }; - - public getTotalOfChildrenNodes = (node) => { - return this.getTotalOfNodes(node.children); - }; - - public getTotalOfNodes = (nodes) => { - return sumBy(nodes, 'total.amount'); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialTable.ts b/packages/server/src/services/FinancialStatements/FinancialTable.ts deleted file mode 100644 index 0a7eafd01..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialTable.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as R from 'ramda'; -import { ITableColumn } from '@/interfaces'; -import { isEmpty, clone, cloneDeep, omit } from 'lodash'; -import { increment } from 'utils'; -import { ITableRow } from '@/interfaces'; -import { IROW_TYPE, DISPLAY_COLUMNS_BY } from './BalanceSheet/constants'; - -export const FinancialTable = (Base) => - class extends Base { - /** - * Table columns cell indexing. - * @param {ITableColumn[]} columns - * @returns {ITableColumn[]} - */ - public tableColumnsCellIndexing = ( - columns: ITableColumn[] - ): ITableColumn[] => { - const cellIndex = increment(-1); - - return this.mapNodesDeep(columns, (column) => { - return isEmpty(column.children) - ? R.assoc('cellIndex', cellIndex(), column) - : column; - }); - }; - - addTotalRow = (node: ITableRow) => { - const clonedNode = clone(node); - - if (clonedNode.children) { - const cells = cloneDeep(node.cells); - cells[0].value = this.i18n.__('financial_sheet.total_row', { - value: cells[0].value, - }); - - clonedNode.children.push({ - ...omit(clonedNode, 'children'), - cells, - rowTypes: [IROW_TYPE.TOTAL], - }); - } - return clonedNode; - }; - - private addTotalRows = (nodes: ITableRow[]) => { - return this.mapNodesDeep(nodes, this.addTotalRow); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialTablePreviousPeriod.ts b/packages/server/src/services/FinancialStatements/FinancialTablePreviousPeriod.ts deleted file mode 100644 index 107431340..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialTablePreviousPeriod.ts +++ /dev/null @@ -1,130 +0,0 @@ -import moment from 'moment'; -import { ITableColumn, IDateRange, ITableColumnAccessor } from '@/interfaces'; - -export const FinancialTablePreviousPeriod = (Base) => - class extends Base { - getTotalPreviousPeriod = () => { - return this.query.PPToDate; - }; - // ---------------------------- - // # Columns - // ---------------------------- - /** - * Retrive previous period total column. - * @param {IDateRange} dateRange - - * @returns {ITableColumn} - */ - protected getPreviousPeriodTotalColumn = ( - dateRange?: IDateRange - ): ITableColumn => { - const PPDate = dateRange - ? dateRange.toDate - : this.getTotalPreviousPeriod(); - const PPFormatted = moment(PPDate).format('YYYY-MM-DD'); - - return { - key: 'previous_period', - label: this.i18n.__(`financial_sheet.previoud_period_date`, { - date: PPFormatted, - }), - }; - }; - - /** - * Retrieve previous period change column. - * @returns {ITableColumn} - */ - protected getPreviousPeriodChangeColumn = (): ITableColumn => { - return { - key: 'previous_period_change', - label: this.i18n.__('fianncial_sheet.previous_period_change'), - }; - }; - - /** - * Retrieve previous period percentage column. - * @returns {ITableColumn} - */ - protected getPreviousPeriodPercentageColumn = (): ITableColumn => { - return { - key: 'previous_period_percentage', - label: this.i18n.__('financial_sheet.previous_period_percentage'), - }; - }; - - /** - * Retrieves previous period total accessor. - * @returns {ITableColumnAccessor} - */ - protected getPreviousPeriodTotalAccessor = (): ITableColumnAccessor => { - return { - key: 'previous_period', - accessor: 'previousPeriod.formattedAmount', - }; - }; - - /** - * Retrieves previous period change accessor. - * @returns - */ - protected getPreviousPeriodChangeAccessor = () => { - return { - key: 'previous_period_change', - accessor: 'previousPeriodChange.formattedAmount', - }; - }; - - /** - * Retrieves previous period percentage accessor. - * @returns {ITableColumnAccessor} - */ - protected getPreviousPeriodPercentageAccessor = - (): ITableColumnAccessor => { - return { - key: 'previous_period_percentage', - accessor: 'previousPeriodPercentage.formattedAmount', - }; - }; - - /** - * Retrieves previous period total horizontal column accessor. - * @param {number} index - * @returns {ITableColumnAccessor} - */ - protected getPreviousPeriodTotalHorizAccessor = ( - index: number - ): ITableColumnAccessor => { - return { - key: 'previous_period', - accessor: `horizontalTotals[${index}].previousPeriod.formattedAmount`, - }; - }; - - /** - * Retrieves previous period change horizontal column accessor. - * @param {number} index - * @returns {ITableColumnAccessor} - */ - protected getPreviousPeriodChangeHorizAccessor = ( - index: number - ): ITableColumnAccessor => { - return { - key: 'previous_period_change', - accessor: `horizontalTotals[${index}].previousPeriodChange.formattedAmount`, - }; - }; - - /** - * Retrieves pervious period percentage horizontal column accessor. - * @param {number} index - * @returns {ITableColumnAccessor} - */ - protected getPreviousPeriodPercentageHorizAccessor = ( - index: number - ): ITableColumnAccessor => { - return { - key: 'previous_period_percentage', - accessor: `horizontalTotals[${index}].previousPeriodPercentage.formattedAmount`, - }; - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialTablePreviousYear.ts b/packages/server/src/services/FinancialStatements/FinancialTablePreviousYear.ts deleted file mode 100644 index 4924926d6..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialTablePreviousYear.ts +++ /dev/null @@ -1,130 +0,0 @@ -import moment from 'moment'; -import { IDateRange, ITableColumn, ITableColumnAccessor } from '@/interfaces'; - -export const FinancialTablePreviousYear = (Base) => - class extends Base { - getTotalPreviousYear = () => { - return this.query.PYToDate; - }; - // ------------------------------------ - // # Columns. - // ------------------------------------ - /** - * Retrive previous year total column. - * @param {DateRange} previousYear - - * @returns {ITableColumn} - */ - protected getPreviousYearTotalColumn = ( - dateRange?: IDateRange - ): ITableColumn => { - const PYDate = dateRange ? dateRange.toDate : this.getTotalPreviousYear(); - const PYFormatted = moment(PYDate).format('YYYY-MM-DD'); - - return { - key: 'previous_year', - label: this.i18n.__('financial_sheet.previous_year_date', { - date: PYFormatted, - }), - }; - }; - - /** - * Retrieve previous year change column. - * @returns {ITableColumn} - */ - protected getPreviousYearChangeColumn = (): ITableColumn => { - return { - key: 'previous_year_change', - label: this.i18n.__('financial_sheet.previous_year_change'), - }; - }; - - /** - * Retrieve previous year percentage column. - * @returns {ITableColumn} - */ - protected getPreviousYearPercentageColumn = (): ITableColumn => { - return { - key: 'previous_year_percentage', - label: this.i18n.__('financial_sheet.previous_year_percentage'), - }; - }; - - // ------------------------------------ - // # Accessors. - // ------------------------------------ - /** - * Retrieves previous year total column accessor. - * @returns {ITableColumnAccessor} - */ - protected getPreviousYearTotalAccessor = (): ITableColumnAccessor => { - return { - key: 'previous_year', - accessor: 'previousYear.formattedAmount', - }; - }; - - /** - * Retrieves previous year change column accessor. - * @returns {ITableColumnAccessor} - */ - protected getPreviousYearChangeAccessor = (): ITableColumnAccessor => { - return { - key: 'previous_year_change', - accessor: 'previousYearChange.formattedAmount', - }; - }; - - /** - * Retrieves previous year percentage column accessor. - * @returns {ITableColumnAccessor} - */ - protected getPreviousYearPercentageAccessor = (): ITableColumnAccessor => { - return { - key: 'previous_year_percentage', - accessor: 'previousYearPercentage.formattedAmount', - }; - }; - - /** - * Retrieves previous year total horizontal column accessor. - * @param {number} index - * @returns {ITableColumnAccessor} - */ - protected getPreviousYearTotalHorizAccessor = ( - index: number - ): ITableColumnAccessor => { - return { - key: 'previous_year', - accessor: `horizontalTotals[${index}].previousYear.formattedAmount`, - }; - }; - - /** - * Retrieves previous previous year change horizontal column accessor. - * @param {number} index - * @returns {ITableColumnAccessor} - */ - protected getPreviousYearChangeHorizAccessor = ( - index: number - ): ITableColumnAccessor => { - return { - key: 'previous_year_change', - accessor: `horizontalTotals[${index}].previousYearChange.formattedAmount`, - }; - }; - - /** - * Retrieves previous year percentage horizontal column accessor. - * @param {number} index - * @returns {ITableColumnAccessor} - */ - protected getPreviousYearPercentageHorizAccessor = ( - index: number - ): ITableColumnAccessor => { - return { - key: 'previous_year_percentage', - accessor: `horizontalTotals[${index}].previousYearPercentage.formattedAmount`, - }; - }; - }; diff --git a/packages/server/src/services/FinancialStatements/FinancialTableStructure.ts b/packages/server/src/services/FinancialStatements/FinancialTableStructure.ts deleted file mode 100644 index 6b3bb38b7..000000000 --- a/packages/server/src/services/FinancialStatements/FinancialTableStructure.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ITableRow } from '@/interfaces'; -import { flatNestedTree } from '@/utils/deepdash'; -import { repeat } from 'lodash'; - -interface FlatNestTreeOpts { - nestedPrefix?: string; - nestedPrefixIndex?: number; -} - -export class FinancialTableStructure { - /** - * Converts the given table object with nested rows in flat rows. - * @param {ITableRow[]} - * @param {FlatNestTreeOpts} - * @returns {ITableRow[]} - */ - public static flatNestedTree = ( - obj: ITableRow[], - options?: FlatNestTreeOpts - ): ITableRow[] => { - const parsedOptions = { - nestedPrefix: ' ', - nestedPrefixIndex: 0, - ...options, - }; - const { nestedPrefixIndex, nestedPrefix } = parsedOptions; - - return flatNestedTree( - obj, - (item, key, context) => { - const cells = item.cells.map((cell, index) => { - return { - ...cell, - value: - (context.depth > 1 && nestedPrefixIndex === index - ? repeat(nestedPrefix, context.depth) - : '') + cell.value, - }; - }); - return { - ...item, - cells, - }; - }, - parsedOptions - ); - }; -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedger.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedger.ts deleted file mode 100644 index 3a8a69bf0..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedger.ts +++ /dev/null @@ -1,382 +0,0 @@ -import { isEmpty, get, last, sumBy, first, head } from 'lodash'; -import moment from 'moment'; -import * as R from 'ramda'; -import { - IGeneralLedgerSheetQuery, - IGeneralLedgerSheetAccount, - IGeneralLedgerSheetAccountBalance, - IGeneralLedgerSheetAccountTransaction, - IAccount, - ILedgerEntry, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { GeneralLedgerRepository } from './GeneralLedgerRepository'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { flatToNestedArray } from '@/utils'; -import Ledger from '@/services/Accounting/Ledger'; -import { calculateRunningBalance } from './_utils'; -import { getTransactionTypeLabel } from '@/utils/transactions-types'; - -/** - * General ledger sheet. - */ -export default class GeneralLedgerSheet extends R.compose( - FinancialSheetStructure -)(FinancialSheet) { - private query: IGeneralLedgerSheetQuery; - private baseCurrency: string; - private i18n: any; - private repository: GeneralLedgerRepository; - - /** - * Constructor method. - * @param {number} tenantId - - * @param {IAccount[]} accounts - - * @param {IJournalPoster} transactions - - * @param {IJournalPoster} openingBalancesJournal - - * @param {IJournalPoster} closingBalancesJournal - - */ - constructor( - query: IGeneralLedgerSheetQuery, - repository: GeneralLedgerRepository, - i18n - ) { - super(); - - this.query = query; - this.numberFormat = this.query.numberFormat; - this.repository = repository; - this.baseCurrency = this.repository.tenant.metadata.currencyCode; - this.i18n = i18n; - } - - /** - * Entry mapper. - * @param {ILedgerEntry} entry - - * @return {IGeneralLedgerSheetAccountTransaction} - */ - private getEntryRunningBalance( - entry: ILedgerEntry, - openingBalance: number, - runningBalance?: number - ): number { - const lastRunningBalance = runningBalance || openingBalance; - - const amount = Ledger.getAmount( - entry.credit, - entry.debit, - entry.accountNormal - ); - return calculateRunningBalance(amount, lastRunningBalance); - } - - /** - * Maps the given ledger entry to G/L transaction. - * @param {ILedgerEntry} entry - * @param {number} runningBalance - * @returns {IGeneralLedgerSheetAccountTransaction} - */ - private transactionMapper( - entry: ILedgerEntry, - runningBalance: number - ): IGeneralLedgerSheetAccountTransaction { - const contact = this.repository.contactsById.get(entry.contactId); - const amount = Ledger.getAmount( - entry.credit, - entry.debit, - entry.accountNormal - ); - return { - id: entry.id, - date: entry.date, - dateFormatted: moment(entry.date).format('YYYY MMM DD'), - - referenceType: entry.transactionType, - referenceId: entry.transactionId, - - transactionNumber: entry.transactionNumber, - transactionTypeFormatted: this.i18n.__( - getTransactionTypeLabel(entry.transactionType, entry.transactionSubType) - ), - contactName: get(contact, 'displayName'), - contactType: get(contact, 'contactService'), - - transactionType: entry.transactionType, - index: entry.index, - note: entry.note, - - credit: entry.credit, - debit: entry.debit, - amount, - runningBalance, - - formattedAmount: this.formatNumber(amount, { excerptZero: false }), - formattedCredit: this.formatNumber(entry.credit, { excerptZero: false }), - formattedDebit: this.formatNumber(entry.debit, { excerptZero: false }), - formattedRunningBalance: this.formatNumber(runningBalance, { - excerptZero: false, - }), - - currencyCode: this.baseCurrency, - } as IGeneralLedgerSheetAccountTransaction; - } - - /** - * Mapping the account transactions to general ledger transactions of the given account. - * @param {IAccount} account - * @return {IGeneralLedgerSheetAccountTransaction[]} - */ - private accountTransactionsMapper( - account: IAccount, - openingBalance: number - ): IGeneralLedgerSheetAccountTransaction[] { - const entries = this.repository.transactionsLedger - .whereAccountId(account.id) - .getEntries(); - - return entries - .reduce((prev: Array<[number, ILedgerEntry]>, current: ILedgerEntry) => { - const prevEntry = last(prev); - const prevRunningBalance = head(prevEntry) as number; - const amount = this.getEntryRunningBalance( - current, - openingBalance, - prevRunningBalance - ); - return [...prev, [amount, current]]; - }, []) - .map((entryPair: [number, ILedgerEntry]) => { - const [runningBalance, entry] = entryPair; - - return this.transactionMapper(entry, runningBalance); - }); - } - - /** - * Retrieves the given account opening balance. - * @param {number} accountId - * @returns {number} - */ - private accountOpeningBalance(accountId: number): number { - return this.repository.openingBalanceTransactionsLedger - .whereAccountId(accountId) - .getClosingBalance(); - } - - /** - * Retrieve the given account opening balance. - * @param {IAccount} account - * @return {IGeneralLedgerSheetAccountBalance} - */ - private accountOpeningBalanceTotal( - accountId: number - ): IGeneralLedgerSheetAccountBalance { - const amount = this.accountOpeningBalance(accountId); - const formattedAmount = this.formatTotalNumber(amount); - const currencyCode = this.baseCurrency; - const date = this.query.fromDate; - - return { amount, formattedAmount, currencyCode, date }; - } - - /** - * Retrieves the given account closing balance. - * @param {number} accountId - * @returns {number} - */ - private accountClosingBalance(accountId: number): number { - const openingBalance = this.repository.openingBalanceTransactionsLedger - .whereAccountId(accountId) - .getClosingBalance(); - - const transactionsBalance = this.repository.transactionsLedger - .whereAccountId(accountId) - .getClosingBalance(); - - return openingBalance + transactionsBalance; - } - - /** - * Retrieves the given account closing balance. - * @param {IAccount} account - * @return {IGeneralLedgerSheetAccountBalance} - */ - private accountClosingBalanceTotal( - accountId: number - ): IGeneralLedgerSheetAccountBalance { - const amount = this.accountClosingBalance(accountId); - const formattedAmount = this.formatTotalNumber(amount); - const currencyCode = this.baseCurrency; - const date = this.query.toDate; - - return { amount, formattedAmount, currencyCode, date }; - } - - /** - * Retrieves the given account closing balance with subaccounts. - * @param {number} accountId - * @returns {number} - */ - private accountClosingBalanceWithSubaccounts = ( - accountId: number - ): number => { - const depsAccountsIds = - this.repository.accountsGraph.dependenciesOf(accountId); - - const openingBalance = this.repository.openingBalanceTransactionsLedger - .whereAccountsIds([...depsAccountsIds, accountId]) - .getClosingBalance(); - - const transactionsBalanceWithSubAccounts = - this.repository.transactionsLedger - .whereAccountsIds([...depsAccountsIds, accountId]) - .getClosingBalance(); - - const closingBalance = openingBalance + transactionsBalanceWithSubAccounts; - - return closingBalance; - }; - - /** - * Retrieves the closing balance with subaccounts total node. - * @param {number} accountId - * @returns {IGeneralLedgerSheetAccountBalance} - */ - private accountClosingBalanceWithSubaccountsTotal = ( - accountId: number - ): IGeneralLedgerSheetAccountBalance => { - const amount = this.accountClosingBalanceWithSubaccounts(accountId); - const formattedAmount = this.formatTotalNumber(amount); - const currencyCode = this.baseCurrency; - const date = this.query.toDate; - - return { amount, formattedAmount, currencyCode, date }; - }; - - /** - * Detarmines whether the closing balance subaccounts node should be exist. - * @param {number} accountId - * @returns {boolean} - */ - private isAccountNodeIncludesClosingSubaccounts = (accountId: number) => { - // Retrun early if there is no accounts in the filter so - // return closing subaccounts in all cases. - if (isEmpty(this.query.accountsIds)) { - return true; - } - // Returns true if the given account id includes transactions. - return this.repository.accountNodesIncludeTransactions.includes(accountId); - }; - - /** - * Retreive general ledger accounts sections. - * @param {IAccount} account - * @return {IGeneralLedgerSheetAccount} - */ - private accountMapper = (account: IAccount): IGeneralLedgerSheetAccount => { - const openingBalance = this.accountOpeningBalanceTotal(account.id); - const transactions = this.accountTransactionsMapper( - account, - openingBalance.amount - ); - const closingBalance = this.accountClosingBalanceTotal(account.id); - const closingBalanceSubaccounts = - this.accountClosingBalanceWithSubaccountsTotal(account.id); - - const initialNode = { - id: account.id, - name: account.name, - code: account.code, - index: account.index, - parentAccountId: account.parentAccountId, - openingBalance, - transactions, - closingBalance, - }; - - return R.compose( - R.when( - () => this.isAccountNodeIncludesClosingSubaccounts(account.id), - R.assoc('closingBalanceSubaccounts', closingBalanceSubaccounts) - ) - )(initialNode); - }; - - /** - * Maps over deep nodes to retrieve the G/L account node. - * @param {IAccount[]} accounts - * @returns {IGeneralLedgerSheetAccount[]} - */ - private accountNodesDeepMap = ( - accounts: IAccount[] - ): IGeneralLedgerSheetAccount[] => { - return this.mapNodesDeep(accounts, this.accountMapper); - }; - - /** - * Transformes the flatten nodes to nested nodes. - */ - private nestedAccountsNode = (flattenAccounts: IAccount[]): IAccount[] => { - return flatToNestedArray(flattenAccounts, { - id: 'id', - parentId: 'parentAccountId', - }); - }; - - /** - * Filters account nodes. - * @param {IGeneralLedgerSheetAccount[]} nodes - * @returns {IGeneralLedgerSheetAccount[]} - */ - private filterAccountNodesByTransactionsFilter = ( - nodes: IGeneralLedgerSheetAccount[] - ): IGeneralLedgerSheetAccount[] => { - return this.filterNodesDeep( - nodes, - (account: IGeneralLedgerSheetAccount) => - !(account.transactions.length === 0 && this.query.noneTransactions) - ); - }; - - /** - * Filters account nodes by the acounts filter. - * @param {IAccount[]} nodes - * @returns {IAccount[]} - */ - private filterAccountNodesByAccountsFilter = ( - nodes: IAccount[] - ): IAccount[] => { - return this.filterNodesDeep(nodes, (node: IGeneralLedgerSheetAccount) => { - if (R.isEmpty(this.query.accountsIds)) { - return true; - } - // Returns true if the given account id exists in the filter. - return this.repository.accountNodeInclude?.includes(node.id); - }); - }; - - /** - * Retrieves mapped accounts with general ledger transactions and - * opeing/closing balance. - * @param {IAccount[]} accounts - - * @return {IGeneralLedgerSheetAccount[]} - */ - private accountsWalker(accounts: IAccount[]): IGeneralLedgerSheetAccount[] { - return R.compose( - R.defaultTo([]), - this.filterAccountNodesByTransactionsFilter, - this.accountNodesDeepMap, - R.defaultTo([]), - this.filterAccountNodesByAccountsFilter, - this.nestedAccountsNode - )(accounts); - } - - /** - * Retrieves general ledger report data. - * @return {IGeneralLedgerSheetAccount[]} - */ - public reportData(): IGeneralLedgerSheetAccount[] { - return this.accountsWalker(this.repository.accounts); - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerApplication.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerApplication.ts deleted file mode 100644 index 6257e34d8..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerApplication.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Inject } from 'typedi'; -import { - IGeneralLedgerSheetQuery, - IGeneralLedgerTableData, -} from '@/interfaces'; -import { GeneralLedgerTableInjectable } from './GeneralLedgerTableInjectable'; -import { GeneralLedgerExportInjectable } from './GeneralLedgerExport'; -import { GeneralLedgerService } from './GeneralLedgerService'; -import { GeneralLedgerPdf } from './GeneralLedgerPdf'; - -export class GeneralLedgerApplication { - @Inject() - private GLTable: GeneralLedgerTableInjectable; - - @Inject() - private GLExport: GeneralLedgerExportInjectable; - - @Inject() - private GLSheet: GeneralLedgerService; - - @Inject() - private GLPdf: GeneralLedgerPdf; - - /** - * Retrieves the G/L sheet in json format. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - */ - public sheet(tenantId: number, query: IGeneralLedgerSheetQuery) { - return this.GLSheet.generalLedger(tenantId, query); - } - - /** - * Retrieves the G/L sheet in table format. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @returns {Promise} - */ - public table( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - return this.GLTable.table(tenantId, query); - } - - /** - * Retrieves the G/L sheet in xlsx format. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @returns {} - */ - public xlsx( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - return this.GLExport.xlsx(tenantId, query); - } - - /** - * Retrieves the G/L sheet in csv format. - * @param {number} tenantId - - * @param {IGeneralLedgerSheetQuery} query - - */ - public csv( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - return this.GLExport.csv(tenantId, query); - } - - /** - * Retrieves the G/L sheet in pdf format. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @returns {Promise} - */ - public pdf( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - return this.GLPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerExport.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerExport.ts deleted file mode 100644 index f05c817c2..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerExport.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { IGeneralLedgerSheetQuery } from '@/interfaces'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { Inject, Service } from 'typedi'; -import { GeneralLedgerTableInjectable } from './GeneralLedgerTableInjectable'; - -@Service() -export class GeneralLedgerExportInjectable { - @Inject() - private generalLedgerTable: GeneralLedgerTableInjectable; - - /** - * Retrieves the general ledger sheet in XLSX format. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IGeneralLedgerSheetQuery) { - const table = await this.generalLedgerTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the general ledger sheet in CSV format. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - const table = await this.generalLedgerTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerMeta.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerMeta.ts deleted file mode 100644 index 00f312654..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerMeta.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { IGeneralLedgerMeta, IGeneralLedgerSheetQuery } from '@/interfaces'; -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; - -@Service() -export class GeneralLedgerMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the balance sheet meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - return { - ...commonMeta, - sheetName: 'Balance Sheet', - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerPdf.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerPdf.ts deleted file mode 100644 index efe082709..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerPdf.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { GeneralLedgerTableInjectable } from './GeneralLedgerTableInjectable'; -import { IGeneralLedgerSheetQuery } from '@/interfaces'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class GeneralLedgerPdf { - @Inject() - private generalLedgerTable: GeneralLedgerTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the general ledger sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IGeneralLedgerSheetQuery} query - - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - const table = await this.generalLedgerTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerRepository.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerRepository.ts deleted file mode 100644 index 875b4fefa..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerRepository.ts +++ /dev/null @@ -1,180 +0,0 @@ -import moment from 'moment'; -import * as R from 'ramda'; -import { - IAccount, - IAccountTransaction, - IContact, - IGeneralLedgerSheetQuery, - ITenant, -} from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; -import { transformToMap } from '@/utils'; -import { Tenant } from '@/system/models'; -import { flatten, isEmpty, uniq } from 'lodash'; - -export class GeneralLedgerRepository { - public filter: IGeneralLedgerSheetQuery; - public accounts: IAccount[]; - - public transactions: IAccountTransaction[]; - public openingBalanceTransactions: IAccountTransaction[]; - - public transactionsLedger: Ledger; - public openingBalanceTransactionsLedger: Ledger; - - public repositories: any; - public models: any; - public accountsGraph: any; - - public contacts: IContact; - public contactsById: Map; - - public tenantId: number; - public tenant: ITenant; - - public accountNodesIncludeTransactions: Array = []; - public accountNodeInclude: Array = []; - - /** - * Constructor method. - * @param models - * @param repositories - * @param filter - */ - constructor( - repositories: any, - filter: IGeneralLedgerSheetQuery, - tenantId: number - ) { - this.filter = filter; - this.repositories = repositories; - this.tenantId = tenantId; - } - - /** - * Initialize the G/L report. - */ - public async asyncInitialize() { - await this.initTenant(); - await this.initAccounts(); - await this.initAccountsGraph(); - await this.initContacts(); - await this.initAccountsOpeningBalance(); - this.initAccountNodesIncludeTransactions(); - await this.initTransactions(); - this.initAccountNodesIncluded(); - } - - /** - * Initialize the tenant. - */ - public async initTenant() { - this.tenant = await Tenant.query() - .findById(this.tenantId) - .withGraphFetched('metadata'); - } - - /** - * Initialize the accounts. - */ - public async initAccounts() { - this.accounts = await this.repositories.accountRepository - .all() - .orderBy('name', 'ASC'); - } - - /** - * Initialize the accounts graph. - */ - public async initAccountsGraph() { - this.accountsGraph = - await this.repositories.accountRepository.getDependencyGraph(); - } - - /** - * Initialize the contacts. - */ - public async initContacts() { - this.contacts = await this.repositories.contactRepository.all(); - this.contactsById = transformToMap(this.contacts, 'id'); - } - - /** - * Initialize the G/L transactions from/to the given date. - */ - public async initTransactions() { - this.transactions = await this.repositories.transactionsRepository - .journal({ - fromDate: this.filter.fromDate, - toDate: this.filter.toDate, - branchesIds: this.filter.branchesIds, - }) - .orderBy('date', 'ASC') - .onBuild((query) => { - if (this.filter.accountsIds?.length > 0) { - query.whereIn('accountId', this.accountNodesIncludeTransactions); - } - }); - // Transform array transactions to journal collection. - this.transactionsLedger = Ledger.fromTransactions(this.transactions); - } - - /** - * Initialize the G/L accounts opening balance. - */ - public async initAccountsOpeningBalance() { - // Retreive opening balance credit/debit sumation. - this.openingBalanceTransactions = - await this.repositories.transactionsRepository.journal({ - toDate: moment(this.filter.fromDate).subtract(1, 'day'), - sumationCreditDebit: true, - branchesIds: this.filter.branchesIds, - }); - - // Accounts opening transactions. - this.openingBalanceTransactionsLedger = Ledger.fromTransactions( - this.openingBalanceTransactions - ); - } - - /** - * Initialize the account nodes that should include transactions. - * @returns {void} - */ - public initAccountNodesIncludeTransactions() { - if (isEmpty(this.filter.accountsIds)) { - return; - } - const childrenNodeIds = this.filter.accountsIds?.map( - (accountId: number) => { - return this.accountsGraph.dependenciesOf(accountId); - } - ); - const nodeIds = R.concat(this.filter.accountsIds, childrenNodeIds); - - this.accountNodesIncludeTransactions = uniq(flatten(nodeIds)); - } - - /** - * Initialize the account node ids should be included, - * if the filter by acounts is presented. - * @returns {void} - */ - public initAccountNodesIncluded() { - if (isEmpty(this.filter.accountsIds)) { - return; - } - const nodeIds = this.filter.accountsIds.map((accountId) => { - const childrenIds = this.accountsGraph.dependenciesOf(accountId); - const parentIds = this.accountsGraph.dependantsOf(accountId); - - return R.concat(childrenIds, parentIds); - }); - - this.accountNodeInclude = R.compose( - R.uniq, - R.flatten, - R.concat(this.filter.accountsIds) - )(nodeIds); - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerService.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerService.ts deleted file mode 100644 index a614c2cf5..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerService.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { IGeneralLedgerSheetQuery, IGeneralLedgerMeta } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import GeneralLedgerSheet from '@/services/FinancialStatements/GeneralLedger/GeneralLedger'; -import { GeneralLedgerMeta } from './GeneralLedgerMeta'; -import { GeneralLedgerRepository } from './GeneralLedgerRepository'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class GeneralLedgerService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private generalLedgerMeta: GeneralLedgerMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults general ledger report filter query. - * @return {IBalanceSheetQuery} - */ - get defaultQuery() { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - basis: 'cash', - numberFormat: { - noCents: false, - divideOn1000: false, - }, - noneZero: false, - accountsIds: [], - }; - } - - /** - * Retrieve general ledger report statement. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @return {Promise} - */ - public async generalLedger( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise<{ - data: any; - query: IGeneralLedgerSheetQuery; - meta: IGeneralLedgerMeta; - }> { - const repositories = this.tenancy.repositories(tenantId); - const i18n = this.tenancy.i18n(tenantId); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const genealLedgerRepository = new GeneralLedgerRepository( - repositories, - query, - tenantId - ); - await genealLedgerRepository.asyncInitialize(); - - // General ledger report instance. - const generalLedgerInstance = new GeneralLedgerSheet( - filter, - genealLedgerRepository, - i18n - ); - // Retrieve general ledger report data. - const reportData = generalLedgerInstance.reportData(); - - // Retrieve general ledger report metadata. - const meta = await this.generalLedgerMeta.meta(tenantId, filter); - - // Triggers `onGeneralLedgerViewed` event. - await this.eventPublisher.emitAsync(events.reports.onGeneralLedgerViewed, { - tenantId, - }); - - return { - data: reportData, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTable.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTable.ts deleted file mode 100644 index 4ecb898e9..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTable.ts +++ /dev/null @@ -1,322 +0,0 @@ -import * as R from 'ramda'; -import { - IColumnMapperMeta, - IGeneralLedgerMeta, - IGeneralLedgerSheetAccount, - IGeneralLedgerSheetAccountTransaction, - IGeneralLedgerSheetData, - IGeneralLedgerSheetQuery, - ITableColumn, - ITableColumnAccessor, - ITableRow, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { FinancialTable } from '../FinancialTable'; -import { tableRowMapper } from '@/utils'; -import { ROW_TYPE } from './utils'; - -export class GeneralLedgerTable extends R.compose( - FinancialTable, - FinancialSheetStructure -)(FinancialSheet) { - private data: IGeneralLedgerSheetData; - private query: IGeneralLedgerSheetQuery; - private meta: IGeneralLedgerMeta; - - /** - * Creates an instance of `GeneralLedgerTable`. - * @param {IGeneralLedgerSheetData} data - * @param {IGeneralLedgerSheetQuery} query - */ - constructor( - data: IGeneralLedgerSheetData, - query: IGeneralLedgerSheetQuery, - meta: IGeneralLedgerMeta - ) { - super(); - - this.data = data; - this.query = query; - this.meta = meta; - } - - /** - * Retrieves the common table accessors. - * @returns {ITableColumnAccessor[]} - */ - private accountColumnsAccessors(): ITableColumnAccessor[] { - return [ - { key: 'date', accessor: 'name' }, - { key: 'account_name', accessor: '_empty_' }, - { key: 'reference_type', accessor: '_empty_' }, - { key: 'reference_number', accessor: '_empty_' }, - { key: 'description', accessor: 'description' }, - { key: 'credit', accessor: '_empty_' }, - { key: 'debit', accessor: '_empty_' }, - { key: 'amount', accessor: 'amount.formattedAmount' }, - { key: 'running_balance', accessor: 'closingBalance.formattedAmount' }, - ]; - } - - /** - * Retrieves the transaction column accessors. - * @returns {ITableColumnAccessor[]} - */ - private transactionColumnAccessors(): ITableColumnAccessor[] { - return [ - { key: 'date', accessor: 'dateFormatted' }, - { key: 'account_name', accessor: 'account.name' }, - { key: 'reference_type', accessor: 'transactionTypeFormatted' }, - { key: 'reference_number', accessor: 'transactionNumber' }, - { key: 'description', accessor: 'note' }, - { key: 'credit', accessor: 'formattedCredit' }, - { key: 'debit', accessor: 'formattedDebit' }, - { key: 'amount', accessor: 'formattedAmount' }, - { key: 'running_balance', accessor: 'formattedRunningBalance' }, - ]; - } - - /** - * Retrieves the opening row column accessors. - * @returns {ITableRowIColumnMapperMeta[]} - */ - private openingBalanceColumnsAccessors(): IColumnMapperMeta[] { - return [ - { key: 'date', value: 'Opening Balance' }, - { key: 'account_name', value: '' }, - { key: 'reference_type', accessor: '_empty_' }, - { key: 'reference_number', accessor: '_empty_' }, - { key: 'description', accessor: 'description' }, - { key: 'credit', accessor: '_empty_' }, - { key: 'debit', accessor: '_empty_' }, - { key: 'amount', accessor: 'openingBalance.formattedAmount' }, - { key: 'running_balance', accessor: 'openingBalance.formattedAmount' }, - ]; - } - - /** - * Closing balance row column accessors. - * @param {IGeneralLedgerSheetAccount} account - - * @returns {ITableColumnAccessor[]} - */ - private closingBalanceColumnAccessors( - account: IGeneralLedgerSheetAccount - ): IColumnMapperMeta[] { - return [ - { key: 'date', value: `Closing balance for ${account.name}` }, - { key: 'account_name', value: `` }, - { key: 'reference_type', accessor: '_empty_' }, - { key: 'reference_number', accessor: '_empty_' }, - { key: 'description', accessor: '_empty_' }, - { key: 'credit', accessor: '_empty_' }, - { key: 'debit', accessor: '_empty_' }, - { key: 'amount', accessor: 'closingBalance.formattedAmount' }, - { key: 'running_balance', accessor: 'closingBalance.formattedAmount' }, - ]; - } - - /** - * Closing balance row column accessors. - * @param {IGeneralLedgerSheetAccount} account - - * @returns {ITableColumnAccessor[]} - */ - private closingBalanceWithSubaccountsColumnAccessors( - account: IGeneralLedgerSheetAccount - ): IColumnMapperMeta[] { - return [ - { - key: 'date', - value: `Closing Balance for ${account.name} with sub-accounts`, - }, - { - key: 'account_name', - value: ``, - }, - { key: 'reference_type', accessor: '_empty_' }, - { key: 'reference_number', accessor: '_empty_' }, - { key: 'description', accessor: '_empty_' }, - { key: 'credit', accessor: '_empty_' }, - { key: 'debit', accessor: '_empty_' }, - { key: 'amount', accessor: 'closingBalanceSubaccounts.formattedAmount' }, - { - key: 'running_balance', - accessor: 'closingBalanceSubaccounts.formattedAmount', - }, - ]; - } - - /** - * Retrieves the common table columns. - * @returns {ITableColumn[]} - */ - private commonColumns(): ITableColumn[] { - return [ - { key: 'date', label: 'Date' }, - { key: 'account_name', label: 'Account Name' }, - { key: 'reference_type', label: 'Transaction Type' }, - { key: 'reference_number', label: 'Transaction #' }, - { key: 'description', label: 'Description' }, - { key: 'credit', label: 'Credit' }, - { key: 'debit', label: 'Debit' }, - { key: 'amount', label: 'Amount' }, - { key: 'running_balance', label: 'Running Balance' }, - ]; - } - - /** - * Maps the given transaction node to table row. - * @param {IGeneralLedgerSheetAccountTransaction} transaction - * @returns {ITableRow} - */ - private transactionMapper = R.curry( - ( - account: IGeneralLedgerSheetAccount, - transaction: IGeneralLedgerSheetAccountTransaction - ): ITableRow => { - const columns = this.transactionColumnAccessors(); - const data = { ...transaction, account }; - const meta = { - rowTypes: [ROW_TYPE.TRANSACTION], - }; - return tableRowMapper(data, columns, meta); - } - ); - - /** - * Maps the given transactions nodes to table rows. - * @param {IGeneralLedgerSheetAccountTransaction[]} transactions - * @returns {ITableRow[]} - */ - private transactionsMapper = ( - account: IGeneralLedgerSheetAccount - ): ITableRow[] => { - const transactionMapper = this.transactionMapper(account); - - return R.map(transactionMapper)(account.transactions); - }; - - /** - * Maps the given account node to opening balance table row. - * @param {IGeneralLedgerSheetAccount} account - * @returns {ITableRow} - */ - private openingBalanceMapper = ( - account: IGeneralLedgerSheetAccount - ): ITableRow => { - const columns = this.openingBalanceColumnsAccessors(); - const meta = { - rowTypes: [ROW_TYPE.OPENING_BALANCE], - }; - return tableRowMapper(account, columns, meta); - }; - - /** - * Maps the given account node to closing balance table row. - * @param {IGeneralLedgerSheetAccount} account - * @returns {ITableRow} - */ - private closingBalanceMapper = (account: IGeneralLedgerSheetAccount) => { - const columns = this.closingBalanceColumnAccessors(account); - const meta = { - rowTypes: [ROW_TYPE.CLOSING_BALANCE], - }; - return tableRowMapper(account, columns, meta); - }; - - /** - * Maps the given account node to opening balance table row. - * @param {IGeneralLedgerSheetAccount} account - * @returns {ITableRow} - */ - private closingBalanceWithSubaccountsMapper = ( - account: IGeneralLedgerSheetAccount - ): ITableRow => { - const columns = this.closingBalanceWithSubaccountsColumnAccessors(account); - const meta = { - rowTypes: [ROW_TYPE.CLOSING_BALANCE], - }; - return tableRowMapper(account, columns, meta); - }; - - /** - * Maps the given account node to transactions table rows. - * @param {IGeneralLedgerSheetAccount} account - * @returns {ITableRow[]} - */ - private transactionsNode = ( - account: IGeneralLedgerSheetAccount - ): ITableRow[] => { - const openingBalance = this.openingBalanceMapper(account); - const transactions = this.transactionsMapper(account); - const closingBalance = this.closingBalanceMapper(account); - - return R.when( - R.always(R.not(R.isEmpty(transactions))), - R.prepend(openingBalance) - )([...transactions, closingBalance]) as ITableRow[]; - }; - - /** - * Maps the given account node to the table rows. - * @param {IGeneralLedgerSheetAccount} account - * @returns {ITableRow} - */ - private accountMapper = (account: IGeneralLedgerSheetAccount): ITableRow => { - const columns = this.accountColumnsAccessors(); - const transactions = this.transactionsNode(account); - const meta = { - rowTypes: [ROW_TYPE.ACCOUNT], - }; - const row = tableRowMapper(account, columns, meta); - const closingBalanceWithSubaccounts = - this.closingBalanceWithSubaccountsMapper(account); - - // Appends the closing balance with sub-accounts row if the account - // has children accounts and the node is define. - const isAppendClosingSubaccounts = () => - account.children?.length > 0 && !!account.closingBalanceSubaccounts; - - const children = R.compose( - R.when( - isAppendClosingSubaccounts, - R.append(closingBalanceWithSubaccounts) - ), - R.concat(R.defaultTo([], transactions)), - R.when( - () => account?.children?.length > 0, - R.concat(R.defaultTo([], account.children)) - ) - )([]); - - return R.assoc('children', children)(row); - }; - - /** - * Maps the given account node to table rows. - * @param {IGeneralLedgerSheetAccount[]} accounts - * @returns {ITableRow[]} - */ - private accountsMapper = ( - accounts: IGeneralLedgerSheetAccount[] - ): ITableRow[] => { - return this.mapNodesDeepReverse(accounts, this.accountMapper); - }; - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableRows(): ITableRow[] { - return R.compose(this.accountsMapper)(this.data); - } - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns(): ITableColumn[] { - const columns = this.commonColumns(); - return R.compose(this.tableColumnsCellIndexing)(columns); - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTableInjectable.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTableInjectable.ts deleted file mode 100644 index c830c29c2..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/GeneralLedgerTableInjectable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - IGeneralLedgerSheetQuery, - IGeneralLedgerTableData, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { GeneralLedgerService } from './GeneralLedgerService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { GeneralLedgerTable } from './GeneralLedgerTable'; - -@Service() -export class GeneralLedgerTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private GLSheet: GeneralLedgerService; - - /** - * Retrieves the G/L table. - * @param {number} tenantId - * @param {IGeneralLedgerSheetQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: IGeneralLedgerSheetQuery - ): Promise { - const { - data: sheetData, - query: sheetQuery, - meta: sheetMeta, - } = await this.GLSheet.generalLedger(tenantId, query); - - const table = new GeneralLedgerTable(sheetData, sheetQuery, sheetMeta); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - query: sheetQuery, - meta: sheetMeta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/_utils.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/_utils.ts deleted file mode 100644 index 916b895c9..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/_utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Calculate the running balance. - * @param {number} amount - Transaction amount. - * @param {number} lastRunningBalance - Last running balance. - * @param {number} openingBalance - Opening balance. - * @return {number} Running balance. - */ -export function calculateRunningBalance( - amount: number, - lastRunningBalance: number -): number { - return amount + lastRunningBalance; -} diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/constants.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/constants.ts deleted file mode 100644 index 9e79a81da..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/constants.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const HtmlTableCustomCss = ` -table tr:last-child td { - border-bottom: 1px solid #ececec; -} -table tr.row-type--account td, -table tr.row-type--opening-balance td, -table tr.row-type--closing-balance td{ - font-weight: 600; -} -table tr.row-type--closing-balance td { - border-bottom: 1px solid #ececec; -} - -table .column--debit, -table .column--credit, -table .column--amount, -table .column--running_balance, -table .cell--debit, -table .cell--credit, -table .cell--amount, -table .cell--running_balance{ - text-align: right; -} -table tr.row-type--account .cell--date span, -table tr.row-type--opening-balance .cell--account_name span, -table tr.row-type--closing-balance .cell--account_name span{ - white-space: nowrap; -} -`; \ No newline at end of file diff --git a/packages/server/src/services/FinancialStatements/GeneralLedger/utils.ts b/packages/server/src/services/FinancialStatements/GeneralLedger/utils.ts deleted file mode 100644 index 07418ae37..000000000 --- a/packages/server/src/services/FinancialStatements/GeneralLedger/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum ROW_TYPE { - ACCOUNT = 'ACCOUNT', - OPENING_BALANCE = 'OPENING_BALANCE', - TRANSACTION = 'TRANSACTION', - CLOSING_BALANCE = 'CLOSING_BALANCE', -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetails.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetails.ts deleted file mode 100644 index 489acff3e..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetails.ts +++ /dev/null @@ -1,433 +0,0 @@ -import * as R from 'ramda'; -import { defaultTo, sumBy, get } from 'lodash'; -import moment from 'moment'; -import { - IInventoryDetailsQuery, - IItem, - IInventoryTransaction, - TInventoryTransactionDirection, - IInventoryDetailsNumber, - IInventoryDetailsDate, - IInventoryDetailsData, - IInventoryDetailsItem, - IInventoryDetailsClosing, - INumberFormatQuery, - IInventoryDetailsOpening, - IInventoryDetailsItemTransaction, - IFormatNumberSettings, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { transformToMapBy, transformToMapKeyValue } from 'utils'; -import { filterDeep } from 'utils/deepdash'; - -const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' }; - -enum INodeTypes { - ITEM = 'item', - TRANSACTION = 'transaction', - OPENING_ENTRY = 'OPENING_ENTRY', - CLOSING_ENTRY = 'CLOSING_ENTRY', -} - -export class InventoryDetails extends FinancialSheet { - readonly inventoryTransactionsByItemId: Map; - readonly openingBalanceTransactions: Map; - readonly query: IInventoryDetailsQuery; - readonly numberFormat: INumberFormatQuery; - readonly baseCurrency: string; - readonly items: IItem[]; - - /** - * Constructor method. - * @param {IItem[]} items - Items. - * @param {IInventoryTransaction[]} inventoryTransactions - Inventory transactions. - * @param {IInventoryDetailsQuery} query - Report query. - * @param {string} baseCurrency - The base currency. - */ - constructor( - items: IItem[], - openingBalanceTransactions: IInventoryTransaction[], - inventoryTransactions: IInventoryTransaction[], - query: IInventoryDetailsQuery, - baseCurrency: string, - i18n: any - ) { - super(); - - this.inventoryTransactionsByItemId = transformToMapBy( - inventoryTransactions, - 'itemId' - ); - this.openingBalanceTransactions = transformToMapKeyValue( - openingBalanceTransactions, - 'itemId' - ); - this.query = query; - this.numberFormat = this.query.numberFormat; - this.items = items; - this.baseCurrency = baseCurrency; - this.i18n = i18n; - } - - /** - * Retrieve the number meta. - * @param {number} number - * @returns - */ - private getNumberMeta( - number: number, - settings?: IFormatNumberSettings - ): IInventoryDetailsNumber { - return { - formattedNumber: this.formatNumber(number, { - excerptZero: true, - money: false, - ...settings, - }), - number: number, - }; - } - - /** - * Retrieve the total number meta. - * @param {number} number - - * @param {IFormatNumberSettings} settings - - * @retrun {IInventoryDetailsNumber} - */ - private getTotalNumberMeta( - number: number, - settings?: IFormatNumberSettings - ): IInventoryDetailsNumber { - return this.getNumberMeta(number, { excerptZero: false, ...settings }); - } - - /** - * Retrieve the date meta. - * @param {Date|string} date - * @returns {IInventoryDetailsDate} - */ - private getDateMeta(date: Date | string): IInventoryDetailsDate { - return { - formattedDate: moment(date).format('YYYY-MM-DD'), - date: moment(date).toDate(), - }; - } - - /** - * Adjusts the movement amount. - * @param {number} amount - * @param {TInventoryTransactionDirection} direction - * @returns {number} - */ - private adjustAmountMovement = R.curry( - (direction: TInventoryTransactionDirection, amount: number): number => { - return direction === 'OUT' ? amount * -1 : amount; - } - ); - - /** - * Accumulate and mapping running quantity on transactions. - * @param {IInventoryDetailsItemTransaction[]} transactions - * @returns {IInventoryDetailsItemTransaction[]} - */ - private mapAccumTransactionsRunningQuantity( - transactions: IInventoryDetailsItemTransaction[] - ): IInventoryDetailsItemTransaction[] { - const initial = this.getNumberMeta(0); - - const mapAccumAppender = (a, b) => { - const total = a.runningQuantity.number + b.quantityMovement.number; - const totalMeta = this.getNumberMeta(total, { excerptZero: false }); - const accum = { ...b, runningQuantity: totalMeta }; - - return [accum, accum]; - }; - return R.mapAccum( - mapAccumAppender, - { runningQuantity: initial }, - transactions - )[1]; - } - - /** - * Accumulate and mapping running valuation on transactions. - * @param {IInventoryDetailsItemTransaction[]} transactions - * @returns {IInventoryDetailsItemTransaction} - */ - private mapAccumTransactionsRunningValuation( - transactions: IInventoryDetailsItemTransaction[] - ): IInventoryDetailsItemTransaction[] { - const initial = this.getNumberMeta(0); - - const mapAccumAppender = (a, b) => { - const adjustment = b.direction === 'OUT' ? -1 : 1; - const total = a.runningValuation.number + b.cost.number * adjustment; - const totalMeta = this.getNumberMeta(total, { excerptZero: false }); - const accum = { ...b, runningValuation: totalMeta }; - - return [accum, accum]; - }; - return R.mapAccum( - mapAccumAppender, - { runningValuation: initial }, - transactions - )[1]; - } - - /** - * Retrieve the inventory transaction total. - * @param {IInventoryTransaction} transaction - * @returns {number} - */ - private getTransactionTotal = (transaction: IInventoryTransaction) => { - return transaction.quantity - ? transaction.quantity * transaction.rate - : transaction.rate; - }; - - /** - * Mappes the item transaction to inventory item transaction node. - * @param {IItem} item - * @param {IInvetoryTransaction} transaction - * @returns {IInventoryDetailsItemTransaction} - */ - private itemTransactionMapper( - item: IItem, - transaction: IInventoryTransaction - ): IInventoryDetailsItemTransaction { - const total = this.getTransactionTotal(transaction); - const amountMovement = this.adjustAmountMovement(transaction.direction); - - // Quantity movement. - const quantityMovement = amountMovement(transaction.quantity); - const cost = get(transaction, 'costLotAggregated.cost', 0); - - // Profit margin. - const profitMargin = total - cost; - - // Value from computed cost in `OUT` or from total sell price in `IN` transaction. - const value = transaction.direction === 'OUT' ? cost : total; - - // Value movement depends on transaction direction. - const valueMovement = amountMovement(value); - - return { - nodeType: INodeTypes.TRANSACTION, - date: this.getDateMeta(transaction.date), - transactionType: this.i18n.__(transaction.transcationTypeFormatted), - transactionNumber: transaction?.meta?.transactionNumber, - direction: transaction.direction, - - quantityMovement: this.getNumberMeta(quantityMovement), - valueMovement: this.getNumberMeta(valueMovement), - - quantity: this.getNumberMeta(transaction.quantity), - total: this.getNumberMeta(total), - - rate: this.getNumberMeta(transaction.rate), - cost: this.getNumberMeta(cost), - value: this.getNumberMeta(value), - - profitMargin: this.getNumberMeta(profitMargin), - - runningQuantity: this.getNumberMeta(0), - runningValuation: this.getNumberMeta(0), - }; - } - - /** - * Retrieve the inventory transcations by item id. - * @param {number} itemId - * @returns {IInventoryTransaction[]} - */ - private getInventoryTransactionsByItemId( - itemId: number - ): IInventoryTransaction[] { - return defaultTo(this.inventoryTransactionsByItemId.get(itemId + ''), []); - } - - /** - * Retrieve the item transaction node by the given item. - * @param {IItem} item - * @returns {IInventoryDetailsItemTransaction[]} - */ - private getItemTransactions(item: IItem): IInventoryDetailsItemTransaction[] { - const transactions = this.getInventoryTransactionsByItemId(item.id); - - return R.compose( - this.mapAccumTransactionsRunningQuantity.bind(this), - this.mapAccumTransactionsRunningValuation.bind(this), - R.map(R.curry(this.itemTransactionMapper.bind(this))(item)) - )(transactions); - } - - /** - * Mappes the given item transactions. - * @param {IItem} item - - * @returns {( - * IInventoryDetailsItemTransaction - * | IInventoryDetailsOpening - * | IInventoryDetailsClosing - * )[]} - */ - private itemTransactionsMapper( - item: IItem - ): ( - | IInventoryDetailsItemTransaction - | IInventoryDetailsOpening - | IInventoryDetailsClosing - )[] { - const transactions = this.getItemTransactions(item); - const openingValuation = this.getItemOpeingValuation(item); - const closingValuation = this.getItemClosingValuation( - item, - transactions, - openingValuation - ); - const hasTransactions = transactions.length > 0; - const isItemHasOpeningBalance = this.isItemHasOpeningBalance(item.id); - - return R.pipe( - R.concat(transactions), - R.when(R.always(isItemHasOpeningBalance), R.prepend(openingValuation)), - R.when(R.always(hasTransactions), R.append(closingValuation)) - )([]); - } - - /** - * Detarmines the given item has opening balance transaction. - * @param {number} itemId - Item id. - * @return {boolean} - */ - private isItemHasOpeningBalance(itemId: number): boolean { - return !!this.openingBalanceTransactions.get(itemId); - } - - /** - * Retrieve the given item opening valuation. - * @param {IItem} item - - * @returns {IInventoryDetailsOpening} - */ - private getItemOpeingValuation(item: IItem): IInventoryDetailsOpening { - const openingBalance = this.openingBalanceTransactions.get(item.id); - const quantity = defaultTo(get(openingBalance, 'quantity'), 0); - const value = defaultTo(get(openingBalance, 'value'), 0); - - return { - nodeType: INodeTypes.OPENING_ENTRY, - date: this.getDateMeta(this.query.fromDate), - quantity: this.getTotalNumberMeta(quantity), - value: this.getTotalNumberMeta(value), - }; - } - - /** - * Retrieve the given item closing valuation. - * @param {IItem} item - - * @returns {IInventoryDetailsOpening} - */ - private getItemClosingValuation( - item: IItem, - transactions: IInventoryDetailsItemTransaction[], - openingValuation: IInventoryDetailsOpening - ): IInventoryDetailsOpening { - const value = sumBy(transactions, 'valueMovement.number'); - const quantity = sumBy(transactions, 'quantityMovement.number'); - const profitMargin = sumBy(transactions, 'profitMargin.number'); - - const closingQuantity = quantity + openingValuation.quantity.number; - const closingValue = value + openingValuation.value.number; - - return { - nodeType: INodeTypes.CLOSING_ENTRY, - date: this.getDateMeta(this.query.toDate), - quantity: this.getTotalNumberMeta(closingQuantity), - value: this.getTotalNumberMeta(closingValue), - profitMargin: this.getTotalNumberMeta(profitMargin), - }; - } - - /** - * Retrieve the item node of the report. - * @param {IItem} item - * @returns {IInventoryDetailsItem} - */ - private itemsNodeMapper(item: IItem): IInventoryDetailsItem { - return { - id: item.id, - name: item.name, - code: item.code, - nodeType: INodeTypes.ITEM, - children: this.itemTransactionsMapper(item), - }; - } - - /** - * Detarmines the given node equals the given type. - * @param {string} nodeType - * @param {IItem} node - * @returns {boolean} - */ - private isNodeTypeEquals( - nodeType: string, - node: IInventoryDetailsItem - ): boolean { - return nodeType === node.nodeType; - } - - /** - * Detarmines whether the given item node has transactions. - * @param {IInventoryDetailsItem} item - * @returns {boolean} - */ - private isItemNodeHasTransactions(item: IInventoryDetailsItem) { - return !!this.inventoryTransactionsByItemId.get(item.id); - } - - /** - * Detarmines the filter - * @param {IInventoryDetailsItem} item - * @return {boolean} - */ - private isFilterNode(item: IInventoryDetailsItem): boolean { - return R.ifElse( - R.curry(this.isNodeTypeEquals)(INodeTypes.ITEM), - this.isItemNodeHasTransactions.bind(this), - R.always(true) - )(item); - } - - /** - * Filters items nodes. - * @param {IInventoryDetailsItem[]} items - - * @returns {IInventoryDetailsItem[]} - */ - private filterItemsNodes(items: IInventoryDetailsItem[]) { - const filtered = filterDeep( - items, - this.isFilterNode.bind(this), - MAP_CONFIG - ); - return defaultTo(filtered, []); - } - - /** - * Retrieve the items nodes of the report. - * @param {IItem} items - * @returns {IInventoryDetailsItem[]} - */ - private itemsNodes(items: IItem[]): IInventoryDetailsItem[] { - return R.compose( - this.filterItemsNodes.bind(this), - R.map(this.itemsNodeMapper.bind(this)) - )(items); - } - - /** - * Retrieve the inventory item details report data. - * @returns {IInventoryDetailsData} - */ - public reportData(): IInventoryDetailsData { - return this.itemsNodes(this.items); - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsApplication.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsApplication.ts deleted file mode 100644 index 50cbd2a2f..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsApplication.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - IInventoryDetailsQuery, - IInvetoryItemDetailsTable, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { InventoryDetailsExportInjectable } from './InventoryDetailsExportInjectable'; -import { InventoryDetailsTableInjectable } from './InventoryDetailsTableInjectable'; -import { InventoryDetailsService } from './InventoryDetailsService'; -import { InventoryDetailsTablePdf } from './InventoryDetailsTablePdf'; - -@Service() -export class InventortyDetailsApplication { - @Inject() - private inventoryDetailsExport: InventoryDetailsExportInjectable; - - @Inject() - private inventoryDetailsTable: InventoryDetailsTableInjectable; - - @Inject() - private inventoryDetails: InventoryDetailsService; - - @Inject() - private inventoryDetailsPdf: InventoryDetailsTablePdf; - - /** - * Retrieves the inventory details report in sheet format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public sheet(tenantId: number, query: IInventoryDetailsQuery) { - return this.inventoryDetails.inventoryDetails(tenantId, query); - } - - /** - * Retrieve the inventory details report in table format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns - */ - public table( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - return this.inventoryDetailsTable.table(tenantId, query); - } - - /** - * Retrieves the inventory details report in XLSX format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public xlsx( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - return this.inventoryDetailsExport.xlsx(tenantId, query); - } - - /** - * Retrieves the inventory details report in CSV format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public csv(tenantId: number, query: IInventoryDetailsQuery): Promise { - return this.inventoryDetailsExport.csv(tenantId, query); - } - - /** - * Retrieves the inventory details report in PDF format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IInventoryDetailsQuery) { - return this.inventoryDetailsPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsExportInjectable.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsExportInjectable.ts deleted file mode 100644 index bede24eb4..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsExportInjectable.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IInventoryDetailsQuery } from '@/interfaces'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { InventoryDetailsTableInjectable } from './InventoryDetailsTableInjectable'; - -@Service() -export class InventoryDetailsExportInjectable { - @Inject() - private inventoryDetailsTable: InventoryDetailsTableInjectable; - - /** - * Retrieves the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IInventoryDetailsQuery) { - const table = await this.inventoryDetailsTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - const table = await this.inventoryDetailsTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsMeta.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsMeta.ts deleted file mode 100644 index 578954833..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsMeta.ts +++ /dev/null @@ -1,35 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { IInventoryDetailsQuery, IInventoryItemDetailMeta } from '@/interfaces'; - -@Service() -export class InventoryDetailsMetaInjectable { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the inventoy details meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedToDay = moment(query.toDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDay}`; - - const sheetName = 'Inventory Item Details'; - - return { - ...commonMeta, - sheetName, - formattedFromDate, - formattedToDay, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsRepository.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsRepository.ts deleted file mode 100644 index 05a4f26a8..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsRepository.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Inject } from 'typedi'; -import { raw } from 'objection'; -import { isEmpty } from 'lodash'; -import moment from 'moment'; -import { - IItem, - IInventoryDetailsQuery, - IInventoryTransaction, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -export default class InventoryDetailsRepository { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve inventory items. - * @param {number} tenantId - - * @returns {Promise} - */ - public getInventoryItems( - tenantId: number, - itemsIds?: number[] - ): Promise { - const { Item } = this.tenancy.models(tenantId); - - return Item.query().onBuild((q) => { - q.where('type', 'inventory'); - - if (!isEmpty(itemsIds)) { - q.whereIn('id', itemsIds); - } - }); - } - - /** - * Retrieve the items opening balance transactions. - * @param {number} tenantId - - * @param {IInventoryDetailsQuery} - * @return {Promise} - */ - public async openingBalanceTransactions( - tenantId: number, - filter: IInventoryDetailsQuery - ): Promise { - const { InventoryTransaction } = this.tenancy.models(tenantId); - - const openingBalanceDate = moment(filter.fromDate) - .subtract(1, 'days') - .toDate(); - - // Opening inventory transactions. - const openingTransactions = InventoryTransaction.query() - .select('*') - .select(raw("IF(`DIRECTION` = 'IN', `QUANTITY`, 0) as 'QUANTITY_IN'")) - .select(raw("IF(`DIRECTION` = 'OUT', `QUANTITY`, 0) as 'QUANTITY_OUT'")) - .select( - raw( - "IF(`DIRECTION` = 'IN', IF(`QUANTITY` IS NULL, `RATE`, `QUANTITY` * `RATE`), 0) as 'VALUE_IN'" - ) - ) - .select( - raw( - "IF(`DIRECTION` = 'OUT', IF(`QUANTITY` IS NULL, `RATE`, `QUANTITY` * `RATE`), 0) as 'VALUE_OUT'" - ) - ) - .modify('filterDateRange', null, openingBalanceDate) - .orderBy('date', 'ASC') - .as('inventory_transactions'); - - if (!isEmpty(filter.warehousesIds)) { - openingTransactions.modify('filterByWarehouses', filter.warehousesIds); - } - if (!isEmpty(filter.branchesIds)) { - openingTransactions.modify('filterByBranches', filter.branchesIds); - } - - const openingBalanceTransactions = await InventoryTransaction.query() - .from(openingTransactions) - .select('itemId') - .select(raw('SUM(`QUANTITY_IN` - `QUANTITY_OUT`) AS `QUANTITY`')) - .select(raw('SUM(`VALUE_IN` - `VALUE_OUT`) AS `VALUE`')) - .groupBy('itemId') - .sum('rate as rate') - .sum('quantityIn as quantityIn') - .sum('quantityOut as quantityOut') - .sum('valueIn as valueIn') - .sum('valueOut as valueOut') - .withGraphFetched('itemCostAggregated'); - - return openingBalanceTransactions; - } - - /** - * Retrieve the items inventory tranasactions. - * @param {number} tenantId - - * @param {IInventoryDetailsQuery} - * @return {Promise} - */ - public async itemInventoryTransactions( - tenantId: number, - filter: IInventoryDetailsQuery - ): Promise { - const { InventoryTransaction } = this.tenancy.models(tenantId); - - const inventoryTransactions = InventoryTransaction.query() - .modify('filterDateRange', filter.fromDate, filter.toDate) - .orderBy('date', 'ASC') - .withGraphFetched('meta') - .withGraphFetched('costLotAggregated'); - - if (!isEmpty(filter.branchesIds)) { - inventoryTransactions.modify('filterByBranches', filter.branchesIds); - } - if (!isEmpty(filter.warehousesIds)) { - inventoryTransactions.modify('filterByWarehouses', filter.warehousesIds); - } - return inventoryTransactions; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsService.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsService.ts deleted file mode 100644 index e9b6614d6..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsService.ts +++ /dev/null @@ -1,94 +0,0 @@ -import moment from 'moment'; -import { Service, Inject } from 'typedi'; -import { IInventoryDetailsQuery, IInvetoryItemDetailDOO } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { InventoryDetails } from './InventoryDetails'; -import FinancialSheet from '../FinancialSheet'; -import InventoryDetailsRepository from './InventoryDetailsRepository'; -import { Tenant } from '@/system/models'; -import { InventoryDetailsMetaInjectable } from './InventoryDetailsMeta'; - -@Service() -export class InventoryDetailsService extends FinancialSheet { - @Inject() - private tenancy: TenancyService; - - @Inject() - private reportRepo: InventoryDetailsRepository; - - @Inject() - private inventoryDetailsMeta: InventoryDetailsMetaInjectable; - - /** - * Defaults balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - private get defaultQuery(): IInventoryDetailsQuery { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - itemsIds: [], - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - noneTransactions: false, - branchesIds: [], - warehousesIds: [], - }; - } - - /** - * Retrieve the inventory details report data. - * @param {number} tenantId - - * @param {IInventoryDetailsQuery} query - - * @return {Promise} - */ - public async inventoryDetails( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - // Retrieves the items. - const items = await this.reportRepo.getInventoryItems( - tenantId, - filter.itemsIds - ); - // Opening balance transactions. - const openingBalanceTransactions = - await this.reportRepo.openingBalanceTransactions(tenantId, filter); - - // Retrieves the inventory transaction. - const inventoryTransactions = - await this.reportRepo.itemInventoryTransactions(tenantId, filter); - - // Inventory details report mapper. - const inventoryDetailsInstance = new InventoryDetails( - items, - openingBalanceTransactions, - inventoryTransactions, - filter, - tenant.metadata.baseCurrency, - i18n - ); - const meta = await this.inventoryDetailsMeta.meta(tenantId, query); - - return { - data: inventoryDetailsInstance.reportData(), - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTable.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTable.ts deleted file mode 100644 index 1fa6d602d..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTable.ts +++ /dev/null @@ -1,197 +0,0 @@ -import * as R from 'ramda'; -import { - IInventoryDetailsItem, - IInventoryDetailsItemTransaction, - IInventoryDetailsClosing, - ITableColumn, - ITableRow, - IInventoryDetailsNode, - IInventoryDetailsOpening, -} from '@/interfaces'; -import { mapValuesDeep } from 'utils/deepdash'; -import { tableRowMapper } from 'utils'; - -enum IROW_TYPE { - ITEM = 'ITEM', - TRANSACTION = 'TRANSACTION', - CLOSING_ENTRY = 'CLOSING_ENTRY', - OPENING_ENTRY = 'OPENING_ENTRY', -} - -const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' }; - -export class InventoryDetailsTable { - i18n: any; - report: any; - - /** - * Constructor method. - * @param {ICashFlowStatement} report - Report statement. - */ - constructor(reportStatement, i18n) { - this.report = reportStatement; - this.i18n = i18n; - } - - /** - * Mappes the item node to table rows. - * @param {IInventoryDetailsItem} item - * @returns {ITableRow} - */ - private itemNodeMapper = (item: IInventoryDetailsItem) => { - const columns = [{ key: 'item_name', accessor: 'name' }]; - - return tableRowMapper(item, columns, { - rowTypes: [IROW_TYPE.ITEM], - }); - }; - - /** - * Mappes the item inventory transaction to table row. - * @param {IInventoryDetailsItemTransaction} transaction - * @returns {ITableRow} - */ - private itemTransactionNodeMapper = ( - transaction: IInventoryDetailsItemTransaction - ) => { - const columns = [ - { key: 'date', accessor: 'date.formattedDate' }, - { key: 'transaction_type', accessor: 'transactionType' }, - { key: 'transaction_id', accessor: 'transactionNumber' }, - { - key: 'quantity_movement', - accessor: 'quantityMovement.formattedNumber', - }, - { key: 'rate', accessor: 'rate.formattedNumber' }, - { key: 'total', accessor: 'total.formattedNumber' }, - { key: 'value', accessor: 'valueMovement.formattedNumber' }, - { key: 'profit_margin', accessor: 'profitMargin.formattedNumber' }, - { key: 'running_quantity', accessor: 'runningQuantity.formattedNumber' }, - { - key: 'running_valuation', - accessor: 'runningValuation.formattedNumber', - }, - ]; - return tableRowMapper(transaction, columns, { - rowTypes: [IROW_TYPE.TRANSACTION], - }); - }; - - /** - * Opening balance transaction mapper to table row. - * @param {IInventoryDetailsOpening} transaction - * @returns {ITableRow} - */ - private openingNodeMapper = ( - transaction: IInventoryDetailsOpening - ): ITableRow => { - const columns = [ - { key: 'date', accessor: 'date.formattedDate' }, - { key: 'closing', value: this.i18n.__('Opening balance') }, - { key: 'empty' }, - { key: 'quantity', accessor: 'quantity.formattedNumber' }, - { key: 'empty' }, - { key: 'empty' }, - { key: 'value', accessor: 'value.formattedNumber' }, - ]; - return tableRowMapper(transaction, columns, { - rowTypes: [IROW_TYPE.OPENING_ENTRY], - }); - }; - - /** - * Closing balance transaction mapper to table raw. - * @param {IInventoryDetailsClosing} transaction - * @returns {ITableRow} - */ - private closingNodeMapper = ( - transaction: IInventoryDetailsClosing - ): ITableRow => { - const columns = [ - { key: 'date', accessor: 'date.formattedDate' }, - { key: 'closing', value: this.i18n.__('Closing balance') }, - { key: 'empty' }, - { key: 'quantity', accessor: 'quantity.formattedNumber' }, - { key: 'empty' }, - { key: 'empty' }, - { key: 'value', accessor: 'value.formattedNumber' }, - { key: 'profitMargin', accessor: 'profitMargin.formattedNumber' }, - ]; - - return tableRowMapper(transaction, columns, { - rowTypes: [IROW_TYPE.CLOSING_ENTRY], - }); - }; - - /** - * Detarmines the ginve inventory details node type. - * @param {string} type - * @param {IInventoryDetailsNode} node - * @returns {boolean} - */ - private isNodeTypeEquals = ( - type: string, - node: IInventoryDetailsNode - ): boolean => { - return node.nodeType === type; - }; - - /** - * Mappes the given item or transactions node to table rows. - * @param {IInventoryDetailsNode} node - - * @return {ITableRow} - */ - private itemMapper = (node: IInventoryDetailsNode): ITableRow => { - return R.compose( - R.when( - R.curry(this.isNodeTypeEquals)('OPENING_ENTRY'), - this.openingNodeMapper - ), - R.when( - R.curry(this.isNodeTypeEquals)('CLOSING_ENTRY'), - this.closingNodeMapper - ), - R.when(R.curry(this.isNodeTypeEquals)('item'), this.itemNodeMapper), - R.when( - R.curry(this.isNodeTypeEquals)('transaction'), - this.itemTransactionNodeMapper - ) - )(node); - }; - - /** - * Mappes the items nodes to table rows. - * @param {IInventoryDetailsItem[]} items - * @returns {ITableRow[]} - */ - private itemsMapper = (items: IInventoryDetailsItem[]): ITableRow[] => { - return mapValuesDeep(items, this.itemMapper, MAP_CONFIG); - }; - - /** - * Retrieve the table rows of the inventory item details. - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return this.itemsMapper(this.report.data); - }; - - /** - * Retrieve the table columns of inventory details report. - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return [ - { key: 'date', label: this.i18n.__('Date') }, - { key: 'transaction_type', label: this.i18n.__('Transaction type') }, - { key: 'transaction_id', label: this.i18n.__('Transaction #') }, - { key: 'quantity', label: this.i18n.__('Quantity') }, - { key: 'rate', label: this.i18n.__('Rate') }, - { key: 'total', label: this.i18n.__('Total') }, - { key: 'value', label: this.i18n.__('Value') }, - { key: 'profit_margin', label: this.i18n.__('Profit Margin') }, - { key: 'running_quantity', label: this.i18n.__('Running quantity') }, - { key: 'running_value', label: this.i18n.__('Running Value') }, - ]; - }; -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTableInjectable.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTableInjectable.ts deleted file mode 100644 index 7cf803b46..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTableInjectable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { InventoryDetailsTable } from './InventoryDetailsTable'; -import { - IInventoryDetailsQuery, - IInvetoryItemDetailsTable, -} from '@/interfaces'; -import { InventoryDetailsService } from './InventoryDetailsService'; - -@Service() -export class InventoryDetailsTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private inventoryDetails: InventoryDetailsService; - - /** - * Retrieves the inventory item details in table format. - * @param {number} tenantId - * @param {IInventoryDetailsQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const inventoryDetails = await this.inventoryDetails.inventoryDetails( - tenantId, - query - ); - const table = new InventoryDetailsTable(inventoryDetails, i18n); - - return { - table: { - rows: table.tableRows(), - columns: table.tableColumns(), - }, - query: inventoryDetails.query, - meta: inventoryDetails.meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTablePdf.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTablePdf.ts deleted file mode 100644 index b14b11c80..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/InventoryDetailsTablePdf.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { InventoryDetailsTableInjectable } from './InventoryDetailsTableInjectable'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { IInventoryDetailsQuery } from '@/interfaces'; -import { HtmlTableCustomCss } from './constant'; - -@Service() -export class InventoryDetailsTablePdf { - @Inject() - private inventoryDetailsTable: InventoryDetailsTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given inventory details sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IInventoryDetailsQuery - ): Promise { - const table = await this.inventoryDetailsTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryDetails/constant.ts b/packages/server/src/services/FinancialStatements/InventoryDetails/constant.ts deleted file mode 100644 index eeb199236..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryDetails/constant.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const HtmlTableCustomCss = ` -table tr.row-type--item td, -table tr.row-type--opening-entry td, -table tr.row-type--closing-entry td{ - font-weight: 500; -} -`; diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts deleted file mode 100644 index fa27707e1..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts +++ /dev/null @@ -1,264 +0,0 @@ -import { sumBy, get, isEmpty } from 'lodash'; -import * as R from 'ramda'; -import FinancialSheet from '../FinancialSheet'; -import { - IItem, - IInventoryValuationReportQuery, - IInventoryValuationItem, - InventoryCostLotTracker, - IInventoryValuationStatement, - IInventoryValuationTotal, -} from '@/interfaces'; -import { allPassedConditionsPass, transformToMap } from 'utils'; - -export class InventoryValuationSheet extends FinancialSheet { - readonly query: IInventoryValuationReportQuery; - readonly items: IItem[]; - readonly INInventoryCostLots: Map; - readonly OUTInventoryCostLots: Map; - readonly baseCurrency: string; - - /** - * Constructor method. - * @param {IInventoryValuationReportQuery} query - * @param items - * @param INInventoryCostLots - * @param OUTInventoryCostLots - * @param baseCurrency - */ - constructor( - query: IInventoryValuationReportQuery, - items: IItem[], - INInventoryCostLots: Map, - OUTInventoryCostLots: Map, - baseCurrency: string - ) { - super(); - - this.query = query; - this.items = items; - this.INInventoryCostLots = transformToMap(INInventoryCostLots, 'itemId'); - this.OUTInventoryCostLots = transformToMap(OUTInventoryCostLots, 'itemId'); - this.baseCurrency = baseCurrency; - this.numberFormat = this.query.numberFormat; - } - - /** - * Retrieve the item cost and quantity from the given transaction map. - * @param {Map} transactionsMap - * @param {number} itemId - * @returns - */ - private getItemTransaction( - transactionsMap: Map, - itemId: number - ): { cost: number; quantity: number } { - const meta = transactionsMap.get(itemId); - - const cost = get(meta, 'cost', 0); - const quantity = get(meta, 'quantity', 0); - - return { cost, quantity }; - } - - /** - * Retrieve the cost and quantity of the givne item from `IN` transactions. - * @param {number} itemId - - */ - private getItemINTransaction(itemId: number): { - cost: number; - quantity: number; - } { - return this.getItemTransaction(this.INInventoryCostLots, itemId); - } - - /** - * Retrieve the cost and quantity of the given item from `OUT` transactions. - * @param {number} itemId - - */ - private getItemOUTTransaction(itemId: number): { - cost: number; - quantity: number; - } { - return this.getItemTransaction(this.OUTInventoryCostLots, itemId); - } - - /** - * Retrieve the item closing valuation. - * @param {number} itemId - Item id. - */ - private getItemValuation(itemId: number): number { - const { cost: INValuation } = this.getItemINTransaction(itemId); - const { cost: OUTValuation } = this.getItemOUTTransaction(itemId); - - return Math.max(INValuation - OUTValuation, 0); - } - - /** - * Retrieve the item closing quantity. - * @param {number} itemId - Item id. - */ - private getItemQuantity(itemId: number): number { - const { quantity: INQuantity } = this.getItemINTransaction(itemId); - const { quantity: OUTQuantity } = this.getItemOUTTransaction(itemId); - - return INQuantity - OUTQuantity; - } - - /** - * Calculates the item weighted average cost from the given valuation and quantity. - * @param {number} valuation - * @param {number} quantity - * @returns {number} - */ - private calcAverage(valuation: number, quantity: number): number { - return quantity ? valuation / quantity : 0; - } - - /** - * Mapping the item model object to inventory valuation item - * @param {IItem} item - * @returns {IInventoryValuationItem} - */ - private itemMapper(item: IItem): IInventoryValuationItem { - const valuation = this.getItemValuation(item.id); - const quantity = this.getItemQuantity(item.id); - const average = this.calcAverage(valuation, quantity); - - return { - id: item.id, - name: item.name, - code: item.code, - valuation, - quantity, - average, - valuationFormatted: this.formatNumber(valuation), - quantityFormatted: this.formatNumber(quantity, { money: false }), - averageFormatted: this.formatNumber(average, { money: false }), - currencyCode: this.baseCurrency, - }; - } - - /** - * Filter none transactions items. - * @param {IInventoryValuationItem} valuationItem - - * @return {boolean} - */ - private filterNoneTransactions = ( - valuationItem: IInventoryValuationItem - ): boolean => { - const transactionIN = this.INInventoryCostLots.get(valuationItem.id); - const transactionOUT = this.OUTInventoryCostLots.get(valuationItem.id); - - return transactionOUT || transactionIN; - }; - - /** - * Filter active only items. - * @param {IInventoryValuationItem} valuationItem - - * @returns {boolean} - */ - private filterActiveOnly = ( - valuationItem: IInventoryValuationItem - ): boolean => { - return ( - valuationItem.average !== 0 || - valuationItem.quantity !== 0 || - valuationItem.valuation !== 0 - ); - }; - - /** - * Filter none-zero total valuation items. - * @param {IInventoryValuationItem} valuationItem - * @returns {boolean} - */ - private filterNoneZero = (valuationItem: IInventoryValuationItem) => { - return valuationItem.valuation !== 0; - }; - - /** - * Filters the inventory valuation items based on query. - * @param {IInventoryValuationItem} valuationItem - * @returns {boolean} - */ - private itemFilter = (valuationItem: IInventoryValuationItem): boolean => { - const { noneTransactions, noneZero, onlyActive } = this.query; - - // Conditions pair filter detarminer. - const condsPairFilters = [ - [noneTransactions, this.filterNoneTransactions], - [noneZero, this.filterNoneZero], - [onlyActive, this.filterActiveOnly], - ]; - return allPassedConditionsPass(condsPairFilters)(valuationItem); - }; - - /** - * Mappes the items to inventory valuation items nodes. - * @param {IItem[]} items - * @returns {IInventoryValuationItem[]} - */ - private itemsMapper = (items: IItem[]): IInventoryValuationItem[] => { - return this.items.map(this.itemMapper.bind(this)); - }; - - /** - * Filters the inventory valuation items nodes. - * @param {IInventoryValuationItem[]} nodes - - * @returns {IInventoryValuationItem[]} - */ - private itemsFilter = ( - nodes: IInventoryValuationItem[] - ): IInventoryValuationItem[] => { - return nodes.filter(this.itemFilter); - }; - - /** - * Detarmines whether the items post filter is active. - */ - private isItemsPostFilter = (): boolean => { - return isEmpty(this.query.itemsIds); - }; - - /** - * Retrieve the inventory valuation items. - * @returns {IInventoryValuationItem[]} - */ - private itemsSection(): IInventoryValuationItem[] { - return R.compose( - R.when(this.isItemsPostFilter, this.itemsFilter), - this.itemsMapper - )(this.items); - } - - /** - * Retrieve the inventory valuation total. - * @param {IInventoryValuationItem[]} items - * @returns {IInventoryValuationTotal} - */ - private totalSection( - items: IInventoryValuationItem[] - ): IInventoryValuationTotal { - const valuation = sumBy(items, (item) => item.valuation); - const quantity = sumBy(items, (item) => item.quantity); - - return { - valuation, - quantity, - valuationFormatted: this.formatTotalNumber(valuation), - quantityFormatted: this.formatTotalNumber(quantity, { money: false }), - }; - } - - /** - * Retrieve the inventory valuation report data. - * @returns {IInventoryValuationStatement} - */ - public reportData(): IInventoryValuationStatement { - const items = this.itemsSection(); - const total = this.totalSection(items); - - return { items, total }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetApplication.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetApplication.ts deleted file mode 100644 index 7c4a65967..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetApplication.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { - IInventoryValuationReportQuery, - IInventoryValuationSheet, - IInventoryValuationTable, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { InventoryValuationSheetService } from './InventoryValuationSheetService'; -import { InventoryValuationSheetTableInjectable } from './InventoryValuationSheetTableInjectable'; -import { InventoryValuationSheetExportable } from './InventoryValuationSheetExportable'; -import { InventoryValuationSheetPdf } from './InventoryValuationSheetPdf'; - -@Service() -export class InventoryValuationSheetApplication { - @Inject() - private inventoryValuationSheet: InventoryValuationSheetService; - - @Inject() - private inventoryValuationTable: InventoryValuationSheetTableInjectable; - - @Inject() - private inventoryValuationExport: InventoryValuationSheetExportable; - - @Inject() - private inventoryValuationPdf: InventoryValuationSheetPdf; - - /** - * Retrieves the inventory valuation json format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns - */ - public sheet( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - return this.inventoryValuationSheet.inventoryValuationSheet( - tenantId, - query - ); - } - - /** - * Retrieves the inventory valuation json table format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns {Promise} - */ - public table( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - return this.inventoryValuationTable.table(tenantId, query); - } - - /** - * Retrieves the inventory valuation xlsx format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns - */ - public xlsx( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - return this.inventoryValuationExport.xlsx(tenantId, query); - } - - /** - * Retrieves the inventory valuation csv format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns - */ - public csv( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - return this.inventoryValuationExport.csv(tenantId, query); - } - - /** - * Retrieves the inventory valuation pdf format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns {Promise} - */ - public pdf( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - return this.inventoryValuationPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetExportable.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetExportable.ts deleted file mode 100644 index 2403ed16b..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetExportable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IInventoryValuationReportQuery } from '@/interfaces'; -import { InventoryValuationSheetTableInjectable } from './InventoryValuationSheetTableInjectable'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; - -@Service() -export class InventoryValuationSheetExportable { - @Inject() - private inventoryValuationTable: InventoryValuationSheetTableInjectable; - - /** - * Retrieves the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - const table = await this.inventoryValuationTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {IInventoryValuationReportQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - const table = await this.inventoryValuationTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetMeta.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetMeta.ts deleted file mode 100644 index 822253342..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetMeta.ts +++ /dev/null @@ -1,33 +0,0 @@ - - -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { IBalanceSheetMeta, IBalanceSheetQuery, IInventoryValuationReportQuery } from '@/interfaces'; -import moment from 'moment'; - -@Service() -export class InventoryValuationMetaInjectable { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the balance sheet meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedAsDate = moment(query.asDate).format('YYYY/MM/DD'); - const formattedDateRange = `As ${formattedAsDate}`; - - return { - ...commonMeta, - sheetName: 'Inventory Valuation Sheet', - formattedAsDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetPdf.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetPdf.ts deleted file mode 100644 index 449cec9cc..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetPdf.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from "typedi"; -import { InventoryValuationSheetTableInjectable } from "./InventoryValuationSheetTableInjectable"; -import { TableSheetPdf } from "../TableSheetPdf"; -import { IInventoryValuationReportQuery } from "@/interfaces"; -import { HtmlTableCustomCss } from "./_constants"; - - -@Service() -export class InventoryValuationSheetPdf { - @Inject() - private inventoryValuationTable: InventoryValuationSheetTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given balance sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - const table = await this.inventoryValuationTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} \ No newline at end of file diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts deleted file mode 100644 index 89a38f49e..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { isEmpty } from 'lodash'; -import { - IInventoryValuationReportQuery, - IInventoryValuationSheet, - IInventoryValuationSheetMeta, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { InventoryValuationSheet } from './InventoryValuationSheet'; -import InventoryService from '@/services/Inventory/Inventory'; -import { Tenant } from '@/system/models'; -import { InventoryValuationMetaInjectable } from './InventoryValuationSheetMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class InventoryValuationSheetService { - @Inject() - tenancy: TenancyService; - - @Inject('logger') - logger: any; - - @Inject() - inventoryService: InventoryService; - - @Inject() - private inventoryValuationMeta: InventoryValuationMetaInjectable; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - get defaultQuery(): IInventoryValuationReportQuery { - return { - asDate: moment().format('YYYY-MM-DD'), - itemsIds: [], - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'always', - negativeFormat: 'mines', - }, - noneTransactions: true, - noneZero: false, - onlyActive: false, - - warehousesIds: [], - branchesIds: [], - }; - } - - /** - * Inventory valuation sheet. - * @param {number} tenantId - Tenant id. - * @param {IInventoryValuationReportQuery} query - Valuation query. - */ - public async inventoryValuationSheet( - tenantId: number, - query: IInventoryValuationReportQuery - ): Promise { - const { Item, InventoryCostLotTracker } = this.tenancy.models(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const inventoryItems = await Item.query().onBuild((q) => { - q.where('type', 'inventory'); - - if (filter.itemsIds.length > 0) { - q.whereIn('id', filter.itemsIds); - } - }); - const inventoryItemsIds = inventoryItems.map((item) => item.id); - - const commonQuery = (builder) => { - builder.whereIn('item_id', inventoryItemsIds); - builder.sum('rate as rate'); - builder.sum('quantity as quantity'); - builder.sum('cost as cost'); - builder.select('itemId'); - builder.groupBy('itemId'); - - if (!isEmpty(query.branchesIds)) { - builder.modify('filterByBranches', query.branchesIds); - } - if (!isEmpty(query.warehousesIds)) { - builder.modify('filterByWarehouses', query.warehousesIds); - } - }; - // Retrieve the inventory cost `IN` transactions. - const INTransactions = await InventoryCostLotTracker.query() - .onBuild(commonQuery) - .where('direction', 'IN'); - - // Retrieve the inventory cost `OUT` transactions. - const OUTTransactions = await InventoryCostLotTracker.query() - .onBuild(commonQuery) - .where('direction', 'OUT'); - - const inventoryValuationInstance = new InventoryValuationSheet( - filter, - inventoryItems, - INTransactions, - OUTTransactions, - tenant.metadata.baseCurrency - ); - // Retrieve the inventory valuation report data. - const inventoryValuationData = inventoryValuationInstance.reportData(); - - // Retrieves the inventorty valuation meta. - const meta = await this.inventoryValuationMeta.meta(tenantId, filter); - - // Triggers `onInventoryValuationViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onInventoryValuationViewed, - { - tenantId, - query, - } - ); - - return { - data: inventoryValuationData, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTable.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTable.ts deleted file mode 100644 index 7e792f6f9..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTable.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as R from 'ramda'; -import { - IInventoryValuationItem, - IInventoryValuationSheetData, - IInventoryValuationTotal, - ITableColumn, - ITableColumnAccessor, - ITableRow, -} from '@/interfaces'; -import { tableRowMapper } from '@/utils'; -import FinancialSheet from '../FinancialSheet'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { FinancialTable } from '../FinancialTable'; -import { ROW_TYPE } from './_constants'; - -export class InventoryValuationSheetTable extends R.compose( - FinancialTable, - FinancialSheetStructure -)(FinancialSheet) { - private readonly data: IInventoryValuationSheetData; - - /** - * Constructor method. - * @param {IInventoryValuationSheetData} data - */ - constructor(data: IInventoryValuationSheetData) { - super(); - this.data = data; - } - - /** - * Retrieves the common columns accessors. - * @returns {ITableColumnAccessor} - */ - private commonColumnsAccessors(): ITableColumnAccessor[] { - return [ - { key: 'item_name', accessor: 'name' }, - { key: 'quantity', accessor: 'quantityFormatted' }, - { key: 'valuation', accessor: 'valuationFormatted' }, - { key: 'average', accessor: 'averageFormatted' }, - ]; - } - - /** - * Maps the given total node to table row. - * @param {IInventoryValuationTotal} total - * @returns {ITableRow} - */ - private totalRowMapper = (total: IInventoryValuationTotal): ITableRow => { - const accessors = this.commonColumnsAccessors(); - const meta = { - rowTypes: [ROW_TYPE.TOTAL], - }; - return tableRowMapper(total, accessors, meta); - }; - - /** - * Maps the given item node to table row. - * @param {IInventoryValuationItem} item - * @returns {ITableRow} - */ - private itemRowMapper = (item: IInventoryValuationItem): ITableRow => { - const accessors = this.commonColumnsAccessors(); - const meta = { - rowTypes: [ROW_TYPE.ITEM], - }; - return tableRowMapper(item, accessors, meta); - }; - - /** - * Maps the given items nodes to table rowes. - * @param {IInventoryValuationItem[]} items - * @returns {ITableRow[]} - */ - private itemsRowsMapper = (items: IInventoryValuationItem[]): ITableRow[] => { - return R.map(this.itemRowMapper)(items); - }; - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableRows(): ITableRow[] { - const itemsRows = this.itemsRowsMapper(this.data.items); - const totalRow = this.totalRowMapper(this.data.total); - - return R.compose( - R.when(R.always(R.not(R.isEmpty(itemsRows))), R.append(totalRow)) - )([...itemsRows]) as ITableRow[]; - } - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns(): ITableColumn[] { - const columns = [ - { key: 'item_name', label: 'Item Name' }, - { key: 'quantity', label: 'Quantity' }, - { key: 'valuation', label: 'Valuation' }, - { key: 'average', label: 'Average' }, - ]; - return R.compose(this.tableColumnsCellIndexing)(columns); - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts deleted file mode 100644 index cad8126b4..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetTableInjectable.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { InventoryValuationSheetService } from './InventoryValuationSheetService'; -import { - IInventoryValuationReportQuery, - IInventoryValuationTable, -} from '@/interfaces'; -import { InventoryValuationSheetTable } from './InventoryValuationSheetTable'; - -@Service() -export class InventoryValuationSheetTableInjectable { - @Inject() - private sheet: InventoryValuationSheetService; - - /** - * Retrieves the inventory valuation json table format. - * @param {number} tenantId - - * @param {IInventoryValuationReportQuery} filter - - * @returns {Promise} - */ - public async table( - tenantId: number, - filter: IInventoryValuationReportQuery - ): Promise { - const { data, query, meta } = await this.sheet.inventoryValuationSheet( - tenantId, - filter - ); - const table = new InventoryValuationSheetTable(data); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - query, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/_constants.ts b/packages/server/src/services/FinancialStatements/InventoryValuationSheet/_constants.ts deleted file mode 100644 index f41136b6f..000000000 --- a/packages/server/src/services/FinancialStatements/InventoryValuationSheet/_constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -export enum ROW_TYPE { - ITEM = 'ITEM', - TOTAL = 'TOTAL', -} - -export const HtmlTableCustomCss = ` -table tr.row-type--total td { - border-top: 1px solid #bbb; - font-weight: 600; - border-bottom: 3px double #000; -} -`; diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts deleted file mode 100644 index 89725db3b..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { sumBy, chain, get, head } from 'lodash'; -import { - IJournalEntry, - IJournalPoster, - IJournalReportEntriesGroup, - IJournalReportQuery, - IJournalReport, - IContact, - IJournalTableData, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import moment from 'moment'; - -export default class JournalSheet extends FinancialSheet { - readonly tenantId: number; - readonly journal: IJournalPoster; - readonly query: IJournalReportQuery; - readonly baseCurrency: string; - readonly contactsById: Map; - - /** - * Constructor method. - * @param {number} tenantId - * @param {IJournalPoster} journal - */ - constructor( - tenantId: number, - query: IJournalReportQuery, - journal: IJournalPoster, - accountsGraph: any, - contactsById: Map, - baseCurrency: string, - i18n - ) { - super(); - - this.tenantId = tenantId; - this.journal = journal; - this.query = query; - this.numberFormat = this.query.numberFormat; - this.accountsGraph = accountsGraph; - this.contactsById = contactsById; - this.baseCurrency = baseCurrency; - this.i18n = i18n; - } - - /** - * Entry mapper. - * @param {IJournalEntry} entry - */ - entryMapper(entry: IJournalEntry) { - const account = this.accountsGraph.getNodeData(entry.accountId); - const contact = this.contactsById.get(entry.contactId); - - return { - entryId: entry.id, - index: entry.index, - note: entry.note, - - contactName: get(contact, 'displayName'), - contactType: get(contact, 'contactService'), - - accountName: account.name, - accountCode: account.code, - transactionNumber: entry.transactionNumber, - - currencyCode: this.baseCurrency, - formattedCredit: this.formatNumber(entry.credit), - formattedDebit: this.formatNumber(entry.debit), - - credit: entry.credit, - debit: entry.debit, - - createdAt: entry.createdAt, - }; - } - - /** - * Mappes the journal entries. - * @param {IJournalEntry[]} entries - - */ - entriesMapper(entries: IJournalEntry[]) { - return entries.map(this.entryMapper.bind(this)); - } - - /** - * Mapping journal entries groups. - * @param {IJournalEntry[]} entriesGroup - - * @param {string} key - - * @return {IJournalReportEntriesGroup} - */ - entriesGroupsMapper( - entriesGroup: IJournalEntry[], - groupEntry: IJournalEntry - ): IJournalReportEntriesGroup { - const totalCredit = sumBy(entriesGroup, 'credit'); - const totalDebit = sumBy(entriesGroup, 'debit'); - - return { - date: groupEntry.date, - dateFormatted: moment(groupEntry.date).format('YYYY MMM DD'), - - referenceType: groupEntry.referenceType, - referenceId: groupEntry.referenceId, - referenceTypeFormatted: this.i18n.__(groupEntry.referenceTypeFormatted), - - entries: this.entriesMapper(entriesGroup), - - currencyCode: this.baseCurrency, - - credit: totalCredit, - debit: totalDebit, - - formattedCredit: this.formatTotalNumber(totalCredit), - formattedDebit: this.formatTotalNumber(totalDebit), - }; - } - - /** - * Mapping the journal entries to entries groups. - * @param {IJournalEntry[]} entries - * @return {IJournalReportEntriesGroup[]} - */ - entriesWalker(entries: IJournalEntry[]): IJournalReportEntriesGroup[] { - return chain(entries) - .groupBy((entry) => `${entry.referenceId}-${entry.referenceType}`) - .map((entriesGroup: IJournalEntry[], key: string) => { - const headEntry = head(entriesGroup); - return this.entriesGroupsMapper(entriesGroup, headEntry); - }) - .value(); - } - - /** - * Retrieve journal report. - * @return {IJournalReport} - */ - reportData(): IJournalTableData { - return this.entriesWalker(this.journal.entries); - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts deleted file mode 100644 index 8d3f5d614..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Inject } from 'typedi'; -import { JournalSheetService } from './JournalSheetService'; -import { JournalSheetTableInjectable } from './JournalSheetTableInjectable'; -import { IJournalReportQuery, IJournalTable } from '@/interfaces'; -import { JournalSheetExportInjectable } from './JournalSheetExport'; -import { JournalSheetPdfInjectable } from './JournalSheetPdfInjectable'; - -export class JournalSheetApplication { - @Inject() - private journalSheetTable: JournalSheetTableInjectable; - - @Inject() - private journalSheet: JournalSheetService; - - @Inject() - private journalExport: JournalSheetExportInjectable; - - @Inject() - private journalPdf: JournalSheetPdfInjectable; - - /** - * Retrieves the journal sheet. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {} - */ - public sheet(tenantId: number, query: IJournalReportQuery) { - return this.journalSheet.journalSheet(tenantId, query); - } - - /** - * Retrieves the journal sheet in table format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - public table( - tenantId: number, - query: IJournalReportQuery - ): Promise { - return this.journalSheetTable.table(tenantId, query); - } - - /** - * Retrieves the journal sheet in xlsx format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns - */ - public xlsx(tenantId: number, query: IJournalReportQuery) { - return this.journalExport.xlsx(tenantId, query); - } - - /** - * Retrieves the journal sheet in csv format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns - */ - public csv(tenantId: number, query: IJournalReportQuery) { - return this.journalExport.csv(tenantId, query); - } - - /** - * Retrieves the journal sheet in pdf format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IJournalReportQuery) { - return this.journalPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetExport.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetExport.ts deleted file mode 100644 index 815c0a308..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetExport.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { IJournalReportQuery } from '@/interfaces'; -import { JournalSheetTableInjectable } from './JournalSheetTableInjectable'; - -@Service() -export class JournalSheetExportInjectable { - @Inject() - private journalSheetTable: JournalSheetTableInjectable; - - /** - * Retrieves the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IJournalReportQuery) { - const table = await this.journalSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IJournalReportQuery - ): Promise { - const table = await this.journalSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetMeta.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetMeta.ts deleted file mode 100644 index 5980e1e70..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetMeta.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import moment from 'moment'; -import { IJournalReportQuery, IJournalSheetMeta } from '@/interfaces'; - -@Service() -export class JournalSheetMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the journal sheet meta. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - public async meta( - tenantId: number, - query: IJournalReportQuery - ): Promise { - const common = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - return { - ...common, - formattedDateRange, - formattedFromDate, - formattedToDate, - }; - } -} - diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts deleted file mode 100644 index 6606d6705..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { IJournalReportQuery } from '@/interfaces'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { JournalSheetTableInjectable } from './JournalSheetTableInjectable'; -import { Inject, Service } from 'typedi'; -import { HtmlTableCustomCss } from './constant'; - -@Service() -export class JournalSheetPdfInjectable { - @Inject() - private journalSheetTable: JournalSheetTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given journal sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IJournalReportQuery - ): Promise { - const table = await this.journalSheetTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts deleted file mode 100644 index f9d23bba6..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { IJournalReportQuery, IJournalSheet } from '@/interfaces'; -import JournalSheet from './JournalSheet'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import Journal from '@/services/Accounting/JournalPoster'; -import { Tenant } from '@/system/models'; -import { transformToMap } from 'utils'; -import { JournalSheetMeta } from './JournalSheetMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class JournalSheetService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private journalSheetMeta: JournalSheetMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Default journal sheet filter queyr. - */ - get defaultQuery() { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - fromRange: null, - toRange: null, - accountsIds: [], - numberFormat: { - noCents: false, - divideOn1000: false, - }, - }; - } - - /** - * Journal sheet. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - async journalSheet( - tenantId: number, - query: IJournalReportQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - const { accountRepository, transactionsRepository, contactRepository } = - this.tenancy.repositories(tenantId); - - const { AccountTransaction } = this.tenancy.models(tenantId); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Retrieve all accounts on the storage. - const accountsGraph = await accountRepository.getDependencyGraph(); - - // Retrieve all contacts on the storage. - const contacts = await contactRepository.all(); - const contactsByIdMap = transformToMap(contacts, 'id'); - - // Retrieve all journal transactions based on the given query. - const transactions = await AccountTransaction.query().onBuild((query) => { - if (filter.fromRange || filter.toRange) { - query.modify('filterAmountRange', filter.fromRange, filter.toRange); - } - query.modify('filterDateRange', filter.fromDate, filter.toDate); - query.orderBy(['date', 'createdAt', 'indexGroup', 'index']); - - if (filter.transactionType) { - query.where('reference_type', filter.transactionType); - } - if (filter.transactionType && filter.transactionId) { - query.where('reference_id', filter.transactionId); - } - }); - // Transform the transactions array to journal collection. - const transactionsJournal = Journal.fromTransactions( - transactions, - tenantId, - accountsGraph - ); - // Journal report instance. - const journalSheetInstance = new JournalSheet( - tenantId, - filter, - transactionsJournal, - accountsGraph, - contactsByIdMap, - tenant.metadata.baseCurrency, - i18n - ); - // Retrieve journal report columns. - const journalSheetData = journalSheetInstance.reportData(); - - // Retrieve the journal sheet meta. - const meta = await this.journalSheetMeta.meta(tenantId, filter); - - // Triggers `onJournalViewed` event. - await this.eventPublisher.emitAsync(events.reports.onJournalViewed, { - tenantId, - query, - }); - - return { - data: journalSheetData, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts deleted file mode 100644 index cb99ba646..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts +++ /dev/null @@ -1,232 +0,0 @@ -import * as R from 'ramda'; -import { first } from 'lodash'; -import { - IColumnMapperMeta, - IJournalEntry, - IJournalReportEntriesGroup, - IJournalReportQuery, - IJournalTableData, - ITableColumn, - ITableColumnAccessor, - ITableRow, -} from '@/interfaces'; -import { tableRowMapper } from '@/utils'; -import { FinancialTable } from '../FinancialTable'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import FinancialSheet from '../FinancialSheet'; -import { ROW_TYPE } from './types'; - -export class JournalSheetTable extends R.compose( - FinancialTable, - FinancialSheetStructure -)(FinancialSheet) { - private data: IJournalTableData; - private query: IJournalReportQuery; - private i18n: any; - - /** - * Constructor method. - * @param {IJournalTableData} data - * @param {IJournalReportQuery} query - * @param i18n - */ - constructor(data: IJournalTableData, query: IJournalReportQuery, i18n: any) { - super(); - - this.data = data; - this.query = query; - this.i18n = i18n; - } - - /** - * Retrieves the common table accessors. - * @returns {ITableColumnAccessor[]} - */ - private groupColumnsAccessors = (): ITableColumnAccessor[] => { - return [ - { key: 'date', accessor: 'dateFormatted' }, - { key: 'transaction_type', accessor: 'referenceTypeFormatted' }, - { key: 'transaction_number', accessor: 'entry.transactionNumber' }, - { key: 'description', accessor: 'entry.note' }, - { key: 'account_code', accessor: 'entry.accountCode' }, - { key: 'account_name', accessor: 'entry.accountName' }, - { key: 'debit', accessor: 'entry.formattedDebit' }, - { key: 'credit', accessor: 'entry.formattedCredit' }, - ]; - }; - - /** - * Retrieves the group entry accessors. - * @returns {ITableColumnAccessor[]} - */ - private entryColumnsAccessors = (): ITableColumnAccessor[] => { - return [ - { key: 'date', accessor: '_empty_' }, - { key: 'transaction_type', accessor: '_empty_' }, - { key: 'transaction_number', accessor: 'transactionNumber' }, - { key: 'description', accessor: 'note' }, - { key: 'account_code', accessor: 'accountCode' }, - { key: 'account_name', accessor: 'accountName' }, - { key: 'debit', accessor: 'formattedDebit' }, - { key: 'credit', accessor: 'formattedCredit' }, - ]; - }; - - /** - * Retrieves the total entry column accessors. - * @returns {ITableColumnAccessor[]} - */ - private totalEntryColumnAccessors = (): ITableColumnAccessor[] => { - return [ - { key: 'date', accessor: '_empty_' }, - { key: 'transaction_type', accessor: '_empty_' }, - { key: 'transaction_number', accessor: '_empty_' }, - { key: 'description', accessor: '_empty_' }, - { key: 'account_code', accessor: '_empty_' }, - { key: 'account_name', accessor: '_empty_' }, - { key: 'debit', accessor: 'formattedDebit' }, - { key: 'credit', accessor: 'formattedCredit' }, - ]; - }; - - /** - * Retrieves the total entry column accessors. - * @returns {IColumnMapperMeta[]} - */ - private blankEnrtyColumnAccessors = (): IColumnMapperMeta[] => { - return [ - { key: 'date', value: '' }, - { key: 'transaction_type', value: '' }, - { key: 'transaction_number', value: '' }, - { key: 'description', value: '' }, - { key: 'account_code', value: '' }, - { key: 'account_name', value: '' }, - { key: 'debit', value: '' }, - { key: 'credit', value: '' }, - ]; - }; - - /** - * Retrieves the common columns. - * @returns {ITableColumn[]} - */ - private commonColumns(): ITableColumn[] { - return [ - { key: 'date', label: 'Date' }, - { key: 'transaction_type', label: 'Transaction Type' }, - { key: 'transaction_number', label: 'Num.' }, - { key: 'description', label: 'Description' }, - { key: 'account_code', label: 'Acc. Code' }, - { key: 'account_name', label: 'Account' }, - { key: 'debit', label: 'Debit' }, - { key: 'credit', label: 'Credit' }, - ]; - } - - /** - * Maps the group and first entry to table row. - * @param {IJournalReportEntriesGroup} group - * @returns {ITableRow} - */ - private firstEntryGroupMapper = ( - group: IJournalReportEntriesGroup - ): ITableRow => { - const meta = { - rowTypes: [ROW_TYPE.ENTRY], - }; - const computedGroup = { ...group, entry: first(group.entries) }; - const columns = this.groupColumnsAccessors(); - - return tableRowMapper(computedGroup, columns, meta); - }; - - /** - * Maps the given group entry to table rows. - * @param {IJournalEntry} entry - * @returns {ITableRow} - */ - private entryMapper = (entry: IJournalEntry): ITableRow => { - const columns = this.entryColumnsAccessors(); - const meta = { - rowTypes: [ROW_TYPE.ENTRY], - }; - return tableRowMapper(entry, columns, meta); - }; - - /** - * Maps the given group entries to table rows. - * @param {IJournalReportEntriesGroup} group - * @returns {ITableRow[]} - */ - private entriesMapper = (group: IJournalReportEntriesGroup): ITableRow[] => { - const entries = R.remove(0, 1, group.entries); - - return R.map(this.entryMapper, entries); - }; - - /** - * Maps the given group entry to total table row. - * @param {IJournalReportEntriesGroup} group - * @returns {ITableRow} - */ - public totalEntryMapper = (group: IJournalReportEntriesGroup): ITableRow => { - const total = this.totalEntryColumnAccessors(); - const meta = { - rowTypes: [ROW_TYPE.TOTAL], - }; - return tableRowMapper(group, total, meta); - }; - - /** - * Retrieves the blank entry row. - * @returns {ITableRow} - */ - private blankEntryMapper = (): ITableRow => { - const columns = this.blankEnrtyColumnAccessors(); - const meta = {}; - return tableRowMapper({} as IJournalEntry, columns, meta); - }; - - /** - * Maps the entry group to table rows. - * @param {IJournalReportEntriesGroup} group - - * @returns {ITableRow} - */ - private groupMapper = (group: IJournalReportEntriesGroup): ITableRow[] => { - const firstRow = this.firstEntryGroupMapper(group); - const lastRows = this.entriesMapper(group); - const totalRow = this.totalEntryMapper(group); - const blankRow = this.blankEntryMapper(); - - return [firstRow, ...lastRows, totalRow, blankRow]; - }; - - /** - * Maps the given group entries to table rows. - * @param {IJournalReportEntriesGroup[]} entries - - * @returns {ITableRow[]} - */ - private groupsMapper = ( - entries: IJournalReportEntriesGroup[] - ): ITableRow[] => { - return R.compose(R.flatten, R.map(this.groupMapper))(entries); - }; - - /** - * Retrieves the table data rows. - * @returns {ITableRow[]} - */ - public tableData(): ITableRow[] { - return R.compose(this.groupsMapper)(this.data); - } - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns(): ITableColumn[] { - const columns = this.commonColumns(); - - return R.compose(this.tableColumnsCellIndexing)(columns); - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTableInjectable.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTableInjectable.ts deleted file mode 100644 index 0754d78f8..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTableInjectable.ts +++ /dev/null @@ -1,39 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject } from 'typedi'; -import { JournalSheetService } from './JournalSheetService'; -import { IJournalReportQuery, IJournalTable } from '@/interfaces'; -import { JournalSheetTable } from './JournalSheetTable'; - -export class JournalSheetTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private journalSheetService: JournalSheetService; - - /** - * Retrieves the journal sheet in table format. - * @param {number} tenantId - * @param {IJournalReportQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: IJournalReportQuery - ): Promise { - const journal = await this.journalSheetService.journalSheet( - tenantId, - query - ); - const table = new JournalSheetTable(journal.data, journal.query, {}); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableData(), - }, - query: journal.query, - meta: journal.meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/constant.ts b/packages/server/src/services/FinancialStatements/JournalSheet/constant.ts deleted file mode 100644 index 58f5237f6..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/constant.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const HtmlTableCustomCss = ` -table tr.row-type--total td{ - font-weight: 600; -} -table tr td:not(:first-child) { - border-left: 1px solid #ececec; -} -table tr:last-child td { - border-bottom: 1px solid #ececec; -} -table .cell--credit, -table .cell--debit, -table .column--credit, -table .column--debit{ - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/types.ts b/packages/server/src/services/FinancialStatements/JournalSheet/types.ts deleted file mode 100644 index 6eff84957..000000000 --- a/packages/server/src/services/FinancialStatements/JournalSheet/types.ts +++ /dev/null @@ -1,5 +0,0 @@ - -export enum ROW_TYPE { - ENTRY = 'ENTRY', - TOTAL = 'TOTAL' -}; \ No newline at end of file diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSchema.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSchema.ts deleted file mode 100644 index f18cdf59e..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSchema.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as R from 'ramda'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; -import { - ProfitLossAggregateNodeId, - ProfitLossNodeType, - IProfitLossSchemaNode, -} from '@/interfaces'; -import { FinancialSchema } from '../FinancialSchema'; - -export const ProfitLossShema = (Base) => - class extends R.compose(FinancialSchema)(Base) { - /** - * Retrieves the report schema. - * @returns {IProfitLossSchemaNode[]} - */ - getSchema = (): IProfitLossSchemaNode[] => { - return getProfitLossSheetSchema(); - }; - }; - -/** - * Retrieves P&L sheet schema. - * @returns {IProfitLossSchemaNode} - */ -export const getProfitLossSheetSchema = (): IProfitLossSchemaNode[] => [ - { - id: ProfitLossAggregateNodeId.INCOME, - name: 'profit_loss_sheet.income', - nodeType: ProfitLossNodeType.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.INCOME], - alwaysShow: true, - }, - { - id: ProfitLossAggregateNodeId.COS, - name: 'profit_loss_sheet.cost_of_sales', - nodeType: ProfitLossNodeType.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.COST_OF_GOODS_SOLD], - }, - { - id: ProfitLossAggregateNodeId.GROSS_PROFIT, - name: 'profit_loss_sheet.gross_profit', - nodeType: ProfitLossNodeType.EQUATION, - equation: `${ProfitLossAggregateNodeId.INCOME} - ${ProfitLossAggregateNodeId.COS}`, - }, - { - id: ProfitLossAggregateNodeId.EXPENSES, - name: 'profit_loss_sheet.expenses', - nodeType: ProfitLossNodeType.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.EXPENSE], - alwaysShow: true, - }, - { - id: ProfitLossAggregateNodeId.NET_OPERATING_INCOME, - name: 'profit_loss_sheet.net_operating_income', - nodeType: ProfitLossNodeType.EQUATION, - equation: `${ProfitLossAggregateNodeId.GROSS_PROFIT} - ${ProfitLossAggregateNodeId.EXPENSES}`, - }, - { - id: ProfitLossAggregateNodeId.OTHER_INCOME, - name: 'profit_loss_sheet.other_income', - nodeType: ProfitLossNodeType.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.OTHER_INCOME], - }, - { - id: ProfitLossAggregateNodeId.OTHER_EXPENSES, - name: 'profit_loss_sheet.other_expenses', - nodeType: ProfitLossNodeType.ACCOUNTS, - accountsTypes: [ACCOUNT_TYPE.OTHER_EXPENSE], - }, - { - id: ProfitLossAggregateNodeId.NET_INCOME, - name: 'profit_loss_sheet.net_income', - nodeType: ProfitLossNodeType.EQUATION, - equation: `${ProfitLossAggregateNodeId.NET_OPERATING_INCOME} + ${ProfitLossAggregateNodeId.OTHER_INCOME} - ${ProfitLossAggregateNodeId.OTHER_EXPENSES}`, - }, -]; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheet.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheet.ts deleted file mode 100644 index ba8d32542..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheet.ts +++ /dev/null @@ -1,334 +0,0 @@ -import * as R from 'ramda'; -import { IProfitLossSheetQuery } from '@/interfaces/ProfitLossSheet'; -import FinancialSheet from '../FinancialSheet'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { - ProfitLossNodeType, - IProfitLossSheetEquationNode, - IProfitLossEquationSchemaNode, - IProfitLossSheetAccountsNode, - IProfitLossAccountsSchemaNode, - IProfitLossSchemaNode, - IProfitLossSheetNode, - IAccount, - IProfitLossSheetAccountNode, -} from '@/interfaces'; -import { ProfitLossShema } from './ProfitLossSchema'; -import { ProfitLossSheetPercentage } from './ProfitLossSheetPercentage'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; -import { ProfitLossSheetRepository } from './ProfitLossSheetRepository'; -import { ProfitLossSheetBase } from './ProfitLossSheetBase'; -import { ProfitLossSheetDatePeriods } from './ProfitLossSheetDatePeriods'; -import { FinancialEvaluateEquation } from '../FinancialEvaluateEquation'; -import { ProfitLossSheetPreviousYear } from './ProfitLossSheetPreviousYear'; -import { ProfitLossSheetPreviousPeriod } from './ProfitLossSheetPreviousPeriod'; -import { FinancialDateRanges } from '../FinancialDateRanges'; -import { ProfitLossSheetFilter } from './ProfitLossSheetFilter'; -import { flatToNestedArray } from '@/utils'; - -export default class ProfitLossSheet extends R.compose( - ProfitLossSheetPreviousYear, - ProfitLossSheetPreviousPeriod, - ProfitLossSheetPercentage, - ProfitLossSheetDatePeriods, - ProfitLossSheetFilter, - ProfitLossShema, - ProfitLossSheetBase, - FinancialDateRanges, - FinancialEvaluateEquation, - FinancialSheetStructure -)(FinancialSheet) { - /** - * Profit/Loss sheet query. - * @param {ProfitLossSheetQuery} - */ - readonly query: ProfitLossSheetQuery; - /** - * @param {string} - */ - readonly comparatorDateType: string; - - /** - * Organization's base currency. - * @param {string} - */ - readonly baseCurrency: string; - - /** - * Profit/Loss repository. - * @param {ProfitLossSheetRepository} - */ - readonly repository: ProfitLossSheetRepository; - - /** - * Constructor method. - * @param {IProfitLossSheetQuery} query - - * @param {IAccount[]} accounts - - * @param {IJournalPoster} transactionsJournal - - */ - constructor( - repository: ProfitLossSheetRepository, - query: IProfitLossSheetQuery, - baseCurrency: string, - i18n: any - ) { - super(); - - this.query = new ProfitLossSheetQuery(query); - this.repository = repository; - this.numberFormat = this.query.query.numberFormat; - this.baseCurrency = baseCurrency; - this.i18n = i18n; - } - - /** - * Retrieve the sheet account node from the given account. - * @param {IAccount} account - * @returns {IProfitLossSheetAccountNode} - */ - private accountNodeMapper = ( - account: IAccount - ): IProfitLossSheetAccountNode => { - // Retrieves the children account ids of the given account id. - const childrenAccountIds = this.repository.accountsGraph.dependenciesOf( - account.id - ); - // Concat the children and the given account id. - const accountIds = R.uniq(R.append(account.id, childrenAccountIds)); - - // Retrieves the closing balance of the account included children accounts. - const total = this.repository.totalAccountsLedger - .whereAccountsIds(accountIds) - .getClosingBalance(); - - return { - id: account.id, - name: account.name, - nodeType: ProfitLossNodeType.ACCOUNT, - total: this.getAmountMeta(total), - }; - }; - - /** - * Compose account node. - * @param {IAccount} node - * @returns {IProfitLossSheetAccountNode} - */ - private accountNodeCompose = ( - account: IAccount - ): IProfitLossSheetAccountNode => { - return R.compose( - R.when( - this.query.isPreviousPeriodActive, - this.previousPeriodAccountNodeCompose - ), - R.when( - this.query.isPreviousYearActive, - this.previousYearAccountNodeCompose - ), - R.when( - this.query.isDatePeriodsColumnsType, - this.assocAccountNodeDatePeriod - ), - this.accountNodeMapper - )(account); - }; - - /** - * Retrieves report accounts nodes by the given accounts types. - * @param {string[]} types - * @returns {IBalanceSheetAccountNode} - */ - private getAccountsNodesByTypes = ( - types: string[] - ): IProfitLossSheetAccountNode[] => { - const accounts = this.repository.getAccountsByType(types); - const accountsTree = flatToNestedArray(accounts, { - id: 'id', - parentId: 'parentAccountId', - }); - return this.mapNodesDeep(accountsTree, this.accountNodeCompose); - }; - - /** - * Mapps the accounts schema node to report node. - * @param {IProfitLossSchemaNode} node - * @returns {IProfitLossSheetNode} - */ - private accountsSchemaNodeMapper = ( - node: IProfitLossAccountsSchemaNode - ): IProfitLossSheetNode => { - // Retrieve accounts node by the given types. - const children = this.getAccountsNodesByTypes(node.accountsTypes); - - // Retrieve the total of the given nodes. - const total = this.getTotalOfNodes(children); - - return { - id: node.id, - name: this.i18n.__(node.name), - nodeType: ProfitLossNodeType.ACCOUNTS, - total: this.getTotalAmountMeta(total), - children, - }; - }; - - /** - * Accounts schema node composer. - * @param {IProfitLossSchemaNode} node - * @returns {IProfitLossSheetAccountsNode} - */ - private accountsSchemaNodeCompose = ( - node: IProfitLossSchemaNode - ): IProfitLossSheetAccountsNode => { - return R.compose( - R.when( - this.query.isPreviousPeriodActive, - this.previousPeriodAggregateNodeCompose - ), - R.when( - this.query.isPreviousYearActive, - this.previousYearAggregateNodeCompose - ), - R.when( - this.query.isDatePeriodsColumnsType, - this.assocAggregateDatePeriod - ), - this.accountsSchemaNodeMapper - )(node); - }; - - /** - * Equation schema node parser. - * @param {(IProfitLossSchemaNode | IProfitLossSheetNode)[]} accNodes - - * @param {IProfitLossEquationSchemaNode} node - - * @param {IProfitLossSheetEquationNode} - */ - private equationSchemaNodeParser = R.curry( - ( - accNodes: (IProfitLossSchemaNode | IProfitLossSheetNode)[], - node: IProfitLossEquationSchemaNode - ): IProfitLossSheetEquationNode => { - const tableNodes = this.getNodesTableForEvaluating( - 'total.amount', - accNodes - ); - // Evaluate the given equation. - const total = this.evaluateEquation(node.equation, tableNodes); - - return { - id: node.id, - name: this.i18n.__(node.name), - nodeType: ProfitLossNodeType.EQUATION, - total: this.getTotalAmountMeta(total), - }; - } - ); - - /** - * Equation schema node composer. - * @param {(IProfitLossSchemaNode | IProfitLossSheetNode)[]} accNodes - - * @param {IProfitLossSchemaNode} node - - * @returns {IProfitLossSheetEquationNode} - */ - private equationSchemaNodeCompose = R.curry( - ( - accNodes: (IProfitLossSchemaNode | IProfitLossSheetNode)[], - node: IProfitLossEquationSchemaNode - ): IProfitLossSheetEquationNode => { - return R.compose( - R.when( - this.query.isPreviousPeriodActive, - this.previousPeriodEquationNodeCompose(accNodes, node.equation) - ), - R.when( - this.query.isPreviousYearActive, - this.previousYearEquationNodeCompose(accNodes, node.equation) - ), - R.when( - this.query.isDatePeriodsColumnsType, - this.assocEquationNodeDatePeriod(accNodes, node.equation) - ), - this.equationSchemaNodeParser(accNodes) - )(node); - } - ); - - /** - * Parses accounts schema node to report node. - * @param {IProfitLossSchemaNode} schemaNode - * @returns {IProfitLossSheetNode | IProfitLossSchemaNode} - */ - private accountsSchemaNodeMap = ( - schemaNode: IProfitLossSchemaNode - ): IProfitLossSheetNode | IProfitLossSchemaNode => { - return R.compose( - R.when( - this.isNodeType(ProfitLossNodeType.ACCOUNTS), - this.accountsSchemaNodeCompose - ) - )(schemaNode); - }; - - /** - * Composes schema equation node to report node. - * @param {IProfitLossSheetNode | IProfitLossSchemaNode} node - * @param {number} key - * @param {IProfitLossSheetNode | IProfitLossSchemaNode} parentValue - * @param {(IProfitLossSheetNode | IProfitLossSchemaNode)[]} accNodes - * @param context - * @returns {IProfitLossSheetEquationNode} - */ - private reportSchemaEquationNodeCompose = ( - node: IProfitLossSheetNode | IProfitLossSchemaNode, - key: number, - parentValue: IProfitLossSheetNode | IProfitLossSchemaNode, - accNodes: (IProfitLossSheetNode | IProfitLossSchemaNode)[], - context - ): IProfitLossSheetEquationNode => { - return R.compose( - R.when( - this.isNodeType(ProfitLossNodeType.EQUATION), - this.equationSchemaNodeCompose(accNodes) - ) - )(node); - }; - - /** - * Parses schema accounts nodes. - * @param {IProfitLossSchemaNode[]} - * @returns {(IProfitLossSheetNode | IProfitLossSchemaNode)[]} - */ - private reportSchemaAccountsNodesCompose = ( - schemaNodes: IProfitLossSchemaNode[] - ): (IProfitLossSheetNode | IProfitLossSchemaNode)[] => { - return this.mapNodesDeep(schemaNodes, this.accountsSchemaNodeMap); - }; - - /** - * Parses schema equation nodes. - * @param {(IProfitLossSheetNode | IProfitLossSchemaNode)[]} nodes - * @returns {(IProfitLossSheetNode | IProfitLossSchemaNode)[]} - */ - private reportSchemaEquationNodesCompose = ( - nodes: (IProfitLossSheetNode | IProfitLossSchemaNode)[] - ): (IProfitLossSheetNode | IProfitLossSchemaNode)[] => { - return this.mapAccNodesDeep(nodes, this.reportSchemaEquationNodeCompose); - }; - - /** - * Retrieve profit/loss report data. - * @return {IProfitLossSheetStatement} - */ - public reportData = (): IProfitLossSheetNode => { - const schema = this.getSchema(); - - return R.compose( - this.reportFilterPlugin, - this.reportRowsPercentageCompose, - this.reportColumnsPerentageCompose, - this.reportSchemaEquationNodesCompose, - this.reportSchemaAccountsNodesCompose - )(schema); - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts deleted file mode 100644 index 6d15e2cc6..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ProfitLossSheetExportInjectable } from './ProfitLossSheetExportInjectable'; -import { ProfitLossSheetTableInjectable } from './ProfitLossSheetTableInjectable'; -import { IProfitLossSheetQuery, IProfitLossSheetTable } from '@/interfaces'; -import ProfitLossSheetService from './ProfitLossSheetService'; -import { ProfitLossTablePdfInjectable } from './ProfitLossTablePdfInjectable'; - -@Service() -export class ProfitLossSheetApplication { - @Inject() - private profitLossTable: ProfitLossSheetTableInjectable; - - @Inject() - private profitLossExport: ProfitLossSheetExportInjectable; - - @Inject() - private profitLossSheet: ProfitLossSheetService; - - @Inject() - private profitLossPdf: ProfitLossTablePdfInjectable; - - /** - * Retreives the profit/loss sheet. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {} - */ - public sheet(tenantId: number, query: IProfitLossSheetQuery) { - return this.profitLossSheet.profitLossSheet(tenantId, query); - } - - /** - * Retrieves the profit/loss sheet table format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {Promise} - */ - public table( - tenantId: number, - query: IProfitLossSheetQuery - ): Promise { - return this.profitLossTable.table(tenantId, query); - } - - /** - * Retrieves the profit/loss sheet in csv format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {Promise} - */ - public csv(tenantId: number, query: IProfitLossSheetQuery): Promise { - return this.profitLossExport.csv(tenantId, query); - } - - /** - * Retrieves the profit/loss sheet in xlsx format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {Promise} - */ - public xlsx(tenantId: number, query: IProfitLossSheetQuery): Promise { - return this.profitLossExport.xlsx(tenantId, query); - } - - /** - * Retrieves the profit/loss sheet in pdf format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IProfitLossSheetQuery): Promise { - return this.profitLossPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetBase.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetBase.ts deleted file mode 100644 index ea5888c55..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetBase.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as R from 'ramda'; -import { TOTAL_NODE_TYPES } from './constants'; - -export const ProfitLossSheetBase = (Base) => - class extends Base { - /** - * - * @param type - * @param node - * @returns - */ - public isNodeType = R.curry((type: string, node) => { - return node.nodeType === type; - }); - - protected isNodeTypeIn = R.curry((types: string[], node) => { - return types.indexOf(node.nodeType) !== -1; - }); - - /** - * - */ - protected findNodeById = R.curry((id, nodes) => { - return this.findNodeDeep(nodes, (node) => node.id === id); - }); - - isNodeTotal = (node) => { - return this.isNodeTypeIn(TOTAL_NODE_TYPES, node); - } - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetDatePeriods.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetDatePeriods.ts deleted file mode 100644 index 8f0f5650a..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetDatePeriods.ts +++ /dev/null @@ -1,236 +0,0 @@ -import * as R from 'ramda'; -import { sumBy } from 'lodash'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; -import { - IDateRange, - IProfitLossHorizontalDatePeriodNode, - IProfitLossSheetAccountNode, - IProfitLossSheetAccountsNode, - IProfitLossSheetCommonNode, - IProfitLossSheetNode, -} from '@/interfaces'; - -export const ProfitLossSheetDatePeriods = (Base) => - class extends R.compose(FinancialDatePeriods)(Base) { - /** - * Retrieves the date periods based on the report query. - * @returns {IDateRange[]} - */ - get datePeriods(): IDateRange[] { - return this.getDateRanges( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy - ); - } - - /** - * Retrieves the date periods of the given node based on the report query. - * @param {IProfitLossSheetCommonNode} node - * @param {Function} callback - * @returns {} - */ - protected getReportNodeDatePeriods = ( - node: IProfitLossSheetCommonNode, - callback: ( - node: IProfitLossSheetCommonNode, - fromDate: Date, - toDate: Date, - index: number - ) => any - ) => { - return this.getNodeDatePeriods( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy, - node, - callback - ); - }; - - // -------------------------- - // # Account Nodes. - // -------------------------- - /** - * Retrieve account node date period total. - * @param {IProfitLossSheetAccount} node - * @param {Date} fromDate - * @param {Date} toDate - * @returns {} - */ - private getAccountNodeDatePeriodTotal = ( - node: IProfitLossSheetAccountNode, - fromDate: Date, - toDate: Date - ) => { - const periodTotal = this.repository.periodsAccountsLedger - .whereAccountId(node.id) - .whereFromDate(fromDate) - .whereToDate(toDate) - .getClosingBalance(); - - return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate); - }; - - /** - * Retrieve account node date period. - * @param {IProfitLossSheetAccountNode} node - * @returns {IProfitLossSheetAccountNode} - */ - public getAccountNodeDatePeriod = (node: IProfitLossSheetAccountNode) => { - return this.getReportNodeDatePeriods( - node, - this.getAccountNodeDatePeriodTotal - ); - }; - - /** - * Account date periods to the given account node. - * @param {IProfitLossSheetAccountNode} node - * @returns {IProfitLossSheetAccountNode} - */ - public assocAccountNodeDatePeriod = ( - node: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - const datePeriods = this.getAccountNodeDatePeriod(node); - - return R.assoc('horizontalTotals', datePeriods, node); - }; - - // -------------------------- - // # Aggregate nodes. - // -------------------------- - /** - * Retrieves sumation of the given aggregate node children totals. - * @param {IProfitLossSheetAccountsNode} node - * @param {number} index - * @returns {number} - */ - private getAggregateDatePeriodIndexTotal = ( - node: IProfitLossSheetAccountsNode, - index: number - ): number => { - return sumBy(node.children, `horizontalTotals[${index}].total.amount`); - }; - - /** - * - * @param {IProfitLossSheetAccount} node - * @param {Date} fromDate - * @param {Date} toDate - * @param {number} index - * @returns {IProfitLossSheetAccount} - */ - private getAggregateNodeDatePeriodTotal = R.curry( - ( - node: IProfitLossSheetAccountsNode, - fromDate: Date, - toDate: Date, - index: number - ): IProfitLossHorizontalDatePeriodNode => { - const periodTotal = this.getAggregateDatePeriodIndexTotal(node, index); - - return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate); - } - ); - - /** - * Retrieves aggregate horizontal date periods. - * @param {IProfitLossSheetAccountsNode} node - * @returns {IProfitLossSheetAccountsNode} - */ - private getAggregateNodeDatePeriod = ( - node: IProfitLossSheetAccountsNode - ): IProfitLossHorizontalDatePeriodNode[] => { - return this.getReportNodeDatePeriods( - node, - this.getAggregateNodeDatePeriodTotal - ); - }; - - /** - * Assoc horizontal date periods to aggregate node. - * @param {IProfitLossSheetAccountsNode} node - * @returns {IProfitLossSheetAccountsNode} - */ - protected assocAggregateDatePeriod = ( - node: IProfitLossSheetAccountsNode - ): IProfitLossSheetAccountsNode => { - const datePeriods = this.getAggregateNodeDatePeriod(node); - - return R.assoc('horizontalTotals', datePeriods, node); - }; - - // -------------------------- - // # Equation nodes. - // -------------------------- - /** - * Retrieves equation date period node. - * @param {IProfitLossSheetNode[]} accNodes - * @param {IProfitLossSheetNode} node - * @param {Date} fromDate - * @param {Date} toDate - * @param {number} index - * @returns {IProfitLossHorizontalDatePeriodNode} - */ - private getEquationNodeDatePeriod = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - node: IProfitLossSheetNode, - fromDate: Date, - toDate: Date, - index: number - ): IProfitLossHorizontalDatePeriodNode => { - const tableNodes = this.getNodesTableForEvaluating( - `horizontalTotals[${index}].total.amount`, - accNodes - ); - // Evaluate the given equation. - const total = this.evaluateEquation(equation, tableNodes); - - return this.getDatePeriodTotalMeta(total, fromDate, toDate); - } - ); - - /** - * Retrieves the equation node date periods. - * @param {IProfitLossSheetNode[]} node - * @param {string} equation - * @param {IProfitLossSheetNode} node - * @returns {IProfitLossHorizontalDatePeriodNode[]} - */ - private getEquationNodeDatePeriods = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - node: IProfitLossSheetNode - ): IProfitLossHorizontalDatePeriodNode[] => { - return this.getReportNodeDatePeriods( - node, - this.getEquationNodeDatePeriod(accNodes, equation) - ); - } - ); - - /** - * Assoc equation node date period. - * @param {IProfitLossSheetNode[]} - * @param {IProfitLossSheetNode} node - * @returns {IProfitLossSheetNode} - */ - protected assocEquationNodeDatePeriod = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - node: IProfitLossSheetNode - ): IProfitLossSheetNode => { - const periods = this.getEquationNodeDatePeriods( - accNodes, - equation, - node - ); - return R.assoc('horizontalTotals', periods, node); - } - ); - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts deleted file mode 100644 index ba2371797..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IProfitLossSheetQuery } from '@/interfaces'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { ProfitLossSheetTableInjectable } from './ProfitLossSheetTableInjectable'; - -@Service() -export class ProfitLossSheetExportInjectable { - @Inject() - private profitLossSheetTable: ProfitLossSheetTableInjectable; - - /** - * Retrieves the profit/loss sheet in XLSX format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IProfitLossSheetQuery) { - const table = await this.profitLossSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the profit/loss sheet in CSV format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IProfitLossSheetQuery - ): Promise { - const table = await this.profitLossSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetFilter.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetFilter.ts deleted file mode 100644 index 864cf1fbe..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetFilter.ts +++ /dev/null @@ -1,170 +0,0 @@ -import * as R from 'ramda'; -import { get } from 'lodash'; -import { IProfitLossSheetNode, ProfitLossNodeType } from '@/interfaces'; -import { FinancialFilter } from '../FinancialFilter'; -import { ProfitLossSheetBase } from './ProfitLossSheetBase'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; - -export const ProfitLossSheetFilter = (Base) => - class extends R.compose(FinancialFilter, ProfitLossSheetBase)(Base) { - query: ProfitLossSheetQuery; - - // ---------------- - // # Account. - // ---------------- - /** - * Filter report node detarmine. - * @param {IProfitLossSheetNode} node - Balance sheet node. - * @return {boolean} - */ - private accountNoneZeroNodesFilterDetarminer = ( - node: IProfitLossSheetNode - ): boolean => { - return R.ifElse( - this.isNodeType(ProfitLossNodeType.ACCOUNT), - this.isNodeNoneZero, - R.always(true) - )(node); - }; - - /** - * Detarmines account none-transactions node. - * @param {IBalanceSheetDataNode} node - * @returns {boolean} - */ - private accountNoneTransFilterDetarminer = ( - node: IProfitLossSheetNode - ): boolean => { - return R.ifElse( - this.isNodeType(ProfitLossNodeType.ACCOUNT), - this.isNodeNoneZero, - R.always(true) - )(node); - }; - - /** - * Report nodes filter. - * @param {IProfitLossSheetNode[]} nodes - - * @return {IProfitLossSheetNode[]} - */ - private accountsNoneZeroNodesFilter = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return this.filterNodesDeep( - nodes, - this.accountNoneZeroNodesFilterDetarminer - ); - }; - - /** - * Filters the accounts none-transactions nodes. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private accountsNoneTransactionsNodesFilter = ( - nodes: IProfitLossSheetNode[] - ) => { - return this.filterNodesDeep(nodes, this.accountNoneTransFilterDetarminer); - }; - - // ---------------- - // # Aggregate. - // ---------------- - /** - * Detearmines aggregate none-children filtering. - * @param {IProfitLossSheetNode} node - * @returns {boolean} - */ - private aggregateNoneChildrenFilterDetarminer = ( - node: IProfitLossSheetNode - ): boolean => { - const schemaNode = this.getSchemaNodeById(node.id); - - // Detarmines whether the given node is aggregate node. - const isAggregateNode = this.isNodeType( - ProfitLossNodeType.ACCOUNTS, - node - ); - // Detarmines if the schema node is always should show. - const isSchemaAlwaysShow = get(schemaNode, 'alwaysShow', false); - - // Should node has children if aggregate node or not always show. - return isAggregateNode && !isSchemaAlwaysShow - ? this.isNodeHasChildren(node) - : true; - }; - - /** - * Filters aggregate none-children nodes. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private aggregateNoneChildrenFilter = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return this.filterNodesDeep2( - this.aggregateNoneChildrenFilterDetarminer, - nodes - ); - }; - - // ---------------- - // # Composers. - // ---------------- - /** - * Filters none-zero nodes. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private filterNoneZeroNodesCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return R.compose( - this.aggregateNoneChildrenFilter, - this.accountsNoneZeroNodesFilter - )(nodes); - }; - - /** - * Filters none-transactions nodes. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private filterNoneTransNodesCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return R.compose( - this.aggregateNoneChildrenFilter, - this.accountsNoneTransactionsNodesFilter - )(nodes); - }; - - /** - * Supress nodes when total accounts range transactions is empty. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private supressNodesWhenRangeTransactionsEmpty = ( - nodes: IProfitLossSheetNode[] - ) => { - return this.repository.totalAccountsLedger.isEmpty() ? [] : nodes; - }; - - /** - * Compose report nodes filtering. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - protected reportFilterPlugin = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return R.compose( - this.supressNodesWhenRangeTransactionsEmpty, - R.when(() => this.query.noneZero, this.filterNoneZeroNodesCompose), - R.when( - () => this.query.noneTransactions, - this.filterNoneTransNodesCompose - ) - )(nodes); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetMeta.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetMeta.ts deleted file mode 100644 index c278420f5..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetMeta.ts +++ /dev/null @@ -1,35 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { ICashFlowStatementMeta, ICashFlowStatementQuery } from '@/interfaces'; - -@Service() -export class ProfitLossSheetMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the P/L sheet meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: ICashFlowStatementQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - const sheetName = 'Cashflow Statement'; - - return { - ...commonMeta, - sheetName, - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPercentage.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPercentage.ts deleted file mode 100644 index e84fdc1a8..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPercentage.ts +++ /dev/null @@ -1,301 +0,0 @@ -import * as R from 'ramda'; -import { - IProfitLossSheetNode, - IProfitLossSheetTotal, - ProfitLossAggregateNodeId, -} from '@/interfaces'; -import { FinancialHorizTotals } from '../FinancialHorizTotals'; - -export const ProfitLossSheetPercentage = (Base) => - class extends R.compose(FinancialHorizTotals)(Base) { - /** - * Assoc column of percentage attribute to the given node. - * @param {IProfitLossSheetNode} netIncomeNode - - * @param {IProfitLossSheetNode} node - - * @return {IProfitLossSheetNode} - */ - private assocColumnPercentage = R.curry( - ( - propertyPath: string, - parentNode: IProfitLossSheetNode, - node: IProfitLossSheetNode - ) => { - const percentage = this.getPercentageBasis( - parentNode.total.amount, - node.total.amount - ); - return R.assoc( - propertyPath, - this.getPercentageAmountMeta(percentage), - node - ); - } - ); - - /** - * Assoc column of percentage attribute to the given node. - * @param {IProfitLossSheetNode} netIncomeNode - - * @param {IProfitLossSheetNode} node - - * @return {IProfitLossSheetNode} - */ - private assocColumnTotalPercentage = R.curry( - ( - propertyPath: string, - parentNode: IProfitLossSheetNode, - node: IProfitLossSheetNode - ) => { - const percentage = this.getPercentageBasis( - parentNode.total.amount, - node.total.amount - ); - return R.assoc( - propertyPath, - this.getPercentageTotalAmountMeta(percentage), - node - ); - } - ); - - /** - * Compose percentage of columns. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private columnPercentageCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - const netIncomeNode = this.findNodeById( - ProfitLossAggregateNodeId.NET_INCOME, - nodes - ); - return this.mapNodesDeep( - nodes, - this.columnPercentageMapper(netIncomeNode) - ); - }; - - /** - * Compose percentage of income. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private incomePercetageCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - const incomeNode = this.findNodeById( - ProfitLossAggregateNodeId.INCOME, - nodes - ); - return this.mapNodesDeep(nodes, this.incomePercentageMapper(incomeNode)); - }; - - /** - * - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private rowPercentageCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return this.mapNodesDeep(nodes, this.rowPercentageMap); - }; - - /** - * - * @param {IProfitLossSheetNode} netIncomeNode - - * @param {IProfitLossSheetNode} node - - * @return {IProfitLossSheetNode} - */ - private columnPercentageMapper = R.curry( - (netIncomeNode: IProfitLossSheetNode, node: IProfitLossSheetNode) => { - const path = 'percentageColumn'; - - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocColumnPercentageHorizTotals(netIncomeNode) - ), - R.ifElse( - this.isNodeTotal, - this.assocColumnTotalPercentage(path, netIncomeNode), - this.assocColumnPercentage(path, netIncomeNode) - ) - )(node); - } - ); - - /** - * - * @param {IProfitLossSheetNode} node - * @returns {IProfitLossSheetNode} - */ - private rowPercentageMap = ( - node: IProfitLossSheetNode - ): IProfitLossSheetNode => { - const path = 'percentageRow'; - - return R.compose( - R.when(this.isNodeHasHorizTotals, this.assocRowPercentageHorizTotals), - R.ifElse( - this.isNodeTotal, - this.assocColumnTotalPercentage(path, node), - this.assocColumnPercentage(path, node) - ) - )(node); - }; - - /** - * - * @param {IProfitLossSheetNode} incomeNode - - * @param {IProfitLossSheetNode} node - - * @returns {IProfitLossSheetNode} - */ - private incomePercentageMapper = R.curry( - (incomeNode: IProfitLossSheetNode, node: IProfitLossSheetNode) => { - const path = 'percentageIncome'; - - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocIncomePercentageHorizTotals(incomeNode) - ), - R.ifElse( - this.isNodeTotal, - this.assocColumnTotalPercentage(path, incomeNode), - this.assocColumnPercentage(path, incomeNode) - ) - )(node); - } - ); - - /** - * - * @param {IProfitLossSheetNode} expenseNode - - * @param {IProfitLossSheetNode} node - - */ - private expensePercentageMapper = R.curry( - (expenseNode: IProfitLossSheetNode, node: IProfitLossSheetNode) => { - const path = 'percentageExpense'; - - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocExpensePercentageHorizTotals(expenseNode) - ), - R.ifElse( - this.isNodeTotal, - this.assocColumnTotalPercentage(path, expenseNode), - this.assocColumnPercentage(path, expenseNode) - ) - )(node); - } - ); - - /** - * Compose percentage of expense. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - private expensesPercentageCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - const expenseNode = this.findNodeById( - ProfitLossAggregateNodeId.EXPENSES, - nodes - ); - return this.mapNodesDeep( - nodes, - this.expensePercentageMapper(expenseNode) - ); - }; - - /** - * Compose percentage attributes. - * @param {IProfitLossSheetNode[]} nodes - * @returns {IProfitLossSheetNode[]} - */ - protected reportColumnsPerentageCompose = ( - nodes: IProfitLossSheetNode[] - ): IProfitLossSheetNode[] => { - return R.compose( - R.when(this.query.isIncomePercentage, this.incomePercetageCompose), - R.when(this.query.isColumnPercentage, this.columnPercentageCompose), - R.when(this.query.isExpensesPercentage, this.expensesPercentageCompose), - R.when(this.query.isRowPercentage, this.rowPercentageCompose) - )(nodes); - }; - - /** - * - * @param {} nodes - * @returns {} - */ - protected reportRowsPercentageCompose = (nodes) => { - return nodes; - }; - - // ---------------------------------- - // # Horizontal Nodes - // ---------------------------------- - /** - * Assoc incomer percentage to horizontal totals nodes. - * @param {IProfitLossSheetNode} incomeNode - - * @param {IProfitLossSheetNode} node - - * @returns {IProfitLossSheetNode} - */ - private assocIncomePercentageHorizTotals = R.curry( - (incomeNode: IProfitLossSheetNode, node: IProfitLossSheetNode) => { - const horTotalsWithIncomePerc = this.assocPercentageHorizTotals( - 'percentageIncome', - incomeNode, - node - ); - return R.assoc('horizontalTotals', horTotalsWithIncomePerc, node); - } - ); - - /** - * Assoc expense percentage to horizontal totals nodes. - * @param {IProfitLossSheetNode} expenseNode - - * @param {IProfitLossSheetNode} node - - * @returns {IProfitLossSheetNode} - */ - private assocExpensePercentageHorizTotals = R.curry( - (expenseNode: IProfitLossSheetNode, node: IProfitLossSheetNode) => { - const horTotalsWithExpensePerc = this.assocPercentageHorizTotals( - 'percentageExpense', - expenseNode, - node - ); - return R.assoc('horizontalTotals', horTotalsWithExpensePerc, node); - } - ); - - /** - * Assoc net income percentage to horizontal totals nodes. - * @param {IProfitLossSheetNode} expenseNode - - * @param {IProfitLossSheetNode} node - - * @returns {IProfitLossSheetNode} - */ - private assocColumnPercentageHorizTotals = R.curry( - (netIncomeNode: IProfitLossSheetNode, node: IProfitLossSheetNode) => { - const horTotalsWithExpensePerc = this.assocPercentageHorizTotals( - 'percentageColumn', - netIncomeNode, - node - ); - return R.assoc('horizontalTotals', horTotalsWithExpensePerc, node); - } - ); - - /** - * - */ - private assocRowPercentageHorizTotals = R.curry((node) => { - const horTotalsWithExpensePerc = this.assocHorizontalPercentageTotals( - 'percentageRow', - node - ); - return R.assoc('horizontalTotals', horTotalsWithExpensePerc, node); - }); - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts deleted file mode 100644 index d8d0489d1..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousPeriod.ts +++ /dev/null @@ -1,395 +0,0 @@ -import * as R from 'ramda'; -import { sumBy } from 'lodash'; -import { - IProfitLossHorizontalDatePeriodNode, - IProfitLossSchemaNode, - IProfitLossSheetAccountNode, - IProfitLossSheetAccountsNode, - IProfitLossSheetEquationNode, - IProfitLossSheetNode, -} from '@/interfaces'; -import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; - -export const ProfitLossSheetPreviousPeriod = (Base) => - class extends R.compose(FinancialPreviousPeriod)(Base) { - query: ProfitLossSheetQuery; - - // --------------------------- - // # Account - // --------------------------- - /** - * Assoc previous period change attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected assocPreviousPeriodTotalAccountNode = ( - node: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - const total = this.repository.PPTotalAccountsLedger.whereAccountId( - node.id - ).getClosingBalance(); - - return R.assoc('previousPeriod', this.getAmountMeta(total), node); - }; - - /** - * Compose previous period account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected previousPeriodAccountNodeCompose = ( - accountNode: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousPeriodAccountHorizNodeCompose - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodChangeNode - ), - this.assocPreviousPeriodTotalAccountNode - )(accountNode); - }; - - // --------------------------- - // # Aggregate - // --------------------------- - /** - * Assoc previous period total attribute to aggregate node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - private assocPreviousPeriodTotalAggregateNode = ( - node: IProfitLossSheetAccountNode - ) => { - const total = sumBy(node.children, 'previousPeriod.amount'); - - return R.assoc('previousPeriod', this.getTotalAmountMeta(total), node); - }; - - /** - * Compose previous period to aggregate node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected previousPeriodAggregateNodeCompose = ( - accountNode: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousPeriodAggregateHorizNode - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - this.assocPreviousPeriodTotalAggregateNode - )(accountNode); - }; - - // --------------------------- - // # Equation - // -------------------------- - /** - * - * @param {(IProfitLossSchemaNode | IProfitLossSheetNode)[]} accNodes - * @param {string} equation - * @param {IProfitLossSheetNode} node - * @returns {IProfitLossSheetEquationNode} - */ - private assocPreviousPeriodTotalEquationNode = R.curry( - ( - accNodes: (IProfitLossSchemaNode | IProfitLossSheetNode)[], - equation: string, - node: IProfitLossSheetEquationNode - ): IProfitLossSheetEquationNode => { - const previousPeriodNodePath = 'previousPeriod.amount'; - const tableNodes = this.getNodesTableForEvaluating( - previousPeriodNodePath, - accNodes - ); - // Evaluate the given equation. - const total = this.evaluateEquation(equation, tableNodes); - - return R.assoc('previousPeriod', this.getTotalAmountMeta(total), node); - } - ); - - /** - * - * @param {(IProfitLossSchemaNode | IProfitLossSheetNode)[]} accNodes - - * @param {string} node - * @param {IProfitLossSheetEquationNode} node - * @returns {IProfitLossSheetEquationNode} - */ - protected previousPeriodEquationNodeCompose = R.curry( - ( - accNodes: (IProfitLossSchemaNode | IProfitLossSheetNode)[], - equation: string, - node: IProfitLossSheetEquationNode - ): IProfitLossSheetEquationNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousPeriodEquationHorizNode(accNodes, equation) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - this.assocPreviousPeriodTotalEquationNode(accNodes, equation) - )(node); - } - ); - - // --------------------------- - // # Horizontal Nodes - Account - // -------------------------- - /** - * Assoc previous period to account horizontal node. - * @param {IProfitLossSheetAccountNode} node - * @param {IProfitLossHorizontalDatePeriodNode} totalNode - * @returns {IProfitLossHorizontalDatePeriodNode} - */ - private assocPerviousPeriodAccountHorizTotal = R.curry( - ( - node: IProfitLossSheetAccountNode, - totalNode: IProfitLossHorizontalDatePeriodNode - ): IProfitLossHorizontalDatePeriodNode => { - const total = this.repository.PPPeriodsAccountsLedger.whereAccountId( - node.id - ) - .whereFromDate(totalNode.previousPeriodFromDate.date) - .whereToDate(totalNode.previousPeriodToDate.date) - .getClosingBalance(); - - return R.assoc('previousPeriod', this.getAmountMeta(total), totalNode); - } - ); - - /** - * @param {IProfitLossSheetAccountNode} node - * @param {IProfitLossSheetTotal} - */ - private previousPeriodAccountHorizNodeCompose = R.curry( - ( - node: IProfitLossSheetAccountNode, - horizontalTotalNode: IProfitLossHorizontalDatePeriodNode, - index: number - ): IProfitLossHorizontalDatePeriodNode => { - return R.compose( - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodChangeNode - ), - this.assocPerviousPeriodAccountHorizTotal(node), - this.assocPreviousPeriodHorizNodeFromToDates( - this.query.displayColumnsBy - ) - )(horizontalTotalNode); - } - ); - - /** - * - * @param {IProfitLossSheetAccountNode} node - * @returns {IProfitLossSheetAccountNode} - */ - private assocPreviousPeriodAccountHorizNodeCompose = ( - node: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousPeriodAccountHorizNodeCompose(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ---------------------------------- - // # Horizontal Nodes - Aggregate - // ---------------------------------- - /** - * Assoc previous period total to aggregate horizontal nodes. - * @param {IProfitLossSheetAccountsNode} node - * @param {number} index - * @param {any} totalNode - * @return {} - */ - private assocPreviousPeriodAggregateHorizTotal = R.curry( - ( - node: IProfitLossSheetAccountsNode, - index: number, - totalNode: IProfitLossHorizontalDatePeriodNode - ) => { - const total = this.getPPHorizNodesTotalSumation(index, node); - - return R.assoc( - 'previousPeriod', - this.getTotalAmountMeta(total), - totalNode - ); - } - ); - - /** - * - * @param {IProfitLossSheetAccountsNode} node - * @param {IProfitLossHorizontalDatePeriodNode} horizontalTotalNode - - * @param {number} index - * @returns {IProfitLossHorizontalDatePeriodNode} - */ - private previousPeriodAggregateHorizNodeCompose = R.curry( - ( - node: IProfitLossSheetAccountsNode, - horizontalTotalNode: IProfitLossHorizontalDatePeriodNode, - index: number - ): IProfitLossHorizontalDatePeriodNode => { - return R.compose( - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodAggregateHorizTotal(node, index) - ), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodHorizNodeFromToDates( - this.query.displayColumnsBy - ) - ) - )(horizontalTotalNode); - } - ); - - /** - * Assoc previous period to aggregate horizontal nodes. - * @param {IProfitLossSheetAccountsNode} node - * @returns - */ - private assocPreviousPeriodAggregateHorizNode = ( - node: IProfitLossSheetAccountsNode - ): IProfitLossSheetAccountsNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousPeriodAggregateHorizNodeCompose(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ---------------------------------- - // # Horizontal Nodes - Equation - // ---------------------------------- - /** - * - * @param {IProfitLossSheetNode[]} accNodes - - * @param {string} equation - * @param {index} number - * @param {} totalNode - */ - private assocPreviousPeriodEquationHorizTotal = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - index: number, - totalNode - ): IProfitLossSheetNode => { - const scopes = this.getNodesTableForEvaluating( - `horizontalTotals[${index}].previousPeriod.amount`, - accNodes - ); - const total = this.evaluateEquation(equation, scopes); - - return R.assoc( - 'previousPeriod', - this.getTotalAmountMeta(total), - totalNode - ); - } - ); - - /** - * - * @param {IProfitLossSheetNode[]} accNodes - - * @param {string} equation - * @param {} horizontalTotalNode - * @param {number} index - */ - private previousPeriodEquationHorizNodeCompose = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - horizontalTotalNode, - index: number - ) => { - const assocHorizTotal = this.assocPreviousPeriodEquationHorizTotal( - accNodes, - equation, - index - ); - return R.compose( - R.when( - this.query.isPreviousPeriodPercentageActive, - this.assocPreviousPeriodTotalPercentageNode - ), - R.when( - this.query.isPreviousPeriodChangeActive, - this.assocPreviousPeriodTotalChangeNode - ), - R.when(this.query.isPreviousPeriodActive, assocHorizTotal), - R.when( - this.query.isPreviousPeriodActive, - this.assocPreviousPeriodHorizNodeFromToDates( - this.query.displayColumnsBy - ) - ) - )(horizontalTotalNode); - } - ); - - /** - * Assoc previous period equation to horizontal nodes. - * @parma {IProfitLossSheetNode[]} accNodes - - * @param {string} equation - * @param {IProfitLossSheetEquationNode} node - * @return {IProfitLossSheetEquationNode} - */ - private assocPreviousPeriodEquationHorizNode = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - node: IProfitLossSheetEquationNode - ): IProfitLossSheetEquationNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousPeriodEquationHorizNodeCompose(accNodes, equation), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - } - ); - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousYear.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousYear.ts deleted file mode 100644 index 4695f3977..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetPreviousYear.ts +++ /dev/null @@ -1,367 +0,0 @@ -import * as R from 'ramda'; -import { sumBy } from 'lodash'; -import { compose } from 'lodash/fp'; -import { - IProfitLossSheetEquationNode, - IProfitLossSheetAccountNode, - IProfitLossSchemaNode, - IProfitLossSheetNode, - IProfitLossSheetTotal, -} from '@/interfaces'; -import { ProfitLossSheetRepository } from './ProfitLossSheetRepository'; -import { FinancialPreviousYear } from '../FinancialPreviousYear'; - -export const ProfitLossSheetPreviousYear = (Base) => - class extends compose(FinancialPreviousYear)(Base) { - repository: ProfitLossSheetRepository; - - // --------------------------- - // # Account - // --------------------------- - /** - * Assoc previous year total attribute to account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - private assocPreviousYearTotalAccountNode = ( - accountNode: IProfitLossSheetAccountNode - ) => { - const total = this.repository.PYTotalAccountsLedger.whereAccountId( - accountNode.id - ).getClosingBalance(); - - return R.assoc('previousYear', this.getAmountMeta(total), accountNode); - }; - - /** - * Compose previous year account node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected previousYearAccountNodeCompose = ( - accountNode: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousYearAccountHorizNodeCompose - ), - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearChangetNode - ), - this.assocPreviousYearTotalAccountNode - )(accountNode); - }; - - // --------------------------- - // # Aggregate - // --------------------------- - /** - * Assoc previous year change attribute to aggregate node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - private assocPreviousYearTotalAggregateNode = ( - node: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - const total = sumBy(node.children, 'previousYear.amount'); - - return R.assoc('previousYear', this.getTotalAmountMeta(total), node); - }; - - /** - * Compose previous year to aggregate node. - * @param {IProfitLossSheetAccountNode} accountNode - * @returns {IProfitLossSheetAccountNode} - */ - protected previousYearAggregateNodeCompose = ( - accountNode: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousYearAggregateHorizNode - ), - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - this.assocPreviousYearTotalAggregateNode - )(accountNode); - }; - - // --------------------------- - // # Equation - // --------------------------- - /** - * Assoc previous year total to equation node. - * @param {(IProfitLossSchemaNode | IProfitLossSheetNode)[]} accNodes - * @param {string} equation - * @param {IProfitLossSheetNode} node - * @returns {IProfitLossSheetEquationNode} - */ - private assocPreviousYearTotalEquationNode = R.curry( - ( - accNodes: (IProfitLossSchemaNode | IProfitLossSheetNode)[], - equation: string, - node: IProfitLossSheetNode - ) => { - const previousPeriodNodePath = 'previousYear.amount'; - const tableNodes = this.getNodesTableForEvaluating( - previousPeriodNodePath, - accNodes - ); - // Evaluate the given equation. - const total = this.evaluateEquation(equation, tableNodes); - - return R.assoc('previousYear', this.getTotalAmountMeta(total), node); - } - ); - - /** - * Previous year equation node. - * @param {(IProfitLossSchemaNode | IProfitLossSheetNode)[]} accNodes - - * @param {string} node - * @param {IProfitLossSheetEquationNode} node - * @returns {IProfitLossSheetEquationNode} - */ - protected previousYearEquationNodeCompose = R.curry( - ( - accNodes: (IProfitLossSchemaNode | IProfitLossSheetNode)[], - equation: string, - node: IProfitLossSheetEquationNode - ) => { - return R.compose( - R.when( - this.isNodeHasHorizTotals, - this.assocPreviousYearEquationHorizNode(accNodes, equation) - ), - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - this.assocPreviousYearTotalEquationNode(accNodes, equation) - )(node); - } - ); - - // ---------------------------------- - // # Horizontal Nodes - Account - // ---------------------------------- - /** - * Assoc preivous year to account horizontal total node. - * @param {IProfitLossSheetAccountNode} node - * @returns - */ - private assocPreviousYearAccountHorizTotal = R.curry( - (node: IProfitLossSheetAccountNode, totalNode) => { - const total = this.repository.PYPeriodsAccountsLedger.whereAccountId( - node.id - ) - .whereFromDate(totalNode.previousYearFromDate.date) - .whereToDate(totalNode.previousYearToDate.date) - .getClosingBalance(); - - return R.assoc('previousYear', this.getAmountMeta(total), totalNode); - } - ); - - /** - * Previous year account horizontal node composer. - * @param {IProfitLossSheetAccountNode} horizontalTotalNode - * @param {IProfitLossSheetTotal} horizontalTotalNode - - * @returns {IProfitLossSheetTotal} - */ - private previousYearAccountHorizNodeCompose = R.curry( - ( - node: IProfitLossSheetAccountNode, - horizontalTotalNode: IProfitLossSheetTotal - ): IProfitLossSheetTotal => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearChangetNode - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearAccountHorizTotal(node) - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearHorizNodeFromToDates - ) - )(horizontalTotalNode); - } - ); - - /** - * - * @param {IProfitLossSheetAccountNode} node - * @returns {IProfitLossSheetAccountNode} - */ - private assocPreviousYearAccountHorizNodeCompose = ( - node: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - const horizontalTotals = R.map( - this.previousYearAccountHorizNodeCompose(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ---------------------------------- - // # Horizontal Nodes - Aggregate - // ---------------------------------- - /** - * - */ - private assocPreviousYearAggregateHorizTotal = R.curry( - (node, index, totalNode) => { - const total = this.getPYHorizNodesTotalSumation(index, node); - - return R.assoc( - 'previousYear', - this.getTotalAmountMeta(total), - totalNode - ); - } - ); - - /** - * - */ - private previousYearAggregateHorizNodeCompose = R.curry( - (node, horizontalTotalNode, index: number) => { - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - R.when( - this.query.isPreviousYearActive, - this.assocPreviousYearAggregateHorizTotal(node, index) - ) - )(horizontalTotalNode); - } - ); - - /** - * - * @param {IProfitLossSheetAccountNode} node - * @returns {IProfitLossSheetAccountNode} - */ - private assocPreviousYearAggregateHorizNode = ( - node: IProfitLossSheetAccountNode - ): IProfitLossSheetAccountNode => { - const horizontalTotals = R.addIndex(R.map)( - this.previousYearAggregateHorizNodeCompose(node), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - }; - - // ---------------------------------- - // # Horizontal Nodes - Equation - // ---------------------------------- - /** - * - * @param {IProfitLossSheetNode[]} accNodes - - * @param {string} equation - * @param {number} index - * @param {} totalNode - - */ - private assocPreviousYearEquationHorizTotal = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - index: number, - totalNode - ) => { - const scopes = this.getNodesTableForEvaluating( - `horizontalTotals[${index}].previousYear.amount`, - accNodes - ); - const total = this.evaluateEquation(equation, scopes); - - return R.assoc( - 'previousYear', - this.getTotalAmountMeta(total), - totalNode - ); - } - ); - - /** - * - * @param {IProfitLossSheetNode[]} accNodes - - * @param {string} equation - * @param {} horizontalTotalNode - * @param {number} index - */ - private previousYearEquationHorizNodeCompose = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - horizontalTotalNode, - index: number - ) => { - const assocHorizTotal = this.assocPreviousYearEquationHorizTotal( - accNodes, - equation, - index - ); - return R.compose( - R.when( - this.query.isPreviousYearPercentageActive, - this.assocPreviousYearTotalPercentageNode - ), - R.when( - this.query.isPreviousYearChangeActive, - this.assocPreviousYearTotalChangeNode - ), - R.when(this.query.isPreviousYearActive, assocHorizTotal) - )(horizontalTotalNode); - } - ); - - /** - * - * @param {IProfitLossSheetNode[]} accNodes - * @param {string} equation - * @param {IProfitLossSheetEquationNode} node - */ - private assocPreviousYearEquationHorizNode = R.curry( - ( - accNodes: IProfitLossSheetNode[], - equation: string, - node: IProfitLossSheetEquationNode - ) => { - const horizontalTotals = R.addIndex(R.map)( - this.previousYearEquationHorizNodeCompose(accNodes, equation), - node.horizontalTotals - ); - return R.assoc('horizontalTotals', horizontalTotals, node); - } - ); - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetQuery.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetQuery.ts deleted file mode 100644 index e21e514bd..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetQuery.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { merge } from 'lodash'; -import * as R from 'ramda'; -import { IProfitLossSheetQuery, IFinancialDatePeriodsUnit } from '@/interfaces'; -import { DISPLAY_COLUMNS_BY } from './constants'; -import { FinancialDateRanges } from '../FinancialDateRanges'; - -export class ProfitLossSheetQuery extends R.compose(FinancialDateRanges)( - class {} -) { - /** - * P&L query. - * @param {IProfitLossSheetQuery} - */ - public readonly query: IProfitLossSheetQuery; - - /** - * Previous year to date. - * @param {Date} - */ - public readonly PYToDate: Date; - /** - * Previous year from date. - * @param {Date} - */ - public readonly PYFromDate: Date; - /** - * Previous period to date. - * @param {Date} - */ - public readonly PPToDate: Date; - /** - * Previous period from date. - * @param {Date} - */ - public readonly PPFromDate: Date; - - /** - * Constructor method. - * @param {IProfitLossSheetQuery} query - */ - constructor(query: IProfitLossSheetQuery) { - super(); - this.query = query; - - // Pervious Year (PY) Dates. - this.PYToDate = this.getPreviousYearDate(this.query.toDate); - this.PYFromDate = this.getPreviousYearDate(this.query.fromDate); - - // Previous Period (PP) Dates for total column.. - if (this.isTotalColumnType()) { - const { fromDate, toDate } = this.getPPTotalDateRange( - this.query.fromDate, - this.query.toDate - ); - this.PPToDate = toDate; - this.PPFromDate = fromDate; - - // Previous period (PP) dates for date periods columns type. - } else if (this.isDatePeriodsColumnsType()) { - const { fromDate, toDate } = this.getPPDatePeriodDateRange( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy as IFinancialDatePeriodsUnit - ); - this.PPToDate = toDate; - this.PPFromDate = fromDate; - } - return merge(this, query); - } - - /** - * Detarmines the given display columns type. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - public isDisplayColumnsBy = (displayColumnsBy: string): boolean => { - return this.query.displayColumnsBy === displayColumnsBy; - }; - - /** - * Detarmines the given display columns by type. - * @param {string} displayColumnsBy - * @returns {boolean} - */ - public isDisplayColumnsType = (displayColumnsType: string): boolean => { - return this.query.displayColumnsType === displayColumnsType; - }; - - /** - * Detarmines whether the columns type is date periods. - * @returns {boolean} - */ - public isDatePeriodsColumnsType = (): boolean => { - return this.isDisplayColumnsType(DISPLAY_COLUMNS_BY.DATE_PERIODS); - }; - - /** - * Detarmines whether the columns type is total. - * @returns {boolean} - */ - public isTotalColumnType = (): boolean => { - return this.isDisplayColumnsType(DISPLAY_COLUMNS_BY.TOTAL); - }; - - // -------------------------------------- - // # Previous Year (PY) - // -------------------------------------- - /** - * Detarmines the report query has previous year enabled. - * @returns {boolean} - */ - public isPreviousYearActive = (): boolean => { - return this.query.previousYear; - }; - - /** - * Detarmines the report query has previous year percentage change active. - * @returns {boolean} - */ - public isPreviousYearPercentageActive = (): boolean => { - return this.query.previousYearPercentageChange; - }; - - /** - * Detarmines the report query has previous year change active. - * @returns {boolean} - */ - public isPreviousYearChangeActive = (): boolean => { - return this.query.previousYearAmountChange; - }; - - /** - * Retrieves PY date based on the current query. - * @returns {Date} - */ - public getTotalPreviousYear = (): Date => { - return this.PYFromDate; - }; - - // -------------------------------------- - // # Previous Period (PP) - // -------------------------------------- - /** - * Detarmines the report query has previous period enabled. - * @returns {boolean} - */ - public isPreviousPeriodActive = (): boolean => { - return this.query.previousPeriod; - }; - - /** - * Detarmines the report query has previous period percentage change active. - * @returns {boolean} - */ - public isPreviousPeriodPercentageActive = (): boolean => { - return this.query.previousPeriodPercentageChange; - }; - - /** - * Detarmines the report query has previous period change active. - * @returns {boolean} - */ - public isPreviousPeriodChangeActive = (): boolean => { - return this.query.previousPeriodAmountChange; - }; - - /** - * Retrieves previous period date based on the current query. - * @returns {Date} - */ - public getTotalPreviousPeriod = (): Date => { - return this.PPFromDate; - }; - - // -------------------------------------- - // # Percentage vertical/horizontal. - // -------------------------------------- - /** - * Detarmines whether percentage of expenses is active. - * @returns {boolean} - */ - public isExpensesPercentage = (): boolean => { - return this.query.percentageExpense; - }; - - /** - * Detarmines whether percentage of income is active. - * @returns {boolean} - */ - public isIncomePercentage = (): boolean => { - return this.query.percentageIncome; - }; - - /** - * Detarmines whether percentage of column is active. - * @returns {boolean} - */ - public isColumnPercentage = (): boolean => { - return this.query.percentageColumn; - }; - - /** - * Detarmines whether percentage of row is active. - * @returns {boolean} - */ - public isRowPercentage = (): boolean => { - return this.query.percentageRow; - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetRepository.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetRepository.ts deleted file mode 100644 index f1bccba01..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetRepository.ts +++ /dev/null @@ -1,370 +0,0 @@ -import { castArray, defaultTo } from 'lodash'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { isEmpty } from 'lodash'; - -import { transformToMapBy } from 'utils'; -import { - IProfitLossSheetQuery, - IAccount, - IAccountTransactionsGroupBy, -} from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; - -export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)( - class {} -) { - /** - * - */ - public models: any; - - /** - * - */ - public accountsByType: any; - - /** - * @param {} - */ - public accounts: IAccount[]; - - /** - * - */ - public accountsGraph: any; - - /** - * Transactions group type. - * @param {IAccountTransactionsGroupBy} - */ - public transactionsGroupType: IAccountTransactionsGroupBy = - IAccountTransactionsGroupBy.Month; - - /** - * @param {IProfitLossSheetQuery} - */ - public query: ProfitLossSheetQuery; - - /** - * Previous year to date. - * @param {Date} - */ - public PYToDate: Date; - - /** - * Previous year from date. - * @param {Date} - */ - public PYFromDate: Date; - - /** - * Previous year to date. - * @param {Date} - */ - public PPToDate: Date; - - /** - * Previous year from date. - * @param {Date} - */ - public PPFromDate: Date; - - // ------------------------ - // # Total - // ------------------------ - /** - * Accounts total. - * @param {Ledger} - */ - public totalAccountsLedger: Ledger; - - // ------------------------ - // # Date Periods. - // ------------------------ - /** - * Accounts date periods. - * @param {Ledger} - */ - public periodsAccountsLedger: Ledger; - - // ------------------------ - // # Previous Year (PY) - // ------------------------ - /** - * @param {Ledger} - */ - public PYTotalAccountsLedger: Ledger; - - /** - * - * @param {Ledger} - */ - public PYPeriodsAccountsLedger: Ledger; - - // ------------------------ - // # Previous Period (PP). - // ------------------------ - /** - * PP Accounts Periods. - * @param {Ledger} - */ - public PPPeriodsAccountsLedger: Ledger; - - /** - * PP Accounts Total. - * @param {Ledger} - */ - public PPTotalAccountsLedger: Ledger; - - /** - * Constructor method. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - */ - constructor(models: any, query: IProfitLossSheetQuery) { - super(); - - this.models = models; - this.query = new ProfitLossSheetQuery(query); - - this.transactionsGroupType = this.getGroupByFromDisplayColumnsBy( - this.query.displayColumnsBy - ); - } - - /** - * Async report repository. - */ - public asyncInitialize = async () => { - await this.initAccounts(); - await this.initAccountsGraph(); - - await this.initAccountsTotalLedger(); - - // Date Periods. - if (this.query.isDatePeriodsColumnsType()) { - await this.initTotalDatePeriods(); - } - // Previous Period (PP) - if (this.query.isPreviousPeriodActive()) { - await this.initTotalPreviousPeriod(); - } - if ( - this.query.isPreviousPeriodActive() && - this.query.isDatePeriodsColumnsType() - ) { - await this.initPeriodsPreviousPeriod(); - } - // Previous Year (PY). - if (this.query.isPreviousYearActive()) { - await this.initTotalPreviousYear(); - } - if ( - this.query.isPreviousYearActive() && - this.query.isDatePeriodsColumnsType() - ) { - await this.initPeriodsPreviousYear(); - } - }; - - // ---------------------------- - // # Accounts - // ---------------------------- - /** - * Initialize accounts of the report. - */ - private initAccounts = async () => { - const accounts = await this.getAccounts(); - - // Inject to the repository. - this.accounts = accounts; - this.accountsByType = transformToMapBy(accounts, 'accountType'); - }; - - /** - * Initialize accounts graph. - */ - private initAccountsGraph = async () => { - const { Account } = this.models; - - this.accountsGraph = Account.toDependencyGraph(this.accounts); - }; - - // ---------------------------- - // # Closing Total. - // ---------------------------- - /** - * Initialize accounts closing total based on the given query. - */ - private initAccountsTotalLedger = async (): Promise => { - const totalByAccount = await this.accountsTotal( - this.query.fromDate, - this.query.toDate - ); - // Inject to the repository. - this.totalAccountsLedger = Ledger.fromTransactions(totalByAccount); - }; - - // ---------------------------- - // # Date periods. - // ---------------------------- - /** - * Initialize date periods total of accounts based on the given query. - */ - private initTotalDatePeriods = async (): Promise => { - // Retrieves grouped transactions by given date group. - const periodsByAccount = await this.accountsDatePeriods( - this.query.fromDate, - this.query.toDate, - this.transactionsGroupType - ); - - // Inject to the repository. - this.periodsAccountsLedger = Ledger.fromTransactions(periodsByAccount); - }; - - // ---------------------------- - // # Previous Period (PP). - // ---------------------------- - /** - * Initialize total of previous period (PP). - */ - private initTotalPreviousPeriod = async (): Promise => { - const PPTotalsByAccounts = await this.accountsTotal( - this.query.PPFromDate, - this.query.PPToDate - ); - // Inject to the repository. - this.PPTotalAccountsLedger = Ledger.fromTransactions(PPTotalsByAccounts); - }; - - /** - * Initialize date periods of previous period (PP). - */ - private initPeriodsPreviousPeriod = async (): Promise => { - // Retrieves grouped transactions by given date group. - const periodsByAccount = await this.accountsDatePeriods( - this.query.PPFromDate, - this.query.PPToDate, - this.transactionsGroupType - ); - // Inject to the repository. - this.PPPeriodsAccountsLedger = Ledger.fromTransactions(periodsByAccount); - }; - - // ---------------------------- - // # Previous Year (PY). - // ---------------------------- - /** - * Initialize total of previous year (PY). - */ - private initTotalPreviousYear = async (): Promise => { - const PYTotalsByAccounts = await this.accountsTotal( - this.query.PYFromDate, - this.query.PYToDate - ); - // Inject to the repository. - this.PYTotalAccountsLedger = Ledger.fromTransactions(PYTotalsByAccounts); - }; - - /** - * Initialize periods of previous year (PY). - */ - private initPeriodsPreviousYear = async () => { - // Retrieves grouped transactions by given date group. - const periodsByAccount = await this.accountsDatePeriods( - this.query.PYFromDate, - this.query.PYToDate, - this.transactionsGroupType - ); - // Inject to the repository. - this.PYPeriodsAccountsLedger = Ledger.fromTransactions(periodsByAccount); - }; - - // ---------------------------- - // # Utils - // ---------------------------- - /** - * Retrieve the opening balance transactions of the report. - */ - public accountsTotal = async (fromDate: Date, toDate: Date) => { - const { AccountTransaction } = this.models; - - return AccountTransaction.query().onBuild((query) => { - query.sum('credit as credit'); - query.sum('debit as debit'); - query.groupBy('accountId'); - query.select(['accountId']); - - query.modify('filterDateRange', fromDate, toDate); - query.withGraphFetched('account'); - - this.commonFilterBranchesQuery(query); - }); - }; - - /** - * Closing accounts date periods. - * @param openingDate - * @param datePeriodsType - * @returns - */ - public accountsDatePeriods = async ( - fromDate: Date, - toDate: Date, - datePeriodsType - ) => { - const { AccountTransaction } = this.models; - - return AccountTransaction.query().onBuild((query) => { - query.sum('credit as credit'); - query.sum('debit as debit'); - query.groupBy('accountId'); - query.select(['accountId']); - - query.modify('groupByDateFormat', datePeriodsType); - query.modify('filterDateRange', fromDate, toDate); - query.withGraphFetched('account'); - - this.commonFilterBranchesQuery(query); - }); - }; - - /** - * Common branches filter query. - * @param {Knex.QueryBuilder} query - */ - private commonFilterBranchesQuery = (query: Knex.QueryBuilder) => { - if (!isEmpty(this.query.branchesIds)) { - query.modify('filterByBranches', this.query.branchesIds); - } - }; - - /** - * Retrieve accounts of the report. - * @return {Promise} - */ - private getAccounts = () => { - const { Account } = this.models; - - return Account.query(); - }; - - /** - * - * @param type - * @returns - */ - public getAccountsByType = (type: string[] | string) => { - return R.compose( - R.flatten, - R.map((accountType) => - R.defaultTo([], this.accountsByType.get(accountType)) - ), - castArray - )(type); - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetService.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetService.ts deleted file mode 100644 index edfb627f6..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetService.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IProfitLossSheetQuery, - IProfitLossSheetMeta, - IProfitLossSheetNode, -} from '@/interfaces'; -import ProfitLossSheet from './ProfitLossSheet'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { Tenant } from '@/system/models'; -import { mergeQueryWithDefaults } from './utils'; -import { ProfitLossSheetRepository } from './ProfitLossSheetRepository'; -import { ProfitLossSheetMeta } from './ProfitLossSheetMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -// Profit/Loss sheet service. -@Service() -export default class ProfitLossSheetService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private profitLossSheetMeta: ProfitLossSheetMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve profit/loss sheet statement. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} query - * @return { } - */ - public profitLossSheet = async ( - tenantId: number, - query: IProfitLossSheetQuery - ): Promise<{ - data: IProfitLossSheetNode[]; - query: IProfitLossSheetQuery; - meta: IProfitLossSheetMeta; - }> => { - const models = this.tenancy.models(tenantId); - const i18n = this.tenancy.i18n(tenantId); - - // Merges the given query with default filter query. - const filter = mergeQueryWithDefaults(query); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const profitLossRepo = new ProfitLossSheetRepository(models, filter); - - // Loads the profit/loss sheet data. - await profitLossRepo.asyncInitialize(); - - // Profit/Loss report instance. - const profitLossInstance = new ProfitLossSheet( - profitLossRepo, - filter, - tenant.metadata.baseCurrency, - i18n - ); - // Profit/loss report data and collumns. - const data = profitLossInstance.reportData(); - - // Retrieve the profit/loss sheet meta. - const meta = await this.profitLossSheetMeta.meta(tenantId, filter); - - // Triggers `onProfitLossSheetViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onProfitLossSheetViewed, - { - tenantId, - query, - } - ); - - return { - query: filter, - data, - meta, - }; - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.ts deleted file mode 100644 index 84694b2dc..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.ts +++ /dev/null @@ -1,233 +0,0 @@ -import * as R from 'ramda'; -import { - IProfitLossSheetQuery, - ITableColumn, - IProfitLossSheetAccountsNode, - ITableColumnAccessor, - ITableRow, - ProfitLossNodeType, - ProfitLossSheetRowType, - IProfitLossSheetNode, - IProfitLossSheetEquationNode, - IProfitLossSheetAccountNode, -} from '@/interfaces'; -import { tableRowMapper } from 'utils'; -import { FinancialTable } from '../FinancialTable'; -import { ProfitLossSheetBase } from './ProfitLossSheetBase'; -import { ProfitLossSheetTablePercentage } from './ProfitLossSheetTablePercentage'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; -import { ProfitLossTablePreviousPeriod } from './ProfitLossTablePreviousPeriod'; -import { ProfitLossTablePreviousYear } from './ProfitLossTablePreviousYear'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { ProfitLossSheetTableDatePeriods } from './ProfitLossSheetTableDatePeriods'; - -export class ProfitLossSheetTable extends R.compose( - ProfitLossTablePreviousPeriod, - ProfitLossTablePreviousYear, - ProfitLossSheetTablePercentage, - ProfitLossSheetTableDatePeriods, - ProfitLossSheetBase, - FinancialSheetStructure, - FinancialTable -)(class {}) { - readonly query: ProfitLossSheetQuery; - - /** - * Constructor method. - * @param {} date - * @param {IProfitLossSheetQuery} query - */ - constructor(data: any, query: IProfitLossSheetQuery, i18n: any) { - super(); - - this.query = new ProfitLossSheetQuery(query); - this.reportData = data; - this.i18n = i18n; - } - - // ---------------------------------- - // # Rows - // ---------------------------------- - /** - * Retrieve the total column accessor. - * @return {ITableColumnAccessor[]} - */ - private totalColumnAccessor = (): ITableColumnAccessor[] => { - return R.pipe( - R.when( - this.query.isPreviousPeriodActive, - R.concat(this.previousPeriodColumnAccessor()) - ), - R.when( - this.query.isPreviousYearActive, - R.concat(this.previousYearColumnAccessor()) - ), - R.concat(this.percentageColumnsAccessor()), - R.concat([{ key: 'total', accessor: 'total.formattedAmount' }]) - )([]); - }; - - /** - * Common columns accessors. - * @returns {ITableColumnAccessor} - */ - private commonColumnsAccessors = (): ITableColumnAccessor[] => { - return R.compose( - R.concat([{ key: 'name', accessor: 'name' }]), - R.ifElse( - this.query.isDatePeriodsColumnsType, - R.concat(this.datePeriodsColumnsAccessors()), - R.concat(this.totalColumnAccessor()) - ) - )([]); - }; - - /** - * - * @param {IProfitLossSheetAccountNode} node - * @returns {ITableRow} - */ - private accountNodeToTableRow = ( - node: IProfitLossSheetAccountNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [ProfitLossSheetRowType.ACCOUNT], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * - * @param {IProfitLossSheetAccountsNode} node - * @returns {ITableRow} - */ - private accountsNodeToTableRow = ( - node: IProfitLossSheetAccountsNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [ProfitLossSheetRowType.ACCOUNTS], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * - * @param {IProfitLossSheetEquationNode} node - * @returns {ITableRow} - */ - private equationNodeToTableRow = ( - node: IProfitLossSheetEquationNode - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - - const meta = { - rowTypes: [ProfitLossSheetRowType.TOTAL], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * - * @param {IProfitLossSheetNode} node - * @returns {ITableRow} - */ - private nodeToTableRowCompose = (node: IProfitLossSheetNode): ITableRow => { - return R.cond([ - [ - this.isNodeType(ProfitLossNodeType.ACCOUNTS), - this.accountsNodeToTableRow, - ], - [ - this.isNodeType(ProfitLossNodeType.EQUATION), - this.equationNodeToTableRow, - ], - [this.isNodeType(ProfitLossNodeType.ACCOUNT), this.accountNodeToTableRow], - ])(node); - }; - - /** - * - * @param {IProfitLossSheetNode[]} nodes - * @returns {ITableRow} - */ - private nodesToTableRowsCompose = ( - nodes: IProfitLossSheetNode[] - ): ITableRow[] => { - return this.mapNodesDeep(nodes, this.nodeToTableRowCompose); - }; - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return R.compose( - this.addTotalRows, - this.nodesToTableRowsCompose - )(this.reportData); - }; - - // ---------------------------------- - // # Columns. - // ---------------------------------- - /** - * Retrieve total column children columns. - * @returns {ITableColumn[]} - */ - private tableColumnChildren = (): ITableColumn[] => { - return R.compose( - R.unless( - R.isEmpty, - R.concat([ - { key: 'total', label: this.i18n.__('profit_loss_sheet.total') }, - ]) - ), - R.concat(this.percentageColumns()), - R.when( - this.query.isPreviousYearActive, - R.concat(this.getPreviousYearColumns()) - ), - R.when( - this.query.isPreviousPeriodActive, - R.concat(this.getPreviousPeriodColumns()) - ) - )([]); - }; - - /** - * Retrieves the total column. - * @returns {ITableColumn[]} - */ - private totalColumn = (): ITableColumn[] => { - return [ - { - key: 'total', - label: this.i18n.__('profit_loss_sheet.total'), - children: this.tableColumnChildren(), - }, - ]; - }; - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return R.compose( - this.tableColumnsCellIndexing, - R.concat([ - { key: 'name', label: this.i18n.__('profit_loss_sheet.account_name') }, - ]), - R.ifElse( - this.query.isDatePeriodsColumnsType, - R.concat(this.datePeriodsColumns()), - R.concat(this.totalColumn()) - ) - )([]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts deleted file mode 100644 index ea7781f2e..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableDatePeriods.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as R from 'ramda'; -import moment from 'moment'; -import { ITableColumn, IDateRange, ITableColumnAccessor } from '@/interfaces'; -import { FinancialDatePeriods } from '../FinancialDatePeriods'; -import { ProfitLossSheetTablePercentage } from './ProfitLossSheetTablePercentage'; -import { ProfitLossTablePreviousPeriod } from './ProfitLossTablePreviousPeriod'; - -export const ProfitLossSheetTableDatePeriods = (Base) => - class extends R.compose( - ProfitLossSheetTablePercentage, - ProfitLossTablePreviousPeriod, - FinancialDatePeriods - )(Base) { - /** - * Retrieves the date periods based on the report query. - * @returns {IDateRange[]} - */ - get datePeriods() { - return this.getDateRanges( - this.query.fromDate, - this.query.toDate, - this.query.displayColumnsBy - ); - } - - // -------------------------------- - // # Accessors - // -------------------------------- - /** - * Date period columns accessor. - * @param {IDateRange} dateRange - - * @param {number} index - - */ - private datePeriodColumnsAccessor = R.curry( - (dateRange: IDateRange, index: number) => { - return R.pipe( - R.when( - this.query.isPreviousPeriodActive, - R.concat(this.previousPeriodHorizontalColumnAccessors(index)) - ), - R.when( - this.query.isPreviousYearActive, - R.concat(this.previousYearHorizontalColumnAccessors(index)) - ), - R.concat(this.percetangeHorizontalColumnsAccessor(index)), - R.concat([ - { - key: `date-range-${index}`, - accessor: `horizontalTotals[${index}].total.formattedAmount`, - }, - ]) - )([]); - } - ); - - /** - * Retrieve the date periods columns accessors. - * @returns {ITableColumnAccessor[]} - */ - protected datePeriodsColumnsAccessors = (): ITableColumnAccessor[] => { - return R.compose( - R.flatten, - R.addIndex(R.map)(this.datePeriodColumnsAccessor) - )(this.datePeriods); - }; - - // -------------------------------- - // # Columns - // -------------------------------- - /** - * Retrieve the formatted column label from the given date range. - * @param {ICashFlowDateRange} dateRange - - * @return {string} - */ - private formatColumnLabel = (dateRange) => { - const monthFormat = (range) => moment(range.toDate).format('YYYY-MM'); - const yearFormat = (range) => moment(range.toDate).format('YYYY'); - const dayFormat = (range) => moment(range.toDate).format('YYYY-MM-DD'); - - const conditions = [ - ['month', monthFormat], - ['year', yearFormat], - ['day', dayFormat], - ['quarter', monthFormat], - ['week', dayFormat], - ]; - const conditionsPairs = R.map( - ([type, formatFn]) => [ - R.always(this.query.isDisplayColumnsBy(type)), - formatFn, - ], - conditions - ); - return R.compose(R.cond(conditionsPairs))(dateRange); - }; - - /** - * - * @param {number} index - * @param {IDateRange} dateRange - * @returns {} - */ - private datePeriodChildrenColumns = ( - index: number, - dateRange: IDateRange - ) => { - return R.compose( - R.unless( - R.isEmpty, - R.concat([ - { key: `total`, label: this.i18n.__('profit_loss_sheet.total') }, - ]) - ), - R.concat(this.percentageColumns()), - R.when( - this.query.isPreviousYearActive, - R.concat(this.getPreviousYearDatePeriodColumnPlugin(dateRange)) - ), - R.when( - this.query.isPreviousPeriodActive, - R.concat(this.getPreviousPeriodDatePeriodsPlugin(dateRange)) - ) - )([]); - }; - - /** - * - * @param {IDateRange} dateRange - * @param {number} index - * @returns {ITableColumn} - */ - private datePeriodColumn = ( - dateRange: IDateRange, - index: number - ): ITableColumn => { - return { - key: `date-range-${index}`, - label: this.formatColumnLabel(dateRange), - children: this.datePeriodChildrenColumns(index, dateRange), - }; - }; - - /** - * Date periods columns. - * @returns {ITableColumn[]} - */ - protected datePeriodsColumns = (): ITableColumn[] => { - return this.datePeriods.map(this.datePeriodColumn); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableInjectable.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableInjectable.ts deleted file mode 100644 index 326e7aaef..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTableInjectable.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Inject, Service } from 'typedi'; -import ProfitLossSheetService from './ProfitLossSheetService'; -import { ProfitLossSheetTable } from './ProfitLossSheetTable'; -import { IProfitLossSheetQuery, IProfitLossSheetTable } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ProfitLossSheetTableInjectable { - @Inject() - private profitLossSheet: ProfitLossSheetService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the profit/loss sheet in table format. - * @param {number} tenantId - * @param {IProfitLossSheetQuery} filter - * @returns {Promise} - */ - public async table( - tenantId: number, - filter: IProfitLossSheetQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const { data, query, meta } = await this.profitLossSheet.profitLossSheet( - tenantId, - filter - ); - const table = new ProfitLossSheetTable(data, query, i18n); - - return { - table: { - rows: table.tableRows(), - columns: table.tableColumns(), - }, - query, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTablePercentage.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTablePercentage.ts deleted file mode 100644 index f2807ba36..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetTablePercentage.ts +++ /dev/null @@ -1,131 +0,0 @@ -import * as R from 'ramda'; -import { ITableColumn, ITableColumnAccessor } from '@/interfaces'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; - -export const ProfitLossSheetTablePercentage = (Base) => - class extends Base { - /** - * @param {ProfitLossSheetQuery} - */ - readonly query: ProfitLossSheetQuery; - - // ---------------------------------- - // # Columns. - // ---------------------------------- - /** - * Retrieve percentage of column/row columns. - * @returns {ITableColumn[]} - */ - protected percentageColumns = (): ITableColumn[] => { - return R.pipe( - R.when( - this.query.isIncomePercentage, - R.append({ - key: 'percentage_income', - label: this.i18n.__('profit_loss_sheet.percentage_of_income'), - }) - ), - R.when( - this.query.isExpensesPercentage, - R.append({ - key: 'percentage_expenses', - label: this.i18n.__('profit_loss_sheet.percentage_of_expenses'), - }) - ), - R.when( - this.query.isColumnPercentage, - R.append({ - key: 'percentage_column', - label: this.i18n.__('profit_loss_sheet.percentage_of_column'), - }) - ), - R.when( - this.query.isRowPercentage, - R.append({ - key: 'percentage_row', - label: this.i18n.__('profit_loss_sheet.percentage_of_row'), - }) - ) - )([]); - }; - - // ---------------------------------- - // # Accessors. - // ---------------------------------- - /** - * Retrieves percentage of column/row accessors. - * @returns {ITableColumn[]} - */ - protected percentageColumnsAccessor = (): ITableColumnAccessor[] => { - return R.pipe( - R.when( - this.query.isIncomePercentage, - R.append({ - key: 'percentage_income', - accessor: 'percentageIncome.formattedAmount', - }) - ), - R.when( - this.query.isExpensesPercentage, - R.append({ - key: 'percentage_expense', - accessor: 'percentageExpense.formattedAmount', - }) - ), - R.when( - this.query.isColumnPercentage, - R.append({ - key: 'percentage_column', - accessor: 'percentageColumn.formattedAmount', - }) - ), - R.when( - this.query.isRowPercentage, - R.append({ - key: 'percentage_row', - accessor: 'percentageRow.formattedAmount', - }) - ) - )([]); - }; - - /** - * Retrieves percentage horizontal columns accessors. - * @param {number} index - * @returns {ITableColumn[]} - */ - protected percetangeHorizontalColumnsAccessor = ( - index: number - ): ITableColumnAccessor[] => { - return R.pipe( - R.when( - this.query.isIncomePercentage, - R.append({ - key: `percentage_income-${index}`, - accessor: `horizontalTotals[${index}].percentageIncome.formattedAmount`, - }) - ), - R.when( - this.query.isExpensesPercentage, - R.append({ - key: `percentage_expense-${index}`, - accessor: `horizontalTotals[${index}].percentageExpense.formattedAmount`, - }) - ), - R.when( - this.query.isColumnPercentage, - R.append({ - key: `percentage_of_column-${index}`, - accessor: `horizontalTotals[${index}].percentageColumn.formattedAmount`, - }) - ), - R.when( - this.query.isRowPercentage, - R.append({ - key: `percentage_of_row-${index}`, - accessor: `horizontalTotals[${index}].percentageRow.formattedAmount`, - }) - ) - )([]); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts deleted file mode 100644 index 4b0ba23de..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IProfitLossSheetQuery } from '@/interfaces'; -import { ProfitLossSheetTableInjectable } from './ProfitLossSheetTableInjectable'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class ProfitLossTablePdfInjectable { - @Inject() - private profitLossTable: ProfitLossSheetTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Retrieves the profit/loss sheet in pdf format. - * @param {number} tenantId - * @param {number} query - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IProfitLossSheetQuery - ): Promise { - const table = await this.profitLossTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts deleted file mode 100644 index 98048b938..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousPeriod.ts +++ /dev/null @@ -1,93 +0,0 @@ -import * as R from 'ramda'; -import { IDateRange, ITableColumn, ITableColumnAccessor } from '@/interfaces'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; -import { FinancialTablePreviousPeriod } from '../FinancialTablePreviousPeriod'; - -export const ProfitLossTablePreviousPeriod = (Base) => - class extends R.compose(FinancialTablePreviousPeriod)(Base) { - query: ProfitLossSheetQuery; - - // ---------------------------- - // # Columns - // ---------------------------- - /** - * Retrieves pervious period comparison columns. - * @returns {ITableColumn[]} - */ - protected getPreviousPeriodColumns = ( - dateRange?: IDateRange - ): ITableColumn[] => { - return R.pipe( - // Previous period columns. - R.append(this.getPreviousPeriodTotalColumn(dateRange)), - R.when( - this.query.isPreviousPeriodChangeActive, - R.append(this.getPreviousPeriodChangeColumn()) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - R.append(this.getPreviousPeriodPercentageColumn()) - ) - )([]); - }; - - /** - * Compose the previous period for date periods columns. - * @params {IDateRange} - * @returns {ITableColumn[]} - */ - protected getPreviousPeriodDatePeriodsPlugin = ( - dateRange: IDateRange - ): ITableColumn[] => { - const PPDateRange = this.getPPDatePeriodDateRange( - dateRange.fromDate, - dateRange.toDate, - this.query.displayColumnsBy - ); - return this.getPreviousPeriodColumns(PPDateRange); - }; - - // ---------------------------- - // # Accessors - // ---------------------------- - /** - * Retrieves previous period columns accessors. - * @returns {ITableColumn[]} - */ - protected previousPeriodColumnAccessor = (): ITableColumnAccessor[] => { - return R.pipe( - // Previous period columns. - R.append(this.getPreviousPeriodTotalAccessor()), - R.when( - this.query.isPreviousPeriodChangeActive, - R.append(this.getPreviousPeriodChangeAccessor()) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - R.append(this.getPreviousPeriodPercentageAccessor()) - ) - )([]); - }; - - /** - * Previous period period column accessor. - * @param {number} index - * @returns {ITableColumn[]} - */ - protected previousPeriodHorizontalColumnAccessors = ( - index: number - ): ITableColumnAccessor[] => { - return R.pipe( - // Previous period columns. - R.append(this.getPreviousPeriodTotalHorizAccessor(index)), - R.when( - this.query.isPreviousPeriodChangeActive, - R.append(this.getPreviousPeriodChangeHorizAccessor(index)) - ), - R.when( - this.query.isPreviousPeriodPercentageActive, - R.append(this.getPreviousPeriodPercentageHorizAccessor(index)) - ) - )([]); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousYear.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousYear.ts deleted file mode 100644 index 27d3db311..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePreviousYear.ts +++ /dev/null @@ -1,107 +0,0 @@ -import * as R from 'ramda'; -import { IDateRange, ITableColumn, ITableColumnAccessor } from '@/interfaces'; -import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; -import { FinancialTablePreviousYear } from '../FinancialTablePreviousYear'; -import { FinancialDateRanges } from '../FinancialDateRanges'; - -export const ProfitLossTablePreviousYear = (Base) => - class extends R.compose( - FinancialTablePreviousYear, - FinancialDateRanges - )(Base) { - query: ProfitLossSheetQuery; - - // ------------------------------------ - // # Columns. - // ------------------------------------ - /** - * Retrieves pervious year comparison columns. - * @returns {ITableColumn[]} - */ - protected getPreviousYearColumns = ( - dateRange?: IDateRange - ): ITableColumn[] => { - return R.pipe( - // Previous year columns. - R.append(this.getPreviousYearTotalColumn(dateRange)), - R.when( - this.query.isPreviousYearChangeActive, - R.append(this.getPreviousYearChangeColumn()) - ), - R.when( - this.query.isPreviousYearPercentageActive, - R.append(this.getPreviousYearPercentageColumn()) - ) - )([]); - }; - - /** - * - * @param {IDateRange} dateRange - * @returns {ITableColumn[]} - */ - private previousYearDatePeriodColumnCompose = ( - dateRange: IDateRange - ): ITableColumn[] => { - const PYDateRange = this.getPreviousYearDateRange( - dateRange.fromDate, - dateRange.toDate - ); - return this.getPreviousYearColumns(PYDateRange); - }; - - /** - * Retrieves previous year date periods columns. - * @param {IDateRange} dateRange - * @returns {ITableColumn[]} - */ - protected getPreviousYearDatePeriodColumnPlugin = ( - dateRange: IDateRange - ): ITableColumn[] => { - return this.previousYearDatePeriodColumnCompose(dateRange); - }; - - // --------------------------------------------------- - // # Accessors. - // --------------------------------------------------- - /** - * Retrieves previous year columns accessors. - * @returns {ITableColumnAccessor[]} - */ - protected previousYearColumnAccessor = (): ITableColumnAccessor[] => { - return R.pipe( - // Previous year columns. - R.append(this.getPreviousYearTotalAccessor()), - R.when( - this.query.isPreviousYearChangeActive, - R.append(this.getPreviousYearChangeAccessor()) - ), - R.when( - this.query.isPreviousYearPercentageActive, - R.append(this.getPreviousYearPercentageAccessor()) - ) - )([]); - }; - - /** - * Previous year period column accessor. - * @param {number} index - * @returns {ITableColumn[]} - */ - protected previousYearHorizontalColumnAccessors = ( - index: number - ): ITableColumnAccessor[] => { - return R.pipe( - // Previous year columns. - R.append(this.getPreviousYearTotalHorizAccessor(index)), - R.when( - this.query.isPreviousYearChangeActive, - R.append(this.getPreviousYearChangeHorizAccessor(index)) - ), - R.when( - this.query.isPreviousYearPercentageActive, - R.append(this.getPreviousYearPercentageHorizAccessor(index)) - ) - )([]); - }; - }; diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/constants.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/constants.ts deleted file mode 100644 index 1ca50c5ed..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/constants.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ProfitLossNodeType } from '@/interfaces'; - -export const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' }; - -export const DISPLAY_COLUMNS_BY = { - DATE_PERIODS: 'date_periods', - TOTAL: 'total', -}; - -export enum IROW_TYPE { - AGGREGATE = 'AGGREGATE', - ACCOUNTS = 'ACCOUNTS', - ACCOUNT = 'ACCOUNT', - TOTAL = 'TOTAL', -} - -export const TOTAL_NODE_TYPES = [ - ProfitLossNodeType.ACCOUNTS, - ProfitLossNodeType.AGGREGATE, - ProfitLossNodeType.EQUATION -]; - -export const HtmlTableCustomCss =` -table tr.row-type--total td { - font-weight: 600; - border-top: 1px solid #bbb; - color: #000; -} -table tr.row-id--net-income td{ - border-bottom: 3px double #000; -} -table .column--name, -table .cell--name { - width: 400px; -} - -table .column--total { - width: 25%; -} -table td.cell--total, -table td.cell--previous_year, -table td.cell--previous_year_change, -table td.cell--previous_year_percentage, - -table td.cell--previous_period, -table td.cell--previous_period_change, -table td.cell--previous_period_percentage, - -table td.cell--percentage_of_row, -table td.cell--percentage_of_column, -table td[class*="cell--date-range"] { - text-align: right; -} - -table .column--total, -table .column--previous_year, -table .column--previous_year_change, -table .column--previous_year_percentage, - -table .column--previous_period, -table .column--previous_period_change, -table .column--previous_period_percentage, - -table .column--percentage_of_row, -table .column--percentage_of_column, -table [class*="column--date-range"] { - text-align: right; -} -`; \ No newline at end of file diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/utils.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/utils.ts deleted file mode 100644 index 85663a0b8..000000000 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/utils.ts +++ /dev/null @@ -1,54 +0,0 @@ -import moment from 'moment'; -import { merge } from 'lodash'; -import { IProfitLossSheetQuery } from '@/interfaces'; - -/** - * Default sheet filter query. - * @return {IBalanceSheetQuery} - */ -export const getDefaultPLQuery = (): IProfitLossSheetQuery => ({ - fromDate: moment().startOf('year').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - - numberFormat: { - divideOn1000: false, - negativeFormat: 'mines', - showZero: false, - formatMoney: 'total', - precision: 2, - }, - basis: 'accrual', - - noneZero: false, - noneTransactions: false, - - displayColumnsType: 'total', - displayColumnsBy: 'month', - - accountsIds: [], - - percentageColumn: false, - percentageRow: false, - - percentageIncome: false, - percentageExpense: false, - - previousPeriod: false, - previousPeriodAmountChange: false, - previousPeriodPercentageChange: false, - - previousYear: false, - previousYearAmountChange: false, - previousYearPercentageChange: false, -}); - -/** - * - * @param query - * @returns - */ -export const mergeQueryWithDefaults = ( - query: IProfitLossSheetQuery -): IProfitLossSheetQuery => { - return merge(getDefaultPLQuery(), query); -}; diff --git a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummary.ts b/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummary.ts deleted file mode 100644 index 22960c52e..000000000 --- a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummary.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { sumBy } from 'lodash'; -import { map } from 'lodash/fp'; -import { - IProjectProfitabilitySummaryProjectNode, - IProjectProfitabilitySummaryTotal, -} from '@/interfaces'; -import Project from 'models/Project'; -import { ProjectProfitabilitySummaryRespository } from './ProjectProfitabilitySummaryRepository'; -import FinancialSheet from '../FinancialSheet'; - -export class ProfitProfitabilitySummary extends FinancialSheet { - private readonly repository: ProjectProfitabilitySummaryRespository; - private readonly baseCurrency: string; - - /** - * Constructor method. - * @param {ProjectProfitabilitySummaryRespository} repository - * @param {string} baseCurrency - */ - constructor( - repository: ProjectProfitabilitySummaryRespository, - baseCurrency: string - ) { - super(); - - this.repository = repository; - this.baseCurrency = baseCurrency; - } - - /** - * Retrieves the project income node. - * @param {number} projectId - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectIncomeNode = ( - projectId: number - ): IProjectProfitabilitySummaryTotal => { - const amount = this.repository.incomeLedger - .whereProject(projectId) - .getClosingBalance(); - - const formattedAmount = this.formatNumber(amount); - - return { - amount, - formattedAmount, - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieves the project expense node. - * @param {number} projectId - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectExpenseNode = ( - projectId: number - ): IProjectProfitabilitySummaryTotal => { - const amount = this.repository.expenseLedger - .whereProject(projectId) - .getClosingBalance(); - - const formattedAmount = this.formatNumber(amount); - - return { - amount, - formattedAmount, - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieves the project profit total node. - * @param {number} projectId - Project id. - * @returns {number} - */ - private getProjectProfitTotal = (projectId: number): number => { - const incomeTotal = this.repository.incomeLedger - .whereProject(projectId) - .getClosingBalance(); - - const expenseTotal = this.repository.expenseLedger - .whereProject(projectId) - .getClosingBalance(); - - return incomeTotal - expenseTotal; - }; - - /** - * Retrieves the project profit node. - * @param {number} projectId - Project id. - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectProfitNode = ( - projectId: number - ): IProjectProfitabilitySummaryTotal => { - const amount = this.getProjectProfitTotal(projectId); - const formattedAmount = this.formatNumber(amount); - - return { - amount, - formattedAmount, - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieves the project node. - * @param {Project} project - * @returns {IProjectProfitabilitySummaryProjectNode} - */ - private getProjectNode = ( - project: Project - ): IProjectProfitabilitySummaryProjectNode => { - return { - projectId: project.id, - projectName: project.name, - projectStatus: 1, - - customerName: project.contact.displayName, - customerId: project.contact.id, - - profit: this.getProjectProfitNode(project.id), - income: this.getProjectIncomeNode(project.id), - expenses: this.getProjectExpenseNode(project.id), - }; - }; - - /** - * Retrieves the projects nodes. - * @returns {IProjectProfitabilitySummaryProjectNode[]} - */ - private getProjectsNode = (): IProjectProfitabilitySummaryProjectNode[] => { - return map(this.getProjectNode)(this.repository.projects); - }; - - /** - * Retrieves the all projects total income node. - * @param {IProjectProfitabilitySummaryProjectNode[]} projects - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectsTotalIncomeNode = ( - projects: IProjectProfitabilitySummaryProjectNode[] - ): IProjectProfitabilitySummaryTotal => { - const amount = sumBy(projects, 'income.amount'); - const formattedAmount = this.formatTotalNumber(amount); - - return { - amount, - formattedAmount, - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieves the all projects expenses total node. - * @param {IProjectProfitabilitySummaryProjectNode[]} projects - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectsTotalExpensesNode = ( - projects: IProjectProfitabilitySummaryProjectNode[] - ): IProjectProfitabilitySummaryTotal => { - const amount = sumBy(projects, 'expenses.amount'); - const formattedAmount = this.formatTotalNumber(amount); - - return { - amount, - formattedAmount, - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retreives the all projects profit total node. - * @param {IProjectProfitabilitySummaryProjectNode[]} projects - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectsTotalProfitNode = ( - projects: IProjectProfitabilitySummaryProjectNode[] - ) => { - const amount = sumBy(projects, 'profit.amount'); - const formattedAmount = this.formatTotalNumber(amount); - - return { - amount, - formattedAmount, - currencyCode: this.baseCurrency, - }; - }; - - /** - * Retrieves the all projects total node. - * @param {IProjectProfitabilitySummaryProjectNode[]} projects - * @returns {IProjectProfitabilitySummaryTotal} - */ - private getProjectsTotalNode = ( - projects: IProjectProfitabilitySummaryProjectNode[] - ) => { - const income = this.getProjectsTotalIncomeNode(projects); - const expenses = this.getProjectsTotalExpensesNode(projects); - const profit = this.getProjectsTotalProfitNode(projects); - - return { income, expenses, profit }; - }; - - /** - * Retrieves the report data. - * @returns {IProjectProfitabilitySummaryTotal} - */ - public getReportData = () => { - const projects = this.getProjectsNode(); - const total = this.getProjectsTotalNode(projects); - - return { projects, total }; - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryRepository.ts b/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryRepository.ts deleted file mode 100644 index 463574a27..000000000 --- a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryRepository.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { ACCOUNT_NORMAL, ACCOUNT_ROOT_TYPE } from '@/data/AccountTypes'; -import { IAccount, ProjectProfitabilitySummaryQuery } from '@/interfaces'; -import { isEmpty, map } from 'lodash'; -import Project from 'models/Project'; -import Ledger from '@/services/Accounting/Ledger'; - -export class ProjectProfitabilitySummaryRespository { - /** - * Tenant models. - */ - private readonly models; - - /** - * The report query. - * @param {ProjectProfitabilitySummaryQuery} - */ - private readonly query: ProjectProfitabilitySummaryQuery; - - /** - * - * @param {Project[]} - */ - public projects: Project[]; - - /** - * Income ledger grouped by projects. - * @param {Ledger} - */ - public incomeLedger: Ledger; - - /** - * Expenses ledger grouped by projects. - * @param {Ledger} - */ - public expenseLedger: Ledger; - - /** - * - * @param {Models} models - - * @param {ProjectProfitabilitySummaryQuery} query - - */ - constructor(models: any, query: ProjectProfitabilitySummaryQuery) { - this.query = query; - this.models = models; - } - - /** - * Async initialize all DB queries. - */ - public asyncInitialize = async () => { - await this.initProjects(); - - const incomeEntries = await this.getIncomeAccountsGroupedEntries(); - const expenseEntries = await this.getExpenseAccountsGroupedEntries(); - - this.incomeLedger = Ledger.fromTransactions(incomeEntries); - this.expenseLedger = Ledger.fromTransactions(expenseEntries); - }; - - /** - * Initialize projects. - */ - public initProjects = async () => { - const { Project } = this.models; - - const projects = await Project.query().onBuild((query) => { - if (this.query.projectsIds) { - query.whereIn('id', this.query.projectsIds); - } - query.withGraphFetched('contact'); - }); - this.projects = projects; - }; - - /** - * Retrieves the sumation of grouped entries by account and project id. - * @param {number[]} accountsIds - * @param {string} accountNormal - - * @returns {} - */ - public getAccountsGroupedEntries = async (accountsIds: number[]) => { - const { AccountTransaction } = this.models; - - return AccountTransaction.query().onBuild((query) => { - query.sum('credit as credit'); - query.sum('debit as debit'); - query.select(['accountId', 'projectId']); - - query.groupBy('accountId'); - query.groupBy('projectId'); - - query.whereNotNull('projectId'); - query.withGraphFetched('account'); - - query.whereIn('accountId', accountsIds); - - if (!isEmpty(this.query.projectsIds)) { - query.modify('filterByProjects', this.query.projectsIds); - } - }); - }; - - /** - * Retrieves all income accounts. - * @returns {IAccount} - */ - public getIncomeAccounts = () => { - const { Account } = this.models; - - return Account.query().modify('filterByRootType', ACCOUNT_ROOT_TYPE.INCOME); - }; - - /** - * Retrieves all expenses accounts. - * @returns - */ - public getExpensesAccounts = () => { - const { Account } = this.models; - - return Account.query().modify( - 'filterByRootType', - ACCOUNT_ROOT_TYPE.EXPENSE - ); - }; - - /** - * Retrieves the sumation of grouped entries by income accounts and projects. - * @returns {} - */ - public getIncomeAccountsGroupedEntries = async () => { - const incomeAccounts = await this.getIncomeAccounts(); - const incomeAccountsIds = map(incomeAccounts, 'id'); - - return this.getAccountsGroupedEntries(incomeAccountsIds); - }; - - /** - * Retrieves the sumation of grouped entries by expenses accounts and projects. - * @returns {} - */ - public getExpenseAccountsGroupedEntries = async () => { - const expenseAccounts = await this.getExpensesAccounts(); - const expenseAccountsIds = map(expenseAccounts, 'id'); - - return this.getAccountsGroupedEntries(expenseAccountsIds); - }; -} diff --git a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryService.ts b/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryService.ts deleted file mode 100644 index 59f8866bd..000000000 --- a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryService.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IProjectProfitabilitySummaryMeta, - IProjectProfitabilitySummaryPOJO, - ProjectProfitabilitySummaryQuery, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Tenant } from '@/system/models'; -import { ProfitProfitabilitySummary } from './ProjectProfitabilitySummary'; -import { ProjectProfitabilitySummaryRespository } from './ProjectProfitabilitySummaryRepository'; - -@Service() -export class ProjectProfitabilitySummaryService { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the project profitiability summary report. - * @param {number} tenantId - * @param {ProjectProfitabilitySummaryQuery} query - * @returns {Promise} - */ - public projectProfitabilitySummary = async ( - tenantId: number, - query: ProjectProfitabilitySummaryQuery - ): Promise => { - const models = this.tenancy.models(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Initialize the report repository. - const projectProfitabilityRepo = new ProjectProfitabilitySummaryRespository( - models, - query - ); - await projectProfitabilityRepo.asyncInitialize(); - - const projectProfitabilityInstance = new ProfitProfitabilitySummary( - projectProfitabilityRepo, - tenant.metadata.baseCurrency - ); - const projectProfitData = projectProfitabilityInstance.getReportData(); - - return { - data: projectProfitData, - query, - meta: this.reportMetadata(tenantId), - }; - }; - - /** - * Retrieve the balance sheet meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - private reportMetadata(tenantId: number): IProjectProfitabilitySummaryMeta { - const settings = this.tenancy.settings(tenantId); - - const organizationName = settings.get({ - group: 'organization', - key: 'name', - }); - const baseCurrency = settings.get({ - group: 'organization', - key: 'base_currency', - }); - - return { - organizationName, - baseCurrency, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryTable.ts b/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryTable.ts deleted file mode 100644 index 0cd1b96df..000000000 --- a/packages/server/src/services/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummaryTable.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { map } from 'lodash/fp'; -import * as R from 'ramda'; -import { - IProjectProfitabilitySummaryData, - IProjectProfitabilitySummaryProjectNode, - IProjectProfitabilitySummaryRowType, - IProjectProfitabilitySummaryTotalNode, - ITableColumn, - ITableRow, -} from '@/interfaces'; -import { tableRowMapper } from 'utils'; - -export class ProjectProfitabilitySummaryTable { - /** - * Holds the report data. - * @var {IProjectProfitabilitySummaryPOJO} - */ - private readonly reportData: IProjectProfitabilitySummaryData; - - /** - * Constructor method. - * @param {IProjectProfitabilitySummaryData} reportData - * @param {} i18n - */ - constructor( - reportData: IProjectProfitabilitySummaryData, - i18n: any - ) { - this.reportData = reportData; - this.i18n = i18n; - } - - // ---------------------------------- - // # ROWS. - // ---------------------------------- - /** - * Retrieves the project node table row. - * @param {IProjectProfitabilitySummaryProjectNode} node - * @returns {ITableRow} - */ - private projectNodeData = ( - node: IProjectProfitabilitySummaryProjectNode - ): ITableRow => { - const meta = { - rowTypes: [IProjectProfitabilitySummaryRowType.PROJECT], - }; - const columns = [ - { key: 'name', accessor: 'projectName' }, - { key: 'customer_name', accessor: 'customerName' }, - { key: 'income', accessor: 'income.formattedAmount' }, - { key: 'expenses', accessor: 'expenses.formattedAmount' }, - { key: 'profit', accessor: 'profit.formattedAmount' }, - ]; - return tableRowMapper(node, columns, meta); - }; - - /** - * Retrieves the projects nodes table rows. - * @param {IProjectProfitabilitySummaryProjectNode[]} nodes - * @returns {ITableRow[]} - */ - public projectsNodesData = ( - nodes: IProjectProfitabilitySummaryProjectNode[] - ): ITableRow[] => { - return map(this.projectNodeData)(nodes); - }; - - /** - * Retrieves the projects total table row. - * @param {IProjectProfitabilitySummaryTotal} totalNode - * @returns {ITableRow} - */ - public projectsTotalRow = ( - node: IProjectProfitabilitySummaryTotalNode - ): ITableRow => { - const meta = { - rowTypes: [IProjectProfitabilitySummaryRowType.TOTAL], - }; - const columns = [ - { key: 'name', value: '' }, - { key: 'customer_name', value: '' }, - { key: 'income', accessor: 'income.formattedAmount' }, - { key: 'expenses', accessor: 'expenses.formattedAmount' }, - { key: 'profit', accessor: 'profit.formattedAmount' }, - ]; - return tableRowMapper(node, columns, meta); - }; - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableData = (): ITableRow[] => { - return R.pipe( - R.concat(this.projectsNodesData(this.reportData.projects)), - R.append(this.projectsTotalRow(this.reportData.total)) - )([]); - }; - - // ---------------------------------- - // # Columns. - // ---------------------------------- - /** - * Retrievs the table columns - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return [ - { key: 'name', label: 'Project Name' }, - { key: 'customer_name', label: 'Customer Name' }, - { key: 'income', label: 'Income' }, - { key: 'expenses', label: 'Expenses' }, - { key: 'profit', label: 'Profit' }, - ]; - }; -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts deleted file mode 100644 index b679334c6..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { get, isEmpty, sumBy } from 'lodash'; -import * as R from 'ramda'; -import FinancialSheet from '../FinancialSheet'; -import { allPassedConditionsPass, transformToMap } from 'utils'; -import { IAccountTransaction, IItem } from '@/interfaces'; -import { - IPurchasesByItemsItem, - IPurchasesByItemsReportQuery, - IPurchasesByItemsSheetData, - IPurchasesByItemsTotal, -} from '@/interfaces/PurchasesByItemsSheet'; - -export class PurchasesByItems extends FinancialSheet { - readonly baseCurrency: string; - readonly items: IItem[]; - readonly itemsTransactions: Map; - readonly query: IPurchasesByItemsReportQuery; - - /** - * Constructor method. - * @param {IPurchasesByItemsReportQuery} query - * @param {IItem[]} items - * @param {IAccountTransaction[]} itemsTransactions - * @param {string} baseCurrency - */ - constructor( - query: IPurchasesByItemsReportQuery, - items: IItem[], - itemsTransactions: IAccountTransaction[], - baseCurrency: string - ) { - super(); - this.baseCurrency = baseCurrency; - this.items = items; - this.itemsTransactions = transformToMap(itemsTransactions, 'itemId'); - this.query = query; - this.numberFormat = this.query.numberFormat; - } - - /** - * Retrieve the item purchase item, cost and average cost price. - * @param {number} itemId - */ - getItemTransaction(itemId: number): { - quantity: number; - cost: number; - average: number; - } { - const transaction = this.itemsTransactions.get(itemId); - - const quantity = get(transaction, 'quantity', 0); - const cost = get(transaction, 'cost', 0); - - const average = cost / quantity; - - return { quantity, cost, average }; - } - - /** - * Detarmines whether the purchase node is active. - * @param {} node - * @returns {boolean} - */ - private filterPurchaseOnlyActive = (node) => { - return node.quantityPurchased !== 0 && node.purchaseCost !== 0; - }; - - /** - * Determines whether the purchase node is not none transactions. - * @param node - * @returns {boolean} - */ - private filterPurchaseNoneTransaction = (node) => { - const anyTransaction = this.itemsTransactions.get(node.id); - - return !isEmpty(anyTransaction); - }; - - /** - * Filters sales by items nodes based on the report query. - * @param {ISalesByItemsItem} saleItem - - * @return {boolean} - */ - private purchaseByItemFilter = (node): boolean => { - const { noneTransactions, onlyActive } = this.query; - - const conditions = [ - [noneTransactions, this.filterPurchaseNoneTransaction], - [onlyActive, this.filterPurchaseOnlyActive], - ]; - return allPassedConditionsPass(conditions)(node); - }; - - /** - * Mapping the given item section. - * @param {IInventoryValuationItem} item - * @returns - */ - private itemSectionMapper = (item: IItem): IPurchasesByItemsItem => { - const meta = this.getItemTransaction(item.id); - - return { - id: item.id, - name: item.name, - code: item.code, - quantityPurchased: meta.quantity, - purchaseCost: meta.cost, - averageCostPrice: meta.average, - quantityPurchasedFormatted: this.formatNumber(meta.quantity, { - money: false, - }), - purchaseCostFormatted: this.formatNumber(meta.cost), - averageCostPriceFormatted: this.formatNumber(meta.average), - currencyCode: this.baseCurrency, - }; - }; - - /** - * Detarmines whether the items post filter is active. - * @returns {boolean} - */ - private isItemsPostFilter = (): boolean => { - return isEmpty(this.query.itemsIds); - }; - - /** - * Filters purchase by items nodes. - * @param {} nodes - - * @returns - */ - private itemsFilter = (nodes) => { - return nodes.filter(this.purchaseByItemFilter); - }; - - /** - * Mappes purchase by items nodes. - * @param items - * @returns - */ - private itemsMapper = (items) => { - return items.map(this.itemSectionMapper); - }; - - /** - * Retrieve the items sections. - * @returns {IPurchasesByItemsItem[]} - */ - private itemsSection = (): IPurchasesByItemsItem[] => { - return R.compose( - R.when(this.isItemsPostFilter, this.itemsFilter), - this.itemsMapper - )(this.items); - }; - - /** - * Retrieve the total section of the sheet. - * @param {IPurchasesByItemsItem[]} items - * @returns {IPurchasesByItemsTotal} - */ - private totalSection(items: IPurchasesByItemsItem[]): IPurchasesByItemsTotal { - const quantityPurchased = sumBy(items, (item) => item.quantityPurchased); - const purchaseCost = sumBy(items, (item) => item.purchaseCost); - - return { - quantityPurchased, - purchaseCost, - quantityPurchasedFormatted: this.formatTotalNumber(quantityPurchased, { - money: false, - }), - purchaseCostFormatted: this.formatTotalNumber(purchaseCost), - currencyCode: this.baseCurrency, - }; - } - - /** - * Retrieve the sheet data. - * @returns {IInventoryValuationStatement} - */ - public reportData(): IPurchasesByItemsSheetData { - const items = this.itemsSection(); - const total = this.totalSection(items); - - return { items, total }; - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsApplication.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsApplication.ts deleted file mode 100644 index eeecaff38..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsApplication.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { PurchasesByItemsExport } from './PurchasesByItemsExport'; -import { - IPurchasesByItemsReportQuery, - IPurchasesByItemsSheet, - IPurchasesByItemsTable, -} from '@/interfaces/PurchasesByItemsSheet'; -import { PurchasesByItemsTableInjectable } from './PurchasesByItemsTableInjectable'; -import { PurchasesByItemsService } from './PurchasesByItemsService'; -import { PurchasesByItemsPdf } from './PurchasesByItemsPdf'; - -@Service() -export class PurcahsesByItemsApplication { - @Inject() - private purchasesByItemsSheet: PurchasesByItemsService; - - @Inject() - private purchasesByItemsTable: PurchasesByItemsTableInjectable; - - @Inject() - private purchasesByItemsExport: PurchasesByItemsExport; - - @Inject() - private purchasesByItemsPdf: PurchasesByItemsPdf; - - /** - * Retrieves the purchases by items in json format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @returns - */ - public sheet( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - return this.purchasesByItemsSheet.purchasesByItems(tenantId, query); - } - - /** - * Retrieves the purchases by items in table format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @returns {Promise} - */ - public table( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - return this.purchasesByItemsTable.table(tenantId, query); - } - - /** - * Retrieves the purchases by items in csv format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @returns {Promise} - */ - public csv( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - return this.purchasesByItemsExport.csv(tenantId, query); - } - - /** - * Retrieves the purchases by items in xlsx format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @returns {Promise} - */ - public xlsx( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - return this.purchasesByItemsExport.xlsx(tenantId, query); - } - - /** - * Retrieves the purchases by items in pdf format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} filter - * @returns {Promise} - */ - public pdf( - tenantId: number, - filter: IPurchasesByItemsReportQuery - ): Promise { - return this.purchasesByItemsPdf.pdf(tenantId, filter); - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsExport.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsExport.ts deleted file mode 100644 index 96ed4daf7..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsExport.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { PurchasesByItemsTableInjectable } from './PurchasesByItemsTableInjectable'; -import { IPurchasesByItemsReportQuery } from '@/interfaces/PurchasesByItemsSheet'; - -@Service() -export class PurchasesByItemsExport { - @Inject() - private purchasesByItemsTable: PurchasesByItemsTableInjectable; - - /** - * Retrieves the purchases by items sheet in XLSX format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - const table = await this.purchasesByItemsTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the purchases by items sheet in CSV format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - const table = await this.purchasesByItemsTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsMeta.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsMeta.ts deleted file mode 100644 index 4bb22c583..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsMeta.ts +++ /dev/null @@ -1,36 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { - IPurchasesByItemsReportQuery, - IPurchasesByItemsSheetMeta, -} from '@/interfaces/PurchasesByItemsSheet'; - -@Service() -export class PurchasesByItemsMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the purchases by items meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - return { - ...commonMeta, - sheetName: 'Purchases By Items', - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsPdf.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsPdf.ts deleted file mode 100644 index 67e3e7a24..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsPdf.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { PurchasesByItemsTableInjectable } from './PurchasesByItemsTableInjectable'; -import { IPurchasesByItemsReportQuery } from '@/interfaces/PurchasesByItemsSheet'; -import { HtmlTableCustomCss } from './_types'; - -@Service() -export class PurchasesByItemsPdf { - @Inject() - private purchasesByItemsTable: PurchasesByItemsTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given journal sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - const table = await this.purchasesByItemsTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsService.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsService.ts deleted file mode 100644 index 5def568cd..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsService.ts +++ /dev/null @@ -1,115 +0,0 @@ -import moment from 'moment'; -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { PurchasesByItems } from './PurchasesByItems'; -import { Tenant } from '@/system/models'; -import { - IPurchasesByItemsReportQuery, - IPurchasesByItemsSheet, -} from '@/interfaces/PurchasesByItemsSheet'; -import { PurchasesByItemsMeta } from './PurchasesByItemsMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class PurchasesByItemsService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private purchasesByItemsMeta: PurchasesByItemsMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults purchases by items filter query. - * @return {IPurchasesByItemsReportQuery} - */ - private get defaultQuery(): IPurchasesByItemsReportQuery { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - itemsIds: [], - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'always', - negativeFormat: 'mines', - }, - noneTransactions: true, - onlyActive: false, - }; - } - - /** - * Retrieve balance sheet statement. - * ------------- - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} query - * @return {Promise} - */ - public async purchasesByItems( - tenantId: number, - query: IPurchasesByItemsReportQuery - ): Promise { - const { Item, InventoryTransaction } = this.tenancy.models(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const inventoryItems = await Item.query().onBuild((q) => { - q.where('type', 'inventory'); - - if (filter.itemsIds.length > 0) { - q.whereIn('id', filter.itemsIds); - } - }); - const inventoryItemsIds = inventoryItems.map((item) => item.id); - - // Calculates the total inventory total quantity and rate `IN` transactions. - const inventoryTransactions = await InventoryTransaction.query().onBuild( - (builder: any) => { - builder.modify('itemsTotals'); - builder.modify('INDirection'); - - // Filter the inventory items only. - builder.whereIn('itemId', inventoryItemsIds); - - // Filter the date range of the sheet. - builder.modify('filterDateRange', filter.fromDate, filter.toDate); - } - ); - const purchasesByItemsInstance = new PurchasesByItems( - filter, - inventoryItems, - inventoryTransactions, - tenant.metadata.baseCurrency - ); - const purchasesByItemsData = purchasesByItemsInstance.reportData(); - - // Retrieve the purchases by items meta. - const meta = await this.purchasesByItemsMeta.meta(tenantId, query); - - // Triggers `onPurchasesByItemViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onPurchasesByItemViewed, - { - tenantId, - query, - } - ); - - return { - data: purchasesByItemsData, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.ts deleted file mode 100644 index a7b6ee735..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.ts +++ /dev/null @@ -1,111 +0,0 @@ -import * as R from 'ramda'; -import { ITableColumn, ITableColumnAccessor, ITableRow } from '@/interfaces'; -import { ROW_TYPE } from './_types'; -import { tableRowMapper } from '@/utils'; -import { FinancialTable } from '../FinancialTable'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import FinancialSheet from '../FinancialSheet'; -import { - IPurchasesByItemsItem, - IPurchasesByItemsSheetData, - IPurchasesByItemsTotal, -} from '@/interfaces/PurchasesByItemsSheet'; - -export class PurchasesByItemsTable extends R.compose( - FinancialTable, - FinancialSheetStructure -)(FinancialSheet) { - private data: IPurchasesByItemsSheetData; - - /** - * Constructor method. - * @param data - */ - constructor(data) { - super(); - this.data = data; - } - - /** - * Retrieves thge common table accessors. - * @returns {ITableColumnAccessor[]} - */ - private commonTableAccessors(): ITableColumnAccessor[] { - return [ - { key: 'item_name', accessor: 'name' }, - { key: 'quantity_purchases', accessor: 'quantityPurchasedFormatted' }, - { key: 'purchase_amount', accessor: 'purchaseCostFormatted' }, - { key: 'average_cost', accessor: 'averageCostPriceFormatted' }, - ]; - } - - /** - * Retrieves the common table columns. - * @returns {ITableColumn[]} - */ - private commonTableColumns(): ITableColumn[] { - return [ - { label: 'Item name', key: 'item_name' }, - { label: 'Quantity Purchased', key: 'quantity_purchases' }, - { label: 'Purchase Amount', key: 'purchase_amount' }, - { label: 'Average Price', key: 'average_cost' }, - ]; - } - - /** - * Maps the given item node to table row. - * @param {IPurchasesByItemsItem} item - * @returns {ITableRow} - */ - private itemMap = (item: IPurchasesByItemsItem): ITableRow => { - const columns = this.commonTableAccessors(); - const meta = { - rowTypes: [ROW_TYPE.ITEM], - }; - return tableRowMapper(item, columns, meta); - }; - - /** - * Maps the given items nodes to table rows. - * @param {IPurchasesByItemsItem[]} items - Items nodes. - * @returns {ITableRow[]} - */ - private itemsMap = (items: IPurchasesByItemsItem[]): ITableRow[] => { - return R.map(this.itemMap)(items); - }; - - /** - * Maps the given total node to table rows. - * @param {IPurchasesByItemsTotal} total - * @returns {ITableRow} - */ - private totalNodeMap = (total: IPurchasesByItemsTotal): ITableRow => { - const columns = this.commonTableAccessors(); - const meta = { - rowTypes: [ROW_TYPE.TOTAL], - }; - return tableRowMapper(total, columns, meta); - }; - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns(): ITableColumn[] { - const columns = this.commonTableColumns(); - return R.compose(this.tableColumnsCellIndexing)(columns); - } - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableData(): ITableRow[] { - const itemsRows = this.itemsMap(this.data.items); - const totalRow = this.totalNodeMap(this.data.total); - - return R.compose( - R.when(R.always(R.not(R.isEmpty(itemsRows))), R.append(totalRow)) - )(itemsRows) as ITableRow[]; - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTableInjectable.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTableInjectable.ts deleted file mode 100644 index 066ac6f72..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItemsTableInjectable.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { - IPurchasesByItemsReportQuery, - IPurchasesByItemsTable, -} from '@/interfaces/PurchasesByItemsSheet'; -import { Inject, Service } from 'typedi'; -import { PurchasesByItemsService } from './PurchasesByItemsService'; -import { PurchasesByItemsTable } from './PurchasesByItemsTable'; - -@Service() -export class PurchasesByItemsTableInjectable { - @Inject() - private purchasesByItemsSheet: PurchasesByItemsService; - - /** - * Retrieves the purchases by items table format. - * @param {number} tenantId - * @param {IPurchasesByItemsReportQuery} filter - * @returns {Promise} - */ - public async table( - tenantId: number, - filter: IPurchasesByItemsReportQuery - ): Promise { - const { data, query, meta } = - await this.purchasesByItemsSheet.purchasesByItems(tenantId, filter); - - const table = new PurchasesByItemsTable(data); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableData(), - }, - meta, - query, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/PurchasesByItems/_types.ts b/packages/server/src/services/FinancialStatements/PurchasesByItems/_types.ts deleted file mode 100644 index bb4927958..000000000 --- a/packages/server/src/services/FinancialStatements/PurchasesByItems/_types.ts +++ /dev/null @@ -1,23 +0,0 @@ -export enum ROW_TYPE { - TOTAL = 'TOTAL', - ITEM = 'ITEM', -} - -export const HtmlTableCustomCss = ` -table tr.row-type--total td { - border-top: 1px solid #bbb; - border-bottom: 3px double #000; - font-weight: 600; -} -table .column--item_name{ - width: 300px; -} -table .column--quantity_purchases, -table .column--purchase_amount, -table .column--average_cost, -table .cell--quantity_purchases, -table .cell--purchase_amount, -table .cell--average_cost{ - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts deleted file mode 100644 index 9d96febd5..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { get, sumBy } from 'lodash'; - -import * as R from 'ramda'; -import FinancialSheet from '../FinancialSheet'; -import { allPassedConditionsPass, transformToMap } from 'utils'; -import { - ISalesByItemsReportQuery, - IAccountTransaction, - ISalesByItemsItem, - ISalesByItemsTotal, - ISalesByItemsSheetData, - IItem, -} from '@/interfaces'; - -export default class SalesByItemsReport extends FinancialSheet { - readonly baseCurrency: string; - readonly items: IItem[]; - readonly itemsTransactions: Map; - readonly query: ISalesByItemsReportQuery; - - /** - * Constructor method. - * @param {ISalesByItemsReportQuery} query - * @param {IItem[]} items - * @param {IAccountTransaction[]} itemsTransactions - * @param {string} baseCurrency - */ - constructor( - query: ISalesByItemsReportQuery, - items: IItem[], - itemsTransactions: IAccountTransaction[], - baseCurrency: string - ) { - super(); - - this.baseCurrency = baseCurrency; - this.items = items; - this.itemsTransactions = transformToMap(itemsTransactions, 'itemId'); - this.query = query; - this.numberFormat = this.query.numberFormat; - } - - /** - * Retrieve the item purchase item, cost and average cost price. - * @param {number} itemId - Item id. - */ - getItemTransaction(itemId: number): { - quantity: number; - cost: number; - average: number; - } { - const transaction = this.itemsTransactions.get(itemId); - - const quantity = get(transaction, 'quantity', 0); - const cost = get(transaction, 'cost', 0); - - const average = cost / quantity; - - return { quantity, cost, average }; - } - - /** - * Mapping the given item section. - * @param {ISalesByItemsItem} item - * @returns - */ - private itemSectionMapper = (item: IItem): ISalesByItemsItem => { - const meta = this.getItemTransaction(item.id); - - return { - id: item.id, - name: item.name, - code: item.code, - quantitySold: meta.quantity, - soldCost: meta.cost, - averageSellPrice: meta.average, - quantitySoldFormatted: this.formatNumber(meta.quantity, { - money: false, - }), - soldCostFormatted: this.formatNumber(meta.cost), - averageSellPriceFormatted: this.formatNumber(meta.average), - currencyCode: this.baseCurrency, - }; - }; - - /** - * Detarmines whether the given sale node is has transactions. - * @param {ISalesByItemsItem} node - - * @returns {boolean} - */ - private filterSaleNoneTransactions = (node: ISalesByItemsItem) => { - return this.itemsTransactions.get(node.id); - }; - - /** - * Detarmines whether the given sale by item node is active. - * @param {ISalesByItemsItem} node - * @returns {boolean} - */ - private filterSaleOnlyActive = (node: ISalesByItemsItem): boolean => { - return node.quantitySold !== 0 || node.soldCost !== 0; - }; - - /** - * Filters sales by items nodes based on the report query. - * @param {ISalesByItemsItem} saleItem - - * @return {boolean} - */ - private itemSaleFilter = (saleItem: ISalesByItemsItem): boolean => { - const { noneTransactions, onlyActive } = this.query; - - const conditions = [ - [noneTransactions, this.filterSaleNoneTransactions], - [onlyActive, this.filterSaleOnlyActive], - ]; - return allPassedConditionsPass(conditions)(saleItem); - }; - - /** - * Mappes the given items to sales by items nodes. - * @param {IItem[]} items - - * @returns {ISalesByItemsItem[]} - */ - private itemsMapper = (items: IItem[]): ISalesByItemsItem[] => { - return items.map(this.itemSectionMapper); - }; - - /** - * Filters sales by items sections. - * @param items - * @returns - */ - private itemsFilters = (nodes: ISalesByItemsItem[]): ISalesByItemsItem[] => { - return nodes.filter(this.itemSaleFilter); - }; - - /** - * Retrieve the items sections. - * @returns {ISalesByItemsItem[]} - */ - private itemsSection(): ISalesByItemsItem[] { - return R.compose(this.itemsFilters, this.itemsMapper)(this.items); - } - - /** - * Retrieve the total section of the sheet. - * @param {IInventoryValuationItem[]} items - * @returns {IInventoryValuationTotal} - */ - private totalSection(items: ISalesByItemsItem[]): ISalesByItemsTotal { - const quantitySold = sumBy(items, (item) => item.quantitySold); - const soldCost = sumBy(items, (item) => item.soldCost); - - return { - quantitySold, - soldCost, - quantitySoldFormatted: this.formatTotalNumber(quantitySold, { - money: false, - }), - soldCostFormatted: this.formatTotalNumber(soldCost), - currencyCode: this.baseCurrency, - }; - } - - /** - * Retrieve the sheet data. - * @returns {ISalesByItemsSheetData} - */ - public reportData(): ISalesByItemsSheetData { - const items = this.itemsSection(); - const total = this.totalSection(items); - - return { items, total }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts deleted file mode 100644 index 3ca915e39..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Inject, Service } from 'typedi'; - -import { - ISalesByItemsReportQuery, - ISalesByItemsSheet, - ISalesByItemsTable, -} from '@/interfaces'; -import { SalesByItemsReportService } from './SalesByItemsService'; -import { SalesByItemsTableInjectable } from './SalesByItemsTableInjectable'; -import { SalesByItemsExport } from './SalesByItemsExport'; -import { SalesByItemsPdfInjectable } from './SalesByItemsPdfInjectable'; - -@Service() -export class SalesByItemsApplication { - @Inject() - private salesByItemsSheet: SalesByItemsReportService; - - @Inject() - private salesByItemsTable: SalesByItemsTableInjectable; - - @Inject() - private salesByItemsExport: SalesByItemsExport; - - @Inject() - private salesByItemsPdf: SalesByItemsPdfInjectable; - - /** - * Retrieves the sales by items report in json format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} filter - * @returns {Promise} - */ - public sheet( - tenantId: number, - filter: ISalesByItemsReportQuery - ): Promise { - return this.salesByItemsSheet.salesByItems(tenantId, filter); - } - - /** - * Retrieves the sales by items report in table format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} filter - * @returns {Promise} - */ - public table( - tenantId: number, - filter: ISalesByItemsReportQuery - ): Promise { - return this.salesByItemsTable.table(tenantId, filter); - } - - /** - * Retrieves the sales by items report in csv format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} filter - * @returns {Promise} - */ - public csv( - tenantId: number, - filter: ISalesByItemsReportQuery - ): Promise { - return this.salesByItemsExport.csv(tenantId, filter); - } - - /** - * Retrieves the sales by items report in xlsx format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} filter - * @returns {Promise} - */ - public xlsx( - tenantId: number, - filter: ISalesByItemsReportQuery - ): Promise { - return this.salesByItemsExport.xlsx(tenantId, filter); - } - - /** - * Retrieves the sales by items in pdf format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} query - * @returns {Promise} - */ - public pdf( - tenantId: number, - query: ISalesByItemsReportQuery - ): Promise { - return this.salesByItemsPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsExport.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsExport.ts deleted file mode 100644 index 067aab546..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsExport.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { ISalesByItemsReportQuery } from '@/interfaces'; -import { SalesByItemsTableInjectable } from './SalesByItemsTableInjectable'; - -@Service() -export class SalesByItemsExport { - @Inject() - private salesByItemsTable: SalesByItemsTableInjectable; - - /** - * Retrieves the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: ISalesByItemsReportQuery) { - const table = await this.salesByItemsTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ISalesByItemsReportQuery - ): Promise { - const table = await this.salesByItemsTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsMeta.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsMeta.ts deleted file mode 100644 index b47b45215..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsMeta.ts +++ /dev/null @@ -1,35 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { ISalesByItemsReportQuery, ISalesByItemsSheetMeta } from '@/interfaces'; - -@Service() -export class SalesByItemsMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieve the sales by items meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: ISalesByItemsReportQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - const sheetName = 'Sales By Items'; - - return { - ...commonMeta, - sheetName, - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts deleted file mode 100644 index 874154086..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISalesByItemsReportQuery } from '@/interfaces'; -import { SalesByItemsTableInjectable } from './SalesByItemsTableInjectable'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class SalesByItemsPdfInjectable { - @Inject() - private salesByItemsTable: SalesByItemsTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Retrieves the sales by items sheet in pdf format. - * @param {number} tenantId - * @param {number} query - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ISalesByItemsReportQuery - ): Promise { - const table = await this.salesByItemsTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsService.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsService.ts deleted file mode 100644 index a4cb25e09..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsService.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { ISalesByItemsReportQuery, ISalesByItemsSheet } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import SalesByItems from './SalesByItems'; -import { Tenant } from '@/system/models'; -import { SalesByItemsMeta } from './SalesByItemsMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class SalesByItemsReportService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private salesByItemsMeta: SalesByItemsMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - private get defaultQuery(): ISalesByItemsReportQuery { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - itemsIds: [], - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'always', - negativeFormat: 'mines', - }, - noneTransactions: true, - onlyActive: false, - }; - } - - /** - * Retrieve balance sheet statement. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @return {Promise} - */ - public async salesByItems( - tenantId: number, - query: ISalesByItemsReportQuery - ): Promise { - const { Item, InventoryTransaction } = this.tenancy.models(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - // Inventory items for sales report. - const inventoryItems = await Item.query().onBuild((q) => { - q.where('type', 'inventory'); - - if (filter.itemsIds.length > 0) { - q.whereIn('id', filter.itemsIds); - } - }); - const inventoryItemsIds = inventoryItems.map((item) => item.id); - - // Calculates the total inventory total quantity and rate `IN` transactions. - const inventoryTransactions = await InventoryTransaction.query().onBuild( - (builder: any) => { - builder.modify('itemsTotals'); - builder.modify('OUTDirection'); - - // Filter the inventory items only. - builder.whereIn('itemId', inventoryItemsIds); - - // Filter the date range of the sheet. - builder.modify('filterDateRange', filter.fromDate, filter.toDate); - } - ); - const sheet = new SalesByItems( - filter, - inventoryItems, - inventoryTransactions, - tenant.metadata.baseCurrency - ); - const salesByItemsData = sheet.reportData(); - - // Retrieve the sales by items meta. - const meta = await this.salesByItemsMeta.meta(tenantId, query); - - // Triggers `onSalesByItemViewed` event. - await this.eventPublisher.emitAsync(events.reports.onSalesByItemViewed, { - tenantId, - query, - }); - - return { - data: salesByItemsData, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTable.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTable.ts deleted file mode 100644 index f06c7bd14..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTable.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as R from 'ramda'; -import { - ISalesByItemsItem, - ISalesByItemsSheetStatement, - ISalesByItemsTotal, - ITableColumn, - ITableRow, -} from '@/interfaces'; -import { tableRowMapper } from '@/utils'; -import FinancialSheet from '../FinancialSheet'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { FinancialTable } from '../FinancialTable'; -import { ROW_TYPE } from './constants'; - -export class SalesByItemsTable extends R.compose( - FinancialTable, - FinancialSheetStructure -)(FinancialSheet) { - private readonly data: ISalesByItemsSheetStatement; - - /** - * Constructor method. - * @param {ISalesByItemsSheetStatement} data - */ - constructor(data: ISalesByItemsSheetStatement) { - super(); - this.data = data; - } - - /** - * Retrieves the common table accessors. - * @returns {ITableColumn[]} - */ - private commonTableAccessors() { - return [ - { key: 'item_name', accessor: 'name' }, - { key: 'sold_quantity', accessor: 'quantitySoldFormatted' }, - { key: 'sold_amount', accessor: 'soldCostFormatted' }, - { key: 'average_price', accessor: 'averageSellPriceFormatted' }, - ]; - } - - /** - * Maps the given item node to table row. - * @param {ISalesByItemsItem} item - * @returns {ITableRow} - */ - private itemMap = (item: ISalesByItemsItem): ITableRow => { - const columns = this.commonTableAccessors(); - const meta = { - rowTypes: [ROW_TYPE.ITEM], - }; - return tableRowMapper(item, columns, meta); - }; - - /** - * Maps the given items nodes to table rows. - * @param {ISalesByItemsItem[]} items - * @returns {ITableRow[]} - */ - private itemsMap = (items: ISalesByItemsItem[]): ITableRow[] => { - return R.map(this.itemMap, items); - }; - - /** - * Maps the given total node to table row. - * @param {ISalesByItemsTotal} total - * @returns {ITableRow[]} - */ - private totalMap = (total: ISalesByItemsTotal) => { - const columns = this.commonTableAccessors(); - const meta = { - rowTypes: [ROW_TYPE.TOTAL], - }; - return tableRowMapper(total, columns, meta); - }; - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableData(): ITableRow[] { - const itemsRows = this.itemsMap(this.data.items); - const totalRow = this.totalMap(this.data.total); - - return R.compose( - R.when(R.always(R.not(R.isEmpty(itemsRows))), R.append(totalRow)) - )([...itemsRows]) as ITableRow[]; - } - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns(): ITableColumn[] { - const columns = [ - { key: 'item_name', label: 'Item name' }, - { key: 'sold_quantity', label: 'Sold quantity' }, - { key: 'sold_amount', label: 'Sold amount' }, - { key: 'average_price', label: 'Average price' }, - ]; - return R.compose(this.tableColumnsCellIndexing)(columns); - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTableInjectable.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTableInjectable.ts deleted file mode 100644 index c947cfa86..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsTableInjectable.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISalesByItemsReportQuery } from '@/interfaces'; -import { SalesByItemsReportService } from './SalesByItemsService'; -import { SalesByItemsTable } from './SalesByItemsTable'; - -@Service() -export class SalesByItemsTableInjectable { - @Inject() - private salesByItemSheet: SalesByItemsReportService; - - /** - * Retrieves the sales by items report in table format. - * @param {number} tenantId - * @param {ISalesByItemsReportQuery} filter - * @returns {Promise} - */ - public async table(tenantId: number, filter: ISalesByItemsReportQuery) { - const { data, query, meta } = await this.salesByItemSheet.salesByItems( - tenantId, - filter - ); - const table = new SalesByItemsTable(data); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableData(), - }, - meta, - query, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/constants.ts b/packages/server/src/services/FinancialStatements/SalesByItems/constants.ts deleted file mode 100644 index 761e37ec5..000000000 --- a/packages/server/src/services/FinancialStatements/SalesByItems/constants.ts +++ /dev/null @@ -1,23 +0,0 @@ -export enum ROW_TYPE { - ITEM = 'ITEM', - TOTAL = 'TOTAL', -} - -export const HtmlTableCustomCss = ` -table tr.row-type--total td { - border-top: 1px solid #bbb; - border-bottom: 3px double #000; - font-weight: 600; -} -table .column--item_name{ - width: 300px; -} -table .column--average_price, -table .column--sold_quantity, -table .column--sold_amount, -table .cell--average_price, -table .cell--sold_quantity, -table .cell--sold_amount{ - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts deleted file mode 100644 index 7f9da7e7c..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.ts +++ /dev/null @@ -1,131 +0,0 @@ -import * as R from 'ramda'; -import { isEmpty, sumBy } from 'lodash'; -import { ITaxRate } from '@/interfaces'; -import { - SalesTaxLiabilitySummaryPayableById, - SalesTaxLiabilitySummaryQuery, - SalesTaxLiabilitySummaryRate, - SalesTaxLiabilitySummaryReportData, - SalesTaxLiabilitySummarySalesById, - SalesTaxLiabilitySummaryTotal, -} from '@/interfaces/SalesTaxLiabilitySummary'; -import FinancialSheet from '../FinancialSheet'; - -export class SalesTaxLiabilitySummary extends FinancialSheet { - private query: SalesTaxLiabilitySummaryQuery; - private taxRates: ITaxRate[]; - private payableTaxesById: SalesTaxLiabilitySummaryPayableById; - private salesTaxesById: SalesTaxLiabilitySummarySalesById; - - /** - * Sales tax liability summary constructor. - * @param {SalesTaxLiabilitySummaryQuery} query - * @param {ITaxRate[]} taxRates - * @param {SalesTaxLiabilitySummaryPayableById} payableTaxesById - * @param {SalesTaxLiabilitySummarySalesById} salesTaxesById - */ - constructor( - query: SalesTaxLiabilitySummaryQuery, - taxRates: ITaxRate[], - payableTaxesById: SalesTaxLiabilitySummaryPayableById, - salesTaxesById: SalesTaxLiabilitySummarySalesById - ) { - super(); - - this.query = query; - this.taxRates = taxRates; - this.payableTaxesById = payableTaxesById; - this.salesTaxesById = salesTaxesById; - } - - /** - * Retrieves the tax rate liability node. - * @param {ITaxRate} taxRate - * @returns {SalesTaxLiabilitySummaryRate} - */ - private taxRateLiability = ( - taxRate: ITaxRate - ): SalesTaxLiabilitySummaryRate => { - const payableTax = this.payableTaxesById[taxRate.id]; - const salesTax = this.salesTaxesById[taxRate.id]; - - const payableTaxAmount = payableTax - ? payableTax.credit - payableTax.debit - : 0; - const salesTaxAmount = salesTax ? salesTax.credit - salesTax.debit : 0; - - // Calculates the tax percentage. - const taxPercentage = R.compose( - R.unless(R.equals(0), R.divide(R.__, salesTaxAmount)) - )(payableTaxAmount); - - // Calculates the payable tax amount. - const collectedTaxAmount = payableTax ? payableTax.debit : 0; - - return { - id: taxRate.id, - taxName: `${taxRate.name} (${taxRate.rate}%)`, - taxableAmount: this.getAmountMeta(salesTaxAmount), - taxAmount: this.getAmountMeta(payableTaxAmount), - taxPercentage: this.getPercentageTotalAmountMeta(taxPercentage), - collectedTaxAmount: this.getAmountMeta(collectedTaxAmount), - }; - }; - - /** - * Filters the non-transactions tax rates. - * @param {SalesTaxLiabilitySummaryRate[]} nodes - * @returns {SalesTaxLiabilitySummaryRate[]} - */ - private filterNonTransactionsTaxRates = ( - nodes: SalesTaxLiabilitySummaryRate[] - ): SalesTaxLiabilitySummaryRate[] => { - return nodes.filter((node) => { - const salesTrxs = this.salesTaxesById[node.id]; - const payableTrxs = this.payableTaxesById[node.id]; - - return !isEmpty(salesTrxs) || !isEmpty(payableTrxs); - }); - }; - - /** - * Retrieves the tax rates liability nodes. - * @returns {SalesTaxLiabilitySummaryRate[]} - */ - private taxRatesLiability = (): SalesTaxLiabilitySummaryRate[] => { - return R.compose( - this.filterNonTransactionsTaxRates, - R.map(this.taxRateLiability) - )(this.taxRates); - }; - - /** - * Retrieves the tax rates total node. - * @param {SalesTaxLiabilitySummaryRate[]} nodes - * @returns {SalesTaxLiabilitySummaryTotal} - */ - private taxRatesTotal = ( - nodes: SalesTaxLiabilitySummaryRate[] - ): SalesTaxLiabilitySummaryTotal => { - const taxableAmount = sumBy(nodes, 'taxableAmount.amount'); - const taxAmount = sumBy(nodes, 'taxAmount.amount'); - const collectedTaxAmount = sumBy(nodes, 'collectedTaxAmount.amount'); - - return { - taxableAmount: this.getTotalAmountMeta(taxableAmount), - taxAmount: this.getTotalAmountMeta(taxAmount), - collectedTaxAmount: this.getTotalAmountMeta(collectedTaxAmount), - }; - }; - - /** - * Retrieves the report data. - * @returns {SalesTaxLiabilitySummaryReportData} - */ - public reportData = (): SalesTaxLiabilitySummaryReportData => { - const taxRates = this.taxRatesLiability(); - const total = this.taxRatesTotal(taxRates); - - return { taxRates, total }; - }; -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts deleted file mode 100644 index f63123687..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryApplication.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { SalesTaxLiabilitySummaryQuery } from '@/interfaces/SalesTaxLiabilitySummary'; -import { SalesTaxLiabilitySummaryTableInjectable } from './SalesTaxLiabilitySummaryTableInjectable'; -import { SalesTaxLiabilitySummaryExportInjectable } from './SalesTaxLiabilitySummaryExportInjectable'; -import { SalesTaxLiabilitySummaryService } from './SalesTaxLiabilitySummaryService'; -import { SalesTaxLiabiltiySummaryPdf } from './SalesTaxLiabiltiySummaryPdf'; - -@Service() -export class SalesTaxLiabilitySummaryApplication { - @Inject() - private salesTaxLiabilitySheet: SalesTaxLiabilitySummaryService; - - @Inject() - private salesTaxLiabilityExport: SalesTaxLiabilitySummaryExportInjectable; - - @Inject() - private salesTaxLiabilityTable: SalesTaxLiabilitySummaryTableInjectable; - - @Inject() - private salesTaxLiabiltiyPdf: SalesTaxLiabiltiySummaryPdf; - - /** - * Retrieves the sales tax liability summary in json format. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @returns {Promise} - */ - public sheet(tenantId: number, query: SalesTaxLiabilitySummaryQuery) { - return this.salesTaxLiabilitySheet.salesTaxLiability(tenantId, query); - } - - /** - * Retrieves the sales tax liability summary in table format. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @return {Promise} - */ - public table(tenantId: number, query: SalesTaxLiabilitySummaryQuery) { - return this.salesTaxLiabilityTable.table(tenantId, query); - } - - /** - * Retrieves the sales tax liability summary in XLSX format. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @returns {Promise} - */ - public xlsx( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - return this.salesTaxLiabilityExport.xlsx(tenantId, query); - } - - /** - * Retrieves the sales tax liability summary in CSV format. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @returns {Promise} - */ - public csv( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - return this.salesTaxLiabilityExport.csv(tenantId, query); - } - - /** - * Retrieves the sales tax liability summary in PDF format. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @returns {Promise} - */ - public pdf( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - return this.salesTaxLiabiltiyPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts deleted file mode 100644 index 932743679..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryExportInjectable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { SalesTaxLiabilitySummaryQuery } from '@/interfaces/SalesTaxLiabilitySummary'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { Inject, Service } from 'typedi'; -import { SalesTaxLiabilitySummaryTableInjectable } from './SalesTaxLiabilitySummaryTableInjectable'; - -@Service() -export class SalesTaxLiabilitySummaryExportInjectable { - @Inject() - private salesTaxLiabilityTable: SalesTaxLiabilitySummaryTableInjectable; - - /** - * Retrieves the cashflow sheet in XLSX format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - const table = await this.salesTaxLiabilityTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the cashflow sheet in CSV format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - const table = await this.salesTaxLiabilityTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts deleted file mode 100644 index c18a8f55d..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryMeta.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import { SalesTaxLiabilitySummaryQuery } from '@/interfaces/SalesTaxLiabilitySummary'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; - -@Service() -export class SalesTaxLiabilitySummaryMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the report meta. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} filter - */ - public async meta(tenantId: number, query: SalesTaxLiabilitySummaryQuery) { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - const sheetName = 'Sales Tax Liability Summary'; - - return { - ...commonMeta, - sheetName, - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts deleted file mode 100644 index 45b955ab9..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryRepository.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; -import { - SalesTaxLiabilitySummaryPayableById, - SalesTaxLiabilitySummarySalesById, -} from '@/interfaces/SalesTaxLiabilitySummary'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { keyBy } from 'lodash'; -import { Inject, Service } from 'typedi'; - -@Service() -export class SalesTaxLiabilitySummaryRepository { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve tax rates. - * @param {number} tenantId - * @returns {Promise} - */ - public taxRates = (tenantId: number) => { - const { TaxRate } = this.tenancy.models(tenantId); - - return TaxRate.query().orderBy('name', 'desc'); - }; - - /** - * Retrieve taxes payable sum grouped by tax rate id. - * @param {number} tenantId - * @returns {Promise} - */ - public async taxesPayableSumGroupedByRateId( - tenantId: number - ): Promise { - const { AccountTransaction, Account } = this.tenancy.models(tenantId); - - // Retrieves tax payable accounts. - const taxPayableAccounts = await Account.query().whereIn('accountType', [ - ACCOUNT_TYPE.TAX_PAYABLE, - ]); - const payableAccountsIds = taxPayableAccounts.map((account) => account.id); - - const groupedTaxesById = await AccountTransaction.query() - .whereIn('account_id', payableAccountsIds) - .whereNot('tax_rate_id', null) - .groupBy('tax_rate_id') - .select(['tax_rate_id']) - .sum('credit as credit') - .sum('debit as debit'); - - return keyBy(groupedTaxesById, 'taxRateId'); - } - - /** - * Retrieve taxes sales sum grouped by tax rate id. - * @param {number} tenantId - * @returns {Promise} - */ - public taxesSalesSumGroupedByRateId = async ( - tenantId: number - ): Promise => { - const { AccountTransaction, Account } = this.tenancy.models(tenantId); - - const incomeAccounts = await Account.query().whereIn('accountType', [ - ACCOUNT_TYPE.INCOME, - ACCOUNT_TYPE.OTHER_INCOME, - ]); - const incomeAccountsIds = incomeAccounts.map((account) => account.id); - - const groupedTaxesById = await AccountTransaction.query() - .whereIn('account_id', incomeAccountsIds) - .whereNot('tax_rate_id', null) - .groupBy('tax_rate_id') - .select(['tax_rate_id']) - .sum('credit as credit') - .sum('debit as debit'); - - return keyBy(groupedTaxesById, 'taxRateId'); - }; -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts deleted file mode 100644 index 585e9e4d9..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryService.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { SalesTaxLiabilitySummaryRepository } from './SalesTaxLiabilitySummaryRepository'; -import { SalesTaxLiabilitySummaryQuery } from '@/interfaces/SalesTaxLiabilitySummary'; -import { SalesTaxLiabilitySummary } from './SalesTaxLiabilitySummary'; -import { SalesTaxLiabilitySummaryMeta } from './SalesTaxLiabilitySummaryMeta'; - -@Service() -export class SalesTaxLiabilitySummaryService { - @Inject() - private repostiory: SalesTaxLiabilitySummaryRepository; - - @Inject() - private salesTaxLiabilityMeta: SalesTaxLiabilitySummaryMeta; - - /** - * Retrieve sales tax liability summary. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @returns - */ - public async salesTaxLiability( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ) { - const payableByRateId = - await this.repostiory.taxesPayableSumGroupedByRateId(tenantId); - - const salesByRateId = await this.repostiory.taxesSalesSumGroupedByRateId( - tenantId - ); - const taxRates = await this.repostiory.taxRates(tenantId); - - const taxLiabilitySummary = new SalesTaxLiabilitySummary( - query, - taxRates, - payableByRateId, - salesByRateId - ); - const meta = await this.salesTaxLiabilityMeta.meta(tenantId, query); - - return { - data: taxLiabilitySummary.reportData(), - query, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts deleted file mode 100644 index 58fa2bc23..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts +++ /dev/null @@ -1,161 +0,0 @@ -import * as R from 'ramda'; -import { - SalesTaxLiabilitySummaryQuery, - SalesTaxLiabilitySummaryRate, - SalesTaxLiabilitySummaryReportData, - SalesTaxLiabilitySummaryTotal, -} from '@/interfaces/SalesTaxLiabilitySummary'; -import { tableRowMapper } from '@/utils'; -import { ITableColumn, ITableRow } from '@/interfaces'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; -import { FinancialTable } from '../FinancialTable'; -import AgingReport from '../AgingSummary/AgingReport'; -import { IROW_TYPE } from './_constants'; - -export class SalesTaxLiabilitySummaryTable extends R.compose( - FinancialSheetStructure, - FinancialTable -)(AgingReport) { - private data: SalesTaxLiabilitySummaryReportData; - private query: SalesTaxLiabilitySummaryQuery; - - /** - * Sales tax liability summary table constructor. - * @param {SalesTaxLiabilitySummaryReportData} data - * @param {SalesTaxLiabilitySummaryQuery} query - */ - constructor( - data: SalesTaxLiabilitySummaryReportData, - query: SalesTaxLiabilitySummaryQuery - ) { - super(); - - this.data = data; - this.query = query; - } - - /** - * Retrieve the tax rate row accessors. - * @returns {ITableColumnAccessor[]} - */ - private get taxRateRowAccessor() { - return [ - { key: 'taxName', accessor: 'taxName' }, - { key: 'taxPercentage', accessor: 'taxPercentage.formattedAmount' }, - { key: 'taxableAmount', accessor: 'taxableAmount.formattedAmount' }, - { key: 'collectedTax', accessor: 'collectedTaxAmount.formattedAmount' }, - { key: 'taxAmount', accessor: 'taxAmount.formattedAmount' }, - ]; - } - - /** - * Retrieve the tax rate total row accessors. - * @returns {ITableColumnAccessor[]} - */ - private get taxRateTotalRowAccessors() { - return [ - { key: 'taxName', value: 'Total' }, - { key: 'taxPercentage', value: '' }, - { key: 'taxableAmount', accessor: 'taxableAmount.formattedAmount' }, - { key: 'collectedTax', accessor: 'collectedTaxAmount.formattedAmount' }, - { key: 'taxAmount', accessor: 'taxAmount.formattedAmount' }, - ]; - } - - /** - * Maps the tax rate node to table row. - * @param {SalesTaxLiabilitySummaryRate} node - * @returns {ITableRow} - */ - private taxRateTableRowMapper = ( - node: SalesTaxLiabilitySummaryRate - ): ITableRow => { - const columns = this.taxRateRowAccessor; - const meta = { - rowTypes: [IROW_TYPE.TaxRate], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Maps the tax rates nodes to table rows. - * @param {SalesTaxLiabilitySummaryRate[]} nodes - * @returns {ITableRow[]} - */ - private taxRatesTableRowsMapper = ( - nodes: SalesTaxLiabilitySummaryRate[] - ): ITableRow[] => { - return nodes.map(this.taxRateTableRowMapper); - }; - - /** - * Maps the tax rate total node to table row. - * @param {SalesTaxLiabilitySummaryTotal} node - * @returns {ITableRow} - */ - private taxRateTotalRowMapper = (node: SalesTaxLiabilitySummaryTotal) => { - const columns = this.taxRateTotalRowAccessors; - const meta = { - rowTypes: [IROW_TYPE.Total], - id: node.key, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Retrieves the tax rate total row. - * @returns {ITableRow} - */ - private get taxRateTotalRow(): ITableRow { - return this.taxRateTotalRowMapper(this.data.total); - } - - /** - * Retrieves the tax rates rows. - * @returns {ITableRow[]} - */ - private get taxRatesRows(): ITableRow[] { - return this.taxRatesTableRowsMapper(this.data.taxRates); - } - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableRows(): ITableRow[] { - return R.compose( - R.unless(R.isEmpty, R.append(this.taxRateTotalRow)), - R.concat(this.taxRatesRows) - )([]); - } - - /** - * Retrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns(): ITableColumn[] { - return R.compose(this.tableColumnsCellIndexing)([ - { - label: 'Tax Name', - key: 'taxName', - }, - { - label: 'Tax Percentage', - key: 'taxPercentage', - }, - { - label: 'Taxable Amount', - key: 'taxableAmount', - }, - { - label: 'Collected Tax', - key: 'collectedTax', - }, - { - label: 'Tax Amount', - key: 'taxRate', - }, - ]); - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts deleted file mode 100644 index 907cab2ad..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTableInjectable.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISalesTaxLiabilitySummaryTable, - SalesTaxLiabilitySummaryQuery, -} from '@/interfaces/SalesTaxLiabilitySummary'; -import { SalesTaxLiabilitySummaryTable } from './SalesTaxLiabilitySummaryTable'; -import { SalesTaxLiabilitySummaryService } from './SalesTaxLiabilitySummaryService'; - -@Service() -export class SalesTaxLiabilitySummaryTableInjectable { - @Inject() - private salesTaxLiability: SalesTaxLiabilitySummaryService; - - /** - * Retrieve sales tax liability summary table. - * @param {number} tenantId - * @param {SalesTaxLiabilitySummaryQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - const report = await this.salesTaxLiability.salesTaxLiability( - tenantId, - query - ); - // Creates the sales tax liability summary table. - const table = new SalesTaxLiabilitySummaryTable(report.data, query); - - return { - table: { - rows: table.tableRows(), - columns: table.tableColumns(), - }, - query: report.query, - meta: report.meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts deleted file mode 100644 index 742241842..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabiltiySummaryPdf.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { SalesTaxLiabilitySummaryTableInjectable } from './SalesTaxLiabilitySummaryTableInjectable'; -import { ISalesByItemsReportQuery } from '@/interfaces'; -import { SalesTaxLiabilitySummaryQuery } from '@/interfaces/SalesTaxLiabilitySummary'; - -@Service() -export class SalesTaxLiabiltiySummaryPdf { - @Inject() - private salesTaxLiabiltiySummaryTable: SalesTaxLiabilitySummaryTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given sales tax liability summary table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {ISalesByItemsReportQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: SalesTaxLiabilitySummaryQuery - ): Promise { - const table = await this.salesTaxLiabiltiySummaryTable.table( - tenantId, - query - ); - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts deleted file mode 100644 index f030fd16c..000000000 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum IROW_TYPE { - TaxRate = 'TaxRate', - Total = 'Total', -} diff --git a/packages/server/src/services/FinancialStatements/TableSheetPdf.ts b/packages/server/src/services/FinancialStatements/TableSheetPdf.ts deleted file mode 100644 index 280adf187..000000000 --- a/packages/server/src/services/FinancialStatements/TableSheetPdf.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { ITableColumn, ITableData, ITableRow } from '@/interfaces'; -import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy'; -import { TemplateInjectable } from '@/services/TemplateInjectable/TemplateInjectable'; -import { FinancialTableStructure } from './FinancialTableStructure'; -import { tableClassNames } from './utils'; - -@Service() -export class TableSheetPdf { - @Inject() - private templateInjectable: TemplateInjectable; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - /** - * Converts the table data into a PDF format. - * @param {number} tenantId - The unique identifier for the tenant. - * @param {ITableData} table - The table data to be converted. - * @param {string} sheetName - The name of the sheet. - * @param {string} sheetDate - The date of the sheet. - * @returns A promise that resolves with the PDF conversion result. - */ - public async convertToPdf( - tenantId: number, - table: ITableData, - sheetName: string, - sheetDate: string, - customCSS?: string - ): Promise { - // Prepare columns and rows for PDF conversion - const columns = this.tablePdfColumns(table.columns); - const rows = this.tablePdfRows(table.rows); - - const landscape = columns.length > 4; - - // Generate HTML content from the template - const htmlContent = await this.templateInjectable.render( - tenantId, - 'modules/financial-sheet', - { - table: { rows, columns }, - sheetName, - sheetDate, - customCSS, - } - ); - // Convert the HTML content to PDF - return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, { - margins: { top: 0, bottom: 0, left: 0, right: 0 }, - landscape, - }); - } - - /** - * Converts the table columns to pdf columns. - * @param {ITableColumn[]} columns - * @returns {ITableColumn[]} - */ - private tablePdfColumns = (columns: ITableColumn[]): ITableColumn[] => { - return columns; - }; - - /** - * Converts the table rows to pdf rows. - * @param {ITableRow[]} rows - - * @returns {ITableRow[]} - */ - private tablePdfRows = (rows: ITableRow[]): ITableRow[] => { - const curriedFlatNestedTree = R.curry( - FinancialTableStructure.flatNestedTree - ); - const flatNestedTree = curriedFlatNestedTree(R.__, { - nestedPrefix: '', - }); - return R.compose(tableClassNames, flatNestedTree)(rows); - }; -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContact.ts b/packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContact.ts deleted file mode 100644 index 05521ed3b..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContact.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { sumBy, defaultTo } from 'lodash'; -import { - ITransactionsByContactsTransaction, - ITransactionsByContactsAmount, - ITransactionsByContactsFilter, - ITransactionsByContactsContact, - IContact, - ILedger, - ILedgerEntry, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { allPassedConditionsPass } from 'utils'; - -export default class TransactionsByContact extends FinancialSheet { - readonly contacts: IContact[]; - readonly ledger: ILedger; - readonly filter: ITransactionsByContactsFilter; - readonly accountsGraph: any; - - /** - * Customer transaction mapper. - * @param {any} transaction - - * @return {Omit} - */ - protected contactTransactionMapper( - entry: ILedgerEntry - ): Omit { - const account = this.accountsGraph.getNodeData(entry.accountId); - const currencyCode = this.baseCurrency; - - return { - credit: this.getContactAmount(entry.credit, currencyCode), - debit: this.getContactAmount(entry.debit, currencyCode), - accountName: account.name, - currencyCode: this.baseCurrency, - transactionNumber: entry.transactionNumber, - transactionType: this.i18n.__(entry.referenceTypeFormatted), - date: entry.date, - createdAt: entry.createdAt, - }; - } - - /** - * Customer transactions mapper with running balance. - * @param {number} openingBalance - * @param {ITransactionsByContactsTransaction[]} transactions - * @returns {ITransactionsByContactsTransaction[]} - */ - protected contactTransactionRunningBalance( - openingBalance: number, - accountNormal: 'credit' | 'debit', - transactions: Omit[] - ): any { - let _openingBalance = openingBalance; - - return transactions.map( - (transaction: ITransactionsByContactsTransaction) => { - _openingBalance += - accountNormal === 'debit' - ? transaction.debit.amount - : -1 * transaction.debit.amount; - - _openingBalance += - accountNormal === 'credit' - ? transaction.credit.amount - : -1 * transaction.credit.amount; - - const runningBalance = this.getTotalAmountMeta( - _openingBalance, - transaction.currencyCode - ); - return { ...transaction, runningBalance }; - } - ); - } - - /** - * Retrieve the customer closing balance from the given transactions and opening balance. - * @param {number} customerTransactions - * @param {number} openingBalance - * @returns {number} - */ - protected getContactClosingBalance( - customerTransactions: ITransactionsByContactsTransaction[], - contactNormal: 'credit' | 'debit', - openingBalance: number - ): number { - const closingBalance = openingBalance; - - const totalCredit = sumBy(customerTransactions, 'credit.amount'); - const totalDebit = sumBy(customerTransactions, 'debit.amount'); - - const total = - contactNormal === 'debit' - ? totalDebit - totalCredit - : totalCredit - totalDebit; - - return closingBalance + total; - } - - /** - * Retrieve the given customer opening balance from the given customer id. - * @param {number} customerId - * @returns {number} - */ - protected getContactOpeningBalance(customerId: number): number { - const openingBalanceLedger = this.ledger - .whereContactId(customerId) - .whereToDate(this.filter.fromDate); - - // Retrieve the closing balance of the ledger. - const openingBalance = openingBalanceLedger.getClosingBalance(); - - return defaultTo(openingBalance, 0); - } - - /** - * Retrieve the customer amount format meta. - * @param {number} amount - * @param {string} currencyCode - * @returns {ITransactionsByContactsAmount} - */ - protected getContactAmount( - amount: number, - currencyCode: string - ): ITransactionsByContactsAmount { - return { - amount, - formattedAmount: this.formatNumber(amount, { currencyCode }), - currencyCode, - }; - } - - /** - * Retrieve the contact total amount format meta. - * @param {number} amount - Amount. - * @param {string} currencyCode - Currency code./ - * @returns {ITransactionsByContactsAmount} - */ - protected getTotalAmountMeta(amount: number, currencyCode: string) { - return { - amount, - formattedAmount: this.formatTotalNumber(amount, { currencyCode }), - currencyCode, - }; - } - - /** - * Filter customer section that has no transactions. - * @param {ITransactionsByCustomersCustomer} transactionsByCustomer - * @returns {boolean} - */ - private filterContactByNoneTransaction = ( - transactionsByContact: ITransactionsByContactsContact - ): boolean => { - return transactionsByContact.transactions.length > 0; - }; - - /** - * Filters customer section has zero closing balnace. - * @param {ITransactionsByCustomersCustomer} transactionsByCustomer - * @returns {boolean} - */ - private filterContactNoneZero = ( - transactionsByContact: ITransactionsByContactsContact - ): boolean => { - return transactionsByContact.closingBalance.amount !== 0; - }; - - /** - * Filters the given customer node; - * @param {ICustomerBalanceSummaryCustomer} customer - */ - private contactNodeFilter = (node: ITransactionsByContactsContact) => { - const { noneTransactions, noneZero } = this.filter; - - // Conditions pair filter detarminer. - const condsPairFilters = [ - [noneTransactions, this.filterContactByNoneTransaction], - [noneZero, this.filterContactNoneZero], - ]; - return allPassedConditionsPass(condsPairFilters)(node); - }; - - /** - * Filters the given customers nodes. - * @param {ICustomerBalanceSummaryCustomer[]} nodes - * @returns {ICustomerBalanceSummaryCustomer[]} - */ - protected contactsFilter = ( - nodes: ITransactionsByContactsContact[] - ): ITransactionsByContactsContact[] => { - return nodes.filter(this.contactNodeFilter); - }; -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContactTableRows.ts b/packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContactTableRows.ts deleted file mode 100644 index ff75e3a9b..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByContact/TransactionsByContactTableRows.ts +++ /dev/null @@ -1,81 +0,0 @@ -import moment from 'moment'; -import * as R from 'ramda'; -import { tableMapper, tableRowMapper } from 'utils'; -import { ITransactionsByContactsContact, ITableRow } from '@/interfaces'; - -enum ROW_TYPE { - OPENING_BALANCE = 'OPENING_BALANCE', - CLOSING_BALANCE = 'CLOSING_BALANCE', - TRANSACTION = 'TRANSACTION', - CUSTOMER = 'CUSTOMER', -} - -export default class TransactionsByContactsTableRows { - private dateAccessor = (value): string => { - return moment(value.date).format('YYYY MMM DD'); - }; - - /** - * Retrieve the table rows of contact transactions. - * @param {ITransactionsByCustomersCustomer} contact - * @returns {ITableRow[]} - */ - protected contactTransactions = ( - contact: ITransactionsByContactsContact - ): ITableRow[] => { - const columns = [ - { key: 'date', accessor: this.dateAccessor }, - { key: 'account', accessor: 'accountName' }, - { key: 'transactionType', accessor: 'transactionType' }, - { key: 'transactionNumber', accessor: 'transactionNumber' }, - { key: 'credit', accessor: 'credit.formattedAmount' }, - { key: 'debit', accessor: 'debit.formattedAmount' }, - { key: 'runningBalance', accessor: 'runningBalance.formattedAmount' }, - ]; - return tableMapper(contact.transactions, columns, { - rowTypes: [ROW_TYPE.TRANSACTION], - }); - }; - - /** - * Retrieve the table row of contact opening balance. - * @param {ITransactionsByCustomersCustomer} contact - * @returns {ITableRow} - */ - protected contactOpeningBalance = ( - contact: ITransactionsByContactsContact - ): ITableRow => { - const columns = [ - { key: 'openingBalanceLabel', value: this.i18n.__('Opening balance') }, - ...R.repeat({ key: 'empty', value: '' }, 5), - { - key: 'openingBalanceValue', - accessor: 'openingBalance.formattedAmount', - }, - ]; - return tableRowMapper(contact, columns, { - rowTypes: [ROW_TYPE.OPENING_BALANCE], - }); - }; - - /** - * Retrieve the table row of contact closing balance. - * @param {ITransactionsByCustomersCustomer} contact - - * @returns {ITableRow} - */ - protected contactClosingBalance = ( - contact: ITransactionsByContactsContact - ): ITableRow => { - const columns = [ - { key: 'closingBalanceLabel', value: this.i18n.__('Closing balance') }, - ...R.repeat({ key: 'empty', value: '' }, 5), - { - key: 'closingBalanceValue', - accessor: 'closingBalance.formattedAmount', - }, - ]; - return tableRowMapper(contact, columns, { - rowTypes: [ROW_TYPE.CLOSING_BALANCE], - }); - }; -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomers.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomers.ts deleted file mode 100644 index e35692bd5..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomers.ts +++ /dev/null @@ -1,142 +0,0 @@ -import * as R from 'ramda'; -import { - ITransactionsByCustomersTransaction, - ITransactionsByCustomersFilter, - ITransactionsByCustomersCustomer, - ITransactionsByCustomersData, - INumberFormatQuery, - ICustomer, -} from '@/interfaces'; -import TransactionsByContact from '../TransactionsByContact/TransactionsByContact'; -import Ledger from '@/services/Accounting/Ledger'; -import { isEmpty } from 'lodash'; - -const CUSTOMER_NORMAL = 'debit'; - -export default class TransactionsByCustomers extends TransactionsByContact { - readonly customers: ICustomer[]; - readonly ledger: Ledger; - readonly filter: ITransactionsByCustomersFilter; - readonly baseCurrency: string; - readonly numberFormat: INumberFormatQuery; - readonly accountsGraph: any; - - /** - * Constructor method. - * @param {ICustomer} customers - * @param {Map} transactionsLedger - * @param {string} baseCurrency - */ - constructor( - customers: ICustomer[], - accountsGraph: any, - ledger: Ledger, - filter: ITransactionsByCustomersFilter, - baseCurrency: string, - i18n - ) { - super(); - - this.customers = customers; - this.accountsGraph = accountsGraph; - this.ledger = ledger; - this.baseCurrency = baseCurrency; - this.filter = filter; - this.numberFormat = this.filter.numberFormat; - this.i18n = i18n; - } - - /** - * Retrieve the customer transactions from the given customer id and opening balance. - * @param {number} customerId - Customer id. - * @param {number} openingBalance - Opening balance amount. - * @returns {ITransactionsByCustomersTransaction[]} - */ - private customerTransactions( - customerId: number, - openingBalance: number - ): ITransactionsByCustomersTransaction[] { - const ledger = this.ledger - .whereContactId(customerId) - .whereFromDate(this.filter.fromDate) - .whereToDate(this.filter.toDate); - - const ledgerEntries = ledger.getEntries(); - - return R.compose( - R.curry(this.contactTransactionRunningBalance)(openingBalance, 'debit'), - R.map(this.contactTransactionMapper.bind(this)) - ).bind(this)(ledgerEntries); - } - - /** - * Customer section mapper. - * @param {ICustomer} customer - * @returns {ITransactionsByCustomersCustomer} - */ - private customerMapper( - customer: ICustomer - ): ITransactionsByCustomersCustomer { - const openingBalance = this.getContactOpeningBalance(customer.id); - const transactions = this.customerTransactions(customer.id, openingBalance); - const closingBalance = this.getCustomerClosingBalance( - transactions, - openingBalance - ); - const currencyCode = this.baseCurrency; - - return { - customerName: customer.displayName, - openingBalance: this.getTotalAmountMeta(openingBalance, currencyCode), - closingBalance: this.getTotalAmountMeta(closingBalance, currencyCode), - transactions, - }; - } - - /** - * Retrieve the vendor closing balance from the given customer transactions. - * @param {ITransactionsByContactsTransaction[]} customerTransactions - * @param {number} openingBalance - * @returns - */ - private getCustomerClosingBalance( - customerTransactions: ITransactionsByCustomersTransaction[], - openingBalance: number - ): number { - return this.getContactClosingBalance( - customerTransactions, - CUSTOMER_NORMAL, - openingBalance - ); - } - - /** - * Detarmines whether the customers post filter is active. - * @returns {boolean} - */ - private isCustomersPostFilter = () => { - return isEmpty(this.filter.customersIds); - }; - - /** - * Retrieve the customers sections of the report. - * @param {ICustomer[]} customers - * @returns {ITransactionsByCustomersCustomer[]} - */ - private customersMapper( - customers: ICustomer[] - ): ITransactionsByCustomersCustomer[] { - return R.compose( - R.when(this.isCustomersPostFilter, this.contactsFilter), - R.map(this.customerMapper.bind(this)) - ).bind(this)(customers); - } - - /** - * Retrieve the report data. - * @returns {ITransactionsByCustomersData} - */ - public reportData(): ITransactionsByCustomersData { - return this.customersMapper(this.customers); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersApplication.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersApplication.ts deleted file mode 100644 index c3e4feb7e..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersApplication.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ITransactionsByCustomersFilter, - ITransactionsByCustomersStatement, -} from '@/interfaces'; -import { TransactionsByCustomersTableInjectable } from './TransactionsByCustomersTableInjectable'; -import { TransactionsByCustomersExportInjectable } from './TransactionsByCustomersExportInjectable'; -import { TransactionsByCustomersSheet } from './TransactionsByCustomersService'; -import { TransactionsByCustomersPdf } from './TransactionsByCustomersPdf'; - -@Service() -export class TransactionsByCustomerApplication { - @Inject() - private transactionsByCustomersTable: TransactionsByCustomersTableInjectable; - - @Inject() - private transactionsByCustomersExport: TransactionsByCustomersExportInjectable; - - @Inject() - private transactionsByCustomersSheet: TransactionsByCustomersSheet; - - @Inject() - private transactionsByCustomersPdf: TransactionsByCustomersPdf; - - /** - * Retrieves the transactions by customers sheet in json format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public sheet( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - return this.transactionsByCustomersSheet.transactionsByCustomers( - tenantId, - query - ); - } - - /** - * Retrieves the transactions by vendors sheet in table format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public table(tenantId: number, query: ITransactionsByCustomersFilter) { - return this.transactionsByCustomersTable.table(tenantId, query); - } - - /** - * Retrieves the transactions by vendors sheet in CSV format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public csv( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - return this.transactionsByCustomersExport.csv(tenantId, query); - } - - /** - * Retrieves the transactions by vendors sheet in XLSX format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public xlsx( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - return this.transactionsByCustomersExport.xlsx(tenantId, query); - } - - /** - * Retrieves the transactions by vendors sheet in PDF format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public pdf( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - return this.transactionsByCustomersPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts deleted file mode 100644 index d5dbffcff..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersExportInjectable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ITransactionsByCustomersFilter } from '@/interfaces'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { TransactionsByCustomersTableInjectable } from './TransactionsByCustomersTableInjectable'; - -@Service() -export class TransactionsByCustomersExportInjectable { - @Inject() - private transactionsByCustomerTable: TransactionsByCustomersTableInjectable; - - /** - * Retrieves the cashflow sheet in XLSX format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - const table = await this.transactionsByCustomerTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the cashflow sheet in CSV format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - const table = await this.transactionsByCustomerTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersMeta.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersMeta.ts deleted file mode 100644 index 710bc0bc4..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersMeta.ts +++ /dev/null @@ -1,36 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { - ITransactionsByCustomersFilter, - ITransactionsByCustomersMeta, -} from '@/interfaces'; - -@Service() -export class TransactionsByCustomersMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the transactions by customers meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - return { - ...commonMeta, - sheetName: 'Transactions By Customers', - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersPdf.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersPdf.ts deleted file mode 100644 index 122cbbaf2..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersPdf.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ITransactionsByCustomersFilter } from '@/interfaces'; -import { Inject } from 'typedi'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { TransactionsByCustomersTableInjectable } from './TransactionsByCustomersTableInjectable'; - -export class TransactionsByCustomersPdf { - @Inject() - private transactionsByCustomersTable: TransactionsByCustomersTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Retrieves the transactions by customers in PDF format. - * @param {number} tenantId - Tenant ID. - * @param {ITransactionsByCustomersFilter} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - const table = await this.transactionsByCustomersTable.table( - tenantId, - query - ); - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersRepository.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersRepository.ts deleted file mode 100644 index 09579e2b2..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersRepository.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Inject } from 'typedi'; -import { isEmpty, map } from 'lodash'; -import { IAccount, IAccountTransaction } from '@/interfaces'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -export default class TransactionsByCustomersRepository { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve the report customers. - * @param {number} tenantId - * @returns {Promise} - */ - public async getCustomers(tenantId: number, customersIds?: number[]) { - const { Customer } = this.tenancy.models(tenantId); - - return Customer.query().onBuild((q) => { - q.orderBy('displayName'); - - if (!isEmpty(customersIds)) { - q.whereIn('id', customersIds); - } - }); - } - - /** - * Retrieve the accounts receivable. - * @param {number} tenantId - * @returns {Promise} - */ - public async getReceivableAccounts(tenantId: number): Promise { - const { Account } = this.tenancy.models(tenantId); - - const accounts = await Account.query().where( - 'accountType', - ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE - ); - return accounts; - } - - /** - * Retrieve the customers opening balance transactions. - * @param {number} tenantId - Tenant id. - * @param {number} openingDate - Opening date. - * @param {number} customersIds - Customers ids. - * @returns {Promise} - */ - public async getCustomersOpeningBalanceTransactions( - tenantId: number, - openingDate: Date, - customersIds?: number[] - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - - const receivableAccounts = await this.getReceivableAccounts(tenantId); - const receivableAccountsIds = map(receivableAccounts, 'id'); - - const openingTransactions = await AccountTransaction.query().modify( - 'contactsOpeningBalance', - openingDate, - receivableAccountsIds, - customersIds - ); - return openingTransactions; - } - - /** - * Retrieve the customers periods transactions. - * @param {number} tenantId - Tenant id. - * @param {Date|string} openingDate - Opening date. - * @param {number[]} customersIds - Customers ids. - * @return {Promise} - */ - public async getCustomersPeriodTransactions( - tenantId: number, - fromDate: Date, - toDate: Date - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - - const receivableAccounts = await this.getReceivableAccounts(tenantId); - const receivableAccountsIds = map(receivableAccounts, 'id'); - - const transactions = await AccountTransaction.query().onBuild((query) => { - // Filter by date. - query.modify('filterDateRange', fromDate, toDate); - - // Filter by customers. - query.whereNot('contactId', null); - - // Filter by accounts. - query.whereIn('accountId', receivableAccountsIds); - }); - return transactions; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersService.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersService.ts deleted file mode 100644 index e30c9bc18..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersService.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { Inject } from 'typedi'; -import * as R from 'ramda'; -import moment from 'moment'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - ITransactionsByCustomersService, - ITransactionsByCustomersFilter, - ITransactionsByCustomersStatement, - ILedgerEntry, -} from '@/interfaces'; -import TransactionsByCustomers from './TransactionsByCustomers'; -import Ledger from '@/services/Accounting/Ledger'; -import TransactionsByCustomersRepository from './TransactionsByCustomersRepository'; -import { Tenant } from '@/system/models'; -import { TransactionsByCustomersMeta } from './TransactionsByCustomersMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -export class TransactionsByCustomersSheet - implements ITransactionsByCustomersService -{ - @Inject() - private tenancy: TenancyService; - - @Inject() - private reportRepository: TransactionsByCustomersRepository; - - @Inject() - private transactionsByCustomersMeta: TransactionsByCustomersMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {ICustomerBalanceSummaryQuery} - */ - private get defaultQuery(): ITransactionsByCustomersFilter { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - comparison: { - percentageOfColumn: true, - }, - noneZero: false, - noneTransactions: true, - customersIds: [], - }; - } - - /** - * Retrieve the customers opening balance ledger entries. - * @param {number} tenantId - * @param {Date} openingDate - * @param {number[]} customersIds - * @returns {Promise} - */ - private async getCustomersOpeningBalanceEntries( - tenantId: number, - openingDate: Date, - customersIds?: number[] - ): Promise { - const openingTransactions = - await this.reportRepository.getCustomersOpeningBalanceTransactions( - tenantId, - openingDate, - customersIds - ); - - return R.compose( - R.map(R.assoc('date', openingDate)), - R.map(R.assoc('accountNormal', 'debit')) - )(openingTransactions); - } - - /** - * Retrieve the customers periods ledger entries. - * @param {number} tenantId - * @param {Date} fromDate - * @param {Date} toDate - * @returns {Promise} - */ - private async getCustomersPeriodsEntries( - tenantId: number, - fromDate: Date | string, - toDate: Date | string - ): Promise { - const transactions = - await this.reportRepository.getCustomersPeriodTransactions( - tenantId, - fromDate, - toDate - ); - return R.compose( - R.map(R.assoc('accountNormal', 'debit')), - R.map((trans) => ({ - ...trans, - referenceTypeFormatted: trans.referenceTypeFormatted, - })) - )(transactions); - } - - /** - * Retrieve transactions by by the customers. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} query - * @return {Promise} - */ - public async transactionsByCustomers( - tenantId: number, - query: ITransactionsByCustomersFilter - ): Promise { - const { accountRepository } = this.tenancy.repositories(tenantId); - const i18n = this.tenancy.i18n(tenantId); - - // Retrieve tenant information. - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { - ...this.defaultQuery, - ...query, - }; - const accountsGraph = await accountRepository.getDependencyGraph(); - - // Retrieve the report customers. - const customers = await this.reportRepository.getCustomers( - tenantId, - filter.customersIds - ); - - const openingBalanceDate = moment(filter.fromDate) - .subtract(1, 'days') - .toDate(); - - // Retrieve all ledger transactions of the opening balance of. - const openingBalanceEntries = await this.getCustomersOpeningBalanceEntries( - tenantId, - openingBalanceDate - ); - // Retrieve all ledger transactions between opeing and closing period. - const customersTransactions = await this.getCustomersPeriodsEntries( - tenantId, - query.fromDate, - query.toDate - ); - // Concats the opening balance and period customer ledger transactions. - const journalTransactions = [ - ...openingBalanceEntries, - ...customersTransactions, - ]; - const journal = new Ledger(journalTransactions); - - // Transactions by customers data mapper. - const reportInstance = new TransactionsByCustomers( - customers, - accountsGraph, - journal, - filter, - tenant.metadata.baseCurrency, - i18n - ); - - const meta = await this.transactionsByCustomersMeta.meta(tenantId, filter); - - // Triggers `onCustomerTransactionsViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onCustomerTransactionsViewed, - { - tenantId, - query, - } - ); - - return { - data: reportInstance.reportData(), - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTable.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTable.ts deleted file mode 100644 index 2f38b9cde..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTable.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as R from 'ramda'; -import { tableRowMapper } from 'utils'; -import { - ITransactionsByCustomersCustomer, - ITableRow, - ITableColumn, -} from '@/interfaces'; -import TransactionsByContactsTableRows from '../TransactionsByContact/TransactionsByContactTableRows'; - -enum ROW_TYPE { - OPENING_BALANCE = 'OPENING_BALANCE', - CLOSING_BALANCE = 'CLOSING_BALANCE', - TRANSACTION = 'TRANSACTION', - CUSTOMER = 'CUSTOMER', -} - -export class TransactionsByCustomersTable extends TransactionsByContactsTableRows { - private customersTransactions: ITransactionsByCustomersCustomer[]; - - /** - * Constructor method. - * @param {ITransactionsByCustomersCustomer[]} customersTransactions - Customers transactions. - */ - constructor(customersTransactions: ITransactionsByCustomersCustomer[], i18n) { - super(); - this.customersTransactions = customersTransactions; - this.i18n = i18n; - } - - /** - * Retrieve the table row of customer details. - * @param {ITransactionsByCustomersCustomer} customer - - * @returns {ITableRow[]} - */ - private customerDetails = (customer: ITransactionsByCustomersCustomer) => { - const columns = [ - { key: 'customerName', accessor: 'customerName' }, - ...R.repeat({ key: 'empty', value: '' }, 5), - { - key: 'closingBalanceValue', - accessor: 'closingBalance.formattedAmount', - }, - ]; - - return { - ...tableRowMapper(customer, columns, { rowTypes: [ROW_TYPE.CUSTOMER] }), - children: R.pipe( - R.when( - R.always(customer.transactions.length > 0), - R.pipe( - R.concat(this.contactTransactions(customer)), - R.prepend(this.contactOpeningBalance(customer)) - ) - ), - R.append(this.contactClosingBalance(customer)) - )([]), - }; - }; - - /** - * Retrieve the table rows of the customer section. - * @param {ITransactionsByCustomersCustomer} customer - * @returns {ITableRow[]} - */ - private customerRowsMapper = (customer: ITransactionsByCustomersCustomer) => { - return R.pipe(this.customerDetails)(customer); - }; - - /** - * Retrieve the table rows of transactions by customers report. - * @param {ITransactionsByCustomersCustomer[]} customers - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return R.map(this.customerRowsMapper.bind(this))( - this.customersTransactions - ); - }; - - /** - * Retrieve the table columns of transactions by customers report. - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return [ - { key: 'customer_name', label: 'Customer name' }, - { key: 'account_name', label: 'Account Name' }, - { key: 'ref_type', label: 'Reference Type' }, - { key: 'transaction_type', label: 'Transaction Type' }, - { key: 'credit', label: 'Credit' }, - { key: 'debit', label: 'Debit' }, - { key: 'running_balance', label: 'Running Balance' }, - ]; - }; -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts b/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts deleted file mode 100644 index 2f2aa0277..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByCustomer/TransactionsByCustomersTableInjectable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ITransactionsByCustomersFilter, ITransactionsByCustomersTable } from '@/interfaces'; -import { TransactionsByCustomersSheet } from './TransactionsByCustomersService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransactionsByCustomersTable } from './TransactionsByCustomersTable'; - -@Service() -export class TransactionsByCustomersTableInjectable { - @Inject() - private transactionsByCustomerService: TransactionsByCustomersSheet; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the transactions by customers sheet in table format. - * @param {number} tenantId - * @param {ITransactionsByCustomersFilter} filter - * @returns {Promise} - */ - public async table( - tenantId: number, - filter: ITransactionsByCustomersFilter - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const customersTransactions = - await this.transactionsByCustomerService.transactionsByCustomers( - tenantId, - filter - ); - const table = new TransactionsByCustomersTable( - customersTransactions.data, - i18n - ); - return { - table: { - rows: table.tableRows(), - columns: table.tableColumns(), - }, - query: customersTransactions.query, - meta: customersTransactions.meta - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceReport.ts b/packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceReport.ts deleted file mode 100644 index d3eb43897..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceReport.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { - IAccount, - IAccountTransaction, - INumberFormatQuery, - ITransactionsByReferenceQuery, - ITransactionsByReferenceTransaction, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; - -export default class TransactionsByReference extends FinancialSheet { - readonly transactions: IAccountTransaction[]; - readonly query: ITransactionsByReferenceQuery; - readonly baseCurrency: string; - readonly numberFormat: INumberFormatQuery; - - /** - * Constructor method. - * @param {IAccountTransaction[]} transactions - * @param {ITransactionsByReferenceQuery} query - * @param {string} baseCurrency - */ - constructor( - transactions: (IAccountTransaction & { account: IAccount }) [], - query: ITransactionsByReferenceQuery, - baseCurrency: string - ) { - super(); - - this.transactions = transactions; - this.query = query; - this.baseCurrency = baseCurrency; - this.numberFormat = this.query.numberFormat; - } - - /** - * Mappes the given account transaction to report transaction. - * @param {IAccountTransaction} transaction - * @returns {ITransactionsByReferenceTransaction} - */ - private transactionMapper = ( - transaction: IAccountTransaction - ): ITransactionsByReferenceTransaction => { - return { - date: this.getDateMeta(transaction.date), - - credit: this.getAmountMeta(transaction.credit, { money: false }), - debit: this.getAmountMeta(transaction.debit, { money: false }), - - referenceTypeFormatted: transaction.referenceTypeFormatted, - referenceType: transaction.referenceType, - referenceId: transaction.referenceId, - - contactId: transaction.contactId, - contactType: transaction.contactType, - contactTypeFormatted: transaction.contactType, - - accountName: transaction.account.name, - accountCode: transaction.account.code, - accountId: transaction.accountId, - }; - }; - - /** - * Mappes the given accounts transactions to report transactions. - * @param {IAccountTransaction} transaction - * @returns {ITransactionsByReferenceTransaction} - */ - private transactionsMapper = ( - transactions: IAccountTransaction[] - ): ITransactionsByReferenceTransaction[] => { - return transactions.map(this.transactionMapper); - }; - - /** - * Retrieve the report data. - * @returns {ITransactionsByReferenceTransaction} - */ - public reportData(): ITransactionsByReferenceTransaction[] { - return this.transactionsMapper(this.transactions); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceRepository.ts b/packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceRepository.ts deleted file mode 100644 index fa20028bc..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByReference/TransactionsByReferenceRepository.ts +++ /dev/null @@ -1,29 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import { IAccount, IAccountTransaction, ITransactionsByReferenceQuery } from '@/interfaces'; - -@Service() -export default class TransactionsByReferenceRepository { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve the accounts transactions of the givne reference id and type. - * @param {number} tenantId - - * @param {number} referenceId - Reference id. - * @param {string} referenceType - Reference type. - * @return {Promise} - */ - public getTransactions( - tenantId: number, - referenceId: number, - referenceType: string, - ): Promise<(IAccountTransaction & { account: IAccount }) []> { - const { AccountTransaction } = this.tenancy.models(tenantId); - - return AccountTransaction.query() - .where('reference_id', referenceId) - .where('reference_type', referenceType) - .withGraphFetched('account'); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByReference/index.ts b/packages/server/src/services/FinancialStatements/TransactionsByReference/index.ts deleted file mode 100644 index 0cc0ad6c1..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByReference/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - ITransactionsByReferenceQuery, - ITransactionsByReferenceTransaction, -} from '@/interfaces'; -import TransactionsByReferenceRepository from './TransactionsByReferenceRepository'; -import TransactionsByReferenceReport from './TransactionsByReferenceReport'; - -@Service() -export default class TransactionsByReferenceService { - @Inject() - tenancy: HasTenancyService; - - @Inject('logger') - logger: any; - - @Inject() - reportRepository: TransactionsByReferenceRepository; - - /** - * Default query of transactions by reference report. - */ - get defaultQuery(): ITransactionsByReferenceQuery { - return { - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - }; - } - - /** - * Retrieve accounts transactions by given reference id and type. - * @param {number} tenantId - * @param {ITransactionsByReferenceQuery} filter - */ - public async getTransactionsByReference( - tenantId: number, - query: ITransactionsByReferenceQuery - ): Promise<{ - transactions: ITransactionsByReferenceTransaction[]; - }> { - const filter = { - ...this.defaultQuery, - ...query, - }; - - // Retrieve the accounts transactions of the given reference. - const transactions = await this.reportRepository.getTransactions( - tenantId, - filter.referenceId, - filter.referenceType - ); - - // Settings tenant service. - const settings = this.tenancy.settings(tenantId); - const baseCurrency = settings.get({ - group: 'organization', - key: 'base_currency', - }); - - // Transactions by reference report. - const report = new TransactionsByReferenceReport( - transactions, - filter, - baseCurrency - ); - - return { - transactions: report.reportData(), - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendor.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendor.ts deleted file mode 100644 index 500e548f7..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendor.ts +++ /dev/null @@ -1,140 +0,0 @@ -import * as R from 'ramda'; -import { isEmpty, sumBy } from 'lodash'; -import { - ITransactionsByContactsTransaction, - ITransactionsByVendorsFilter, - ITransactionsByVendorsTransaction, - ITransactionsByVendorsVendor, - ITransactionsByVendorsData, - ILedger, - INumberFormatQuery, - IVendor, -} from '@/interfaces'; -import TransactionsByContact from '../TransactionsByContact/TransactionsByContact'; - -const VENDOR_NORMAL = 'credit'; - -export default class TransactionsByVendors extends TransactionsByContact { - readonly contacts: IVendor[]; - readonly transactionsByContact: any; - readonly filter: ITransactionsByVendorsFilter; - readonly baseCurrency: string; - readonly numberFormat: INumberFormatQuery; - readonly accountsGraph: any; - readonly ledger: ILedger; - - /** - * Constructor method. - * @param {IVendor} vendors - * @param {Map} transactionsByContact - * @param {string} baseCurrency - */ - constructor( - vendors: IVendor[], - accountsGraph: any, - ledger: ILedger, - filter: ITransactionsByVendorsFilter, - baseCurrency: string, - i18n - ) { - super(); - - this.contacts = vendors; - this.accountsGraph = accountsGraph; - this.ledger = ledger; - this.baseCurrency = baseCurrency; - this.filter = filter; - this.numberFormat = this.filter.numberFormat; - this.i18n = i18n; - } - - /** - * Retrieve the vendor transactions from the given vendor id and opening balance. - * @param {number} vendorId - Vendor id. - * @param {number} openingBalance - Opening balance amount. - * @returns {ITransactionsByVendorsTransaction[]} - */ - private vendorTransactions( - vendorId: number, - openingBalance: number - ): ITransactionsByVendorsTransaction[] { - const openingBalanceLedger = this.ledger - .whereContactId(vendorId) - .whereFromDate(this.filter.fromDate) - .whereToDate(this.filter.toDate); - - const openingEntries = openingBalanceLedger.getEntries(); - - return R.compose( - R.curry(this.contactTransactionRunningBalance)(openingBalance, 'credit'), - R.map(this.contactTransactionMapper.bind(this)) - ).bind(this)(openingEntries); - } - - /** - * Vendor section mapper. - * @param {IVendor} vendor - * @returns {ITransactionsByVendorsVendor} - */ - private vendorMapper(vendor: IVendor): ITransactionsByVendorsVendor { - const openingBalance = this.getContactOpeningBalance(vendor.id); - const transactions = this.vendorTransactions(vendor.id, openingBalance); - const closingBalance = this.getVendorClosingBalance( - transactions, - openingBalance - ); - const currencyCode = this.baseCurrency; - - return { - vendorName: vendor.displayName, - openingBalance: this.getTotalAmountMeta(openingBalance, currencyCode), - closingBalance: this.getTotalAmountMeta(closingBalance, currencyCode), - transactions, - }; - } - - /** - * Retrieve the vendor closing balance from the given customer transactions. - * @param {ITransactionsByContactsTransaction[]} customerTransactions - * @param {number} openingBalance - * @returns - */ - private getVendorClosingBalance( - customerTransactions: ITransactionsByContactsTransaction[], - openingBalance: number - ) { - return this.getContactClosingBalance( - customerTransactions, - VENDOR_NORMAL, - openingBalance - ); - } - - /** - * Detarmines whether the vendors post filter is active. - * @returns {boolean} - */ - private isVendorsPostFilter = (): boolean => { - return isEmpty(this.filter.vendorsIds); - }; - - /** - * Retrieve the vendors sections of the report. - * @param {IVendor[]} vendors - * @returns {ITransactionsByVendorsVendor[]} - */ - private vendorsMapper(vendors: IVendor[]): ITransactionsByVendorsVendor[] { - return R.compose( - R.when(this.isVendorsPostFilter, this.contactsFilter), - R.map(this.vendorMapper.bind(this)) - ).bind(this)(vendors); - } - - /** - * Retrieve the report data. - * @returns {ITransactionsByVendorsData} - */ - public reportData(): ITransactionsByVendorsData { - return this.vendorsMapper(this.contacts); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorApplication.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorApplication.ts deleted file mode 100644 index 54a4c7ed4..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorApplication.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ITransactionsByVendorTable, - ITransactionsByVendorsFilter, - ITransactionsByVendorsStatement, -} from '@/interfaces'; -import { TransactionsByVendorExportInjectable } from './TransactionsByVendorExportInjectable'; -import { TransactionsByVendorTableInjectable } from './TransactionsByVendorTableInjectable'; -import { TransactionsByVendorsInjectable } from './TransactionsByVendorInjectable'; -import { TransactionsByVendorsPdf } from './TransactionsByVendorPdf'; - -@Service() -export class TransactionsByVendorApplication { - @Inject() - private transactionsByVendorTable: TransactionsByVendorTableInjectable; - - @Inject() - private transactionsByVendorExport: TransactionsByVendorExportInjectable; - - @Inject() - private transactionsByVendorSheet: TransactionsByVendorsInjectable; - - @Inject() - private transactionsByVendorPdf: TransactionsByVendorsPdf; - - /** - * Retrieves the transactions by vendor in sheet format. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @returns {Promise} - */ - public sheet( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - return this.transactionsByVendorSheet.transactionsByVendors( - tenantId, - query - ); - } - - /** - * Retrieves the transactions by vendor in table format. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @returns {Promise} - */ - public table( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - return this.transactionsByVendorTable.table(tenantId, query); - } - - /** - * Retrieves the transactions by vendor in CSV format. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @returns {Promise} - */ - public csv( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - return this.transactionsByVendorExport.csv(tenantId, query); - } - - /** - * Retrieves the transactions by vendor in XLSX format. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @returns {Promise} - */ - public xlsx( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - return this.transactionsByVendorExport.xlsx(tenantId, query); - } - - /** - * Retrieves the transactions by vendor in PDF format. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: ITransactionsByVendorsFilter) { - return this.transactionsByVendorPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorExportInjectable.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorExportInjectable.ts deleted file mode 100644 index 1d547e752..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorExportInjectable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ITransactionsByVendorsFilter } from '@/interfaces'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { TransactionsByVendorTableInjectable } from './TransactionsByVendorTableInjectable'; - -@Service() -export class TransactionsByVendorExportInjectable { - @Inject() - private transactionsByVendorTable: TransactionsByVendorTableInjectable; - - /** - * Retrieves the cashflow sheet in XLSX format. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @returns {Promise} - */ - public async xlsx( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - const table = await this.transactionsByVendorTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the cashflow sheet in CSV format. - * @param {number} tenantId - * @param {ICashFlowStatementQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - const table = await this.transactionsByVendorTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorInjectable.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorInjectable.ts deleted file mode 100644 index 165ff4edd..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorInjectable.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { Inject } from 'typedi'; -import moment from 'moment'; -import * as R from 'ramda'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - ITransactionsByVendorsService, - ITransactionsByVendorsFilter, - ITransactionsByVendorsStatement, - ILedgerEntry, -} from '@/interfaces'; -import TransactionsByVendor from './TransactionsByVendor'; -import Ledger from '@/services/Accounting/Ledger'; -import TransactionsByVendorRepository from './TransactionsByVendorRepository'; -import { Tenant } from '@/system/models'; -import { TransactionsByVendorMeta } from './TransactionsByVendorMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -export class TransactionsByVendorsInjectable - implements ITransactionsByVendorsService -{ - @Inject() - private tenancy: TenancyService; - - @Inject() - private reportRepository: TransactionsByVendorRepository; - - @Inject() - private transactionsByVendorMeta: TransactionsByVendorMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {IVendorBalanceSummaryQuery} - */ - get defaultQuery(): ITransactionsByVendorsFilter { - return { - fromDate: moment().startOf('month').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - comparison: { - percentageOfColumn: true, - }, - noneZero: false, - noneTransactions: true, - vendorsIds: [], - }; - } - - /** - * Retrieve the customers opening balance transactions. - * @param {number} tenantId - * @param {number} openingDate - * @param {number} customersIds - * @returns {Promise} - */ - private async getVendorsOpeningBalanceEntries( - tenantId: number, - openingDate: Date, - customersIds?: number[] - ): Promise { - const openingTransactions = - await this.reportRepository.getVendorsOpeningBalance( - tenantId, - openingDate, - customersIds - ); - return R.compose( - R.map(R.assoc('date', openingDate)), - R.map(R.assoc('accountNormal', 'credit')) - )(openingTransactions); - } - - /** - * - * @param {number} tenantId - * @param {Date|string} openingDate - * @param {number[]} customersIds - */ - private async getVendorsPeriodEntries( - tenantId: number, - fromDate: Date, - toDate: Date - ): Promise { - const transactions = - await this.reportRepository.getVendorsPeriodTransactions( - tenantId, - fromDate, - toDate - ); - return R.compose( - R.map(R.assoc('accountNormal', 'credit')), - R.map((trans) => ({ - ...trans, - referenceTypeFormatted: trans.referenceTypeFormatted, - })) - )(transactions); - } - - /** - * Retrieve the report ledger entries from repository. - * @param {number} tenantId - * @param {Date} fromDate - * @param {Date} toDate - * @returns {Promise} - */ - private async getReportEntries( - tenantId: number, - fromDate: Date, - toDate: Date - ): Promise { - const openingBalanceDate = moment(fromDate).subtract(1, 'days').toDate(); - - return [ - ...(await this.getVendorsOpeningBalanceEntries( - tenantId, - openingBalanceDate - )), - ...(await this.getVendorsPeriodEntries(tenantId, fromDate, toDate)), - ]; - } - - /** - * Retrieve transactions by by the customers. - * @param {number} tenantId - * @param {ITransactionsByVendorsFilter} query - * @return {Promise} - */ - public async transactionsByVendors( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const i18n = this.tenancy.i18n(tenantId); - - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { ...this.defaultQuery, ...query }; - - // Retrieve the report vendors. - const vendors = await this.reportRepository.getVendors( - tenantId, - filter.vendorsIds - ); - // Retrieve the accounts graph. - const accountsGraph = await accountRepository.getDependencyGraph(); - - // Journal transactions. - const reportEntries = await this.getReportEntries( - tenantId, - filter.fromDate, - filter.toDate - ); - // Ledger collection. - const journal = new Ledger(reportEntries); - - // Transactions by customers data mapper. - const reportInstance = new TransactionsByVendor( - vendors, - accountsGraph, - journal, - filter, - tenant.metadata.baseCurrency, - i18n - ); - const meta = await this.transactionsByVendorMeta.meta(tenantId, filter); - - // Triggers `onVendorTransactionsViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onVendorTransactionsViewed, - { - tenantId, - query, - } - ); - - return { - data: reportInstance.reportData(), - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorMeta.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorMeta.ts deleted file mode 100644 index 42295cc22..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorMeta.ts +++ /dev/null @@ -1,38 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { - ITransactionsByVendorMeta, - ITransactionsByVendorsFilter, -} from '@/interfaces'; - -@Service() -export class TransactionsByVendorMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the transactions by vendor meta. - * @param {number} tenantId - - * @returns {Promise} - */ - public async meta( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} | To ${formattedToDate}`; - - const sheetName = 'Transactions By Vendor'; - - return { - ...commonMeta, - sheetName, - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorPdf.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorPdf.ts deleted file mode 100644 index d133a9ebc..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorPdf.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ITransactionsByVendorsFilter } from '@/interfaces'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { TransactionsByVendorTableInjectable } from './TransactionsByVendorTableInjectable'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class TransactionsByVendorsPdf { - @Inject() - private transactionsByVendorTable: TransactionsByVendorTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given balance sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {IBalanceSheetQuery} query - Balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - const table = await this.transactionsByVendorTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorRepository.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorRepository.ts deleted file mode 100644 index d0b50873f..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorRepository.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty, map } from 'lodash'; -import { IVendor, IAccount, IAccountTransaction } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -@Service() -export default class TransactionsByVendorRepository { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieve the report vendors. - * @param {number} tenantId - * @returns {Promise} - */ - public getVendors( - tenantId: number, - vendorsIds?: number[] - ): Promise { - const { Vendor } = this.tenancy.models(tenantId); - - return Vendor.query().onBuild((q) => { - q.orderBy('displayName'); - - if (!isEmpty(vendorsIds)) { - q.whereIn('id', vendorsIds); - } - }); - } - - /** - * Retrieve the accounts receivable. - * @param {number} tenantId - * @returns {Promise} - */ - private async getPayableAccounts(tenantId: number): Promise { - const { Account } = this.tenancy.models(tenantId); - - const accounts = await Account.query().where( - 'accountType', - ACCOUNT_TYPE.ACCOUNTS_PAYABLE - ); - return accounts; - } - - /** - * Retrieve the customers opening balance transactions. - * @param {number} tenantId - * @param {number} openingDate - * @param {number} customersIds - * @returns {} - */ - public async getVendorsOpeningBalance( - tenantId: number, - openingDate: Date, - customersIds?: number[] - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - - const payableAccounts = await this.getPayableAccounts(tenantId); - const payableAccountsIds = map(payableAccounts, 'id'); - - const openingTransactions = await AccountTransaction.query().modify( - 'contactsOpeningBalance', - openingDate, - payableAccountsIds, - customersIds - ); - return openingTransactions; - } - - /** - * Retrieve vendors periods transactions. - * @param {number} tenantId - * @param {Date|string} openingDate - * @param {number[]} customersIds - */ - public async getVendorsPeriodTransactions( - tenantId: number, - fromDate: Date, - toDate: Date - ): Promise { - const { AccountTransaction } = this.tenancy.models(tenantId); - - const receivableAccounts = await this.getPayableAccounts(tenantId); - const receivableAccountsIds = map(receivableAccounts, 'id'); - - const transactions = await AccountTransaction.query().onBuild((query) => { - // Filter by date. - query.modify('filterDateRange', fromDate, toDate); - - // Filter by customers. - query.whereNot('contactId', null); - - // Filter by accounts. - query.whereIn('accountId', receivableAccountsIds); - }); - return transactions; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTable.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTable.ts deleted file mode 100644 index 2f8bf2498..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTable.ts +++ /dev/null @@ -1,94 +0,0 @@ -import * as R from 'ramda'; -import { tableRowMapper } from 'utils'; -import { - ITransactionsByVendorsVendor, - ITableRow, - ITableColumn, -} from '@/interfaces'; -import TransactionsByContactsTableRows from '../TransactionsByContact/TransactionsByContactTableRows'; - -enum ROW_TYPE { - OPENING_BALANCE = 'OPENING_BALANCE', - CLOSING_BALANCE = 'CLOSING_BALANCE', - TRANSACTION = 'TRANSACTION', - VENDOR = 'VENDOR', -} - -export class TransactionsByVendorsTable extends TransactionsByContactsTableRows { - private vendorsTransactions: ITransactionsByVendorsVendor[]; - - /** - * Constructor method. - * @param {ITransactionsByVendorsVendor[]} vendorsTransactions - - * @param {any} i18n - */ - constructor(vendorsTransactions: ITransactionsByVendorsVendor[], i18n) { - super(); - - this.vendorsTransactions = vendorsTransactions; - this.i18n = i18n; - } - - /** - * Retrieve the table row of vendor details. - * @param {ITransactionsByVendorsVendor} vendor - - * @returns {ITableRow[]} - */ - private vendorDetails = (vendor: ITransactionsByVendorsVendor) => { - const columns = [ - { key: 'vendorName', accessor: 'vendorName' }, - ...R.repeat({ key: 'empty', value: '' }, 5), - { - key: 'closingBalanceValue', - accessor: 'closingBalance.formattedAmount', - }, - ]; - return { - ...tableRowMapper(vendor, columns, { rowTypes: [ROW_TYPE.VENDOR] }), - children: R.pipe( - R.when( - R.always(vendor.transactions.length > 0), - R.pipe( - R.concat(this.contactTransactions(vendor)), - R.prepend(this.contactOpeningBalance(vendor)) - ) - ), - R.append(this.contactClosingBalance(vendor)) - )([]), - }; - }; - - /** - * Retrieve the table rows of the vendor section. - * @param {ITransactionsByVendorsVendor} vendor - * @returns {ITableRow[]} - */ - private vendorRowsMapper = (vendor: ITransactionsByVendorsVendor) => { - return R.pipe(this.vendorDetails)(vendor); - }; - - /** - * Retrieve the table rows of transactions by vendors report. - * @param {ITransactionsByVendorsVendor[]} vendors - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return R.map(this.vendorRowsMapper)(this.vendorsTransactions); - }; - - /** - * Retrieve the table columns of transactions by vendors report. - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return [ - { key: 'vendor_name', label: 'Vendor name' }, - { key: 'account_name', label: 'Account Name' }, - { key: 'ref_type', label: 'Reference Type' }, - { key: 'transaction_type', label: 'Transaction Type' }, - { key: 'credit', label: 'Credit' }, - { key: 'debit', label: 'Debit' }, - { key: 'running_balance', label: 'Running Balance' }, - ]; - }; -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTableInjectable.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTableInjectable.ts deleted file mode 100644 index 5c5243059..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/TransactionsByVendorTableInjectable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransactionsByVendorsTable } from './TransactionsByVendorTable'; -import { - ITransactionsByVendorTable, - ITransactionsByVendorsFilter, -} from '@/interfaces'; -import { TransactionsByVendorsInjectable } from './TransactionsByVendorInjectable'; - -@Service() -export class TransactionsByVendorTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transactionsByVendor: TransactionsByVendorsInjectable; - - /** - * Retrieves the transactions by vendor in table format. - * @param {number} tenantId - * @param {ITransactionsByReferenceQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: ITransactionsByVendorsFilter - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const sheet = await this.transactionsByVendor.transactionsByVendors( - tenantId, - query - ); - const table = new TransactionsByVendorsTable(sheet.data, i18n); - - return { - table: { - rows: table.tableRows(), - columns: table.tableColumns(), - }, - query, - meta: sheet.meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TransactionsByVendor/constants.ts b/packages/server/src/services/FinancialStatements/TransactionsByVendor/constants.ts deleted file mode 100644 index d35a2f105..000000000 --- a/packages/server/src/services/FinancialStatements/TransactionsByVendor/constants.ts +++ /dev/null @@ -1,23 +0,0 @@ -export const HtmlTableCustomCss = ` -table tr td:not(:first-child) { - border-left: 1px solid #ececec; -} -table tr:last-child td { - border-bottom: 1px solid #ececec; -} -table .cell--credit, -table .cell--debit, -table .column--credit, -table .column--debit, -table .column--running_balance, -table .cell--running_balance{ - text-align: right; -} -table tr.row-type--closing-balance td, -table tr.row-type--opening-balance td { - font-weight: 600; -} -table tr.row-type--vendor:not(:first-child) td { - border-top: 1px solid #ddd; -} -`; diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts deleted file mode 100644 index 62b847f7c..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; -import { ITrialBalanceSheetQuery } from '@/interfaces'; -import { TrialBalanceSheetTableInjectable } from './TrialBalanceSheetTableInjectable'; -import { TrialBalanceSheetPdfInjectable } from './TrialBalanceSheetPdfInjectsable'; - -@Service() -export class TrialBalanceExportInjectable { - @Inject() - private trialBalanceSheetTable: TrialBalanceSheetTableInjectable; - - @Inject() - private trialBalanceSheetPdf: TrialBalanceSheetPdfInjectable; - - /** - * Retrieves the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: ITrialBalanceSheetQuery) { - const table = await this.trialBalanceSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - const table = await this.trialBalanceSheetTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } - - /** - * Retrieves the trial balance sheet in PDF format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - return this.trialBalanceSheetPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.ts deleted file mode 100644 index 8554268e3..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { sumBy } from 'lodash'; -import * as R from 'ramda'; -import { - ITrialBalanceSheetQuery, - ITrialBalanceAccount, - IAccount, - ITrialBalanceTotal, - ITrialBalanceSheetData, - IAccountType, -} from '@/interfaces'; -import FinancialSheet from '../FinancialSheet'; -import { allPassedConditionsPass, flatToNestedArray } from 'utils'; -import { TrialBalanceSheetRepository } from './TrialBalanceSheetRepository'; - -export default class TrialBalanceSheet extends FinancialSheet { - /** - * Trial balance sheet query. - * @param {ITrialBalanceSheetQuery} query - */ - private query: ITrialBalanceSheetQuery; - - /** - * Trial balance sheet repository. - * @param {TrialBalanceSheetRepository} - */ - private repository: TrialBalanceSheetRepository; - - /** - * Organization base currency. - * @param {string} - */ - private baseCurrency: string; - - /** - * Constructor method. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @param {IAccount[]} accounts - * @param journalFinancial - */ - constructor( - tenantId: number, - query: ITrialBalanceSheetQuery, - repository: TrialBalanceSheetRepository, - baseCurrency: string - ) { - super(); - - this.tenantId = tenantId; - this.query = query; - this.repository = repository; - this.numberFormat = this.query.numberFormat; - this.baseCurrency = baseCurrency; - } - - /** - * Retrieves the closing credit of the given account. - * @param {number} accountId - * @returns {number} - */ - public getClosingAccountCredit(accountId: number) { - const depsAccountsIds = - this.repository.accountsDepGraph.dependenciesOf(accountId); - - return this.repository.totalAccountsLedger - .whereAccountsIds([accountId, ...depsAccountsIds]) - .getClosingCredit(); - } - - /** - * Retrieves the closing debit of the given account. - * @param {number} accountId - * @returns {number} - */ - public getClosingAccountDebit(accountId: number) { - const depsAccountsIds = - this.repository.accountsDepGraph.dependenciesOf(accountId); - - return this.repository.totalAccountsLedger - .whereAccountsIds([accountId, ...depsAccountsIds]) - .getClosingDebit(); - } - - /** - * Retrieves the closing total of the given account. - * @param {number} accountId - * @returns {number} - */ - public getClosingAccountTotal(accountId: number) { - const credit = this.getClosingAccountCredit(accountId); - const debit = this.getClosingAccountDebit(accountId); - - return debit - credit; - } - - /** - * Account mapper. - * @param {IAccount} account - * @return {ITrialBalanceAccount} - */ - private accountTransformer = ( - account: IAccount & { type: IAccountType } - ): ITrialBalanceAccount => { - const debit = this.getClosingAccountDebit(account.id); - const credit = this.getClosingAccountCredit(account.id); - const balance = this.getClosingAccountTotal(account.id); - - return { - id: account.id, - parentAccountId: account.parentAccountId, - name: account.name, - formattedName: account.code - ? `${account.name} - ${account.code}` - : `${account.name}`, - code: account.code, - accountNormal: account.accountNormal, - - credit, - debit, - balance, - currencyCode: this.baseCurrency, - - formattedCredit: this.formatNumber(credit), - formattedDebit: this.formatNumber(debit), - formattedBalance: this.formatNumber(balance), - }; - }; - - /** - * Filters trial balance sheet accounts nodes based on the given report query. - * @param {ITrialBalanceAccount} accountNode - * @returns {boolean} - */ - private accountFilter = (accountNode: ITrialBalanceAccount): boolean => { - const { noneTransactions, noneZero, onlyActive } = this.query; - - // Conditions pair filter detarminer. - const condsPairFilters = [ - [noneTransactions, this.filterNoneTransactions], - [noneZero, this.filterNoneZero], - [onlyActive, this.filterActiveOnly], - ]; - return allPassedConditionsPass(condsPairFilters)(accountNode); - }; - - /** - * Fitlers the accounts nodes. - * @param {ITrialBalanceAccount[]} accountsNodes - * @returns {ITrialBalanceAccount[]} - */ - private accountsFilter = ( - accountsNodes: ITrialBalanceAccount[] - ): ITrialBalanceAccount[] => { - return accountsNodes.filter(this.accountFilter); - }; - - /** - * Mappes the given account object to trial balance account node. - * @param {IAccount[]} accountsNodes - * @returns {ITrialBalanceAccount[]} - */ - private accountsMapper = ( - accountsNodes: IAccount[] - ): ITrialBalanceAccount[] => { - return accountsNodes.map(this.accountTransformer); - }; - - /** - * Detarmines whether the given account node is not none transactions. - * @param {ITrialBalanceAccount} accountNode - * @returns {boolean} - */ - private filterNoneTransactions = ( - accountNode: ITrialBalanceAccount - ): boolean => { - return false === this.repository.totalAccountsLedger.isEmpty(); - }; - - /** - * Detarmines whether the given account none zero. - * @param {ITrialBalanceAccount} accountNode - * @returns {boolean} - */ - private filterNoneZero = (accountNode: ITrialBalanceAccount): boolean => { - return accountNode.balance !== 0; - }; - - /** - * Detarmines whether the given account is active. - * @param {ITrialBalanceAccount} accountNode - * @returns {boolean} - */ - private filterActiveOnly = (accountNode: ITrialBalanceAccount): boolean => { - return accountNode.credit !== 0 || accountNode.debit !== 0; - }; - - /** - * Transformes the flatten nodes to nested nodes. - * @param {ITrialBalanceAccount[]} flattenAccounts - * @returns {ITrialBalanceAccount[]} - */ - private nestedAccountsNode = ( - flattenAccounts: ITrialBalanceAccount[] - ): ITrialBalanceAccount[] => { - return flatToNestedArray(flattenAccounts, { - id: 'id', - parentId: 'parentAccountId', - }); - }; - - /** - * Retrieve trial balance total section. - * @param {ITrialBalanceAccount[]} accountsBalances - * @return {ITrialBalanceTotal} - */ - private tatalSection( - accountsBalances: ITrialBalanceAccount[] - ): ITrialBalanceTotal { - const credit = sumBy(accountsBalances, 'credit'); - const debit = sumBy(accountsBalances, 'debit'); - const balance = sumBy(accountsBalances, 'balance'); - const currencyCode = this.baseCurrency; - - return { - credit, - debit, - balance, - currencyCode, - formattedCredit: this.formatTotalNumber(credit), - formattedDebit: this.formatTotalNumber(debit), - formattedBalance: this.formatTotalNumber(balance), - }; - } - - /** - * Retrieve accounts section of trial balance report. - * @param {IAccount[]} accounts - * @returns {ITrialBalanceAccount[]} - */ - private accountsSection(accounts: IAccount & { type: IAccountType }[]) { - return R.compose( - this.nestedAccountsNode, - this.accountsFilter, - this.accountsMapper - )(accounts); - } - - /** - * Retrieve trial balance sheet statement data. - * Note: Retruns null in case there is no transactions between the given date periods. - * - * @return {ITrialBalanceSheetData} - */ - public reportData(): ITrialBalanceSheetData { - // Retrieve accounts nodes. - const accounts = this.accountsSection(this.repository.accounts); - - // Retrieve account node. - const total = this.tatalSection(accounts); - - return { accounts, total }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts deleted file mode 100644 index 20c485ecc..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TrialBalanceSheetTableInjectable } from './TrialBalanceSheetTableInjectable'; -import { TrialBalanceExportInjectable } from './TrialBalanceExportInjectable'; -import { ITrialBalanceSheetQuery, ITrialBalanceStatement } from '@/interfaces'; -import TrialBalanceSheetService from './TrialBalanceSheetInjectable'; - -@Service() -export class TrialBalanceSheetApplication { - @Inject() - private sheetService: TrialBalanceSheetService; - - @Inject() - private tablable: TrialBalanceSheetTableInjectable; - - @Inject() - private exportable: TrialBalanceExportInjectable; - - /** - * Retrieves the trial balance sheet. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public sheet( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - return this.sheetService.trialBalanceSheet(tenantId, query); - } - - /** - * Retrieves the trial balance sheet in table format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public table(tenantId: number, query: ITrialBalanceSheetQuery) { - return this.tablable.table(tenantId, query); - } - - /** - * Retrieve the trial balance sheet in CSV format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public csv(tenantId: number, query: ITrialBalanceSheetQuery) { - return this.exportable.csv(tenantId, query); - } - - /** - * Retrieve the trial balance sheet in XLSX format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: ITrialBalanceSheetQuery) { - return this.exportable.xlsx(tenantId, query); - } - - /** - * Retrieve the trial balance sheet in pdf format. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async pdf(tenantId: number, query: ITrialBalanceSheetQuery) { - return this.exportable.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetInjectable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetInjectable.ts deleted file mode 100644 index c33e80fd4..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetInjectable.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ITrialBalanceSheetQuery, ITrialBalanceStatement } from '@/interfaces'; -import TrialBalanceSheet from './TrialBalanceSheet'; -import FinancialSheet from '../FinancialSheet'; -import { Tenant } from '@/system/models'; -import { TrialBalanceSheetRepository } from './TrialBalanceSheetRepository'; -import { TrialBalanceSheetMeta } from './TrialBalanceSheetMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export default class TrialBalanceSheetService extends FinancialSheet { - @Inject() - private tenancy: TenancyService; - - @Inject() - private trialBalanceSheetMetaService: TrialBalanceSheetMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults trial balance sheet filter query. - * @return {IBalanceSheetQuery} - */ - private get defaultQuery(): ITrialBalanceSheetQuery { - return { - fromDate: moment().startOf('year').format('YYYY-MM-DD'), - toDate: moment().format('YYYY-MM-DD'), - numberFormat: { - divideOn1000: false, - negativeFormat: 'mines', - showZero: false, - formatMoney: 'total', - precision: 2, - }, - basis: 'accrual', - noneZero: false, - noneTransactions: true, - onlyActive: false, - accountIds: [], - }; - } - - /** - * Retrieve trial balance sheet statement. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - * @return {IBalanceSheetStatement} - */ - public async trialBalanceSheet( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - const filter = { - ...this.defaultQuery, - ...query, - }; - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const models = this.tenancy.models(tenantId); - const repos = this.tenancy.repositories(tenantId); - - const trialBalanceSheetRepos = new TrialBalanceSheetRepository( - models, - repos, - filter - ); - // Loads the resources. - await trialBalanceSheetRepos.asyncInitialize(); - - // Trial balance report instance. - const trialBalanceInstance = new TrialBalanceSheet( - tenantId, - filter, - trialBalanceSheetRepos, - tenant.metadata.baseCurrency - ); - // Trial balance sheet data. - const trialBalanceSheetData = trialBalanceInstance.reportData(); - - // Trial balance sheet meta. - const meta = await this.trialBalanceSheetMetaService.meta(tenantId, filter); - - // Triggers `onTrialBalanceSheetViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onTrialBalanceSheetView, - { - tenantId, - query, - } - ); - - return { - data: trialBalanceSheetData, - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetMeta.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetMeta.ts deleted file mode 100644 index 7561e2b66..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetMeta.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import { ITrialBalanceSheetMeta, ITrialBalanceSheetQuery } from '@/interfaces'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; - -@Service() -export class TrialBalanceSheetMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the trial balance sheet meta. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async meta( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - - const formattedFromDate = moment(query.fromDate).format('YYYY/MM/DD'); - const formattedToDate = moment(query.toDate).format('YYYY/MM/DD'); - const formattedDateRange = `From ${formattedFromDate} to ${formattedToDate}`; - - const sheetName = 'Trial Balance Sheet'; - - return { - ...commonMeta, - sheetName, - formattedFromDate, - formattedToDate, - formattedDateRange, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts deleted file mode 100644 index b7b53d437..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ITrialBalanceSheetQuery } from '@/interfaces'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { TrialBalanceSheetTableInjectable } from './TrialBalanceSheetTableInjectable'; -import { HtmlTableCustomCss } from './_constants'; - -@Service() -export class TrialBalanceSheetPdfInjectable { - @Inject() - private trialBalanceSheetTable: TrialBalanceSheetTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Converts the given trial balance sheet table to pdf. - * @param {number} tenantId - Tenant ID. - * @param {ITrialBalanceSheetQuery} query - Trial balance sheet query. - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - const table = await this.trialBalanceSheetTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedDateRange, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetRepository.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetRepository.ts deleted file mode 100644 index 1c37edd4d..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetRepository.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { ITrialBalanceSheetQuery } from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; -import { Knex } from 'knex'; -import { isEmpty } from 'lodash'; -import { Service } from 'typedi'; - -@Service() -export class TrialBalanceSheetRepository { - private query: ITrialBalanceSheetQuery; - private models: any; - public accounts: any; - public accountsDepGraph; - - /** - * Total closing accounts ledger. - * @param {Ledger} - */ - public totalAccountsLedger: Ledger; - - /** - * Constructor method. - * @param {number} tenantId - * @param {IBalanceSheetQuery} query - */ - constructor(models: any, repos: any, query: ITrialBalanceSheetQuery) { - this.query = query; - this.repos = repos; - this.models = models; - } - - /** - * Async initialize. - * @returns {Promise} - */ - public asyncInitialize = async () => { - await this.initAccounts(); - await this.initAccountsClosingTotalLedger(); - }; - - // ---------------------------- - // # Accounts - // ---------------------------- - /** - * Initialize accounts. - * @returns {Promise} - */ - public initAccounts = async () => { - const accounts = await this.getAccounts(); - const accountsDepGraph = - await this.repos.accountRepository.getDependencyGraph(); - - this.accountsDepGraph = accountsDepGraph; - this.accounts = accounts; - }; - - /** - * Initialize all accounts closing total ledger. - * @return {Promise} - */ - public initAccountsClosingTotalLedger = async (): Promise => { - const totalByAccounts = await this.closingAccountsTotal(this.query.toDate); - - this.totalAccountsLedger = Ledger.fromTransactions(totalByAccounts); - }; - - /** - * Retrieve accounts of the report. - * @return {Promise} - */ - private getAccounts = () => { - const { Account } = this.models; - - return Account.query(); - }; - - /** - * Retrieve the opening balance transactions of the report. - * @param {Date|string} openingDate - - */ - public closingAccountsTotal = async (openingDate: Date | string) => { - const { AccountTransaction } = this.models; - - return AccountTransaction.query().onBuild((query) => { - query.sum('credit as credit'); - query.sum('debit as debit'); - query.groupBy('accountId'); - query.select(['accountId']); - - query.modify('filterDateRange', null, openingDate); - query.withGraphFetched('account'); - - this.commonFilterBranchesQuery(query); - }); - }; - - /** - * Common branches filter query. - * @param {Knex.QueryBuilder} query - */ - private commonFilterBranchesQuery = (query: Knex.QueryBuilder) => { - if (!isEmpty(this.query.branchesIds)) { - query.modify('filterByBranches', this.query.branchesIds); - } - }; -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.ts deleted file mode 100644 index 0d4df537e..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.ts +++ /dev/null @@ -1,146 +0,0 @@ -import * as R from 'ramda'; -import FinancialSheet from '../FinancialSheet'; -import { FinancialTable } from '../FinancialTable'; -import { - ITableColumn, - ITableColumnAccessor, - ITableRow, - ITrialBalanceAccount, - ITrialBalanceSheetData, - ITrialBalanceSheetQuery, - ITrialBalanceTotal, -} from '@/interfaces'; -import { tableRowMapper } from '@/utils'; -import { IROW_TYPE } from '../BalanceSheet/constants'; -import { FinancialSheetStructure } from '../FinancialSheetStructure'; - -export class TrialBalanceSheetTable extends R.compose( - FinancialTable, - FinancialSheetStructure -)(FinancialSheet) { - /** - * Trial balance sheet data. - * @param {ITrialBalanceSheetData} - */ - public data: ITrialBalanceSheetData; - - /** - * Trial balance sheet query. - * @param {ITrialBalanceSheetQuery} - */ - public query: ITrialBalanceSheetQuery; - - /** - * Constructor method. - * @param {IBalanceSheetStatementData} reportData - - * @param {ITrialBalanceSheetQuery} query - - */ - constructor( - data: ITrialBalanceSheetData, - query: ITrialBalanceSheetQuery, - i18n: any - ) { - super(); - - this.data = data; - this.query = query; - this.i18n = i18n; - } - - /** - * Retrieve the common columns for all report nodes. - * @param {ITableColumnAccessor[]} - */ - private commonColumnsAccessors = (): ITableColumnAccessor[] => { - return [ - { key: 'account', accessor: 'formattedName' }, - { key: 'debit', accessor: 'formattedDebit' }, - { key: 'credit', accessor: 'formattedCredit' }, - { key: 'total', accessor: 'formattedBalance' }, - ]; - }; - - /** - * Maps the account node to table row. - * @param {ITrialBalanceAccount} node - - * @returns {ITableRow} - */ - private accountNodeTableRowsMapper = ( - node: ITrialBalanceAccount - ): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [IROW_TYPE.ACCOUNT], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Maps the total node to table row. - * @param {ITrialBalanceTotal} node - - * @returns {ITableRow} - */ - private totalNodeTableRowsMapper = (node: ITrialBalanceTotal): ITableRow => { - const columns = this.commonColumnsAccessors(); - const meta = { - rowTypes: [IROW_TYPE.TOTAL], - id: node.id, - }; - return tableRowMapper(node, columns, meta); - }; - - /** - * Mappes the given report sections to table rows. - * @param {IBalanceSheetDataNode[]} nodes - - * @return {ITableRow} - */ - private accountsToTableRowsMap = ( - nodes: ITrialBalanceAccount[] - ): ITableRow[] => { - return this.mapNodesDeep(nodes, this.accountNodeTableRowsMapper); - }; - - /** - * Retrieves the accounts table rows of the given report data. - * @returns {ITableRow[]} - */ - private accountsTableRows = (): ITableRow[] => { - return this.accountsToTableRowsMap(this.data.accounts); - }; - - /** - * Maps the given total node to table row. - * @returns {ITableRow} - */ - private totalTableRow = (): ITableRow => { - return this.totalNodeTableRowsMapper(this.data.total); - }; - - /** - * Retrieves the table rows. - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - return R.compose( - R.unless(R.isEmpty, R.append(this.totalTableRow())), - R.concat(this.accountsTableRows()) - )([]); - }; - - /** - * Retrrieves the table columns. - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - return R.compose( - this.tableColumnsCellIndexing, - R.concat([ - { key: 'account', label: 'Account' }, - { key: 'debit', label: 'Debit' }, - { key: 'credit', label: 'Credit' }, - { key: 'total', label: 'Total' }, - ]) - )([]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts deleted file mode 100644 index e62a1dde2..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTableInjectable.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ITrialBalanceSheetQuery, ITrialBalanceSheetTable } from '@/interfaces'; -import { TrialBalanceSheetTable } from './TrialBalanceSheetTable'; -import TrialBalanceSheetService from './TrialBalanceSheetInjectable'; - -@Service() -export class TrialBalanceSheetTableInjectable { - @Inject() - private sheet: TrialBalanceSheetService; - - /** - * Retrieves the trial balance sheet table. - * @param {number} tenantId - * @param {ITrialBalanceSheetQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: ITrialBalanceSheetQuery - ): Promise { - const trialBalance = await this.sheet.trialBalanceSheet(tenantId, query); - const table = new TrialBalanceSheetTable(trialBalance.data, query, {}); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - meta: trialBalance.meta, - query: trialBalance.query, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/_constants.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/_constants.ts deleted file mode 100644 index 7a52e631b..000000000 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/_constants.ts +++ /dev/null @@ -1,25 +0,0 @@ -export enum IROW_TYPE { - ACCOUNT = 'ACCOUNT', - TOTAL = 'TOTAL', -} - -export const HtmlTableCustomCss = ` -table tr.row-type--total td{ - border-top: 1px solid #bbb; - font-weight: 600; - border-bottom: 3px double #000; -} - -table .column--account { - width: 400px; -} - -table .column--debit, -table .column--credit, -table .column--total, -table .cell--debit, -table .cell--credit, -table .cell--total{ - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummary.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummary.ts deleted file mode 100644 index 6d04461b6..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummary.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as R from 'ramda'; -import { isEmpty } from 'lodash'; -import { - ILedger, - IVendor, - IVendorBalanceSummaryVendor, - IVendorBalanceSummaryQuery, - IVendorBalanceSummaryData, - INumberFormatQuery, -} from '@/interfaces'; -import { ContactBalanceSummaryReport } from '../ContactBalanceSummary/ContactBalanceSummary'; - -export class VendorBalanceSummaryReport extends ContactBalanceSummaryReport { - readonly ledger: ILedger; - readonly baseCurrency: string; - readonly vendors: IVendor[]; - readonly filter: IVendorBalanceSummaryQuery; - readonly numberFormat: INumberFormatQuery; - - /** - * Constructor method. - * @param {IJournalPoster} receivableLedger - * @param {IVendor[]} vendors - * @param {IVendorBalanceSummaryQuery} filter - * @param {string} baseCurrency - */ - constructor( - ledger: ILedger, - vendors: IVendor[], - filter: IVendorBalanceSummaryQuery, - baseCurrency: string - ) { - super(); - - this.ledger = ledger; - this.baseCurrency = baseCurrency; - this.vendors = vendors; - this.filter = filter; - this.numberFormat = this.filter.numberFormat; - } - - /** - * Customer section mapper. - * @param {IVendor} vendor - * @returns {IVendorBalanceSummaryVendor} - */ - private vendorMapper = (vendor: IVendor): IVendorBalanceSummaryVendor => { - const closingBalance = this.ledger - .whereContactId(vendor.id) - .getClosingBalance(); - - return { - id: vendor.id, - vendorName: vendor.displayName, - total: this.getContactTotalFormat(closingBalance), - }; - }; - - /** - * Mappes the vendor model object to vendor balance summary section. - * @param {IVendor[]} vendors - Customers. - * @returns {IVendorBalanceSummaryVendor[]} - */ - private vendorsMapper = ( - vendors: IVendor[] - ): IVendorBalanceSummaryVendor[] => { - return vendors.map(this.vendorMapper); - }; - - /** - * Detarmines whether the vendors post filter is active. - * @returns {boolean} - */ - private isVendorsPostFilter = (): boolean => { - return isEmpty(this.filter.vendorsIds); - }; - - /** - * Retrieve the vendors sections of the report. - * @param {IVendor} vendors - * @returns {IVendorBalanceSummaryVendor[]} - */ - private getVendorsSection(vendors: IVendor[]): IVendorBalanceSummaryVendor[] { - return R.compose( - R.when(this.isVendorsPostFilter, this.contactsFilter), - R.when( - R.always(this.filter.percentageColumn), - this.contactCamparsionPercentageOfColumn - ), - this.vendorsMapper - )(vendors); - } - - /** - * Retrieve the report statement data. - * @returns {IVendorBalanceSummaryData} - */ - public reportData(): IVendorBalanceSummaryData { - const vendors = this.getVendorsSection(this.vendors); - const total = this.getContactsTotalSection(vendors); - - return { vendors, total }; - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts deleted file mode 100644 index c02eac224..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IVendorBalanceSummaryQuery } from '@/interfaces'; -import { VendorBalanceSummaryTableInjectable } from './VendorBalanceSummaryTableInjectable'; -import { VendorBalanceSummaryExportInjectable } from './VendorBalanceSummaryExportInjectable'; -import { VendorBalanceSummaryService } from './VendorBalanceSummaryService'; -import { VendorBalanceSummaryPdf } from './VendorBalanceSummaryPdf'; - -@Service() -export class VendorBalanceSummaryApplication { - @Inject() - private vendorBalanceSummaryTable: VendorBalanceSummaryTableInjectable; - - @Inject() - private vendorBalanceSummarySheet: VendorBalanceSummaryService; - - @Inject() - private vendorBalanceSummaryExport: VendorBalanceSummaryExportInjectable; - - @Inject() - private vendorBalanceSummaryPdf: VendorBalanceSummaryPdf; - - /** - * Retrieves the vendor balance summary sheet in sheet format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - */ - public sheet(tenantId: number, query: IVendorBalanceSummaryQuery) { - return this.vendorBalanceSummarySheet.vendorBalanceSummary(tenantId, query); - } - - /** - * Retrieves the vendor balance summary sheet in table format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {} - */ - public table(tenantId: number, query: IVendorBalanceSummaryQuery) { - return this.vendorBalanceSummaryTable.table(tenantId, query); - } - - /** - * Retrieves the vendor balance summary sheet in xlsx format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {Promise} - */ - public xlsx( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - return this.vendorBalanceSummaryExport.xlsx(tenantId, query); - } - - /** - * Retrieves the vendor balance summary sheet in csv format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {Promise} - */ - public csv( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - return this.vendorBalanceSummaryExport.csv(tenantId, query); - } - - /** - * Retrieves the vendor balance summary sheet in pdf format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {Promise} - */ - public pdf(tenantId: number, query: IVendorBalanceSummaryQuery) { - return this.vendorBalanceSummaryPdf.pdf(tenantId, query); - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts deleted file mode 100644 index ba278f88d..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryExportInjectable.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IVendorBalanceSummaryQuery } from '@/interfaces'; -import { VendorBalanceSummaryTableInjectable } from './VendorBalanceSummaryTableInjectable'; -import { TableSheet } from '@/lib/Xlsx/TableSheet'; - -@Service() -export class VendorBalanceSummaryExportInjectable { - @Inject() - private customerBalanceSummaryTable: VendorBalanceSummaryTableInjectable; - - /** - * Retrieves the vendor balance summary sheet in XLSX format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {Promise} - */ - public async xlsx(tenantId: number, query: IVendorBalanceSummaryQuery) { - const table = await this.customerBalanceSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToXLSX(); - - return tableSheet.convertToBuffer(tableCsv, 'xlsx'); - } - - /** - * Retrieves the vendor balance summary sheet in CSV format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {Promise} - */ - public async csv( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - const table = await this.customerBalanceSummaryTable.table(tenantId, query); - - const tableSheet = new TableSheet(table.table); - const tableCsv = tableSheet.convertToCSV(); - - return tableCsv; - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryMeta.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryMeta.ts deleted file mode 100644 index 80071f8ca..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryMeta.ts +++ /dev/null @@ -1,32 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { FinancialSheetMeta } from '../FinancialSheetMeta'; -import { - IVendorBalanceSummaryMeta, - IVendorBalanceSummaryQuery, -} from '@/interfaces'; - -@Service() -export class VendorBalanceSummaryMeta { - @Inject() - private financialSheetMeta: FinancialSheetMeta; - - /** - * Retrieves the vendor balance summary meta. - * @param {number} tenantId - - * @returns {IBalanceSheetMeta} - */ - public async meta( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - const commonMeta = await this.financialSheetMeta.meta(tenantId); - const formattedAsDate = moment(query.asDate).format('YYYY/MM/DD'); - - return { - ...commonMeta, - sheetName: 'Vendor Balance Summary', - formattedAsDate, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts deleted file mode 100644 index f13ffc98c..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IVendorBalanceSummaryQuery } from '@/interfaces'; -import { TableSheetPdf } from '../TableSheetPdf'; -import { VendorBalanceSummaryTableInjectable } from './VendorBalanceSummaryTableInjectable'; -import { HtmlTableCustomCss } from './constants'; - -@Service() -export class VendorBalanceSummaryPdf { - @Inject() - private vendorBalanceSummaryTable: VendorBalanceSummaryTableInjectable; - - @Inject() - private tableSheetPdf: TableSheetPdf; - - /** - * Retrieves the sales by items sheet in pdf format. - * @param {number} tenantId - * @param {number} query - * @returns {Promise} - */ - public async pdf( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - const table = await this.vendorBalanceSummaryTable.table(tenantId, query); - - return this.tableSheetPdf.convertToPdf( - tenantId, - table.table, - table.meta.sheetName, - table.meta.formattedAsDate, - HtmlTableCustomCss - ); - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryRepository.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryRepository.ts deleted file mode 100644 index 721291b7d..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryRepository.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isEmpty, map } from 'lodash'; -import { IVendor, IAccount } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; - -@Service() -export default class VendorBalanceSummaryRepository { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve the report vendors. - * @param {number} tenantId - * @param {number[]} vendorsIds - Vendors ids. - * @returns {IVendor[]} - */ - public getVendors( - tenantId: number, - vendorsIds?: number[] - ): Promise { - const { Vendor } = this.tenancy.models(tenantId); - - const vendorQuery = Vendor.query().orderBy('displayName'); - - if (!isEmpty(vendorsIds)) { - vendorQuery.whereIn('id', vendorsIds); - } - return vendorQuery; - } - - /** - * Retrieve the payable accounts. - * @param {number} tenantId - * @returns {Promise} - */ - public getPayableAccounts(tenantId: number): Promise { - const { Account } = this.tenancy.models(tenantId); - - return Account.query().where('accountType', ACCOUNT_TYPE.ACCOUNTS_PAYABLE); - } - - /** - * Retrieve the vendors transactions. - * @param {number} tenantId - * @param {Date} asDate - * @returns - */ - public async getVendorsTransactions(tenantId: number, asDate: Date | string) { - const { AccountTransaction } = this.tenancy.models(tenantId); - - // Retrieve payable accounts . - const payableAccounts = await this.getPayableAccounts(tenantId); - const payableAccountsIds = map(payableAccounts, 'id'); - - // Retrieve the customers transactions of A/R accounts. - const customersTranasctions = await AccountTransaction.query().onBuild( - (query) => { - query.whereIn('accountId', payableAccountsIds); - query.modify('filterDateRange', null, asDate); - query.groupBy('contactId'); - query.sum('credit as credit'); - query.sum('debit as debit'); - query.select('contactId'); - } - ); - return customersTranasctions; - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryService.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryService.ts deleted file mode 100644 index 41b63749e..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryService.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { Inject } from 'typedi'; -import moment from 'moment'; -import * as R from 'ramda'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - IVendorBalanceSummaryService, - IVendorBalanceSummaryQuery, - IVendorBalanceSummaryStatement, - ILedgerEntry, -} from '@/interfaces'; -import { VendorBalanceSummaryReport } from './VendorBalanceSummary'; -import Ledger from '@/services/Accounting/Ledger'; -import VendorBalanceSummaryRepository from './VendorBalanceSummaryRepository'; -import { Tenant } from '@/system/models'; -import { JournalSheetMeta } from '../JournalSheet/JournalSheetMeta'; - -import { VendorBalanceSummaryMeta } from './VendorBalanceSummaryMeta'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -export class VendorBalanceSummaryService - implements IVendorBalanceSummaryService -{ - @Inject() - private tenancy: TenancyService; - - @Inject() - private reportRepo: VendorBalanceSummaryRepository; - - @Inject() - private vendorBalanceSummaryMeta: VendorBalanceSummaryMeta; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Defaults balance sheet filter query. - * @return {IVendorBalanceSummaryQuery} - */ - private get defaultQuery(): IVendorBalanceSummaryQuery { - return { - asDate: moment().format('YYYY-MM-DD'), - numberFormat: { - precision: 2, - divideOn1000: false, - showZero: false, - formatMoney: 'total', - negativeFormat: 'mines', - }, - percentageColumn: false, - noneZero: false, - noneTransactions: true, - }; - } - - /** - * - * Retrieve the vendors ledger entrjes. - * @param {number} tenantId - - * @param {Date|string} date - - * @returns {Promise} - */ - private async getReportVendorsEntries( - tenantId: number, - date: Date | string - ): Promise { - const transactions = await this.reportRepo.getVendorsTransactions( - tenantId, - date - ); - const commonProps = { accountNormal: 'credit' }; - - return R.map(R.merge(commonProps))(transactions); - } - - /** - * Retrieve the statment of customer balance summary report. - * @param {number} tenantId - Tenant id. - * @param {IVendorBalanceSummaryQuery} query - - * @return {Promise} - */ - public async vendorBalanceSummary( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const filter = { ...this.defaultQuery, ...query }; - - // Retrieve the vendors transactions. - const vendorsEntries = await this.getReportVendorsEntries( - tenantId, - query.asDate - ); - // Retrieve the customers list ordered by the display name. - const vendors = await this.reportRepo.getVendors( - tenantId, - query.vendorsIds - ); - // Ledger query. - const vendorsLedger = new Ledger(vendorsEntries); - - // Report instance. - const reportInstance = new VendorBalanceSummaryReport( - vendorsLedger, - vendors, - filter, - tenant.metadata.baseCurrency - ); - // Retrieve the vendor balance summary meta. - const meta = await this.vendorBalanceSummaryMeta.meta(tenantId, filter); - - // Triggers `onVendorBalanceSummaryViewed` event. - await this.eventPublisher.emitAsync( - events.reports.onVendorBalanceSummaryViewed, - { - tenantId, - query, - } - ); - - return { - data: reportInstance.reportData(), - query: filter, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts deleted file mode 100644 index c055b1151..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableInjectable.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - IVendorBalanceSummaryQuery, - IVendorBalanceSummaryTable, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { VendorBalanceSummaryTable } from './VendorBalanceSummaryTableRows'; -import { VendorBalanceSummaryService } from './VendorBalanceSummaryService'; - -@Service() -export class VendorBalanceSummaryTableInjectable { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private vendorBalanceSummarySheet: VendorBalanceSummaryService; - - /** - * Retrieves the vendor balance summary sheet in table format. - * @param {number} tenantId - * @param {IVendorBalanceSummaryQuery} query - * @returns {Promise} - */ - public async table( - tenantId: number, - query: IVendorBalanceSummaryQuery - ): Promise { - const i18n = this.tenancy.i18n(tenantId); - - const { data, meta } = - await this.vendorBalanceSummarySheet.vendorBalanceSummary( - - tenantId, - query - ); - const table = new VendorBalanceSummaryTable(data, query, i18n); - - return { - table: { - columns: table.tableColumns(), - rows: table.tableRows(), - }, - query, - meta, - }; - } -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts deleted file mode 100644 index 56fdbf924..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryTableRows.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as R from 'ramda'; -import { tableMapper, tableRowMapper } from 'utils'; -import { - IVendorBalanceSummaryData, - IVendorBalanceSummaryVendor, - IVendorBalanceSummaryTotal, - ITableRow, - IColumnMapperMeta, - IVendorBalanceSummaryQuery, - ITableColumn, -} from '@/interfaces'; - -enum TABLE_ROWS_TYPES { - VENDOR = 'VENDOR', - TOTAL = 'TOTAL', -} - -export class VendorBalanceSummaryTable { - i18n: any; - report: IVendorBalanceSummaryData; - query: IVendorBalanceSummaryQuery; - - /** - * Constructor method. - * @param {IVendorBalanceSummaryData} report - * @param i18n - */ - constructor( - report: IVendorBalanceSummaryData, - query: IVendorBalanceSummaryQuery, - i18n - ) { - this.report = report; - this.query = query; - this.i18n = i18n; - } - - /** - * Retrieve percentage columns accessor. - * @returns {IColumnMapperMeta[]} - */ - private getPercentageColumnsAccessor = (): IColumnMapperMeta[] => { - return [ - { - key: 'percentageOfColumn', - accessor: 'percentageOfColumn.formattedAmount', - }, - ]; - }; - - /** - * Retrieve vendor node columns accessor. - * @returns {IColumnMapperMeta[]} - */ - private getVendorColumnsAccessor = (): IColumnMapperMeta[] => { - const columns = [ - { key: 'name', accessor: 'vendorName' }, - { key: 'total', accessor: 'total.formattedAmount' }, - ]; - return R.compose( - R.concat(columns), - R.when( - R.always(this.query.percentageColumn), - R.concat(this.getPercentageColumnsAccessor()) - ) - )([]); - }; - - /** - * Transformes the vendors to table rows. - * @param {IVendorBalanceSummaryVendor[]} vendors - * @returns {ITableRow[]} - */ - private vendorsTransformer = ( - vendors: IVendorBalanceSummaryVendor[] - ): ITableRow[] => { - const columns = this.getVendorColumnsAccessor(); - - return tableMapper(vendors, columns, { - rowTypes: [TABLE_ROWS_TYPES.VENDOR], - }); - }; - - /** - * Retrieve total node columns accessor. - * @returns {IColumnMapperMeta[]} - */ - private getTotalColumnsAccessor = (): IColumnMapperMeta[] => { - const columns = [ - { key: 'name', value: this.i18n.__('Total') }, - { key: 'total', accessor: 'total.formattedAmount' }, - ]; - return R.compose( - R.concat(columns), - R.when( - R.always(this.query.percentageColumn), - R.concat(this.getPercentageColumnsAccessor()) - ) - )([]); - }; - - /** - * Transformes the total to table row. - * @param {IVendorBalanceSummaryTotal} total - * @returns {ITableRow} - */ - private totalTransformer = (total: IVendorBalanceSummaryTotal): ITableRow => { - const columns = this.getTotalColumnsAccessor(); - - return tableRowMapper(total, columns, { - rowTypes: [TABLE_ROWS_TYPES.TOTAL], - }); - }; - - /** - * Transformes the vendor balance summary to table rows. - * @param {IVendorBalanceSummaryData} vendorBalanceSummary - * @returns {ITableRow[]} - */ - public tableRows = (): ITableRow[] => { - const vendors = this.vendorsTransformer(this.report.vendors); - const total = this.totalTransformer(this.report.total); - - return vendors.length > 0 ? [...vendors, total] : []; - }; - - /** - * Retrieve the report statement columns - * @returns {ITableColumn[]} - */ - public tableColumns = (): ITableColumn[] => { - const columns = [ - { - key: 'name', - label: this.i18n.__('contact_summary_balance.account_name'), - }, - { key: 'total', label: this.i18n.__('contact_summary_balance.total') }, - ]; - return R.compose( - R.when( - R.always(this.query.percentageColumn), - R.append({ - key: 'percentage_of_column', - label: this.i18n.__('contact_summary_balance.percentage_column'), - }) - ), - R.concat(columns) - )([]); - }; -} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/constants.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/constants.ts deleted file mode 100644 index 513a3dcdb..000000000 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/constants.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const HtmlTableCustomCss = ` -table tr.row-type--total td { - font-weight: 600; - border-top: 1px solid #bbb; - border-bottom: 3px double #333; -} -table .column--name { - width: 65%; -} -table .column--total, -table .cell--total { - text-align: right; -} -`; diff --git a/packages/server/src/services/FinancialStatements/utils.ts b/packages/server/src/services/FinancialStatements/utils.ts deleted file mode 100644 index 5d304ca6f..000000000 --- a/packages/server/src/services/FinancialStatements/utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { kebabCase } from 'lodash'; -import { ITableRow } from '@/interfaces'; - -export const formatNumber = (balance, { noCents, divideOn1000 }): string => { - let formattedBalance: number = parseFloat(balance); - - if (noCents) { - formattedBalance = parseInt(formattedBalance, 10); - } - if (divideOn1000) { - formattedBalance /= 1000; - } - return formattedBalance; -}; - -export const tableClassNames = (rows: ITableRow[]) => { - return rows.map((row) => { - const classNames = - row?.rowTypes?.map((rowType) => `row-type--${kebabCase(rowType)}`) || []; - - if (row.id) { - classNames.push(`row-id--${kebabCase(row.id)}`); - } - - return { - ...row, - classNames, - }; - }); -}; diff --git a/packages/server/src/services/I18n/I18nService.ts b/packages/server/src/services/I18n/I18nService.ts deleted file mode 100644 index e7771b15f..000000000 --- a/packages/server/src/services/I18n/I18nService.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as R from 'ramda'; -import { isUndefined } from 'lodash'; -import * as qim from 'qim'; -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class I18nService { - @Inject() - tenancy: HasTenancyService; - - /** - * - * @param i18n - * @param attributes - * @param data - * @returns - */ - private i18nAttributesMapper(i18n, attributes, data) { - return attributes.reduce((acc, attr, index) => { - return { - ...acc, - [attr]: i18n.__(acc[attr]), - }; - }, data); - } - - /** - * Mappes array collection to i18n localization based in given attributes. - * @param {Array} data - Array collection. - * @param {string[]} attributes - Attributes. - * @param {number} tenantId - Tenant id. - */ - public i18nMapper( - data: Array, - attributes: string[] = [], - tenantId: number - ) { - const i18n = this.tenancy.i18n(tenantId); - - return data.map((_data) => { - const newData = this.i18nAttributesMapper(i18n, attributes, _data); - - return { - ..._data, - ...newData, - }; - }); - } - - public i18nApply( - paths: (string|Function)[][], - data: Array, - tenantId: number, - ) { - const i18n = this.tenancy.i18n(tenantId); - const applyCurry = R.curryN(3, qim.apply); - const transformedData = !isUndefined(data.toJSON) ? data.toJSON() : data; - - const transform = (value) => i18n.__(value) || value; - - const curriedCallbacks = paths.map((path) => applyCurry(path, transform)); - - return R.compose(...curriedCallbacks)(transformedData); - } -} diff --git a/packages/server/src/services/Import/ImportALS.ts b/packages/server/src/services/Import/ImportALS.ts deleted file mode 100644 index d1298e5bd..000000000 --- a/packages/server/src/services/Import/ImportALS.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Service } from 'typedi'; -import { AsyncLocalStorage } from 'async_hooks'; - -@Service() -export class ImportAls { - private als: AsyncLocalStorage>; - - constructor() { - this.als = new AsyncLocalStorage(); - } - - /** - * Runs a callback function within the context of a new AsyncLocalStorage store. - * @param callback The function to be executed within the AsyncLocalStorage context. - * @returns The result of the callback function. - */ - public run(callback: () => T): T { - return this.als.run(new Map(), callback); - } - - /** - * Runs a callback function in preview mode within the AsyncLocalStorage context. - * @param callback The function to be executed in preview mode. - * @returns The result of the callback function. - */ - public runPreview(callback: () => T): T { - return this.run(() => { - this.markAsImport(); - this.markAsImportPreview(); - return callback(); - }); - } - - /** - * Runs a callback function in commit mode within the AsyncLocalStorage context. - * @param {() => T} callback - The function to be executed in commit mode. - * @returns {T} The result of the callback function. - */ - public runCommit(callback: () => T): T { - return this.run(() => { - this.markAsImport(); - this.markAsImportCommit(); - return callback(); - }); - } - - /** - * Retrieves the current AsyncLocalStorage store. - * @returns The current store or undefined if not in a valid context. - */ - public getStore(): Map | undefined { - return this.als.getStore(); - } - - /** - * Marks the current context as an import operation. - * @param flag Boolean flag to set or unset the import status. Defaults to true. - */ - public markAsImport(flag: boolean = true): void { - const store = this.getStore(); - store?.set('isImport', flag); - } - - /** - * Marks the current context as an import commit operation. - * @param flag Boolean flag to set or unset the import commit status. Defaults to true. - */ - public markAsImportCommit(flag: boolean = true): void { - const store = this.getStore(); - store?.set('isImportCommit', flag); - } - - /** - * Marks the current context as an import preview operation. - * @param {boolean} flag - Boolean flag to set or unset the import preview status. Defaults to true. - */ - public markAsImportPreview(flag: boolean = true): void { - const store = this.getStore(); - store?.set('isImportPreview', flag); - } - - /** - * Checks if the current context is an import operation. - * @returns {boolean} True if the context is an import operation, false otherwise. - */ - public get isImport(): boolean { - return !!this.getStore()?.get('isImport'); - } - - /** - * Checks if the current context is an import commit operation. - * @returns {boolean} True if the context is an import commit operation, false otherwise. - */ - public get isImportCommit(): boolean { - return !!this.getStore()?.get('isImportCommit'); - } - - /** - * Checks if the current context is an import preview operation. - * @returns {boolean} True if the context is an import preview operation, false otherwise. - */ - public get isImportPreview(): boolean { - return !!this.getStore()?.get('isImportPreview'); - } -} diff --git a/packages/server/src/services/Import/ImportFileCommon.ts b/packages/server/src/services/Import/ImportFileCommon.ts deleted file mode 100644 index e8391882e..000000000 --- a/packages/server/src/services/Import/ImportFileCommon.ts +++ /dev/null @@ -1,175 +0,0 @@ -import bluebird from 'bluebird'; -import * as R from 'ramda'; -import { Inject, Service } from 'typedi'; -import { first } from 'lodash'; -import { ImportFileDataValidator } from './ImportFileDataValidator'; -import { Knex } from 'knex'; -import { - ImportInsertError, - ImportOperError, - ImportOperSuccess, - ImportableContext, -} from './interfaces'; -import { ServiceError } from '@/exceptions'; -import { getUniqueImportableValue, trimObject } from './_utils'; -import { ImportableResources } from './ImportableResources'; -import ResourceService from '../Resource/ResourceService'; -import { Import } from '@/system/models'; - -@Service() -export class ImportFileCommon { - @Inject() - private importFileValidator: ImportFileDataValidator; - - @Inject() - private importable: ImportableResources; - - @Inject() - private resource: ResourceService; - - /** - * Imports the given parsed data to the resource storage through registered importable service. - * @param {number} tenantId - - * @param {string} resourceName - Resource name. - * @param {Record} parsedData - Parsed data. - * @param {Knex.Transaction} trx - Knex transaction. - * @returns {Promise<[ImportOperSuccess[], ImportOperError[]]>} - */ - public async import( - tenantId: number, - importFile: Import, - parsedData: Record[], - trx?: Knex.Transaction - ): Promise<[ImportOperSuccess[], ImportOperError[]]> { - const resourceFields = this.resource.getResourceFields2( - tenantId, - importFile.resource - ); - const ImportableRegistry = this.importable.registry; - const importable = ImportableRegistry.getImportable(importFile.resource); - - const concurrency = importable.concurrency || 10; - - const success: ImportOperSuccess[] = []; - const failed: ImportOperError[] = []; - - const importAsync = async (objectDTO, index: number): Promise => { - const context: ImportableContext = { - rowIndex: index, - import: importFile, - }; - const transformedDTO = importable.transform(objectDTO, context); - const rowNumber = index + 1; - const uniqueValue = getUniqueImportableValue(resourceFields, objectDTO); - const errorContext = { - rowNumber, - uniqueValue, - }; - try { - // Validate the DTO object before passing it to the service layer. - await this.importFileValidator.validateData( - resourceFields, - transformedDTO - ); - try { - // Run the importable function and listen to the errors. - const data = await importable.importable( - tenantId, - transformedDTO, - trx - ); - success.push({ index, data }); - } catch (err) { - if (err instanceof ServiceError) { - const error: ImportInsertError[] = [ - { - errorCode: 'ServiceError', - errorMessage: err.message || err.errorType, - ...errorContext, - }, - ]; - failed.push({ index, error }); - } else { - const error: ImportInsertError[] = [ - { - errorCode: 'UnknownError', - errorMessage: 'Unknown error occurred', - ...errorContext, - }, - ]; - failed.push({ index, error }); - } - } - } catch (errors) { - const error = errors.map((er) => ({ ...er, ...errorContext })); - failed.push({ index, error }); - } - }; - await bluebird.map(parsedData, importAsync, { concurrency }); - - return [success, failed]; - } - - /** - * - * @param {string} resourceName - * @param {Record} params - */ - public async validateParamsSchema( - resourceName: string, - params: Record - ) { - const ImportableRegistry = this.importable.registry; - const importable = ImportableRegistry.getImportable(resourceName); - - const yupSchema = importable.paramsValidationSchema(); - - try { - await yupSchema.validate(params, { abortEarly: false }); - } catch (validationError) { - const errors = validationError.inner.map((error) => ({ - errorCode: 'ParamsValidationError', - errorMessage: error.errors, - })); - throw errors; - } - } - - /** - * - * @param {string} resourceName - * @param {Record} params - */ - public async validateParams( - tenantId: number, - resourceName: string, - params: Record - ) { - const ImportableRegistry = this.importable.registry; - const importable = ImportableRegistry.getImportable(resourceName); - - await importable.validateParams(tenantId, params); - } - - /** - * - * @param {string} resourceName - * @param {Record} params - * @returns - */ - public transformParams(resourceName: string, params: Record) { - const ImportableRegistry = this.importable.registry; - const importable = ImportableRegistry.getImportable(resourceName); - - return importable.transformParams(params); - } - - /** - * Retrieves the sheet columns from the given sheet data. - * @param {unknown[]} json - * @returns {string[]} - */ - public parseSheetColumns(json: unknown[]): string[] { - return R.compose(Object.keys, trimObject, first)(json); - } -} diff --git a/packages/server/src/services/Import/ImportFileDataTransformer.ts b/packages/server/src/services/Import/ImportFileDataTransformer.ts deleted file mode 100644 index 5e391fc6e..000000000 --- a/packages/server/src/services/Import/ImportFileDataTransformer.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Inject, Service } from 'typedi'; -import bluebird from 'bluebird'; -import { isUndefined, pickBy, set } from 'lodash'; -import { Knex } from 'knex'; -import { ImportMappingAttr, ResourceMetaFieldsMap } from './interfaces'; -import { - valueParser, - parseKey, - getFieldKey, - aggregate, - sanitizeSheetData, - getMapToPath, -} from './_utils'; -import ResourceService from '../Resource/ResourceService'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { CurrencyParsingDTOs } from './_constants'; - -@Service() -export class ImportFileDataTransformer { - @Inject() - private resource: ResourceService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Parses the given sheet data before passing to the service layer. - * based on the mapped fields and the each field type. - * @param {number} tenantId - - * @param {} - */ - public async parseSheetData( - tenantId: number, - importFile: any, - importableFields: ResourceMetaFieldsMap, - data: Record[], - trx?: Knex.Transaction - ): Promise[]> { - // Sanitize the sheet data. - const sanitizedData = sanitizeSheetData(data); - - // Map the sheet columns key with the given map. - const mappedDTOs = this.mapSheetColumns( - sanitizedData, - importFile.mappingParsed - ); - // Parse the mapped sheet values. - const parsedValues = await this.parseExcelValues( - tenantId, - importableFields, - mappedDTOs, - trx - ); - const aggregateValues = this.aggregateParsedValues( - tenantId, - importFile.resource, - parsedValues - ); - return aggregateValues; - } - - /** - * Aggregates parsed data based on resource metadata configuration. - * @param {number} tenantId - * @param {string} resourceName - * @param {Record} parsedData - * @returns {Record[]} - */ - public aggregateParsedValues = ( - tenantId: number, - resourceName: string, - parsedData: Record[] - ): Record[] => { - let _value = parsedData; - const meta = this.resource.getResourceMeta(tenantId, resourceName); - - if (meta.importAggregator === 'group') { - _value = aggregate( - _value, - meta.importAggregateBy, - meta.importAggregateOn - ); - } - return _value; - }; - - /** - * Maps the columns of the imported data based on the provided mapping attributes. - * @param {Record[]} body - The array of data objects to map. - * @param {ImportMappingAttr[]} map - The mapping attributes. - * @returns {Record[]} - The mapped data objects. - */ - public mapSheetColumns( - body: Record[], - map: ImportMappingAttr[] - ): Record[] { - return body.map((item) => { - const newItem = {}; - map - .filter((mapping) => !isUndefined(item[mapping.from])) - .forEach((mapping) => { - const toPath = getMapToPath(mapping.to, mapping.group); - newItem[toPath] = item[mapping.from]; - }); - return newItem; - }); - } - - /** - * Parses sheet values before passing to the service layer. - * @param {ResourceMetaFieldsMap} fields - - * @param {Record} valueDTOS - - * @returns {Record} - */ - public async parseExcelValues( - tenantId: number, - fields: ResourceMetaFieldsMap, - valueDTOs: Record[], - trx?: Knex.Transaction - ): Promise[]> { - const tenantModels = this.tenancy.models(tenantId); - const _valueParser = valueParser(fields, tenantModels, trx); - const _keyParser = parseKey(fields); - - const parseAsync = async (valueDTO) => { - // Clean up the undefined keys that not exist in resource fields. - const _valueDTO = pickBy( - valueDTO, - (value, key) => !isUndefined(fields[getFieldKey(key)]) - ); - // Keys of mapped values. key structure: `group.key` or `key`. - const keys = Object.keys(_valueDTO); - - // Map the object values. - return bluebird.reduce( - keys, - async (acc, key) => { - const parsedValue = await _valueParser(_valueDTO[key], key); - const parsedKey = await _keyParser(key); - - set(acc, parsedKey, parsedValue); - return acc; - }, - {} - ); - }; - return bluebird.map(valueDTOs, parseAsync, { - concurrency: CurrencyParsingDTOs, - }); - } -} diff --git a/packages/server/src/services/Import/ImportFileDataValidator.ts b/packages/server/src/services/Import/ImportFileDataValidator.ts deleted file mode 100644 index 143533c66..000000000 --- a/packages/server/src/services/Import/ImportFileDataValidator.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Service } from 'typedi'; -import { ImportInsertError, ResourceMetaFieldsMap } from './interfaces'; -import { ERRORS, convertFieldsToYupValidation } from './_utils'; -import { IModelMeta } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; - -@Service() -export class ImportFileDataValidator { - /** - * Validates the given resource is importable. - * @param {IModelMeta} resourceMeta - */ - public validateResourceImportable(resourceMeta: IModelMeta) { - // Throw service error if the resource does not support importing. - if (!resourceMeta.importable) { - throw new ServiceError(ERRORS.RESOURCE_NOT_IMPORTABLE); - } - } - - /** - * Validates the given mapped DTOs and returns errors with their index. - * @param {Record} mappedDTOs - * @returns {Promise} - */ - public async validateData( - importableFields: ResourceMetaFieldsMap, - data: Record - ): Promise { - const YupSchema = convertFieldsToYupValidation(importableFields); - const _data = { ...data }; - - try { - await YupSchema.validate(_data, { abortEarly: false }); - } catch (validationError) { - const errors = validationError.inner.reduce((errors, error) => { - const newErrors = error.errors.map((errMsg) => ({ - errorCode: 'ValidationError', - errorMessage: errMsg, - })); - return [...errors, ...newErrors]; - }, []); - - throw errors; - } - } -} diff --git a/packages/server/src/services/Import/ImportFileMapping.ts b/packages/server/src/services/Import/ImportFileMapping.ts deleted file mode 100644 index 3ef321239..000000000 --- a/packages/server/src/services/Import/ImportFileMapping.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { fromPairs, isUndefined } from 'lodash'; -import { Inject, Service } from 'typedi'; -import { - ImportDateFormats, - ImportFileMapPOJO, - ImportMappingAttr, -} from './interfaces'; -import ResourceService from '../Resource/ResourceService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './_utils'; -import { Import } from '@/system/models'; - -@Service() -export class ImportFileMapping { - @Inject() - private resource: ResourceService; - - /** - * Mapping the excel sheet columns with resource columns. - * @param {number} tenantId - * @param {number} importId - * @param {ImportMappingAttr} maps - */ - public async mapping( - tenantId: number, - importId: string, - maps: ImportMappingAttr[] - ): Promise { - const importFile = await Import.query() - .findOne('filename', importId) - .throwIfNotFound(); - - // Invalidate the from/to map attributes. - this.validateMapsAttrs(tenantId, importFile, maps); - - // @todo validate the required fields. - - // Validate the diplicated relations of map attrs. - this.validateDuplicatedMapAttrs(maps); - - // Validate the date format mapping. - this.validateDateFormatMapping(tenantId, importFile.resource, maps); - - const mappingStringified = JSON.stringify(maps); - - await Import.query().findById(importFile.id).patch({ - mapping: mappingStringified, - }); - return { - import: { - importId: importFile.importId, - resource: importFile.resource, - }, - }; - } - - /** - * Validate the mapping attributes. - * @param {number} tenantId - - * @param {} importFile - - * @param {ImportMappingAttr[]} maps - * @throws {ServiceError(ERRORS.INVALID_MAP_ATTRS)} - */ - private validateMapsAttrs( - tenantId: number, - importFile: any, - maps: ImportMappingAttr[] - ) { - const fields = this.resource.getResourceFields2( - tenantId, - importFile.resource - ); - const columnsMap = fromPairs( - importFile.columnsParsed.map((field) => [field, '']) - ); - const invalid = []; - - // is not empty, is not undefined or map.group - maps.forEach((map) => { - let _invalid = true; - - if (!map.group && fields[map.to]) { - _invalid = false; - } - if (map.group && fields[map.group] && fields[map.group]?.fields[map.to]) { - _invalid = false; - } - if (columnsMap[map.from]) { - _invalid = false; - } - if (_invalid) { - invalid.push(map); - } - }); - if (invalid.length > 0) { - throw new ServiceError(ERRORS.INVALID_MAP_ATTRS); - } - } - - /** - * Validate the map attrs relation should be one-to-one relation only. - * @param {ImportMappingAttr[]} maps - */ - private validateDuplicatedMapAttrs(maps: ImportMappingAttr[]) { - const fromMap = {}; - const toMap = {}; - - maps.forEach((map) => { - if (fromMap[map.from]) { - throw new ServiceError(ERRORS.DUPLICATED_FROM_MAP_ATTR); - } else { - fromMap[map.from] = true; - } - const toPath = !isUndefined(map?.group) - ? `${map.group}.${map.to}` - : map.to; - - if (toMap[toPath]) { - throw new ServiceError(ERRORS.DUPLICATED_TO_MAP_ATTR); - } else { - toMap[toPath] = true; - } - }); - } - - /** - * Validates the date format mapping. - * @param {number} tenantId - * @param {string} resource - * @param {ImportMappingAttr[]} maps - */ - private validateDateFormatMapping( - tenantId: number, - resource: string, - maps: ImportMappingAttr[] - ) { - const fields = this.resource.getResourceImportableFields( - tenantId, - resource - ); - // @todo Validate date type of the nested fields. - maps.forEach((map) => { - if ( - typeof fields[map.to] !== 'undefined' && - fields[map.to].fieldType === 'date' - ) { - if ( - typeof map.dateFormat !== 'undefined' && - ImportDateFormats.indexOf(map.dateFormat) === -1 - ) { - throw new ServiceError(ERRORS.INVALID_MAP_DATE_FORMAT); - } - } - }); - } -} diff --git a/packages/server/src/services/Import/ImportFileMeta.ts b/packages/server/src/services/Import/ImportFileMeta.ts deleted file mode 100644 index c20d49120..000000000 --- a/packages/server/src/services/Import/ImportFileMeta.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { ImportFileMetaTransformer } from './ImportFileMetaTransformer'; -import { Import } from '@/system/models'; - -@Service() -export class ImportFileMeta { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the import meta of the given import model id. - * @param {number} tenantId - * @param {number} importId - * @returns {} - */ - async getImportMeta(tenantId: number, importId: string) { - const importFile = await Import.query() - .where('tenantId', tenantId) - .findOne('importId', importId); - - // Retrieves the transformed accounts collection. - return this.transformer.transform( - tenantId, - importFile, - new ImportFileMetaTransformer() - ); - } -} diff --git a/packages/server/src/services/Import/ImportFileMetaTransformer.ts b/packages/server/src/services/Import/ImportFileMetaTransformer.ts deleted file mode 100644 index 6c50c1e37..000000000 --- a/packages/server/src/services/Import/ImportFileMetaTransformer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class ImportFileMetaTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['map']; - }; - - public excludeAttributes = (): string[] => { - return ['id', 'filename', 'columns', 'mappingParsed', 'mapping']; - } - - map(importFile) { - return importFile.mappingParsed; - } -} diff --git a/packages/server/src/services/Import/ImportFilePreview.ts b/packages/server/src/services/Import/ImportFilePreview.ts deleted file mode 100644 index e8b566bbe..000000000 --- a/packages/server/src/services/Import/ImportFilePreview.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { ImportFilePreviewPOJO } from './interfaces'; -import { ImportFileProcess } from './ImportFileProcess'; -import { ImportAls } from './ImportALS'; - -@Service() -export class ImportFilePreview { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private importFile: ImportFileProcess; - - @Inject() - private importAls: ImportAls; - - /** - * Preview the imported file results before commiting the transactions. - * @param {number} tenantId - - * @param {string} importId - - * @returns {Promise} - */ - public async preview( - tenantId: number, - importId: string - ): Promise { - return this.importAls.runPreview>(() => - this.previewAlsRun(tenantId, importId) - ); - } - - /** - * Preview the imported file results before commiting the transactions. - * @param {number} tenantId - * @param {number} importId - * @returns {Promise} - */ - public async previewAlsRun( - tenantId: number, - importId: string - ): Promise { - const knex = this.tenancy.knex(tenantId); - const trx = await knex.transaction({ isolationLevel: 'read uncommitted' }); - - const meta = await this.importFile.import(tenantId, importId, trx); - - // Rollback the successed transaction. - await trx.rollback(); - - return meta; - } -} diff --git a/packages/server/src/services/Import/ImportFileProcess.ts b/packages/server/src/services/Import/ImportFileProcess.ts deleted file mode 100644 index 405b0da43..000000000 --- a/packages/server/src/services/Import/ImportFileProcess.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { chain } from 'lodash'; -import { Knex } from 'knex'; -import { ServiceError } from '@/exceptions'; -import { ERRORS, getUnmappedSheetColumns, readImportFile } from './_utils'; -import { ImportFileCommon } from './ImportFileCommon'; -import { ImportFileDataTransformer } from './ImportFileDataTransformer'; -import ResourceService from '../Resource/ResourceService'; -import UnitOfWork from '../UnitOfWork'; -import { ImportFilePreviewPOJO } from './interfaces'; -import { Import } from '@/system/models'; -import { parseSheetData } from './sheet_utils'; - -@Service() -export class ImportFileProcess { - @Inject() - private resource: ResourceService; - - @Inject() - private importCommon: ImportFileCommon; - - @Inject() - private importParser: ImportFileDataTransformer; - - @Inject() - private uow: UnitOfWork; - - /** - * Preview the imported file results before commiting the transactions. - * @param {number} tenantId - * @param {number} importId - * @returns {Promise} - */ - public async import( - tenantId: number, - importId: string, - trx?: Knex.Transaction - ): Promise { - const importFile = await Import.query() - .findOne('importId', importId) - .where('tenantId', tenantId) - .throwIfNotFound(); - - // Throw error if the import file is not mapped yet. - if (!importFile.isMapped) { - throw new ServiceError(ERRORS.IMPORT_FILE_NOT_MAPPED); - } - // Read the imported file and parse the given buffer to get columns - // and sheet data in json format. - const buffer = await readImportFile(importFile.filename); - const [sheetData, sheetColumns] = parseSheetData(buffer); - - const resource = importFile.resource; - const resourceFields = this.resource.getResourceFields2(tenantId, resource); - - // Runs the importing operation with ability to return errors that will happen. - const [successedImport, failedImport, allData] = - await this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Prases the sheet json data. - const parsedData = await this.importParser.parseSheetData( - tenantId, - importFile, - resourceFields, - sheetData, - trx - ); - const [successedImport, failedImport] = - await this.importCommon.import( - tenantId, - importFile, - parsedData, - trx - ); - return [successedImport, failedImport, parsedData]; - }, - trx - ); - const mapping = importFile.mappingParsed; - const errors = chain(failedImport) - .map((oper) => oper.error) - .flatten() - .value(); - - const unmappedColumns = getUnmappedSheetColumns(sheetColumns, mapping); - const totalCount = allData.length; - - const createdCount = successedImport.length; - const errorsCount = failedImport.length; - const skippedCount = errorsCount; - - return { - resource, - createdCount, - skippedCount, - totalCount, - errorsCount, - errors, - unmappedColumns: unmappedColumns, - unmappedColumnsCount: unmappedColumns.length, - }; - } -} diff --git a/packages/server/src/services/Import/ImportFileProcessCommit.ts b/packages/server/src/services/Import/ImportFileProcessCommit.ts deleted file mode 100644 index f9cb640fc..000000000 --- a/packages/server/src/services/Import/ImportFileProcessCommit.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { ImportFilePreviewPOJO } from './interfaces'; -import { ImportFileProcess } from './ImportFileProcess'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { IImportFileCommitedEventPayload } from '@/interfaces/Import'; -import { ImportAls } from './ImportALS'; - -@Service() -export class ImportFileProcessCommit { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private importFile: ImportFileProcess; - - @Inject() - private importAls: ImportAls; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Commits the imported file under ALS. - * @param {number} tenantId - * @param {string} importId - * @returns {Promise} - */ - public commit( - tenantId: number, - importId: string - ): Promise { - return this.importAls.runCommit>(() => - this.commitAlsRun(tenantId, importId) - ); - } - - /** - * Commits the imported file. - * @param {number} tenantId - * @param {number} importId - * @returns {Promise} - */ - public async commitAlsRun( - tenantId: number, - importId: string - ): Promise { - const knex = this.tenancy.knex(tenantId); - const trx = await knex.transaction({ isolationLevel: 'read uncommitted' }); - - const meta = await this.importFile.import(tenantId, importId, trx); - - // Commit the successed transaction. - await trx.commit(); - - // Triggers `onImportFileCommitted` event. - await this.eventPublisher.emitAsync(events.import.onImportCommitted, { - meta, - importId, - tenantId, - } as IImportFileCommitedEventPayload); - - return meta; - } -} diff --git a/packages/server/src/services/Import/ImportFileUpload.ts b/packages/server/src/services/Import/ImportFileUpload.ts deleted file mode 100644 index 9f954de9d..000000000 --- a/packages/server/src/services/Import/ImportFileUpload.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - deleteImportFile, - getResourceColumns, - readImportFile, - sanitizeResourceName, - validateSheetEmpty, -} from './_utils'; -import ResourceService from '../Resource/ResourceService'; -import { ImportFileCommon } from './ImportFileCommon'; -import { ImportFileDataValidator } from './ImportFileDataValidator'; -import { ImportFileUploadPOJO } from './interfaces'; -import { Import } from '@/system/models'; -import { parseSheetData } from './sheet_utils'; - -@Service() -export class ImportFileUploadService { - @Inject() - private resourceService: ResourceService; - - @Inject() - private importFileCommon: ImportFileCommon; - - @Inject() - private importValidator: ImportFileDataValidator; - - /** - * Imports the specified file for the given resource. - * Deletes the file if an error occurs during the import process. - * @param {number} tenantId - * @param {string} resourceName - * @param {string} filename - * @param {Record} params - * @returns {Promise} - */ - public async import( - tenantId: number, - resourceName: string, - filename: string, - params: Record - ): Promise { - try { - return await this.importUnhandled( - tenantId, - resourceName, - filename, - params - ); - } catch (err) { - deleteImportFile(filename); - throw err; - } - } - - /** - * Reads the imported file and stores the import file meta under unqiue id. - * @param {number} tenantId - Tenant id. - * @param {string} resource - Resource name. - * @param {string} filePath - File path. - * @param {string} fileName - File name. - * @returns {Promise} - */ - public async importUnhandled( - tenantId: number, - resourceName: string, - filename: string, - params: Record - ): Promise { - const resource = sanitizeResourceName(resourceName); - const resourceMeta = this.resourceService.getResourceMeta( - tenantId, - resource - ); - // Throw service error if the resource does not support importing. - this.importValidator.validateResourceImportable(resourceMeta); - - // Reads the imported file into buffer. - const buffer = await readImportFile(filename); - - // Parse the buffer file to array data. - const [sheetData, sheetColumns] = parseSheetData(buffer); - const coumnsStringified = JSON.stringify(sheetColumns); - - // Throws service error if the sheet data is empty. - validateSheetEmpty(sheetData); - - try { - // Validates the params Yup schema. - await this.importFileCommon.validateParamsSchema(resource, params); - - // Validates importable params asyncly. - await this.importFileCommon.validateParams(tenantId, resource, params); - } catch (error) { - throw error; - } - const _params = this.importFileCommon.transformParams(resource, params); - const paramsStringified = JSON.stringify(_params); - - // Store the import model with related metadata. - const importFile = await Import.query().insert({ - filename, - resource, - tenantId, - importId: filename, - columns: coumnsStringified, - params: paramsStringified, - }); - const resourceColumnsMap = this.resourceService.getResourceFields2( - tenantId, - resource - ); - const resourceColumns = getResourceColumns(resourceColumnsMap); - - return { - import: { - importId: importFile.importId, - resource: importFile.resource, - }, - sheetColumns, - resourceColumns, - }; - } -} diff --git a/packages/server/src/services/Import/ImportRemoveExpiredFiles.ts b/packages/server/src/services/Import/ImportRemoveExpiredFiles.ts deleted file mode 100644 index c20f486f5..000000000 --- a/packages/server/src/services/Import/ImportRemoveExpiredFiles.ts +++ /dev/null @@ -1,34 +0,0 @@ -import moment from 'moment'; -import bluebird from 'bluebird'; -import { Import } from '@/system/models'; -import { deleteImportFile } from './_utils'; -import { Service } from 'typedi'; - -@Service() -export class ImportDeleteExpiredFiles { - /** - * Delete expired files. - */ - async deleteExpiredFiles() { - const yesterday = moment().subtract(1, 'hour').format('YYYY-MM-DD HH:mm'); - - const expiredImports = await Import.query().where( - 'createdAt', - '<', - yesterday - ); - await bluebird.map( - expiredImports, - async (expiredImport) => { - await deleteImportFile(expiredImport.filename); - }, - { concurrency: 10 } - ); - const expiredImportsIds = expiredImports.map( - (expiredImport) => expiredImport.id - ); - if (expiredImportsIds.length > 0) { - await Import.query().whereIn('id', expiredImportsIds).delete(); - } - } -} diff --git a/packages/server/src/services/Import/ImportResourceApplication.ts b/packages/server/src/services/Import/ImportResourceApplication.ts deleted file mode 100644 index 6e000804c..000000000 --- a/packages/server/src/services/Import/ImportResourceApplication.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Inject } from 'typedi'; -import { ImportFileUploadService } from './ImportFileUpload'; -import { ImportFileMapping } from './ImportFileMapping'; -import { ImportMappingAttr } from './interfaces'; -import { ImportFileProcess } from './ImportFileProcess'; -import { ImportFilePreview } from './ImportFilePreview'; -import { ImportSampleService } from './ImportSample'; -import { ImportFileMeta } from './ImportFileMeta'; -import { ImportFileProcessCommit } from './ImportFileProcessCommit'; - -@Inject() -export class ImportResourceApplication { - @Inject() - private importFileService: ImportFileUploadService; - - @Inject() - private importMappingService: ImportFileMapping; - - @Inject() - private importProcessService: ImportFileProcess; - - @Inject() - private ImportFilePreviewService: ImportFilePreview; - - @Inject() - private importSampleService: ImportSampleService; - - @Inject() - private importMetaService: ImportFileMeta; - - @Inject() - private importProcessCommit: ImportFileProcessCommit; - - /** - * Reads the imported file and stores the import file meta under unqiue id. - * @param {number} tenantId - - * @param {string} resource - Resource name. - * @param {string} fileName - File name. - * @returns {Promise} - */ - public async import( - tenantId: number, - resource: string, - filename: string, - params: Record - ) { - return this.importFileService.import(tenantId, resource, filename, params); - } - - /** - * Mapping the excel sheet columns with resource columns. - * @param {number} tenantId - * @param {number} importId - Import id. - * @param {ImportMappingAttr} maps - */ - public async mapping( - tenantId: number, - importId: string, - maps: ImportMappingAttr[] - ) { - return this.importMappingService.mapping(tenantId, importId, maps); - } - - /** - * Preview the mapped results before process importing. - * @param {number} tenantId - * @param {number} importId - Import id. - * @returns {Promise} - */ - public async preview(tenantId: number, importId: string) { - return this.ImportFilePreviewService.preview(tenantId, importId); - } - - /** - * Process the import file sheet through service for creating entities. - * @param {number} tenantId - * @param {number} importId - * @returns {Promise} - */ - public async process(tenantId: number, importId: string) { - return this.importProcessCommit.commit(tenantId, importId); - } - - /** - * Retrieves the import meta of the given import id. - * @param {number} tenantId - - * @param {string} importId - Import id. - * @returns {} - */ - public importMeta(tenantId: number, importId: string) { - return this.importMetaService.getImportMeta(tenantId, importId); - } - - /** - * Retrieves the csv/xlsx sample sheet of the given - * @param {number} tenantId - * @param {number} resource - Resource name. - */ - public sample( - tenantId: number, - resource: string, - format: 'csv' | 'xlsx' = 'csv' - ) { - return this.importSampleService.sample(tenantId, resource, format); - } -} diff --git a/packages/server/src/services/Import/ImportSample.ts b/packages/server/src/services/Import/ImportSample.ts deleted file mode 100644 index db2fe0543..000000000 --- a/packages/server/src/services/Import/ImportSample.ts +++ /dev/null @@ -1,46 +0,0 @@ -import XLSX from 'xlsx'; -import { Inject, Service } from 'typedi'; -import { ImportableResources } from './ImportableResources'; -import { sanitizeResourceName } from './_utils'; - -@Service() -export class ImportSampleService { - @Inject() - private importable: ImportableResources; - - /** - * Retrieves the sample sheet of the given resource. - * @param {number} tenantId - * @param {string} resource - * @param {string} format - * @returns {Buffer | string} - */ - public sample( - tenantId: number, - resource: string, - format: 'csv' | 'xlsx' - ): Buffer | string { - const _resource = sanitizeResourceName(resource); - - const ImportableRegistry = this.importable.registry; - const importable = ImportableRegistry.getImportable(_resource); - - const data = importable.sampleData(); - - const workbook = XLSX.utils.book_new(); - const worksheet = XLSX.utils.json_to_sheet(data); - XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); - - // Determine the output format - if (format === 'csv') { - const csvOutput = XLSX.utils.sheet_to_csv(worksheet); - return csvOutput; - } else { - const xlsxOutput = XLSX.write(workbook, { - bookType: 'xlsx', - type: 'buffer', - }); - return xlsxOutput; - } - } -} diff --git a/packages/server/src/services/Import/Importable.ts b/packages/server/src/services/Import/Importable.ts deleted file mode 100644 index 9cb82b56c..000000000 --- a/packages/server/src/services/Import/Importable.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import * as Yup from 'yup'; -import { ImportableContext } from './interfaces'; - -export abstract class Importable { - /** - * - * @param {number} tenantId - * @param {any} createDTO - * @param {Knex.Transaction} trx - */ - public importable(tenantId: number, createDTO: any, trx?: Knex.Transaction) { - throw new Error( - 'The `importable` function is not defined in service importable.' - ); - } - - /** - * Transformes the DTO before passing it to importable and validation. - * @param {Record} createDTO - * @param {ImportableContext} context - * @returns {Record} - */ - public transform(createDTO: Record, context: ImportableContext) { - return createDTO; - } - - /** - * Concurrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 10; - } - - /** - * Retrieves the sample data of importable. - * @returns {Array} - */ - public sampleData(): Array { - return []; - } - - // ------------------ - // # Params - // ------------------ - /** - * Params Yup validation schema. - * @returns {Yup.ObjectSchema} - */ - public paramsValidationSchema(): Yup.ObjectSchema { - return Yup.object().nullable(); - } - - /** - * Validates the params of the importable service. - * @param {Record} - * @returns {Promise} - True means passed and false failed. - */ - public async validateParams( - tenantId: number, - params: Record - ): Promise {} - - /** - * Transformes the import params before storing them. - * @param {Record} parmas - */ - public transformParams(parmas: Record) { - return parmas; - } -} \ No newline at end of file diff --git a/packages/server/src/services/Import/ImportableRegistry.ts b/packages/server/src/services/Import/ImportableRegistry.ts deleted file mode 100644 index 9fe25ec43..000000000 --- a/packages/server/src/services/Import/ImportableRegistry.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { camelCase, upperFirst } from 'lodash'; -import { Importable } from './Importable'; - -export class ImportableRegistry { - private static instance: ImportableRegistry; - private importables: Record; - - constructor() { - this.importables = {}; - } - - /** - * Gets singleton instance of registry. - * @returns {ImportableRegistry} - */ - public static getInstance(): ImportableRegistry { - if (!ImportableRegistry.instance) { - ImportableRegistry.instance = new ImportableRegistry(); - } - return ImportableRegistry.instance; - } - - /** - * Registers the given importable service. - * @param {string} resource - * @param {Importable} importable - */ - public registerImportable(resource: string, importable: Importable): void { - const _resource = this.sanitizeResourceName(resource); - this.importables[_resource] = importable; - } - - /** - * Retrieves the importable service instance of the given resource name. - * @param {string} name - * @returns {Importable} - */ - public getImportable(name: string): Importable { - const _name = this.sanitizeResourceName(name); - return this.importables[_name]; - } - - private sanitizeResourceName(resource: string) { - return upperFirst(camelCase(resource)); - } -} diff --git a/packages/server/src/services/Import/ImportableResources.ts b/packages/server/src/services/Import/ImportableResources.ts deleted file mode 100644 index f79ceb36f..000000000 --- a/packages/server/src/services/Import/ImportableResources.ts +++ /dev/null @@ -1,73 +0,0 @@ -import Container, { Service } from 'typedi'; -import { AccountsImportable } from '../Accounts/AccountsImportable'; -import { ImportableRegistry } from './ImportableRegistry'; -import { UncategorizedTransactionsImportable } from '../Cashflow/UncategorizedTransactionsImportable'; -import { CustomersImportable } from '../Contacts/Customers/CustomersImportable'; -import { VendorsImportable } from '../Contacts/Vendors/VendorsImportable'; -import { ItemsImportable } from '../Items/ItemsImportable'; -import { ItemCategoriesImportable } from '../ItemCategories/ItemCategoriesImportable'; -import { ManualJournalImportable } from '../ManualJournals/ManualJournalsImport'; -import { BillsImportable } from '../Purchases/Bills/BillsImportable'; -import { ExpensesImportable } from '../Expenses/ExpensesImportable'; -import { SaleInvoicesImportable } from '../Sales/Invoices/SaleInvoicesImportable'; -import { SaleEstimatesImportable } from '../Sales/Estimates/SaleEstimatesImportable'; -import { BillPaymentsImportable } from '../Purchases/BillPayments/BillPaymentsImportable'; -import { VendorCreditsImportable } from '../Purchases/VendorCredits/VendorCreditsImportable'; -import { PaymentsReceivedImportable } from '../Sales/PaymentReceived/PaymentsReceivedImportable'; -import { CreditNotesImportable } from '../CreditNotes/CreditNotesImportable'; -import { SaleReceiptsImportable } from '../Sales/Receipts/SaleReceiptsImportable'; -import { TaxRatesImportable } from '../TaxRates/TaxRatesImportable'; - -@Service() -export class ImportableResources { - private static registry: ImportableRegistry; - - constructor() { - this.boot(); - } - - /** - * Importable instances. - */ - private importables = [ - { resource: 'Account', importable: AccountsImportable }, - { - resource: 'UncategorizedCashflowTransaction', - importable: UncategorizedTransactionsImportable, - }, - { resource: 'Customer', importable: CustomersImportable }, - { resource: 'Vendor', importable: VendorsImportable }, - { resource: 'Item', importable: ItemsImportable }, - { resource: 'ItemCategory', importable: ItemCategoriesImportable }, - { resource: 'ManualJournal', importable: ManualJournalImportable }, - { resource: 'Bill', importable: BillsImportable }, - { resource: 'Expense', importable: ExpensesImportable }, - { resource: 'SaleInvoice', importable: SaleInvoicesImportable }, - { resource: 'SaleEstimate', importable: SaleEstimatesImportable }, - { resource: 'BillPayment', importable: BillPaymentsImportable }, - { resource: 'PaymentReceive', importable: PaymentsReceivedImportable }, - { resource: 'VendorCredit', importable: VendorCreditsImportable }, - { resource: 'CreditNote', importable: CreditNotesImportable }, - { resource: 'SaleReceipt', importable: SaleReceiptsImportable }, - { resource: 'TaxRate', importable: TaxRatesImportable }, - ]; - - public get registry() { - return ImportableResources.registry; - } - - /** - * Boots all the registered importables. - */ - public boot() { - if (!ImportableResources.registry) { - const instance = ImportableRegistry.getInstance(); - - this.importables.forEach((importable) => { - const importableInstance = Container.get(importable.importable); - instance.registerImportable(importable.resource, importableInstance); - }); - ImportableResources.registry = instance; - } - } -} diff --git a/packages/server/src/services/Import/_constants.ts b/packages/server/src/services/Import/_constants.ts deleted file mode 100644 index 1e9d37cbf..000000000 --- a/packages/server/src/services/Import/_constants.ts +++ /dev/null @@ -1,3 +0,0 @@ - - -export const CurrencyParsingDTOs = 10; \ No newline at end of file diff --git a/packages/server/src/services/Import/_utils.ts b/packages/server/src/services/Import/_utils.ts deleted file mode 100644 index c3127f110..000000000 --- a/packages/server/src/services/Import/_utils.ts +++ /dev/null @@ -1,459 +0,0 @@ -import * as Yup from 'yup'; -import moment from 'moment'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import fs from 'fs/promises'; -import path from 'path'; -import { - defaultTo, - upperFirst, - camelCase, - first, - isUndefined, - pickBy, - isEmpty, - castArray, - get, - head, - split, - last, -} from 'lodash'; -import pluralize from 'pluralize'; -import { ResourceMetaFieldsMap } from './interfaces'; -import { IModelMetaField, IModelMetaField2 } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { multiNumberParse } from '@/utils/multi-number-parse'; - -export const ERRORS = { - RESOURCE_NOT_IMPORTABLE: 'RESOURCE_NOT_IMPORTABLE', - INVALID_MAP_ATTRS: 'INVALID_MAP_ATTRS', - DUPLICATED_FROM_MAP_ATTR: 'DUPLICATED_FROM_MAP_ATTR', - DUPLICATED_TO_MAP_ATTR: 'DUPLICATED_TO_MAP_ATTR', - IMPORT_FILE_NOT_MAPPED: 'IMPORT_FILE_NOT_MAPPED', - INVALID_MAP_DATE_FORMAT: 'INVALID_MAP_DATE_FORMAT', - MAP_DATE_FORMAT_NOT_DEFINED: 'MAP_DATE_FORMAT_NOT_DEFINED', - IMPORTED_SHEET_EMPTY: 'IMPORTED_SHEET_EMPTY', -}; - -/** - * Trimms the imported object string values before parsing. - * @param {Record} obj - * @returns {} - */ -export function trimObject(obj: Record) { - return Object.entries(obj).reduce((acc, [key, value]) => { - // Trim the key - const trimmedKey = key.trim(); - - // Trim the value if it's a string, otherwise leave it as is - const trimmedValue = typeof value === 'string' ? value.trim() : value; - - // Assign the trimmed key and value to the accumulator object - return { ...acc, [trimmedKey]: trimmedValue }; - }, {}); -} - -/** - * Generates the Yup validation schema based on the given resource fields. - * @param {ResourceMetaFieldsMap} fields - * @returns {Yup} - */ -export const convertFieldsToYupValidation = (fields: ResourceMetaFieldsMap) => { - const yupSchema = {}; - - Object.keys(fields).forEach((fieldName: string) => { - const field = fields[fieldName] as IModelMetaField; - let fieldSchema; - fieldSchema = Yup.string().label(field.name); - - if (field.fieldType === 'text') { - if (!isUndefined(field.minLength)) { - fieldSchema = fieldSchema.min( - field.minLength, - `Minimum length is ${field.minLength} characters` - ); - } - if (!isUndefined(field.maxLength)) { - fieldSchema = fieldSchema.max( - field.maxLength, - `Maximum length is ${field.maxLength} characters` - ); - } - } else if (field.fieldType === 'number') { - fieldSchema = Yup.number().label(field.name); - - if (!isUndefined(field.max)) { - fieldSchema = fieldSchema.max(field.max); - } - if (!isUndefined(field.min)) { - fieldSchema = fieldSchema.min(field.min); - } - } else if (field.fieldType === 'boolean') { - fieldSchema = Yup.boolean().label(field.name); - } else if (field.fieldType === 'enumeration') { - const options = field.options.reduce((acc, option) => { - acc[option.key] = option.label; - return acc; - }, {}); - fieldSchema = Yup.string().oneOf(Object.keys(options)).label(field.name); - // Validate date field type. - } else if (field.fieldType === 'date') { - fieldSchema = fieldSchema.test( - 'date validation', - 'Invalid date or format. The string should be a valid YYYY-MM-DD format.', - (val) => { - if (!val) { - return true; - } - return moment(val, 'YYYY-MM-DD', true).isValid(); - } - ); - } else if (field.fieldType === 'url') { - fieldSchema = fieldSchema.url(); - } else if (field.fieldType === 'collection') { - const nestedFieldShema = convertFieldsToYupValidation(field.fields); - fieldSchema = Yup.array().label(field.name); - - if (!isUndefined(field.collectionMaxLength)) { - fieldSchema = fieldSchema.max(field.collectionMaxLength); - } - if (!isUndefined(field.collectionMinLength)) { - fieldSchema = fieldSchema.min(field.collectionMinLength); - } - fieldSchema = fieldSchema.of(nestedFieldShema); - } - if (field.required) { - fieldSchema = fieldSchema.required(); - } - const _fieldName = parseFieldName(fieldName, field); - - yupSchema[_fieldName] = fieldSchema; - }); - return Yup.object().shape(yupSchema); -}; - -const parseFieldName = (fieldName: string, field: IModelMetaField) => { - let _key = fieldName; - - if (field.dataTransferObjectKey) { - _key = field.dataTransferObjectKey; - } - return _key; -}; - -/** - * Retrieves the unmapped sheet columns. - * @param columns - * @param mapping - * @returns - */ -export const getUnmappedSheetColumns = (columns, mapping) => { - return columns.filter( - (column) => !mapping.some((map) => map.from === column) - ); -}; - -export const sanitizeResourceName = (resourceName: string) => { - return upperFirst(camelCase(pluralize.singular(resourceName))); -}; - -export const getSheetColumns = (sheetData: unknown[]) => { - return Object.keys(first(sheetData)); -}; - -/** - * Retrieves the unique value from the given imported object DTO based on the - * configured unique resource field. - * @param {{ [key: string]: IModelMetaField }} importableFields - - * @param {} - * @returns {string} - */ -export const getUniqueImportableValue = ( - importableFields: { [key: string]: IModelMetaField2 }, - objectDTO: Record -) => { - const uniqueImportableValue = pickBy( - importableFields, - (field) => field.unique - ); - const uniqueImportableKeys = Object.keys(uniqueImportableValue); - const uniqueImportableKey = first(uniqueImportableKeys); - - return defaultTo(objectDTO[uniqueImportableKey], ''); -}; - -/** - * Throws service error the given sheet is empty. - * @param {Array} sheetData - */ -export const validateSheetEmpty = (sheetData: Array) => { - if (isEmpty(sheetData)) { - throw new ServiceError(ERRORS.IMPORTED_SHEET_EMPTY); - } -}; - -const booleanValuesRepresentingTrue: string[] = ['true', 'yes', 'y', 't', '1']; -const booleanValuesRepresentingFalse: string[] = ['false', 'no', 'n', 'f', '0']; - -/** - * Parses the given string value to boolean. - * @param {string} value - * @returns {string|null} - */ -export const parseBoolean = (value: string): boolean | null => { - const normalizeValue = (value: string): string => - value.toString().trim().toLowerCase(); - - const normalizedValue = normalizeValue(value); - const valuesRepresentingTrue = - booleanValuesRepresentingTrue.map(normalizeValue); - const valueRepresentingFalse = - booleanValuesRepresentingFalse.map(normalizeValue); - - if (valuesRepresentingTrue.includes(normalizedValue)) { - return true; - } else if (valueRepresentingFalse.includes(normalizedValue)) { - return false; - } - return null; -}; - -export const transformInputToGroupedFields = (input) => { - const output = []; - - // Group for non-nested fields - const mainGroup = { - groupLabel: '', - groupKey: '', - fields: [], - }; - input.forEach((item) => { - if (!item.fields) { - // If the item does not have nested fields, add it to the main group - mainGroup.fields.push(item); - } else { - // If the item has nested fields, create a new group for these fields - output.push({ - groupLabel: item.name, - groupKey: item.key, - fields: item.fields, - }); - } - }); - // Add the main group to the output if it contains any fields - if (mainGroup.fields.length > 0) { - output.unshift(mainGroup); // Add the main group at the beginning - } - return output; -}; - -export const getResourceColumns = (resourceColumns: { - [key: string]: IModelMetaField2; -}) => { - const mapColumn = - (group: string) => - ([fieldKey, { name, importHint, required, order, ...field }]: [ - string, - IModelMetaField2 - ]) => { - const extra: Record = {}; - const key = fieldKey; - - if (group) { - extra.group = group; - } - if (field.fieldType === 'collection') { - extra.fields = mapColumns(field.fields, key); - } - return { - key, - name, - required, - hint: importHint, - order, - ...extra, - }; - }; - const sortColumn = (a, b) => - a.order && b.order ? a.order - b.order : a.order ? -1 : b.order ? 1 : 0; - - const mapColumns = (columns, parentKey = '') => - Object.entries(columns).map(mapColumn(parentKey)).sort(sortColumn); - - return R.compose(transformInputToGroupedFields, mapColumns)(resourceColumns); -}; - -// Prases the given object value based on the field key type. -export const valueParser = - (fields: ResourceMetaFieldsMap, tenantModels: any, trx?: Knex.Transaction) => - async (value: any, key: string, group = '') => { - let _value = value; - - const fieldKey = key.includes('.') ? key.split('.')[0] : key; - const field = group ? fields[group]?.fields[fieldKey] : fields[fieldKey]; - - // Parses the boolean value. - if (field.fieldType === 'boolean') { - _value = parseBoolean(value); - - // Parses the enumeration value. - } else if (field.fieldType === 'enumeration') { - const option = get(field, 'options', []).find( - (option) => option.label?.toLowerCase() === value?.toLowerCase() - ); - _value = get(option, 'key'); - // Parses the numeric value. - } else if (field.fieldType === 'number') { - _value = multiNumberParse(value); - // Parses the relation value. - } else if (field.fieldType === 'relation') { - const RelationModel = tenantModels[field.relationModel]; - - if (!RelationModel) { - throw new Error(`The relation model of ${key} field is not exist.`); - } - const relationQuery = RelationModel.query(trx); - const relationKeys = castArray(field?.relationImportMatch); - - relationQuery.where(function () { - relationKeys.forEach((relationKey: string) => { - this.orWhereRaw('LOWER(??) = LOWER(?)', [relationKey, value]); - }); - }); - const result = await relationQuery.first(); - _value = get(result, 'id'); - } else if (field.fieldType === 'collection') { - const ObjectFieldKey = key.includes('.') ? key.split('.')[1] : key; - const _valueParser = valueParser(fields, tenantModels); - _value = await _valueParser(value, ObjectFieldKey, fieldKey); - } - return _value; - }; - -/** - * Parses the field key and detarmines the key path. - * @param {{ [key: string]: IModelMetaField2 }} fields - * @param {string} key - Mapped key path. formats: `group.key` or `key`. - * @returns {string} - */ -export const parseKey = R.curry( - (fields: { [key: string]: IModelMetaField2 }, key: string) => { - const fieldKey = getFieldKey(key); - const field = fields[fieldKey]; - let _key = key; - - if (field.fieldType === 'collection') { - if (field.collectionOf === 'object') { - const nestedFieldKey = last(key.split('.')); - _key = `${fieldKey}[0].${nestedFieldKey}`; - } else if ( - field.collectionOf === 'string' || - field.collectionOf || - 'numberic' - ) { - _key = `${fieldKey}`; - } - } - return _key; - } -); - -/** - * Retrieves the field root key, for instance: I -> entries.itemId O -> entries. - * @param {string} input - * @returns {string} - */ -export const getFieldKey = (input: string) => { - const keys = split(input, '.'); - const firstKey = head(keys).split('[')[0]; // Split by "[" in case of array notation - return firstKey; -}; - -/** -{ * Aggregates the input array of objects based on a comparator attribute and groups the entries. - * This function is useful for combining multiple entries into a single entry based on a specific attribute, - * while aggregating other attributes into an array.} - * - * @param {Array} input - The array of objects to be aggregated. - * @param {string} comparatorAttr - The attribute of the objects used for comparison to aggregate. - * @param {string} groupOn - The attribute of the objects where the grouped entries will be pushed. - * @returns {Array} - The aggregated array of objects. - * - * @example - * // Example input: - * const input = [ - * { id: 1, name: 'John', entries: ['entry1'] }, - * { id: 2, name: 'Jane', entries: ['entry2'] }, - * { id: 1, name: 'John', entries: ['entry3'] }, - * ]; - * const comparatorAttr = 'id'; - * const groupOn = 'entries'; - * - * // Example output: - * const output = [ - * { id: 1, name: 'John', entries: ['entry1', 'entry3'] }, - * { id: 2, name: 'Jane', entries: ['entry2'] }, - * ]; - */ -export function aggregate( - input: Array, - comparatorAttr: string, - groupOn: string -): Array> { - return input.reduce((acc, curr) => { - const existingEntry = acc.find( - (entry) => entry[comparatorAttr] === curr[comparatorAttr] - ); - - if (existingEntry) { - existingEntry[groupOn].push(...curr.entries); - } else { - acc.push({ ...curr }); - } - return acc; - }, []); -} - -/** - * Sanitizes the data in the imported sheet by trimming object keys. - * @param json - The JSON data representing the imported sheet. - * @returns {string[][]} - The sanitized data with trimmed object keys. - */ -export const sanitizeSheetData = (json) => { - return R.compose(R.map(trimObject))(json); -}; - -/** - * Returns the path to map a value to based on the 'to' and 'group' parameters. - * @param {string} to - The target key to map the value to. - * @param {string} group - The group key to nest the target key under. - * @returns {string} - The path to map the value to. - */ -export const getMapToPath = (to: string, group = '') => - group ? `${group}.${to}` : to; - -export const getImportsStoragePath = () => { - return path.join(global.__storage_dir, `/imports`); -}; - -/** - * Deletes the imported file from the storage and database. - * @param {string} filename - */ -export const deleteImportFile = async (filename: string) => { - const filePath = getImportsStoragePath(); - - // Deletes the imported file. - await fs.unlink(`${filePath}/${filename}`); -}; - -/** - * Reads the import file. - * @param {string} filename - * @returns {Promise} - */ -export const readImportFile = (filename: string) => { - const filePath = getImportsStoragePath(); - - return fs.readFile(`${filePath}/${filename}`); -}; diff --git a/packages/server/src/services/Import/interfaces.ts b/packages/server/src/services/Import/interfaces.ts deleted file mode 100644 index 65d53ff59..000000000 --- a/packages/server/src/services/Import/interfaces.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { IModelMetaField, IModelMetaField2 } from '@/interfaces'; -import Import from '@/models/Import'; - -export interface ImportMappingAttr { - from: string; - to: string; - group?: string; - dateFormat?: string; -} - -export interface ImportValidationError { - index: number; - property: string; - constraints: Record; -} - -export type ResourceMetaFieldsMap = { [key: string]: IModelMetaField2 }; - -export interface ImportInsertError { - rowNumber: number; - errorCode: string; - errorMessage: string; -} - -export interface ImportFileUploadPOJO { - import: { - importId: string; - resource: string; - }; - sheetColumns: string[]; - resourceColumns: { - key: string; - name: string; - required?: boolean; - hint?: string; - }[]; -} - -export interface ImportFileMapPOJO { - import: { - importId: string; - resource: string; - }; -} - -export interface ImportFilePreviewPOJO { - resource: string; - createdCount: number; - skippedCount: number; - totalCount: number; - errorsCount: number; - errors: ImportInsertError[]; - unmappedColumns: string[]; - unmappedColumnsCount: number; -} - -export interface ImportOperSuccess { - data: unknown; - index: number; -} - -export interface ImportOperError { - error: ImportInsertError[]; - index: number; -} - -export interface ImportableContext { - import: Import; - rowIndex: number; -} - -export const ImportDateFormats = [ - 'yyyy-MM-dd', - 'dd.MM.yy', - 'MM/dd/yy', - 'dd/MMM/yyyy', -]; diff --git a/packages/server/src/services/Import/jobs/ImportDeleteExpiredFilesJob.ts b/packages/server/src/services/Import/jobs/ImportDeleteExpiredFilesJob.ts deleted file mode 100644 index 849703546..000000000 --- a/packages/server/src/services/Import/jobs/ImportDeleteExpiredFilesJob.ts +++ /dev/null @@ -1,28 +0,0 @@ -// import Container, { Service } from 'typedi'; -// import { ImportDeleteExpiredFiles } from '../ImportRemoveExpiredFiles'; - -// @Service() -// export class ImportDeleteExpiredFilesJobs { -// /** -// * Constructor method. -// */ -// constructor(agenda) { -// agenda.define('delete-expired-imported-files', this.handler); -// } - -// /** -// * Triggers sending invoice mail. -// */ -// private handler = async (job, done: Function) => { -// const importDeleteExpiredFiles = Container.get(ImportDeleteExpiredFiles); - -// try { -// console.log('Delete expired import files has started.'); -// await importDeleteExpiredFiles.deleteExpiredFiles(); -// done(); -// } catch (error) { -// console.log(error); -// done(error); -// } -// }; -// } diff --git a/packages/server/src/services/Import/sheet_utils.ts b/packages/server/src/services/Import/sheet_utils.ts deleted file mode 100644 index b21f07320..000000000 --- a/packages/server/src/services/Import/sheet_utils.ts +++ /dev/null @@ -1,56 +0,0 @@ -import XLSX from 'xlsx'; -import { first } from 'lodash'; - -/** - * Parses the given sheet buffer to worksheet. - * @param {Buffer} buffer - * @returns {XLSX.WorkSheet} - */ -export function parseFirstSheet(buffer: Buffer): XLSX.WorkSheet { - const workbook = XLSX.read(buffer, { type: 'buffer', raw: true }); - - const firstSheetName = workbook.SheetNames[0]; - const worksheet = workbook.Sheets[firstSheetName]; - - return worksheet; -} - -/** - * Extracts the given worksheet to columns. - * @param {XLSX.WorkSheet} worksheet - * @returns {Array} - */ -export function extractSheetColumns(worksheet: XLSX.WorkSheet): Array { - // By default, sheet_to_json scans the first row and uses the values as headers. - // With the header: 1 option, the function exports an array of arrays of values. - const sheetCells = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); - const sheetCols = first(sheetCells) as Array; - - return sheetCols.filter((col) => col); -} - -/** - * Parses the given worksheet to json values. the keys are columns labels. - * @param {XLSX.WorkSheet} worksheet - * @returns {Array>} - */ -export function parseSheetToJson( - worksheet: XLSX.WorkSheet -): Array> { - return XLSX.utils.sheet_to_json(worksheet, {}); -} - -/** - * Parses the given sheet buffer then retrieves the sheet data and columns. - * @param {Buffer} buffer - */ -export function parseSheetData( - buffer: Buffer -): [Array>, string[]] { - const worksheet = parseFirstSheet(buffer); - - const columns = extractSheetColumns(worksheet); - const data = parseSheetToJson(worksheet); - - return [data, columns]; -} diff --git a/packages/server/src/services/Inventory/Inventory.ts b/packages/server/src/services/Inventory/Inventory.ts deleted file mode 100644 index db1a3fb72..000000000 --- a/packages/server/src/services/Inventory/Inventory.ts +++ /dev/null @@ -1,384 +0,0 @@ -import { Container, Service, Inject } from 'typedi'; -import { pick } from 'lodash'; -import config from '@/config'; -import { - IInventoryLotCost, - IInventoryTransaction, - TInventoryTransactionDirection, - IItemEntry, - IItemEntryTransactionType, - IInventoryTransactionsCreatedPayload, - IInventoryTransactionsDeletedPayload, - IInventoryItemCostScheduledPayload, -} from '@/interfaces'; -import InventoryAverageCost from '@/services/Inventory/InventoryAverageCost'; -import InventoryCostLotTracker from '@/services/Inventory/InventoryCostLotTracker'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; - -type TCostMethod = 'FIFO' | 'LIFO' | 'AVG'; - -@Service() -export default class InventoryService { - @Inject() - tenancy: TenancyService; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - itemsEntriesService: ItemsEntriesService; - - @Inject() - uow: UnitOfWork; - - /** - * Transforms the items entries to inventory transactions. - */ - transformItemEntriesToInventory(transaction: { - transactionId: number; - transactionType: IItemEntryTransactionType; - transactionNumber?: string; - - exchangeRate?: number; - - warehouseId: number | null; - - date: Date | string; - direction: TInventoryTransactionDirection; - entries: IItemEntry[]; - createdAt: Date; - }): IInventoryTransaction[] { - const exchangeRate = transaction.exchangeRate || 1; - - return transaction.entries.map((entry: IItemEntry) => ({ - ...pick(entry, ['itemId', 'quantity']), - rate: entry.rate * exchangeRate, - transactionType: transaction.transactionType, - transactionId: transaction.transactionId, - direction: transaction.direction, - date: transaction.date, - entryId: entry.id, - createdAt: transaction.createdAt, - costAccountId: entry.costAccountId, - - warehouseId: entry.warehouseId || transaction.warehouseId, - meta: { - transactionNumber: transaction.transactionNumber, - description: entry.description, - }, - })); - } - - async computeItemCost(tenantId: number, fromDate: Date, itemId: number) { - return this.uow.withTransaction(tenantId, (trx: Knex.Transaction) => { - return this.computeInventoryItemCost(tenantId, fromDate, itemId); - }); - } - - /** - * Computes the given item cost and records the inventory lots transactions - * and journal entries based on the cost method FIFO, LIFO or average cost rate. - * @param {number} tenantId - Tenant id. - * @param {Date} fromDate - From date. - * @param {number} itemId - Item id. - */ - async computeInventoryItemCost( - tenantId: number, - fromDate: Date, - itemId: number, - trx?: Knex.Transaction - ) { - const { Item } = this.tenancy.models(tenantId); - - // Fetches the item with associated item category. - const item = await Item.query().findById(itemId); - - // Cannot continue if the given item was not inventory item. - if (item.type !== 'inventory') { - throw new Error('You could not compute item cost has no inventory type.'); - } - let costMethodComputer: IInventoryCostMethod; - - // Switch between methods based on the item cost method. - switch ('AVG') { - case 'FIFO': - case 'LIFO': - costMethodComputer = new InventoryCostLotTracker( - tenantId, - fromDate, - itemId - ); - break; - case 'AVG': - costMethodComputer = new InventoryAverageCost( - tenantId, - fromDate, - itemId, - trx - ); - break; - } - return costMethodComputer.computeItemCost(); - } - - /** - * Schedule item cost compute job. - * @param {number} tenantId - * @param {number} itemId - * @param {Date} startingDate - */ - async scheduleComputeItemCost( - tenantId: number, - itemId: number, - startingDate: Date | string - ) { - const agenda = Container.get('agenda'); - - const commonJobsQuery = { - name: 'compute-item-cost', - lastRunAt: { $exists: false }, - 'data.tenantId': tenantId, - 'data.itemId': itemId, - }; - // Cancel any `compute-item-cost` in the queue has upper starting date - // with the same given item. - await agenda.cancel({ - ...commonJobsQuery, - 'data.startingDate': { $lte: startingDate }, - }); - // Retrieve any `compute-item-cost` in the queue has lower starting date - // with the same given item. - const dependsJobs = await agenda.jobs({ - ...commonJobsQuery, - 'data.startingDate': { $gte: startingDate }, - }); - // If the depends jobs cleared. - if (dependsJobs.length === 0) { - await agenda.schedule( - config.scheduleComputeItemCost, - 'compute-item-cost', - { - startingDate, - itemId, - tenantId, - } - ); - // Triggers `onComputeItemCostJobScheduled` event. - await this.eventPublisher.emitAsync( - events.inventory.onComputeItemCostJobScheduled, - { startingDate, itemId, tenantId } as IInventoryItemCostScheduledPayload - ); - } else { - // Re-schedule the jobs that have higher date from current moment. - await Promise.all( - dependsJobs.map((job) => - job.schedule(config.scheduleComputeItemCost).save() - ) - ); - } - } - - /** - * Records the inventory transactions. - * @param {number} tenantId - Tenant id. - * @param {Bill} bill - Bill model object. - * @param {number} billId - Bill id. - * @return {Promise} - */ - async recordInventoryTransactions( - tenantId: number, - transactions: IInventoryTransaction[], - override: boolean = false, - trx?: Knex.Transaction - ): Promise { - const bulkInsertOpers = []; - - transactions.forEach((transaction: IInventoryTransaction) => { - const oper = this.recordInventoryTransaction( - tenantId, - transaction, - override, - trx - ); - bulkInsertOpers.push(oper); - }); - const inventoryTransactions = await Promise.all(bulkInsertOpers); - - // Triggers `onInventoryTransactionsCreated` event. - await this.eventPublisher.emitAsync( - events.inventory.onInventoryTransactionsCreated, - { - tenantId, - inventoryTransactions, - trx, - } as IInventoryTransactionsCreatedPayload - ); - } - - /** - * Writes the inventory transactiosn on the storage from the given - * inventory transactions entries. - * - * @param {number} tenantId - - * @param {IInventoryTransaction} inventoryEntry - - * @param {boolean} deleteOld - - */ - async recordInventoryTransaction( - tenantId: number, - inventoryEntry: IInventoryTransaction, - deleteOld: boolean = false, - trx: Knex.Transaction - ): Promise { - const { InventoryTransaction } = this.tenancy.models(tenantId); - - if (deleteOld) { - await this.deleteInventoryTransactions( - tenantId, - inventoryEntry.transactionId, - inventoryEntry.transactionType, - trx - ); - } - return InventoryTransaction.query(trx).insertGraph({ - ...inventoryEntry, - }); - } - - /** - * Records the inventory transactions from items entries that have (inventory) type. - * @param {number} tenantId - * @param {number} transactionId - * @param {string} transactionType - * @param {Date|string} transactionDate - * @param {boolean} override - */ - async recordInventoryTransactionsFromItemsEntries( - tenantId: number, - transaction: { - transactionId: number; - transactionType: IItemEntryTransactionType; - exchangeRate: number; - - date: Date | string; - direction: TInventoryTransactionDirection; - entries: IItemEntry[]; - createdAt: Date | string; - - warehouseId: number; - }, - override: boolean = false, - trx?: Knex.Transaction - ): Promise { - // Can't continue if there is no entries has inventory items in the invoice. - if (transaction.entries.length <= 0) { - return; - } - // Inventory transactions. - const inventoryTranscations = - this.transformItemEntriesToInventory(transaction); - - // Records the inventory transactions of the given sale invoice. - await this.recordInventoryTransactions( - tenantId, - inventoryTranscations, - override, - trx - ); - } - - /** - * Deletes the given inventory transactions. - * @param {number} tenantId - Tenant id. - * @param {string} transactionType - * @param {number} transactionId - * @return {Promise<{ - * oldInventoryTransactions: IInventoryTransaction[] - * }>} - */ - async deleteInventoryTransactions( - tenantId: number, - transactionId: number, - transactionType: string, - trx?: Knex.Transaction - ): Promise<{ oldInventoryTransactions: IInventoryTransaction[] }> { - const { InventoryTransaction } = this.tenancy.models(tenantId); - - // Retrieve the inventory transactions of the given sale invoice. - const oldInventoryTransactions = await InventoryTransaction.query( - trx - ).where({ transactionId, transactionType }); - - // Deletes the inventory transactions by the given transaction type and id. - await InventoryTransaction.query(trx) - .where({ transactionType, transactionId }) - .delete(); - - // Triggers `onInventoryTransactionsDeleted` event. - await this.eventPublisher.emitAsync( - events.inventory.onInventoryTransactionsDeleted, - { - tenantId, - oldInventoryTransactions, - transactionId, - transactionType, - trx, - } as IInventoryTransactionsDeletedPayload - ); - return { oldInventoryTransactions }; - } - - /** - * Records the inventory cost lot transaction. - * @param {number} tenantId - * @param {IInventoryLotCost} inventoryLotEntry - * @return {Promise} - */ - async recordInventoryCostLotTransaction( - tenantId: number, - inventoryLotEntry: IInventoryLotCost - ): Promise { - const { InventoryCostLotTracker } = this.tenancy.models(tenantId); - - return InventoryCostLotTracker.query().insert({ - ...inventoryLotEntry, - }); - } - - /** - * Mark item cost computing is running. - * @param {number} tenantId - - * @param {boolean} isRunning - - */ - async markItemsCostComputeRunning( - tenantId: number, - isRunning: boolean = true - ) { - const settings = this.tenancy.settings(tenantId); - - settings.set({ - key: 'cost_compute_running', - group: 'inventory', - value: isRunning, - }); - await settings.save(); - } - - /** - * - * @param {number} tenantId - * @returns - */ - isItemsCostComputeRunning(tenantId) { - const settings = this.tenancy.settings(tenantId); - - return settings.get({ - key: 'cost_compute_running', - group: 'inventory', - }); - } -} diff --git a/packages/server/src/services/Inventory/InventoryAdjustmentGL.ts b/packages/server/src/services/Inventory/InventoryAdjustmentGL.ts deleted file mode 100644 index 7d03c7558..000000000 --- a/packages/server/src/services/Inventory/InventoryAdjustmentGL.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import * as R from 'ramda'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - AccountNormal, - IInventoryAdjustment, - IInventoryAdjustmentEntry, - ILedgerEntry, -} from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export default class InventoryAdjustmentsGL { - @Inject() - private tenancy: TenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Retrieves the inventory adjustment common GL entry. - * @param {InventoryAdjustment} inventoryAdjustment - - * @param {string} baseCurrency - - * @returns {ILedgerEntry} - */ - private getAdjustmentGLCommonEntry = ( - inventoryAdjustment: IInventoryAdjustment, - baseCurrency: string - ) => { - return { - currencyCode: baseCurrency, - exchangeRate: 1, - - transactionId: inventoryAdjustment.id, - transactionType: 'InventoryAdjustment', - referenceNumber: inventoryAdjustment.referenceNo, - - date: inventoryAdjustment.date, - - userId: inventoryAdjustment.userId, - branchId: inventoryAdjustment.branchId, - - createdAt: inventoryAdjustment.createdAt, - - credit: 0, - debit: 0, - }; - }; - - /** - * Retrieve the inventory adjustment inventory GL entry. - * @param {IInventoryAdjustment} inventoryAdjustment -Inventory adjustment model. - * @param {string} baseCurrency - Base currency of the organization. - * @param {IInventoryAdjustmentEntry} entry - - * @param {number} index - - * @returns {ILedgerEntry} - */ - private getAdjustmentGLInventoryEntry = R.curry( - ( - inventoryAdjustment: IInventoryAdjustment, - baseCurrency: string, - entry: IInventoryAdjustmentEntry, - index: number - ): ILedgerEntry => { - const commonEntry = this.getAdjustmentGLCommonEntry( - inventoryAdjustment, - baseCurrency - ); - const amount = entry.cost * entry.quantity; - - return { - ...commonEntry, - debit: amount, - accountId: entry.item.inventoryAccountId, - accountNormal: AccountNormal.DEBIT, - index, - }; - } - ); - - /** - * Retrieves the inventory adjustment - * @param {IInventoryAdjustment} inventoryAdjustment - * @param {IInventoryAdjustmentEntry} entry - * @returns {ILedgerEntry} - */ - private getAdjustmentGLCostEntry = R.curry( - ( - inventoryAdjustment: IInventoryAdjustment, - baseCurrency: string, - entry: IInventoryAdjustmentEntry, - index: number - ): ILedgerEntry => { - const commonEntry = this.getAdjustmentGLCommonEntry( - inventoryAdjustment, - baseCurrency - ); - const amount = entry.cost * entry.quantity; - - return { - ...commonEntry, - accountId: inventoryAdjustment.adjustmentAccountId, - accountNormal: AccountNormal.DEBIT, - credit: amount, - index: index + 2, - }; - } - ); - - /** - * Retrieve the inventory adjustment GL item entry. - * @param {InventoryAdjustment} adjustment - * @param {string} baseCurrency - * @param {InventoryAdjustmentEntry} entry - * @param {number} index - * @returns {} - */ - private getAdjustmentGLItemEntry = R.curry( - ( - adjustment: IInventoryAdjustment, - baseCurrency: string, - entry: IInventoryAdjustmentEntry, - index: number - ): ILedgerEntry[] => { - const getInventoryEntry = this.getAdjustmentGLInventoryEntry( - adjustment, - baseCurrency - ); - const inventoryEntry = getInventoryEntry(entry, index); - const costEntry = this.getAdjustmentGLCostEntry( - adjustment, - baseCurrency, - entry, - index - ); - return [inventoryEntry, costEntry]; - } - ); - - /** - * Writes increment inventroy adjustment GL entries. - * @param {InventoryAdjustment} inventoryAdjustment - - * @param {JournalPoster} jorunal - - * @returns {ILedgerEntry[]} - */ - public getIncrementAdjustmentGLEntries( - inventoryAdjustment: IInventoryAdjustment, - baseCurrency: string - ): ILedgerEntry[] { - const getItemEntry = this.getAdjustmentGLItemEntry( - inventoryAdjustment, - baseCurrency - ); - return inventoryAdjustment.entries.map(getItemEntry).flat(); - } - - /** - * Writes inventory increment adjustment GL entries. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId - */ - public writeAdjustmentGLEntries = async ( - tenantId: number, - inventoryAdjustmentId: number, - trx?: Knex.Transaction - ): Promise => { - const { InventoryAdjustment } = this.tenancy.models(tenantId); - - // Retrieves the inventory adjustment with associated entries. - const adjustment = await InventoryAdjustment.query(trx) - .findById(inventoryAdjustmentId) - .withGraphFetched('entries.item'); - - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieves the inventory adjustment GL entries. - const entries = this.getIncrementAdjustmentGLEntries( - adjustment, - tenantMeta.baseCurrency - ); - const ledger = new Ledger(entries); - - // Commits the ledger entries to the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Reverts the adjustment transactions GL entries. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId - * @returns {Promise} - */ - public revertAdjustmentGLEntries = ( - tenantId: number, - inventoryAdjustmentId: number, - trx?: Knex.Transaction - ): Promise => { - return this.ledgerStorage.deleteByReference( - tenantId, - inventoryAdjustmentId, - 'InventoryAdjustment', - trx - ); - }; - - /** - * Rewrite inventory adjustment GL entries. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId - * @param {Knex.Transaction} trx - */ - public rewriteAdjustmentGLEntries = async ( - tenantId: number, - inventoryAdjustmentId: number, - trx?: Knex.Transaction - ) => { - // Reverts GL entries of the given inventory adjustment. - await this.revertAdjustmentGLEntries(tenantId, inventoryAdjustmentId, trx); - - // Writes GL entries of th egiven inventory adjustment. - await this.writeAdjustmentGLEntries(tenantId, inventoryAdjustmentId, trx); - }; -} diff --git a/packages/server/src/services/Inventory/InventoryAdjustmentService.ts b/packages/server/src/services/Inventory/InventoryAdjustmentService.ts deleted file mode 100644 index 48b94d149..000000000 --- a/packages/server/src/services/Inventory/InventoryAdjustmentService.ts +++ /dev/null @@ -1,475 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { omit } from 'lodash'; -import moment from 'moment'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { ServiceError } from '@/exceptions'; -import { - IQuickInventoryAdjustmentDTO, - IInventoryAdjustment, - IPaginationMeta, - IInventoryAdjustmentsFilter, - ISystemUser, - IInventoryTransaction, - IInventoryAdjustmentEventCreatedPayload, - IInventoryAdjustmentEventPublishedPayload, - IInventoryAdjustmentEventDeletedPayload, - IInventoryAdjustmentCreatingPayload, - IInventoryAdjustmentDeletingPayload, - IInventoryAdjustmentPublishingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import InventoryService from './Inventory'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import InventoryAdjustmentTransformer from './InventoryAdjustmentTransformer'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -const ERRORS = { - INVENTORY_ADJUSTMENT_NOT_FOUND: 'INVENTORY_ADJUSTMENT_NOT_FOUND', - ITEM_SHOULD_BE_INVENTORY_TYPE: 'ITEM_SHOULD_BE_INVENTORY_TYPE', - INVENTORY_ADJUSTMENT_ALREADY_PUBLISHED: - 'INVENTORY_ADJUSTMENT_ALREADY_PUBLISHED', -}; - -@Service() -export default class InventoryAdjustmentService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private inventoryService: InventoryService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - @Inject() - private transfromer: TransformerInjectable; - - /** - * Transformes the quick inventory adjustment DTO to model object. - * @param {IQuickInventoryAdjustmentDTO} adjustmentDTO - - * @return {IInventoryAdjustment} - */ - private transformQuickAdjToModel( - tenantId: number, - adjustmentDTO: IQuickInventoryAdjustmentDTO, - authorizedUser: ISystemUser - ): IInventoryAdjustment { - const entries = [ - { - index: 1, - itemId: adjustmentDTO.itemId, - ...('increment' === adjustmentDTO.type - ? { - quantity: adjustmentDTO.quantity, - cost: adjustmentDTO.cost, - } - : {}), - ...('decrement' === adjustmentDTO.type - ? { - quantity: adjustmentDTO.quantity, - } - : {}), - }, - ]; - const initialDTO = { - ...omit(adjustmentDTO, ['quantity', 'cost', 'itemId', 'publish']), - userId: authorizedUser.id, - ...(adjustmentDTO.publish - ? { - publishedAt: moment().toMySqlDateTime(), - } - : {}), - entries, - }; - return R.compose( - this.warehouseDTOTransform.transformDTO(tenantId), - this.branchDTOTransform.transformDTO(tenantId) - )(initialDTO); - } - - /** - * Validate the item inventory type. - * @param {IItem} item - */ - validateItemInventoryType(item) { - if (item.type !== 'inventory') { - throw new ServiceError(ERRORS.ITEM_SHOULD_BE_INVENTORY_TYPE); - } - } - - /** - * Retrieve the inventory adjustment or throw not found service error. - * @param {number} tenantId - - * @param {number} adjustmentId - - */ - async getInventoryAdjustmentOrThrowError( - tenantId: number, - adjustmentId: number - ) { - const { InventoryAdjustment } = this.tenancy.models(tenantId); - - const inventoryAdjustment = await InventoryAdjustment.query() - .findById(adjustmentId) - .withGraphFetched('entries'); - - if (!inventoryAdjustment) { - throw new ServiceError(ERRORS.INVENTORY_ADJUSTMENT_NOT_FOUND); - } - return inventoryAdjustment; - } - - /** - * Creates a quick inventory adjustment for specific item. - * @param {number} tenantId - Tenant id. - * @param {IQuickInventoryAdjustmentDTO} quickAdjustmentDTO - qucik adjustment DTO. - */ - public async createQuickAdjustment( - tenantId: number, - quickAdjustmentDTO: IQuickInventoryAdjustmentDTO, - authorizedUser: ISystemUser - ): Promise { - const { InventoryAdjustment, Account, Item } = - this.tenancy.models(tenantId); - - // Retrieve the adjustment account or throw not found error. - const adjustmentAccount = await Account.query() - .findById(quickAdjustmentDTO.adjustmentAccountId) - .throwIfNotFound(); - - // Retrieve the item model or throw not found service error. - const item = await Item.query() - .findById(quickAdjustmentDTO.itemId) - .throwIfNotFound(); - - // Validate item inventory type. - this.validateItemInventoryType(item); - - // Transform the DTO to inventory adjustment model. - const invAdjustmentObject = this.transformQuickAdjToModel( - tenantId, - quickAdjustmentDTO, - authorizedUser - ); - // Writes inventory adjustment transaction with associated transactions - // under unit-of-work envirment. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onInventoryAdjustmentCreating` event. - await this.eventPublisher.emitAsync( - events.inventoryAdjustment.onQuickCreating, - { - tenantId, - trx, - quickAdjustmentDTO, - } as IInventoryAdjustmentCreatingPayload - ); - // Saves the inventory adjustment with associated entries to the storage. - const inventoryAdjustment = await InventoryAdjustment.query( - trx - ).upsertGraph({ - ...invAdjustmentObject, - }); - // Triggers `onInventoryAdjustmentQuickCreated` event. - await this.eventPublisher.emitAsync( - events.inventoryAdjustment.onQuickCreated, - { - tenantId, - inventoryAdjustment, - inventoryAdjustmentId: inventoryAdjustment.id, - trx, - } as IInventoryAdjustmentEventCreatedPayload - ); - return inventoryAdjustment; - }); - } - - /** - * Deletes the inventory adjustment transaction. - * @param {number} tenantId - Tenant id. - * @param {number} inventoryAdjustmentId - Inventory adjustment id. - */ - public async deleteInventoryAdjustment( - tenantId: number, - inventoryAdjustmentId: number - ): Promise { - const { InventoryAdjustmentEntry, InventoryAdjustment } = - this.tenancy.models(tenantId); - - // Retrieve the inventory adjustment or throw not found service error. - const oldInventoryAdjustment = - await this.getInventoryAdjustmentOrThrowError( - tenantId, - inventoryAdjustmentId - ); - // Deletes the inventory adjustment transaction and associated transactions - // under unit-of-work env. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onInventoryAdjustmentDeleting` event. - await this.eventPublisher.emitAsync( - events.inventoryAdjustment.onDeleting, - { - trx, - oldInventoryAdjustment, - tenantId, - } as IInventoryAdjustmentDeletingPayload - ); - - // Deletes the inventory adjustment entries. - await InventoryAdjustmentEntry.query(trx) - .where('adjustment_id', inventoryAdjustmentId) - .delete(); - - // Deletes the inventory adjustment transaction. - await InventoryAdjustment.query(trx) - .findById(inventoryAdjustmentId) - .delete(); - - // Triggers `onInventoryAdjustmentDeleted` event. - await this.eventPublisher.emitAsync( - events.inventoryAdjustment.onDeleted, - { - tenantId, - inventoryAdjustmentId, - oldInventoryAdjustment, - trx, - } as IInventoryAdjustmentEventDeletedPayload - ); - }); - } - - /** - * Publish the inventory adjustment transaction. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId - */ - public async publishInventoryAdjustment( - tenantId: number, - inventoryAdjustmentId: number - ): Promise { - const { InventoryAdjustment } = this.tenancy.models(tenantId); - - // Retrieve the inventory adjustment or throw not found service error. - const oldInventoryAdjustment = - await this.getInventoryAdjustmentOrThrowError( - tenantId, - inventoryAdjustmentId - ); - - // Validate adjustment not already published. - this.validateAdjustmentTransactionsNotPublished(oldInventoryAdjustment); - - // Publishes inventory adjustment with associated inventory transactions - // under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - await this.eventPublisher.emitAsync( - events.inventoryAdjustment.onPublishing, - { - trx, - tenantId, - oldInventoryAdjustment, - } as IInventoryAdjustmentPublishingPayload - ); - - // Publish the inventory adjustment transaction. - await InventoryAdjustment.query().findById(inventoryAdjustmentId).patch({ - publishedAt: moment().toMySqlDateTime(), - }); - // Retrieve the inventory adjustment after the modification. - const inventoryAdjustment = await InventoryAdjustment.query() - .findById(inventoryAdjustmentId) - .withGraphFetched('entries'); - - // Triggers `onInventoryAdjustmentDeleted` event. - await this.eventPublisher.emitAsync( - events.inventoryAdjustment.onPublished, - { - tenantId, - inventoryAdjustmentId, - inventoryAdjustment, - oldInventoryAdjustment, - trx, - } as IInventoryAdjustmentEventPublishedPayload - ); - }); - } - - /** - * Parses inventory adjustments list filter DTO. - * @param filterDTO - - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } - - /** - * Retrieve the inventory adjustments paginated list. - * @param {number} tenantId - * @param {IInventoryAdjustmentsFilter} adjustmentsFilter - */ - public async getInventoryAdjustments( - tenantId: number, - filterDTO: IInventoryAdjustmentsFilter - ): Promise<{ - inventoryAdjustments: IInventoryAdjustment[]; - pagination: IPaginationMeta; - }> { - const { InventoryAdjustment } = this.tenancy.models(tenantId); - - // Parses inventory adjustments list filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - InventoryAdjustment, - filter - ); - const { results, pagination } = await InventoryAdjustment.query() - .onBuild((query) => { - query.withGraphFetched('entries.item'); - query.withGraphFetched('adjustmentAccount'); - - dynamicFilter.buildQuery()(query); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Retrieves the transformed inventory adjustments. - const inventoryAdjustments = await this.transfromer.transform( - tenantId, - results, - new InventoryAdjustmentTransformer() - ); - return { - inventoryAdjustments, - pagination, - }; - } - - /** - * Writes the inventory transactions from the inventory adjustment transaction. - * @param {number} tenantId - - * @param {IInventoryAdjustment} inventoryAdjustment - - * @param {boolean} override - - * @param {Knex.Transaction} trx - - * @return {Promise} - */ - public async writeInventoryTransactions( - tenantId: number, - inventoryAdjustment: IInventoryAdjustment, - override: boolean = false, - trx?: Knex.Transaction - ): Promise { - const commonTransaction = { - direction: inventoryAdjustment.inventoryDirection, - date: inventoryAdjustment.date, - transactionType: 'InventoryAdjustment', - transactionId: inventoryAdjustment.id, - createdAt: inventoryAdjustment.createdAt, - costAccountId: inventoryAdjustment.adjustmentAccountId, - - branchId: inventoryAdjustment.branchId, - warehouseId: inventoryAdjustment.warehouseId, - }; - const inventoryTransactions = []; - - inventoryAdjustment.entries.forEach((entry) => { - inventoryTransactions.push({ - ...commonTransaction, - itemId: entry.itemId, - quantity: entry.quantity, - rate: entry.cost, - }); - }); - // Saves the given inventory transactions to the storage. - await this.inventoryService.recordInventoryTransactions( - tenantId, - inventoryTransactions, - override, - trx - ); - } - - /** - * Reverts the inventory transactions from the inventory adjustment transaction. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId - */ - async revertInventoryTransactions( - tenantId: number, - inventoryAdjustmentId: number, - trx?: Knex.Transaction - ): Promise<{ oldInventoryTransactions: IInventoryTransaction[] }> { - return this.inventoryService.deleteInventoryTransactions( - tenantId, - inventoryAdjustmentId, - 'InventoryAdjustment', - trx - ); - } - - /** - * Retrieve specific inventory adjustment transaction details. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId - */ - async getInventoryAdjustment( - tenantId: number, - inventoryAdjustmentId: number - ) { - const { InventoryAdjustment } = this.tenancy.models(tenantId); - - // Retrieve inventory adjustment transation with associated models. - const inventoryAdjustment = await InventoryAdjustment.query() - .findById(inventoryAdjustmentId) - .withGraphFetched('entries.item') - .withGraphFetched('adjustmentAccount'); - - // Throw not found if the given adjustment transaction not exists. - this.throwIfAdjustmentNotFound(inventoryAdjustment); - - return this.transfromer.transform( - tenantId, - inventoryAdjustment, - new InventoryAdjustmentTransformer() - ); - } - - /** - * Validate the adjustment transaction is exists. - * @param {IInventoryAdjustment} inventoryAdjustment - */ - private throwIfAdjustmentNotFound(inventoryAdjustment: IInventoryAdjustment) { - if (!inventoryAdjustment) { - throw new ServiceError(ERRORS.INVENTORY_ADJUSTMENT_NOT_FOUND); - } - } - - /** - * Validates the adjustment transaction is not already published. - * @param {IInventoryAdjustment} oldInventoryAdjustment - */ - private validateAdjustmentTransactionsNotPublished( - oldInventoryAdjustment: IInventoryAdjustment - ) { - if (oldInventoryAdjustment.isPublished) { - throw new ServiceError(ERRORS.INVENTORY_ADJUSTMENT_ALREADY_PUBLISHED); - } - } -} diff --git a/packages/server/src/services/Inventory/InventoryAdjustmentTransformer.ts b/packages/server/src/services/Inventory/InventoryAdjustmentTransformer.ts deleted file mode 100644 index f98acaaf8..000000000 --- a/packages/server/src/services/Inventory/InventoryAdjustmentTransformer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { IInventoryAdjustment } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; - -export default class InventoryAdjustmentTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['formattedType']; - }; - - /** - * Retrieves the formatted and localized adjustment type. - * @param {IInventoryAdjustment} inventoryAdjustment - * @returns {string} - */ - formattedType(inventoryAdjustment: IInventoryAdjustment) { - const types = { - increment: 'inventory_adjustment.type.increment', - decrement: 'inventory_adjustment.type.decrement', - }; - return this.context.i18n.__(types[inventoryAdjustment.type] || ''); - } -} diff --git a/packages/server/src/services/Inventory/InventoryAverageCost.ts b/packages/server/src/services/Inventory/InventoryAverageCost.ts deleted file mode 100644 index 84c2bdd85..000000000 --- a/packages/server/src/services/Inventory/InventoryAverageCost.ts +++ /dev/null @@ -1,257 +0,0 @@ -import { pick } from 'lodash'; -import { Knex } from 'knex'; -import { IInventoryTransaction } from '@/interfaces'; -import InventoryCostMethod from '@/services/Inventory/InventoryCostMethod'; - -export default class InventoryAverageCostMethod - extends InventoryCostMethod - implements IInventoryCostMethod -{ - startingDate: Date; - itemId: number; - costTransactions: any[]; - trx: Knex.Transaction; - - /** - * Constructor method. - * @param {number} tenantId - The given tenant id. - * @param {Date} startingDate - - * @param {number} itemId - The given inventory item id. - */ - constructor( - tenantId: number, - startingDate: Date, - itemId: number, - trx?: Knex.Transaction - ) { - super(tenantId, startingDate, itemId); - - this.trx = trx; - this.startingDate = startingDate; - this.itemId = itemId; - this.costTransactions = []; - } - - /** - * Computes items costs from the given date using average cost method. - * ---------- - * - Calculate the items average cost in the given date. - * - Remove the journal entries that associated to the inventory transacions - * after the given date. - * - Re-compute the inventory transactions and re-write the journal entries - * after the given date. - * ---------- - * @async - * @param {Date} startingDate - * @param {number} referenceId - * @param {string} referenceType - */ - public async computeItemCost() { - const { InventoryTransaction } = this.tenantModels; - const { averageCost, openingQuantity, openingCost } = - await this.getOpeningAverageCost(this.startingDate, this.itemId); - - const afterInvTransactions: IInventoryTransaction[] = - await InventoryTransaction.query() - .modify('filterDateRange', this.startingDate) - .orderBy('date', 'ASC') - .orderByRaw("FIELD(direction, 'IN', 'OUT')") - .orderBy('createdAt', 'ASC') - .where('item_id', this.itemId) - .withGraphFetched('item'); - - // Tracking inventroy transactions and retrieve cost transactions based on - // average rate cost method. - const costTransactions = this.trackingCostTransactions( - afterInvTransactions, - openingQuantity, - openingCost - ); - // Revert the inveout out lots transactions - await this.revertTheInventoryOutLotTrans(); - - // Store inventory lots cost transactions. - await this.storeInventoryLotsCost(costTransactions); - } - - /** - * Get items Average cost from specific date from inventory transactions. - * @async - * @param {Date} closingDate - * @return {number} - */ - public async getOpeningAverageCost(closingDate: Date, itemId: number) { - const { InventoryCostLotTracker } = this.tenantModels; - - const commonBuilder = (builder: any) => { - if (closingDate) { - builder.where('date', '<', closingDate); - } - builder.where('item_id', itemId); - builder.sum('rate as rate'); - builder.sum('quantity as quantity'); - builder.sum('cost as cost'); - builder.first(); - }; - // Calculates the total inventory total quantity and rate `IN` transactions. - const inInvSumationOper: Promise = InventoryCostLotTracker.query() - .onBuild(commonBuilder) - .where('direction', 'IN'); - - // Calculates the total inventory total quantity and rate `OUT` transactions. - const outInvSumationOper: Promise = InventoryCostLotTracker.query() - .onBuild(commonBuilder) - .where('direction', 'OUT'); - - const [inInvSumation, outInvSumation] = await Promise.all([ - inInvSumationOper, - outInvSumationOper, - ]); - return this.computeItemAverageCost( - inInvSumation?.cost || 0, - inInvSumation?.quantity || 0, - outInvSumation?.cost || 0, - outInvSumation?.quantity || 0 - ); - } - - /** - * Computes the item average cost. - * @static - * @param {number} quantityIn - * @param {number} rateIn - * @param {number} quantityOut - * @param {number} rateOut - */ - public computeItemAverageCost( - totalCostIn: number, - totalQuantityIn: number, - - totalCostOut: number, - totalQuantityOut: number - ) { - const openingCost = totalCostIn - totalCostOut; - const openingQuantity = totalQuantityIn - totalQuantityOut; - - const averageCost = openingQuantity ? openingCost / openingQuantity : 0; - - return { averageCost, openingCost, openingQuantity }; - } - - private getCost(rate: number, quantity: number) { - return quantity ? rate * quantity : rate; - } - - /** - * Records the journal entries from specific item inventory transactions. - * @param {IInventoryTransaction[]} invTransactions - * @param {number} openingAverageCost - * @param {string} referenceType - * @param {number} referenceId - * @param {JournalCommand} journalCommands - */ - public trackingCostTransactions( - invTransactions: IInventoryTransaction[], - openingQuantity: number = 0, - openingCost: number = 0 - ) { - const costTransactions: any[] = []; - - // Cumulative item quantity and cost. This will decrement after - // each out transactions depends on its quantity and cost. - let accQuantity: number = openingQuantity; - let accCost: number = openingCost; - - invTransactions.forEach((invTransaction: IInventoryTransaction) => { - const commonEntry = { - invTransId: invTransaction.id, - ...pick(invTransaction, [ - 'date', - 'direction', - 'itemId', - 'quantity', - 'rate', - 'entryId', - 'transactionId', - 'transactionType', - 'createdAt', - 'costAccountId', - 'branchId', - 'warehouseId', - ]), - inventoryTransactionId: invTransaction.id, - }; - switch (invTransaction.direction) { - case 'IN': - const inCost = this.getCost( - invTransaction.rate, - invTransaction.quantity - ); - // Increases the quantity and cost in `IN` inventory transactions. - accQuantity += invTransaction.quantity; - accCost += inCost; - - costTransactions.push({ - ...commonEntry, - cost: inCost, - }); - break; - case 'OUT': - // Average cost = Total cost / Total quantity - const averageCost = accQuantity ? accCost / accQuantity : 0; - - const quantity = - accQuantity > 0 - ? Math.min(invTransaction.quantity, accQuantity) - : invTransaction.quantity; - - // Cost = the transaction quantity * Average cost. - const cost = this.getCost(averageCost, quantity); - - // Revenue = transaction quanity * rate. - // const revenue = quantity * invTransaction.rate; - costTransactions.push({ - ...commonEntry, - quantity, - cost, - }); - accQuantity = Math.max(accQuantity - quantity, 0); - accCost = Math.max(accCost - cost, 0); - - if (invTransaction.quantity > quantity) { - const remainingQuantity = Math.max( - invTransaction.quantity - quantity, - 0 - ); - const remainingIncome = remainingQuantity * invTransaction.rate; - - costTransactions.push({ - ...commonEntry, - quantity: remainingQuantity, - cost: 0, - }); - accQuantity = Math.max(accQuantity - remainingQuantity, 0); - accCost = Math.max(accCost - remainingIncome, 0); - } - break; - } - }); - return costTransactions; - } - - /** - * Reverts the inventory lots `OUT` transactions. - * @param {Date} openingDate - Opening date. - * @param {number} itemId - Item id. - * @returns {Promise} - */ - async revertTheInventoryOutLotTrans(): Promise { - const { InventoryCostLotTracker } = this.tenantModels; - - await InventoryCostLotTracker.query(this.trx) - .modify('filterDateRange', this.startingDate) - .orderBy('date', 'DESC') - .where('item_id', this.itemId) - .delete(); - } -} diff --git a/packages/server/src/services/Inventory/InventoryCostApplication.ts b/packages/server/src/services/Inventory/InventoryCostApplication.ts deleted file mode 100644 index 3fd3b021a..000000000 --- a/packages/server/src/services/Inventory/InventoryCostApplication.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { IInventoryItemCostMeta } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import { InventoryItemCostService } from './InventoryCostsService'; - -@Service() -export class InventoryCostApplication { - @Inject() - inventoryCost: InventoryItemCostService; - - /** - * Retrieves the items inventory valuation list. - * @param {number} tenantId - * @param {number[]} itemsId - * @param {Date} date - * @returns {Promise} - */ - public getItemsInventoryValuationList = async ( - tenantId: number, - itemsId: number[], - date: Date - ): Promise => { - const itemsMap = await this.inventoryCost.getItemsInventoryValuation( - tenantId, - itemsId, - date - ); - return [...itemsMap.values()]; - }; -} diff --git a/packages/server/src/services/Inventory/InventoryCostGLStorage.ts b/packages/server/src/services/Inventory/InventoryCostGLStorage.ts deleted file mode 100644 index 2860b0d66..000000000 --- a/packages/server/src/services/Inventory/InventoryCostGLStorage.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export class InventoryCostGLStorage { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Reverts the inventory cost GL entries from the given starting date. - * @param {number} tenantId - * @param {Date} startingDate - * @param {Knex.Transaction} trx - */ - public revertInventoryCostGLEntries = async ( - tenantId: number, - startingDate: Date, - trx?: Knex.Transaction - ): Promise => { - const { AccountTransaction } = this.tenancy.models(tenantId); - - // Retrieve transactions from specific date range and costable transactions only. - const transactions = await AccountTransaction.query() - .where('costable', true) - .modify('filterDateRange', startingDate) - .withGraphFetched('account'); - - // Transform transaction to ledger entries and reverse them. - const reversedLedger = Ledger.fromTransactions(transactions).reverse(); - - // Deletes and reverts balances of the given ledger. - await this.ledgerStorage.delete(tenantId, reversedLedger, trx); - }; -} diff --git a/packages/server/src/services/Inventory/InventoryCostLotTracker.ts b/packages/server/src/services/Inventory/InventoryCostLotTracker.ts deleted file mode 100644 index aa317674c..000000000 --- a/packages/server/src/services/Inventory/InventoryCostLotTracker.ts +++ /dev/null @@ -1,302 +0,0 @@ -import { pick, chain } from 'lodash'; -import moment from 'moment'; -import { IInventoryLotCost, IInventoryTransaction } from "interfaces"; -import InventoryCostMethod from '@/services/Inventory/InventoryCostMethod'; - -type TCostMethod = 'FIFO' | 'LIFO'; - -export default class InventoryCostLotTracker extends InventoryCostMethod implements IInventoryCostMethod { - startingDate: Date; - itemId: number; - costMethod: TCostMethod; - itemsById: Map; - inventoryINTrans: any; - inventoryByItem: any; - costLotsTransactions: IInventoryLotCost[]; - inTransactions: any[]; - outTransactions: IInventoryTransaction[]; - revertJEntriesTransactions: IInventoryTransaction[]; - - /** - * Constructor method. - * @param {Date} startingDate - - * @param {number} itemId - - * @param {string} costMethod - - */ - constructor( - tenantId: number, - startingDate: Date, - itemId: number, - costMethod: TCostMethod = 'FIFO' - ) { - super(tenantId, startingDate, itemId); - - this.startingDate = startingDate; - this.itemId = itemId; - this.costMethod = costMethod; - - // Collect cost lots transactions to insert them to the storage in bulk. - this.costLotsTransactions= []; - // Collect inventory transactions by item id. - this.inventoryByItem = {}; - // Collection `IN` inventory tranaction by transaction id. - this.inventoryINTrans = {}; - // Collects `IN` transactions. - this.inTransactions = []; - // Collects `OUT` transactions. - this.outTransactions = []; - } - - /** - * Computes items costs from the given date using FIFO or LIFO cost method. - * -------- - * - Revert the inventory lots after the given date. - * - Remove all the journal entries from the inventory transactions - * after the given date. - * - Re-tracking the inventory lots from inventory transactions. - * - Re-write the journal entries from the given inventory transactions. - * @async - * @return {void} - */ - public async computeItemCost(): Promise { - await this.revertInventoryLots(this.startingDate); - await this.fetchInvINTransactions(); - await this.fetchInvOUTTransactions(); - await this.fetchRevertInvJReferenceIds(); - await this.fetchItemsMapped(); - - this.trackingInventoryINLots(this.inTransactions); - this.trackingInventoryOUTLots(this.outTransactions); - - // Re-tracking the inventory `IN` and `OUT` lots costs. - const storedTrackedInvLotsOper = this.storeInventoryLotsCost( - this.costLotsTransactions, - ); - return Promise.all([ - storedTrackedInvLotsOper, - ]); - } - - /** - * Fetched inventory transactions that has date from the starting date and - * fetches available IN LOTs transactions that has remaining bigger than zero. - * @private - */ - private async fetchInvINTransactions() { - const { InventoryTransaction, InventoryLotCostTracker } = this.tenantModels; - - const commonBuilder = (builder: any) => { - builder.orderBy('date', (this.costMethod === 'LIFO') ? 'DESC': 'ASC'); - builder.where('item_id', this.itemId); - }; - const afterInvTransactions: IInventoryTransaction[] = - await InventoryTransaction.query() - .modify('filterDateRange', this.startingDate) - .orderByRaw("FIELD(direction, 'IN', 'OUT')") - .onBuild(commonBuilder) - .orderBy('lot_number', (this.costMethod === 'LIFO') ? 'DESC' : 'ASC') - .withGraphFetched('item'); - - const availableINLots: IInventoryLotCost[] = - await InventoryLotCostTracker.query() - .modify('filterDateRange', null, this.startingDate) - .orderBy('date', 'ASC') - .where('direction', 'IN') - .orderBy('lot_number', 'ASC') - .onBuild(commonBuilder) - .whereNot('remaining', 0); - - this.inTransactions = [ - ...availableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })), - ...afterInvTransactions.map((trans) => ({ invTransId: trans.id, ...trans })), - ]; - } - - /** - * Fetches inventory OUT transactions that has date from the starting date. - * @private - */ - private async fetchInvOUTTransactions() { - const { InventoryTransaction } = this.tenantModels; - - const afterOUTTransactions: IInventoryTransaction[] = - await InventoryTransaction.query() - .modify('filterDateRange', this.startingDate) - .orderBy('date', 'ASC') - .orderBy('lot_number', 'ASC') - .where('item_id', this.itemId) - .where('direction', 'OUT') - .withGraphFetched('item'); - - this.outTransactions = [ ...afterOUTTransactions ]; - } - - private async fetchItemsMapped() { - const itemsIds = chain(this.inTransactions).map((e) => e.itemId).uniq().value(); - const { Item } = this.tenantModels; - const storedItems = await Item.query() - .where('type', 'inventory') - .whereIn('id', itemsIds); - - this.itemsById = new Map(storedItems.map((item: any) => [item.id, item])); - } - - /** - * Fetch the inventory transactions that should revert its journal entries. - * @private - */ - private async fetchRevertInvJReferenceIds() { - const { InventoryTransaction } = this.tenantModels; - const revertJEntriesTransactions: IInventoryTransaction[] = - await InventoryTransaction.query() - .select(['transactionId', 'transactionType']) - .modify('filterDateRange', this.startingDate) - .where('direction', 'OUT') - .where('item_id', this.itemId); - - this.revertJEntriesTransactions = revertJEntriesTransactions; - } - - /** - * Revert the inventory lots to the given date by removing the inventory lots - * transactions after the given date and increment the remaining that - * associate to lot number. - * @async - * @return {Promise} - */ - public async revertInventoryLots(startingDate: Date) { - const { InventoryLotCostTracker } = this.tenantModels; - const asyncOpers: any[] = []; - const inventoryLotsTrans = await InventoryLotCostTracker.query() - .modify('filterDateRange', this.startingDate) - .orderBy('date', 'DESC') - .where('item_id', this.itemId) - .where('direction', 'OUT'); - - const deleteInvLotsTrans = InventoryLotCostTracker.query() - .modify('filterDateRange', this.startingDate) - .where('item_id', this.itemId) - .delete(); - - inventoryLotsTrans.forEach((inventoryLot: IInventoryLotCost) => { - if (!inventoryLot.lotNumber) { return; } - - const incrementOper = InventoryLotCostTracker.query() - .where('lot_number', inventoryLot.lotNumber) - .where('direction', 'IN') - .increment('remaining', inventoryLot.quantity); - - asyncOpers.push(incrementOper); - }); - return Promise.all([deleteInvLotsTrans, ...asyncOpers]); - } - - /** - * Tracking inventory `IN` lots transactions. - * @public - * @param {IInventoryTransaction[]} inventoryTransactions - - * @return {void} - */ - public trackingInventoryINLots( - inventoryTransactions: IInventoryTransaction[], - ) { - inventoryTransactions.forEach((transaction: IInventoryTransaction) => { - const { itemId, id } = transaction; - (this.inventoryByItem[itemId] || (this.inventoryByItem[itemId] = [])); - - const commonLotTransaction: IInventoryLotCost = { - ...pick(transaction, [ - 'date', 'rate', 'itemId', 'quantity', 'invTransId', 'lotTransId', - 'direction', 'transactionType', 'transactionId', 'lotNumber', 'remaining' - ]), - }; - this.inventoryByItem[itemId].push(id); - this.inventoryINTrans[id] = { - ...commonLotTransaction, - decrement: 0, - remaining: commonLotTransaction.remaining || commonLotTransaction.quantity, - }; - this.costLotsTransactions.push(this.inventoryINTrans[id]); - }); - } - - /** - * Tracking inventory `OUT` lots transactions. - * @public - * @param {IInventoryTransaction[]} inventoryTransactions - - * @return {void} - */ - public trackingInventoryOUTLots( - inventoryTransactions: IInventoryTransaction[], - ) { - inventoryTransactions.forEach((transaction: IInventoryTransaction) => { - const { itemId, id } = transaction; - (this.inventoryByItem[itemId] || (this.inventoryByItem[itemId] = [])); - - const commonLotTransaction: IInventoryLotCost = { - ...pick(transaction, [ - 'date', 'rate', 'itemId', 'quantity', 'invTransId', 'lotTransId', 'entryId', - 'direction', 'transactionType', 'transactionId', 'lotNumber', 'remaining' - ]), - }; - let invRemaining = transaction.quantity; - const idsShouldDel: number[] = []; - - this.inventoryByItem?.[itemId]?.some((_invTransactionId: number) => { - const _invINTransaction = this.inventoryINTrans[_invTransactionId]; - - // Can't continue if the IN transaction remaining equals zero. - if (invRemaining <= 0) { return true; } - - // Can't continue if the IN transaction date is after the current transaction date. - if (moment(_invINTransaction.date).isAfter(transaction.date)) { - return true; - } - // Detarmines the 'OUT' lot tranasctions whether bigger than 'IN' remaining transaction. - const biggerThanRemaining = (_invINTransaction.remaining - transaction.quantity) > 0; - const decrement = (biggerThanRemaining) ? transaction.quantity : _invINTransaction.remaining; - const maxDecrement = Math.min(decrement, invRemaining); - const cost = maxDecrement * _invINTransaction.rate; - - _invINTransaction.decrement += maxDecrement; - _invINTransaction.remaining = Math.max( - _invINTransaction.remaining - maxDecrement, - 0, - ); - invRemaining = Math.max(invRemaining - maxDecrement, 0); - - this.costLotsTransactions.push({ - ...commonLotTransaction, - cost, - quantity: maxDecrement, - lotNumber: _invINTransaction.lotNumber, - }); - // Pop the 'IN' lots that has zero remaining. - if (_invINTransaction.remaining === 0) { - idsShouldDel.push(_invTransactionId); - } - return false; - }); - if (invRemaining > 0) { - this.costLotsTransactions.push({ - ...commonLotTransaction, - quantity: invRemaining, - }); - } - this.removeInventoryItems(itemId, idsShouldDel); - }); - } - - /** - * Remove inventory transactions for specific item id. - * @private - * @param {number} itemId - * @param {number[]} idsShouldDel - * @return {void} - */ - private removeInventoryItems(itemId: number, idsShouldDel: number[]) { - // Remove the IN transactions that has zero remaining amount. - this.inventoryByItem[itemId] = this.inventoryByItem?.[itemId] - ?.filter((transId: number) => idsShouldDel.indexOf(transId) === -1); - } -} \ No newline at end of file diff --git a/packages/server/src/services/Inventory/InventoryCostMethod.ts b/packages/server/src/services/Inventory/InventoryCostMethod.ts deleted file mode 100644 index b90711db7..000000000 --- a/packages/server/src/services/Inventory/InventoryCostMethod.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { omit } from 'lodash'; -import { Container } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { IInventoryLotCost } from '@/interfaces'; - -export default class InventoryCostMethod { - tenancy: TenancyService; - tenantModels: any; - - /** - * Constructor method. - * @param {number} tenantId - The given tenant id. - */ - constructor(tenantId: number, startingDate: Date, itemId: number) { - const tenancyService = Container.get(TenancyService); - - this.tenantModels = tenancyService.models(tenantId); - } - - /** - * Stores the inventory lots costs transactions in bulk. - * @param {IInventoryLotCost[]} costLotsTransactions - * @return {Promise[]} - */ - public storeInventoryLotsCost( - costLotsTransactions: IInventoryLotCost[] - ): Promise { - const { InventoryCostLotTracker } = this.tenantModels; - const opers: any = []; - - costLotsTransactions.forEach((transaction: any) => { - if (transaction.lotTransId && transaction.decrement) { - const decrementOper = InventoryCostLotTracker.query(this.trx) - .where('id', transaction.lotTransId) - .decrement('remaining', transaction.decrement); - opers.push(decrementOper); - } else if (!transaction.lotTransId) { - const operation = InventoryCostLotTracker.query(this.trx).insert({ - ...omit(transaction, ['decrement', 'invTransId', 'lotTransId']), - }); - opers.push(operation); - } - }); - return Promise.all(opers); - } -} diff --git a/packages/server/src/services/Inventory/InventoryCostsService.ts b/packages/server/src/services/Inventory/InventoryCostsService.ts deleted file mode 100644 index 7008e802f..000000000 --- a/packages/server/src/services/Inventory/InventoryCostsService.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { keyBy, get } from 'lodash'; -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { IInventoryItemCostMeta } from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import ItemWarehouseQuantity from 'models/ItemWarehouseQuantity'; -import { ModelUpdateOptions } from 'mongoose'; - -@Service() -export class InventoryItemCostService { - @Inject() - tenancy: TenancyService; - - /** - * Common query of items inventory valuation. - * @param {number[]} itemsIds - - * @param {Date} date - - * @param {Knex.QueryBuilder} builder - - */ - private itemsInventoryValuationCommonQuery = R.curry( - (itemsIds: number[], date: Date, builder: Knex.QueryBuilder) => { - if (date) { - builder.where('date', '<', date); - } - builder.whereIn('item_id', itemsIds); - builder.sum('rate as rate'); - builder.sum('quantity as quantity'); - builder.sum('cost as cost'); - - builder.groupBy('item_id'); - builder.select(['item_id']); - } - ); - - /** - * - * @param {} INValuationMap - - * @param {} OUTValuationMap - - * @param {number} itemId - */ - private getItemInventoryMeta = R.curry( - ( - INValuationMap, - OUTValuationMap, - itemId: number - ): IInventoryItemCostMeta => { - const INCost = get(INValuationMap, `[${itemId}].cost`, 0); - const INQuantity = get(INValuationMap, `[${itemId}].quantity`, 0); - - const OUTCost = get(OUTValuationMap, `[${itemId}].cost`, 0); - const OUTQuantity = get(OUTValuationMap, `[${itemId}].quantity`, 0); - - const valuation = INCost - OUTCost; - const quantity = INQuantity - OUTQuantity; - const average = quantity ? valuation / quantity : 0; - - return { itemId, valuation, quantity, average }; - } - ); - - /** - * - * @param {number} tenantId - * @param {number} itemsId - * @param {Date} date - * @returns - */ - private getItemsInventoryINAndOutAggregated = ( - tenantId: number, - itemsId: number[], - date: Date - ): Promise => { - const { InventoryCostLotTracker } = this.tenancy.models(tenantId); - - const commonBuilder = this.itemsInventoryValuationCommonQuery( - itemsId, - date - ); - const INValuationOper = InventoryCostLotTracker.query() - .onBuild(commonBuilder) - .where('direction', 'IN'); - - const OUTValuationOper = InventoryCostLotTracker.query() - .onBuild(commonBuilder) - .where('direction', 'OUT'); - - return Promise.all([OUTValuationOper, INValuationOper]); - }; - - /** - * - * @param {number} tenantId - - * @param {number[]} itemsIds - - * @param {Date} date - - */ - private getItemsInventoryInOutMap = async ( - tenantId: number, - itemsId: number[], - date: Date - ) => { - const [OUTValuation, INValuation] = - await this.getItemsInventoryINAndOutAggregated(tenantId, itemsId, date); - - const OUTValuationMap = keyBy(OUTValuation, 'itemId'); - const INValuationMap = keyBy(INValuation, 'itemId'); - - return [OUTValuationMap, INValuationMap]; - }; - - /** - * - * @param {number} tenantId - * @param {number} itemId - * @param {Date} date - * @returns {Promise>} - */ - public getItemsInventoryValuation = async ( - tenantId: number, - itemsId: number[], - date: Date - ): Promise> => { - const { Item } = this.tenancy.models(tenantId); - - // Retrieves the inventory items. - const items = await Item.query() - .whereIn('id', itemsId) - .where('type', 'inventory'); - - // Retrieves the inventory items ids. - const inventoryItemsIds: number[] = items.map((item) => item.id); - - // Retreives the items inventory IN/OUT map. - const [OUTValuationMap, INValuationMap] = - await this.getItemsInventoryInOutMap(tenantId, itemsId, date); - - const getItemValuation = this.getItemInventoryMeta( - INValuationMap, - OUTValuationMap - ); - const itemsValuations = inventoryItemsIds.map(getItemValuation); - const itemsValuationsMap = new Map( - itemsValuations.map((i) => [i.itemId, i]) - ); - return itemsValuationsMap; - }; -} diff --git a/packages/server/src/services/Inventory/InventoryItemsQuantitySync.ts b/packages/server/src/services/Inventory/InventoryItemsQuantitySync.ts deleted file mode 100644 index 9d7e832be..000000000 --- a/packages/server/src/services/Inventory/InventoryItemsQuantitySync.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { toSafeInteger } from 'lodash'; -import { IInventoryTransaction, IItemsQuantityChanges } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Knex from 'knex'; - -/** - * Syncs the inventory transactions with inventory items quantity. - */ -@Service() -export default class InventoryItemsQuantitySync { - @Inject() - tenancy: HasTenancyService; - - /** - * Reverse the given inventory transactions. - * @param {IInventoryTransaction[]} inventroyTransactions - * @return {IInventoryTransaction[]} - */ - reverseInventoryTransactions( - inventroyTransactions: IInventoryTransaction[] - ): IInventoryTransaction[] { - return inventroyTransactions.map((transaction) => ({ - ...transaction, - direction: transaction.direction === 'OUT' ? 'IN' : 'OUT', - })); - } - - /** - * Reverses the inventory transactions. - * @param {IInventoryTransaction[]} inventroyTransactions - - * @return {IItemsQuantityChanges[]} - */ - getReverseItemsQuantityChanges( - inventroyTransactions: IInventoryTransaction[] - ): IItemsQuantityChanges[] { - const reversedTransactions = this.reverseInventoryTransactions( - inventroyTransactions - ); - return this.getItemsQuantityChanges(reversedTransactions); - } - - /** - * Retrieve the items quantity changes from the given inventory transactions. - * @param {IInventoryTransaction[]} inventroyTransactions - Inventory transactions. - * @return {IItemsQuantityChanges[]} - */ - getItemsQuantityChanges( - inventroyTransactions: IInventoryTransaction[] - ): IItemsQuantityChanges[] { - const balanceMap: { [itemId: number]: number } = {}; - - inventroyTransactions.forEach( - (inventoryTransaction: IInventoryTransaction) => { - const { itemId, direction, quantity } = inventoryTransaction; - - if (!balanceMap[itemId]) { - balanceMap[itemId] = 0; - } - balanceMap[itemId] += direction === 'IN' ? quantity : 0; - balanceMap[itemId] -= direction === 'OUT' ? quantity : 0; - } - ); - - return Object.entries(balanceMap).map(([itemId, balanceChange]) => ({ - itemId: toSafeInteger(itemId), - balanceChange, - })); - } - - /** - * Changes the items quantity changes. - * @param {IItemsQuantityChanges[]} itemsQuantity - Items quantity changes. - * @return {Promise} - */ - async changeItemsQuantity( - tenantId: number, - itemsQuantity: IItemsQuantityChanges[], - trx?: Knex.Transaction - ): Promise { - const { itemRepository } = this.tenancy.repositories(tenantId); - const opers = []; - - itemsQuantity.forEach((itemQuantity: IItemsQuantityChanges) => { - const changeQuantityOper = itemRepository.changeNumber( - { id: itemQuantity.itemId, type: 'inventory' }, - 'quantityOnHand', - itemQuantity.balanceChange, - trx - ); - opers.push(changeQuantityOper); - }); - await Promise.all(opers); - } -} diff --git a/packages/server/src/services/Inventory/subscribers/InventoryCostGLBeforeWriteSubscriber.ts b/packages/server/src/services/Inventory/subscribers/InventoryCostGLBeforeWriteSubscriber.ts deleted file mode 100644 index 4ae087238..000000000 --- a/packages/server/src/services/Inventory/subscribers/InventoryCostGLBeforeWriteSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IInventoryCostLotsGLEntriesWriteEvent } from '@/interfaces'; -import { InventoryCostGLStorage } from '../InventoryCostGLStorage'; - -@Service() -export class InventoryCostGLBeforeWriteSubscriber { - @Inject() - private inventoryCostGLStorage: InventoryCostGLStorage; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe( - events.inventory.onCostLotsGLEntriesBeforeWrite, - this.revertsInventoryCostGLEntries - ); - } - - /** - * Writes the receipts cost GL entries once the inventory cost lots be written. - * @param {IInventoryCostLotsGLEntriesWriteEvent} - */ - private revertsInventoryCostGLEntries = async ({ - trx, - startingDate, - tenantId, - }: IInventoryCostLotsGLEntriesWriteEvent) => { - await this.inventoryCostGLStorage.revertInventoryCostGLEntries( - tenantId, - startingDate, - trx - ); - }; -} diff --git a/packages/server/src/services/Inventory/utils.ts b/packages/server/src/services/Inventory/utils.ts deleted file mode 100644 index f961694b1..000000000 --- a/packages/server/src/services/Inventory/utils.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { chain } from 'lodash'; - -/** - * Grpups by transaction type and id the inventory transactions. - * @param {IInventoryTransaction} invTransactions - * @returns - */ -export function groupInventoryTransactionsByTypeId( - transactions: { transactionType: string; transactionId: number }[] -): { transactionType: string; transactionId: number }[][] { - return chain(transactions) - .groupBy((t) => `${t.transactionType}-${t.transactionId}`) - .values() - .value(); -} diff --git a/packages/server/src/services/InviteUsers/AcceptInviteUser.ts b/packages/server/src/services/InviteUsers/AcceptInviteUser.ts deleted file mode 100644 index 40b83e521..000000000 --- a/packages/server/src/services/InviteUsers/AcceptInviteUser.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { ServiceError } from '@/exceptions'; -import { Invite, SystemUser, Tenant } from '@/system/models'; -import { hashPassword } from 'utils'; -import events from '@/subscribers/events'; -import { - IAcceptInviteEventPayload, - IInviteUserInput, - ICheckInviteEventPayload, - IUserInvite, -} from '@/interfaces'; -import { ERRORS } from './constants'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { IAcceptInviteUserService } from '@/interfaces'; - -@Service() -export default class AcceptInviteUserService - implements IAcceptInviteUserService -{ - @Inject() - private eventPublisher: EventPublisher; - - /** - * Accept the received invite. - * @param {string} token - * @param {IInviteUserInput} inviteUserInput - * @throws {ServiceErrors} - * @returns {Promise} - */ - public async acceptInvite( - token: string, - inviteUserDTO: IInviteUserInput - ): Promise { - // Retrieve the invite token or throw not found error. - const inviteToken = await this.getInviteTokenOrThrowError(token); - - // Hash the given password. - const hashedPassword = await hashPassword(inviteUserDTO.password); - - // Retrieve the system user. - const user = await SystemUser.query().findOne('email', inviteToken.email); - - // Sets the invited user details after invite accepting. - const systemUser = await SystemUser.query().updateAndFetchById( - inviteToken.userId, - { - ...inviteUserDTO, - inviteAcceptedAt: moment().format('YYYY-MM-DD'), - password: hashedPassword, - } - ); - // Clear invite token by the given user id. - await this.clearInviteTokensByUserId(inviteToken.userId); - - // Triggers `onUserAcceptInvite` event. - await this.eventPublisher.emitAsync(events.inviteUser.acceptInvite, { - inviteToken, - user: systemUser, - inviteUserDTO, - } as IAcceptInviteEventPayload); - } - - /** - * Validate the given invite token. - * @param {string} token - the given token string. - * @throws {ServiceError} - */ - public async checkInvite( - token: string - ): Promise<{ inviteToken: IUserInvite; orgName: object }> { - const inviteToken = await this.getInviteTokenOrThrowError(token); - - // Find the tenant that associated to the given token. - const tenant = await Tenant.query() - .findById(inviteToken.tenantId) - .withGraphFetched('metadata'); - - // Triggers `onUserCheckInvite` event. - await this.eventPublisher.emitAsync(events.inviteUser.checkInvite, { - inviteToken, - tenant, - } as ICheckInviteEventPayload); - - return { inviteToken, orgName: tenant.metadata.name }; - } - - /** - * Retrieve invite model from the given token or throw error. - * @param {string} token - Then given token string. - * @throws {ServiceError} - * @returns {Invite} - */ - private getInviteTokenOrThrowError = async ( - token: string - ): Promise => { - const inviteToken = await Invite.query() - .modify('notExpired') - .findOne('token', token); - - if (!inviteToken) { - throw new ServiceError(ERRORS.INVITE_TOKEN_INVALID); - } - return inviteToken; - }; - - /** - * Validate the given user email and phone number uniquine. - * @param {IInviteUserInput} inviteUserInput - */ - private validateUserPhoneNumberNotExists = async ( - phoneNumber: string - ): Promise => { - const foundUser = await SystemUser.query().findOne({ phoneNumber }); - - if (foundUser) { - throw new ServiceError(ERRORS.PHONE_NUMBER_EXISTS); - } - }; - - /** - * Clear invite tokens of the given user id. - * @param {number} userId - User id. - */ - private clearInviteTokensByUserId = async (userId: number) => { - await Invite.query().where('user_id', userId).delete(); - }; -} diff --git a/packages/server/src/services/InviteUsers/InviteSendMailNotificationSubscribe.ts b/packages/server/src/services/InviteUsers/InviteSendMailNotificationSubscribe.ts deleted file mode 100644 index 24966f3bb..000000000 --- a/packages/server/src/services/InviteUsers/InviteSendMailNotificationSubscribe.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { IUserInviteTenantSyncedEventPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; - -@Service() -export default class InviteSendMainNotificationSubscribe { - @Inject('agenda') - private agenda: any; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.inviteUser.sendInviteTenantSynced, - this.sendMailNotification - ); - } - - /** - * Sends mail notification. - * @param {IUserInvitedEventPayload} payload - */ - private sendMailNotification = ( - payload: IUserInviteTenantSyncedEventPayload - ) => { - const { invite, authorizedUser, tenantId } = payload; - - this.agenda.now('user-invite-mail', { - invite, - authorizedUser, - tenantId, - }); - }; -} diff --git a/packages/server/src/services/InviteUsers/SendInviteUsersMailMessage.ts b/packages/server/src/services/InviteUsers/SendInviteUsersMailMessage.ts deleted file mode 100644 index 9e6e89dd6..000000000 --- a/packages/server/src/services/InviteUsers/SendInviteUsersMailMessage.ts +++ /dev/null @@ -1,46 +0,0 @@ -import path from 'path'; -import { ISystemUser } from '@/interfaces'; -import Mail from '@/lib/Mail'; -import { Service } from 'typedi'; -import { Tenant } from '@/system/models'; -import config from '@/config'; - -@Service() -export default class SendInviteUsersMailMessage { - /** - * Sends invite mail to the given email. - * @param user - * @param invite - */ - async sendInviteMail(tenantId: number, fromUser: ISystemUser, invite: any) { - // Retreive tenant orgnaization name. - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - const root = path.join(global.__views_dir, '/images/bigcapital.png'); - - const mail = new Mail() - .setSubject(`${fromUser.firstName} has invited you to join a Bigcapital`) - .setView('mail/UserInvite.html') - .setTo(invite.email) - .setAttachments([ - { - filename: 'bigcapital.png', - path: root, - cid: 'bigcapital_logo', - }, - ]) - .setData({ - root, - acceptUrl: `${config.baseURL}/auth/invite/${invite.token}/accept`, - fullName: `${fromUser.firstName} ${fromUser.lastName}`, - firstName: fromUser.firstName, - lastName: fromUser.lastName, - email: fromUser.email, - organizationName: tenant.metadata.name, - }); - - await mail.send(); - } -} diff --git a/packages/server/src/services/InviteUsers/SyncSystemSendInvite.ts b/packages/server/src/services/InviteUsers/SyncSystemSendInvite.ts deleted file mode 100644 index fd29b6738..000000000 --- a/packages/server/src/services/InviteUsers/SyncSystemSendInvite.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IUserInvitedEventPayload, - IUserInviteResendEventPayload, - IUserInviteTenantSyncedEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { Invite, SystemUser } from '@/system/models'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export default class SyncSystemSendInvite { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe(events.inviteUser.sendInvite, this.syncSendInviteSystem); - bus.subscribe( - events.inviteUser.resendInvite, - this.syncResendInviteSystemUser - ); - } - - /** - * Syncs send invite to system user. - * @param {IUserInvitedEventPayload} payload - - */ - private syncSendInviteSystem = async ({ - inviteToken, - user, - tenantId, - authorizedUser, - }: IUserInvitedEventPayload) => { - const { User } = this.tenancy.models(tenantId); - - // Creates a new system user. - const systemUser = await SystemUser.query().insert({ - email: user.email, - active: user.active, - tenantId, - - // Email should be verified since the user got the invite token through email. - verified: true, - }); - // Creates a invite user token. - const invite = await Invite.query().insert({ - email: user.email, - tenantId, - userId: systemUser.id, - token: inviteToken, - }); - // Links the tenant user with created system user. - await User.query().findById(user.id).patch({ - systemUserId: systemUser.id, - }); - // Triggers `onUserSendInviteTenantSynced` event. - await this.eventPublisher.emitAsync( - events.inviteUser.sendInviteTenantSynced, - { - invite, - tenantId, - user, - authorizedUser, - } as IUserInviteTenantSyncedEventPayload - ); - }; - - /** - * Syncs resend invite to system user. - * @param {IUserInviteResendEventPayload} payload - - */ - private syncResendInviteSystemUser = async ({ - inviteToken, - authorizedUser, - tenantId, - user, - }: IUserInviteResendEventPayload) => { - // Clear all invite tokens of the given user id. - await this.clearInviteTokensByUserId(user.systemUserId, tenantId); - - const invite = await Invite.query().insert({ - email: user.email, - tenantId, - userId: user.systemUserId, - token: inviteToken, - }); - }; - - /** - * Clear invite tokens of the given user id. - * @param {number} userId - User id. - */ - private clearInviteTokensByUserId = async ( - userId: number, - tenantId: number - ) => { - await Invite.query() - .where({ - userId, - tenantId, - }) - .delete(); - }; -} diff --git a/packages/server/src/services/InviteUsers/SyncTenantAcceptInvite.ts b/packages/server/src/services/InviteUsers/SyncTenantAcceptInvite.ts deleted file mode 100644 index a1b1e7239..000000000 --- a/packages/server/src/services/InviteUsers/SyncTenantAcceptInvite.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit } from 'lodash'; -import moment from 'moment'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { IAcceptInviteEventPayload } from '@/interfaces'; - -@Service() -export default class SyncTenantAcceptInvite { - @Inject() - private tenancy: HasTenancyService; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe(events.inviteUser.acceptInvite, this.syncTenantAcceptInvite); - } - - /** - * Syncs accept invite to tenant user. - * @param {IAcceptInviteEventPayload} payload - - */ - private syncTenantAcceptInvite = async ({ - inviteToken, - user, - inviteUserDTO, - }: IAcceptInviteEventPayload) => { - const { User } = this.tenancy.models(inviteToken.tenantId); - - await User.query() - .where('systemUserId', inviteToken.userId) - .update({ - ...omit(inviteUserDTO, ['password']), - inviteAcceptedAt: moment().format('YYYY-MM-DD'), - }); - }; -} diff --git a/packages/server/src/services/InviteUsers/TenantInviteUser.ts b/packages/server/src/services/InviteUsers/TenantInviteUser.ts deleted file mode 100644 index fffa0d632..000000000 --- a/packages/server/src/services/InviteUsers/TenantInviteUser.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { Service, Inject } from 'typedi'; -import uniqid from 'uniqid'; -import moment from 'moment'; -import { ServiceError } from '@/exceptions'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { - ISystemUser, - IUserSendInviteDTO, - IInviteUserService, - ITenantUser, - IUserInvitedEventPayload, - IUserInviteResendEventPayload, -} from '@/interfaces'; -import { ERRORS } from './constants'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import RolesService from '@/services/Roles/RolesService'; - -@Service() -export default class InviteTenantUserService implements IInviteUserService { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: TenancyService; - - @Inject() - private rolesService: RolesService; - - /** - * Sends invite mail to the given email from the given tenant and user. - * @param {number} tenantId - - * @param {string} email - - * @param {IUser} authorizedUser - - * @return {Promise} - */ - public async sendInvite( - tenantId: number, - sendInviteDTO: IUserSendInviteDTO, - authorizedUser: ISystemUser - ): Promise<{ - invitedUser: ITenantUser; - }> { - const { User } = this.tenancy.models(tenantId); - - // Get the given role or throw not found service error. - const role = await this.rolesService.getRoleOrThrowError( - tenantId, - sendInviteDTO.roleId - ); - // Validates the given email not exists on the storage. - await this.validateUserEmailNotExists(tenantId, sendInviteDTO.email); - - // Generates a new invite token. - const inviteToken = uniqid(); - - // Creates and fetches a tenant user. - const user = await User.query().insertAndFetch({ - email: sendInviteDTO.email, - roleId: sendInviteDTO.roleId, - active: true, - invitedAt: new Date(), - }); - // Triggers `onUserSendInvite` event. - await this.eventPublisher.emitAsync(events.inviteUser.sendInvite, { - inviteToken, - authorizedUser, - tenantId, - user, - } as IUserInvitedEventPayload); - - return { invitedUser: user }; - } - - /** - * Re-send user invite. - * @param {number} tenantId - - * @param {string} email - - * @return {Promise<{ invite: IUserInvite }>} - */ - public async resendInvite( - tenantId: number, - userId: number, - authorizedUser: ISystemUser - ): Promise<{ user: ITenantUser }> { - // Retrieve the user by id or throw not found service error. - const user = await this.getUserByIdOrThrowError(tenantId, userId); - - // Validate the user is not invited recently. - this.validateUserInviteThrottle(user); - - // Validate the given user is not accepted yet. - this.validateInviteUserNotAccept(user); - - // Generates a new invite token. - const inviteToken = uniqid(); - - // Triggers `onUserSendInvite` event. - await this.eventPublisher.emitAsync(events.inviteUser.resendInvite, { - authorizedUser, - tenantId, - user, - inviteToken, - } as IUserInviteResendEventPayload); - - return { user }; - } - - /** - * Validate the given user has no active invite token. - * @param {number} tenantId - * @param {number} userId - User id. - */ - private validateInviteUserNotAccept = (user: ITenantUser) => { - // Throw the error if the one invite tokens is still active. - if (user.inviteAcceptedAt) { - throw new ServiceError(ERRORS.USER_RECENTLY_INVITED); - } - }; - - /** - * Validates user invite is not invited recently before specific time point. - * @param {ITenantUser} user - */ - private validateUserInviteThrottle = (user: ITenantUser) => { - const PARSE_FORMAT = 'M/D/YYYY, H:mm:ss A'; - const beforeTime = moment().subtract(5, 'minutes'); - - if (moment(user.invitedAt, PARSE_FORMAT).isAfter(beforeTime)) { - throw new ServiceError(ERRORS.USER_RECENTLY_INVITED); - } - }; - - /** - * Retrieve the given user by id or throw not found service error. - * @param {number} userId - User id. - */ - private getUserByIdOrThrowError = async ( - tenantId: number, - userId: number - ): Promise => { - const { User } = this.tenancy.models(tenantId); - - // Retrieve the tenant user. - const user = await User.query().findById(userId); - - // Throw if the user not found. - if (!user) { - throw new ServiceError(ERRORS.USER_NOT_FOUND); - } - return user; - }; - - /** - * Throws error in case the given user email not exists on the storage. - * @param {string} email - * @throws {ServiceError} - */ - private async validateUserEmailNotExists( - tenantId: number, - email: string - ): Promise { - const { User } = this.tenancy.models(tenantId); - const foundUser = await User.query().findOne('email', email); - - if (foundUser) { - throw new ServiceError(ERRORS.EMAIL_EXISTS); - } - } -} diff --git a/packages/server/src/services/InviteUsers/constants.ts b/packages/server/src/services/InviteUsers/constants.ts deleted file mode 100644 index 1e0516917..000000000 --- a/packages/server/src/services/InviteUsers/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ - - -export const ERRORS = { - EMAIL_ALREADY_INVITED: 'EMAIL_ALREADY_INVITED', - INVITE_TOKEN_INVALID: 'INVITE_TOKEN_INVALID', - PHONE_NUMBER_EXISTS: 'PHONE_NUMBER_EXISTS', - USER_NOT_FOUND: 'USER_NOT_FOUND', - EMAIL_EXISTS: 'EMAIL_EXISTS', - EMAIL_NOT_EXISTS: 'EMAIL_NOT_EXISTS', - USER_RECENTLY_INVITED: 'USER_RECENTLY_INVITED', -}; \ No newline at end of file diff --git a/packages/server/src/services/ItemCategories/ItemCategoriesExportable.ts b/packages/server/src/services/ItemCategories/ItemCategoriesExportable.ts deleted file mode 100644 index 0cc8142ce..000000000 --- a/packages/server/src/services/ItemCategories/ItemCategoriesExportable.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Exportable } from '../Export/Exportable'; -import { IAccountsFilter, IAccountsStructureType } from '@/interfaces'; -import ItemCategoriesService from './ItemCategoriesService'; - -@Service() -export class ItemCategoriesExportable extends Exportable { - @Inject() - private itemCategoriesApplication: ItemCategoriesService; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IAccountsFilter) { - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - inactiveMode: false, - ...query, - structure: IAccountsStructureType.Flat, - } as IAccountsFilter; - - return this.itemCategoriesApplication - .getItemCategoriesList(tenantId, parsedQuery, {}) - .then((output) => output.itemCategories); - } -} diff --git a/packages/server/src/services/ItemCategories/ItemCategoriesImportable.ts b/packages/server/src/services/ItemCategories/ItemCategoriesImportable.ts deleted file mode 100644 index 458a64a8a..000000000 --- a/packages/server/src/services/ItemCategories/ItemCategoriesImportable.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Inject, Service } from 'typedi'; -import ItemCategoriesService from './ItemCategoriesService'; -import { Importable } from '../Import/Importable'; -import { Knex } from 'knex'; -import { IItemCategoryOTD } from '@/interfaces'; -import { ItemCategoriesSampleData } from './constants'; - -@Service() -export class ItemCategoriesImportable extends Importable { - @Inject() - private itemCategoriesService: ItemCategoriesService; - - /** - * Importing to create new item category service. - * @param {number} tenantId - * @param {any} createDTO - * @param {Knex.Transaction} trx - */ - public async importable( - tenantId: number, - createDTO: IItemCategoryOTD, - trx?: Knex.Transaction - ) { - await this.itemCategoriesService.newItemCategory( - tenantId, - createDTO, - {}, - trx - ); - } - - /** - * Item categories sample data used to download sample sheet file. - */ - public sampleData(): any[] { - return ItemCategoriesSampleData; - } -} diff --git a/packages/server/src/services/ItemCategories/ItemCategoriesService.ts b/packages/server/src/services/ItemCategories/ItemCategoriesService.ts deleted file mode 100644 index 26c7d4256..000000000 --- a/packages/server/src/services/ItemCategories/ItemCategoriesService.ts +++ /dev/null @@ -1,383 +0,0 @@ -import { Inject } from 'typedi'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { ServiceError } from '@/exceptions'; -import { - IItemCategory, - IItemCategoryOTD, - IItemCategoriesService, - IItemCategoriesFilter, - ISystemUser, - IFilterMeta, - IItemCategoryCreatedPayload, - IItemCategoryEditedPayload, - IItemCategoryDeletedPayload, -} from '@/interfaces'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { ACCOUNT_ROOT_TYPE, ACCOUNT_TYPE } from '@/data/AccountTypes'; -import { ERRORS } from './constants'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -export default class ItemCategoriesService implements IItemCategoriesService { - @Inject() - tenancy: TenancyService; - - @Inject() - dynamicListService: DynamicListingService; - - @Inject('logger') - logger: any; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - uow: UnitOfWork; - - /** - * Retrieve item category or throw not found error. - * @param {number} tenantId - * @param {number} itemCategoryId - */ - private async getItemCategoryOrThrowError( - tenantId: number, - itemCategoryId: number - ) { - const { ItemCategory } = this.tenancy.models(tenantId); - const category = await ItemCategory.query().findById(itemCategoryId); - - if (!category) { - throw new ServiceError(ERRORS.CATEGORY_NOT_FOUND); - } - return category; - } - - /** - * Transforms OTD to model object. - * @param {IItemCategoryOTD} itemCategoryOTD - * @param {ISystemUser} authorizedUser - */ - private transformOTDToObject( - itemCategoryOTD: IItemCategoryOTD, - authorizedUser: ISystemUser - ) { - return { ...itemCategoryOTD, userId: authorizedUser.id }; - } - - /** - * Retrieve item category of the given id. - * @param {number} tenantId - - * @param {number} itemCategoryId - - * @returns {IItemCategory} - */ - public async getItemCategory( - tenantId: number, - itemCategoryId: number, - user: ISystemUser - ) { - return this.getItemCategoryOrThrowError(tenantId, itemCategoryId); - } - - /** - * Validates the category name uniquiness. - * @param {number} tenantId - Tenant id. - * @param {string} categoryName - Category name. - * @param {number} notAccountId - Ignore the account id. - */ - private async validateCategoryNameUniquiness( - tenantId: number, - categoryName: string, - notCategoryId?: number - ) { - const { ItemCategory } = this.tenancy.models(tenantId); - - const foundItemCategory = await ItemCategory.query() - .findOne('name', categoryName) - .onBuild((query) => { - if (notCategoryId) { - query.whereNot('id', notCategoryId); - } - }); - if (foundItemCategory) { - throw new ServiceError( - ERRORS.CATEGORY_NAME_EXISTS, - 'The item category name is already exist.' - ); - } - } - - /** - * Inserts a new item category. - * @param {number} tenantId - * @param {IItemCategoryOTD} itemCategoryOTD - * @return {Promise} - */ - public async newItemCategory( - tenantId: number, - itemCategoryOTD: IItemCategoryOTD, - authorizedUser: ISystemUser, - trx?: Knex.Transaction - ): Promise { - const { ItemCategory } = this.tenancy.models(tenantId); - - // Validate the category name uniquiness. - await this.validateCategoryNameUniquiness(tenantId, itemCategoryOTD.name); - - if (itemCategoryOTD.sellAccountId) { - await this.validateSellAccount(tenantId, itemCategoryOTD.sellAccountId); - } - if (itemCategoryOTD.costAccountId) { - await this.validateCostAccount(tenantId, itemCategoryOTD.costAccountId); - } - if (itemCategoryOTD.inventoryAccountId) { - await this.validateInventoryAccount( - tenantId, - itemCategoryOTD.inventoryAccountId - ); - } - const itemCategoryObj = this.transformOTDToObject( - itemCategoryOTD, - authorizedUser - ); - // Creates item category under unit-of-work evnirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Inserts the item category. - const itemCategory = await ItemCategory.query(trx).insert({ - ...itemCategoryObj, - }); - // Triggers `onItemCategoryCreated` event. - await this.eventPublisher.emitAsync(events.itemCategory.onCreated, { - itemCategory, - tenantId, - trx, - } as IItemCategoryCreatedPayload); - - return itemCategory; - }, - trx - ); - } - - /** - * Validates sell account existance and type. - * @param {number} tenantId - Tenant id. - * @param {number} sellAccountId - Sell account id. - * @return {Promise} - */ - private async validateSellAccount(tenantId: number, sellAccountId: number) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const foundAccount = await accountRepository.findOneById(sellAccountId); - - if (!foundAccount) { - throw new ServiceError(ERRORS.SELL_ACCOUNT_NOT_FOUND); - } else if (!foundAccount.isRootType(ACCOUNT_ROOT_TYPE.INCOME)) { - throw new ServiceError(ERRORS.SELL_ACCOUNT_NOT_INCOME); - } - } - - /** - * Validates COGS account existance and type. - * @param {number} tenantId - - * @param {number} costAccountId - - * @return {Promise} - */ - private async validateCostAccount(tenantId: number, costAccountId: number) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const foundAccount = await accountRepository.findOneById(costAccountId); - - if (!foundAccount) { - throw new ServiceError(ERRORS.COST_ACCOUNT_NOT_FOUMD); - } else if (!foundAccount.isRootType(ACCOUNT_ROOT_TYPE.EXPENSE)) { - throw new ServiceError(ERRORS.COST_ACCOUNT_NOT_COGS); - } - } - - /** - * Validates inventory account existance and type. - * @param {number} tenantId - * @param {number} inventoryAccountId - * @return {Promise} - */ - private async validateInventoryAccount( - tenantId: number, - inventoryAccountId: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const foundAccount = await accountRepository.findOneById( - inventoryAccountId - ); - if (!foundAccount) { - throw new ServiceError(ERRORS.INVENTORY_ACCOUNT_NOT_FOUND); - } else if (!foundAccount.isAccountType(ACCOUNT_TYPE.INVENTORY)) { - throw new ServiceError(ERRORS.INVENTORY_ACCOUNT_NOT_INVENTORY); - } - } - - /** - * Edits item category. - * @param {number} tenantId - * @param {number} itemCategoryId - * @param {IItemCategoryOTD} itemCategoryOTD - * @return {Promise} - */ - public async editItemCategory( - tenantId: number, - itemCategoryId: number, - itemCategoryOTD: IItemCategoryOTD, - authorizedUser: ISystemUser - ): Promise { - const { ItemCategory } = this.tenancy.models(tenantId); - - // Retrieve the item category from the storage. - const oldItemCategory = await this.getItemCategoryOrThrowError( - tenantId, - itemCategoryId - ); - // Validate the category name whether unique on the storage. - await this.validateCategoryNameUniquiness( - tenantId, - itemCategoryOTD.name, - itemCategoryId - ); - if (itemCategoryOTD.sellAccountId) { - await this.validateSellAccount(tenantId, itemCategoryOTD.sellAccountId); - } - if (itemCategoryOTD.costAccountId) { - await this.validateCostAccount(tenantId, itemCategoryOTD.costAccountId); - } - if (itemCategoryOTD.inventoryAccountId) { - await this.validateInventoryAccount( - tenantId, - itemCategoryOTD.inventoryAccountId - ); - } - const itemCategoryObj = this.transformOTDToObject( - itemCategoryOTD, - authorizedUser - ); - // - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // - const itemCategory = await ItemCategory.query().patchAndFetchById( - itemCategoryId, - { ...itemCategoryObj } - ); - // Triggers `onItemCategoryEdited` event. - await this.eventPublisher.emitAsync(events.itemCategory.onEdited, { - oldItemCategory, - tenantId, - trx, - } as IItemCategoryEditedPayload); - - return itemCategory; - }); - } - - /** - * Deletes the given item category. - * @param {number} tenantId - Tenant id. - * @param {number} itemCategoryId - Item category id. - * @return {Promise} - */ - public async deleteItemCategory( - tenantId: number, - itemCategoryId: number, - authorizedUser: ISystemUser - ) { - const { ItemCategory } = this.tenancy.models(tenantId); - - // Retrieve item category or throw not found error. - const oldItemCategory = await this.getItemCategoryOrThrowError( - tenantId, - itemCategoryId - ); - - // - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Unassociate items with item category. - await this.unassociateItemsWithCategories(tenantId, itemCategoryId, trx); - - // - await ItemCategory.query(trx).findById(itemCategoryId).delete(); - - // - await this.eventPublisher.emitAsync(events.itemCategory.onDeleted, { - tenantId, - itemCategoryId, - oldItemCategory, - } as IItemCategoryDeletedPayload); - }); - } - - /** - * Parses items categories filter DTO. - * @param {} filterDTO - * @returns - */ - private parsesListFilterDTO(filterDTO) { - return R.compose( - // Parses stringified filter roles. - this.dynamicListService.parseStringifiedFilter - )(filterDTO); - } - - /** - * Retrieve item categories list. - * @param {number} tenantId - * @param filter - */ - public async getItemCategoriesList( - tenantId: number, - filterDTO: IItemCategoriesFilter, - authorizedUser: ISystemUser - ): Promise<{ itemCategories: IItemCategory[]; filterMeta: IFilterMeta }> { - const { ItemCategory } = this.tenancy.models(tenantId); - - // Parses list filter DTO. - const filter = this.parsesListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - ItemCategory, - filter - ); - // Items categories. - const itemCategories = await ItemCategory.query().onBuild((query) => { - // Subquery to calculate sumation of associated items to the item category. - query.select('*', ItemCategory.relatedQuery('items').count().as('count')); - - dynamicList.buildQuery()(query); - }); - return { itemCategories, filterMeta: dynamicList.getResponseMeta() }; - } - - /** - * Unlink items relations with item categories. - * @param {number} tenantId - * @param {number|number[]} itemCategoryId - - * @return {Promise} - */ - private async unassociateItemsWithCategories( - tenantId: number, - itemCategoryId: number | number[], - trx?: Knex.Transaction - ): Promise { - const { Item } = this.tenancy.models(tenantId); - const ids = Array.isArray(itemCategoryId) - ? itemCategoryId - : [itemCategoryId]; - - await Item.query(trx) - .whereIn('category_id', ids) - .patch({ category_id: null }); - } -} diff --git a/packages/server/src/services/ItemCategories/constants.ts b/packages/server/src/services/ItemCategories/constants.ts deleted file mode 100644 index c92830805..000000000 --- a/packages/server/src/services/ItemCategories/constants.ts +++ /dev/null @@ -1,35 +0,0 @@ -// eslint-disable-next-line import/prefer-default-export -export const ERRORS = { - ITEM_CATEGORIES_NOT_FOUND: 'ITEM_CATEGORIES_NOT_FOUND', - CATEGORY_NAME_EXISTS: 'CATEGORY_NAME_EXISTS', - CATEGORY_NOT_FOUND: 'CATEGORY_NOT_FOUND', - COST_ACCOUNT_NOT_FOUMD: 'COST_ACCOUNT_NOT_FOUMD', - COST_ACCOUNT_NOT_COGS: 'COST_ACCOUNT_NOT_COGS', - SELL_ACCOUNT_NOT_INCOME: 'SELL_ACCOUNT_NOT_INCOME', - SELL_ACCOUNT_NOT_FOUND: 'SELL_ACCOUNT_NOT_FOUND', - INVENTORY_ACCOUNT_NOT_FOUND: 'INVENTORY_ACCOUNT_NOT_FOUND', - INVENTORY_ACCOUNT_NOT_INVENTORY: 'INVENTORY_ACCOUNT_NOT_INVENTORY', - CATEGORY_HAVE_ITEMS: 'CATEGORY_HAVE_ITEMS', -}; - -export const ItemCategoriesSampleData = [ - { - Name: 'Kassulke Group', - Description: 'Optio itaque eaque qui adipisci illo sed.', - }, - { - Name: 'Crist, Mraz and Lueilwitz', - Description: - 'Dolores veniam deserunt sed commodi error quia veritatis non.', - }, - { - Name: 'Gutmann and Sons', - Description: - 'Ratione aperiam voluptas rem adipisci assumenda eos neque veritatis tempora.', - }, - { - Name: 'Reichel - Raynor', - Description: - 'Necessitatibus repellendus placeat possimus dolores excepturi ut.', - }, -]; diff --git a/packages/server/src/services/Items/ActivateItem.ts b/packages/server/src/services/Items/ActivateItem.ts deleted file mode 100644 index 1e417d881..000000000 --- a/packages/server/src/services/Items/ActivateItem.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; - -@Service() -export class ActivateItem { - @Inject() - tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Activates the given item on the storage. - * @param {number} tenantId - - * @param {number} itemId - - * @return {Promise} - */ - public async activateItem(tenantId: number, itemId: number): Promise { - const { Item } = this.tenancy.models(tenantId); - - // Retreives the given item or throw not found error. - const oldItem = await Item.query().findById(itemId).throwIfNotFound(); - - // Activate the given item with associated transactions under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Mutate item on the storage. - await Item.query(trx).findById(itemId).patch({ active: true }); - - // Triggers `onItemActivated` event. - await this.eventPublisher.emitAsync(events.item.onActivated, {}); - }); - } -} diff --git a/packages/server/src/services/Items/CreateItem.ts b/packages/server/src/services/Items/CreateItem.ts deleted file mode 100644 index 5864f2e09..000000000 --- a/packages/server/src/services/Items/CreateItem.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Knex } from 'knex'; -import { defaultTo } from 'lodash'; -import { Service, Inject } from 'typedi'; -import { IItem, IItemDTO, IItemEventCreatedPayload } from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { ItemsValidators } from './ItemValidators'; - -@Service() -export class CreateItem { - @Inject() - private validators: ItemsValidators; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Authorize the creating item. - * @param {number} tenantId - * @param {IItemDTO} itemDTO - */ - async authorize(tenantId: number, itemDTO: IItemDTO) { - // Validate whether the given item name already exists on the storage. - await this.validators.validateItemNameUniquiness(tenantId, itemDTO.name); - - if (itemDTO.categoryId) { - await this.validators.validateItemCategoryExistance( - tenantId, - itemDTO.categoryId - ); - } - if (itemDTO.sellAccountId) { - await this.validators.validateItemSellAccountExistance( - tenantId, - itemDTO.sellAccountId - ); - } - // Validate the income account id existance if the item is sellable. - this.validators.validateIncomeAccountExistance( - itemDTO.sellable, - itemDTO.sellAccountId - ); - if (itemDTO.costAccountId) { - await this.validators.validateItemCostAccountExistance( - tenantId, - itemDTO.costAccountId - ); - } - // Validate the cost account id existance if the item is purchasable. - this.validators.validateCostAccountExistance( - itemDTO.purchasable, - itemDTO.costAccountId - ); - if (itemDTO.inventoryAccountId) { - await this.validators.validateItemInventoryAccountExistance( - tenantId, - itemDTO.inventoryAccountId - ); - } - if (itemDTO.purchaseTaxRateId) { - await this.validators.validatePurchaseTaxRateExistance( - tenantId, - itemDTO.purchaseTaxRateId - ); - } - if (itemDTO.sellTaxRateId) { - await this.validators.validateSellTaxRateExistance( - tenantId, - itemDTO.sellTaxRateId - ); - } - } - - /** - * Transforms the item DTO to model. - * @param {IItemDTO} itemDTO - Item DTO. - * @return {IItem} - */ - private transformNewItemDTOToModel(itemDTO: IItemDTO) { - return { - ...itemDTO, - active: defaultTo(itemDTO.active, 1), - quantityOnHand: itemDTO.type === 'inventory' ? 0 : null, - }; - } - - /** - * Creates a new item. - * @param {number} tenantId DTO - * @param {IItemDTO} item - * @return {Promise} - */ - public async createItem( - tenantId: number, - itemDTO: IItemDTO, - trx?: Knex.Transaction - ): Promise { - const { Item } = this.tenancy.models(tenantId); - - // Authorize the item before creating. - await this.authorize(tenantId, itemDTO); - - // Creates a new item with associated transactions under unit-of-work envirement. - const item = this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Inserts a new item and fetch the created item. - const item = await Item.query(trx).insertAndFetch({ - ...this.transformNewItemDTOToModel(itemDTO), - }); - // Triggers `onItemCreated` event. - await this.eventPublisher.emitAsync(events.item.onCreated, { - tenantId, - item, - itemId: item.id, - trx, - } as IItemEventCreatedPayload); - - return item; - }, - trx - ); - return item; - } -} diff --git a/packages/server/src/services/Items/DeleteItem.ts b/packages/server/src/services/Items/DeleteItem.ts deleted file mode 100644 index 900faca03..000000000 --- a/packages/server/src/services/Items/DeleteItem.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IItemEventDeletedPayload, - IItemEventDeletingPayload, -} from '@/interfaces'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { ERRORS } from './constants'; - -@Service() -export class DeleteItem { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Delete the given item from the storage. - * @param {number} tenantId - Tenant id. - * @param {number} itemId - Item id. - * @return {Promise} - */ - public async deleteItem(tenantId: number, itemId: number) { - const { Item } = this.tenancy.models(tenantId); - - // Retreive the given item or throw not found service error. - const oldItem = await Item.query() - .findById(itemId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.ITEM_HAS_ASSOCIATED_TRANSACTIONS, - }); - // Delete item in unit of work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onItemDeleting` event. - await this.eventPublisher.emitAsync(events.item.onDeleting, { - tenantId, - trx, - oldItem, - } as IItemEventDeletingPayload); - - // Deletes the item. - await Item.query(trx).findById(itemId).delete(); - - const eventPayload: IItemEventDeletedPayload = { - tenantId, - oldItem, - itemId, - trx, - }; - // Triggers `onItemDeleted` event. - await this.eventPublisher.emitAsync(events.item.onDeleted, eventPayload); - }); - } -} diff --git a/packages/server/src/services/Items/EditItem.ts b/packages/server/src/services/Items/EditItem.ts deleted file mode 100644 index 17ac8240e..000000000 --- a/packages/server/src/services/Items/EditItem.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IItem, - IItemDTO, - IItemEditDTO, - IItemEventEditedPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { ItemsValidators } from './ItemValidators'; -import events from '@/subscribers/events'; - -@Service() -export class EditItem { - @Inject() - private validators: ItemsValidators; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Authorize the editing item. - * @param {number} tenantId - * @param {IItemEditDTO} itemDTO - * @param {IItem} oldItem - */ - async authorize(tenantId: number, itemDTO: IItemEditDTO, oldItem: IItem) { - // Validate edit item type from inventory type. - this.validators.validateEditItemFromInventory(itemDTO, oldItem); - - // Validate edit item type to inventory type. - await this.validators.validateEditItemTypeToInventory( - tenantId, - oldItem, - itemDTO - ); - // Validate whether the given item name already exists on the storage. - await this.validators.validateItemNameUniquiness( - tenantId, - itemDTO.name, - oldItem.id - ); - // Validate the item category existance on the storage, - if (itemDTO.categoryId) { - await this.validators.validateItemCategoryExistance( - tenantId, - itemDTO.categoryId - ); - } - // Validate the income account id existance if the item is sellable. - this.validators.validateIncomeAccountExistance( - itemDTO.sellable, - itemDTO.sellAccountId - ); - // Validate the sell account existance on the storage. - if (itemDTO.sellAccountId) { - await this.validators.validateItemSellAccountExistance( - tenantId, - itemDTO.sellAccountId - ); - } - // Validate the cost account id existance if the item is purchasable. - this.validators.validateCostAccountExistance( - itemDTO.purchasable, - itemDTO.costAccountId - ); - // Validate the cost account existance on the storage. - if (itemDTO.costAccountId) { - await this.validators.validateItemCostAccountExistance( - tenantId, - itemDTO.costAccountId - ); - } - // Validate the inventory account existance onthe storage. - if (itemDTO.inventoryAccountId) { - await this.validators.validateItemInventoryAccountExistance( - tenantId, - itemDTO.inventoryAccountId - ); - } - // Validate the purchase tax rate id existance. - if (itemDTO.purchaseTaxRateId) { - await this.validators.validatePurchaseTaxRateExistance( - tenantId, - itemDTO.purchaseTaxRateId - ); - } - // Validate the sell tax rate id existance. - if (itemDTO.sellTaxRateId) { - await this.validators.validateSellTaxRateExistance( - tenantId, - itemDTO.sellTaxRateId - ); - } - // Validate inventory account should be modified in inventory item - // has inventory transactions. - await this.validators.validateItemInvnetoryAccountModified( - tenantId, - oldItem, - itemDTO - ); - } - - /** - * Transformes edit item DTO to model. - * @param {IItemDTO} itemDTO - Item DTO. - * @param {IItem} oldItem - - */ - private transformEditItemDTOToModel(itemDTO: IItemDTO, oldItem: IItem) { - return { - ...itemDTO, - ...(itemDTO.type === 'inventory' && oldItem.type !== 'inventory' - ? { - quantityOnHand: 0, - } - : {}), - }; - } - - /** - * Edits the item metadata. - * @param {number} tenantId - * @param {number} itemId - * @param {IItemDTO} itemDTO - */ - public async editItem(tenantId: number, itemId: number, itemDTO: IItemDTO) { - const { Item } = this.tenancy.models(tenantId); - - // Validates the given item existance on the storage. - const oldItem = await Item.query().findById(itemId).throwIfNotFound(); - - // Authorize before editing item. - await this.authorize(tenantId, itemDTO, oldItem); - - // Transform the edit item DTO to model. - const itemModel = this.transformEditItemDTOToModel(itemDTO, oldItem); - - // Edits the item with associated transactions under unit-of-work envirement. - const newItem = this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Updates the item on the storage and fetches the updated once. - const newItem = await Item.query(trx).patchAndFetchById(itemId, { - ...itemModel, - }); - // Edit event payload. - const eventPayload: IItemEventEditedPayload = { - tenantId, - item: newItem, - oldItem, - itemId: newItem.id, - trx, - }; - // Triggers `onItemEdited` event. - await this.eventPublisher.emitAsync(events.item.onEdited, eventPayload); - - return newItem; - } - ); - - return newItem; - } -} diff --git a/packages/server/src/services/Items/GetItem.ts b/packages/server/src/services/Items/GetItem.ts deleted file mode 100644 index fd43cbf87..000000000 --- a/packages/server/src/services/Items/GetItem.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Inject } from 'typedi'; -import { IItem } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import ItemTransformer from './ItemTransformer'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Inject() -export class GetItem { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve the item details of the given id with associated details. - * @param {number} tenantId - * @param {number} itemId - */ - public async getItem(tenantId: number, itemId: number): Promise { - const { Item } = this.tenancy.models(tenantId); - - const item = await Item.query() - .findById(itemId) - .withGraphFetched('sellAccount') - .withGraphFetched('inventoryAccount') - .withGraphFetched('category') - .withGraphFetched('costAccount') - .withGraphFetched('itemWarehouses.warehouse') - .withGraphFetched('sellTaxRate') - .withGraphFetched('purchaseTaxRate') - .throwIfNotFound(); - - const transformed = await this.transformer.transform( - tenantId, - item, - new ItemTransformer() - ); - const eventPayload = { tenantId, itemId }; - - // Triggers the `onItemViewed` event. - await this.eventPublisher.emitAsync(events.item.onViewed, eventPayload); - - return transformed; - } -} diff --git a/packages/server/src/services/Items/GetItems.ts b/packages/server/src/services/Items/GetItems.ts deleted file mode 100644 index 24a7745ea..000000000 --- a/packages/server/src/services/Items/GetItems.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { IItemsFilter } from '@/interfaces'; -import ItemTransformer from './ItemTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetItems { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Parses items list filter DTO. - * @param {} filterDTO - Filter DTO. - */ - private parseItemsListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } - - /** - * Retrieve items datatable list. - * @param {number} tenantId - - * @param {IItemsFilter} itemsFilter - - */ - public async getItems(tenantId: number, filterDTO: IItemsFilter) { - const { Item } = this.tenancy.models(tenantId); - - // Parses items list filter DTO. - const filter = this.parseItemsListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - Item, - filter - ); - const { results: items, pagination } = await Item.query() - .onBuild((builder) => { - builder.modify('inactiveMode', filter.inactiveMode); - - builder.withGraphFetched('inventoryAccount'); - builder.withGraphFetched('sellAccount'); - builder.withGraphFetched('costAccount'); - builder.withGraphFetched('category'); - - dynamicFilter.buildQuery()(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Retrieves the transformed items. - const transformedItems = await this.transformer.transform( - tenantId, - items, - new ItemTransformer() - ); - return { - items: transformedItems, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - } -} diff --git a/packages/server/src/services/Items/InactivateItem.ts b/packages/server/src/services/Items/InactivateItem.ts deleted file mode 100644 index 5f1ccb83b..000000000 --- a/packages/server/src/services/Items/InactivateItem.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; - -@Service() -export class InactivateItem { - @Inject() - tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Inactivates the given item on the storage. - * @param {number} tenantId - * @param {number} itemId - * @return {Promise} - */ - public async inactivateItem(tenantId: number, itemId: number): Promise { - const { Item } = this.tenancy.models(tenantId); - - // Retrieves the item or throw not found error. - const oldItem = await Item.query().findById(itemId).throwIfNotFound(); - - // Inactivate item under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Activate item on the storage. - await Item.query(trx).findById(itemId).patch({ active: false }); - - // Triggers `onItemInactivated` event. - await this.eventPublisher.emitAsync(events.item.onInactivated, { trx }); - }); - } -} diff --git a/packages/server/src/services/Items/ItemBillsTransactionsTransformer.ts b/packages/server/src/services/Items/ItemBillsTransactionsTransformer.ts deleted file mode 100644 index 434de3b8c..000000000 --- a/packages/server/src/services/Items/ItemBillsTransactionsTransformer.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ItemBillTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedBillDate', - 'formattedRate', - 'formattedCost', - ]; - }; - - /** - * Formatted sell price. - * @param item - * @returns {string} - */ - public formattedAmount(item): string { - return formatNumber(item.amount, { - currencyCode: item.bill.currencyCode, - }); - } - - /** - * Formatted bill date. - * @param item - * @returns {string} - */ - public formattedBillDate = (entry): string => { - return this.formatDate(entry.bill.billDate); - }; - - /** - * Formatted quantity. - * @returns {string} - */ - public formattedQuantity = (entry): string => { - return entry.quantity; - }; - - /** - * Formatted rate. - * @param entry - * @returns {string} - */ - public formattedRate = (entry): string => { - return formatNumber(entry.rate, { - currencyCode: entry.bill.currencyCode, - }); - }; - - /** - * Formatted bill due date. - * @param entry - * @returns - */ - public formattedBillDueDate = (entry): string => { - return this.formatDate(entry.bill.dueDate); - }; - - /** - * - * @param entry - * @returns - */ - public transform = (entry) => { - return { - billId: entry.bill.id, - - billNumber: entry.bill.billNumber, - referenceNumber: entry.bill.referenceNo, - - billDate: entry.bill.billDate, - formattedBillDate: entry.formattedBillDate, - - billDueDate: entry.bill.dueDate, - formattedBillDueDate: entry.formattedBillDueDate, - - amount: entry.amount, - formattedAmount: entry.formattedAmount, - - quantity: entry.quantity, - formattedQuantity: entry.formattedQuantity, - - rate: entry.rate, - formattedRate: entry.formattedRate, - - vendorDisplayName: entry.bill.vendor.displayName, - vendorCurrencyCode: entry.bill.vendor.currencyCode, - }; - }; -} diff --git a/packages/server/src/services/Items/ItemEstimatesTransactionTransformer.ts b/packages/server/src/services/Items/ItemEstimatesTransactionTransformer.ts deleted file mode 100644 index 256419d91..000000000 --- a/packages/server/src/services/Items/ItemEstimatesTransactionTransformer.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ItemEstimateTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedEstimateDate', - 'formattedRate', - 'formattedCost', - ]; - }; - - /** - * Formatted sell price. - * @returns {string} - */ - public formattedAmount(item): string { - return formatNumber(item.amount, { - currencyCode: item.estimate.currencyCode, - }); - } - - /** - * Formatted estimate date. - * @returns {string} - */ - public formattedEstimateDate = (entry): string => { - return this.formatDate(entry.estimate.estimateDate); - }; - - /** - * Formatted quantity. - * @returns {string} - */ - public formattedQuantity = (entry): string => { - return entry.quantity; - }; - - /** - * Formatted rate. - * @returns {string} - */ - public formattedRate = (entry): string => { - return formatNumber(entry.rate, { - currencyCode: entry.estimate.currencyCode, - }); - }; - - /** - * - * @param entry - * @returns - */ - public transform = (entry) => { - return { - estimateId: entry.estimate.id, - - estimateNumber: entry.estimate.estimateNumber, - referenceNumber: entry.estimate.referenceNo, - - estimateDate: entry.estimate.estimateDate, - formattedEstimateDate: entry.formattedEstimateDate, - - amount: entry.amount, - formattedAmount: entry.formattedAmount, - - quantity: entry.quantity, - formattedQuantity: entry.formattedQuantity, - - rate: entry.rate, - formattedRate: entry.formattedRate, - - customerDisplayName: entry.estimate.customer.displayName, - customerCurrencyCode: entry.estimate.customer.currencyCode, - }; - }; -} diff --git a/packages/server/src/services/Items/ItemInvoicesTransactionsTransformer.ts b/packages/server/src/services/Items/ItemInvoicesTransactionsTransformer.ts deleted file mode 100644 index a244f47a4..000000000 --- a/packages/server/src/services/Items/ItemInvoicesTransactionsTransformer.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ItemInvoicesTransactionsTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedInvoiceDate', - 'formattedRate', - 'formattedCost', - ]; - }; - - /** - * Formatted sell price. - * @param item - * @returns {string} - */ - public formattedAmount(item): string { - return formatNumber(item.amount, { - currencyCode: item.invoice.currencyCode, - }); - } - - /** - * Formatted invoice date. - * @param item - * @returns - */ - public formattedInvoiceDate = (entry): string => { - return this.formatDate(entry.invoice.invoiceDate); - }; - - /** - * Formatted item quantity. - * @returns {string} - */ - public formattedQuantity = (entry): string => { - return entry.quantity; - }; - - /** - * Formatted date. - * @param entry - * @returns {string} - */ - public formattedRate = (entry): string => { - return formatNumber(entry.rate, { - currencyCode: entry.invoice.currencyCode, - }); - }; - - /** - * - * @param entry - * @returns - */ - public transform = (entry) => { - return { - invoiceId: entry.invoice.id, - - invoiceNumber: entry.invoice.invoiceNo, - referenceNumber: entry.invoice.referenceNo, - - invoiceDate: entry.invoice.invoiceDate, - formattedInvoiceDate: entry.formattedInvoiceDate, - - amount: entry.amount, - formattedAmount: entry.formattedAmount, - - quantity: entry.quantity, - formattedQuantity: entry.formattedQuantity, - - rate: entry.rate, - formattedRate: entry.formattedRate, - - customerDisplayName: entry.invoice.customer.displayName, - customerCurrencyCode: entry.invoice.customer.currencyCode, - }; - }; -} diff --git a/packages/server/src/services/Items/ItemReceiptsTransactionsTransformer.ts b/packages/server/src/services/Items/ItemReceiptsTransactionsTransformer.ts deleted file mode 100644 index 2d50e02f1..000000000 --- a/packages/server/src/services/Items/ItemReceiptsTransactionsTransformer.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ItemReceiptTransactionTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedReceiptDate', - 'formattedRate', - 'formattedCost', - ]; - }; - - /** - * Formatted sell price. - * @param item - * @returns {string} - */ - public formattedAmount(item): string { - return formatNumber(item.amount, { - currencyCode: item.receipt.currencyCode, - }); - } - - /** - * - * @param item - * @returns - */ - public formattedReceiptDate = (entry): string => { - return this.formatDate(entry.receipt.receiptDate); - }; - - /** - * - */ - public formattedQuantity = (entry): string => { - return entry.quantity; - }; - - /** - * - * @param entry - * @returns - */ - public formattedRate = (entry): string => { - return formatNumber(entry.rate, { - currencyCode: entry.receipt.currencyCode, - }); - }; - - /** - * - * @param entry - * @returns - */ - public transform = (entry) => { - return { - receiptId: entry.receipt.id, - - receipNumber: entry.receipt.receiptNumber, - referenceNumber: entry.receipt.referenceNo, - - receiptDate: entry.receipt.receiptDate, - formattedReceiptDate: entry.formattedReceiptDate, - - amount: entry.amount, - formattedAmount: entry.formattedAmount, - - quantity: entry.quantity, - formattedQuantity: entry.formattedQuantity, - - rate: entry.rate, - formattedRate: entry.formattedRate, - - customerDisplayName: entry.receipt.customer.displayName, - customerCurrencyCode: entry.receipt.customer.currencyCode, - }; - }; -} diff --git a/packages/server/src/services/Items/ItemTransactionsService.ts b/packages/server/src/services/Items/ItemTransactionsService.ts deleted file mode 100644 index 5defa6362..000000000 --- a/packages/server/src/services/Items/ItemTransactionsService.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ItemInvoicesTransactionsTransformer } from './ItemInvoicesTransactionsTransformer'; -import { ItemEstimateTransactionTransformer } from './ItemEstimatesTransactionTransformer'; -import { ItemBillTransactionTransformer } from './ItemBillsTransactionsTransformer'; -import { ItemReceiptTransactionTransformer } from './ItemReceiptsTransactionsTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class ItemTransactionsService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the item associated invoices transactions. - * @param {number} tenantId - - * @param {number} itemId - - */ - public async getItemInvoicesTransactions(tenantId: number, itemId: number) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const invoiceEntries = await ItemEntry.query() - .where('itemId', itemId) - .where('referenceType', 'SaleInvoice') - .withGraphJoined('invoice.customer(selectCustomerColumns)') - .orderBy('invoice:invoiceDate', 'ASC') - .modifiers({ - selectCustomerColumns: (builder) => { - builder.select('displayName', 'currencyCode', 'id'); - }, - }); - // Retrieves the transformed invoice entries. - return this.transformer.transform( - tenantId, - invoiceEntries, - new ItemInvoicesTransactionsTransformer() - ); - } - - /** - * Retrieve the item associated invoices transactions. - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public async getItemBillTransactions(tenantId: number, itemId: number) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const billEntries = await ItemEntry.query() - .where('itemId', itemId) - .where('referenceType', 'Bill') - .withGraphJoined('bill.vendor(selectVendorColumns)') - .orderBy('bill:billDate', 'ASC') - .modifiers({ - selectVendorColumns: (builder) => { - builder.select('displayName', 'currencyCode', 'id'); - }, - }); - // Retrieves the transformed bill entries. - return this.transformer.transform( - tenantId, - billEntries, - new ItemBillTransactionTransformer() - ); - } - - /** - * - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public async getItemEstimateTransactions(tenantId: number, itemId: number) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const estimatesEntries = await ItemEntry.query() - .where('itemId', itemId) - .where('referenceType', 'SaleEstimate') - .withGraphJoined('estimate.customer(selectCustomerColumns)') - .orderBy('estimate:estimateDate', 'ASC') - .modifiers({ - selectCustomerColumns: (builder) => { - builder.select('displayName', 'currencyCode', 'id'); - }, - }); - // Retrieves the transformed estimates entries. - return this.transformer.transform( - tenantId, - estimatesEntries, - new ItemEstimateTransactionTransformer() - ); - } - - /** - * - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public async getItemReceiptTransactions(tenantId: number, itemId: number) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const receiptsEntries = await ItemEntry.query() - .where('itemId', itemId) - .where('referenceType', 'SaleReceipt') - .withGraphJoined('receipt.customer(selectCustomerColumns)') - .orderBy('receipt:receiptDate', 'ASC') - .modifiers({ - selectCustomerColumns: (builder) => { - builder.select('displayName', 'currencyCode', 'id'); - }, - }); - // Retrieves the transformed receipts entries. - return this.transformer.transform( - tenantId, - receiptsEntries, - new ItemReceiptTransactionTransformer() - ); - } -} diff --git a/packages/server/src/services/Items/ItemTransformer.ts b/packages/server/src/services/Items/ItemTransformer.ts deleted file mode 100644 index 8952599f7..000000000 --- a/packages/server/src/services/Items/ItemTransformer.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { GetItemWarehouseTransformer } from '@/services/Warehouses/Items/GettItemWarehouseTransformer'; -import { formatNumber } from 'utils'; - -export default class ItemTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'typeFormatted', - 'sellPriceFormatted', - 'costPriceFormatted', - 'itemWarehouses', - ]; - }; - - /** - * Formatted item type. - * @param {IItem} item - * @returns {string} - */ - public typeFormatted(item): string { - return this.context.i18n.__(`item.field.type.${item.type}`); - } - - /** - * Formatted sell price. - * @param item - * @returns {string} - */ - public sellPriceFormatted(item): string { - return formatNumber(item.sellPrice, { - currencyCode: this.context.organization.baseCurrency, - }); - } - - /** - * Formatted cost price. - * @param item - * @returns {string} - */ - public costPriceFormatted(item): string { - return formatNumber(item.costPrice, { - currencyCode: this.context.organization.baseCurrency, - }); - } - - /** - * Associate the item warehouses quantity. - * @param item - * @returns - */ - public itemWarehouses = (item) => { - return this.item( - item.itemWarehouses, - new GetItemWarehouseTransformer(), - {} - ); - }; -} diff --git a/packages/server/src/services/Items/ItemValidators.ts b/packages/server/src/services/Items/ItemValidators.ts deleted file mode 100644 index 3468ad1d0..000000000 --- a/packages/server/src/services/Items/ItemValidators.ts +++ /dev/null @@ -1,319 +0,0 @@ -import { - ACCOUNT_PARENT_TYPE, - ACCOUNT_ROOT_TYPE, - ACCOUNT_TYPE, -} from '@/data/AccountTypes'; -import { ServiceError } from '@/exceptions'; -import { IItem, IItemDTO } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ERRORS } from './constants'; - -@Service() -export class ItemsValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validate wether the given item name already exists on the storage. - * @param {number} tenantId - * @param {string} itemName - * @param {number} notItemId - * @return {Promise} - */ - public async validateItemNameUniquiness( - tenantId: number, - itemName: string, - notItemId?: number - ): Promise { - const { Item } = this.tenancy.models(tenantId); - - const foundItems: [] = await Item.query().onBuild((builder: any) => { - builder.where('name', itemName); - if (notItemId) { - builder.whereNot('id', notItemId); - } - }); - if (foundItems.length > 0) { - throw new ServiceError( - ERRORS.ITEM_NAME_EXISTS, - 'The item name is already exist.' - ); - } - } - - /** - * Validate item COGS account existance and type. - * @param {number} tenantId - * @param {number} costAccountId - * @return {Promise} - */ - public async validateItemCostAccountExistance( - tenantId: number, - costAccountId: number - ): Promise { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const foundAccount = await accountRepository.findOneById(costAccountId); - - if (!foundAccount) { - throw new ServiceError(ERRORS.COST_ACCOUNT_NOT_FOUMD); - - // Detarmines the cost of goods sold account. - } else if (!foundAccount.isParentType(ACCOUNT_PARENT_TYPE.EXPENSE)) { - throw new ServiceError(ERRORS.COST_ACCOUNT_NOT_COGS); - } - } - - /** - * Validate item sell account existance and type. - * @param {number} tenantId - Tenant id. - * @param {number} sellAccountId - Sell account id. - */ - public async validateItemSellAccountExistance( - tenantId: number, - sellAccountId: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const foundAccount = await accountRepository.findOneById(sellAccountId); - - if (!foundAccount) { - throw new ServiceError(ERRORS.SELL_ACCOUNT_NOT_FOUND); - } else if (!foundAccount.isParentType(ACCOUNT_ROOT_TYPE.INCOME)) { - throw new ServiceError(ERRORS.SELL_ACCOUNT_NOT_INCOME); - } - } - - /** - * Validates income account existance. - * @param {number|null} sellable - Detarmines if the item sellable. - * @param {number|null} incomeAccountId - Income account id. - * @throws {ServiceError(ERRORS.INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM)} - */ - public validateIncomeAccountExistance( - sellable?: boolean, - incomeAccountId?: number - ) { - if (sellable && !incomeAccountId) { - throw new ServiceError( - ERRORS.INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM, - 'Income account is require with sellable item.' - ); - } - } - - /** - * Validates the cost account existance. - * @param {boolean|null} purchasable - Detarmines if the item purchasble. - * @param {number|null} costAccountId - Cost account id. - * @throws {ServiceError(ERRORS.COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM)} - */ - public validateCostAccountExistance( - purchasable: boolean, - costAccountId?: number - ) { - if (purchasable && !costAccountId) { - throw new ServiceError( - ERRORS.COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM, - 'The cost account is required with purchasable item.' - ); - } - } - - /** - * Validate item inventory account existance and type. - * @param {number} tenantId - * @param {number} inventoryAccountId - */ - public async validateItemInventoryAccountExistance( - tenantId: number, - inventoryAccountId: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const foundAccount = await accountRepository.findOneById( - inventoryAccountId - ); - - if (!foundAccount) { - throw new ServiceError(ERRORS.INVENTORY_ACCOUNT_NOT_FOUND); - } else if (!foundAccount.isAccountType(ACCOUNT_TYPE.INVENTORY)) { - throw new ServiceError(ERRORS.INVENTORY_ACCOUNT_NOT_INVENTORY); - } - } - - /** - * Validate item category existance. - * @param {number} tenantId - * @param {number} itemCategoryId - */ - public async validateItemCategoryExistance( - tenantId: number, - itemCategoryId: number - ) { - const { ItemCategory } = this.tenancy.models(tenantId); - const foundCategory = await ItemCategory.query().findById(itemCategoryId); - - if (!foundCategory) { - throw new ServiceError(ERRORS.ITEM_CATEOGRY_NOT_FOUND); - } - } - - /** - * Validates the given item or items have no associated invoices or bills. - * @param {number} tenantId - Tenant id. - * @param {number|number[]} itemId - Item id. - * @throws {ServiceError} - */ - public async validateHasNoInvoicesOrBills( - tenantId: number, - itemId: number[] | number - ) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const ids = Array.isArray(itemId) ? itemId : [itemId]; - const foundItemEntries = await ItemEntry.query().whereIn('item_id', ids); - - if (foundItemEntries.length > 0) { - throw new ServiceError( - ids.length > 1 - ? ERRORS.ITEMS_HAVE_ASSOCIATED_TRANSACTIONS - : ERRORS.ITEM_HAS_ASSOCIATED_TRANSACTINS - ); - } - } - - /** - * Validates the given item has no associated inventory adjustment transactions. - * @param {number} tenantId - - * @param {number} itemId - - */ - public async validateHasNoInventoryAdjustments( - tenantId: number, - itemId: number[] | number - ): Promise { - const { InventoryAdjustmentEntry } = this.tenancy.models(tenantId); - const itemsIds = Array.isArray(itemId) ? itemId : [itemId]; - - const inventoryAdjEntries = await InventoryAdjustmentEntry.query().whereIn( - 'item_id', - itemsIds - ); - if (inventoryAdjEntries.length > 0) { - throw new ServiceError(ERRORS.ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT); - } - } - - /** - * Validates edit item type from service/non-inventory to inventory. - * Should item has no any relations with accounts transactions. - * @param {number} tenantId - Tenant id. - * @param {number} itemId - Item id. - */ - public async validateEditItemTypeToInventory( - tenantId: number, - oldItem: IItem, - newItemDTO: IItemDTO - ) { - const { AccountTransaction } = this.tenancy.models(tenantId); - - // We have no problem in case the item type not modified. - if (newItemDTO.type === oldItem.type || oldItem.type === 'inventory') { - return; - } - // Retrieve all transactions that associated to the given item id. - const itemTransactionsCount = await AccountTransaction.query() - .where('item_id', oldItem.id) - .count('item_id', { as: 'transactions' }) - .first(); - - if (itemTransactionsCount.transactions > 0) { - throw new ServiceError( - ERRORS.TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS - ); - } - } - - /** - * Validate the item inventory account whether modified and item - * has associated inventory transactions. - * @param {numnber} tenantId - * @param {IItem} oldItem - * @param {IItemDTO} newItemDTO - * @returns - */ - async validateItemInvnetoryAccountModified( - tenantId: number, - oldItem: IItem, - newItemDTO: IItemDTO - ) { - const { AccountTransaction } = this.tenancy.models(tenantId); - - if ( - newItemDTO.type !== 'inventory' || - oldItem.inventoryAccountId === newItemDTO.inventoryAccountId - ) { - return; - } - // Inventory transactions associated to the given item id. - const transactions = await AccountTransaction.query().where({ - itemId: oldItem.id, - }); - // Throw the service error in case item has associated inventory transactions. - if (transactions.length > 0) { - throw new ServiceError(ERRORS.INVENTORY_ACCOUNT_CANNOT_MODIFIED); - } - } - - /** - * Validate edit item type from inventory to another type that not allowed. - * @param {IItemDTO} itemDTO - Item DTO. - * @param {IItem} oldItem - Old item. - */ - public validateEditItemFromInventory(itemDTO: IItemDTO, oldItem: IItem) { - if ( - itemDTO.type && - oldItem.type === 'inventory' && - itemDTO.type !== oldItem.type - ) { - throw new ServiceError(ERRORS.ITEM_CANNOT_CHANGE_INVENTORY_TYPE); - } - } - - /** - * Validate the purchase tax rate id existance. - * @param {number} tenantId - - * @param {number} taxRateId - - */ - public async validatePurchaseTaxRateExistance( - tenantId: number, - taxRateId: number - ) { - const { TaxRate } = this.tenancy.models(tenantId); - - const foundTaxRate = await TaxRate.query().findById(taxRateId); - - if (!foundTaxRate) { - throw new ServiceError(ERRORS.PURCHASE_TAX_RATE_NOT_FOUND); - } - } - - /** - * Validate the sell tax rate id existance. - * @param {number} tenantId - * @param {number} taxRateId - */ - public async validateSellTaxRateExistance( - tenantId: number, - taxRateId: number - ) { - const { TaxRate } = this.tenancy.models(tenantId); - - const foundTaxRate = await TaxRate.query().findById(taxRateId); - - if (!foundTaxRate) { - throw new ServiceError(ERRORS.SELL_TAX_RATE_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Items/ItemsApplication.ts b/packages/server/src/services/Items/ItemsApplication.ts deleted file mode 100644 index 24b72ec39..000000000 --- a/packages/server/src/services/Items/ItemsApplication.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IItem, - IItemCreateDTO, - IItemDTO, - IItemEditDTO, - IItemsFilter, -} from '@/interfaces'; -import { CreateItem } from './CreateItem'; -import { EditItem } from './EditItem'; -import { DeleteItem } from './DeleteItem'; -import { GetItem } from './GetItem'; -import { GetItems } from './GetItems'; -import { ActivateItem } from './ActivateItem'; -import { InactivateItem } from './InactivateItem'; - -@Service() -export class ItemsApplication { - @Inject() - private createItemService: CreateItem; - - @Inject() - private editItemService: EditItem; - - @Inject() - private getItemService: GetItem; - - @Inject() - private getItemsService: GetItems; - - @Inject() - private deleteItemService: DeleteItem; - - @Inject() - private activateItemService: ActivateItem; - - @Inject() - private inactivateItemService: InactivateItem; - - /** - * Creates a new item (service/product). - * @param {number} tenantId - * @param {IItemCreateDTO} itemDTO - * @returns {Promise} - */ - public async createItem( - tenantId: number, - itemDTO: IItemCreateDTO - ): Promise { - return this.createItemService.createItem(tenantId, itemDTO); - } - - /** - * Retrieves the given item. - * @param {number} tenantId - * @param {number} itemId - * @returns {Promise} - */ - public getItem(tenantId: number, itemId: number): Promise { - return this.getItemService.getItem(tenantId, itemId); - } - - /** - * Edits the given item (service/product). - * @param {number} tenantId - * @param {number} itemId - * @param {IItemEditDTO} itemDTO - * @returns {Promise} - */ - public editItem(tenantId: number, itemId: number, itemDTO: IItemEditDTO) { - return this.editItemService.editItem(tenantId, itemId, itemDTO); - } - - /** - * Deletes the given item (service/product). - * @param {number} tenantId - * @param {number} itemId - * @returns {Promise} - */ - public deleteItem(tenantId: number, itemId: number) { - return this.deleteItemService.deleteItem(tenantId, itemId); - } - - /** - * Activates the given item (service/product). - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public activateItem(tenantId: number, itemId: number): Promise { - return this.activateItemService.activateItem(tenantId, itemId); - } - - /** - * Inactivates the given item. - * @param {number} tenantId - - * @param {number} itemId - - */ - public inactivateItem(tenantId: number, itemId: number): Promise { - return this.inactivateItemService.inactivateItem(tenantId, itemId); - } - - /** - * Retrieves the items paginated list. - * @param {number} tenantId - * @param {IItemsFilter} filterDTO - * @returns {} - */ - public getItems(tenantId: number, filterDTO: IItemsFilter) { - return this.getItemsService.getItems(tenantId, filterDTO); - } -} diff --git a/packages/server/src/services/Items/ItemsEntriesService.ts b/packages/server/src/services/Items/ItemsEntriesService.ts deleted file mode 100644 index 89cdb62b7..000000000 --- a/packages/server/src/services/Items/ItemsEntriesService.ts +++ /dev/null @@ -1,251 +0,0 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { Knex } from 'knex'; -import { sumBy, difference, map } from 'lodash'; -import { IItemEntry, IItemEntryDTO, IItem } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { Item, ItemEntry } from '@/models'; -import { entriesAmountDiff } from 'utils'; - -const ERRORS = { - ITEMS_NOT_FOUND: 'ITEMS_NOT_FOUND', - ENTRIES_IDS_NOT_FOUND: 'ENTRIES_IDS_NOT_FOUND', - NOT_PURCHASE_ABLE_ITEMS: 'NOT_PURCHASE_ABLE_ITEMS', - NOT_SELL_ABLE_ITEMS: 'NOT_SELL_ABLE_ITEMS', -}; - -@Injectable() -export default class ItemsEntriesService { - constructor( - @Inject(Item.name) - private readonly itemModel: TenantModelProx, - - @Inject(ItemEntry.name) - private readonly itemEntryModel: TenantModelProxy, - private readonly itemRepository: any // Replace 'any' with proper repository type - ) {} - - /** - * Retrieve the inventory items entries of the reference id and type. - * @param {string} referenceType - * @param {string} referenceId - * @return {Promise} - */ - public async getInventoryEntries( - referenceType: string, - referenceId: number - ): Promise { - const itemsEntries = await this.itemEntryModel - .query() - .where('reference_type', referenceType) - .where('reference_id', referenceId); - - const inventoryItems = await this.itemModel - .query() - .whereIn('id', map(itemsEntries, 'itemId')) - .where('type', 'inventory'); - - const inventoryItemsIds = map(inventoryItems, 'id'); - - const inventoryItemsEntries = itemsEntries.filter( - (itemEntry) => inventoryItemsIds.indexOf(itemEntry.itemId) !== -1 - ); - return inventoryItemsEntries; - } - - /** - * Filter the given entries to inventory entries. - * @param {IItemEntry[]} entries - - * @returns {IItemEntry[]} - */ - public async filterInventoryEntries( - entries: IItemEntry[], - trx?: Knex.Transaction - ): Promise { - const entriesItemsIds = entries.map((e) => e.itemId); - - const inventoryItems = await this.itemModel - .query(trx) - .whereIn('id', entriesItemsIds) - .where('type', 'inventory'); - - const inventoryEntries = entries.filter((entry) => - inventoryItems.some((item) => item.id === entry.itemId) - ); - return inventoryEntries; - } - - /** - * Validates the entries items ids. - * @async - * @param {IItemEntryDTO[]} itemEntries - - */ - public async validateItemsIdsExistance(itemEntries: IItemEntryDTO[]) { - const itemsIds = itemEntries.map((e) => e.itemId); - - const foundItems = await this.itemModel.query().whereIn('id', itemsIds); - - const foundItemsIds = foundItems.map((item: IItem) => item.id); - const notFoundItemsIds = difference(itemsIds, foundItemsIds); - - if (notFoundItemsIds.length > 0) { - throw new ServiceError(ERRORS.ITEMS_NOT_FOUND); - } - return foundItems; - } - - /** - * Validates the entries ids existance on the storage. - * @param {number} billId - - * @param {IItemEntry[]} billEntries - - */ - public async validateEntriesIdsExistance( - referenceId: number, - referenceType: string, - billEntries: IItemEntryDTO[] - ) { - const entriesIds = billEntries - .filter((e: IItemEntry) => e.id) - .map((e: IItemEntry) => e.id); - - const storedEntries = await this.itemEntryModel - .query() - .whereIn('reference_id', [referenceId]) - .whereIn('reference_type', [referenceType]); - - const storedEntriesIds = storedEntries.map((entry) => entry.id); - const notFoundEntriesIds = difference(entriesIds, storedEntriesIds); - - if (notFoundEntriesIds.length > 0) { - throw new ServiceError(ERRORS.ENTRIES_IDS_NOT_FOUND); - } - } - - /** - * Validate the entries items that not purchase-able. - */ - public async validateNonPurchasableEntriesItems( - itemEntries: IItemEntryDTO[] - ) { - const itemsIds = itemEntries.map((e: IItemEntryDTO) => e.itemId); - - const purchasbleItems = await this.itemModel - .query() - .where('purchasable', true) - .whereIn('id', itemsIds); - - const purchasbleItemsIds = purchasbleItems.map((item: IItem) => item.id); - const notPurchasableItems = difference(itemsIds, purchasbleItemsIds); - - if (notPurchasableItems.length > 0) { - throw new ServiceError(ERRORS.NOT_PURCHASE_ABLE_ITEMS); - } - } - - /** - * Validate the entries items that not sell-able. - */ - public async validateNonSellableEntriesItems(itemEntries: IItemEntryDTO[]) { - const itemsIds = itemEntries.map((e: IItemEntryDTO) => e.itemId); - - const sellableItems = await this.itemModel - .query() - .where('sellable', true) - .whereIn('id', itemsIds); - - const sellableItemsIds = sellableItems.map((item: IItem) => item.id); - const nonSellableItems = difference(itemsIds, sellableItemsIds); - - if (nonSellableItems.length > 0) { - throw new ServiceError(ERRORS.NOT_SELL_ABLE_ITEMS); - } - } - - /** - * Changes items quantity from the given items entries the new and old onces. - * @param {IItemEntry[]} entries - Items entries. - * @param {IItemEntry[]} oldEntries - Old items entries. - */ - public async changeItemsQuantity( - entries: IItemEntry[], - oldEntries?: IItemEntry[] - ): Promise { - const opers = []; - - const diffEntries = entriesAmountDiff( - entries, - oldEntries, - 'quantity', - 'itemId' - ); - diffEntries.forEach((entry: IItemEntry) => { - const changeQuantityOper = this.itemRepository.changeNumber( - { id: entry.itemId, type: 'inventory' }, - 'quantityOnHand', - entry.quantity - ); - opers.push(changeQuantityOper); - }); - await Promise.all(opers); - } - - /** - * Increment items quantity from the given items entries. - * @param {IItemEntry[]} entries - Items entries. - */ - public async incrementItemsEntries(entries: IItemEntry[]): Promise { - return this.changeItemsQuantity(entries); - } - - /** - * Decrement items quantity from the given items entries. - * @param {IItemEntry[]} entries - Items entries. - */ - public async decrementItemsQuantity(entries: IItemEntry[]): Promise { - return this.changeItemsQuantity( - entries.map((entry) => ({ - ...entry, - quantity: entry.quantity * -1, - })) - ); - } - - /** - * Sets the cost/sell accounts to the invoice entries. - */ - public setItemsEntriesDefaultAccounts() { - return async (entries: IItemEntry[]) => { - const entriesItemsIds = entries.map((e) => e.itemId); - const items = await this.itemModel.query().whereIn('id', entriesItemsIds); - - return entries.map((entry) => { - const item = items.find((i) => i.id === entry.itemId); - - return { - ...entry, - sellAccountId: entry.sellAccountId || item.sellAccountId, - ...(item.type === 'inventory' && { - costAccountId: entry.costAccountId || item.costAccountId, - }), - }; - }); - }; - } - - /** - * Retrieve the total items entries. - * @param entries - * @returns - */ - public getTotalItemsEntries(entries: ItemEntry[]): number { - return sumBy(entries, (e) => ItemEntry.calcAmount(e)); - } - - /** - * Retrieve the non-zero tax items entries. - * @param {IItemEntry[]} entries - - * @returns {IItemEntry[]} - */ - public getNonZeroEntries(entries: IItemEntry[]): IItemEntry[] { - return entries.filter((e) => e.taxRate > 0); - } -} diff --git a/packages/server/src/services/Items/ItemsExportable.ts b/packages/server/src/services/Items/ItemsExportable.ts deleted file mode 100644 index c39b70259..000000000 --- a/packages/server/src/services/Items/ItemsExportable.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Exportable } from '../Export/Exportable'; -import { IItemsFilter } from '@/interfaces'; -import { ItemsApplication } from './ItemsApplication'; -import { EXPORT_SIZE_LIMIT } from '../Export/constants'; - -@Service() -export class ItemsExportable extends Exportable { - @Inject() - private itemsApplication: ItemsApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IItemsFilter) { - const parsedQuery = { - sortOrder: 'DESC', - columnSortBy: 'created_at', - page: 1, - ...query, - pageSize: EXPORT_SIZE_LIMIT, - } as IItemsFilter; - - return this.itemsApplication - .getItems(tenantId, parsedQuery) - .then((output) => output.items); - } -} diff --git a/packages/server/src/services/Items/ItemsImportable.ts b/packages/server/src/services/Items/ItemsImportable.ts deleted file mode 100644 index bcce0e089..000000000 --- a/packages/server/src/services/Items/ItemsImportable.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { Importable } from '@/services/Import/Importable'; -import { IItemCreateDTO } from '@/interfaces'; -import { CreateItem } from './CreateItem'; -import { ItemsSampleData } from './constants'; - -@Service() -export class ItemsImportable extends Importable { - @Inject() - private createItemService: CreateItem; - - /** - * Mapps the imported data to create a new item service. - * @param {number} tenantId - * @param {ICustomerNewDTO} createDTO - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public async importable( - tenantId: number, - createDTO: IItemCreateDTO, - trx?: Knex.Transaction - ): Promise { - await this.createItemService.createItem(tenantId, createDTO, trx); - } - - /** - * Retrieves the sample data of customers used to download sample sheet. - */ - public sampleData(): any[] { - return ItemsSampleData; - } -} diff --git a/packages/server/src/services/Items/constants.ts b/packages/server/src/services/Items/constants.ts deleted file mode 100644 index 9b4089687..000000000 --- a/packages/server/src/services/Items/constants.ts +++ /dev/null @@ -1,141 +0,0 @@ -export const ERRORS = { - NOT_FOUND: 'NOT_FOUND', - ITEMS_NOT_FOUND: 'ITEMS_NOT_FOUND', - - ITEM_NAME_EXISTS: 'ITEM_NAME_EXISTS', - ITEM_CATEOGRY_NOT_FOUND: 'ITEM_CATEOGRY_NOT_FOUND', - COST_ACCOUNT_NOT_COGS: 'COST_ACCOUNT_NOT_COGS', - COST_ACCOUNT_NOT_FOUMD: 'COST_ACCOUNT_NOT_FOUMD', - SELL_ACCOUNT_NOT_FOUND: 'SELL_ACCOUNT_NOT_FOUND', - SELL_ACCOUNT_NOT_INCOME: 'SELL_ACCOUNT_NOT_INCOME', - - INVENTORY_ACCOUNT_NOT_FOUND: 'INVENTORY_ACCOUNT_NOT_FOUND', - INVENTORY_ACCOUNT_NOT_INVENTORY: 'INVENTORY_ACCOUNT_NOT_INVENTORY', - - ITEMS_HAVE_ASSOCIATED_TRANSACTIONS: 'ITEMS_HAVE_ASSOCIATED_TRANSACTIONS', - ITEM_HAS_ASSOCIATED_TRANSACTINS: 'ITEM_HAS_ASSOCIATED_TRANSACTINS', - - ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT: - 'ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT', - ITEM_CANNOT_CHANGE_INVENTORY_TYPE: 'ITEM_CANNOT_CHANGE_INVENTORY_TYPE', - TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS: - 'TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS', - INVENTORY_ACCOUNT_CANNOT_MODIFIED: 'INVENTORY_ACCOUNT_CANNOT_MODIFIED', - - ITEM_HAS_ASSOCIATED_TRANSACTIONS: 'ITEM_HAS_ASSOCIATED_TRANSACTIONS', - - PURCHASE_TAX_RATE_NOT_FOUND: 'PURCHASE_TAX_RATE_NOT_FOUND', - SELL_TAX_RATE_NOT_FOUND: 'SELL_TAX_RATE_NOT_FOUND', - - INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM: - 'INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM', - COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM: - 'COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM', -}; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'Services', - slug: 'services', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'type', comparator: 'equals', value: 'service' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Inventory', - slug: 'inventory', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'type', comparator: 'equals', value: 'inventory' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Non Inventory', - slug: 'non-inventory', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'type', - comparator: 'equals', - value: 'non-inventory', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const ItemsSampleData = [ - { - 'Item Type': 'Inventory', - 'Item Name': 'Hettinger, Schumm and Bartoletti', - 'Item Code': '1000', - Sellable: 'T', - Purchasable: 'T', - 'Cost Price': '10000', - 'Sell Price': '1000', - 'Cost Account': 'Cost of Goods Sold', - 'Sell Account': 'Other Income', - 'Inventory Account': 'Inventory Asset', - 'Sell Description': 'Description ....', - 'Purchase Description': 'Description ....', - Category: 'sdafasdfsadf', - Note: 'At dolor est non tempore et quisquam.', - Active: 'TRUE', - }, - { - 'Item Type': 'Inventory', - 'Item Name': 'Schmitt Group', - 'Item Code': '1001', - Sellable: 'T', - Purchasable: 'T', - 'Cost Price': '10000', - 'Sell Price': '1000', - 'Cost Account': 'Cost of Goods Sold', - 'Sell Account': 'Other Income', - 'Inventory Account': 'Inventory Asset', - 'Sell Description': 'Description ....', - 'Purchase Description': 'Description ....', - Category: 'sdafasdfsadf', - Note: 'Id perspiciatis at adipisci minus accusamus dolor iure dolore.', - Active: 'TRUE', - }, - { - 'Item Type': 'Inventory', - 'Item Name': 'Marks - Carroll', - 'Item Code': '1002', - Sellable: 'T', - Purchasable: 'T', - 'Cost Price': '10000', - 'Sell Price': '1000', - 'Cost Account': 'Cost of Goods Sold', - 'Sell Account': 'Other Income', - 'Inventory Account': 'Inventory Asset', - 'Sell Description': 'Description ....', - 'Purchase Description': 'Description ....', - Category: 'sdafasdfsadf', - Note: 'Odio odio minus similique.', - Active: 'TRUE', - }, - { - 'Item Type': 'Inventory', - 'Item Name': 'VonRueden, Ruecker and Hettinger', - 'Item Code': '1003', - Sellable: 'T', - Purchasable: 'T', - 'Cost Price': '10000', - 'Sell Price': '1000', - 'Cost Account': 'Cost of Goods Sold', - 'Sell Account': 'Other Income', - 'Inventory Account': 'Inventory Asset', - 'Sell Description': 'Description ....', - 'Purchase Description': 'Description ....', - Category: 'sdafasdfsadf', - Note: 'Quibusdam dolores illo.', - Active: 'TRUE', - }, -]; diff --git a/packages/server/src/services/Items/utils.ts b/packages/server/src/services/Items/utils.ts deleted file mode 100644 index 58e9b8de0..000000000 --- a/packages/server/src/services/Items/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IItemEntry } from '@/interfaces'; -import { isNull, isUndefined } from 'lodash'; - -export function assocItemEntriesDefaultIndex( - entries: Array -): Array { - return entries.map((entry, index) => { - return { - index: - isUndefined(entry.index) || isNull(entry.index) - ? index + 1 - : entry.index, - ...entry, - }; - }); -} diff --git a/packages/server/src/services/Jobs/JobTransformer.ts b/packages/server/src/services/Jobs/JobTransformer.ts deleted file mode 100644 index 1def63923..000000000 --- a/packages/server/src/services/Jobs/JobTransformer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Service } from 'typedi'; -import moment from 'moment'; -import { Transformer } from '@/lib/Transformer/Transformer'; - -@Service() -export class JobTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['queued', 'completed', 'failed']; - }; - - /** - * Detarmines the queued state. - * @param {IJob} job - * @returns {String} - */ - protected queued = (job): boolean => { - return !!job.nextRunAt && moment().isSameOrAfter(job.nextRunAt, 'seconds'); - }; - - /** - * Detarmines the completed state. - * @param job - * @returns - */ - protected completed = (job): boolean => { - return !!job.lastFinishedAt; - }; - - /** - * Detarmines the failed state. - * @param job - * @returns - */ - protected failed = (job): boolean => { - return ( - job.lastFinishedAt && - job.failedAt && - moment(job.failedAt).isSame(job.lastFinishedAt) - ); - }; -} diff --git a/packages/server/src/services/Jobs/JobsService.ts b/packages/server/src/services/Jobs/JobsService.ts deleted file mode 100644 index 6f1cc69cb..000000000 --- a/packages/server/src/services/Jobs/JobsService.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { pick, first } from 'lodash'; -import { ObjectId } from 'mongodb'; -import { Service, Inject } from 'typedi'; -import { JobTransformer } from './JobTransformer'; -import { IJobMeta } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class JobsService { - @Inject('agenda') - agenda: any; - - @Inject() - transformer: TransformerInjectable; - - /** - * Retrieve job details of the given job id. - * @param {number} tenantId - - * @param {string} jobId - - * @returns {Promise} - */ - async getJob(jobId: string): Promise { - const jobs = await this.agenda.jobs({ _id: new ObjectId(jobId) }); - - // Transformes job to json. - const jobJson = this.transformJobToJson(first(jobs)); - - return this.transformer.transform(null, jobJson, new JobTransformer()); - } - - /** - * Transformes the job to json. - * @param job - * @returns - */ - private transformJobToJson(job) { - return { - id: job.attrs._id, - ...pick(job.attrs, [ - 'nextRunAt', - 'lastModifiedBy', - 'lockedAt', - 'lastRunAt', - 'failCount', - 'failReason', - 'failedAt', - 'lastFinishedAt', - ]), - running: job.isRunning(), - }; - } -} diff --git a/packages/server/src/services/Ledger/LedgerRepository.ts b/packages/server/src/services/Ledger/LedgerRepository.ts deleted file mode 100644 index e8e7866e9..000000000 --- a/packages/server/src/services/Ledger/LedgerRepository.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Service } from 'typedi'; -import { omit } from 'lodash'; -import JournalPoster from '@/services/Accounting/JournalPoster'; -import JournalEntry from '@/services/Accounting/JournalEntry'; -import Knex from 'knex'; -import { ILedgerEntry } from '@/interfaces'; - -@Service() -export default class LedgerRepository { - /** - * - * @param {number} tenantId - * @param {ILedgerEntry[]} ledgerEntries - * @param {Knex.Transaction} trx - */ - public saveLedgerEntries = async ( - tenantId: number, - ledgerEntries: ILedgerEntry[], - trx?: Knex.Transaction - ) => { - const journal = new JournalPoster(tenantId, null, trx); - - ledgerEntries.forEach((ledgerEntry) => { - const entry = new JournalEntry({ - ...omit(ledgerEntry, [ - 'accountNormal', - 'referenceNo', - 'transactionId', - 'transactionType', - ]), - contactId: ledgerEntry.contactId, - account: ledgerEntry.accountId, - referenceId: ledgerEntry.transactionId, - referenceType: ledgerEntry.transactionType, - referenceNumber: ledgerEntry.referenceNo, - transactionNumber: ledgerEntry.transactionNumber, - index: ledgerEntry.index, - indexGroup: ledgerEntry.indexGroup, - }); - - if (ledgerEntry.credit) { - journal.credit(entry); - } - if (ledgerEntry.debit) { - journal.debit(entry); - } - }); - - await Promise.all([ - journal.deleteEntries(), - journal.saveBalance(), - journal.saveContactsBalance(), - journal.saveEntries(), - ]); - } -} diff --git a/packages/server/src/services/Loops/LoopsEventsSubscriber.ts b/packages/server/src/services/Loops/LoopsEventsSubscriber.ts deleted file mode 100644 index 33fe56e1a..000000000 --- a/packages/server/src/services/Loops/LoopsEventsSubscriber.ts +++ /dev/null @@ -1,51 +0,0 @@ -import axios from 'axios'; -import config from '@/config'; -import { IAuthSignUpVerifiedEventPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { SystemUser } from '@/system/models'; - -export class LoopsEventsSubscriber { - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.auth.signUpConfirmed, - this.triggerEventOnSignupVerified.bind(this) - ); - } - - /** - * Once the user verified sends the event to the Loops. - * @param {IAuthSignUpVerifiedEventPayload} param0 - */ - public async triggerEventOnSignupVerified({ - email, - userId, - }: IAuthSignUpVerifiedEventPayload) { - // Can't continue since the Loops the api key is not configured. - if (!config.loops.apiKey) { - return; - } - const user = await SystemUser.query().findById(userId); - - const options = { - method: 'POST', - url: 'https://app.loops.so/api/v1/events/send', - headers: { - Authorization: `Bearer ${config.loops.apiKey}`, - 'Content-Type': 'application/json', - }, - data: { - email, - userId, - firstName: user.firstName, - lastName: user.lastName, - eventName: 'USER_VERIFIED', - eventProperties: {}, - mailingLists: {}, - }, - }; - await axios(options); - } -} diff --git a/packages/server/src/services/MailNotification/ContactMailNotification.ts b/packages/server/src/services/MailNotification/ContactMailNotification.ts deleted file mode 100644 index d6e8a1e04..000000000 --- a/packages/server/src/services/MailNotification/ContactMailNotification.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CommonMailOptions } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { MailTenancy } from '@/services/MailTenancy/MailTenancy'; -import { formatSmsMessage } from '@/utils'; -import { Tenant } from '@/system/models'; -import { castArray } from 'lodash'; - -@Service() -export class ContactMailNotification { - @Inject() - private mailTenancy: MailTenancy; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Gets the default mail address of the given contact. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Contact id. - * @returns {Promise>} - */ - public async getDefaultMailOptions( - tenantId: number, - customerId: number - ): Promise< - Pick - > { - const { Customer } = this.tenancy.models(tenantId); - const customer = await Customer.query() - .findById(customerId) - .throwIfNotFound(); - - const toOptions = customer.contactAddresses; - const fromOptions = await this.mailTenancy.senders(tenantId); - - const toAddress = toOptions.find((a) => a.primary); - const fromAddress = fromOptions.find((a) => a.primary); - - const to = toAddress?.mail ? castArray(toAddress?.mail) : []; - const from = fromAddress?.mail ? castArray(fromAddress?.mail) : []; - - return { to, from, toOptions, fromOptions }; - } - - /** - * Retrieves the mail options of the given contact. - * @param {number} tenantId - Tenant id. - * @returns {Promise} - */ - public async formatMailOptions( - tenantId: number, - mailOptions: CommonMailOptions, - formatterArgs?: Record - ): Promise { - const commonFormatArgs = await this.getCommonFormatArgs(tenantId); - const formatArgs = { - ...commonFormatArgs, - ...formatterArgs, - }; - const subjectFormatted = formatSmsMessage(mailOptions?.subject, formatArgs); - const messageFormatted = formatSmsMessage(mailOptions?.message, formatArgs); - - return { - ...mailOptions, - subject: subjectFormatted, - message: messageFormatted, - }; - } - - /** - * Retrieves the common format args. - * @param {number} tenantId - * @returns {Promise>} - */ - public async getCommonFormatArgs( - tenantId: number - ): Promise> { - const organization = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - return { - ['Company Name']: organization.metadata.name, - }; - } -} diff --git a/packages/server/src/services/MailNotification/constants.ts b/packages/server/src/services/MailNotification/constants.ts deleted file mode 100644 index 95b720d70..000000000 --- a/packages/server/src/services/MailNotification/constants.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const ERRORS = { - MAIL_FROM_NOT_FOUND: 'Mail from address not found', - MAIL_TO_NOT_FOUND: 'Mail to address not found', - MAIL_SUBJECT_NOT_FOUND: 'Mail subject not found', - MAIL_BODY_NOT_FOUND: 'Mail body not found', -}; diff --git a/packages/server/src/services/MailNotification/utils.ts b/packages/server/src/services/MailNotification/utils.ts deleted file mode 100644 index 63e9550ba..000000000 --- a/packages/server/src/services/MailNotification/utils.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { castArray, isEmpty } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import { CommonMailOptions } from '@/interfaces'; -import { ERRORS } from './constants'; - -/** - * Merges the mail options with incoming options. - * @param {Partial} mailOptions - * @param {Partial} overridedOptions - */ -export function parseMailOptions( - mailOptions: CommonMailOptions, - overridedOptions: Partial -): CommonMailOptions { - const mergedMessageOptions = { - ...mailOptions, - ...overridedOptions, - }; - const parsedMessageOptions = { - ...mergedMessageOptions, - from: mergedMessageOptions?.from - ? castArray(mergedMessageOptions?.from) - : [], - to: mergedMessageOptions?.to ? castArray(mergedMessageOptions?.to) : [], - cc: mergedMessageOptions?.cc ? castArray(mergedMessageOptions?.cc) : [], - bcc: mergedMessageOptions?.bcc ? castArray(mergedMessageOptions?.bcc) : [], - }; - return parsedMessageOptions; -} - -export function validateRequiredMailOptions( - mailOptions: Partial -) { - if (isEmpty(mailOptions.from)) { - throw new ServiceError(ERRORS.MAIL_FROM_NOT_FOUND); - } - if (isEmpty(mailOptions.to)) { - throw new ServiceError(ERRORS.MAIL_TO_NOT_FOUND); - } - if (isEmpty(mailOptions.subject)) { - throw new ServiceError(ERRORS.MAIL_SUBJECT_NOT_FOUND); - } - if (isEmpty(mailOptions.message)) { - throw new ServiceError(ERRORS.MAIL_BODY_NOT_FOUND); - } -} - -export const mergeAndValidateMailOptions = ( - mailOptions: CommonMailOptions, - overridedOptions: Partial -): CommonMailOptions => { - const parsedMessageOptions = parseMailOptions(mailOptions, overridedOptions); - validateRequiredMailOptions(parsedMessageOptions); - - return parsedMessageOptions; -}; diff --git a/packages/server/src/services/MailTenancy/MailTenancy.ts b/packages/server/src/services/MailTenancy/MailTenancy.ts deleted file mode 100644 index 6f8e82e11..000000000 --- a/packages/server/src/services/MailTenancy/MailTenancy.ts +++ /dev/null @@ -1,25 +0,0 @@ -import config from '@/config'; -import { Tenant } from "@/system/models"; -import { Service } from 'typedi'; - - -@Service() -export class MailTenancy { - /** - * Retrieves the senders mails of the given tenant. - * @param {number} tenantId - */ - public async senders(tenantId: number) { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - return [ - { - mail: config.mail.from, - label: tenant.metadata.name, - primary: true, - } - ].filter((item) => item.mail) - } -} \ No newline at end of file diff --git a/packages/server/src/services/ManualJournals/AutoIncrementManualJournal.ts b/packages/server/src/services/ManualJournals/AutoIncrementManualJournal.ts deleted file mode 100644 index d8d9b3665..000000000 --- a/packages/server/src/services/ManualJournals/AutoIncrementManualJournal.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService'; - -@Service() -export class AutoIncrementManualJournal { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - public autoIncrementEnabled = (tenantId: number) => { - return this.autoIncrementOrdersService.autoIncrementEnabled( - tenantId, - 'manual_journals' - ); - }; - - /** - * Retrieve the next journal number. - */ - public getNextJournalNumber = (tenantId: number): string => { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'manual_journals' - ); - }; - - /** - * Increment the manual journal number. - * @param {number} tenantId - */ - public incrementNextJournalNumber = (tenantId: number) => { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'manual_journals' - ); - }; -} diff --git a/packages/server/src/services/ManualJournals/CommandManualJournalValidators.ts b/packages/server/src/services/ManualJournals/CommandManualJournalValidators.ts deleted file mode 100644 index d165fbca9..000000000 --- a/packages/server/src/services/ManualJournals/CommandManualJournalValidators.ts +++ /dev/null @@ -1,308 +0,0 @@ -import { difference, isEmpty, round, sumBy } from 'lodash'; -import { Service, Inject } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { - IManualJournalDTO, - IManualJournalEntry, - IManualJournal, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { AutoIncrementManualJournal } from './AutoIncrementManualJournal'; - -@Service() -export class CommandManualJournalValidators { - @Inject() - private tenancy: TenancyService; - - @Inject() - private autoIncrement: AutoIncrementManualJournal; - - /** - * Validate manual journal credit and debit should be equal. - * @param {IManualJournalDTO} manualJournalDTO - */ - public valdiateCreditDebitTotalEquals(manualJournalDTO: IManualJournalDTO) { - const totalCredit = round( - sumBy(manualJournalDTO.entries, (entry) => entry.credit || 0), - 2 - ); - const totalDebit = round( - sumBy(manualJournalDTO.entries, (entry) => entry.debit || 0), - 2 - ); - if (totalCredit <= 0 || totalDebit <= 0) { - throw new ServiceError(ERRORS.CREDIT_DEBIT_NOT_EQUAL_ZERO); - } - - if (totalCredit !== totalDebit) { - throw new ServiceError(ERRORS.CREDIT_DEBIT_NOT_EQUAL); - } - } - - /** - * Validate manual entries accounts existance on the storage. - * @param {number} tenantId - - * @param {IManualJournalDTO} manualJournalDTO - - */ - public async validateAccountsExistance( - tenantId: number, - manualJournalDTO: IManualJournalDTO - ) { - const { Account } = this.tenancy.models(tenantId); - const manualAccountsIds = manualJournalDTO.entries.map((e) => e.accountId); - - const accounts = await Account.query().whereIn('id', manualAccountsIds); - - const storedAccountsIds = accounts.map((account) => account.id); - - if (difference(manualAccountsIds, storedAccountsIds).length > 0) { - throw new ServiceError(ERRORS.ACCOUNTS_IDS_NOT_FOUND); - } - } - - /** - * Validate manual journal number unique. - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - */ - public async validateManualJournalNoUnique( - tenantId: number, - journalNumber: string, - notId?: number - ) { - const { ManualJournal } = this.tenancy.models(tenantId); - const journals = await ManualJournal.query() - .where('journal_number', journalNumber) - .onBuild((builder) => { - if (notId) { - builder.whereNot('id', notId); - } - }); - if (journals.length > 0) { - throw new ServiceError( - ERRORS.JOURNAL_NUMBER_EXISTS, - 'The journal number is already exist.' - ); - } - } - - /** - * Validate accounts with contact type. - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - * @param {string} accountBySlug - * @param {string} contactType - */ - public async validateAccountWithContactType( - tenantId: number, - entriesDTO: IManualJournalEntry[], - accountBySlug: string, - contactType: string - ): Promise { - const { Account } = this.tenancy.models(tenantId); - const { contactRepository } = this.tenancy.repositories(tenantId); - - // Retrieve account meta by the given account slug. - const account = await Account.query().findOne('slug', accountBySlug); - - // Retrieve all stored contacts on the storage from contacts entries. - const storedContacts = await contactRepository.findWhereIn( - 'id', - entriesDTO - .filter((entry) => entry.contactId) - .map((entry) => entry.contactId) - ); - // Converts the stored contacts to map with id as key and entry as value. - const storedContactsMap = new Map( - storedContacts.map((contact) => [contact.id, contact]) - ); - - // Filter all entries of the given account. - const accountEntries = entriesDTO.filter( - (entry) => entry.accountId === account.id - ); - // Can't continue if there is no entry that associate to the given account. - if (accountEntries.length === 0) { - return; - } - // Filter entries that have no contact type or not equal the valid type. - const entriesNoContact = accountEntries.filter((entry) => { - const contact = storedContactsMap.get(entry.contactId); - return !contact || contact.contactService !== contactType; - }); - // Throw error in case one of entries that has invalid contact type. - if (entriesNoContact.length > 0) { - const indexes = entriesNoContact.map((e) => e.index); - - return new ServiceError(ERRORS.ENTRIES_SHOULD_ASSIGN_WITH_CONTACT, '', { - accountSlug: accountBySlug, - contactType, - indexes, - }); - } - } - - /** - * Dynamic validates accounts with contacts. - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - */ - public async dynamicValidateAccountsWithContactType( - tenantId: number, - entriesDTO: IManualJournalEntry[] - ): Promise { - return Promise.all([ - this.validateAccountWithContactType( - tenantId, - entriesDTO, - 'accounts-receivable', - 'customer' - ), - this.validateAccountWithContactType( - tenantId, - entriesDTO, - 'accounts-payable', - 'vendor' - ), - ]).then((results) => { - const metadataErrors = results - .filter((result) => result instanceof ServiceError) - .map((result: ServiceError) => result.payload); - - if (metadataErrors.length > 0) { - throw new ServiceError( - ERRORS.ENTRIES_SHOULD_ASSIGN_WITH_CONTACT, - '', - metadataErrors - ); - } - - return results; - }); - } - - /** - * Validate entries contacts existance. - * @param {number} tenantId - - * @param {IManualJournalDTO} manualJournalDTO - */ - public async validateContactsExistance( - tenantId: number, - manualJournalDTO: IManualJournalDTO - ) { - const { contactRepository } = this.tenancy.repositories(tenantId); - - // Filters the entries that have contact only. - const entriesContactPairs = manualJournalDTO.entries.filter( - (entry) => entry.contactId - ); - - if (entriesContactPairs.length > 0) { - const entriesContactsIds = entriesContactPairs.map( - (entry) => entry.contactId - ); - // Retrieve all stored contacts on the storage from contacts entries. - const storedContacts = await contactRepository.findWhereIn( - 'id', - entriesContactsIds - ); - // Converts the stored contacts to map with id as key and entry as value. - const storedContactsMap = new Map( - storedContacts.map((contact) => [contact.id, contact]) - ); - const notFoundContactsIds = []; - - entriesContactPairs.forEach((contactEntry) => { - const storedContact = storedContactsMap.get(contactEntry.contactId); - - // in case the contact id not found. - if (!storedContact) { - notFoundContactsIds.push(storedContact); - } - }); - if (notFoundContactsIds.length > 0) { - throw new ServiceError(ERRORS.CONTACTS_NOT_FOUND, '', { - contactsIds: notFoundContactsIds, - }); - } - } - } - - /** - * Validates expenses is not already published before. - * @param {IManualJournal} manualJournal - */ - public validateManualJournalIsNotPublished(manualJournal: IManualJournal) { - if (manualJournal.publishedAt) { - throw new ServiceError(ERRORS.MANUAL_JOURNAL_ALREADY_PUBLISHED); - } - } - - /** - * Validates the manual journal number require. - * @param {string} journalNumber - * @throws {ServiceError(ERRORS.MANUAL_JOURNAL_NO_REQUIRED)} - */ - public validateJournalNoRequireWhenAutoNotEnabled = ( - journalNumber: string - ) => { - if (isEmpty(journalNumber)) { - throw new ServiceError(ERRORS.MANUAL_JOURNAL_NO_REQUIRED); - } - }; - - /** - * Filters the not published manual jorunals. - * @param {IManualJournal[]} manualJournal - Manual journal. - * @return {IManualJournal[]} - */ - public getNonePublishedManualJournals( - manualJournals: IManualJournal[] - ): IManualJournal[] { - return manualJournals.filter((manualJournal) => !manualJournal.publishedAt); - } - - /** - * Filters the published manual journals. - * @param {IManualJournal[]} manualJournal - Manual journal. - * @return {IManualJournal[]} - */ - public getPublishedManualJournals( - manualJournals: IManualJournal[] - ): IManualJournal[] { - return manualJournals.filter((expense) => expense.publishedAt); - } - - /** - * - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - */ - public validateJournalCurrencyWithAccountsCurrency = async ( - tenantId: number, - manualJournalDTO: IManualJournalDTO, - baseCurrency: string - ) => { - const { Account } = this.tenancy.models(tenantId); - - const accountsIds = manualJournalDTO.entries.map((e) => e.accountId); - const accounts = await Account.query().whereIn('id', accountsIds); - - // Filters the accounts that has no base currency or DTO currency. - const notSupportedCurrency = accounts.filter((account) => { - if ( - account.currencyCode === baseCurrency || - account.currencyCode === manualJournalDTO.currencyCode - ) { - return false; - } - return true; - }); - if (notSupportedCurrency.length > 0) { - throw new ServiceError( - ERRORS.COULD_NOT_ASSIGN_DIFFERENT_CURRENCY_TO_ACCOUNTS - ); - } - }; -} diff --git a/packages/server/src/services/ManualJournals/CreateManualJournal.ts b/packages/server/src/services/ManualJournals/CreateManualJournal.ts deleted file mode 100644 index 9908f5485..000000000 --- a/packages/server/src/services/ManualJournals/CreateManualJournal.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { sumBy, omit } from 'lodash'; -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { - IManualJournalDTO, - ISystemUser, - IManualJournal, - IManualJournalEventCreatedPayload, - IManualJournalCreatingPayload, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { TenantMetadata } from '@/system/models'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandManualJournalValidators } from './CommandManualJournalValidators'; -import { AutoIncrementManualJournal } from './AutoIncrementManualJournal'; -import { ManualJournalBranchesDTOTransformer } from '@/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer'; -import { assocItemEntriesDefaultIndex } from '../Items/utils'; - -@Service() -export class CreateManualJournalService { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandManualJournalValidators; - - @Inject() - private autoIncrement: AutoIncrementManualJournal; - - @Inject() - private branchesDTOTransformer: ManualJournalBranchesDTOTransformer; - - /** - * Transform the new manual journal DTO to upsert graph operation. - * @param {IManualJournalDTO} manualJournalDTO - Manual jorunal DTO. - * @param {ISystemUser} authorizedUser - */ - private transformNewDTOToModel( - tenantId, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser, - baseCurrency: string - ) { - const amount = sumBy(manualJournalDTO.entries, 'credit') || 0; - const date = moment(manualJournalDTO.date).format('YYYY-MM-DD'); - - // Retrieve the next manual journal number. - const autoNextNumber = this.autoIncrement.getNextJournalNumber(tenantId); - - // The manual or auto-increment journal number. - const journalNumber = manualJournalDTO.journalNumber || autoNextNumber; - - const entries = R.compose( - // Associate the default index to each item entry. - assocItemEntriesDefaultIndex - )(manualJournalDTO.entries); - - const initialDTO = { - ...omit(manualJournalDTO, ['publish', 'attachments']), - ...(manualJournalDTO.publish - ? { publishedAt: moment().toMySqlDateTime() } - : {}), - amount, - date, - currencyCode: manualJournalDTO.currencyCode || baseCurrency, - exchangeRate: manualJournalDTO.exchangeRate || 1, - journalNumber, - entries, - userId: authorizedUser.id, - }; - return R.compose( - // Omits the `branchId` from entries if multiply branches feature not active. - this.branchesDTOTransformer.transformDTO(tenantId) - )(initialDTO); - } - - /** - * Authorize the manual journal creating. - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - * @param {ISystemUser} authorizedUser - */ - private authorize = async ( - tenantId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser, - baseCurrency: string - ) => { - // Validate the total credit should equals debit. - this.validator.valdiateCreditDebitTotalEquals(manualJournalDTO); - - // Validate the contacts existance. - await this.validator.validateContactsExistance(tenantId, manualJournalDTO); - - // Validate entries accounts existance. - await this.validator.validateAccountsExistance(tenantId, manualJournalDTO); - - // Validate manual journal number require when auto-increment not enabled. - this.validator.validateJournalNoRequireWhenAutoNotEnabled( - manualJournalDTO.journalNumber - ); - // Validate manual journal uniquiness on the storage. - if (manualJournalDTO.journalNumber) { - await this.validator.validateManualJournalNoUnique( - tenantId, - manualJournalDTO.journalNumber - ); - } - // Validate accounts with contact type from the given config. - await this.validator.dynamicValidateAccountsWithContactType( - tenantId, - manualJournalDTO.entries - ); - // Validates the accounts currency with journal currency. - await this.validator.validateJournalCurrencyWithAccountsCurrency( - tenantId, - manualJournalDTO, - baseCurrency - ); - }; - - /** - * Make journal entries. - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - * @param {ISystemUser} authorizedUser - */ - public makeJournalEntries = async ( - tenantId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser, - trx?: Knex.Transaction - ): Promise<{ manualJournal: IManualJournal }> => { - const { ManualJournal } = this.tenancy.models(tenantId); - - // Retrieves the tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Authorize manual journal creating. - await this.authorize( - tenantId, - manualJournalDTO, - authorizedUser, - tenantMeta.baseCurrency - ); - // Transformes the next DTO to model. - const manualJournalObj = this.transformNewDTOToModel( - tenantId, - manualJournalDTO, - authorizedUser, - tenantMeta.baseCurrency - ); - // Creates a manual journal transactions with associated transactions - // under unit-of-work envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onManualJournalCreating` event. - await this.eventPublisher.emitAsync(events.manualJournals.onCreating, { - tenantId, - manualJournalDTO, - trx, - } as IManualJournalCreatingPayload); - - // Upsert the manual journal object. - const manualJournal = await ManualJournal.query(trx).upsertGraph({ - ...manualJournalObj, - }); - // Triggers `onManualJournalCreated` event. - await this.eventPublisher.emitAsync(events.manualJournals.onCreated, { - tenantId, - manualJournal, - manualJournalId: manualJournal.id, - manualJournalDTO, - trx, - } as IManualJournalEventCreatedPayload); - - return { manualJournal }; - }, - trx - ); - }; -} diff --git a/packages/server/src/services/ManualJournals/DeleteManualJournal.ts b/packages/server/src/services/ManualJournals/DeleteManualJournal.ts deleted file mode 100644 index 1635972b7..000000000 --- a/packages/server/src/services/ManualJournals/DeleteManualJournal.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - IManualJournal, - IManualJournalEventDeletedPayload, - IManualJournalDeletingPayload, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class DeleteManualJournal { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the given manual journal - * @param {number} tenantId - * @param {number} manualJournalId - * @return {Promise} - */ - public deleteManualJournal = async ( - tenantId: number, - manualJournalId: number - ): Promise<{ - oldManualJournal: IManualJournal; - }> => { - const { ManualJournal, ManualJournalEntry } = this.tenancy.models(tenantId); - - // Validate the manual journal exists on the storage. - const oldManualJournal = await ManualJournal.query() - .findById(manualJournalId) - .throwIfNotFound(); - - // Deletes the manual journal with associated transactions under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onManualJournalDeleting` event. - await this.eventPublisher.emitAsync(events.manualJournals.onDeleting, { - tenantId, - oldManualJournal, - trx, - } as IManualJournalDeletingPayload); - - // Deletes the manual journal entries. - await ManualJournalEntry.query(trx) - .where('manualJournalId', manualJournalId) - .delete(); - - // Deletes the manual journal transaction. - await ManualJournal.query(trx).findById(manualJournalId).delete(); - - // Triggers `onManualJournalDeleted` event. - await this.eventPublisher.emitAsync(events.manualJournals.onDeleted, { - tenantId, - manualJournalId, - oldManualJournal, - trx, - } as IManualJournalEventDeletedPayload); - - return { oldManualJournal }; - }); - }; -} diff --git a/packages/server/src/services/ManualJournals/EditManualJournal.ts b/packages/server/src/services/ManualJournals/EditManualJournal.ts deleted file mode 100644 index 56ba1cf7d..000000000 --- a/packages/server/src/services/ManualJournals/EditManualJournal.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { omit, sumBy } from 'lodash'; -import moment from 'moment'; -import { - IManualJournalDTO, - ISystemUser, - IManualJournal, - IManualJournalEventEditedPayload, - IManualJournalEditingPayload, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandManualJournalValidators } from './CommandManualJournalValidators'; - -@Service() -export class EditManualJournal { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandManualJournalValidators; - - /** - * Authorize the manual journal editing. - * @param {number} tenantId - * @param {number} manualJournalId - * @param {IManualJournalDTO} manualJournalDTO - */ - private authorize = async ( - tenantId: number, - manualJournalId: number, - manualJournalDTO: IManualJournalDTO - ) => { - // Validates the total credit and debit to be equals. - this.validator.valdiateCreditDebitTotalEquals(manualJournalDTO); - - // Validate the contacts existance. - await this.validator.validateContactsExistance(tenantId, manualJournalDTO); - - // Validates entries accounts existance. - await this.validator.validateAccountsExistance(tenantId, manualJournalDTO); - - // Validates the manual journal number uniquiness. - if (manualJournalDTO.journalNumber) { - await this.validator.validateManualJournalNoUnique( - tenantId, - manualJournalDTO.journalNumber, - manualJournalId - ); - } - // Validate accounts with contact type from the given config. - await this.validator.dynamicValidateAccountsWithContactType( - tenantId, - manualJournalDTO.entries - ); - }; - - /** - * Transform the edit manual journal DTO to upsert graph operation. - * @param {IManualJournalDTO} manualJournalDTO - Manual jorunal DTO. - * @param {IManualJournal} oldManualJournal - */ - private transformEditDTOToModel = ( - manualJournalDTO: IManualJournalDTO, - oldManualJournal: IManualJournal - ) => { - const amount = sumBy(manualJournalDTO.entries, 'credit') || 0; - const date = moment(manualJournalDTO.date).format('YYYY-MM-DD'); - - return { - id: oldManualJournal.id, - ...omit(manualJournalDTO, ['publish', 'attachments']), - ...(manualJournalDTO.publish && !oldManualJournal.publishedAt - ? { publishedAt: moment().toMySqlDateTime() } - : {}), - amount, - date, - }; - }; - - /** - * Edits jouranl entries. - * @param {number} tenantId - * @param {number} manualJournalId - * @param {IMakeJournalDTO} manualJournalDTO - * @param {ISystemUser} authorizedUser - */ - public async editJournalEntries( - tenantId: number, - manualJournalId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser - ): Promise<{ - manualJournal: IManualJournal; - oldManualJournal: IManualJournal; - }> { - const { ManualJournal } = this.tenancy.models(tenantId); - - // Validates the manual journal existance on the storage. - const oldManualJournal = await ManualJournal.query() - .findById(manualJournalId) - .throwIfNotFound(); - - // Authorize manual journal editing. - await this.authorize(tenantId, manualJournalId, manualJournalDTO); - - // Transform manual journal DTO to model. - const manualJournalObj = this.transformEditDTOToModel( - manualJournalDTO, - oldManualJournal - ); - // Edits the manual journal transactions with associated transactions - // under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onManualJournalEditing` event. - await this.eventPublisher.emitAsync(events.manualJournals.onEditing, { - tenantId, - manualJournalDTO, - oldManualJournal, - trx, - } as IManualJournalEditingPayload); - - // Upserts the manual journal graph to the storage. - await ManualJournal.query(trx).upsertGraph({ - ...manualJournalObj, - }); - // Retrieve the given manual journal with associated entries after modifications. - const manualJournal = await ManualJournal.query(trx) - .findById(manualJournalId) - .withGraphFetched('entries'); - - // Triggers `onManualJournalEdited` event. - await this.eventPublisher.emitAsync(events.manualJournals.onEdited, { - tenantId, - manualJournal, - oldManualJournal, - manualJournalDTO, - trx, - } as IManualJournalEventEditedPayload); - - return { manualJournal, oldManualJournal }; - }); - } -} diff --git a/packages/server/src/services/ManualJournals/GetManualJournal.ts b/packages/server/src/services/ManualJournals/GetManualJournal.ts deleted file mode 100644 index 8be45f948..000000000 --- a/packages/server/src/services/ManualJournals/GetManualJournal.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ManualJournalTransfromer } from './ManualJournalTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetManualJournal { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve manual journal details with associated journal transactions. - * @param {number} tenantId - * @param {number} manualJournalId - */ - public getManualJournal = async ( - tenantId: number, - manualJournalId: number - ) => { - const { ManualJournal } = this.tenancy.models(tenantId); - - const manualJournal = await ManualJournal.query() - .findById(manualJournalId) - .withGraphFetched('entries.account') - .withGraphFetched('entries.contact') - .withGraphFetched('entries.branch') - .withGraphFetched('transactions') - .withGraphFetched('attachments') - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - manualJournal, - new ManualJournalTransfromer() - ); - }; -} diff --git a/packages/server/src/services/ManualJournals/GetManualJournals.ts b/packages/server/src/services/ManualJournals/GetManualJournals.ts deleted file mode 100644 index d4dd35f4d..000000000 --- a/packages/server/src/services/ManualJournals/GetManualJournals.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { - IManualJournalsFilter, - IManualJournal, - IPaginationMeta, - IFilterMeta, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { ManualJournalTransfromer } from './ManualJournalTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetManualJournals { - @Inject() - private tenancy: TenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Parses filter DTO of the manual journals list. - * @param filterDTO - */ - private parseListFilterDTO = (filterDTO) => { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - }; - - /** - * Retrieve manual journals datatable list. - * @param {number} tenantId - - * @param {IManualJournalsFilter} filter - - */ - public getManualJournals = async ( - tenantId: number, - filterDTO: IManualJournalsFilter - ): Promise<{ - manualJournals: IManualJournal[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> => { - const { ManualJournal } = this.tenancy.models(tenantId); - - // Parses filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic service. - const dynamicService = await this.dynamicListService.dynamicList( - tenantId, - ManualJournal, - filter - ); - const { results, pagination } = await ManualJournal.query() - .onBuild((builder) => { - dynamicService.buildQuery()(builder); - builder.withGraphFetched('entries.account'); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transformes the manual journals models to POJO. - const manualJournals = await this.transformer.transform( - tenantId, - results, - new ManualJournalTransfromer() - ); - - return { - manualJournals, - pagination, - filterMeta: dynamicService.getResponseMeta(), - }; - }; -} diff --git a/packages/server/src/services/ManualJournals/ManualJournalExportable.ts b/packages/server/src/services/ManualJournals/ManualJournalExportable.ts deleted file mode 100644 index 5fcdb1efc..000000000 --- a/packages/server/src/services/ManualJournals/ManualJournalExportable.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IManualJournalsFilter } from '@/interfaces'; -import { Exportable } from '../Export/Exportable'; -import { ManualJournalsApplication } from './ManualJournalsApplication'; -import { EXPORT_SIZE_LIMIT } from '../Export/constants'; - -@Service() -export class ManualJournalsExportable extends Exportable { - @Inject() - private manualJournalsApplication: ManualJournalsApplication; - - /** - * Retrieves the manual journals data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IManualJournalsFilter) { - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - } as IManualJournalsFilter; - - return this.manualJournalsApplication - .getManualJournals(tenantId, parsedQuery) - .then((output) => output.manualJournals); - } -} diff --git a/packages/server/src/services/ManualJournals/ManualJournalGLEntries.ts b/packages/server/src/services/ManualJournals/ManualJournalGLEntries.ts deleted file mode 100644 index 9f8d419fc..000000000 --- a/packages/server/src/services/ManualJournals/ManualJournalGLEntries.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { - IManualJournal, - IManualJournalEntry, - ILedgerEntry, -} from '@/interfaces'; -import { Knex } from 'knex'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ManualJournalGLEntries { - @Inject() - private ledgerStorage: LedgerStorageService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Create manual journal GL entries. - * @param {number} tenantId - * @param {number} manualJournalId - * @param {Knex.Transaction} trx - */ - public createManualJournalGLEntries = async ( - tenantId: number, - manualJournalId: number, - trx?: Knex.Transaction - ) => { - const { ManualJournal } = this.tenancy.models(tenantId); - - // Retrieves the given manual journal with associated entries. - const manualJournal = await ManualJournal.query(trx) - .findById(manualJournalId) - .withGraphFetched('entries.account'); - - // Retrieves the ledger entries of the given manual journal. - const ledger = this.getManualJournalGLedger(manualJournal); - - // Commits the given ledger on the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Edits manual journal GL entries. - * @param {number} tenantId - * @param {number} manualJournalId - * @param {Knex.Transaction} trx - */ - public editManualJournalGLEntries = async ( - tenantId: number, - manualJournalId: number, - trx?: Knex.Transaction - ) => { - // Reverts the manual journal GL entries. - await this.revertManualJournalGLEntries(tenantId, manualJournalId, trx); - - // Write the manual journal GL entries. - await this.createManualJournalGLEntries(tenantId, manualJournalId, trx); - }; - - /** - * Deletes the manual journal GL entries. - * @param {number} tenantId - * @param {number} manualJournalId - * @param {Knex.Transaction} trx - */ - public revertManualJournalGLEntries = async ( - tenantId: number, - manualJournalId: number, - trx?: Knex.Transaction - ): Promise => { - return this.ledgerStorage.deleteByReference( - tenantId, - manualJournalId, - 'Journal', - trx - ); - }; - - /** - * Retrieves the ledger of the given manual journal. - * @param {IManualJournal} manualJournal - * @returns {Ledger} - */ - private getManualJournalGLedger = (manualJournal: IManualJournal) => { - const entries = this.getManualJournalGLEntries(manualJournal); - - return new Ledger(entries); - }; - - /** - * Retrieves the common entry details of the manual journal - * @param {IManualJournal} manualJournal - * @returns {Partial} - */ - private getManualJournalCommonEntry = ( - manualJournal: IManualJournal - ): Partial => { - return { - transactionNumber: manualJournal.journalNumber, - referenceNumber: manualJournal.reference, - createdAt: manualJournal.createdAt, - date: manualJournal.date, - currencyCode: manualJournal.currencyCode, - exchangeRate: manualJournal.exchangeRate, - - transactionType: 'Journal', - transactionId: manualJournal.id, - - userId: manualJournal.userId, - }; - }; - - /** - * Retrieves the ledger entry of the given manual journal and - * its associated entry. - * @param {IManualJournal} manualJournal - - * @param {IManualJournalEntry} entry - - * @returns {ILedgerEntry} - */ - private getManualJournalEntry = R.curry( - ( - manualJournal: IManualJournal, - entry: IManualJournalEntry - ): ILedgerEntry => { - const commonEntry = this.getManualJournalCommonEntry(manualJournal); - - return { - ...commonEntry, - debit: entry.debit, - credit: entry.credit, - accountId: entry.accountId, - - contactId: entry.contactId, - note: entry.note, - - index: entry.index, - accountNormal: entry.account.accountNormal, - - branchId: entry.branchId, - projectId: entry.projectId, - }; - } - ); - - /** - * Retrieves the ledger of the given manual journal. - * @param {IManualJournal} manualJournal - * @returns {ILedgerEntry[]} - */ - private getManualJournalGLEntries = ( - manualJournal: IManualJournal - ): ILedgerEntry[] => { - const transformEntry = this.getManualJournalEntry(manualJournal); - - return manualJournal.entries.map(transformEntry).flat(); - }; -} diff --git a/packages/server/src/services/ManualJournals/ManualJournalGLEntriesSubscriber.ts b/packages/server/src/services/ManualJournals/ManualJournalGLEntriesSubscriber.ts deleted file mode 100644 index 21f921d22..000000000 --- a/packages/server/src/services/ManualJournals/ManualJournalGLEntriesSubscriber.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Inject } from 'typedi'; -import { EventSubscriber } from 'event-dispatch'; -import { - IManualJournalEventCreatedPayload, - IManualJournalEventEditedPayload, - IManualJournalEventPublishedPayload, - IManualJournalEventDeletedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { ManualJournalGLEntries } from './ManualJournalGLEntries'; -import { AutoIncrementManualJournal } from './AutoIncrementManualJournal'; - -@EventSubscriber() -export class ManualJournalWriteGLSubscriber { - @Inject() - private manualJournalGLEntries: ManualJournalGLEntries; - - @Inject() - private manualJournalAutoIncrement: AutoIncrementManualJournal; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.manualJournals.onCreated, - this.handleWriteJournalEntriesOnCreated - ); - bus.subscribe( - events.manualJournals.onCreated, - this.handleJournalNumberIncrement - ); - bus.subscribe( - events.manualJournals.onEdited, - this.handleRewriteJournalEntriesOnEdited - ); - bus.subscribe( - events.manualJournals.onPublished, - this.handleWriteJournalEntriesOnPublished - ); - bus.subscribe( - events.manualJournals.onDeleted, - this.handleRevertJournalEntries - ); - } - - /** - * Handle manual journal created event. - * @param {IManualJournalEventCreatedPayload} payload - - * @returns {Promise} - */ - private handleWriteJournalEntriesOnCreated = async ({ - tenantId, - manualJournal, - trx, - }: IManualJournalEventCreatedPayload) => { - // Ingore writing manual journal journal entries in case was not published. - if (!manualJournal.publishedAt) return; - - await this.manualJournalGLEntries.createManualJournalGLEntries( - tenantId, - manualJournal.id, - trx - ); - }; - - /** - * Handles the manual journal next number increment once the journal be created. - * @param {IManualJournalEventCreatedPayload} payload - - * @return {Promise} - */ - private handleJournalNumberIncrement = async ({ - tenantId, - }: IManualJournalEventCreatedPayload) => { - await this.manualJournalAutoIncrement.incrementNextJournalNumber(tenantId); - }; - - /** - * Handle manual journal edited event. - * @param {IManualJournalEventEditedPayload} - * @return {Promise} - */ - private handleRewriteJournalEntriesOnEdited = async ({ - tenantId, - manualJournal, - oldManualJournal, - trx, - }: IManualJournalEventEditedPayload) => { - if (manualJournal.publishedAt) { - await this.manualJournalGLEntries.editManualJournalGLEntries( - tenantId, - manualJournal.id, - trx - ); - } - }; - - /** - * Handles writing journal entries once the manula journal publish. - * @param {IManualJournalEventPublishedPayload} payload - - * @return {Promise} - */ - private handleWriteJournalEntriesOnPublished = async ({ - tenantId, - manualJournal, - trx, - }: IManualJournalEventPublishedPayload) => { - await this.manualJournalGLEntries.createManualJournalGLEntries( - tenantId, - manualJournal.id, - trx - ); - }; - - /** - * Handle manual journal deleted event. - * @param {IManualJournalEventDeletedPayload} payload - - */ - private handleRevertJournalEntries = async ({ - tenantId, - manualJournalId, - trx, - }: IManualJournalEventDeletedPayload) => { - await this.manualJournalGLEntries.revertManualJournalGLEntries( - tenantId, - manualJournalId, - trx - ); - }; -} diff --git a/packages/server/src/services/ManualJournals/ManualJournalTransformer.ts b/packages/server/src/services/ManualJournals/ManualJournalTransformer.ts deleted file mode 100644 index 84ac7e0c9..000000000 --- a/packages/server/src/services/ManualJournals/ManualJournalTransformer.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { IManualJournal } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { AttachmentTransformer } from '../Attachments/AttachmentTransformer'; - -export class ManualJournalTransfromer extends Transformer { - /** - * Include these attributes to expense object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedDate', - 'formattedPublishedAt', - 'formattedCreatedAt', - 'attachments', - ]; - }; - - /** - * Retrieve formatted journal amount. - * @param {IManualJournal} manualJournal - * @returns {string} - */ - protected formattedAmount = (manualJorunal: IManualJournal): string => { - return formatNumber(manualJorunal.amount, { - currencyCode: manualJorunal.currencyCode, - }); - }; - - /** - * Retrieve formatted date. - * @param {IManualJournal} manualJournal - * @returns {string} - */ - protected formattedDate = (manualJorunal: IManualJournal): string => { - return this.formatDate(manualJorunal.date); - }; - - /** - * Retrieve formatted created at date. - * @param {IManualJournal} manualJournal - * @returns {string} - */ - protected formattedCreatedAt = (manualJorunal: IManualJournal): string => { - return this.formatDate(manualJorunal.createdAt); - }; - - /** - * Retrieve formatted published at date. - * @param {IManualJournal} manualJournal - * @returns {string} - */ - protected formattedPublishedAt = (manualJorunal: IManualJournal): string => { - return this.formatDate(manualJorunal.publishedAt); - }; - - /** - * Retrieves the manual journal attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (manualJorunal: IManualJournal) => { - return this.item(manualJorunal.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/ManualJournals/ManualJournalsApplication.ts b/packages/server/src/services/ManualJournals/ManualJournalsApplication.ts deleted file mode 100644 index 78167c803..000000000 --- a/packages/server/src/services/ManualJournals/ManualJournalsApplication.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IManualJournalDTO, - IManualJournalsFilter, - ISystemUser, -} from '@/interfaces'; -import { CreateManualJournalService } from './CreateManualJournal'; -import { DeleteManualJournal } from './DeleteManualJournal'; -import { EditManualJournal } from './EditManualJournal'; -import { PublishManualJournal } from './PublishManualJournal'; -import { GetManualJournals } from './GetManualJournals'; -import { GetManualJournal } from './GetManualJournal'; - -@Service() -export class ManualJournalsApplication { - @Inject() - private createManualJournalService: CreateManualJournalService; - - @Inject() - private editManualJournalService: EditManualJournal; - - @Inject() - private deleteManualJournalService: DeleteManualJournal; - - @Inject() - private publishManualJournalService: PublishManualJournal; - - @Inject() - private getManualJournalsService: GetManualJournals; - - @Inject() - private getManualJournalService: GetManualJournal; - - /** - * Make journal entries. - * @param {number} tenantId - * @param {IManualJournalDTO} manualJournalDTO - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public createManualJournal = ( - tenantId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser - ) => { - return this.createManualJournalService.makeJournalEntries( - tenantId, - manualJournalDTO, - authorizedUser - ); - }; - - /** - * Edits jouranl entries. - * @param {number} tenantId - * @param {number} manualJournalId - * @param {IMakeJournalDTO} manualJournalDTO - * @param {ISystemUser} authorizedUser - */ - public editManualJournal = ( - tenantId: number, - manualJournalId: number, - manualJournalDTO: IManualJournalDTO, - authorizedUser: ISystemUser - ) => { - return this.editManualJournalService.editJournalEntries( - tenantId, - manualJournalId, - manualJournalDTO, - authorizedUser - ); - }; - - /** - * Deletes the given manual journal - * @param {number} tenantId - * @param {number} manualJournalId - * @return {Promise} - */ - public deleteManualJournal = (tenantId: number, manualJournalId: number) => { - return this.deleteManualJournalService.deleteManualJournal( - tenantId, - manualJournalId - ); - }; - - /** - * Publish the given manual journal. - * @param {number} tenantId - Tenant id. - * @param {number} manualJournalId - Manual journal id. - */ - public publishManualJournal = (tenantId: number, manualJournalId: number) => { - return this.publishManualJournalService.publishManualJournal( - tenantId, - manualJournalId - ); - }; - - /** - * Retrieves the specific manual journal. - * @param {number} tenantId - * @param {number} manualJournalId - * @returns - */ - public getManualJournal = (tenantId: number, manualJournalId: number) => { - return this.getManualJournalService.getManualJournal( - tenantId, - manualJournalId - ); - }; - - /** - * Retrieves the paginated manual journals. - * @param {number} tenantId - * @param {IManualJournalsFilter} filterDTO - * @returns - */ - public getManualJournals = ( - tenantId: number, - filterDTO: IManualJournalsFilter - ) => { - return this.getManualJournalsService.getManualJournals(tenantId, filterDTO); - }; -} diff --git a/packages/server/src/services/ManualJournals/ManualJournalsImport.ts b/packages/server/src/services/ManualJournals/ManualJournalsImport.ts deleted file mode 100644 index 1f3af74e9..000000000 --- a/packages/server/src/services/ManualJournals/ManualJournalsImport.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Inject } from 'typedi'; -import { Knex } from 'knex'; -import * as Yup from 'yup'; -import { Importable } from '../Import/Importable'; -import { CreateManualJournalService } from './CreateManualJournal'; -import { IManualJournalDTO } from '@/interfaces'; -import { ImportableContext } from '../Import/interfaces'; -import { ManualJournalsSampleData } from './constants'; - -export class ManualJournalImportable extends Importable { - @Inject() - private createManualJournalService: CreateManualJournalService; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createJournalDTO: IManualJournalDTO, - trx?: Knex.Transaction - ) { - return this.createManualJournalService.makeJournalEntries( - tenantId, - createJournalDTO, - {}, - trx - ); - } - - /** - * Transformes the DTO before passing it to importable and validation. - * @param {Record} createDTO - * @param {ImportableContext} context - * @returns {Record} - */ - public transform(createDTO: Record, context: ImportableContext) { - return createDTO; - } - - /** - * Params validation schema. - * @returns {ValidationSchema[]} - */ - public paramsValidationSchema() { - return Yup.object().shape({ - autoIncrement: Yup.boolean(), - }); - } - - /** - * Retrieves the sample data of manual journals that used to download sample sheet. - * @returns {Record} - */ - public sampleData(): Record[] { - return ManualJournalsSampleData; - } -} diff --git a/packages/server/src/services/ManualJournals/PublishManualJournal.ts b/packages/server/src/services/ManualJournals/PublishManualJournal.ts deleted file mode 100644 index d2d2de702..000000000 --- a/packages/server/src/services/ManualJournals/PublishManualJournal.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { Knex } from 'knex'; -import { - IManualJournal, - IManualJournalEventPublishedPayload, - IManualJournalPublishingPayload, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; - -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandManualJournalValidators } from './CommandManualJournalValidators'; - -@Service() -export class PublishManualJournal { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validator: CommandManualJournalValidators; - - /** - * Authorize the manual journal publishing. - * @param {number} tenantId - * @param {number} manualJournalId - */ - private authorize = (tenantId: number, oldManualJournal: IManualJournal) => { - // Validate the manual journal is not published. - this.validator.validateManualJournalIsNotPublished(oldManualJournal); - }; - - /** - * Publish the given manual journal. - * @param {number} tenantId - Tenant id. - * @param {number} manualJournalId - Manual journal id. - */ - public async publishManualJournal( - tenantId: number, - manualJournalId: number - ): Promise { - const { ManualJournal } = this.tenancy.models(tenantId); - - // Find the old manual journal or throw not found error. - const oldManualJournal = await ManualJournal.query() - .findById(manualJournalId) - .throwIfNotFound(); - - // Authorize the manual journal publishing. - await this.authorize(tenantId, oldManualJournal); - - // Publishes the manual journal with associated transactions. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onManualJournalPublishing` event. - await this.eventPublisher.emitAsync(events.manualJournals.onPublishing, { - oldManualJournal, - trx, - tenantId, - } as IManualJournalPublishingPayload); - - // Mark the given manual journal as published. - await ManualJournal.query(trx).findById(manualJournalId).patch({ - publishedAt: moment().toMySqlDateTime(), - }); - // Retrieve the manual journal with enrties after modification. - const manualJournal = await ManualJournal.query() - .findById(manualJournalId) - .withGraphFetched('entries'); - - // Triggers `onManualJournalPublishedBulk` event. - await this.eventPublisher.emitAsync(events.manualJournals.onPublished, { - tenantId, - manualJournal, - manualJournalId, - oldManualJournal, - trx, - } as IManualJournalEventPublishedPayload); - }); - } -} diff --git a/packages/server/src/services/ManualJournals/constants.ts b/packages/server/src/services/ManualJournals/constants.ts deleted file mode 100644 index e72cc11cf..000000000 --- a/packages/server/src/services/ManualJournals/constants.ts +++ /dev/null @@ -1,64 +0,0 @@ -export const ERRORS = { - NOT_FOUND: 'manual_journal_not_found', - CREDIT_DEBIT_NOT_EQUAL_ZERO: 'credit_debit_not_equal_zero', - CREDIT_DEBIT_NOT_EQUAL: 'credit_debit_not_equal', - ACCOUNTS_IDS_NOT_FOUND: 'accounts_ids_not_found', - JOURNAL_NUMBER_EXISTS: 'journal_number_exists', - ENTRIES_SHOULD_ASSIGN_WITH_CONTACT: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT', - CONTACTS_NOT_FOUND: 'contacts_not_found', - ENTRIES_CONTACTS_NOT_FOUND: 'ENTRIES_CONTACTS_NOT_FOUND', - MANUAL_JOURNAL_ALREADY_PUBLISHED: 'MANUAL_JOURNAL_ALREADY_PUBLISHED', - MANUAL_JOURNAL_NO_REQUIRED: 'MANUAL_JOURNAL_NO_REQUIRED', - COULD_NOT_ASSIGN_DIFFERENT_CURRENCY_TO_ACCOUNTS: - 'COULD_NOT_ASSIGN_DIFFERENT_CURRENCY_TO_ACCOUNTS', - MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID: - 'MANUAL_JOURNAL_ENTRIES_HAVE_NO_BRANCH_ID', -}; - -export const CONTACTS_CONFIG = [ - { - accountBySlug: 'accounts-receivable', - contactService: 'customer', - assignRequired: true, - }, - { - accountBySlug: 'accounts-payable', - contactService: 'vendor', - assignRequired: true, - }, -]; - -export const DEFAULT_VIEWS = []; - -export const ManualJournalsSampleData = [ - { - Date: '2024-02-02', - 'Journal No': 'J-100022', - 'Reference No.': 'REF-10000', - 'Currency Code': '', - 'Exchange Rate': '', - 'Journal Type': '', - Description: 'Animi quasi qui itaque aut possimus illum est magnam enim.', - Credit: 1000, - Debit: 0, - Note: 'Qui reprehenderit voluptate.', - Account: 'Bank Account', - Contact: '', - Publish: 'T', - }, - { - Date: '2024-02-02', - 'Journal No': 'J-100022', - 'Reference No.': 'REF-10000', - 'Currency Code': '', - 'Exchange Rate': '', - 'Journal Type': '', - Description: 'In assumenda dicta autem non est corrupti non et.', - Credit: 0, - Debit: 1000, - Note: 'Omnis tempora qui fugiat neque dolor voluptatem aut repudiandae nihil.', - Account: 'Bank Account', - Contact: '', - Publish: 'T', - }, -]; diff --git a/packages/server/src/services/Media/MediaService.ts b/packages/server/src/services/Media/MediaService.ts deleted file mode 100644 index 8f13cbddd..000000000 --- a/packages/server/src/services/Media/MediaService.ts +++ /dev/null @@ -1,223 +0,0 @@ -import fs from 'fs'; -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from "exceptions"; -import { IMedia, IMediaService } from '@/interfaces'; -import { difference } from 'lodash'; - -const fsPromises = fs.promises; - -const ERRORS = { - MINETYPE_NOT_SUPPORTED: 'MINETYPE_NOT_SUPPORTED', - MEDIA_NOT_FOUND: 'MEDIA_NOT_FOUND', - MODEL_NAME_HAS_NO_MEDIA: 'MODEL_NAME_HAS_NO_MEDIA', - MODEL_ID_NOT_FOUND: 'MODEL_ID_NOT_FOUND', - MEDIA_IDS_NOT_FOUND: 'MEDIA_IDS_NOT_FOUND', - MEDIA_LINK_EXISTS: 'MEDIA_LINK_EXISTS' -} -const publicPath = 'storage/app/public/'; -const attachmentsMimes = ['image/png', 'image/jpeg']; - -@Service() -export default class MediaService implements IMediaService { - @Inject('logger') - logger: any; - - @Inject() - tenancy: TenancyService; - - @Inject('repositories') - sysRepositories: any; - - /** - * Retrieve media model or throw not found error - * @param tenantId - * @param mediaId - */ - async getMediaOrThrowError(tenantId: number, mediaId: number) { - const { Media } = this.tenancy.models(tenantId); - const foundMedia = await Media.query().findById(mediaId); - - if (!foundMedia) { - throw new ServiceError(ERRORS.MEDIA_NOT_FOUND); - } - return foundMedia; - } - - /** - * Retreive media models by the given ids or throw not found error. - * @param {number} tenantId - * @param {number[]} mediaIds - */ - async getMediaByIdsOrThrowError(tenantId: number, mediaIds: number[]) { - const { Media } = this.tenancy.models(tenantId); - const foundMedia = await Media.query().whereIn('id', mediaIds); - - const storedMediaIds = foundMedia.map((m) => m.id); - const notFoundMedia = difference(mediaIds, storedMediaIds); - - if (notFoundMedia.length > 0) { - throw new ServiceError(ERRORS.MEDIA_IDS_NOT_FOUND); - } - return foundMedia; - } - - /** - * Validates the model name and id. - * @param {number} tenantId - * @param {string} modelName - * @param {number} modelId - */ - async validateModelNameAndIdExistance(tenantId: number, modelName: string, modelId: number) { - const models = this.tenancy.models(tenantId); - this.logger.info('[media] trying to validate model name and id.', { tenantId, modelName, modelId }); - - if (!models[modelName]) { - this.logger.info('[media] model name not found.', { tenantId, modelName, modelId }); - throw new ServiceError(ERRORS.MODEL_NAME_HAS_NO_MEDIA); - } - if (!models[modelName].media) { - this.logger.info('[media] model is not media-able.', { tenantId, modelName, modelId }); - throw new ServiceError(ERRORS.MODEL_NAME_HAS_NO_MEDIA); - } - - const foundModel = await models[modelName].query().findById(modelId); - - if (!foundModel) { - this.logger.info('[media] model is not found.', { tenantId, modelName, modelId }); - throw new ServiceError(ERRORS.MODEL_ID_NOT_FOUND); - } - } - - /** - * Validates the media existance. - * @param {number} tenantId - * @param {number} mediaId - * @param {number} modelId - * @param {string} modelName - */ - async validateMediaLinkExistance( - tenantId: number, - mediaId: number, - modelId: number, - modelName: string - ) { - const { MediaLink } = this.tenancy.models(tenantId); - - const foundMediaLinks = await MediaLink.query() - .where('media_id', mediaId) - .where('model_id', modelId) - .where('model_name', modelName); - - if (foundMediaLinks.length > 0) { - throw new ServiceError(ERRORS.MEDIA_LINK_EXISTS); - } - } - - /** - * Links the given media to the specific media-able model resource. - * @param {number} tenantId - * @param {number} mediaId - * @param {number} modelId - * @param {string} modelType - */ - async linkMedia(tenantId: number, mediaId: number, modelId: number, modelName: string) { - this.logger.info('[media] trying to link media.', { tenantId, mediaId, modelId, modelName }); - const { MediaLink } = this.tenancy.models(tenantId); - await this.validateMediaLinkExistance(tenantId, mediaId, modelId, modelName); - - const media = await this.getMediaOrThrowError(tenantId, mediaId); - await this.validateModelNameAndIdExistance(tenantId, modelName, modelId); - - await MediaLink.query().insert({ mediaId, modelId, modelName }); - } - - /** - * Retrieve media metadata. - * @param {number} tenantId - Tenant id. - * @param {number} mediaId - Media id. - * @return {Promise} - */ - public async getMedia(tenantId: number, mediaId: number): Promise { - this.logger.info('[media] try to get media.', { tenantId, mediaId }); - return this.getMediaOrThrowError(tenantId, mediaId); - } - - /** - * Deletes the given media. - * @param {number} tenantId - * @param {number} mediaId - * @return {Promise} - */ - public async deleteMedia(tenantId: number, mediaId: number|number[]): Promise { - const { Media, MediaLink } = this.tenancy.models(tenantId); - const { tenantRepository } = this.sysRepositories; - - this.logger.info('[media] trying to delete media.', { tenantId, mediaId }); - - const mediaIds = Array.isArray(mediaId) ? mediaId : [mediaId]; - - const tenant = await tenantRepository.findOneById(tenantId); - const media = await this.getMediaByIdsOrThrowError(tenantId, mediaIds); - - const tenantPath = `${publicPath}${tenant.organizationId}`; - const unlinkOpers = []; - - media.forEach((mediaModel) => { - const oper = fsPromises.unlink(`${tenantPath}/${mediaModel.attachmentFile}`); - unlinkOpers.push(oper); - }); - await Promise.all(unlinkOpers) - .then((resolved) => { - resolved.forEach(() => { - this.logger.info('[attachment] file has been deleted.'); - }); - }) - .catch((errors) => { - this.logger.info('[attachment] Delete item attachment file delete failed.', { errors }); - }); - await MediaLink.query().whereIn('media_id', mediaIds).delete(); - await Media.query().whereIn('id', mediaIds).delete(); - } - - /** - * Uploads the given attachment. - * @param {number} tenantId - - * @param {any} attachment - - * @return {Promise} - */ - public async upload(tenantId: number, attachment: any, modelName?: string, modelId?: number): Promise { - const { tenantRepository } = this.sysRepositories; - const { Media } = this.tenancy.models(tenantId); - - this.logger.info('[media] trying to upload media.', { tenantId }); - - const tenant = await tenantRepository.findOneById(tenantId); - const fileName = `${attachment.md5}.png`; - - // Validate the attachment. - if (attachment && attachmentsMimes.indexOf(attachment.mimetype) === -1) { - throw new ServiceError(ERRORS.MINETYPE_NOT_SUPPORTED); - } - if (modelName && modelId) { - await this.validateModelNameAndIdExistance(tenantId, modelName, modelId); - } - try { - await attachment.mv(`${publicPath}${tenant.organizationId}/${fileName}`); - this.logger.info('[attachment] uploaded successfully'); - } catch (error) { - this.logger.info('[attachment] uploading failed.', { error }); - } - const media = await Media.query().insertGraph({ - attachmentFile: `${fileName}`, - ...(modelName && modelId) ? { - links: [{ - modelName, - modelId, - }] - } : {}, - }); - this.logger.info('[media] uploaded successfully.', { tenantId, fileName, modelName, modelId }); - return media; - } -} \ No newline at end of file diff --git a/packages/server/src/services/Miscellaneous/DateFormats/constants.ts b/packages/server/src/services/Miscellaneous/DateFormats/constants.ts deleted file mode 100644 index 5ae4630c9..000000000 --- a/packages/server/src/services/Miscellaneous/DateFormats/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const DATE_FORMATS = [ - 'MM/DD/YY', - 'DD/MM/YY', - 'YY/MM/DD', - 'MM/DD/yyyy', - 'DD/MM/yyyy', - 'yyyy/MM/DD', - 'DD MMM YYYY', - 'DD MMMM YYYY', - 'MMMM DD, YYYY', -]; diff --git a/packages/server/src/services/Miscellaneous/DateFormats/index.ts b/packages/server/src/services/Miscellaneous/DateFormats/index.ts deleted file mode 100644 index 2a5bef6d3..000000000 --- a/packages/server/src/services/Miscellaneous/DateFormats/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import moment from 'moment-timezone'; -import { Service } from 'typedi'; -import { DATE_FORMATS } from './constants'; - -@Service() -export default class DateFormatsService { - getDateFormats() { - return DATE_FORMATS.map((dateFormat) => { - return { - label: `${moment().format(dateFormat)} [${dateFormat}]`, - key: dateFormat, - }; - }); - } -} diff --git a/packages/server/src/services/Miscellaneous/MiscService.ts b/packages/server/src/services/Miscellaneous/MiscService.ts deleted file mode 100644 index e24a3b3d3..000000000 --- a/packages/server/src/services/Miscellaneous/MiscService.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Service } from 'typedi'; - -@Service() -export default class MiscService { - getDateFormats() { - return []; - } -} diff --git a/packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts b/packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts deleted file mode 100644 index 687bb2032..000000000 --- a/packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { faker } from '@faker-js/faker'; -import uniqid from 'uniqid'; -import AuthenticationApplication from '../Authentication/AuthApplication'; -import OrganizationService from '../Organization/OrganizationService'; -import { OneClickDemo } from '@/system/models/OneclickDemo'; -import { SystemUser } from '@/system/models'; -import { IAuthSignInPOJO } from '@/interfaces'; -import { ICreateOneClickDemoPOJO } from './interfaces'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { defaultDemoOrganizationDTO } from './_constants'; - -@Service() -export class CreateOneClickDemo { - @Inject() - private authApp: AuthenticationApplication; - - @Inject() - private organizationService: OrganizationService; - - @Inject() - private eventPublisher: EventPublisher; - - - /** - * Creates one-click demo account. - * @returns {Promise} - */ - public async createOneClickDemo(): Promise { - const firstName = faker.person.firstName(); - const lastName = faker.person.lastName(); - const email = faker.internet.email(); - const password = '123123123'; - const demoId = uniqid(); - - await this.authApp.signUp({ firstName, lastName, email, password }); - - const signedIn = await this.authApp.signIn(email, password); - const tenantId = signedIn.tenant.id; - const userId = signedIn.user.id; - - // Creates a new one-click demo. - await OneClickDemo.query().insert({ key: demoId, tenantId, userId }); - - const buildJob = await this.organizationService.buildRunJob( - tenantId, - defaultDemoOrganizationDTO, - signedIn.user - ); - return { email, demoId, signedIn, buildJob }; - } - - /** - * Sign-in automicatlly using the demo id one creating an account finish. - * @param {string} oneClickDemoId - - * @returns {Promise} - */ - async autoSignIn(oneClickDemoId: string): Promise { - const foundOneclickDemo = await OneClickDemo.query() - .findOne('key', oneClickDemoId) - .throwIfNotFound(); - - const userId = foundOneclickDemo.userId; - const user = await SystemUser.query().findById(userId); - - const email = user.email; - const password = '123123123'; - - const signedIn = await this.authApp.signIn(email, password); - - return signedIn; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoAbstract.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoAbstract.ts deleted file mode 100644 index 54bde2d70..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoAbstract.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class SeedDemoAbstract { - /** - * Retrieves the seeder file mapping. - * @returns {Array<>} - */ - get mapping() { - return []; - } - - /** - * Retireves the seeder file import params. - * @returns {Record} - */ - get importParams() { - return {}; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoBankTransactions.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoBankTransactions.ts deleted file mode 100644 index a2c3aaa50..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoBankTransactions.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoBankTransactions extends SeedDemoAbstract { - get mapping() { - return [ - { from: 'Date', to: 'date' }, - { from: 'Payee', to: 'payee' }, - { from: 'Description', to: 'description' }, - { from: 'Reference No.', to: 'referenceNo' }, - { from: 'Amount', to: 'amount' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `bank-transactions.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'UncategorizedCashflowTransaction'; - } - - get importParams() { - return { - accountId: 1001, - }; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoCustomers.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoCustomers.ts deleted file mode 100644 index 4aeb24846..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoCustomers.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoAccountCustomers extends SeedDemoAbstract { - /** - * Retrieves the seeder file mapping. - */ - get mapping() { - return [ - { from: 'Customer Type', to: 'customerType' }, - { from: 'First Name', to: 'firstName' }, - { from: 'Last Name', to: 'lastName' }, - { from: 'Display Name', to: 'displayName' }, - { from: 'Email', to: 'email' }, - { from: 'Work Phone Number', to: 'workPhone' }, - { from: 'Personal Phone Number', to: 'personalPhone' }, - { from: 'Company Name', to: 'companyName' }, - { from: 'Website', to: 'website' }, - { from: 'Active', to: 'active' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `customers.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'Customer'; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoExpenses.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoExpenses.ts deleted file mode 100644 index 922f8b478..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoExpenses.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoAccountExpenses extends SeedDemoAbstract { - /** - * Retrieves the seeder file mapping. - */ - get mapping() { - return [ - { from: 'Payment Account', to: 'paymentAccountId' }, - { from: 'Reference No.', to: 'referenceNo' }, - { from: 'Payment Date', to: 'paymentDate' }, - { from: 'Description', to: 'description' }, - { from: 'Publish', to: 'publish' }, - { - from: 'Expense Account', - to: 'expenseAccountId', - group: 'categories', - }, - { from: 'Amount', to: 'amount', group: 'categories' }, - { from: 'Line Description', to: 'description', group: 'categories' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `Expenses.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'Expense'; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoItems.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoItems.ts deleted file mode 100644 index 00a7e9ea3..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoItems.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoAccountItems extends SeedDemoAbstract { - /** - * Retrieves the seeder file mapping. - */ - get mapping() { - return [ - { from: 'Item Type', to: 'type' }, - { from: 'Item Name', to: 'name' }, - { from: 'Item Code', to: 'code' }, - { from: 'Sellable', to: 'sellable' }, - { from: 'Purchasable', to: 'purchasable' }, - { from: 'Sell Price', to: 'sellPrice' }, - { from: 'Cost Price', to: 'costPrice' }, - { from: 'Cost Account', to: 'costAccountId' }, - { from: 'Sell Account', to: 'sellAccountId' }, - { from: 'Inventory Account', to: 'inventoryAccountId' }, - { from: 'Sell Description', to: 'sellDescription' }, - { - from: 'Purchase Description', - to: 'purchaseDescription', - }, - { from: 'Note', to: 'note' }, - { from: 'Category', to: 'category' }, - { from: 'Active', to: 'active' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `items.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'Item'; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoManualJournals.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoManualJournals.ts deleted file mode 100644 index fbf34c359..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoManualJournals.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoAccountManualJournals extends SeedDemoAbstract { - /** - * Retrieves the seeder file mapping. - */ - get mapping() { - return [ - { from: 'Date', to: 'date' }, - { from: 'Journal No', to: 'journalNumber' }, - { from: 'Reference No.', to: 'reference' }, - { from: 'Description', to: 'description' }, - { from: 'Publish', to: 'publish' }, - { from: 'Credit', to: 'credit', group: 'entries' }, - { from: 'Debit', to: 'debit', group: 'entries' }, - { from: 'Account', to: 'accountId', group: 'entries' }, - { from: 'Note', to: 'note', group: 'entries' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `manual-journals.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'ManualJournal'; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoSaleInvoices.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoSaleInvoices.ts deleted file mode 100644 index ccf2b1524..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoSaleInvoices.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoSaleInvoices extends SeedDemoAbstract { - get mapping() { - return [ - { from: 'Invoice Date', to: 'invoiceDate' }, - { from: 'Due Date', to: 'dueDate' }, - { from: 'Reference No.', to: 'referenceNo' }, - { from: 'Invoice No.', to: 'invoiceNo' }, - { from: 'Customer', to: 'customerId' }, - { from: 'Exchange Rate', to: 'exchangeRate' }, - { from: 'Invoice Message', to: 'invoiceMessage' }, - { from: 'Terms & Conditions', to: 'termsConditions' }, - { from: 'Delivered', to: 'delivered' }, - { from: 'Item', to: 'itemId', group: 'entries' }, - { from: 'Rate', to: 'rate', group: 'entries' }, - { from: 'Quantity', to: 'quantity', group: 'entries' }, - { from: 'Description', to: 'description', group: 'entries' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `sale-invoices.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'SaleInvoice'; - } -} diff --git a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoVendors.ts b/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoVendors.ts deleted file mode 100644 index 2525f08bf..000000000 --- a/packages/server/src/services/OneClickDemo/DemoSeeders/SeedDemoVendors.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { SeedDemoAbstract } from './SeedDemoAbstract'; - -export class SeedDemoAccountVendors extends SeedDemoAbstract { - /** - * Retrieves the seeder file mapping. - */ - get mapping() { - return [ - { from: 'First Name', to: 'firstName' }, - { from: 'Last Name', to: 'lastName' }, - { from: 'Display Name', to: 'displayName' }, - { from: 'Email', to: 'email' }, - { from: 'Work Phone Number', to: 'workPhone' }, - { from: 'Personal Phone Number', to: 'personalPhone' }, - { from: 'Company Name', to: 'companyName' }, - { from: 'Website', to: 'website' }, - { from: 'Active', to: 'active' }, - ]; - } - - /** - * Retrieves the seeder file name. - * @returns {string} - */ - get importFileName() { - return `vendors.csv`; - } - - /** - * Retrieve the resource name of the seeder. - * @returns {string} - */ - get resource() { - return 'Vendor'; - } -} diff --git a/packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts b/packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts deleted file mode 100644 index 6b4bb2177..000000000 --- a/packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CreateOneClickDemo } from './CreateOneClickDemo'; - -@Service() -export class OneClickDemoApplication { - @Inject() - private createOneClickDemoService: CreateOneClickDemo; - - /** - * Creates one-click demo account. - * @returns {Promise} - */ - public createOneClick() { - return this.createOneClickDemoService.createOneClickDemo(); - } - - /** - * Auto-sign-in to created demo account. - * @param {string} demoId - - * @returns {Promise} - */ - public autoSignIn(demoId: string) { - return this.createOneClickDemoService.autoSignIn(demoId); - } -} diff --git a/packages/server/src/services/OneClickDemo/_constants.ts b/packages/server/src/services/OneClickDemo/_constants.ts deleted file mode 100644 index 27faecc17..000000000 --- a/packages/server/src/services/OneClickDemo/_constants.ts +++ /dev/null @@ -1,12 +0,0 @@ - - -export const defaultDemoOrganizationDTO = { - name: 'BIGCAPITAL, INC', - baseCurrency: 'USD', - location: 'US', - language: 'en', - industry: 'Technology', - fiscalYear: 'march', - timezone: 'US/Central', - dateFormat: 'MM/DD/yyyy', -} \ No newline at end of file diff --git a/packages/server/src/services/OneClickDemo/events/SeedInitialDemoAccountData.ts b/packages/server/src/services/OneClickDemo/events/SeedInitialDemoAccountData.ts deleted file mode 100644 index 4e18f2a39..000000000 --- a/packages/server/src/services/OneClickDemo/events/SeedInitialDemoAccountData.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Inject } from 'typedi'; -import { promises as fs } from 'fs'; -import path from 'path'; -import uniqid from 'uniqid'; -import { isEmpty } from 'lodash'; -import events from '@/subscribers/events'; -import { PromisePool } from '@supercharge/promise-pool'; -import { IOrganizationBuiltEventPayload } from '@/interfaces'; -import { SeedDemoAccountItems } from '../DemoSeeders/SeedDemoItems'; -import { ImportResourceApplication } from '@/services/Import/ImportResourceApplication'; -import { getImportsStoragePath } from '@/services/Import/_utils'; -import { OneClickDemo } from '@/system/models/OneclickDemo'; -import { SeedDemoAccountCustomers } from '../DemoSeeders/SeedDemoCustomers'; -import { SeedDemoAccountVendors } from '../DemoSeeders/SeedDemoVendors'; -import { SeedDemoAccountManualJournals } from '../DemoSeeders/SeedDemoManualJournals'; -import { SeedDemoAccountExpenses } from '../DemoSeeders/SeedDemoExpenses'; -import { SeedDemoBankTransactions } from '../DemoSeeders/SeedDemoBankTransactions'; -import { SeedDemoSaleInvoices } from '../DemoSeeders/SeedDemoSaleInvoices'; - -export class SeedInitialDemoAccountDataOnOrgBuild { - @Inject() - private importApp: ImportResourceApplication; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.organization.built, - this.seedInitialDemoAccountDataOnOrgBuild.bind(this) - ); - }; - - /** - * Demo account seeder. - */ - get seedDemoAccountSeeders() { - return [ - SeedDemoAccountItems, - SeedDemoBankTransactions, - SeedDemoAccountCustomers, - SeedDemoAccountVendors, - SeedDemoAccountManualJournals, - SeedDemoSaleInvoices, - SeedDemoAccountExpenses, - ]; - } - - /** - * Initialize the seeder sheet file to the import storage first. - * @param {string} fileName - - * @returns {Promise} - */ - async initiateSeederFile(fileName: string) { - const destFileName = uniqid(); - const source = path.join(global.__views_dir, `/demo-sheets`, fileName); - const destination = path.join(getImportsStoragePath(), destFileName); - - // Use the fs.promises.copyFile method to copy the file - await fs.copyFile(source, destination); - - return destFileName; - } - - /** - * Seeds initial demo account data on organization build - * @param {IOrganizationBuildEventPayload} - */ - async seedInitialDemoAccountDataOnOrgBuild({ - tenantId, - }: IOrganizationBuiltEventPayload) { - const foundDemo = await OneClickDemo.query().findOne('tenantId', tenantId); - - // Can't continue if the found demo is not exists. - // Means that account is not demo account. - if (!foundDemo) { - return null; - } - const results = await PromisePool.for(this.seedDemoAccountSeeders) - .withConcurrency(1) - .process(async (SeedDemoAccountSeeder) => { - const seederInstance = new SeedDemoAccountSeeder(); - - // Initialize the seeder sheet file before importing. - const importFileName = await this.initiateSeederFile(seederInstance.importFileName); - - // Import the given seeder file. - const importedFile = await this.importApp.import( - tenantId, - seederInstance.resource, - importFileName, - seederInstance.importParams - ); - // Mapping the columns with resource fields. - await this.importApp.mapping( - tenantId, - importedFile.import.importId, - seederInstance.mapping - ); - await this.importApp.preview(tenantId, importedFile.import.importId); - - // Commit the imported file. - await this.importApp.process( - tenantId, - importedFile.import.importId - ); - }); - - if (!isEmpty(results.errors)) { - throw results.errors; - } - } -} diff --git a/packages/server/src/services/OneClickDemo/interfaces.ts b/packages/server/src/services/OneClickDemo/interfaces.ts deleted file mode 100644 index e2b54b167..000000000 --- a/packages/server/src/services/OneClickDemo/interfaces.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { IAuthSignInPOJO } from '@/interfaces'; - -export interface ICreateOneClickDemoPOJO { - email: string; - demoId: string; - signedIn: IAuthSignInPOJO; - buildJob: any; -} diff --git a/packages/server/src/services/Organization/OrganizationBaseCurrencyLocking.ts b/packages/server/src/services/Organization/OrganizationBaseCurrencyLocking.ts deleted file mode 100644 index ad3fd2783..000000000 --- a/packages/server/src/services/Organization/OrganizationBaseCurrencyLocking.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { isEmpty } from 'lodash'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TimeoutSettings } from 'puppeteer'; - -interface MutateBaseCurrencyLockMeta { - modelName: string; - pluralName?: string; -} - -@Service() -export default class OrganizationBaseCurrencyLocking { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieves the tenant models that have prevented mutation base currency. - */ - private getModelsPreventsMutate = (tenantId: number) => { - const Models = this.tenancy.models(tenantId); - - const filteredEntries = Object.entries(Models).filter( - ([key, Model]) => !!Model.preventMutateBaseCurrency - ); - return Object.fromEntries(filteredEntries); - }; - - /** - * Detarmines the mutation base currency model is locked. - * @param {Model} Model - * @returns {Promise} - */ - private isModelMutateLocked = async ( - Model - ): Promise => { - const validateQuery = Model.query(); - - if (typeof Model?.modifiers?.preventMutateBaseCurrency !== 'undefined') { - validateQuery.modify('preventMutateBaseCurrency'); - } else { - validateQuery.select(['id']).first(); - } - const validateResult = await validateQuery; - const isValid = !isEmpty(validateResult); - - return isValid - ? { - modelName: Model.name, - pluralName: Model.pluralName, - } - : false; - }; - - /** - * Retrieves the base currency mutation locks of the tenant models. - * @param {number} tenantId - * @returns {Promise} - */ - public async baseCurrencyMutateLocks( - tenantId: number - ): Promise { - const PreventedModels = this.getModelsPreventsMutate(tenantId); - - const opers = Object.entries(PreventedModels).map(([ModelName, Model]) => - this.isModelMutateLocked(Model) - ); - const results = await Promise.all(opers); - - return results.filter( - (result) => result !== false - ) as MutateBaseCurrencyLockMeta[]; - } - - /** - * Detarmines the base currency mutation locked. - * @param {number} tenantId - * @returns {Promise} - */ - public isBaseCurrencyMutateLocked = async (tenantId: number) => { - const locks = await this.baseCurrencyMutateLocks(tenantId); - - return !isEmpty(locks); - }; -} diff --git a/packages/server/src/services/Organization/OrganizationService.ts b/packages/server/src/services/Organization/OrganizationService.ts deleted file mode 100644 index 67c9656c8..000000000 --- a/packages/server/src/services/Organization/OrganizationService.ts +++ /dev/null @@ -1,338 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ObjectId } from 'mongodb'; -import { defaultTo, pick } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import { - IOrganizationBuildDTO, - IOrganizationBuildEventPayload, - IOrganizationBuiltEventPayload, - IOrganizationUpdateDTO, - ISystemUser, - ITenant, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import config from '../../config'; -import TenantsManager from '@/services/Tenancy/TenantsManager'; -import { Tenant } from '@/system/models'; -import OrganizationBaseCurrencyLocking from './OrganizationBaseCurrencyLocking'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { initializeTenantSettings } from '@/api/middleware/SettingsMiddleware'; -import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection'; - -@Service() -export default class OrganizationService { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenantsManager: TenantsManager; - - @Inject('agenda') - private agenda: any; - - @Inject() - private baseCurrencyMutateLocking: OrganizationBaseCurrencyLocking; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Builds the database schema and seed data of the given organization id. - * @param {srting} organizationId - * @return {Promise} - */ - public async build( - tenantId: number, - buildDTO: IOrganizationBuildDTO, - systemUser: ISystemUser - ): Promise { - const tenant = await this.getTenantOrThrowError(tenantId); - - // Throw error if the tenant is already initialized. - this.throwIfTenantInitizalized(tenant); - - // Drop the database if is already exists. - await this.tenantsManager.dropDatabaseIfExists(tenant); - - // Creates a new database. - await this.tenantsManager.createDatabase(tenant); - - // Migrate the tenant. - await this.tenantsManager.migrateTenant(tenant); - - // Migrated tenant. - const migratedTenant = await tenant.$query().withGraphFetched('metadata'); - - // Injects the given tenant IoC services. - await initalizeTenantServices(tenantId); - await initializeTenantSettings(tenantId); - - // Creates a tenancy object from given tenant model. - const tenancyContext = - this.tenantsManager.getSeedMigrationContext(migratedTenant); - - // Seed tenant. - await this.tenantsManager.seedTenant(migratedTenant, tenancyContext); - - // Throws `onOrganizationBuild` event. - await this.eventPublisher.emitAsync(events.organization.build, { - tenantId: tenant.id, - buildDTO, - systemUser, - } as IOrganizationBuildEventPayload); - - // Markes the tenant as completed builing. - await Tenant.markAsBuilt(tenantId); - await Tenant.markAsBuildCompleted(tenantId); - - // - await this.flagTenantDBBatch(tenantId); - - // Triggers the organization built event. - await this.eventPublisher.emitAsync(events.organization.built, { - tenantId: tenant.id, - } as IOrganizationBuiltEventPayload); - } - - /** - * - * @param {number} tenantId - * @param {IOrganizationBuildDTO} buildDTO - * @returns - */ - async buildRunJob( - tenantId: number, - buildDTO: IOrganizationBuildDTO, - authorizedUser: ISystemUser - ) { - const tenant = await this.getTenantOrThrowError(tenantId); - - // Throw error if the tenant is already initialized. - this.throwIfTenantInitizalized(tenant); - - // Throw error if tenant is currently building. - this.throwIfTenantIsBuilding(tenant); - - // Transformes build DTO object. - const transformedBuildDTO = this.transformBuildDTO(buildDTO); - - // Saves the tenant metadata. - await tenant.saveMetadata(transformedBuildDTO); - - // Send welcome mail to the user. - const jobMeta = await this.agenda.now('organization-setup', { - tenantId, - buildDTO, - authorizedUser, - }); - // Transformes the mangodb id to string. - const jobId = new ObjectId(jobMeta.attrs._id).toString(); - - // Markes the tenant as currently building. - await Tenant.markAsBuilding(tenantId, jobId); - - return { - nextRunAt: jobMeta.attrs.nextRunAt, - jobId: jobMeta.attrs._id, - }; - } - - /** - * Unlocks tenant build run job. - * @param {number} tenantId - * @param {number} jobId - */ - public async revertBuildRunJob(tenantId: number, jobId: string) { - await Tenant.markAsBuildCompleted(tenantId, jobId); - } - - /** - * Retrieve the current organization metadata. - * @param {number} tenantId - * @returns {Promise} - */ - public async currentOrganization(tenantId: number): Promise { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('subscriptions') - .withGraphFetched('metadata'); - - this.throwIfTenantNotExists(tenant); - - return tenant; - } - - /** - * Retrieve organization ability of mutate base currency - * @param {number} tenantId - * @returns - */ - public mutateBaseCurrencyAbility(tenantId: number) { - return this.baseCurrencyMutateLocking.baseCurrencyMutateLocks(tenantId); - } - - /** - * Updates organization information. - * @param {ITenant} tenantId - * @param {IOrganizationUpdateDTO} organizationDTO - */ - public async updateOrganization( - tenantId: number, - organizationDTO: IOrganizationUpdateDTO - ): Promise { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Throw error if the tenant not exists. - this.throwIfTenantNotExists(tenant); - - // Validate organization transactions before mutate base currency. - if (organizationDTO.baseCurrency) { - await this.validateMutateBaseCurrency( - tenant, - organizationDTO.baseCurrency, - tenant.metadata?.baseCurrency - ); - } - await tenant.saveMetadata(organizationDTO); - - if (organizationDTO.baseCurrency !== tenant.metadata?.baseCurrency) { - // Triggers `onOrganizationBaseCurrencyUpdated` event. - await this.eventPublisher.emitAsync( - events.organization.baseCurrencyUpdated, - { - tenantId, - organizationDTO, - } - ); - } - } - - /** - * Transformes build DTO object. - * @param {IOrganizationBuildDTO} buildDTO - * @returns {IOrganizationBuildDTO} - */ - private transformBuildDTO( - buildDTO: IOrganizationBuildDTO - ): IOrganizationBuildDTO { - return { - ...buildDTO, - dateFormat: defaultTo(buildDTO.dateFormat, 'DD MMM yyyy'), - }; - } - - /** - * Throw base currency mutate locked error. - */ - private throwBaseCurrencyMutateLocked() { - throw new ServiceError(ERRORS.BASE_CURRENCY_MUTATE_LOCKED); - } - - /** - * Validate mutate base currency ability. - * @param {Tenant} tenant - - * @param {string} newBaseCurrency - - * @param {string} oldBaseCurrency - - */ - private async validateMutateBaseCurrency( - tenant: Tenant, - newBaseCurrency: string, - oldBaseCurrency: string - ) { - if (tenant.isReady && newBaseCurrency !== oldBaseCurrency) { - const isLocked = - await this.baseCurrencyMutateLocking.isBaseCurrencyMutateLocked( - tenant.id - ); - - if (isLocked) { - this.throwBaseCurrencyMutateLocked(); - } - } - } - - /** - * Throws error in case the given tenant is undefined. - * @param {ITenant} tenant - */ - private throwIfTenantNotExists(tenant: ITenant) { - if (!tenant) { - throw new ServiceError(ERRORS.TENANT_NOT_FOUND); - } - } - - /** - * Throws error in case the given tenant is already initialized. - * @param {ITenant} tenant - */ - private throwIfTenantInitizalized(tenant: ITenant) { - if (tenant.builtAt) { - throw new ServiceError(ERRORS.TENANT_ALREADY_BUILT); - } - } - - /** - * Throw error if the tenant is building. - * @param {ITenant} tenant - */ - private throwIfTenantIsBuilding(tenant) { - if (tenant.buildJobId) { - throw new ServiceError(ERRORS.TENANT_IS_BUILDING); - } - } - - /** - * Retrieve tenant of throw not found error. - * @param {number} tenantId - - */ - async getTenantOrThrowError(tenantId: number): Promise { - const tenant = await Tenant.query().findById(tenantId); - - if (!tenant) { - throw new ServiceError(ERRORS.TENANT_NOT_FOUND); - } - return tenant; - } - - /** - * Adds organization database latest batch number. - * @param {number} tenantId - * @param {number} version - */ - public async flagTenantDBBatch(tenantId: number) { - await Tenant.query() - .update({ - databaseBatch: config.databaseBatch, - }) - .where({ id: tenantId }); - } - - /** - * Syncs system user to tenant user. - */ - public async syncSystemUserToTenant( - tenantId: number, - systemUser: ISystemUser - ) { - const { User, Role } = this.tenancy.models(tenantId); - - const adminRole = await Role.query().findOne('slug', 'admin'); - - await User.query().insert({ - ...pick(systemUser, [ - 'firstName', - 'lastName', - 'phoneNumber', - 'email', - 'active', - 'inviteAcceptedAt', - ]), - systemUserId: systemUser.id, - roleId: adminRole.id, - }); - } -} diff --git a/packages/server/src/services/Organization/OrganizationUpgrade.ts b/packages/server/src/services/Organization/OrganizationUpgrade.ts deleted file mode 100644 index 9155539aa..000000000 --- a/packages/server/src/services/Organization/OrganizationUpgrade.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ObjectId } from 'mongodb'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { SeedMigration } from '@/lib/Seeder/SeedMigration'; -import { Tenant } from '@/system/models'; -import { ServiceError } from '@/exceptions'; -import TenantDBManager from '@/services/Tenancy/TenantDBManager'; -import config from '../../config'; -import { ERRORS } from './constants'; -import OrganizationService from './OrganizationService'; -import TenantsManagerService from '@/services/Tenancy/TenantsManager'; - -@Service() -export default class OrganizationUpgrade { - @Inject() - private organizationService: OrganizationService; - - @Inject() - private tenantsManager: TenantsManagerService; - - @Inject('agenda') - private agenda: any; - - /** - * Upgrades the given organization database. - * @param {number} tenantId - Tenant id. - * @returns {Promise} - */ - public upgradeJob = async (tenantId: number): Promise => { - const tenant = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - // Validate tenant version. - this.validateTenantVersion(tenant); - - // Initialize the tenant. - const seedContext = this.tenantsManager.getSeedMigrationContext(tenant); - - // Database manager. - const dbManager = new TenantDBManager(); - - // Migrate the organization database schema. - await dbManager.migrate(tenant); - - // Seeds the organization database data. - await new SeedMigration(seedContext.knex, seedContext).latest(); - - // Update the organization database version. - await this.organizationService.flagTenantDBBatch(tenantId); - - // Remove the tenant job id. - await Tenant.markAsUpgraded(tenantId); - }; - - /** - * Running organization upgrade job. - * @param {number} tenantId - Tenant id. - * @return {Promise} - */ - public upgrade = async (tenantId: number): Promise<{ jobId: string }> => { - const tenant = await Tenant.query().findById(tenantId); - - // Validate tenant version. - this.validateTenantVersion(tenant); - - // Validate tenant upgrade is not running. - this.validateTenantUpgradeNotRunning(tenant); - - // Send welcome mail to the user. - const jobMeta = await this.agenda.now('organization-upgrade', { - tenantId, - }); - // Transformes the mangodb id to string. - const jobId = new ObjectId(jobMeta.attrs._id).toString(); - - // Markes the tenant as currently building. - await Tenant.markAsUpgrading(tenantId, jobId); - - return { jobId }; - }; - - /** - * Validates the given tenant version. - * @param {ITenant} tenant - */ - private validateTenantVersion(tenant) { - if (tenant.databaseBatch >= config.databaseBatch) { - throw new ServiceError(ERRORS.TENANT_DATABASE_UPGRADED); - } - } - - /** - * Validates the given tenant upgrade is not running. - * @param tenant - */ - private validateTenantUpgradeNotRunning(tenant) { - if (tenant.isUpgradeRunning) { - throw new ServiceError(ERRORS.TENANT_UPGRADE_IS_RUNNING); - } - } -} diff --git a/packages/server/src/services/Organization/constants.ts b/packages/server/src/services/Organization/constants.ts deleted file mode 100644 index a1c0bd6f7..000000000 --- a/packages/server/src/services/Organization/constants.ts +++ /dev/null @@ -1,43 +0,0 @@ -import currencies from 'js-money/lib/currency'; - -export const DATE_FORMATS = [ - 'MM.dd.yy', - 'dd.MM.yy', - 'yy.MM.dd', - 'MM.dd.yyyy', - 'dd.MM.yyyy', - 'yyyy.MM.dd', - 'MM/DD/YYYY', - 'M/D/YYYY', - 'dd MMM YYYY', - 'dd MMMM YYYY', - 'MMMM dd, YYYY', - 'EEE, MMMM dd, YYYY', -]; -export const MONTHS = [ - 'january', - 'february', - 'march', - 'april', - 'may', - 'june', - 'july', - 'august', - 'september', - 'october', - 'november', - 'december', -]; - -export const ACCEPTED_LOCALES = ['en', 'ar']; - -export const ERRORS = { - TENANT_DATABASE_UPGRADED: 'TENANT_DATABASE_UPGRADED', - TENANT_NOT_FOUND: 'tenant_not_found', - TENANT_ALREADY_BUILT: 'TENANT_ALREADY_BUILT', - TENANT_ALREADY_SEEDED: 'tenant_already_seeded', - TENANT_DB_NOT_BUILT: 'tenant_db_not_built', - TENANT_IS_BUILDING: 'TENANT_IS_BUILDING', - BASE_CURRENCY_MUTATE_LOCKED: 'BASE_CURRENCY_MUTATE_LOCKED', - TENANT_UPGRADE_IS_RUNNING: 'TENANT_UPGRADE_IS_RUNNING' -}; diff --git a/packages/server/src/services/PaymentLinks/CreateInvoiceCheckoutSession.ts b/packages/server/src/services/PaymentLinks/CreateInvoiceCheckoutSession.ts deleted file mode 100644 index e46919e47..000000000 --- a/packages/server/src/services/PaymentLinks/CreateInvoiceCheckoutSession.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { StripePaymentService } from '../StripePayment/StripePaymentService'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { ISaleInvoice } from '@/interfaces'; -import { StripeInvoiceCheckoutSessionPOJO } from '@/interfaces/StripePayment'; -import { PaymentLink } from '@/system/models'; -import { initializeTenantSettings } from '@/api/middleware/SettingsMiddleware'; -import config from '@/config'; - -const origin = 'http://localhost'; - -@Service() -export class CreateInvoiceCheckoutSession { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private stripePaymentService: StripePaymentService; - - /** - * Creates a new Stripe checkout session from the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - Sale invoice id. - * @returns {Promise} - */ - async createInvoiceCheckoutSession( - publicPaymentLinkId: string - ): Promise { - // Retrieves the payment link from the given id. - const paymentLink = await PaymentLink.query() - .findOne('linkId', publicPaymentLinkId) - .where('resourceType', 'SaleInvoice') - .throwIfNotFound(); - - const tenantId = paymentLink.tenantId; - await initializeTenantSettings(tenantId); - - const { SaleInvoice } = this.tenancy.models(tenantId); - // Retrieves the invoice from associated payment link. - const invoice = await SaleInvoice.query() - .findById(paymentLink.resourceId) - .withGraphFetched('paymentMethods') - .throwIfNotFound(); - - // It will be only one Stripe payment method associated to the invoice. - const stripePaymentMethod = invoice.paymentMethods?.find( - (method) => method.paymentIntegration?.service === 'Stripe' - ); - const stripeAccountId = stripePaymentMethod?.paymentIntegration?.accountId; - const paymentIntegrationId = stripePaymentMethod?.paymentIntegration?.id; - - // Creates checkout session for the given invoice. - const session = await this.createCheckoutSession(invoice, stripeAccountId, { - tenantId, - paymentLinkId: paymentLink.id, - }); - return { - sessionId: session.id, - publishableKey: config.stripePayment.publishableKey, - redirectTo: session.url, - }; - } - - /** - * Creates a new Stripe checkout session for the given sale invoice. - * @param {ISaleInvoice} invoice - The sale invoice for which the checkout session is created. - * @param {string} stripeAccountId - The Stripe account ID associated with the payment method. - * @returns {Promise} - The created Stripe checkout session. - */ - private createCheckoutSession( - invoice: ISaleInvoice, - stripeAccountId: string, - metadata?: Record - ) { - return this.stripePaymentService.stripe.checkout.sessions.create( - { - payment_method_types: ['card'], - line_items: [ - { - price_data: { - currency: invoice.currencyCode, - product_data: { - name: invoice.invoiceNo, - }, - unit_amount: invoice.total * 100, // Amount in cents - }, - quantity: 1, - }, - ], - mode: 'payment', - success_url: `${origin}/success`, - cancel_url: `${origin}/cancel`, - metadata: { - saleInvoiceId: invoice.id, - resource: 'SaleInvoice', - ...metadata, - }, - }, - { stripeAccount: stripeAccountId } - ); - } -} diff --git a/packages/server/src/services/PaymentLinks/GetInvoicePaymentLinkMetadata.ts b/packages/server/src/services/PaymentLinks/GetInvoicePaymentLinkMetadata.ts deleted file mode 100644 index f437869bd..000000000 --- a/packages/server/src/services/PaymentLinks/GetInvoicePaymentLinkMetadata.ts +++ /dev/null @@ -1,58 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { PaymentLink } from '@/system/models'; -import { GetInvoicePaymentLinkMetaTransformer } from '../Sales/Invoices/GetInvoicePaymentLinkTransformer'; -import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection'; - -@Service() -export class GetInvoicePaymentLinkMetadata { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the invoice sharable link meta of the link id. - * @param {number} - * @param {string} linkId - */ - async getInvoicePaymentLinkMeta(linkId: string) { - const paymentLink = await PaymentLink.query() - .findOne('linkId', linkId) - .where('resourceType', 'SaleInvoice') - .throwIfNotFound(); - - // Validate the expiry at date. - if (paymentLink.expiryAt) { - const currentDate = moment(); - const expiryDate = moment(paymentLink.expiryAt); - - if (expiryDate.isBefore(currentDate)) { - throw new ServiceError('PAYMENT_LINK_EXPIRED'); - } - } - const tenantId = paymentLink.tenantId; - await initalizeTenantServices(tenantId); - - const { SaleInvoice } = this.tenancy.models(tenantId); - - const invoice = await SaleInvoice.query() - .findById(paymentLink.resourceId) - .withGraphFetched('entries.item') - .withGraphFetched('customer') - .withGraphFetched('taxes.taxRate') - .withGraphFetched('paymentMethods.paymentIntegration') - .withGraphFetched('pdfTemplate') - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - invoice, - new GetInvoicePaymentLinkMetaTransformer() - ); - } -} diff --git a/packages/server/src/services/PaymentLinks/GetPaymentLinkInvoicePdf.ts b/packages/server/src/services/PaymentLinks/GetPaymentLinkInvoicePdf.ts deleted file mode 100644 index 41ff85c0b..000000000 --- a/packages/server/src/services/PaymentLinks/GetPaymentLinkInvoicePdf.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection'; -import { SaleInvoicePdf } from '../Sales/Invoices/SaleInvoicePdf'; -import { PaymentLink } from '@/system/models'; - -@Service() -export class GetPaymentLinkInvoicePdf { - @Inject() - private getSaleInvoicePdfService: SaleInvoicePdf; - - /** - * Retrieves the sale invoice PDF of the given payment link id. - * @param {number} tenantId - * @param {number} paymentLinkId - * @returns {Promise} - */ - async getPaymentLinkInvoicePdf( - paymentLinkId: string - ): Promise<[Buffer, string]> { - const paymentLink = await PaymentLink.query() - .findOne('linkId', paymentLinkId) - .where('resourceType', 'SaleInvoice') - .throwIfNotFound(); - - const tenantId = paymentLink.tenantId; - await initalizeTenantServices(tenantId); - - const saleInvoiceId = paymentLink.resourceId; - - return this.getSaleInvoicePdfService.saleInvoicePdf( - tenantId, - saleInvoiceId - ); - } -} diff --git a/packages/server/src/services/PaymentLinks/PaymentLinksApplication.ts b/packages/server/src/services/PaymentLinks/PaymentLinksApplication.ts deleted file mode 100644 index 6938f964b..000000000 --- a/packages/server/src/services/PaymentLinks/PaymentLinksApplication.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { GetInvoicePaymentLinkMetadata } from './GetInvoicePaymentLinkMetadata'; -import { CreateInvoiceCheckoutSession } from './CreateInvoiceCheckoutSession'; -import { StripeInvoiceCheckoutSessionPOJO } from '@/interfaces/StripePayment'; -import { GetPaymentLinkInvoicePdf } from './GetPaymentLinkInvoicePdf'; - -@Service() -export class PaymentLinksApplication { - @Inject() - private getInvoicePaymentLinkMetadataService: GetInvoicePaymentLinkMetadata; - - @Inject() - private createInvoiceCheckoutSessionService: CreateInvoiceCheckoutSession; - - @Inject() - private getPaymentLinkInvoicePdfService: GetPaymentLinkInvoicePdf; - - /** - * Retrieves the invoice payment link. - * @param {string} paymentLinkId - * @returns {} - */ - public getInvoicePaymentLink(paymentLinkId: string) { - return this.getInvoicePaymentLinkMetadataService.getInvoicePaymentLinkMeta( - paymentLinkId - ); - } - - /** - * Create the invoice payment checkout session from the given payment link id. - * @param {string} paymentLinkId - Payment link id. - * @returns {Promise} - */ - public createInvoicePaymentCheckoutSession( - paymentLinkId: string - ): Promise { - return this.createInvoiceCheckoutSessionService.createInvoiceCheckoutSession( - paymentLinkId - ); - } - - /** - * Retrieves the sale invoice pdf of the given payment link id. - * @param {number} tenantId - * @param {number} paymentLinkId - * @returns {Promise } - */ - public getPaymentLinkInvoicePdf( - paymentLinkId: string - ): Promise<[Buffer, string]> { - return this.getPaymentLinkInvoicePdfService.getPaymentLinkInvoicePdf( - paymentLinkId - ); - } -} diff --git a/packages/server/src/services/PaymentServices/DeletePaymentMethodService.ts b/packages/server/src/services/PaymentServices/DeletePaymentMethodService.ts deleted file mode 100644 index 9e0802220..000000000 --- a/packages/server/src/services/PaymentServices/DeletePaymentMethodService.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class DeletePaymentMethodService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes the given payment integration. - * @param {number} tenantId - * @param {number} paymentIntegrationId - * @returns {Promise} - */ - public async deletePaymentMethod( - tenantId: number, - paymentIntegrationId: number - ): Promise { - const { PaymentIntegration, TransactionPaymentServiceEntry } = - this.tenancy.models(tenantId); - - const paymentIntegration = await PaymentIntegration.query() - .findById(paymentIntegrationId) - .throwIfNotFound(); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Delete payment methods links. - await TransactionPaymentServiceEntry.query(trx) - .where('paymentIntegrationId', paymentIntegrationId) - .delete(); - - // Delete the payment integration. - await PaymentIntegration.query(trx) - .findById(paymentIntegrationId) - .delete(); - - // Triggers `onPaymentMethodDeleted` event. - await this.eventPublisher.emitAsync(events.paymentMethod.onDeleted, { - tenantId, - paymentIntegrationId, - }); - }); - } -} diff --git a/packages/server/src/services/PaymentServices/EditPaymentMethodService.ts b/packages/server/src/services/PaymentServices/EditPaymentMethodService.ts deleted file mode 100644 index 75a140c78..000000000 --- a/packages/server/src/services/PaymentServices/EditPaymentMethodService.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { EditPaymentMethodDTO } from './types'; -import events from '@/subscribers/events'; - -@Service() -export class EditPaymentMethodService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Edits the given payment method. - * @param {number} tenantId - * @param {number} paymentIntegrationId - * @param {EditPaymentMethodDTO} editPaymentMethodDTO - * @returns {Promise} - */ - async editPaymentMethod( - tenantId: number, - paymentIntegrationId: number, - editPaymentMethodDTO: EditPaymentMethodDTO - ): Promise { - const { PaymentIntegration } = this.tenancy.models(tenantId); - - const paymentMethod = await PaymentIntegration.query() - .findById(paymentIntegrationId) - .throwIfNotFound(); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onPaymentMethodEditing` event. - await this.eventPublisher.emitAsync(events.paymentMethod.onEditing, { - tenantId, - paymentIntegrationId, - editPaymentMethodDTO, - trx, - }); - await PaymentIntegration.query(trx) - .findById(paymentIntegrationId) - .patch({ - ...editPaymentMethodDTO, - }); - // Triggers `onPaymentMethodEdited` event. - await this.eventPublisher.emitAsync(events.paymentMethod.onEdited, { - tenantId, - paymentIntegrationId, - editPaymentMethodDTO, - trx, - }); - }); - } -} diff --git a/packages/server/src/services/PaymentServices/GetPaymentMethodsState.ts b/packages/server/src/services/PaymentServices/GetPaymentMethodsState.ts deleted file mode 100644 index 122fdcea4..000000000 --- a/packages/server/src/services/PaymentServices/GetPaymentMethodsState.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { GetPaymentMethodsPOJO } from './types'; -import config from '@/config'; -import { isStripePaymentConfigured } from './utils'; -import { GetStripeAuthorizationLinkService } from '../StripePayment/GetStripeAuthorizationLink'; - -@Service() -export class GetPaymentMethodsStateService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private getStripeAuthorizationLinkService: GetStripeAuthorizationLinkService; - - /** - * Retrieves the payment state provising state. - * @param {number} tenantId - * @returns {Promise} - */ - public async getPaymentMethodsState( - tenantId: number - ): Promise { - const { PaymentIntegration } = this.tenancy.models(tenantId); - - const stripePayment = await PaymentIntegration.query() - .orderBy('createdAt', 'ASC') - .findOne({ - service: 'Stripe', - }); - const isStripeAccountCreated = !!stripePayment; - const isStripePaymentEnabled = stripePayment?.paymentEnabled; - const isStripePayoutEnabled = stripePayment?.payoutEnabled; - const isStripeEnabled = stripePayment?.fullEnabled; - - const stripePaymentMethodId = stripePayment?.id || null; - const stripeAccountId = stripePayment?.accountId || null; - const stripePublishableKey = config.stripePayment.publishableKey; - const stripeCurrencies = ['USD', 'EUR']; - const stripeRedirectUrl = 'https://your-stripe-redirect-url.com'; - const isStripeServerConfigured = isStripePaymentConfigured(); - const stripeAuthLink = - this.getStripeAuthorizationLinkService.getStripeAuthLink(); - - const paymentMethodPOJO: GetPaymentMethodsPOJO = { - stripe: { - isStripeAccountCreated, - isStripePaymentEnabled, - isStripePayoutEnabled, - isStripeEnabled, - isStripeServerConfigured, - stripeAccountId, - stripePaymentMethodId, - stripePublishableKey, - stripeCurrencies, - stripeAuthLink, - stripeRedirectUrl, - }, - }; - return paymentMethodPOJO; - } -} diff --git a/packages/server/src/services/PaymentServices/GetPaymentService.ts b/packages/server/src/services/PaymentServices/GetPaymentService.ts deleted file mode 100644 index 35557c46a..000000000 --- a/packages/server/src/services/PaymentServices/GetPaymentService.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { GetPaymentMethodsPOJO } from './types'; - -@Service() -export class GetPaymentMethodService { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the payment state provising state. - * @param {number} tenantId - * @returns {Promise} - */ - public async getPaymentMethod( - tenantId: number, - paymentServiceId: number - ): Promise { - const { PaymentIntegration } = this.tenancy.models(tenantId); - - const stripePayment = await PaymentIntegration.query() - .findById(paymentServiceId) - .throwIfNotFound(); - - return stripePayment; - } -} diff --git a/packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoice.ts b/packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoice.ts deleted file mode 100644 index eaab16921..000000000 --- a/packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoice.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetPaymentServicesSpecificInvoiceTransformer } from './GetPaymentServicesSpecificInvoiceTransformer'; - -@Service() -export class GetPaymentServicesSpecificInvoice { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transform: TransformerInjectable; - - /** - * Retrieves the payment services of the given invoice. - * @param {number} tenantId - * @param {number} invoiceId - * @returns - */ - async getPaymentServicesInvoice(tenantId: number) { - const { PaymentIntegration } = this.tenancy.models(tenantId); - - const paymentGateways = await PaymentIntegration.query() - .modify('fullEnabled') - .orderBy('name', 'ASC'); - - return this.transform.transform( - tenantId, - paymentGateways, - new GetPaymentServicesSpecificInvoiceTransformer() - ); - } -} diff --git a/packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoiceTransformer.ts b/packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoiceTransformer.ts deleted file mode 100644 index 9ef5ca61f..000000000 --- a/packages/server/src/services/PaymentServices/GetPaymentServicesSpecificInvoiceTransformer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetPaymentServicesSpecificInvoiceTransformer extends Transformer { - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['accountId']; - }; - - public includeAttributes = (): string[] => { - return ['serviceFormatted']; - }; - - public serviceFormatted(method) { - return 'Stripe'; - } -} diff --git a/packages/server/src/services/PaymentServices/PaymentServicesApplication.ts b/packages/server/src/services/PaymentServices/PaymentServicesApplication.ts deleted file mode 100644 index b062b4bb9..000000000 --- a/packages/server/src/services/PaymentServices/PaymentServicesApplication.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { GetPaymentServicesSpecificInvoice } from './GetPaymentServicesSpecificInvoice'; -import { DeletePaymentMethodService } from './DeletePaymentMethodService'; -import { EditPaymentMethodService } from './EditPaymentMethodService'; -import { EditPaymentMethodDTO, GetPaymentMethodsPOJO } from './types'; -import { GetPaymentMethodsStateService } from './GetPaymentMethodsState'; -import { GetPaymentMethodService } from './GetPaymentService'; - -@Service() -export class PaymentServicesApplication { - @Inject() - private getPaymentServicesSpecificInvoice: GetPaymentServicesSpecificInvoice; - - @Inject() - private deletePaymentMethodService: DeletePaymentMethodService; - - @Inject() - private editPaymentMethodService: EditPaymentMethodService; - - @Inject() - private getPaymentMethodsStateService: GetPaymentMethodsStateService; - - @Inject() - private getPaymentMethodService: GetPaymentMethodService; - - /** - * Retrieves the payment services for a specific invoice. - * @param {number} tenantId - The ID of the tenant. - * @param {number} invoiceId - The ID of the invoice. - * @returns {Promise} The payment services for the specified invoice. - */ - public async getPaymentServicesForInvoice(tenantId: number): Promise { - return this.getPaymentServicesSpecificInvoice.getPaymentServicesInvoice( - tenantId - ); - } - - /** - * Retrieves specific payment service details. - * @param {number} tenantId - Tennat id. - * @param {number} paymentServiceId - Payment service id. - */ - public async getPaymentService(tenantId: number, paymentServiceId: number) { - return this.getPaymentMethodService.getPaymentMethod( - tenantId, - paymentServiceId - ); - } - - /** - * Deletes the given payment method. - * @param {number} tenantId - * @param {number} paymentIntegrationId - * @returns {Promise} - */ - public async deletePaymentMethod( - tenantId: number, - paymentIntegrationId: number - ): Promise { - return this.deletePaymentMethodService.deletePaymentMethod( - tenantId, - paymentIntegrationId - ); - } - - /** - * Edits the given payment method. - * @param {number} tenantId - * @param {number} paymentIntegrationId - * @param {EditPaymentMethodDTO} editPaymentMethodDTO - * @returns {Promise} - */ - public async editPaymentMethod( - tenantId: number, - paymentIntegrationId: number, - editPaymentMethodDTO: EditPaymentMethodDTO - ): Promise { - return this.editPaymentMethodService.editPaymentMethod( - tenantId, - paymentIntegrationId, - editPaymentMethodDTO - ); - } - - /** - * Retrieves the payment state providing state. - * @param {number} tenantId - * @returns {Promise} - */ - public async getPaymentMethodsState( - tenantId: number - ): Promise { - return this.getPaymentMethodsStateService.getPaymentMethodsState(tenantId); - } -} diff --git a/packages/server/src/services/PaymentServices/types.ts b/packages/server/src/services/PaymentServices/types.ts deleted file mode 100644 index f3ec7b41f..000000000 --- a/packages/server/src/services/PaymentServices/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -export interface EditPaymentMethodDTO { - name?: string; - options?: { - bankAccountId?: number; // bank account. - clearningAccountId?: number; // current liability. - - showVisa?: boolean; - showMasterCard?: boolean; - showDiscover?: boolean; - showAmer?: boolean; - showJcb?: boolean; - showDiners?: boolean; - }; -} - -export interface GetPaymentMethodsPOJO { - stripe: { - isStripeAccountCreated: boolean; - - isStripePaymentEnabled: boolean; - isStripePayoutEnabled: boolean; - isStripeEnabled: boolean; - - isStripeServerConfigured: boolean; - - stripeAccountId: string | null; - stripePaymentMethodId: number | null; - stripePublishableKey: string | null; - stripeAuthLink: string; - stripeCurrencies: Array; - stripeRedirectUrl: string | null; - }; -} diff --git a/packages/server/src/services/PaymentServices/utils.ts b/packages/server/src/services/PaymentServices/utils.ts deleted file mode 100644 index c8ddbc844..000000000 --- a/packages/server/src/services/PaymentServices/utils.ts +++ /dev/null @@ -1,9 +0,0 @@ -import config from '@/config'; - -export const isStripePaymentConfigured = () => { - return ( - config.stripePayment.secretKey && - config.stripePayment.publishableKey && - config.stripePayment.webhooksSecret - ); -}; diff --git a/packages/server/src/services/PdfTemplate/AssignPdfTemplateDefault.ts b/packages/server/src/services/PdfTemplate/AssignPdfTemplateDefault.ts deleted file mode 100644 index 04a7c5e4f..000000000 --- a/packages/server/src/services/PdfTemplate/AssignPdfTemplateDefault.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class AssignPdfTemplateDefault { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Assigns a default PDF template for a specific tenant. - * @param {number} tenantId - The ID of the tenant for whom the default template is being assigned. - * @param {number} templateId - The ID of the template to be set as the default. - * @returns {Promise} A promise that resolves when the operation is complete. - * @throws {Error} Throws ddan error if the specified template is not found. - */ - public async assignDefaultTemplate(tenantId: number, templateId: number) { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const oldPdfTempalte = await PdfTemplate.query() - .findById(templateId) - .throwIfNotFound(); - - return this.uow.withTransaction( - tenantId, - async (trx?: Knex.Transaction) => { - // Triggers `onPdfTemplateAssigningDefault` event. - await this.eventPublisher.emitAsync( - events.pdfTemplate.onAssigningDefault, - { - tenantId, - templateId, - } - ); - await PdfTemplate.query(trx) - .where('resource', oldPdfTempalte.resource) - .patch({ default: false }); - - await PdfTemplate.query(trx) - .findById(templateId) - .patch({ default: true }); - - // Triggers `onPdfTemplateAssignedDefault` event. - await this.eventPublisher.emitAsync( - events.pdfTemplate.onAssignedDefault, - { - tenantId, - templateId, - } - ); - } - ); - } -} diff --git a/packages/server/src/services/PdfTemplate/BrandingTemplateDTOTransformer.ts b/packages/server/src/services/PdfTemplate/BrandingTemplateDTOTransformer.ts deleted file mode 100644 index 54b97708c..000000000 --- a/packages/server/src/services/PdfTemplate/BrandingTemplateDTOTransformer.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { isNil } from 'lodash'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export class BrandingTemplateDTOTransformer { - @Inject() - private tenancy: HasTenancyService; - - /** - * Associates the default branding template id. - * @param {number} tenantId - * @param {string} resource - * @param {Record} object - * @param {string} attributeName - * @returns - */ - public assocDefaultBrandingTemplate = - (tenantId: number, resource: string) => - async (object: Record) => { - const { PdfTemplate } = this.tenancy.models(tenantId); - const attributeName = 'pdfTemplateId'; - - const defaultTemplate = await PdfTemplate.query() - .modify('default') - .findOne({ resource }); - - // If the default template is not found OR the given object has no defined template id. - if (!defaultTemplate || !isNil(object[attributeName])) { - return object; - } - return { - ...object, - [attributeName]: defaultTemplate.id, - }; - }; -} diff --git a/packages/server/src/services/PdfTemplate/CreatePdfTemplate.ts b/packages/server/src/services/PdfTemplate/CreatePdfTemplate.ts deleted file mode 100644 index a437b163c..000000000 --- a/packages/server/src/services/PdfTemplate/CreatePdfTemplate.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICreateInvoicePdfTemplateDTO } from './types'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class CreatePdfTemplate { - @Inject() - private tennacy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates a new pdf template. - * @param {number} tenantId - * @param {ICreateInvoicePdfTemplateDTO} invoiceTemplateDTO - */ - public createPdfTemplate( - tenantId: number, - templateName: string, - resource: string, - invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO - ) { - const { PdfTemplate } = this.tennacy.models(tenantId); - const attributes = invoiceTemplateDTO; - - return this.uow.withTransaction(tenantId, async (trx) => { - // Triggers `onPdfTemplateCreating` event. - await this.eventPublisher.emitAsync(events.pdfTemplate.onCreating, { - tenantId, - }); - - const pdfTemplate = await PdfTemplate.query(trx).insert({ - templateName, - resource, - attributes, - }); - // Triggers `onPdfTemplateCreated` event. - await this.eventPublisher.emitAsync(events.pdfTemplate.onCreated, { - tenantId, - }); - return pdfTemplate; - }); - } -} diff --git a/packages/server/src/services/PdfTemplate/DeletePdfTemplate.ts b/packages/server/src/services/PdfTemplate/DeletePdfTemplate.ts deleted file mode 100644 index 246d12636..000000000 --- a/packages/server/src/services/PdfTemplate/DeletePdfTemplate.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './types'; - -@Service() -export class DeletePdfTemplate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes a pdf template. - * @param {number} tenantId - * @param {number} templateId - Pdf template id. - */ - public async deletePdfTemplate(tenantId: number, templateId: number) { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const oldPdfTemplate = await PdfTemplate.query() - .findById(templateId) - .throwIfNotFound(); - - // Cannot delete the predefined pdf templates. - if (oldPdfTemplate.predefined) { - throw new ServiceError(ERRORS.CANNOT_DELETE_PREDEFINED_PDF_TEMPLATE); - } - return this.uow.withTransaction(tenantId, async (trx) => { - // Triggers `onPdfTemplateDeleting` event. - await this.eventPublisher.emitAsync(events.pdfTemplate.onDeleting, { - tenantId, - templateId, - oldPdfTemplate, - trx, - }); - await PdfTemplate.query(trx).deleteById(templateId); - - // Triggers `onPdfTemplateDeleted` event. - await this.eventPublisher.emitAsync(events.pdfTemplate.onDeleted, { - tenantId, - templateId, - oldPdfTemplate, - trx, - }); - }); - } -} diff --git a/packages/server/src/services/PdfTemplate/EditPdfTemplate.ts b/packages/server/src/services/PdfTemplate/EditPdfTemplate.ts deleted file mode 100644 index 1436e4af5..000000000 --- a/packages/server/src/services/PdfTemplate/EditPdfTemplate.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IEditPdfTemplateDTO } from './types'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class EditPdfTemplate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Edits an existing pdf template. - * @param {number} tenantId - * @param {number} templateId - Template id. - * @param {IEditPdfTemplateDTO} editTemplateDTO - */ - public async editPdfTemplate( - tenantId: number, - templateId: number, - editTemplateDTO: IEditPdfTemplateDTO - ) { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const oldPdfTemplate = await PdfTemplate.query() - .findById(templateId) - .throwIfNotFound(); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onPdfTemplateEditing` event. - await this.eventPublisher.emitAsync(events.pdfTemplate.onEditing, { - tenantId, - templateId, - }); - const pdfTemplate = await PdfTemplate.query(trx) - .where('id', templateId) - .update({ - templateName: editTemplateDTO.templateName, - attributes: editTemplateDTO.attributes, - }); - - // Triggers `onPdfTemplatedEdited` event. - await this.eventPublisher.emitAsync(events.pdfTemplate.onEdited, { - tenantId, - templateId, - }); - return pdfTemplate; - }); - } -} diff --git a/packages/server/src/services/PdfTemplate/GetOrganizationBrandingAttributes.ts b/packages/server/src/services/PdfTemplate/GetOrganizationBrandingAttributes.ts deleted file mode 100644 index 989bc0714..000000000 --- a/packages/server/src/services/PdfTemplate/GetOrganizationBrandingAttributes.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Service } from 'typedi'; -import { TenantMetadata } from '@/system/models'; -import { CommonOrganizationBrandingAttributes } from './types'; - -@Service() -export class GetOrganizationBrandingAttributes { - /** - * Retrieves the given organization branding attributes initial state. - * @param {number} tenantId - * @returns {Promise} - */ - async getOrganizationBrandingAttributes( - tenantId: number - ): Promise { - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - const companyName = tenantMetadata?.name; - const primaryColor = tenantMetadata?.primaryColor; - const companyLogoKey = tenantMetadata?.logoKey; - const companyLogoUri = tenantMetadata?.logoUri; - const companyAddress = tenantMetadata?.addressTextFormatted; - - return { - companyName, - companyAddress, - companyLogoUri, - companyLogoKey, - primaryColor, - }; - } -} diff --git a/packages/server/src/services/PdfTemplate/GetPdfTemplate.ts b/packages/server/src/services/PdfTemplate/GetPdfTemplate.ts deleted file mode 100644 index feaa402a2..000000000 --- a/packages/server/src/services/PdfTemplate/GetPdfTemplate.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { GetPdfTemplateTransformer } from './GetPdfTemplateTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetPdfTemplate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable - - /** - * Retrieves a pdf template by its ID. - * @param {number} tenantId - The ID of the tenant. - * @param {number} templateId - The ID of the pdf template to retrieve. - * @return {Promise} - The retrieved pdf template. - */ - async getPdfTemplate( - tenantId: number, - templateId: number, - trx?: Knex.Transaction - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const template = await PdfTemplate.query(trx) - .findById(templateId) - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - template, - new GetPdfTemplateTransformer() - ); - } -} diff --git a/packages/server/src/services/PdfTemplate/GetPdfTemplateBrandingState.ts b/packages/server/src/services/PdfTemplate/GetPdfTemplateBrandingState.ts deleted file mode 100644 index 358bb747e..000000000 --- a/packages/server/src/services/PdfTemplate/GetPdfTemplateBrandingState.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { GetOrganizationBrandingAttributes } from './GetOrganizationBrandingAttributes'; - -@Service() -export class GetPdfTemplateBrandingState { - @Inject() - private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; - - getBrandingState(tenantId: number) { - const brandingAttributes = - this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(tenantId); - - return brandingAttributes; - } -} diff --git a/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts b/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts deleted file mode 100644 index 5d7470018..000000000 --- a/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { getTransactionTypeLabel } from '@/utils/transactions-types'; - -export class GetPdfTemplateTransformer extends Transformer { - /** - * Included attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return ['createdAtFormatted', 'resourceFormatted', 'attributes']; - }; - - /** - * Formats the creation date of the PDF template. - * @param {Object} template - * @returns {string} A formatted string representing the creation date of the template. - */ - protected createdAtFormatted = (template) => { - return this.formatDate(template.createdAt); - }; - - /** - * Formats the creation date of the PDF template. - * @param {Object} template - - * @returns {string} A formatted string representing the creation date of the template. - */ - protected resourceFormatted = (template) => { - return getTransactionTypeLabel(template.resource); - }; - - /** - * Retrieves transformed brand attributes. - * @param {} template - * @returns - */ - protected attributes = (template) => { - return this.item( - template.attributes, - new GetPdfTemplateAttributesTransformer() - ); - }; -} - -class GetPdfTemplateAttributesTransformer extends Transformer { - /** - * Included attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return []; - }; -} diff --git a/packages/server/src/services/PdfTemplate/GetPdfTemplates.ts b/packages/server/src/services/PdfTemplate/GetPdfTemplates.ts deleted file mode 100644 index ba6d7cdaa..000000000 --- a/packages/server/src/services/PdfTemplate/GetPdfTemplates.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { GetPdfTemplatesTransformer } from './GetPdfTemplatesTransformer'; -import { Inject, Service } from 'typedi'; - -@Service() -export class GetPdfTemplates { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformInjectable: TransformerInjectable; - - /** - * Retrieves a list of PDF templates for a specified tenant. - * @param {number} tenantId - The ID of the tenant for which to retrieve templates. - * @param {Object} [query] - Optional query parameters to filter the templates. - * @param {string} [query.resource] - The resource type to filter the templates by. - * @returns {Promise} - A promise that resolves to the transformed list of PDF templates. - */ - async getPdfTemplates(tenantId: number, query?: { resource?: string }) { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const templates = await PdfTemplate.query().onBuild((q) => { - if (query?.resource) { - q.where('resource', query?.resource); - } - q.orderBy('createdAt', 'ASC'); - }); - - return this.transformInjectable.transform( - tenantId, - templates, - new GetPdfTemplatesTransformer() - ); - } -} diff --git a/packages/server/src/services/PdfTemplate/GetPdfTemplatesTransformer.ts b/packages/server/src/services/PdfTemplate/GetPdfTemplatesTransformer.ts deleted file mode 100644 index 1b6904752..000000000 --- a/packages/server/src/services/PdfTemplate/GetPdfTemplatesTransformer.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { getTransactionTypeLabel } from '@/utils/transactions-types'; - -export class GetPdfTemplatesTransformer extends Transformer { - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['attributes']; - }; - - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return ['createdAtFormatted', 'resourceFormatted']; - }; - - /** - * Formats the creation date of the PDF template. - * @param {Object} template - * @returns {string} A formatted string representing the creation date of the template. - */ - protected createdAtFormatted = (template) => { - return this.formatDate(template.createdAt); - }; - - /** - * Formats the creation date of the PDF template. - * @param {Object} template - - * @returns {string} A formatted string representing the creation date of the template. - */ - protected resourceFormatted = (template) => { - return getTransactionTypeLabel(template.resource); - }; -} diff --git a/packages/server/src/services/PdfTemplate/PdfTemplateApplication.ts b/packages/server/src/services/PdfTemplate/PdfTemplateApplication.ts deleted file mode 100644 index e9ff586af..000000000 --- a/packages/server/src/services/PdfTemplate/PdfTemplateApplication.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICreateInvoicePdfTemplateDTO, IEditPdfTemplateDTO } from './types'; -import { CreatePdfTemplate } from './CreatePdfTemplate'; -import { DeletePdfTemplate } from './DeletePdfTemplate'; -import { GetPdfTemplate } from './GetPdfTemplate'; -import { GetPdfTemplates } from './GetPdfTemplates'; -import { EditPdfTemplate } from './EditPdfTemplate'; -import { AssignPdfTemplateDefault } from './AssignPdfTemplateDefault'; -import { GetPdfTemplateBrandingState } from './GetPdfTemplateBrandingState'; - -@Service() -export class PdfTemplateApplication { - @Inject() - private createPdfTemplateService: CreatePdfTemplate; - - @Inject() - private deletePdfTemplateService: DeletePdfTemplate; - - @Inject() - private getPdfTemplateService: GetPdfTemplate; - - @Inject() - private getPdfTemplatesService: GetPdfTemplates; - - @Inject() - private editPdfTemplateService: EditPdfTemplate; - - @Inject() - private assignPdfTemplateDefaultService: AssignPdfTemplateDefault; - - @Inject() - private getPdfTemplateBrandingStateService: GetPdfTemplateBrandingState; - - /** - * Creates a new PDF template. - * @param {number} tenantId - - * @param {string} templateName - The name of the PDF template to create. - * @param {string} resource - The resource type associated with the PDF template. - * @param {ICreateInvoicePdfTemplateDTO} invoiceTemplateDTO - The data transfer object containing the details for the new PDF template. - * @returns {Promise} - */ - public async createPdfTemplate( - tenantId: number, - templateName: string, - resource: string, - invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO - ) { - return this.createPdfTemplateService.createPdfTemplate( - tenantId, - templateName, - resource, - invoiceTemplateDTO - ); - } - - /** - * Edits an existing PDF template. - * @param {number} tenantId - The ID of the tenant. - * @param {number} templateId - The ID of the PDF template to edit. - * @param {IEditPdfTemplateDTO} editTemplateDTO - The data transfer object containing the updated details for the PDF template. - * @returns {Promise} - */ - public async editPdfTemplate( - tenantId: number, - templateId: number, - editTemplateDTO: IEditPdfTemplateDTO - ) { - return this.editPdfTemplateService.editPdfTemplate( - tenantId, - templateId, - editTemplateDTO - ); - } - - /** - * Deletes a PDF template. - * @param {number} tenantId - The ID of the tenant. - * @param {number} templateId - The ID of the PDF template to delete. - * @returns {Promise} - */ - - public async deletePdfTemplate(tenantId: number, templateId: number) { - return this.deletePdfTemplateService.deletePdfTemplate( - tenantId, - templateId - ); - } - - /** - * Retrieves a PDF template by its ID for a specified tenant. - * @param {number} tenantId - - * @param {number} templateId - The ID of the PDF template to retrieve. - * @returns {Promise} - */ - public async getPdfTemplate(tenantId: number, templateId: number) { - return this.getPdfTemplateService.getPdfTemplate(tenantId, templateId); - } - - /** - * Retrieves a list of PDF templates. - * @param {number} tenantId - The ID of the tenant for which to retrieve templates. - * @param {Object} query - * @returns {Promise} - */ - public async getPdfTemplates( - tenantId: number, - query?: { resource?: string } - ) { - return this.getPdfTemplatesService.getPdfTemplates(tenantId, query); - } - - /** - * Assigns a PDF template as the default template. - * @param {number} tenantId - * @param {number} templateId - The ID of the PDF template to assign as default. - * @returns {Promise} - */ - public async assignPdfTemplateAsDefault( - tenantId: number, - templateId: number - ) { - return this.assignPdfTemplateDefaultService.assignDefaultTemplate( - tenantId, - templateId - ); - } - - /** - * - * @param {number} tenantId - */ - public async getPdfTemplateBrandingState(tenantId: number) { - return this.getPdfTemplateBrandingStateService.getBrandingState(tenantId); - } -} diff --git a/packages/server/src/services/PdfTemplate/types.ts b/packages/server/src/services/PdfTemplate/types.ts deleted file mode 100644 index de1029afa..000000000 --- a/packages/server/src/services/PdfTemplate/types.ts +++ /dev/null @@ -1,75 +0,0 @@ -export enum ERRORS { - CANNOT_DELETE_PREDEFINED_PDF_TEMPLATE = 'CANNOT_DELETE_PREDEFINED_PDF_TEMPLATE', -} - -export interface IEditPdfTemplateDTO { - templateName: string; - attributes: Record; -} - -export interface ICreateInvoicePdfTemplateDTO { - // Colors - primaryColor?: string; - secondaryColor?: string; - - // Company Logo - showCompanyLogo?: boolean; - companyLogo?: string; - - // Top details. - showInvoiceNumber?: boolean; - invoiceNumberLabel?: string; - - showDateIssue?: boolean; - dateIssueLabel?: string; - - showDueDate?: boolean; - dueDateLabel?: string; - - // Company name - companyName?: string; - - // Addresses - showBilledFromAddress?: boolean; - showBillingToAddress?: boolean; - billedToLabel?: string; - - // Entries - itemNameLabel?: string; - itemDescriptionLabel?: string; - itemRateLabel?: string; - itemTotalLabel?: string; - - // Totals - showSubtotal?: boolean; - subtotalLabel?: string; - - showDiscount?: boolean; - discountLabel?: string; - - showTaxes?: boolean; - - showTotal?: boolean; - totalLabel?: string; - - paymentMadeLabel?: string; - showPaymentMade?: boolean; - - dueAmountLabel?: string; - showDueAmount?: boolean; - - // Footer paragraphs. - termsConditionsLabel?: string; - showTermsConditions?: boolean; - - statementLabel?: string; - showStatement?: boolean; -} - -export interface CommonOrganizationBrandingAttributes { - companyName?: string; - primaryColor?: string; - companyLogoKey?: string; - companyLogoUri?: string; - companyAddress?: string; -} diff --git a/packages/server/src/services/Projects/Projects/CreateProject.ts b/packages/server/src/services/Projects/Projects/CreateProject.ts deleted file mode 100644 index 5199524cf..000000000 --- a/packages/server/src/services/Projects/Projects/CreateProject.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IProjectCreatedEventPayload, - IProjectCreateDTO, - IProjectCreatePOJO, - IProjectCreatingEventPayload, - IProjectStatus, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { ProjectsValidator } from './ProjectsValidator'; -import events from '@/subscribers/events'; - -@Service() -export default class CreateProject { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private validator: ProjectsValidator; - - /** - * Creates a new credit note. - * @param {IProjectCreateDTO} creditNoteDTO - */ - public createProject = async ( - tenantId: number, - projectDTO: IProjectCreateDTO - ): Promise => { - const { Project } = this.tenancy.models(tenantId); - - // Validate customer existance. - await this.validator.validateContactExists(tenantId, projectDTO.contactId); - - // Triggers `onProjectCreate` event. - await this.eventPublisher.emitAsync(events.project.onCreate, { - tenantId, - projectDTO, - } as IProjectCreatedEventPayload); - - // Creates a new project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectCreating` event. - await this.eventPublisher.emitAsync(events.project.onCreating, { - tenantId, - projectDTO, - trx, - } as IProjectCreatingEventPayload); - - // Upsert the project object. - const project = await Project.query(trx).upsertGraph({ - ...projectDTO, - status: IProjectStatus.InProgress, - }); - // Triggers `onProjectCreated` event. - await this.eventPublisher.emitAsync(events.project.onCreated, { - tenantId, - projectDTO, - project, - trx, - } as IProjectCreatedEventPayload); - - return project; - }); - }; -} diff --git a/packages/server/src/services/Projects/Projects/DeleteProject.ts b/packages/server/src/services/Projects/Projects/DeleteProject.ts deleted file mode 100644 index 193866fcf..000000000 --- a/packages/server/src/services/Projects/Projects/DeleteProject.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IProjectDeletedEventPayload, - IProjectDeleteEventPayload, - IProjectDeletingEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export default class DeleteProject { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes the give project. - * @param {number} projectId - - * @returns {Promise} - */ - public deleteProject = async (tenantId: number, projectId: number) => { - const { Project } = this.tenancy.models(tenantId); - - // Triggers `onProjectDelete` event. - await this.eventPublisher.emitAsync(events.project.onDelete, { - tenantId, - projectId, - } as IProjectDeleteEventPayload); - - // Validate customer existance. - const oldProject = await Project.query().findById(projectId).throwIfNotFound(); - - // Deletes the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectDeleting` event. - await this.eventPublisher.emitAsync(events.project.onDeleting, { - tenantId, - oldProject, - trx, - } as IProjectDeletingEventPayload); - - // Deletes the project from the storage. - await Project.query(trx).findById(projectId).delete(); - - // Triggers `onProjectDeleted` event. - await this.eventPublisher.emitAsync(events.project.onDeleted, { - tenantId, - oldProject, - trx, - } as IProjectDeletedEventPayload); - }); - }; -} diff --git a/packages/server/src/services/Projects/Projects/EditProject.ts b/packages/server/src/services/Projects/Projects/EditProject.ts deleted file mode 100644 index 0e64f9016..000000000 --- a/packages/server/src/services/Projects/Projects/EditProject.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IProjectEditDTO, - IProjectEditedEventPayload, - IProjectEditEventPayload, - IProjectEditingEventPayload, - IProjectEditPOJO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { ProjectsValidator } from './ProjectsValidator'; - -@Service() -export default class EditProjectService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private projectsValidator: ProjectsValidator; - - /** - * Edits a new credit note. - * @param {number} tenantId - - * @param {number} projectId - - * @param {IProjectEditDTO} projectDTO - - */ - public editProject = async ( - tenantId: number, - projectId: number, - projectDTO: IProjectEditDTO - ): Promise => { - const { Project } = this.tenancy.models(tenantId); - - // Validate customer existance. - const oldProject = await Project.query().findById(projectId).throwIfNotFound(); - - // Validate the project's contact id existance. - if (oldProject.contactId !== projectDTO.contactId) { - await this.projectsValidator.validateContactExists( - tenantId, - projectDTO.contactId - ); - } - // Triggers `onProjectEdit` event. - await this.eventPublisher.emitAsync(events.project.onEdit, { - tenantId, - oldProject, - projectDTO, - } as IProjectEditEventPayload); - - // Edits the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectEditing` event. - await this.eventPublisher.emitAsync(events.project.onEditing, { - tenantId, - projectDTO, - oldProject, - trx, - } as IProjectEditingEventPayload); - - // Upsert the project object. - const project = await Project.query(trx).upsertGraph({ - id: projectId, - ...projectDTO, - }); - // Triggers `onProjectEdited` event. - await this.eventPublisher.emitAsync(events.project.onEdited, { - tenantId, - oldProject, - project, - projectDTO, - trx, - } as IProjectEditedEventPayload); - - return project; - }); - }; -} diff --git a/packages/server/src/services/Projects/Projects/EditProjectStatus.ts b/packages/server/src/services/Projects/Projects/EditProjectStatus.ts deleted file mode 100644 index 3d2826c16..000000000 --- a/packages/server/src/services/Projects/Projects/EditProjectStatus.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { IProjectStatus } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export default class EditProjectStatusService { - @Inject() - uow: UnitOfWork; - - @Inject() - tenancy: HasTenancyService; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Edits a new credit note. - * @param {number} projectId - - * @param {IProjectStatus} status - - */ - public editProjectStatus = async ( - tenantId: number, - projectId: number, - status: IProjectStatus - ) => { - const { Project } = this.tenancy.models(tenantId); - - // Validate customer existance. - const oldProject = await Project.query() - .findById(projectId) - .throwIfNotFound(); - - // Edits the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Upsert the project object. - const project = await Project.query(trx).upsertGraph({ - id: projectId, - status, - }); - return project; - }); - }; -} diff --git a/packages/server/src/services/Projects/Projects/GetProject.ts b/packages/server/src/services/Projects/Projects/GetProject.ts deleted file mode 100644 index b7770b03c..000000000 --- a/packages/server/src/services/Projects/Projects/GetProject.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { IProjectGetPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ProjectDetailedTransformer } from './ProjectDetailedTransformer'; - -@Service() -export default class GetProject { - @Inject() - tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the project. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getProject = async ( - tenantId: number, - projectId: number - ): Promise => { - const { Project } = this.tenancy.models(tenantId); - - // Retrieve the project. - const project = await Project.query() - .findById(projectId) - .withGraphFetched('contact') - .modify('totalExpensesDetails') - .modify('totalBillsDetails') - .modify('totalTasksDetails') - .throwIfNotFound(); - - // Transformes and returns object. - return this.transformer.transform( - tenantId, - project, - new ProjectDetailedTransformer() - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/GetProjectBillableEntries.ts b/packages/server/src/services/Projects/Projects/GetProjectBillableEntries.ts deleted file mode 100644 index 443b82909..000000000 --- a/packages/server/src/services/Projects/Projects/GetProjectBillableEntries.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { flatten, includes, isEmpty } from 'lodash'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ProjectBillableBillTransformer } from './ProjectBillableBillTransformer'; -import { ProjectBillableExpenseTransformer } from './ProjectBillableExpenseTransformer'; -import { ProjectBillableTaskTransformer } from './ProjectBillableTaskTransformer'; -import { - ProjectBillableEntriesQuery, - ProjectBillableEntry, - ProjectBillableType, -} from '@/interfaces'; -import { ProjectBillableGetter } from './_types'; - -@Service() -export default class GetProjectBillableEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Billable getter with type. - * @get - * @returns {ProjectBillableGetter[]} - */ - get billableGetters(): ProjectBillableGetter[] { - return [ - { type: ProjectBillableType.Task, getter: this.getProjectBillableTasks }, - { - type: ProjectBillableType.Expense, - getter: this.getProjectBillableExpenses, - }, - { type: ProjectBillableType.Bill, getter: this.getProjectBillableBills }, - ]; - } - - /** - * Retrieve the billable entries of the given project. - * @param {number} tenantId - * @param {number} projectId - * @param {ProjectBillableEntriesQuery} query - - * @returns {} - */ - public getProjectBillableEntries = async ( - tenantId: number, - projectId: number, - query: ProjectBillableEntriesQuery = { - billableType: [], - } - ): Promise => { - const gettersOpers = this.billableGetters - .filter( - (billableGetter) => - includes(query.billableType, billableGetter.type) || - isEmpty(query.billableType) - ) - .map((billableGetter) => - billableGetter.getter(tenantId, projectId, query) - ); - const gettersResults = await Promise.all(gettersOpers); - - return flatten(gettersResults); - }; - - /** - * Retrieves the billable tasks of the given project. - * @param {number} tenantId - * @param {number} projectId - * @param {ProjectBillableEntriesQuery} query - * @returns {ProjectBillableEntry[]} - */ - private getProjectBillableTasks = async ( - tenantId: number, - projectId: number, - query: ProjectBillableEntriesQuery - ): Promise => { - const { Task } = this.tenancy.models(tenantId); - - const billableTasks = await Task.query().where('projectId', projectId); - - return this.transformer.transform( - tenantId, - billableTasks, - new ProjectBillableTaskTransformer() - ); - }; - - /** - * Retrieves the billable expenses of the given project. - * @param {number} tenantId - * @param {number} projectId - * @param {ProjectBillableEntriesQuery} query - * @returns - */ - private getProjectBillableExpenses = async ( - tenantId: number, - projectId: number, - query: ProjectBillableEntriesQuery - ) => { - const { Expense } = this.tenancy.models(tenantId); - - const billableExpenses = await Expense.query() - .where('projectId', projectId) - .modify('filterByDateRange', null, query.toDate) - .modify('filterByPublished'); - - return this.transformer.transform( - tenantId, - billableExpenses, - new ProjectBillableExpenseTransformer() - ); - }; - - /** - * Retrieves billable bills of the given project. - * @param {number} tenantId - * @param {number} projectId - * @param {ProjectBillableEntriesQuery} query - */ - private getProjectBillableBills = async ( - tenantId: number, - projectId: number, - query: ProjectBillableEntriesQuery - ) => { - const { Bill } = this.tenancy.models(tenantId); - - const billableBills = await Bill.query() - .where('projectId', projectId) - .modify('published'); - - return this.transformer.transform( - tenantId, - billableBills, - new ProjectBillableBillTransformer() - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/GetProjects.ts b/packages/server/src/services/Projects/Projects/GetProjects.ts deleted file mode 100644 index 196b62462..000000000 --- a/packages/server/src/services/Projects/Projects/GetProjects.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IProjectGetPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ProjectDetailedTransformer } from './ProjectDetailedTransformer'; - -@Service() -export default class GetProjects { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the projects list. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getProjects = async (tenantId: number): Promise => { - const { Project } = this.tenancy.models(tenantId); - - // Retrieve projects. - const projects = await Project.query() - .withGraphFetched('contact') - .modify('totalExpensesDetails') - .modify('totalBillsDetails') - .modify('totalTasksDetails'); - - // Transformes and returns object. - return this.transformer.transform( - tenantId, - projects, - new ProjectDetailedTransformer() - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableBill.ts b/packages/server/src/services/Projects/Projects/ProjectBillableBill.ts deleted file mode 100644 index d97dc6156..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableBill.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ProjectBillableBill { - @Inject() - private tenancy: HasTenancyService; - - /** - * Increase the invoiced amount of the given bill. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Bill id. - * @param {number} invoicedAmount - Invoiced amount. - */ - public increaseInvoicedBill = async ( - tenantId: number, - billId: number, - invoicedAmount: number - ) => { - const { Bill } = this.tenancy.models(tenantId); - - await Bill.query() - .findById(billId) - .increment('projectInvoicedAmount', invoicedAmount); - }; - - /** - * Decrease the invoiced amount of the given bill. - * @param {number} tenantId - * @param {number} billId - Bill id. - * @param {number} invoiceHours - Invoiced amount. - * @returns {} - */ - public decreaseInvoicedBill = async ( - tenantId: number, - billId: number, - invoiceHours: number - ) => { - const { Bill } = this.tenancy.models(tenantId); - - await Bill.query() - .findById(billId) - .decrement('projectInvoicedAmount', invoiceHours); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableBillInvoiced.ts b/packages/server/src/services/Projects/Projects/ProjectBillableBillInvoiced.ts deleted file mode 100644 index c32228755..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableBillInvoiced.ts +++ /dev/null @@ -1,116 +0,0 @@ -import async from 'async'; -import { Knex } from 'knex'; -import { Service } from 'typedi'; -import { ISaleInvoice, ISaleInvoiceDTO, ProjectLinkRefType } from '@/interfaces'; -import { ProjectBillableExpense } from './ProjectBillableExpense'; -import { filterEntriesByRefType } from './_utils'; - -@Service() -export class ProjectBillableBill { - @Inject() - private projectBillableExpense: ProjectBillableExpense; - - /** - * Increases the invoiced amount of the given bills that associated - * to the invoice entries. - * @param {number} tenantId - * @param {ISaleInvoice | ISaleInvoiceDTO} saleInvoiceDTO - * @param {Knex.Transaction} trx - */ - public increaseInvoicedBill = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoice | ISaleInvoiceDTO, - trx?: Knex.Transaction - ) => { - // Initiates a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.increaseInvoicedExpenseQueue, - 10 - ); - const filteredEntries = filterEntriesByRefType( - saleInvoiceDTO.entries, - ProjectLinkRefType.Task - ); - filteredEntries.forEach((entry) => { - saveAccountsBalanceQueue.push({ - tenantId, - projectRefId: entry.projectRefId, - projectRefInvoicedAmount: entry.projectRefInvoicedAmount, - trx, - }); - }); - if (filteredEntries.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Decreases the invoiced amount of the given bills that associated - * to the invoice entries. - * @param {number} tenantId - * @param {ISaleInvoice | ISaleInvoiceDTO} saleInvoiceDTO - * @param {Knex.Transaction} trx - */ - public decreaseInvoicedBill = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoice | ISaleInvoiceDTO, - trx?: Knex.Transaction - ) => { - // Initiates a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.decreaseInvoicedExpenseQueue, - 10 - ); - const filteredEntries = filterEntriesByRefType( - saleInvoiceDTO.entries, - ProjectLinkRefType.Task - ); - filteredEntries.forEach((entry) => { - saveAccountsBalanceQueue.push({ - tenantId, - projectRefId: entry.projectRefId, - projectRefInvoicedAmount: entry.projectRefInvoicedAmount, - trx, - }); - }); - if (filteredEntries.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Queue job increases the invoiced amount of the given bill. - * @param {IncreaseInvoicedTaskQueuePayload} - payload - */ - private increaseInvoicedExpenseQueue = async ({ - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx, - }) => { - await this.projectBillableExpense.increaseInvoicedExpense( - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx - ); - }; - - /** - * Queue job decreases the invoiced amount of the given bill. - * @param {IncreaseInvoicedTaskQueuePayload} - payload - */ - private decreaseInvoicedExpenseQueue = async ({ - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx, - }) => { - await this.projectBillableExpense.decreaseInvoicedExpense( - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableBillSubscriber.ts b/packages/server/src/services/Projects/Projects/ProjectBillableBillSubscriber.ts deleted file mode 100644 index 92f23c87b..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableBillSubscriber.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import { ProjectBillableTask } from './ProjectBillableTasks'; -import { ProjectBillableExpense } from './ProjectBillableExpense'; -import { ProjectBillableExpenseInvoiced } from './ProjectBillableExpenseInvoiced'; - -@Service() -export class ProjectBillableBillSubscriber { - @Inject() - private projectBillableExpenseInvoiced: ProjectBillableExpenseInvoiced; - - /** - * Attaches events with handlers. - * @param bus - */ - attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleIncreaseBillableBill - ); - bus.subscribe(events.saleInvoice.onEdited, this.handleEditBillableBill); - bus.subscribe( - events.saleInvoice.onDeleted, - this.handleDecreaseBillableBill - ); - } - - /** - * Increases the billable amount of expense. - * @param {ISaleInvoiceCreatedPayload} payload - - */ - public handleIncreaseBillableBill = async ({ - tenantId, - saleInvoice, - saleInvoiceDTO, - trx, - }: ISaleInvoiceCreatedPayload) => { - await this.projectBillableExpenseInvoiced.increaseInvoicedExpense( - tenantId, - saleInvoiceDTO, - trx - ); - }; - - /** - * Decreases the billable amount of expense. - * @param {ISaleInvoiceDeletedPayload} payload - - */ - public handleDecreaseBillableBill = async ({ - tenantId, - oldSaleInvoice, - trx, - }: ISaleInvoiceDeletedPayload) => { - await this.projectBillableExpenseInvoiced.decreaseInvoicedExpense( - tenantId, - oldSaleInvoice, - trx - ); - }; - - /** - * - * @param {ISaleInvoiceEditedPayload} payload - - */ - public handleEditBillableBill = async ({ - tenantId, - oldSaleInvoice, - saleInvoiceDTO, - trx, - }: ISaleInvoiceEditedPayload) => { - await this.projectBillableExpenseInvoiced.decreaseInvoicedExpense( - tenantId, - oldSaleInvoice, - trx - ); - await this.projectBillableExpenseInvoiced.increaseInvoicedExpense( - tenantId, - saleInvoiceDTO, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableBillTransformer.ts b/packages/server/src/services/Projects/Projects/ProjectBillableBillTransformer.ts deleted file mode 100644 index 5d26fb5ef..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableBillTransformer.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { IBill } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ProjectBillableBillTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'billableType', - 'billableId', - 'billableAmount', - 'billableAmountFormatted', - 'billableCurrency', - 'billableTransactionNo', - 'billableDate', - 'billableDateFormatted', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Billable type. - * @returns {string} - */ - public billableType = () => { - return 'Bill'; - }; - - /** - * Billable id. - * @param {IBill} bill - * @returns {string} - */ - public billableId = (bill: IBill) => { - return bill.id; - }; - - /** - * Billable amount. - * @param {IBill} bill - * @returns {string} - */ - public billableAmount = (bill: IBill) => { - return bill.billableAmount; - }; - - /** - * Billable amount formatted. - * @param {IBill} bill - * @returns {string} - */ - public billableAmountFormatted = (bill: IBill) => { - return formatNumber(bill.billableAmount, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Billable currency. - * @param {IBill} bill - * @returns {string} - */ - public billableCurrency = (bill: IBill) => { - return bill.currencyCode; - }; - - /** - * - * @param {IBill} bill - * @returns {string} - */ - public billableTransactionNo = (bill: IBill) => { - return bill.billNumber; - }; - - /** - * Billable date. - * @returns {Date} - */ - public billableDate = (bill: IBill) => { - return bill.createdAt; - }; - - /** - * Billable date formatted. - * @returns {string} - */ - public billableDateFormatted = (bill: IBill) => { - return this.formatDate(bill.createdAt); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableExpense.ts b/packages/server/src/services/Projects/Projects/ProjectBillableExpense.ts deleted file mode 100644 index cdedfa8ee..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableExpense.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class ProjectBillableExpense { - @Inject() - private tenancy: HasTenancyService; - - /** - * Increase the invoiced amount of the given expense. - * @param {number} tenantId - * @param {number} expenseId - * @param {number} invoicedAmount - * @param {Knex.Transaction} trx - */ - public increaseInvoicedExpense = async ( - tenantId: number, - expenseId: number, - invoicedAmount: number, - trx?: Knex.Transaction - ) => { - const { Expense } = this.tenancy.models(tenantId); - - await Expense.query(trx) - .findById(expenseId) - .increment('invoicedAmount', invoicedAmount); - }; - - /** - * Decrease the invoiced amount of the given expense. - * @param {number} tenantId - * @param {number} taskId - * @param {number} invoiceHours - * @param {Knex.Transaction} knex - */ - public decreaseInvoicedExpense = async ( - tenantId: number, - expenseId: number, - invoiceHours: number, - trx?: Knex.Transaction - ) => { - const { Expense } = this.tenancy.models(tenantId); - - await Expense.query(trx) - .findById(expenseId) - .decrement('invoicedAmount', invoiceHours); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableExpenseInvoiced.ts b/packages/server/src/services/Projects/Projects/ProjectBillableExpenseInvoiced.ts deleted file mode 100644 index 3e253e702..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableExpenseInvoiced.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import async from 'async'; -import { - ISaleInvoice, - ISaleInvoiceDTO, - ProjectLinkRefType, -} from '@/interfaces'; -import { ProjectBillableExpense } from './ProjectBillableExpense'; -import { filterEntriesByRefType } from './_utils'; - -@Service() -export class ProjectBillableExpenseInvoiced { - @Inject() - private projectBillableExpense: ProjectBillableExpense; - - /** - * Increases the invoiced amount of invoice entries that reference to - * expense entries. - * @param {number} tenantId - * @param {ISaleInvoice | ISaleInvoiceDTO} saleInvoiceDTO - * @param {Knex.Transaction} trx - */ - public increaseInvoicedExpense = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoice | ISaleInvoiceDTO, - trx?: Knex.Transaction - ) => { - // Initiates a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.increaseInvoicedExpenseQueue, - 10 - ); - const filteredEntries = filterEntriesByRefType( - saleInvoiceDTO.entries, - ProjectLinkRefType.Expense - ); - filteredEntries.forEach((entry) => { - saveAccountsBalanceQueue.push({ - tenantId, - projectRefId: entry.projectRefId, - projectRefInvoicedAmount: entry.projectRefInvoicedAmount, - trx, - }); - }); - if (filteredEntries.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Decreases the invoiced amount of the given expenses from - * the invoice entries. - * @param {number} tenantId - * @param {ISaleInvoice | ISaleInvoiceDTO} saleInvoiceDTO - * @param {Knex.Transaction} trx - */ - public decreaseInvoicedExpense = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoice | ISaleInvoiceDTO, - trx?: Knex.Transaction - ) => { - // Initiates a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.decreaseInvoicedExpenseQueue, - 10 - ); - const filteredEntries = filterEntriesByRefType( - saleInvoiceDTO.entries, - ProjectLinkRefType.Expense - ); - filteredEntries.forEach((entry) => { - saveAccountsBalanceQueue.push({ - tenantId, - projectRefId: entry.projectRefId, - projectRefInvoicedAmount: entry.projectRefInvoicedAmount, - trx, - }); - }); - if (filteredEntries.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Queue job increases the invoiced amount of the given expense. - * @param {IncreaseInvoicedTaskQueuePayload} - payload - */ - private increaseInvoicedExpenseQueue = async ({ - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx, - }) => { - await this.projectBillableExpense.increaseInvoicedExpense( - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx - ); - }; - - /** - * Queue job decreases the invoiced amount of the given expense. - * @param {IncreaseInvoicedTaskQueuePayload} - payload - */ - private decreaseInvoicedExpenseQueue = async ({ - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx, - }) => { - await this.projectBillableExpense.decreaseInvoicedExpense( - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableExpenseSubscriber.ts b/packages/server/src/services/Projects/Projects/ProjectBillableExpenseSubscriber.ts deleted file mode 100644 index 55a87f077..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableExpenseSubscriber.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import { ProjectBillableExpenseInvoiced } from './ProjectBillableExpenseInvoiced'; - -@Service() -export class ProjectBillableExpensesSubscriber { - @Inject() - private projectBillableExpenseInvoiced: ProjectBillableExpenseInvoiced; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleIncreaseBillableExpenses - ); - bus.subscribe(events.saleInvoice.onEdited, this.handleEditBillableExpenses); - bus.subscribe( - events.saleInvoice.onDeleted, - this.handleDecreaseBillableExpenses - ); - } - - /** - * Increases the billable amount of expense. - * @param {ISaleInvoiceCreatedPayload} payload - - */ - public handleIncreaseBillableExpenses = async ({ - tenantId, - saleInvoiceDTO, - trx, - }: ISaleInvoiceCreatedPayload) => { - await this.projectBillableExpenseInvoiced.increaseInvoicedExpense( - tenantId, - saleInvoiceDTO, - trx - ); - }; - - /** - * Decreases the billable amount of expense. - * @param {ISaleInvoiceDeletedPayload} payload - - */ - public handleDecreaseBillableExpenses = async ({ - tenantId, - oldSaleInvoice, - trx, - }: ISaleInvoiceDeletedPayload) => { - await this.projectBillableExpenseInvoiced.increaseInvoicedExpense( - tenantId, - oldSaleInvoice, - trx - ); - }; - - /** - * Decreases the old invoice and increases the new invoice DTO. - * @param {ISaleInvoiceEditedPayload} payload - - */ - public handleEditBillableExpenses = async ({ - tenantId, - saleInvoice, - oldSaleInvoice, - trx, - }: ISaleInvoiceEditedPayload) => { - await this.projectBillableExpenseInvoiced.decreaseInvoicedExpense( - tenantId, - oldSaleInvoice, - trx - ); - await this.projectBillableExpenseInvoiced.increaseInvoicedExpense( - tenantId, - saleInvoice, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableExpenseTransformer.ts b/packages/server/src/services/Projects/Projects/ProjectBillableExpenseTransformer.ts deleted file mode 100644 index b827c520f..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableExpenseTransformer.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { IExpense } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ProjectBillableExpenseTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'billableType', - 'billableId', - 'billableAmount', - 'billableAmountFormatted', - 'billableCurrency', - 'billableTransactionNo', - 'billableDate', - 'billableDateFormatted', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieves the billable type. - * @returns {string} - */ - public billableType = () => { - return 'Expense'; - }; - - /** - * Retrieves the billable id. - * @param {IExpense} expense - * @returns {string} - */ - public billableId = (expense: IExpense) => { - return expense.id; - }; - - /** - * Retrieves the billable amount of expense. - * @param {IExpense} expense - - * @returns {number} - */ - public billableAmount = (expense: IExpense) => { - return expense.billableAmount; - }; - - /** - * Retrieves the billable formatted amount of expense. - * @param {IExpense} expense - * @returns {string} - */ - public billableAmountFormatted = (expense: IExpense) => { - return formatNumber(expense.billableAmount, { - currencyCode: expense.currencyCode, - }); - }; - - /** - * Retrieves the currency of billable expense. - * @param {IExpense} expense - * @returns {string} - */ - public billableCurrency = (expense: IExpense) => { - return expense.currencyCode; - }; - - /** - * Billable transaction number. - * @returns {string} - */ - public billableTransactionNo = () => { - return ''; - }; - - /** - * Billable date. - * @returns {Date} - */ - public billableDate = (expense: IExpense) => { - return expense.createdAt; - }; - - /** - * Billable date formatted. - * @returns {string} - */ - public billableDateFormatted = (expense: IExpense) => { - return this.formatDate(expense.createdAt); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableTaskTransformer.ts b/packages/server/src/services/Projects/Projects/ProjectBillableTaskTransformer.ts deleted file mode 100644 index 71aff5c4a..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableTaskTransformer.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { IProjectTask } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class ProjectBillableTaskTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'billableType', - 'billableId', - 'billableAmount', - 'billableAmountFormatted', - 'billableHours', - 'billableCurrency', - 'billableTransactionNo', - 'billableDate', - 'billableDateFormatted', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Billable type. - * @returns {string} - */ - public billableType = () => { - return 'Task'; - }; - - /** - * Billable id. - * @param {IProjectTask} task - * @returns {string} - */ - public billableId = (task: IProjectTask) => { - return task.id; - }; - - /** - * Billable amount. - * @param {IProjectTask} task - * @returns {number} - */ - public billableAmount = (task: IProjectTask) => { - return task.billableAmount; - }; - - /** - * Billable amount formatted. - * @returns {string} - */ - public billableAmountFormatted = (task: IProjectTask) => { - return formatNumber(task.billableAmount, { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Billable hours of the task. - * @param {IProjectTask} task - * @returns {number} - */ - public billableHours = (task: IProjectTask) => { - return task.billableHours; - }; - - /** - * Retrieves the currency of billable entry. - * @returns {string} - */ - public billableCurrency = () => { - return this.context.baseCurrency; - }; - - /** - * Billable transaction number. - * @returns {string} - */ - public billableTransactionNo = () => { - return ''; - }; - - /** - * Billable date. - * @returns {Date} - */ - public billableDate = (task: IProjectTask) => { - return task.createdAt; - }; - - /** - * Billable date formatted. - * @returns {string} - */ - public billableDateFormatted = (task: IProjectTask) => { - return this.formatDate(task.createdAt); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableTasks.ts b/packages/server/src/services/Projects/Projects/ProjectBillableTasks.ts deleted file mode 100644 index 511a751c3..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableTasks.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Knex } from 'knex'; - -@Service() -export class ProjectBillableTask { - @Inject() - private tenancy: HasTenancyService; - - /** - * Increase the invoiced hours of the given task. - * @param {number} tenantId - * @param {number} taskId - * @param {number} invoiceHours - */ - public increaseInvoicedTask = async ( - tenantId: number, - taskId: number, - invoiceHours: number, - trx?: Knex.Transaction - ) => { - const { Task } = this.tenancy.models(tenantId); - - await Task.query(trx) - .findById(taskId) - .increment('invoicedHours', invoiceHours); - }; - - /** - * Decrease the invoiced hours of the given task. - * @param {number} tenantId - * @param {number} taskId - * @param {number} invoiceHours - - * @returns {} - */ - public decreaseInvoicedTask = async ( - tenantId: number, - taskId: number, - invoiceHours: number, - trx?: Knex.Transaction - ) => { - const { Task } = this.tenancy.models(tenantId); - - await Task.query(trx) - .findById(taskId) - .decrement('invoicedHours', invoiceHours); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableTasksInvoiced.ts b/packages/server/src/services/Projects/Projects/ProjectBillableTasksInvoiced.ts deleted file mode 100644 index d54958de9..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableTasksInvoiced.ts +++ /dev/null @@ -1,116 +0,0 @@ -import async from 'async'; -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ISaleInvoice, ISaleInvoiceDTO, ProjectLinkRefType } from '@/interfaces'; -import { ProjectBillableTask } from './ProjectBillableTasks'; -import { filterEntriesByRefType } from './_utils'; -import { IncreaseInvoicedTaskQueuePayload } from './_types'; - -@Service() -export class ProjectBillableTasksInvoiced { - @Inject() - private projectBillableTasks: ProjectBillableTask; - - /** - * Increases the invoiced amount of the given tasks that associated - * to the invoice entries. - * @param {number} tenantId - * @param {ISaleInvoiceDTO} saleInvoiceDTO - */ - public increaseInvoicedTasks = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoiceDTO | ISaleInvoice, - trx?: Knex.Transaction - ) => { - // Initiate a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.increaseInvoicedTaskQueue, - 10 - ); - const filteredEntries = filterEntriesByRefType( - saleInvoiceDTO.entries, - ProjectLinkRefType.Task - ); - filteredEntries.forEach((entry) => { - saveAccountsBalanceQueue.push({ - tenantId, - projectRefId: entry.projectRefId, - projectRefInvoicedAmount: entry.projectRefInvoicedAmount, - trx, - }); - }); - if (filteredEntries.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Decreases the invoiced amount of the given tasks that associated - * to the invoice entries. - * @param {number} tenantId - * @param {ISaleInvoiceDTO | ISaleInvoice} saleInvoiceDTO - * @param {Knex.Transaction} trx - */ - public decreaseInvoicedTasks = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoiceDTO | ISaleInvoice, - trx?: Knex.Transaction - ) => { - // Initiate a new queue for accounts balance mutation. - const saveAccountsBalanceQueue = async.queue( - this.decreaseInvoicedTaskQueue, - 10 - ); - const filteredEntries = filterEntriesByRefType( - saleInvoiceDTO.entries, - ProjectLinkRefType.Task - ); - filteredEntries.forEach((entry) => { - saveAccountsBalanceQueue.push({ - tenantId, - projectRefId: entry.projectRefId, - projectRefInvoicedAmount: entry.projectRefInvoicedAmount, - trx, - }); - }); - if (filteredEntries.length > 0) { - await saveAccountsBalanceQueue.drain(); - } - }; - - /** - * Queue job increases the invoiced amount of the given task. - * @param {IncreaseInvoicedTaskQueuePayload} - payload - */ - private increaseInvoicedTaskQueue = async ({ - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx, - }: IncreaseInvoicedTaskQueuePayload) => { - await this.projectBillableTasks.increaseInvoicedTask( - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx - ); - }; - - /** - * Queue jobs decreases the invoiced amount of the given task. - * @param {IncreaseInvoicedTaskQueuePayload} - payload - */ - private decreaseInvoicedTaskQueue = async ({ - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx, - }) => { - await this.projectBillableTasks.decreaseInvoicedTask( - tenantId, - projectRefId, - projectRefInvoicedAmount, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectBillableTasksSubscriber.ts b/packages/server/src/services/Projects/Projects/ProjectBillableTasksSubscriber.ts deleted file mode 100644 index 3cc53215d..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectBillableTasksSubscriber.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import { ProjectInvoiceValidator } from './ProjectInvoiceValidator'; -import { ProjectBillableTasksInvoiced } from './ProjectBillableTasksInvoiced'; - -@Service() -export class ProjectBillableTasksSubscriber { - @Inject() - private projectBillableTasks: ProjectBillableTasksInvoiced; - - @Inject() - private projectBillableTasksValidator: ProjectInvoiceValidator; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreating, - this.handleValidateInvoiceTasksRefs - ); - bus.subscribe( - events.saleInvoice.onCreated, - this.handleIncreaseBillableTasks - ); - bus.subscribe(events.saleInvoice.onEdited, this.handleEditBillableTasks); - bus.subscribe( - events.saleInvoice.onDeleted, - this.handleDecreaseBillableTasks - ); - } - - /** - * Validate the tasks refs ids existance. - * @param {ISaleInvoiceCreatedPayload} payload - - */ - public handleValidateInvoiceTasksRefs = async ({ - tenantId, - saleInvoiceDTO, - }: ISaleInvoiceCreatedPayload) => { - await this.projectBillableTasksValidator.validateTasksRefsExistance( - tenantId, - saleInvoiceDTO - ); - }; - - /** - * Handle increase the invoiced tasks once the sale invoice be created. - * @param {ISaleInvoiceCreatedPayload} payload - - */ - public handleIncreaseBillableTasks = async ({ - tenantId, - saleInvoiceDTO, - }: ISaleInvoiceCreatedPayload) => { - await this.projectBillableTasks.increaseInvoicedTasks( - tenantId, - saleInvoiceDTO - ); - }; - - /** - * Handle decrease the invoiced tasks once the sale invoice be deleted. - * @param {ISaleInvoiceDeletedPayload} payload - - */ - public handleDecreaseBillableTasks = async ({ - tenantId, - oldSaleInvoice, - trx, - }: ISaleInvoiceDeletedPayload) => { - await this.projectBillableTasks.decreaseInvoicedTasks( - tenantId, - oldSaleInvoice, - trx - ); - }; - - /** - * Handle adjusting the invoiced tasks once the sale invoice be edited. - * @param {ISaleInvoiceEditedPayload} payload - - */ - public handleEditBillableTasks = async ({ - tenantId, - oldSaleInvoice, - saleInvoiceDTO, - trx, - }: ISaleInvoiceEditedPayload) => { - await this.projectBillableTasks.increaseInvoicedTasks( - tenantId, - saleInvoiceDTO, - trx - ); - await this.projectBillableTasks.decreaseInvoicedTasks( - tenantId, - oldSaleInvoice, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectDetailedTransformer.ts b/packages/server/src/services/Projects/Projects/ProjectDetailedTransformer.ts deleted file mode 100644 index ff4c91dd4..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectDetailedTransformer.ts +++ /dev/null @@ -1,391 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { sumBy } from 'lodash'; -import Project from 'models/Project'; -import { formatNumber } from 'utils'; -import { formatMinutes } from 'utils/formatMinutes'; - -export class ProjectDetailedTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'costEstimateFormatted', - 'deadlineFormatted', - 'contactDisplayName', - 'statusFormatted', - - 'totalActualHours', - 'totalActualHoursFormatted', - 'totalEstimateHours', - 'totalEstimateHoursFormatted', - 'totalInvoicedHours', - 'totalInvoicedHoursFormatted', - 'totalBillableHours', - 'totalBillableHoursFormatted', - - 'totalActualHoursAmount', - 'totalActualHoursAmountFormatted', - 'totalEstimateHoursAmount', - 'totalEstimateHoursAmountFormatted', - 'totalInvoicedHoursAmount', - 'totalInvoicedHoursAmountFormatted', - 'totalBillableHoursAmount', - 'totalBillableHoursAmountFormatted', - - 'totalExpenses', - 'totalExpensesFormatted', - - 'totalInvoicedExpenses', - 'totalInvoicedExpensesFormatted', - - 'totalBillableExpenses', - 'totalBillableExpensesFormatted', - - 'totalInvoiced', - 'totalInvoicedFormatted', - - 'totalBillable', - 'totalBillableFormatted', - ]; - }; - - /** - * Exclude these attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['contact', 'tasks', 'expenses', 'bills']; - }; - - /** - * Retrieves the formatted value of cost estimate. - * @param {Project} project - * @returns {string} - */ - public costEstimateFormatted = (project: Project) => { - return formatNumber(project.costEstimate, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieves the formatted value of the deadline date. - * @param {Project} project - * @returns {string} - */ - public deadlineFormatted = (project: Project) => { - return this.formatDate(project.deadline); - }; - - /** - * Retrieves the contact display name. - * @param {Project} project - * @returns {string} - */ - public contactDisplayName = (project: Project) => { - return project.contact.displayName; - }; - - /** - * Retrieves the formatted value of project's status. - * @param {Project} project - * @returns {string} - */ - public statusFormatted = (project: Project) => { - return project.status; - }; - - // -------------------------------------------------------------- - // # Tasks Hours - // -------------------------------------------------------------- - /** - * Total actual hours. - * @param {Project} project - * @returns {number} - */ - public totalActualHours = (project: Project) => { - return sumBy(project.tasks, 'totalActualHours'); - }; - - /** - * Retrieves the formatted total actual hours. - * @param {Project} project - * @returns {string} - */ - public totalActualHoursFormatted = (project: Project) => { - const hours = this.totalActualHours(project); - return formatMinutes(hours); - }; - - /** - * Total Estimated hours. - * @param {Project} project - * @returns {number} - */ - public totalEstimateHours = (project: Project) => { - return sumBy(project.tasks, 'totalEstimateHours'); - }; - - /** - * Total estimate hours formatted. - * @param {Project} project - * @returns {string} - */ - public totalEstimateHoursFormatted = (project: Project) => { - const hours = this.totalEstimateHours(project); - return formatMinutes(hours); - }; - - /** - * Total invoiced hours. - * @param {Project} project - * @returns {number} - */ - public totalInvoicedHours = (project: Project) => { - return sumBy(project.tasks, 'totalInvoicedHours'); - }; - - /** - * Total invoiced hours formatted. - * @param {Project} project - * @returns {string} - */ - public totalInvoicedHoursFormatted = (project: Project) => { - const hours = this.totalInvoicedHours(project); - return formatMinutes(hours); - }; - - /** - * Total billable hours. - * @param {Project} project - * @returns {number} - */ - public totalBillableHours = (project: Project) => { - const totalActualHours = this.totalActualHours(project); - const totalInvoicedHours = this.totalInvoicedHours(project); - - return Math.max(totalActualHours - totalInvoicedHours, 0); - }; - - /** - * Retrieves the billable hours formatted. - * @param {Project} project - * @returns {string} - */ - public totalBillableHoursFormatted = (project) => { - const hours = this.totalBillableHours(project); - return formatMinutes(hours); - }; - - // -------------------------------------------------------------- - // # Tasks Hours Amount - // -------------------------------------------------------------- - /** - * Total amount of invoiced hours. - * @param {Project} project - * @returns {number} - */ - public totalActualHoursAmount = (project: Project) => { - return sumBy(project.tasks, 'totalActualAmount'); - }; - - /** - * Total amount of invoiced hours. - * @param {Project} project - * @returns {number} - */ - public totalActualHoursAmountFormatted = (project: Project) => { - return formatNumber(this.totalActualHoursAmount(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Total amount of estimated hours. - * @param {Project} project - * @returns {number} - */ - public totalEstimateHoursAmount = (project: Project) => { - return sumBy(project.tasks, 'totalEstimateAmount'); - }; - - /** - * Formatted amount of total estimate hours. - * @param {Project} project - * @returns {string} - */ - public totalEstimateHoursAmountFormatted = (project: Project) => { - return formatNumber(this.totalEstimateHoursAmount(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Total amount of invoiced hours. - * @param {Project} project - * @returns {number} - */ - public totalInvoicedHoursAmount = (project) => { - return sumBy(project.tasks, 'totalInvoicedAmount'); - }; - - /** - * Formatted total amount of invoiced hours. - * @param {Project} project - * @returns {number} - */ - public totalInvoicedHoursAmountFormatted = (project) => { - return formatNumber(this.totalInvoicedHoursAmount(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Total amount of billable hours. - * @param {Project} project - * @returns {number} - */ - public totalBillableHoursAmount = (project) => { - const totalActualAmount = this.totalActualHoursAmount(project); - const totalBillableAmount = this.totalInvoicedHoursAmount(project); - - return Math.max(totalActualAmount, totalBillableAmount); - }; - - /** - * Formatted total amount of billable hours. - * @param {Project} project - * @returns {string} - */ - public totalBillableHoursAmountFormatted = (project) => { - return formatNumber(this.totalBillableHoursAmount(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - // -------------------------------------------------------------- - // # Expenses - // -------------------------------------------------------------- - /** - * Total expenses amount. - * @param {Project} project - * @returns {number} - */ - public totalExpenses = (project) => { - const expensesTotal = sumBy(project.expenses, 'totalExpenses'); - const billsTotal = sumBy(project.bills, 'totalBills'); - - return expensesTotal + billsTotal; - }; - - /** - * Formatted total amount of expenses. - * @param {Project} project - * @returns {string} - */ - public totalExpensesFormatted = (project) => { - return formatNumber(this.totalExpenses(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Total amount of invoiced expenses. - * @param {Project} project - * @returns {number} - */ - public totalInvoicedExpenses = (project: Project) => { - const totalInvoicedExpenses = sumBy( - project.expenses, - 'totalInvoicedExpenses' - ); - const totalInvoicedBills = sumBy(project.bills, 'totalInvoicedBills'); - - return totalInvoicedExpenses + totalInvoicedBills; - }; - - /** - * Formatted total amount of invoiced expenses. - * @param {Project} project - * @returns {string} - */ - public totalInvoicedExpensesFormatted = (project: Project) => { - return formatNumber(this.totalInvoicedExpenses(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Total amount of billable expenses. - * @param {Project} project - * @returns {number} - */ - public totalBillableExpenses = (project: Project) => { - const totalInvoiced = this.totalInvoicedExpenses(project); - const totalInvoice = this.totalExpenses(project); - - return totalInvoice - totalInvoiced; - }; - - /** - * Formatted total amount of billable expenses. - * @param {Project} project - * @returns {string} - */ - public totalBillableExpensesFormatted = (project: Project) => { - return formatNumber(this.totalBillableExpenses(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - // -------------------------------------------------------------- - // # Total - // -------------------------------------------------------------- - /** - * Total invoiced amount. - * @param {Project} project - * @returns {number} - */ - public totalInvoiced = (project: Project) => { - const invoicedExpenses = this.totalInvoicedExpenses(project); - const invoicedTasks = this.totalInvoicedHoursAmount(project); - - return invoicedExpenses + invoicedTasks; - }; - - /** - * Formatted amount of total invoiced. - * @param {Project} project - * @returns {number} - */ - public totalInvoicedFormatted = (project: Project) => { - return formatNumber(this.totalInvoiced(project), { - currencyCode: this.context.baseCurrency, - }); - }; - - /** - * Total billable amount. - * @param {Project} project - * @returns {number} - */ - public totalBillable = (project: Project) => { - const billableExpenses = this.totalBillableExpenses(project); - const billableTasks = this.totalBillableHoursAmount(project); - - return billableExpenses + billableTasks; - }; - - /** - * Formatted amount of billable total. - * @param {Project} project - * @returns {string} - */ - public totalBillableFormatted = (project: Project) => { - return formatNumber(this.totalBillable(project), { - currencyCode: this.context.baseCurrency, - }); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectInvoiceValidator.ts b/packages/server/src/services/Projects/Projects/ProjectInvoiceValidator.ts deleted file mode 100644 index 5e045623e..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectInvoiceValidator.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { ISaleInvoiceCreateDTO, ProjectLinkRefType } from '@/interfaces'; -import { difference, isEmpty } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ERRORS } from './constants'; - -@Service() -export class ProjectInvoiceValidator { - @Inject() - tenancy: HasTenancyService; - - /** - * Validate the tasks refs ids existance. - * @param {number} tenantId - * @param {ISaleInvoiceCreateDTO} saleInvoiceDTO - * @returns {Promise} - */ - async validateTasksRefsExistance( - tenantId: number, - saleInvoiceDTO: ISaleInvoiceCreateDTO - ) { - const { Task } = this.tenancy.models(tenantId); - - // Filters the invoice entries that have `Task` type and not empty ref. id. - const tasksRefs = saleInvoiceDTO.entries.filter( - (entry) => - entry?.projectRefType === ProjectLinkRefType.Task && - !isEmpty(entry?.projectRefId) - ); - // - if (!tasksRefs.length || (tasksRefs.length && !saleInvoiceDTO.projectId)) { - return; - } - const tasksRefsIds = tasksRefs.map((ref) => ref.projectRefId); - - const tasks = await Task.query() - .whereIn('id', tasksRefsIds) - .where('projectId', saleInvoiceDTO.projectId); - - const tasksIds = tasks.map((task) => task.id); - const notFoundTasksIds = difference(tasksIds, tasksRefsIds); - - if (!notFoundTasksIds.length) { - throw new ServiceError(ERRORS.ITEM_ENTRIES_REF_IDS_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Projects/Projects/ProjectTransformer.ts b/packages/server/src/services/Projects/Projects/ProjectTransformer.ts deleted file mode 100644 index ba13c33a3..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectTransformer.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import Project from 'models/Project'; -import { formatNumber } from 'utils'; - -export class ProjectTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'costEstimateFormatted', - 'deadlineFormatted', - 'contactDisplayName', - 'statusFormatted', - ]; - }; - - /** - * Exclude these attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['contact']; - }; - - /** - * Retrieves the formatted value of cost estimate. - * @param {Project} project - * @returns {string} - */ - public costEstimateFormatted = (project: Project) => { - return formatNumber(project.costEstimate, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieves the formatted value of the deadline date. - * @param {Project} project - * @returns {string} - */ - public deadlineFormatted = (project: Project) => { - return this.formatDate(project.deadline); - }; - - /** - * Retrieves the contact display name. - * @param {Project} project - * @returns {string} - */ - public contactDisplayName = (project: Project) => { - return project.contact.displayName; - }; - - /** - * Retrieves the formatted value of project's status. - * @param {Project} project - * @returns {string} - */ - public statusFormatted = (project: Project) => { - return project.status; - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectsApplication.ts b/packages/server/src/services/Projects/Projects/ProjectsApplication.ts deleted file mode 100644 index 645e28219..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectsApplication.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IProjectCreateDTO, - IProjectCreatePOJO, - IProjectEditPOJO, - IProjectGetPOJO, - IProjectStatus, - IVendorsFilter, - ProjectBillableEntriesQuery, - ProjectBillableEntry, -} from '@/interfaces'; -import CreateProject from './CreateProject'; -import DeleteProject from './DeleteProject'; -import GetProject from './GetProject'; -import EditProjectService from './EditProject'; -import GetProjects from './GetProjects'; -import EditProjectStatusService from './EditProjectStatus'; -import GetProjectBillableEntries from './GetProjectBillableEntries'; - -@Service() -export class ProjectsApplication { - @Inject() - private createProjectService: CreateProject; - - @Inject() - private editProjectService: EditProjectService; - - @Inject() - private deleteProjectService: DeleteProject; - - @Inject() - private getProjectService: GetProject; - - @Inject() - private getProjectsService: GetProjects; - - @Inject() - private editProjectStatusService: EditProjectStatusService; - - @Inject() - private getProjectBillable: GetProjectBillableEntries; - - /** - * Creates a new project. - * @param {number} tenantId - Tenant id. - * @param {IProjectCreateDTO} projectDTO - Create project DTO. - * @return {Promise} - */ - public createProject = ( - tenantId: number, - projectDTO: IProjectCreateDTO - ): Promise => { - return this.createProjectService.createProject(tenantId, projectDTO); - }; - - /** - * Edits details of the given vendor. - * @param {number} tenantId - Tenant id. - * @param {number} vendorId - Vendor id. - * @param {IProjectCreateDTO} projectDTO - Create project DTO. - * @returns {Promise} - */ - public editProject = ( - tenantId: number, - projectId: number, - projectDTO: IProjectCreateDTO - ): Promise => { - return this.editProjectService.editProject(tenantId, projectId, projectDTO); - }; - - /** - * Deletes the given project. - * @param {number} tenantId - * @param {number} vendorId - * @return {Promise} - */ - public deleteProject = ( - tenantId: number, - projectId: number - ): Promise => { - return this.deleteProjectService.deleteProject(tenantId, projectId); - }; - - /** - * Retrieves the vendor details. - * @param {number} tenantId - * @param {number} projectId - * @returns {Promise} - */ - public getProject = ( - tenantId: number, - projectId: number - ): Promise => { - return this.getProjectService.getProject(tenantId, projectId); - }; - - /** - * Retrieves the vendors paginated list. - * @param {number} tenantId - * @param {IVendorsFilter} filterDTO - * @returns {Promise} - */ - public getProjects = ( - tenantId: number, - filterDTO: IVendorsFilter - ): Promise => { - return this.getProjectsService.getProjects(tenantId); - }; - - /** - * Edits the given project status. - * @param {number} tenantId - * @param {number} projectId - * @param {IProjectStatus} status - * @returns {Promise} - */ - public editProjectStatus = ( - tenantId: number, - projectId: number, - status: IProjectStatus - ) => { - return this.editProjectStatusService.editProjectStatus( - tenantId, - projectId, - status - ); - }; - - /** - * Retrieves the billable entries of the given project. - * @param {number} tenantId - * @param {number} projectId - * @param {ProjectBillableEntriesQuery} query - * @returns {Promise} - */ - public getProjectBillableEntries = ( - tenantId: number, - projectId: number, - query?: ProjectBillableEntriesQuery - ): Promise => { - return this.getProjectBillable.getProjectBillableEntries( - tenantId, - projectId, - query - ); - }; -} diff --git a/packages/server/src/services/Projects/Projects/ProjectsValidator.ts b/packages/server/src/services/Projects/Projects/ProjectsValidator.ts deleted file mode 100644 index d3ba9b283..000000000 --- a/packages/server/src/services/Projects/Projects/ProjectsValidator.ts +++ /dev/null @@ -1,23 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; - -@Service() -export class ProjectsValidator { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validate contact exists. - * @param {number} tenantId - * @param {number} contactId - */ - public async validateContactExists(tenantId: number, contactId: number) { - const { Contact } = this.tenancy.models(tenantId); - - // Validate customer existance. - await Contact.query() - .modify('customer') - .findById(contactId) - .throwIfNotFound(); - } -} diff --git a/packages/server/src/services/Projects/Projects/_types.ts b/packages/server/src/services/Projects/Projects/_types.ts deleted file mode 100644 index b3ba925f7..000000000 --- a/packages/server/src/services/Projects/Projects/_types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { - ProjectBillableEntriesQuery, - ProjectBillableEntry, - ProjectBillableType, -} from '@/interfaces'; -import { Knex } from 'knex'; - -export interface IncreaseInvoicedTaskQueuePayload { - tenantId: number; - projectRefId: number; - projectRefInvoicedAmount: number; - trx?: Knex.Transaction; -} - -export interface ProjectBillableGetter { - type: ProjectBillableType; - getter: ( - tenantId: number, - projectId: number, - query: ProjectBillableEntriesQuery - ) => Promise; -} diff --git a/packages/server/src/services/Projects/Projects/_utils.ts b/packages/server/src/services/Projects/Projects/_utils.ts deleted file mode 100644 index 91e08efba..000000000 --- a/packages/server/src/services/Projects/Projects/_utils.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { IItemEntry, IItemEntryDTO } from '@/interfaces'; - -export const filterEntriesByRefType = ( - entries: (IItemEntry | IItemEntryDTO)[], - projectRefType: string -) => { - return entries.filter((entry) => entry.projectRefType === projectRefType); -}; diff --git a/packages/server/src/services/Projects/Projects/constants.ts b/packages/server/src/services/Projects/Projects/constants.ts deleted file mode 100644 index 3d1147d9d..000000000 --- a/packages/server/src/services/Projects/Projects/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum ERRORS { - ITEM_ENTRIES_REF_IDS_NOT_FOUND = 'ITEM_ENTRIES_REF_IDS_NOT_FOUND', -} diff --git a/packages/server/src/services/Projects/Tasks/CreateTask.ts b/packages/server/src/services/Projects/Tasks/CreateTask.ts deleted file mode 100644 index 2d28ea646..000000000 --- a/packages/server/src/services/Projects/Tasks/CreateTask.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - ICreateTaskDTO, - IProjectTaskCreatePOJO, - ITaskCreatedEventPayload, - ITaskCreateEventPayload, - ITaskCreatingEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class CreateTaskService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates a new task. - * @param {number} tenantId - - * @param {number} projectId - Project id. - * @param {ICreateTaskDTO} taskDTO - Project's task DTO. - * @returns {Promise} - */ - public createTask = async ( - tenantId: number, - projectId: number, - taskDTO: ICreateTaskDTO - ): Promise => { - const { Task, Project } = this.tenancy.models(tenantId); - - // Validate project existance. - const project = await Project.query().findById(projectId).throwIfNotFound(); - - // Triggers `onProjectTaskCreate` event. - await this.eventPublisher.emitAsync(events.projectTask.onCreate, { - tenantId, - taskDTO, - } as ITaskCreateEventPayload); - - // Creates a new project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectTaskCreating` event. - await this.eventPublisher.emitAsync(events.projectTask.onCreating, { - tenantId, - taskDTO, - trx, - } as ITaskCreatingEventPayload); - - const task = await Task.query().insert({ - ...taskDTO, - actualHours: 0, - projectId, - }); - // Triggers `onProjectTaskCreated` event. - await this.eventPublisher.emitAsync(events.projectTask.onCreated, { - tenantId, - taskDTO, - task, - trx, - } as ITaskCreatedEventPayload); - - return task; - }); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/DeleteTask.ts b/packages/server/src/services/Projects/Tasks/DeleteTask.ts deleted file mode 100644 index 44f665038..000000000 --- a/packages/server/src/services/Projects/Tasks/DeleteTask.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - ITaskDeletedEventPayload, - ITaskDeleteEventPayload, - ITaskDeletingEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class DeleteTaskService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes the give project. - * @param {number} projectId - - * @returns {Promise} - */ - public deleteTask = async ( - tenantId: number, - taskId: number - ): Promise => { - const { Task } = this.tenancy.models(tenantId); - - // Validate customer existance. - const oldTask = await Task.query().findById(taskId).throwIfNotFound(); - - // Triggers `onDeleteProjectTask` event. - await this.eventPublisher.emitAsync(events.projectTask.onDelete, { - tenantId, - taskId, - } as ITaskDeleteEventPayload); - - // Deletes the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectDeleting` event. - await this.eventPublisher.emitAsync(events.projectTask.onDeleting, { - tenantId, - oldTask, - trx, - } as ITaskDeletingEventPayload); - - // Deletes the project object from the storage. - await Task.query(trx).findById(taskId).delete(); - - // Triggers `onProjectDeleted` event. - await this.eventPublisher.emitAsync(events.projectTask.onDeleted, { - tenantId, - oldTask, - trx, - } as ITaskDeletedEventPayload); - }); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/EditTask.ts b/packages/server/src/services/Projects/Tasks/EditTask.ts deleted file mode 100644 index 3c1f0eba3..000000000 --- a/packages/server/src/services/Projects/Tasks/EditTask.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IEditTaskDTO, - IProjectTaskEditPOJO, - ITaskEditedEventPayload, - ITaskEditEventPayload, - ITaskEditingEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class EditTaskService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Edits a new credit note. - * @param {number} tenantId - - * @param {number} taskId - - * @param {IEditTaskDTO} taskDTO - - * @returns {IProjectTaskEditPOJO} - */ - public editTask = async ( - tenantId: number, - taskId: number, - taskDTO: IEditTaskDTO - ): Promise => { - const { Task } = this.tenancy.models(tenantId); - - // Validate task existance. - const oldTask = await Task.query().findById(taskId).throwIfNotFound(); - - // Triggers `onProjectTaskEdit` event. - await this.eventPublisher.emitAsync(events.projectTask.onEdit, { - tenantId, - taskId, - taskDTO, - } as ITaskEditEventPayload); - - // Edits the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectTaskEditing` event. - await this.eventPublisher.emitAsync(events.projectTask.onEditing, { - tenantId, - oldTask, - taskDTO, - trx, - } as ITaskEditingEventPayload); - - // Upsert the project's task object. - const task = await Task.query(trx).upsertGraph({ - id: taskId, - ...taskDTO, - }); - // Triggers `onProjectTaskEdited` event. - await this.eventPublisher.emitAsync(events.projectTask.onEdited, { - tenantId, - oldTask, - taskDTO, - task, - trx, - } as ITaskEditedEventPayload); - - return task; - }); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/GetTask.ts b/packages/server/src/services/Projects/Tasks/GetTask.ts deleted file mode 100644 index 4fe4bb9cb..000000000 --- a/packages/server/src/services/Projects/Tasks/GetTask.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { IProjectTaskGetPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { TaskTransformer } from './TaskTransformer'; - -@Service() -export class GetTaskService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the tasks list. - * @param {number} tenantId - Tenant Id. - * @param {number} taskId - Task Id. - * @returns {Promise} - */ - public getTask = async ( - tenantId: number, - taskId: number - ): Promise => { - const { Task } = this.tenancy.models(tenantId); - - // Retrieve the project. - const task = await Task.query().findById(taskId).throwIfNotFound(); - - // Transformes and returns object. - return this.transformer.transform(tenantId, task, new TaskTransformer()); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/GetTasks.ts b/packages/server/src/services/Projects/Tasks/GetTasks.ts deleted file mode 100644 index 0bd46c78e..000000000 --- a/packages/server/src/services/Projects/Tasks/GetTasks.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { IProjectTaskGetPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { TaskTransformer } from './TaskTransformer'; - -@Service() -export class GetTasksService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the tasks list. - * @param {number} tenantId - Tenant Id. - * @param {number} taskId - Task Id. - * @returns {} - */ - public getTasks = async ( - tenantId: number, - projectId: number - ): Promise => { - const { Task } = this.tenancy.models(tenantId); - - // Retrieve the project. - const tasks = await Task.query().where('projectId', projectId); - - // Transformes and returns object. - return this.transformer.transform(tenantId, tasks, new TaskTransformer()); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/TaskTransformer.ts b/packages/server/src/services/Projects/Tasks/TaskTransformer.ts deleted file mode 100644 index 116be783a..000000000 --- a/packages/server/src/services/Projects/Tasks/TaskTransformer.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatMinutes } from 'utils/formatMinutes'; - -export class TaskTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'estimateHoursFormatted', - 'actualHoursFormatted', - 'invoicedHoursFormatted', - 'billableHoursFormatted', - ]; - }; - - /** - * Retrieves the formatted estimate hours. - * @returns {string} - */ - public estimateHoursFormatted = (task): string => { - return formatMinutes(task.estimateHours); - }; - - /** - * Retrieves the formatted actual hours. - * @returns {string} - */ - public actualHoursFormatted = (task): string => { - return formatMinutes(task.actualHours); - }; - - /** - * Retrieves the formatted billable hours. - * @returns {string} - */ - public billableHoursFormatted = (task): string => { - return formatMinutes(task.billableHours); - }; - - /** - * Retreives the formatted invoiced hours. - * @returns {string} - */ - public invoicedHoursFormatted = (task): string => { - return formatMinutes(task.invoicedHours); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/TasksApplication.ts b/packages/server/src/services/Projects/Tasks/TasksApplication.ts deleted file mode 100644 index 3260d4054..000000000 --- a/packages/server/src/services/Projects/Tasks/TasksApplication.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ICreateTaskDTO, - IEditTaskDTO, - IProjectTaskCreatePOJO, - IProjectTaskEditPOJO, - IProjectTaskGetPOJO, -} from '@/interfaces'; -import { CreateTaskService } from './CreateTask'; -import { DeleteTaskService } from './DeleteTask'; -import { GetTaskService } from './GetTask'; -import { EditTaskService } from './EditTask'; -import { GetTasksService } from './GetTasks'; - -@Service() -export class TasksApplication { - @Inject() - private createTaskService: CreateTaskService; - - @Inject() - private editTaskService: EditTaskService; - - @Inject() - private deleteTaskService: DeleteTaskService; - - @Inject() - private getTaskService: GetTaskService; - - @Inject() - private getTasksService: GetTasksService; - - /** - * Creates a new task associated to specific project. - * @param {number} tenantId - Tenant id. - * @param {number} project - Project id. - * @param {ICreateTaskDTO} taskDTO - Create project DTO. - * @return {Promise} - */ - public createTask = ( - tenantId: number, - projectId: number, - taskDTO: ICreateTaskDTO - ): Promise => { - return this.createTaskService.createTask(tenantId, projectId, taskDTO); - }; - - /** - * Edits details of the given task. - * @param {number} tenantId - Tenant id. - * @param {number} vendorId - Vendor id. - * @param {IEditTaskDTO} projectDTO - Create project DTO. - * @returns {Promise} - */ - public editTask = ( - tenantId: number, - taskId: number, - taskDTO: IEditTaskDTO - ): Promise => { - return this.editTaskService.editTask(tenantId, taskId, taskDTO); - }; - - /** - * Deletes the given task. - * @param {number} tenantId - * @param {number} taskId - Task id. - * @return {Promise} - */ - public deleteTask = (tenantId: number, taskId: number): Promise => { - return this.deleteTaskService.deleteTask(tenantId, taskId); - }; - - /** - * Retrieves the given task details. - * @param {number} tenantId - * @param {number} taskId - * @returns {Promise} - */ - public getTask = ( - tenantId: number, - taskId: number - ): Promise => { - return this.getTaskService.getTask(tenantId, taskId); - }; - - /** - * Retrieves the vendors paginated list. - * @param {number} tenantId - * @param {IVendorsFilter} filterDTO - * @returns {Promise} - */ - public getTasks = ( - tenantId: number, - projectId: number - ): Promise => { - return this.getTasksService.getTasks(tenantId, projectId); - }; -} diff --git a/packages/server/src/services/Projects/Tasks/constants.ts b/packages/server/src/services/Projects/Tasks/constants.ts deleted file mode 100644 index 5f7cb0008..000000000 --- a/packages/server/src/services/Projects/Tasks/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum ProjectTaskChargeType { - Fixed = 'FIXED', - Time = 'TIME', - NonChargable = 'NON_CHARGABLE', -} diff --git a/packages/server/src/services/Projects/Times/CreateTime.ts b/packages/server/src/services/Projects/Times/CreateTime.ts deleted file mode 100644 index ed3a10340..000000000 --- a/packages/server/src/services/Projects/Times/CreateTime.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IProjectTimeCreatedEventPayload, - IProjectTimeCreateDTO, - IProjectTimeCreateEventPayload, - IProjectTimeCreatePOJO, - IProjectTimeCreatingEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class CreateTimeService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates a new time. - * @param {number} taskId - - * @param {IProjectTimeCreateDTO} timeDTO - - * @returns {Promise} - */ - public createTime = async ( - tenantId: number, - taskId: number, - timeDTO: IProjectTimeCreateDTO - ): Promise => { - const { Time, Task } = this.tenancy.models(tenantId); - - const task = await Task.query().findById(taskId).throwIfNotFound(); - - // Triggers `onProjectTimeCreate` event. - await this.eventPublisher.emitAsync(events.projectTime.onCreate, { - tenantId, - timeDTO, - } as IProjectTimeCreateEventPayload); - - // Creates a new project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectTimeCreating` event. - await this.eventPublisher.emitAsync(events.projectTime.onCreating, { - tenantId, - timeDTO, - trx, - } as IProjectTimeCreatingEventPayload); - - const time = await Time.query().insert({ - ...timeDTO, - taskId, - projectId: task.projectId, - }); - - // Triggers `onProjectTimeCreated` event. - await this.eventPublisher.emitAsync(events.projectTime.onCreated, { - tenantId, - time, - trx, - } as IProjectTimeCreatedEventPayload); - - return time; - }); - }; -} diff --git a/packages/server/src/services/Projects/Times/DeleteTime.ts b/packages/server/src/services/Projects/Times/DeleteTime.ts deleted file mode 100644 index 91026133f..000000000 --- a/packages/server/src/services/Projects/Times/DeleteTime.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IProjectTimeDeletedEventPayload, - IProjectTimeDeleteEventPayload, - IProjectTimeDeletingEventPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class DeleteTimeService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes the give task's time that associated to the given project. - * @param {number} projectId - - * @returns {Promise} - */ - public deleteTime = async (tenantId: number, timeId: number) => { - const { Time } = this.tenancy.models(tenantId); - - // Validate customer existance. - const oldTime = await Time.query().findById(timeId).throwIfNotFound(); - - // Triggers `onProjectDelete` event. - await this.eventPublisher.emitAsync(events.projectTime.onDelete, { - tenantId, - timeId, - } as IProjectTimeDeleteEventPayload); - - // Deletes the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectDeleting` event. - await this.eventPublisher.emitAsync(events.projectTime.onDeleting, { - tenantId, - oldTime, - trx, - } as IProjectTimeDeletingEventPayload); - - // Upsert the project object. - await Time.query(trx).findById(timeId).delete(); - - // Triggers `onProjectDeleted` event. - await this.eventPublisher.emitAsync(events.projectTime.onDeleted, { - tenantId, - oldTime, - trx, - } as IProjectTimeDeletedEventPayload); - }); - }; -} diff --git a/packages/server/src/services/Projects/Times/EditTime.ts b/packages/server/src/services/Projects/Times/EditTime.ts deleted file mode 100644 index 06d93ab14..000000000 --- a/packages/server/src/services/Projects/Times/EditTime.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { - IProjectTimeEditDTO, - IProjectTimeEditedEventPayload, - IProjectTimeEditEventPayload, - IProjectTimeEditingEventPayload, - IProjectTimeEditPOJO, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class EditTimeService { - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Edits the given project's time that associated to the given task. - * @param {number} tenantId - Tenant id. - * @param {number} taskId - Task id. - * @returns {Promise} - */ - public editTime = async ( - tenantId: number, - timeId: number, - timeDTO: IProjectTimeEditDTO - ): Promise => { - const { Time } = this.tenancy.models(tenantId); - - // Validate customer existance. - const oldTime = await Time.query().findById(timeId).throwIfNotFound(); - - // Triggers `onProjectEdit` event. - await this.eventPublisher.emitAsync(events.projectTime.onEdit, { - tenantId, - oldTime, - timeDTO, - } as IProjectTimeEditEventPayload); - - // Edits the given project under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onProjectEditing` event. - await this.eventPublisher.emitAsync(events.projectTime.onEditing, { - tenantId, - timeDTO, - oldTime, - trx, - } as IProjectTimeEditingEventPayload); - - // Upsert the task's time object. - const time = await Time.query(trx).upsertGraphAndFetch({ - id: timeId, - ...timeDTO, - }); - // Triggers `onProjectEdited` event. - await this.eventPublisher.emitAsync(events.projectTime.onEdited, { - tenantId, - oldTime, - timeDTO, - time, - trx, - } as IProjectTimeEditedEventPayload); - - return time; - }); - }; -} diff --git a/packages/server/src/services/Projects/Times/GetTime.ts b/packages/server/src/services/Projects/Times/GetTime.ts deleted file mode 100644 index 5b0603fee..000000000 --- a/packages/server/src/services/Projects/Times/GetTime.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { IProjectTimeGetPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { TimeTransformer } from './TimeTransformer'; - -@Service() -export class GetTimeService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the tasks list. - * @param {number} tenantId - Tenant Id. - * @param {number} taskId - Task Id. - * @returns {Promise} - */ - public getTime = async ( - tenantId: number, - timeId: number - ): Promise => { - const { Time } = this.tenancy.models(tenantId); - - // Retrieve the project. - const time = await Time.query() - .findById(timeId) - .withGraphFetched('project.contact') - .withGraphFetched('task') - .throwIfNotFound(); - - // Transformes and returns object. - return this.transformer.transform(tenantId, time, new TimeTransformer()); - }; -} diff --git a/packages/server/src/services/Projects/Times/GetTimes.ts b/packages/server/src/services/Projects/Times/GetTimes.ts deleted file mode 100644 index c8adeec6e..000000000 --- a/packages/server/src/services/Projects/Times/GetTimes.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IProjectTimeGetPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TimeTransformer } from './TimeTransformer'; - -@Service() -export class GetTimelineService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the tasks list. - * @param {number} tenantId - Tenant Id. - * @param {number} taskId - Task Id. - * @returns {Promise} - */ - public getTimeline = async ( - tenantId: number, - projectId: number - ): Promise => { - const { Time } = this.tenancy.models(tenantId); - - // Retrieve the project. - const times = await Time.query() - .where('projectId', projectId) - .withGraphFetched('project.contact') - .withGraphFetched('task'); - - // Transformes and returns object. - return this.transformer.transform(tenantId, times, new TimeTransformer()); - }; -} diff --git a/packages/server/src/services/Projects/Times/SyncActualTimeTask.ts b/packages/server/src/services/Projects/Times/SyncActualTimeTask.ts deleted file mode 100644 index 1afe9e5d3..000000000 --- a/packages/server/src/services/Projects/Times/SyncActualTimeTask.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class SyncActualTimeTask { - @Inject() - private tenancy: HasTenancyService; - - /** - * Increases the actual time of the given task. - * @param {number} tenantId - * @param {number} taskId - * @param {number} actualHours - * @param {Knex.Transaction} trx - */ - public increaseActualTimeTask = async ( - tenantId: number, - taskId: number, - actualHours: number, - trx?: Knex.Transaction - ) => { - const { Task } = this.tenancy.models(tenantId); - - await Task.query(trx) - .findById(taskId) - .increment('actualHours', actualHours); - }; - - /** - * Decreases the actual time of the given task. - * @param {number} tenantId - * @param {number} taskId - * @param {number} actualHours - * @param {Knex.Transaction} trx - */ - public decreaseActualTimeTask = async ( - tenantId: number, - taskId: number, - actualHours: number, - trx?: Knex.Transaction - ) => { - const { Task } = this.tenancy.models(tenantId); - - await Task.query(trx) - .findById(taskId) - .decrement('actualHours', actualHours); - }; -} diff --git a/packages/server/src/services/Projects/Times/SyncActualTimeTaskSubscriber.ts b/packages/server/src/services/Projects/Times/SyncActualTimeTaskSubscriber.ts deleted file mode 100644 index 82b24b31b..000000000 --- a/packages/server/src/services/Projects/Times/SyncActualTimeTaskSubscriber.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IProjectTimeCreatedEventPayload, - IProjectTimeDeletedEventPayload, - IProjectTimeEditedEventPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { SyncActualTimeTask } from './SyncActualTimeTask'; - -@Service() -export class SyncActualTimeTaskSubscriber { - @Inject() - private syncActualTimeTask: SyncActualTimeTask; - - /** - * Attaches events with handlers. - * @param bus - */ - attach(bus) { - bus.subscribe( - events.projectTime.onCreated, - this.handleIncreaseActualTimeOnTimeCreate - ); - bus.subscribe( - events.projectTime.onDeleted, - this.handleDecreaseActualTimeOnTimeDelete - ); - bus.subscribe( - events.projectTime.onEdited, - this.handleAdjustActualTimeOnTimeEdited - ); - } - - /** - * Handles increasing the actual time of the task once time entry be created. - * @param {IProjectTimeCreatedEventPayload} payload - - */ - private handleIncreaseActualTimeOnTimeCreate = async ({ - tenantId, - time, - trx, - }: IProjectTimeCreatedEventPayload) => { - await this.syncActualTimeTask.increaseActualTimeTask( - tenantId, - time.taskId, - time.duration, - trx - ); - }; - - /** - * Handle decreasing the actual time of the tsak once time entry be deleted. - * @param {IProjectTimeDeletedEventPayload} payload - */ - private handleDecreaseActualTimeOnTimeDelete = async ({ - tenantId, - oldTime, - trx, - }: IProjectTimeDeletedEventPayload) => { - await this.syncActualTimeTask.decreaseActualTimeTask( - tenantId, - oldTime.taskId, - oldTime.duration, - trx - ); - }; - - /** - * Handle adjusting the actual time of the task once time be edited. - * @param {IProjectTimeEditedEventPayload} payload - - */ - private handleAdjustActualTimeOnTimeEdited = async ({ - tenantId, - time, - oldTime, - trx, - }: IProjectTimeEditedEventPayload) => { - await this.syncActualTimeTask.decreaseActualTimeTask( - tenantId, - oldTime.taskId, - oldTime.duration, - trx - ); - await this.syncActualTimeTask.increaseActualTimeTask( - tenantId, - time.taskId, - time.duration, - trx - ); - }; -} diff --git a/packages/server/src/services/Projects/Times/TimeTransformer.ts b/packages/server/src/services/Projects/Times/TimeTransformer.ts deleted file mode 100644 index e18bd74ca..000000000 --- a/packages/server/src/services/Projects/Times/TimeTransformer.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import Time from 'models/Time'; -import { formatMinutes } from 'utils/formatMinutes'; - -export class TimeTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['projectName', 'taskName', 'customerName', 'durationFormatted']; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['project', 'task']; - }; - - /** - * Retrieves the project name that associated to the time entry. - * @param {Time} time - * @returns {string} - */ - public projectName = (time: Time) => { - return time.project.name; - }; - - /** - * Retrieves the task name that associated to the time entry. - * @param {Time} time - * @returns {string} - */ - public taskName = (time: Time) => { - return time.task.name; - }; - - /** - * Retrieves the customer name that associated to the task of the time entry. - * @param {Time} time - * @returns {string} - */ - public customerName = (time: Time) => { - return time?.project?.contact?.displayName; - }; - - /** - * Retrieves the formatted duration. - * @param {Time} time - * @returns {string} - */ - public durationFormatted = (time: Time) => { - return formatMinutes(time.duration); - } -} diff --git a/packages/server/src/services/Projects/Times/TimesApplication.ts b/packages/server/src/services/Projects/Times/TimesApplication.ts deleted file mode 100644 index 872fc79fb..000000000 --- a/packages/server/src/services/Projects/Times/TimesApplication.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CreateTimeService } from './CreateTime'; -import { EditTimeService } from './EditTime'; -import { GetTimelineService } from './GetTimes'; -import { GetTimeService } from './GetTime'; -import { DeleteTimeService } from './DeleteTime'; -import { - IProjectTimeCreateDTO, - IProjectTimeCreatePOJO, - IProjectTimeEditDTO, - IProjectTimeEditPOJO, - IProjectTimeGetPOJO, -} from '@/interfaces'; - -@Service() -export class TimesApplication { - @Inject() - private createTimeService: CreateTimeService; - - @Inject() - private editTimeService: EditTimeService; - - @Inject() - private deleteTimeService: DeleteTimeService; - - @Inject() - private getTimeService: GetTimeService; - - @Inject() - private getTimelineService: GetTimelineService; - - /** - * Creates a new time for specific project's task. - * @param {number} tenantId - Tenant id. - * @param {IProjectTimeCreateDTO} timeDTO - Create project's time DTO. - * @return {Promise} - */ - public createTime = ( - tenantId: number, - taskId: number, - timeDTO: IProjectTimeCreateDTO - ): Promise => { - return this.createTimeService.createTime(tenantId, taskId, timeDTO); - }; - - /** - * Edits details of the given task. - * @param {number} tenantId - Tenant id. - * @param {number} vendorId - Vendor id. - * @param {IProjectCreateDTO} projectDTO - Create project DTO. - * @returns {Promise} - */ - public editTime = ( - tenantId: number, - timeId: number, - taskDTO: IProjectTimeEditDTO - ): Promise => { - return this.editTimeService.editTime(tenantId, timeId, taskDTO); - }; - - /** - * Deletes the given task. - * @param {number} tenantId - * @param {number} taskId - * @return {Promise} - */ - public deleteTime = (tenantId: number, timeId: number): Promise => { - return this.deleteTimeService.deleteTime(tenantId, timeId); - }; - - /** - * Retrieves the given task details. - * @param {number} tenantId - * @param {number} timeId - * @returns {Promise} - */ - public getTime = ( - tenantId: number, - timeId: number - ): Promise => { - return this.getTimeService.getTime(tenantId, timeId); - }; - - /** - * Retrieves the vendors paginated list. - * @param {number} tenantId - * @param {IVendorsFilter} filterDTO - * @returns {Promise} - */ - public getTimeline = ( - tenantId: number, - projectId: number - ): Promise => { - return this.getTimelineService.getTimeline(tenantId, projectId); - }; -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentBillSync.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentBillSync.ts deleted file mode 100644 index 3447fd2a3..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentBillSync.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IBillPaymentEntryDTO } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { entriesAmountDiff } from '@/utils'; - -@Service() -export class BillPaymentBillSync { - @Inject() - private tenancy: HasTenancyService; - - /** - * Saves bills payment amount changes different. - * @param {number} tenantId - - * @param {IBillPaymentEntryDTO[]} paymentMadeEntries - - * @param {IBillPaymentEntryDTO[]} oldPaymentMadeEntries - - */ - public async saveChangeBillsPaymentAmount( - tenantId: number, - paymentMadeEntries: IBillPaymentEntryDTO[], - oldPaymentMadeEntries?: IBillPaymentEntryDTO[], - trx?: Knex.Transaction - ): Promise { - const { Bill } = this.tenancy.models(tenantId); - const opers: Promise[] = []; - - const diffEntries = entriesAmountDiff( - paymentMadeEntries, - oldPaymentMadeEntries, - 'paymentAmount', - 'billId' - ); - diffEntries.forEach( - (diffEntry: { paymentAmount: number; billId: number }) => { - if (diffEntry.paymentAmount === 0) { - return; - } - const oper = Bill.changePaymentAmount( - diffEntry.billId, - diffEntry.paymentAmount, - trx - ); - opers.push(oper); - } - ); - await Promise.all(opers); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentEntryTransformer.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentEntryTransformer.ts deleted file mode 100644 index 43edf0571..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentEntryTransformer.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from '@/utils'; -import { PurchaseInvoiceTransformer } from '../Bills/PurchaseInvoiceTransformer'; - -export class BillPaymentEntryTransformer extends Transformer { - /** - * Include these attributes to bill payment object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['paymentAmountFormatted', 'bill']; - }; - - /** - * Retreives the - */ - protected bill = (entry) => { - return this.item(entry.bill, new PurchaseInvoiceTransformer()); - }; - - /** - * Retreives the payment amount formatted. - * @returns {string} - */ - protected paymentAmountFormatted(entry) { - return formatNumber(entry.paymentAmount, { money: false }); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentExportable.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentExportable.ts deleted file mode 100644 index 0622d3733..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentExportable.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Exportable } from '@/services/Export/Exportable'; -import { BillPaymentsApplication } from './BillPaymentsApplication'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class BillPaymentExportable extends Exportable { - @Inject() - private billPaymentsApplication: BillPaymentsApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: any) { - const filterQuery = (builder) => { - builder.withGraphFetched('entries.bill'); - builder.withGraphFetched('branch'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery - } as any; - - return this.billPaymentsApplication - .getBillPayments(tenantId, parsedQuery) - .then((output) => output.billPayments); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntries.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntries.ts deleted file mode 100644 index 57f4966d7..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntries.ts +++ /dev/null @@ -1,277 +0,0 @@ -import moment from 'moment'; -import { sumBy } from 'lodash'; -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { AccountNormal, IBillPayment, ILedgerEntry } from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class BillPaymentGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Creates a bill payment GL entries. - * @param {number} tenantId - * @param {number} billPaymentId - * @param {Knex.Transaction} trx - */ - public writePaymentGLEntries = async ( - tenantId: number, - billPaymentId: number, - trx?: Knex.Transaction - ): Promise => { - const { accountRepository } = this.tenancy.repositories(tenantId); - const { BillPayment, Account } = this.tenancy.models(tenantId); - - // Retrieves the bill payment details with associated entries. - const payment = await BillPayment.query(trx) - .findById(billPaymentId) - .withGraphFetched('entries.bill'); - - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Finds or creates a new A/P account of the given currency. - const APAccount = await accountRepository.findOrCreateAccountsPayable( - payment.currencyCode, - {}, - trx - ); - // Exchange gain or loss account. - const EXGainLossAccount = await Account.query(trx).modify( - 'findBySlug', - 'exchange-grain-loss' - ); - // Retrieves the bill payment ledger. - const ledger = this.getBillPaymentLedger( - payment, - APAccount.id, - EXGainLossAccount.id, - tenantMeta.baseCurrency - ); - // Commits the ledger on the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Rewrites the bill payment GL entries. - * @param {number} tenantId - * @param {number} billPaymentId - * @param {Knex.Transaction} trx - */ - public rewritePaymentGLEntries = async ( - tenantId: number, - billPaymentId: number, - trx?: Knex.Transaction - ): Promise => { - // Revert payment GL entries. - await this.revertPaymentGLEntries(tenantId, billPaymentId, trx); - - // Write payment GL entries. - await this.writePaymentGLEntries(tenantId, billPaymentId, trx); - }; - - /** - * Reverts the bill payment GL entries. - * @param {number} tenantId - * @param {number} billPaymentId - * @param {Knex.Transaction} trx - */ - public revertPaymentGLEntries = async ( - tenantId: number, - billPaymentId: number, - trx?: Knex.Transaction - ): Promise => { - await this.ledgerStorage.deleteByReference( - tenantId, - billPaymentId, - 'BillPayment', - trx - ); - }; - - /** - * Retrieves the payment common entry. - * @param {IBillPayment} billPayment - * @returns {} - */ - private getPaymentCommonEntry = (billPayment: IBillPayment) => { - const formattedDate = moment(billPayment.paymentDate).format('YYYY-MM-DD'); - - return { - debit: 0, - credit: 0, - - exchangeRate: billPayment.exchangeRate, - currencyCode: billPayment.currencyCode, - - transactionId: billPayment.id, - transactionType: 'BillPayment', - - transactionNumber: billPayment.paymentNumber, - referenceNumber: billPayment.reference, - - date: formattedDate, - createdAt: billPayment.createdAt, - - branchId: billPayment.branchId, - }; - }; - - /** - * Calculates the payment total exchange gain/loss. - * @param {IBillPayment} paymentReceive - Payment receive with entries. - * @returns {number} - */ - private getPaymentExGainOrLoss = (billPayment: IBillPayment): number => { - return sumBy(billPayment.entries, (entry) => { - const paymentLocalAmount = entry.paymentAmount * billPayment.exchangeRate; - const invoicePayment = entry.paymentAmount * entry.bill.exchangeRate; - - return invoicePayment - paymentLocalAmount; - }); - }; - - /** - * Retrieves the payment exchange gain/loss entries. - * @param {IBillPayment} billPayment - - * @param {number} APAccountId - - * @param {number} gainLossAccountId - - * @param {string} baseCurrency - - * @returns {ILedgerEntry[]} - */ - private getPaymentExGainOrLossEntries = ( - billPayment: IBillPayment, - APAccountId: number, - gainLossAccountId: number, - baseCurrency: string - ): ILedgerEntry[] => { - const commonEntry = this.getPaymentCommonEntry(billPayment); - const totalExGainOrLoss = this.getPaymentExGainOrLoss(billPayment); - const absExGainOrLoss = Math.abs(totalExGainOrLoss); - - return totalExGainOrLoss - ? [ - { - ...commonEntry, - currencyCode: baseCurrency, - exchangeRate: 1, - credit: totalExGainOrLoss > 0 ? absExGainOrLoss : 0, - debit: totalExGainOrLoss < 0 ? absExGainOrLoss : 0, - accountId: gainLossAccountId, - index: 2, - indexGroup: 20, - accountNormal: AccountNormal.DEBIT, - }, - { - ...commonEntry, - currencyCode: baseCurrency, - exchangeRate: 1, - debit: totalExGainOrLoss > 0 ? absExGainOrLoss : 0, - credit: totalExGainOrLoss < 0 ? absExGainOrLoss : 0, - accountId: APAccountId, - index: 3, - accountNormal: AccountNormal.DEBIT, - }, - ] - : []; - }; - - /** - * Retrieves the payment deposit GL entry. - * @param {IBillPayment} billPayment - * @returns {ILedgerEntry} - */ - private getPaymentGLEntry = (billPayment: IBillPayment): ILedgerEntry => { - const commonEntry = this.getPaymentCommonEntry(billPayment); - - return { - ...commonEntry, - credit: billPayment.localAmount, - accountId: billPayment.paymentAccountId, - accountNormal: AccountNormal.DEBIT, - index: 2, - }; - }; - - /** - * Retrieves the payment GL payable entry. - * @param {IBillPayment} billPayment - * @param {number} APAccountId - * @returns {ILedgerEntry} - */ - private getPaymentGLPayableEntry = ( - billPayment: IBillPayment, - APAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getPaymentCommonEntry(billPayment); - - return { - ...commonEntry, - exchangeRate: billPayment.exchangeRate, - debit: billPayment.localAmount, - contactId: billPayment.vendorId, - accountId: APAccountId, - accountNormal: AccountNormal.CREDIT, - index: 1, - }; - }; - - /** - * Retrieves the payment GL entries. - * @param {IBillPayment} billPayment - * @param {number} APAccountId - * @returns {ILedgerEntry[]} - */ - private getPaymentGLEntries = ( - billPayment: IBillPayment, - APAccountId: number, - gainLossAccountId: number, - baseCurrency: string - ): ILedgerEntry[] => { - // Retrieves the payment deposit entry. - const paymentEntry = this.getPaymentGLEntry(billPayment); - - // Retrieves the payment debit A/R entry. - const payableEntry = this.getPaymentGLPayableEntry( - billPayment, - APAccountId - ); - // Retrieves the exchange gain/loss entries. - const exGainLossEntries = this.getPaymentExGainOrLossEntries( - billPayment, - APAccountId, - gainLossAccountId, - baseCurrency - ); - return [paymentEntry, payableEntry, ...exGainLossEntries]; - }; - - /** - * Retrieves the bill payment ledger. - * @param {IBillPayment} billPayment - * @param {number} APAccountId - * @returns {Ledger} - */ - private getBillPaymentLedger = ( - billPayment: IBillPayment, - APAccountId: number, - gainLossAccountId: number, - baseCurrency: string - ): Ledger => { - const entries = this.getPaymentGLEntries( - billPayment, - APAccountId, - gainLossAccountId, - baseCurrency - ); - return new Ledger(entries); - }; -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber.ts deleted file mode 100644 index cdfb456d5..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IBillPaymentEventCreatedPayload, - IBillPaymentEventDeletedPayload, - IBillPaymentEventEditedPayload, -} from '@/interfaces'; -import { BillPaymentGLEntries } from './BillPaymentGLEntries'; - -@Service() -export class PaymentWriteGLEntriesSubscriber { - @Inject() - private billPaymentGLEntries: BillPaymentGLEntries; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe(events.billPayment.onCreated, this.handleWriteJournalEntries); - bus.subscribe( - events.billPayment.onEdited, - this.handleRewriteJournalEntriesOncePaymentEdited - ); - bus.subscribe( - events.billPayment.onDeleted, - this.handleRevertJournalEntries - ); - } - - /** - * Handle bill payment writing journal entries once created. - */ - private handleWriteJournalEntries = async ({ - tenantId, - billPayment, - trx, - }: IBillPaymentEventCreatedPayload) => { - // Records the journal transactions after bills payment - // and change diff account balance. - await this.billPaymentGLEntries.writePaymentGLEntries( - tenantId, - billPayment.id, - trx - ); - }; - - /** - * Handle bill payment re-writing journal entries once the payment transaction be edited. - */ - private handleRewriteJournalEntriesOncePaymentEdited = async ({ - tenantId, - billPayment, - trx, - }: IBillPaymentEventEditedPayload) => { - await this.billPaymentGLEntries.rewritePaymentGLEntries( - tenantId, - billPayment.id, - trx - ); - }; - - /** - * Reverts journal entries once bill payment deleted. - */ - private handleRevertJournalEntries = async ({ - tenantId, - billPaymentId, - trx, - }: IBillPaymentEventDeletedPayload) => { - await this.billPaymentGLEntries.revertPaymentGLEntries( - tenantId, - billPaymentId, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentTransactionTransformer.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentTransactionTransformer.ts deleted file mode 100644 index 598609e44..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentTransactionTransformer.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class BillPaymentTransactionTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['formattedPaymentAmount', 'formattedPaymentDate']; - }; - - /** - * Retrieve formatted bill payment amount. - * @param {ICreditNote} credit - * @returns {string} - */ - protected formattedPaymentAmount = (entry): string => { - return formatNumber(entry.paymentAmount, { - currencyCode: entry.payment.currencyCode, - }); - }; - - /** - * Retrieve formatted bill payment date. - * @param entry - * @returns {string} - */ - protected formattedPaymentDate = (entry): string => { - return this.formatDate(entry.payment.paymentDate); - }; - - /** - * - * @param entry - * @returns - */ - public transform = (entry) => { - return { - billId: entry.billId, - billPaymentId: entry.billPaymentId, - - paymentDate: entry.payment.paymentDate, - formattedPaymentDate: entry.formattedPaymentDate, - - paymentAmount: entry.paymentAmount, - formattedPaymentAmount: entry.formattedPaymentAmount, - currencyCode: entry.payment.currencyCode, - - paymentNumber: entry.payment.paymentNumber, - paymentReferenceNo: entry.payment.reference, - - billNumber: entry.bill.billNumber, - billReferenceNo: entry.bill.referenceNo, - - paymentAccountId: entry.payment.paymentAccountId, - paymentAccountName: entry.payment.paymentAccount.name, - paymentAccountSlug: entry.payment.paymentAccount.slug, - }; - }; -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentTransformer.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentTransformer.ts deleted file mode 100644 index 6299b3758..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentTransformer.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { IBillPayment } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { BillPaymentEntryTransformer } from './BillPaymentEntryTransformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; - -export class BillPaymentTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedPaymentDate', - 'formattedCreatedAt', - 'formattedAmount', - 'entries', - 'attachments', - ]; - }; - - /** - * Retrieve formatted invoice date. - * @param {IBill} invoice - * @returns {String} - */ - protected formattedPaymentDate = (billPayment: IBillPayment): string => { - return this.formatDate(billPayment.paymentDate); - }; - - /** - * Retrieve formatted created at date. - * @param {IBillPayment} billPayment - * @returns {string} - */ - protected formattedCreatedAt = (billPayment: IBillPayment): string => { - return this.formatDate(billPayment.createdAt); - } - - /** - * Retrieve formatted bill amount. - * @param {IBill} invoice - * @returns {string} - */ - protected formattedAmount = (billPayment: IBillPayment): string => { - return formatNumber(billPayment.amount, { - currencyCode: billPayment.currencyCode, - }); - }; - - /** - * Retreives the bill payment entries. - */ - protected entries = (billPayment) => { - return this.item(billPayment.entries, new BillPaymentEntryTransformer()); - }; - - /** - * Retrieves the bill attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (billPayment) => { - return this.item(billPayment.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentValidators.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentValidators.ts deleted file mode 100644 index 8bbfadbff..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentValidators.ts +++ /dev/null @@ -1,264 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { sumBy, difference } from 'lodash'; -import { - IBill, - IBillPaymentDTO, - IBillPaymentEntryDTO, - IBillPayment, - IBillPaymentEntry, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; -import { ERRORS } from './constants'; - -@Service() -export class BillPaymentValidators { - @Inject() - private tenancy: TenancyService; - - /** - * Validates the bill payment existance. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - public async getPaymentMadeOrThrowError( - tenantid: number, - paymentMadeId: number - ) { - const { BillPayment } = this.tenancy.models(tenantid); - const billPayment = await BillPayment.query() - .withGraphFetched('entries') - .findById(paymentMadeId); - - if (!billPayment) { - throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND); - } - return billPayment; - } - - /** - * Validates the payment account. - * @param {number} tenantId - - * @param {number} paymentAccountId - * @return {Promise} - */ - public async getPaymentAccountOrThrowError( - tenantId: number, - paymentAccountId: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const paymentAccount = await accountRepository.findOneById( - paymentAccountId - ); - if (!paymentAccount) { - throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_FOUND); - } - // Validate the payment account type. - if ( - !paymentAccount.isAccountType([ - ACCOUNT_TYPE.BANK, - ACCOUNT_TYPE.CASH, - ACCOUNT_TYPE.OTHER_CURRENT_ASSET, - ]) - ) { - throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE); - } - return paymentAccount; - } - - /** - * Validates the payment number uniqness. - * @param {number} tenantId - - * @param {string} paymentMadeNumber - - * @return {Promise} - */ - public async validatePaymentNumber( - tenantId: number, - paymentMadeNumber: string, - notPaymentMadeId?: number - ) { - const { BillPayment } = this.tenancy.models(tenantId); - - const foundBillPayment = await BillPayment.query().onBuild( - (builder: any) => { - builder.findOne('payment_number', paymentMadeNumber); - - if (notPaymentMadeId) { - builder.whereNot('id', notPaymentMadeId); - } - } - ); - - if (foundBillPayment) { - throw new ServiceError(ERRORS.BILL_PAYMENT_NUMBER_NOT_UNQIUE); - } - return foundBillPayment; - } - - /** - * Validate whether the entries bills ids exist on the storage. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async validateBillsExistance( - tenantId: number, - billPaymentEntries: { billId: number }[], - vendorId: number - ) { - const { Bill } = this.tenancy.models(tenantId); - const entriesBillsIds = billPaymentEntries.map((e: any) => e.billId); - - const storedBills = await Bill.query() - .whereIn('id', entriesBillsIds) - .where('vendor_id', vendorId); - - const storedBillsIds = storedBills.map((t: IBill) => t.id); - const notFoundBillsIds = difference(entriesBillsIds, storedBillsIds); - - if (notFoundBillsIds.length > 0) { - throw new ServiceError(ERRORS.BILL_ENTRIES_IDS_NOT_FOUND); - } - // Validate the not opened bills. - const notOpenedBills = storedBills.filter((bill) => !bill.openedAt); - - if (notOpenedBills.length > 0) { - throw new ServiceError(ERRORS.BILLS_NOT_OPENED_YET, null, { - notOpenedBills, - }); - } - return storedBills; - } - - /** - * Validate wether the payment amount bigger than the payable amount. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - * @return {void} - */ - public async validateBillsDueAmount( - tenantId: number, - billPaymentEntries: IBillPaymentEntryDTO[], - oldPaymentEntries: IBillPaymentEntry[] = [] - ) { - const { Bill } = this.tenancy.models(tenantId); - const billsIds = billPaymentEntries.map( - (entry: IBillPaymentEntryDTO) => entry.billId - ); - - const storedBills = await Bill.query().whereIn('id', billsIds); - const storedBillsMap = new Map( - storedBills.map((bill) => { - const oldEntries = oldPaymentEntries.filter( - (entry) => entry.billId === bill.id - ); - const oldPaymentAmount = sumBy(oldEntries, 'paymentAmount') || 0; - - return [ - bill.id, - { ...bill, dueAmount: bill.dueAmount + oldPaymentAmount }, - ]; - }) - ); - interface invalidPaymentAmountError { - index: number; - due_amount: number; - } - const hasWrongPaymentAmount: invalidPaymentAmountError[] = []; - - billPaymentEntries.forEach((entry: IBillPaymentEntryDTO, index: number) => { - const entryBill = storedBillsMap.get(entry.billId); - const { dueAmount } = entryBill; - - if (dueAmount < entry.paymentAmount) { - hasWrongPaymentAmount.push({ index, due_amount: dueAmount }); - } - }); - if (hasWrongPaymentAmount.length > 0) { - throw new ServiceError(ERRORS.INVALID_BILL_PAYMENT_AMOUNT); - } - } - - /** - * Validate the payment receive entries IDs existance. - * @param {Request} req - * @param {Response} res - * @return {Response} - */ - public async validateEntriesIdsExistance( - tenantId: number, - billPaymentId: number, - billPaymentEntries: IBillPaymentEntry[] - ) { - const { BillPaymentEntry } = this.tenancy.models(tenantId); - - const entriesIds = billPaymentEntries - .filter((entry: any) => entry.id) - .map((entry: any) => entry.id); - - const storedEntries = await BillPaymentEntry.query().where( - 'bill_payment_id', - billPaymentId - ); - - const storedEntriesIds = storedEntries.map((entry: any) => entry.id); - const notFoundEntriesIds = difference(entriesIds, storedEntriesIds); - - if (notFoundEntriesIds.length > 0) { - throw new ServiceError(ERRORS.BILL_PAYMENT_ENTRIES_NOT_FOUND); - } - } - - /** - * * Validate the payment vendor whether modified. - * @param {string} billPaymentNo - */ - public validateVendorNotModified( - billPaymentDTO: IBillPaymentDTO, - oldBillPayment: IBillPayment - ) { - if (billPaymentDTO.vendorId !== oldBillPayment.vendorId) { - throw new ServiceError(ERRORS.PAYMENT_NUMBER_SHOULD_NOT_MODIFY); - } - } - - /** - * Validates the payment account currency code. The deposit account curreny - * should be equals the customer currency code or the base currency. - * @param {string} paymentAccountCurrency - * @param {string} customerCurrency - * @param {string} baseCurrency - * @throws {ServiceError(ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID)} - */ - public validateWithdrawalAccountCurrency = ( - paymentAccountCurrency: string, - customerCurrency: string, - baseCurrency: string - ) => { - if ( - paymentAccountCurrency !== customerCurrency && - paymentAccountCurrency !== baseCurrency - ) { - throw new ServiceError(ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID); - } - }; - - /** - * Validates the given vendor has no associated payments. - * @param {number} tenantId - * @param {number} vendorId - */ - public async validateVendorHasNoPayments(tenantId: number, vendorId: number) { - const { BillPayment } = this.tenancy.models(tenantId); - - const payments = await BillPayment.query().where('vendor_id', vendorId); - - if (payments.length > 0) { - throw new ServiceError(ERRORS.VENDOR_HAS_PAYMENTS); - } - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentsApplication.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentsApplication.ts deleted file mode 100644 index c7f8923b1..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentsApplication.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IBillPaymentDTO, IBillPayment } from '@/interfaces'; -import { CreateBillPayment } from './CreateBillPayment'; -import { DeleteBillPayment } from './DeleteBillPayment'; -import { EditBillPayment } from './EditBillPayment'; -import { GetBillPayments } from './GetBillPayments'; -import { GetBillPayment } from './GetBillPayment'; -import { GetPaymentBills } from './GetPaymentBills'; - -/** - * Bill payments application. - * @service - */ -@Service() -export class BillPaymentsApplication { - @Inject() - private createBillPaymentService: CreateBillPayment; - - @Inject() - private deleteBillPaymentService: DeleteBillPayment; - - @Inject() - private editBillPaymentService: EditBillPayment; - - @Inject() - private getBillPaymentsService: GetBillPayments; - - @Inject() - private getBillPaymentService: GetBillPayment; - - @Inject() - private getPaymentBillsService: GetPaymentBills; - - /** - * Creates a bill payment with associated GL entries. - * @param {number} tenantId - * @param {IBillPaymentDTO} billPaymentDTO - * @returns {Promise} - */ - public createBillPayment( - tenantId: number, - billPaymentDTO: IBillPaymentDTO - ): Promise { - return this.createBillPaymentService.createBillPayment( - tenantId, - billPaymentDTO - ); - } - - /** - * Delets the given bill payment with associated GL entries. - * @param {number} tenantId - * @param {number} billPaymentId - */ - public deleteBillPayment(tenantId: number, billPaymentId: number) { - return this.deleteBillPaymentService.deleteBillPayment( - tenantId, - billPaymentId - ); - } - - /** - * Edits the given bill payment with associated GL entries. - * @param {number} tenantId - * @param {number} billPaymentId - * @param billPaymentDTO - * @returns {Promise} - */ - public editBillPayment( - tenantId: number, - billPaymentId: number, - billPaymentDTO - ): Promise { - return this.editBillPaymentService.editBillPayment( - tenantId, - billPaymentId, - billPaymentDTO - ); - } - - /** - * Retrieves bill payments list. - * @param {number} tenantId - * @param filterDTO - * @returns - */ - public getBillPayments(tenantId: number, filterDTO: IBillPaymentsFilter) { - return this.getBillPaymentsService.getBillPayments(tenantId, filterDTO); - } - - /** - * Retrieve specific bill payment. - * @param {number} tenantId - * @param {number} billPyamentId - * @returns - */ - public getBillPayment(tenantId: number, billPyamentId: number) { - return this.getBillPaymentService.getBillPayment(tenantId, billPyamentId); - } - - /** - * Retrieve payment made associated bills. - * @param {number} tenantId - - * @param {number} billPaymentId - - */ - public getPaymentBills(tenantId: number, billPaymentId: number) { - return this.getPaymentBillsService.getPaymentBills(tenantId, billPaymentId); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentsImportable.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentsImportable.ts deleted file mode 100644 index 343d4e532..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentsImportable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IBillPaymentDTO } from '@/interfaces'; -import { CreateBillPayment } from './CreateBillPayment'; -import { Importable } from '@/services/Import/Importable'; -import { BillsPaymentsSampleData } from './constants'; - -@Service() -export class BillPaymentsImportable extends Importable { - @Inject() - private createBillPaymentService: CreateBillPayment; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - billPaymentDTO: IBillPaymentDTO, - trx?: Knex.Transaction - ) { - return this.createBillPaymentService.createBillPayment( - tenantId, - billPaymentDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return BillsPaymentsSampleData; - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/BillPaymentsPages.ts b/packages/server/src/services/Purchases/BillPayments/BillPaymentsPages.ts deleted file mode 100644 index a23d0c472..000000000 --- a/packages/server/src/services/Purchases/BillPayments/BillPaymentsPages.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { omit } from 'lodash'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { IBill, IBillPayment, IBillReceivePageEntry } from '@/interfaces'; -import { ERRORS } from './constants'; -import { ServiceError } from '@/exceptions'; - -@Service() -export default class BillPaymentsPages { - @Inject() - private tenancy: TenancyService; - - /** - * Retrieve bill payment with associated metadata. - * @param {number} billPaymentId - The bill payment id. - * @return {object} - */ - public async getBillPaymentEditPage( - tenantId: number, - billPaymentId: number - ): Promise<{ - billPayment: Omit; - entries: IBillReceivePageEntry[]; - }> { - const { BillPayment, Bill } = this.tenancy.models(tenantId); - const billPayment = await BillPayment.query() - .findById(billPaymentId) - .withGraphFetched('entries.bill') - .withGraphFetched('attachments'); - - // Throw not found the bill payment. - if (!billPayment) { - throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND); - } - const paymentEntries = billPayment.entries.map((entry) => ({ - ...this.mapBillToPageEntry(entry.bill), - dueAmount: entry.bill.dueAmount + entry.paymentAmount, - paymentAmount: entry.paymentAmount, - })); - - const resPayableBills = await Bill.query() - .modify('opened') - .modify('dueBills') - .where('vendor_id', billPayment.vendorId) - .whereNotIn( - 'id', - billPayment.entries.map((e) => e.billId) - ) - .orderBy('bill_date', 'ASC'); - - // Mapping the payable bills to entries. - const restPayableEntries = resPayableBills.map(this.mapBillToPageEntry); - const entries = [...paymentEntries, ...restPayableEntries]; - - return { - billPayment: omit(billPayment, ['entries']), - entries, - }; - } - - /** - * Retrieve the payable entries of the new page once vendor be selected. - * @param {number} tenantId - * @param {number} vendorId - */ - public async getNewPageEntries( - tenantId: number, - vendorId: number - ): Promise { - const { Bill } = this.tenancy.models(tenantId); - - // Retrieve all payable bills that associated to the payment made transaction. - const payableBills = await Bill.query() - .modify('opened') - .modify('dueBills') - .where('vendor_id', vendorId) - .orderBy('bill_date', 'ASC'); - - return payableBills.map(this.mapBillToPageEntry); - } - - /** - * Retrive edit page invoices entries from the given sale invoices models. - * @param {ISaleInvoice[]} invoices - Invoices. - * @return {IPaymentReceiveEditPageEntry} - */ - private mapBillToPageEntry(bill: IBill): IBillReceivePageEntry { - return { - entryType: 'invoice', - billId: bill.id, - billNo: bill.billNumber, - amount: bill.amount, - dueAmount: bill.dueAmount, - totalPaymentAmount: bill.paymentAmount, - paymentAmount: bill.paymentAmount, - currencyCode: bill.currencyCode, - date: bill.billDate, - }; - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/CommandBillPaymentDTOTransformer.ts b/packages/server/src/services/Purchases/BillPayments/CommandBillPaymentDTOTransformer.ts deleted file mode 100644 index 9edacd478..000000000 --- a/packages/server/src/services/Purchases/BillPayments/CommandBillPaymentDTOTransformer.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { omit, sumBy } from 'lodash'; -import { IBillPayment, IBillPaymentDTO, IVendor } from '@/interfaces'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; -import { formatDateFields } from '@/utils'; - -@Service() -export class CommandBillPaymentDTOTransformer { - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - /** - * Transforms create/edit DTO to model. - * @param {number} tenantId - * @param {IBillPaymentDTO} billPaymentDTO - Bill payment. - * @param {IBillPayment} oldBillPayment - Old bill payment. - * @return {Promise} - */ - public async transformDTOToModel( - tenantId: number, - billPaymentDTO: IBillPaymentDTO, - vendor: IVendor, - oldBillPayment?: IBillPayment - ): Promise { - const amount = - billPaymentDTO.amount ?? sumBy(billPaymentDTO.entries, 'paymentAmount'); - - // Associate the default index to each item entry. - const entries = R.compose( - // Associate the default index to payment entries. - assocItemEntriesDefaultIndex - )(billPaymentDTO.entries); - - const initialDTO = { - ...formatDateFields(omit(billPaymentDTO, ['attachments']), [ - 'paymentDate', - ]), - amount, - currencyCode: vendor.currencyCode, - exchangeRate: billPaymentDTO.exchangeRate || 1, - entries, - }; - return R.compose( - this.branchDTOTransform.transformDTO(tenantId) - )(initialDTO); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/CreateBillPayment.ts b/packages/server/src/services/Purchases/BillPayments/CreateBillPayment.ts deleted file mode 100644 index ed16e0715..000000000 --- a/packages/server/src/services/Purchases/BillPayments/CreateBillPayment.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IBillPaymentDTO, - IBillPayment, - IBillPaymentEventCreatedPayload, - IBillPaymentCreatingPayload, -} from '@/interfaces'; -import { TenantMetadata } from '@/system/models'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { BillPaymentValidators } from './BillPaymentValidators'; -import { CommandBillPaymentDTOTransformer } from './CommandBillPaymentDTOTransformer'; - -@Service() -export class CreateBillPayment { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: BillPaymentValidators; - - @Inject() - private commandTransformerDTO: CommandBillPaymentDTOTransformer; - - /** - * Creates a new bill payment transcations and store it to the storage - * with associated bills entries and journal transactions. - * ------ - * Precedures:- - * ------ - * - Records the bill payment transaction. - * - Records the bill payment associated entries. - * - Increment the payment amount of the given vendor bills. - * - Decrement the vendor balance. - * - Records payment journal entries. - * ------ - * @param {number} tenantId - Tenant id. - * @param {BillPaymentDTO} billPayment - Bill payment object. - */ - public async createBillPayment( - tenantId: number, - billPaymentDTO: IBillPaymentDTO, - trx?: Knex.Transaction - ): Promise { - const { BillPayment, Contact } = this.tenancy.models(tenantId); - - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieves the payment vendor or throw not found error. - const vendor = await Contact.query() - .findById(billPaymentDTO.vendorId) - .modify('vendor') - .throwIfNotFound(); - - // Transform create DTO to model object. - const billPaymentObj = await this.commandTransformerDTO.transformDTOToModel( - tenantId, - billPaymentDTO, - vendor - ); - // Validate the payment account existance and type. - const paymentAccount = await this.validators.getPaymentAccountOrThrowError( - tenantId, - billPaymentObj.paymentAccountId - ); - // Validate the payment number uniquiness. - if (billPaymentObj.paymentNumber) { - await this.validators.validatePaymentNumber( - tenantId, - billPaymentObj.paymentNumber - ); - } - // Validates the bills existance and associated to the given vendor. - await this.validators.validateBillsExistance( - tenantId, - billPaymentObj.entries, - billPaymentDTO.vendorId - ); - // Validates the bills due payment amount. - await this.validators.validateBillsDueAmount( - tenantId, - billPaymentObj.entries - ); - // Validates the withdrawal account currency code. - this.validators.validateWithdrawalAccountCurrency( - paymentAccount.currencyCode, - vendor.currencyCode, - tenantMeta.baseCurrency - ); - // Writes bill payment transacation with associated transactions - // under unit-of-work envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onBillPaymentCreating` event. - await this.eventPublisher.emitAsync(events.billPayment.onCreating, { - tenantId, - billPaymentDTO, - trx, - } as IBillPaymentCreatingPayload); - - // Writes the bill payment graph to the storage. - const billPayment = await BillPayment.query(trx).insertGraphAndFetch({ - ...billPaymentObj, - }); - // Triggers `onBillPaymentCreated` event. - await this.eventPublisher.emitAsync(events.billPayment.onCreated, { - tenantId, - billPayment, - billPaymentId: billPayment.id, - billPaymentDTO, - trx, - } as IBillPaymentEventCreatedPayload); - - return billPayment; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/DeleteBillPayment.ts b/packages/server/src/services/Purchases/BillPayments/DeleteBillPayment.ts deleted file mode 100644 index e4a1ab1fa..000000000 --- a/packages/server/src/services/Purchases/BillPayments/DeleteBillPayment.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Knex } from 'knex'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { - IBillPaymentDeletingPayload, - IBillPaymentEventDeletedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; - -@Service() -export class DeleteBillPayment { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the bill payment and associated transactions. - * @param {number} tenantId - Tenant id. - * @param {Integer} billPaymentId - The given bill payment id. - * @return {Promise} - */ - public async deleteBillPayment(tenantId: number, billPaymentId: number) { - const { BillPayment, BillPaymentEntry } = this.tenancy.models(tenantId); - - // Retrieve the bill payment or throw not found service error. - const oldBillPayment = await BillPayment.query() - .withGraphFetched('entries') - .findById(billPaymentId) - .throwIfNotFound(); - - // Deletes the bill transactions with associated transactions under - // unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBillPaymentDeleting` payload. - await this.eventPublisher.emitAsync(events.billPayment.onDeleting, { - tenantId, - trx, - oldBillPayment, - } as IBillPaymentDeletingPayload); - - // Deletes the bill payment assocaited entries. - await BillPaymentEntry.query(trx) - .where('bill_payment_id', billPaymentId) - .delete(); - - // Deletes the bill payment transaction. - await BillPayment.query(trx).where('id', billPaymentId).delete(); - - // Triggers `onBillPaymentDeleted` event. - await this.eventPublisher.emitAsync(events.billPayment.onDeleted, { - tenantId, - billPaymentId, - oldBillPayment, - trx, - } as IBillPaymentEventDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/EditBillPayment.ts b/packages/server/src/services/Purchases/BillPayments/EditBillPayment.ts deleted file mode 100644 index 78141b035..000000000 --- a/packages/server/src/services/Purchases/BillPayments/EditBillPayment.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { BillPaymentValidators } from './BillPaymentValidators'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - IBillPayment, - IBillPaymentEditingPayload, - IBillPaymentEventEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { Knex } from 'knex'; -import UnitOfWork from '@/services/UnitOfWork'; -import { CommandBillPaymentDTOTransformer } from './CommandBillPaymentDTOTransformer'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class EditBillPayment { - @Inject() - private validators: BillPaymentValidators; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private transformer: CommandBillPaymentDTOTransformer; - - /** - * Edits the details of the given bill payment. - * - * Preceducres: - * ------ - * - Update the bill payment transaction. - * - Insert the new bill payment entries that have no ids. - * - Update the bill paymeny entries that have ids. - * - Delete the bill payment entries that not presented. - * - Re-insert the journal transactions and update the diff accounts balance. - * - Update the diff vendor balance. - * - Update the diff bill payment amount. - * ------ - * @param {number} tenantId - Tenant id - * @param {Integer} billPaymentId - * @param {BillPaymentDTO} billPayment - * @param {IBillPayment} oldBillPayment - */ - public async editBillPayment( - tenantId: number, - billPaymentId: number, - billPaymentDTO - ): Promise { - const { BillPayment, Contact } = this.tenancy.models(tenantId); - - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - const oldBillPayment = await BillPayment.query() - .findById(billPaymentId) - .withGraphFetched('entries') - .throwIfNotFound(); - - // Retrieves the bill payment vendor or throw not found error. - const vendor = await Contact.query() - .modify('vendor') - .findById(billPaymentDTO.vendorId) - .throwIfNotFound(); - - // Transform bill payment DTO to model object. - const billPaymentObj = await this.transformer.transformDTOToModel( - tenantId, - billPaymentDTO, - vendor, - oldBillPayment - ); - // Validate vendor not modified. - this.validators.validateVendorNotModified(billPaymentDTO, oldBillPayment); - - // Validate the payment account existance and type. - const paymentAccount = await this.validators.getPaymentAccountOrThrowError( - tenantId, - billPaymentObj.paymentAccountId - ); - // Validate the items entries IDs existance on the storage. - await this.validators.validateEntriesIdsExistance( - tenantId, - billPaymentId, - billPaymentObj.entries - ); - // Validate the bills existance and associated to the given vendor. - await this.validators.validateBillsExistance( - tenantId, - billPaymentObj.entries, - billPaymentDTO.vendorId - ); - // Validates the bills due payment amount. - await this.validators.validateBillsDueAmount( - tenantId, - billPaymentObj.entries, - oldBillPayment.entries - ); - // Validate the payment number uniquiness. - if (billPaymentObj.paymentNumber) { - await this.validators.validatePaymentNumber( - tenantId, - billPaymentObj.paymentNumber, - billPaymentId - ); - } - // Validates the withdrawal account currency code. - this.validators.validateWithdrawalAccountCurrency( - paymentAccount.currencyCode, - vendor.currencyCode, - tenantMeta.baseCurrency - ); - // Edits the bill transactions with associated transactions - // under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBillPaymentEditing` event. - await this.eventPublisher.emitAsync(events.billPayment.onEditing, { - tenantId, - oldBillPayment, - billPaymentDTO, - trx, - } as IBillPaymentEditingPayload); - - // Edits the bill payment transaction graph on the storage. - const billPayment = await BillPayment.query(trx).upsertGraphAndFetch({ - id: billPaymentId, - ...billPaymentObj, - }); - // Triggers `onBillPaymentEdited` event. - await this.eventPublisher.emitAsync(events.billPayment.onEdited, { - tenantId, - billPaymentId, - billPayment, - oldBillPayment, - billPaymentDTO, - trx, - } as IBillPaymentEventEditedPayload); - - return billPayment; - }); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/GetBillPayment.ts b/packages/server/src/services/Purchases/BillPayments/GetBillPayment.ts deleted file mode 100644 index 6383c8a4e..000000000 --- a/packages/server/src/services/Purchases/BillPayments/GetBillPayment.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { IBillPayment } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { BillPaymentTransformer } from './BillPaymentTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetBillPayment { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves bill payment. - * @param {number} tenantId - * @param {number} billPyamentId - * @return {Promise} - */ - public async getBillPayment( - tenantId: number, - billPyamentId: number - ): Promise { - const { BillPayment } = this.tenancy.models(tenantId); - - const billPayment = await BillPayment.query() - .withGraphFetched('entries.bill') - .withGraphFetched('vendor') - .withGraphFetched('paymentAccount') - .withGraphFetched('transactions') - .withGraphFetched('branch') - .withGraphFetched('attachments') - .findById(billPyamentId) - .throwIfNotFound(); - - return this.transformer.transform( - tenantId, - billPayment, - new BillPaymentTransformer() - ); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/GetBillPayments.ts b/packages/server/src/services/Purchases/BillPayments/GetBillPayments.ts deleted file mode 100644 index 518e90b4f..000000000 --- a/packages/server/src/services/Purchases/BillPayments/GetBillPayments.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { - IBillPayment, - IBillPaymentsFilter, - IPaginationMeta, - IFilterMeta, -} from '@/interfaces'; -import { BillPaymentTransformer } from './BillPaymentTransformer'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetBillPayments { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve bill payment paginted and filterable list. - * @param {number} tenantId - * @param {IBillPaymentsFilter} billPaymentsFilter - */ - public async getBillPayments( - tenantId: number, - filterDTO: IBillPaymentsFilter - ): Promise<{ - billPayments: IBillPayment[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { BillPayment } = this.tenancy.models(tenantId); - - // Parses filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - BillPayment, - filter - ); - const { results, pagination } = await BillPayment.query() - .onBuild((builder) => { - builder.withGraphFetched('vendor'); - builder.withGraphFetched('paymentAccount'); - - dynamicList.buildQuery()(builder); - filter?.filterQuery && filter?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transformes the bill payments models to POJO. - const billPayments = await this.transformer.transform( - tenantId, - results, - new BillPaymentTransformer() - ); - return { - billPayments, - pagination, - filterMeta: dynamicList.getResponseMeta(), - }; - } - - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/GetPaymentBills.ts b/packages/server/src/services/Purchases/BillPayments/GetPaymentBills.ts deleted file mode 100644 index ec839411b..000000000 --- a/packages/server/src/services/Purchases/BillPayments/GetPaymentBills.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { BillPaymentValidators } from './BillPaymentValidators'; - -@Service() -export class GetPaymentBills { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: BillPaymentValidators; - - /** - * Retrieve payment made associated bills. - * @param {number} tenantId - - * @param {number} billPaymentId - - */ - public async getPaymentBills(tenantId: number, billPaymentId: number) { - const { Bill, BillPayment } = this.tenancy.models(tenantId); - - const billPayment = await BillPayment.query() - .findById(billPaymentId) - .throwIfNotFound(); - - const paymentBillsIds = billPayment.entries.map((entry) => entry.id); - - const bills = await Bill.query().whereIn('id', paymentBillsIds); - - return bills; - } -} diff --git a/packages/server/src/services/Purchases/BillPayments/constants.ts b/packages/server/src/services/Purchases/BillPayments/constants.ts deleted file mode 100644 index 29c93b1f5..000000000 --- a/packages/server/src/services/Purchases/BillPayments/constants.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const ERRORS = { - BILL_VENDOR_NOT_FOUND: 'VENDOR_NOT_FOUND', - PAYMENT_MADE_NOT_FOUND: 'PAYMENT_MADE_NOT_FOUND', - BILL_PAYMENT_NUMBER_NOT_UNQIUE: 'BILL_PAYMENT_NUMBER_NOT_UNQIUE', - PAYMENT_ACCOUNT_NOT_FOUND: 'PAYMENT_ACCOUNT_NOT_FOUND', - PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE: - 'PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE', - BILL_ENTRIES_IDS_NOT_FOUND: 'BILL_ENTRIES_IDS_NOT_FOUND', - BILL_PAYMENT_ENTRIES_NOT_FOUND: 'BILL_PAYMENT_ENTRIES_NOT_FOUND', - INVALID_BILL_PAYMENT_AMOUNT: 'INVALID_BILL_PAYMENT_AMOUNT', - PAYMENT_NUMBER_SHOULD_NOT_MODIFY: 'PAYMENT_NUMBER_SHOULD_NOT_MODIFY', - BILLS_NOT_OPENED_YET: 'BILLS_NOT_OPENED_YET', - VENDOR_HAS_PAYMENTS: 'VENDOR_HAS_PAYMENTS', - WITHDRAWAL_ACCOUNT_CURRENCY_INVALID: 'WITHDRAWAL_ACCOUNT_CURRENCY_INVALID', -}; - -export const DEFAULT_VIEWS = []; - -export const BillsPaymentsSampleData = [ - { - 'Payment Date': '2024-03-01', - Vendor: 'Gabriel Kovacek', - 'Payment No.': 'P-10001', - 'Reference No.': 'REF-1', - 'Payment Account': 'Petty Cash', - Statement: 'Vel et dolorem architecto veniam.', - 'Bill No': 'B-120', - 'Payment Amount': 100, - }, - { - 'Payment Date': '2024-03-02', - Vendor: 'Gabriel Kovacek', - 'Payment No.': 'P-10002', - 'Reference No.': 'REF-2', - 'Payment Account': 'Petty Cash', - Statement: 'Id est molestias.', - 'Bill No': 'B-121', - 'Payment Amount': 100, - }, - { - 'Payment Date': '2024-03-03', - Vendor: 'Gabriel Kovacek', - 'Payment No.': 'P-10003', - 'Reference No.': 'REF-3', - 'Payment Account': 'Petty Cash', - Statement: 'Quam cupiditate at nihil dicta dignissimos non fugit illo.', - 'Bill No': 'B-122', - 'Payment Amount': 100, - }, -]; diff --git a/packages/server/src/services/Purchases/Bills/BillDTOTransformer.ts b/packages/server/src/services/Purchases/Bills/BillDTOTransformer.ts deleted file mode 100644 index f391c4464..000000000 --- a/packages/server/src/services/Purchases/Bills/BillDTOTransformer.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { omit, sumBy } from 'lodash'; -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import composeAsync from 'async/compose'; -import { assocDepthLevelToObjectTree, formatDateFields } from 'utils'; -import { - IBillDTO, - IBill, - ISystemUser, - IVendor, - IItemEntry, -} from '@/interfaces'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ItemEntriesTaxTransactions } from '@/services/TaxRates/ItemEntriesTaxTransactions'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; - -@Service() -export class BillDTOTransformer { - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - @Inject() - private taxDTOTransformer: ItemEntriesTaxTransactions; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve the bill entries total. - * @param {IItemEntry[]} entries - * @returns {number} - */ - private getBillEntriesTotal(tenantId: number, entries: IItemEntry[]): number { - const { ItemEntry } = this.tenancy.models(tenantId); - - return sumBy(entries, (e) => ItemEntry.calcAmount(e)); - } - - /** - * Retrieve the bill landed cost amount. - * @param {IBillDTO} billDTO - * @returns {number} - */ - private getBillLandedCostAmount(tenantId: number, billDTO: IBillDTO): number { - const costEntries = billDTO.entries.filter((entry) => entry.landedCost); - - return this.getBillEntriesTotal(tenantId, costEntries); - } - - /** - * Converts create bill DTO to model. - * @param {number} tenantId - * @param {IBillDTO} billDTO - * @param {IBill} oldBill - * @returns {IBill} - */ - public async billDTOToModel( - tenantId: number, - billDTO: IBillDTO, - vendor: IVendor, - authorizedUser: ISystemUser, - oldBill?: IBill - ) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const amount = sumBy(billDTO.entries, (e) => ItemEntry.calcAmount(e)); - - // Retrieve the landed cost amount from landed cost entries. - const landedCostAmount = this.getBillLandedCostAmount(tenantId, billDTO); - - // Bill number from DTO or from auto-increment. - const billNumber = billDTO.billNumber || oldBill?.billNumber; - - const initialEntries = billDTO.entries.map((entry) => ({ - referenceType: 'Bill', - isInclusiveTax: billDTO.isInclusiveTax, - ...omit(entry, ['amount']), - })); - const asyncEntries = await composeAsync( - // Associate tax rate from tax id to entries. - this.taxDTOTransformer.assocTaxRateFromTaxIdToEntries(tenantId), - // Associate tax rate id from tax code to entries. - this.taxDTOTransformer.assocTaxRateIdFromCodeToEntries(tenantId), - // Sets the default cost account to the bill entries. - this.setBillEntriesDefaultAccounts(tenantId) - )(initialEntries); - - const entries = R.compose( - // Remove tax code from entries. - R.map(R.omit(['taxCode'])), - // Associate the default index to each item entry line. - assocItemEntriesDefaultIndex - )(asyncEntries); - - const initialDTO = { - ...formatDateFields(omit(billDTO, ['open', 'entries', 'attachments']), [ - 'billDate', - 'dueDate', - ]), - amount, - landedCostAmount, - currencyCode: vendor.currencyCode, - exchangeRate: billDTO.exchangeRate || 1, - billNumber, - entries, - // Avoid rewrite the open date in edit mode when already opened. - ...(billDTO.open && - !oldBill?.openedAt && { - openedAt: moment().toMySqlDateTime(), - }), - userId: authorizedUser.id, - }; - return R.compose( - // Associates tax amount withheld to the model. - this.taxDTOTransformer.assocTaxAmountWithheldFromEntries, - this.branchDTOTransform.transformDTO(tenantId), - this.warehouseDTOTransform.transformDTO(tenantId) - )(initialDTO); - } - - /** - * Sets the default cost account to the bill entries. - */ - private setBillEntriesDefaultAccounts(tenantId: number) { - return async (entries: IItemEntry[]) => { - const { Item } = this.tenancy.models(tenantId); - - const entriesItemsIds = entries.map((e) => e.itemId); - const items = await Item.query().whereIn('id', entriesItemsIds); - - return entries.map((entry) => { - const item = items.find((i) => i.id === entry.itemId); - - return { - ...entry, - ...(item.type !== 'inventory' && { - costAccountId: entry.costAccountId || item.costAccountId, - }), - }; - }); - }; - } -} diff --git a/packages/server/src/services/Purchases/Bills/BillGLEntries.ts b/packages/server/src/services/Purchases/Bills/BillGLEntries.ts deleted file mode 100644 index a5daf87fe..000000000 --- a/packages/server/src/services/Purchases/Bills/BillGLEntries.ts +++ /dev/null @@ -1,363 +0,0 @@ -import moment from 'moment'; -import { sumBy } from 'lodash'; -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { AccountNormal, IBill, IItemEntry, ILedgerEntry } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; - -@Service() -export class BillGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - /** - * Creates bill GL entries. - * @param {number} tenantId - - * @param {number} billId - - * @param {Knex.Transaction} trx - - */ - public writeBillGLEntries = async ( - tenantId: number, - billId: number, - trx?: Knex.Transaction - ) => { - const { accountRepository } = this.tenancy.repositories(tenantId); - const { Bill } = this.tenancy.models(tenantId); - - // Retrieves bill with associated entries and landed costs. - const bill = await Bill.query(trx) - .findById(billId) - .withGraphFetched('entries.item') - .withGraphFetched('entries.allocatedCostEntries') - .withGraphFetched('locatedLandedCosts.allocateEntries'); - - // Finds or create a A/P account based on the given currency. - const APAccount = await accountRepository.findOrCreateAccountsPayable( - bill.currencyCode, - {}, - trx - ); - // Find or create tax payable account. - const taxPayableAccount = await accountRepository.findOrCreateTaxPayable( - {}, - trx - ); - // Find or create other expenses account. - const otherExpensesAccount = - await accountRepository.findOrCreateOtherExpensesAccount({}, trx); - // Find or create purchase discount account. - const purchaseDiscountAccount = - await accountRepository.findOrCreatePurchaseDiscountAccount({}, trx); - const billLedger = this.getBillLedger( - bill, - APAccount.id, - taxPayableAccount.id, - purchaseDiscountAccount.id, - otherExpensesAccount.id - ); - // Commit the GL enties on the storage. - await this.ledgerStorage.commit(tenantId, billLedger, trx); - }; - - /** - * Reverts the given bill GL entries. - * @param {number} tenantId - * @param {number} billId - * @param {Knex.Transaction} trx - */ - public revertBillGLEntries = async ( - tenantId: number, - billId: number, - trx?: Knex.Transaction - ) => { - await this.ledgerStorage.deleteByReference(tenantId, billId, 'Bill', trx); - }; - - /** - * Rewrites the given bill GL entries. - * @param {number} tenantId - * @param {number} billId - * @param {Knex.Transaction} trx - */ - public rewriteBillGLEntries = async ( - tenantId: number, - billId: number, - trx?: Knex.Transaction - ) => { - // Reverts the bill GL entries. - await this.revertBillGLEntries(tenantId, billId, trx); - - // Writes the bill GL entries. - await this.writeBillGLEntries(tenantId, billId, trx); - }; - - /** - * Retrieves the bill common entry. - * @param {IBill} bill - * @returns {ILedgerEntry} - */ - private getBillCommonEntry = (bill: IBill) => { - return { - debit: 0, - credit: 0, - - currencyCode: bill.currencyCode, - exchangeRate: bill.exchangeRate || 1, - - transactionId: bill.id, - transactionType: 'Bill', - - date: moment(bill.billDate).format('YYYY-MM-DD'), - userId: bill.userId, - - referenceNumber: bill.referenceNo, - transactionNumber: bill.billNumber, - - branchId: bill.branchId, - projectId: bill.projectId, - - createdAt: bill.createdAt, - }; - }; - - /** - * Retrieves the bill item inventory/cost entry. - * @param {IBill} bill - - * @param {IItemEntry} entry - - * @param {number} index - - */ - private getBillItemEntry = R.curry( - (bill: IBill, entry: IItemEntry, index: number): ILedgerEntry => { - const commonJournalMeta = this.getBillCommonEntry(bill); - const totalLocal = bill.exchangeRate * entry.totalExcludingTax; - const landedCostAmount = sumBy(entry.allocatedCostEntries, 'cost'); - - return { - ...commonJournalMeta, - debit: totalLocal + landedCostAmount, - accountId: - ['inventory'].indexOf(entry.item.type) !== -1 - ? entry.item.inventoryAccountId - : entry.costAccountId, - index: index + 1, - indexGroup: 10, - itemId: entry.itemId, - itemQuantity: entry.quantity, - accountNormal: AccountNormal.DEBIT, - }; - } - ); - - /** - * Retrieves the bill landed cost entry. - * @param {IBill} bill - - * @param {} landedCost - - * @param {number} index - - */ - private getBillLandedCostEntry = R.curry( - (bill: IBill, landedCost, index: number): ILedgerEntry => { - const commonJournalMeta = this.getBillCommonEntry(bill); - - return { - ...commonJournalMeta, - credit: landedCost.amount, - accountId: landedCost.costAccountId, - accountNormal: AccountNormal.DEBIT, - index: 1, - indexGroup: 20, - }; - } - ); - - /** - * Retrieves the bill payable entry. - * @param {number} payableAccountId - * @param {IBill} bill - * @returns {ILedgerEntry} - */ - private getBillPayableEntry = ( - payableAccountId: number, - bill: IBill - ): ILedgerEntry => { - const commonJournalMeta = this.getBillCommonEntry(bill); - - return { - ...commonJournalMeta, - credit: bill.totalLocal, - accountId: payableAccountId, - contactId: bill.vendorId, - accountNormal: AccountNormal.CREDIT, - index: 1, - indexGroup: 5, - }; - }; - - /** - * Retrieves the bill tax GL entry. - * @param {IBill} bill - - * @param {number} taxPayableAccountId - - * @param {IItemEntry} entry - - * @param {number} index - - * @returns {ILedgerEntry} - */ - private getBillTaxEntry = R.curry( - ( - bill: IBill, - taxPayableAccountId: number, - entry: IItemEntry, - index: number - ): ILedgerEntry => { - const commonJournalMeta = this.getBillCommonEntry(bill); - - return { - ...commonJournalMeta, - debit: entry.taxAmount, - index, - indexGroup: 30, - accountId: taxPayableAccountId, - accountNormal: AccountNormal.CREDIT, - taxRateId: entry.taxRateId, - taxRate: entry.taxRate, - }; - } - ); - - /** - * Retrieves the bill tax GL entries. - * @param {IBill} bill - * @param {number} taxPayableAccountId - * @returns {ILedgerEntry[]} - */ - private getBillTaxEntries = (bill: IBill, taxPayableAccountId: number) => { - // Retrieves the non-zero tax entries. - const nonZeroTaxEntries = this.itemsEntriesService.getNonZeroEntries( - bill.entries - ); - const transformTaxEntry = this.getBillTaxEntry(bill, taxPayableAccountId); - - return nonZeroTaxEntries.map(transformTaxEntry); - }; - - /** - * Retrieves the purchase discount GL entry. - * @param {IBill} bill - * @param {number} purchaseDiscountAccountId - * @returns {ILedgerEntry} - */ - private getPurchaseDiscountEntry = ( - bill: IBill, - purchaseDiscountAccountId: number - ) => { - const commonEntry = this.getBillCommonEntry(bill); - - return { - ...commonEntry, - credit: bill.discountAmountLocal, - accountId: purchaseDiscountAccountId, - accountNormal: AccountNormal.DEBIT, - index: 1, - indexGroup: 40, - }; - }; - - /** - * Retrieves the purchase other charges GL entry. - * @param {IBill} bill - * @param {number} otherChargesAccountId - * @returns {ILedgerEntry} - */ - private getAdjustmentEntry = ( - bill: IBill, - otherExpensesAccountId: number - ) => { - const commonEntry = this.getBillCommonEntry(bill); - const adjustmentAmount = Math.abs(bill.adjustmentLocal); - - return { - ...commonEntry, - debit: bill.adjustmentLocal > 0 ? adjustmentAmount : 0, - credit: bill.adjustmentLocal < 0 ? adjustmentAmount : 0, - accountId: otherExpensesAccountId, - accountNormal: AccountNormal.DEBIT, - index: 1, - indexGroup: 40, - }; - }; - - /** - * Retrieves the given bill GL entries. - * @param {IBill} bill - * @param {number} payableAccountId - * @returns {ILedgerEntry[]} - */ - private getBillGLEntries = ( - bill: IBill, - payableAccountId: number, - taxPayableAccountId: number, - purchaseDiscountAccountId: number, - otherExpensesAccountId: number - ): ILedgerEntry[] => { - const payableEntry = this.getBillPayableEntry(payableAccountId, bill); - - const itemEntryTransformer = this.getBillItemEntry(bill); - const landedCostTransformer = this.getBillLandedCostEntry(bill); - - const itemsEntries = bill.entries.map(itemEntryTransformer); - const landedCostEntries = bill.locatedLandedCosts.map( - landedCostTransformer - ); - const taxEntries = this.getBillTaxEntries(bill, taxPayableAccountId); - - const purchaseDiscountEntry = this.getPurchaseDiscountEntry( - bill, - purchaseDiscountAccountId - ); - const adjustmentEntry = this.getAdjustmentEntry( - bill, - otherExpensesAccountId - ); - - // Allocate cost entries journal entries. - return [ - payableEntry, - ...itemsEntries, - ...landedCostEntries, - ...taxEntries, - purchaseDiscountEntry, - adjustmentEntry, - ]; - }; - - /** - * Retrieves the given bill ledger. - * @param {IBill} bill - * @param {number} payableAccountId - * @returns {Ledger} - */ - private getBillLedger = ( - bill: IBill, - payableAccountId: number, - taxPayableAccountId: number, - purchaseDiscountAccountId: number, - otherExpensesAccountId: number - ) => { - const entries = this.getBillGLEntries( - bill, - payableAccountId, - taxPayableAccountId, - purchaseDiscountAccountId, - otherExpensesAccountId - ); - return new Ledger(entries); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/BillGLEntriesSubscriber.ts b/packages/server/src/services/Purchases/Bills/BillGLEntriesSubscriber.ts deleted file mode 100644 index 231b3cedd..000000000 --- a/packages/server/src/services/Purchases/Bills/BillGLEntriesSubscriber.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IBillCreatedPayload, - IBillEditedPayload, - IBIllEventDeletedPayload, - IBillOpenedPayload, -} from '@/interfaces'; -import { BillGLEntries } from './BillGLEntries'; - -@Service() -export class BillGLEntriesSubscriber { - @Inject() - private billGLEntries: BillGLEntries; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe( - events.bill.onCreated, - this.handlerWriteJournalEntriesOnCreate - ); - bus.subscribe( - events.bill.onOpened, - this.handlerWriteJournalEntriesOnCreate - ); - bus.subscribe( - events.bill.onEdited, - this.handleOverwriteJournalEntriesOnEdit - ); - bus.subscribe(events.bill.onDeleted, this.handlerDeleteJournalEntries); - } - - /** - * Handles writing journal entries once bill created. - * @param {IBillCreatedPayload} payload - - */ - private handlerWriteJournalEntriesOnCreate = async ({ - tenantId, - bill, - trx, - }: IBillCreatedPayload | IBillOpenedPayload) => { - if (!bill.openedAt) return null; - - await this.billGLEntries.writeBillGLEntries(tenantId, bill.id, trx); - }; - - /** - * Handles the overwriting journal entries once bill edited. - * @param {IBillEditedPayload} payload - - */ - private handleOverwriteJournalEntriesOnEdit = async ({ - tenantId, - billId, - bill, - trx, - }: IBillEditedPayload) => { - if (!bill.openedAt) return null; - - await this.billGLEntries.rewriteBillGLEntries(tenantId, billId, trx); - }; - - /** - * Handles revert journal entries on bill deleted. - * @param {IBIllEventDeletedPayload} payload - - */ - private handlerDeleteJournalEntries = async ({ - tenantId, - billId, - trx, - }: IBIllEventDeletedPayload) => { - await this.billGLEntries.revertBillGLEntries(tenantId, billId, trx); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/BillInventoryTransactions.ts b/packages/server/src/services/Purchases/Bills/BillInventoryTransactions.ts deleted file mode 100644 index 1486ce2c5..000000000 --- a/packages/server/src/services/Purchases/Bills/BillInventoryTransactions.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import InventoryService from '@/services/Inventory/Inventory'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class BillInventoryTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private inventoryService: InventoryService; - - /** - * Records the inventory transactions from the given bill input. - * @param {Bill} bill - Bill model object. - * @param {number} billId - Bill id. - * @return {Promise} - */ - public async recordInventoryTransactions( - tenantId: number, - billId: number, - override?: boolean, - trx?: Knex.Transaction - ): Promise { - const { Bill } = this.tenancy.models(tenantId); - - // Retireve bill with assocaited entries and allocated cost entries. - const bill = await Bill.query(trx) - .findById(billId) - .withGraphFetched('entries.allocatedCostEntries'); - - // Loads the inventory items entries of the given sale invoice. - const inventoryEntries = - await this.itemsEntriesService.filterInventoryEntries( - tenantId, - bill.entries - ); - const transaction = { - transactionId: bill.id, - transactionType: 'Bill', - exchangeRate: bill.exchangeRate, - - date: bill.billDate, - direction: 'IN', - entries: inventoryEntries, - createdAt: bill.createdAt, - - warehouseId: bill.warehouseId, - }; - await this.inventoryService.recordInventoryTransactionsFromItemsEntries( - tenantId, - transaction, - override, - trx - ); - } - - /** - * Reverts the inventory transactions of the given bill id. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Bill id. - * @return {Promise} - */ - public async revertInventoryTransactions( - tenantId: number, - billId: number, - trx?: Knex.Transaction - ) { - // Deletes the inventory transactions by the given reference id and type. - await this.inventoryService.deleteInventoryTransactions( - tenantId, - billId, - 'Bill', - trx - ); - } -} diff --git a/packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewrite.ts b/packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewrite.ts deleted file mode 100644 index 66ca5b841..000000000 --- a/packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewrite.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Knex } from 'knex'; -import async from 'async'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { BillPaymentGLEntries } from '../BillPayments/BillPaymentGLEntries'; - -@Service() -export class BillPaymentsGLEntriesRewrite { - @Inject() - public tenancy: HasTenancyService; - - @Inject() - public paymentGLEntries: BillPaymentGLEntries; - - /** - * Rewrites payments GL entries that associated to the given bill. - * @param {number} tenantId - * @param {number} billId - * @param {Knex.Transaction} trx - */ - public rewriteBillPaymentsGLEntries = async ( - tenantId: number, - billId: number, - trx?: Knex.Transaction - ) => { - const { BillPaymentEntry } = this.tenancy.models(tenantId); - - const billPaymentEntries = await BillPaymentEntry.query().where( - 'billId', - billId - ); - const paymentsIds = billPaymentEntries.map((e) => e.billPaymentId); - - await this.rewritePaymentsGLEntriesQueue(tenantId, paymentsIds, trx); - }; - - /** - * Rewrites the payments GL entries under async queue. - * @param {number} tenantId - * @param {number[]} paymentsIds - * @param {Knex.Transaction} trx - */ - public rewritePaymentsGLEntriesQueue = async ( - tenantId: number, - paymentsIds: number[], - trx?: Knex.Transaction - ) => { - // Initiate a new queue for accounts balance mutation. - const rewritePaymentGL = async.queue(this.rewritePaymentsGLEntriesTask, 10); - - paymentsIds.forEach((paymentId: number) => { - rewritePaymentGL.push({ paymentId, trx, tenantId }); - }); - // - if (paymentsIds.length > 0) await rewritePaymentGL.drain(); - }; - - /** - * Rewrites the payments GL entries task. - * @param {number} tenantId - - * @param {number} paymentId - - * @param {Knex.Transaction} trx - - * @returns {Promise} - */ - public rewritePaymentsGLEntriesTask = async ({ - tenantId, - paymentId, - trx, - }) => { - await this.paymentGLEntries.rewritePaymentGLEntries( - tenantId, - paymentId, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewriteSubscriber.ts b/packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewriteSubscriber.ts deleted file mode 100644 index 4e193fe2f..000000000 --- a/packages/server/src/services/Purchases/Bills/BillPaymentsGLEntriesRewriteSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IBillEditedPayload } from '@/interfaces'; -import { BillPaymentsGLEntriesRewrite } from './BillPaymentsGLEntriesRewrite'; - -@Service() -export class BillPaymentsGLEntriesRewriteSubscriber { - @Inject() - private billPaymentGLEntriesRewrite: BillPaymentsGLEntriesRewrite; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe( - events.bill.onEdited, - this.handlerRewritePaymentsGLOnBillEdited - ); - } - - /** - * Handles writing journal entries once bill created. - * @param {IBillCreatedPayload} payload - - */ - private handlerRewritePaymentsGLOnBillEdited = async ({ - tenantId, - billId, - trx, - }: IBillEditedPayload) => { - await this.billPaymentGLEntriesRewrite.rewriteBillPaymentsGLEntries( - tenantId, - billId, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/BillsApplication.ts b/packages/server/src/services/Purchases/Bills/BillsApplication.ts deleted file mode 100644 index 2593b03b2..000000000 --- a/packages/server/src/services/Purchases/Bills/BillsApplication.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CreateBill } from './CreateBill'; -import { EditBill } from './EditBill'; -import { GetBill } from './GetBill'; -import { GetBills } from './GetBills'; -import { DeleteBill } from './DeleteBill'; -import { - IBill, - IBillDTO, - IBillEditDTO, - IBillsFilter, - IFilterMeta, - IPaginationMeta, - ISystemUser, -} from '@/interfaces'; -import { GetDueBills } from './GetDueBills'; -import { OpenBill } from './OpenBill'; -import { GetBillPayments } from './GetBillPayments'; - -@Service() -export class BillsApplication { - @Inject() - private createBillService: CreateBill; - - @Inject() - private editBillService: EditBill; - - @Inject() - private getBillService: GetBill; - - @Inject() - private getBillsService: GetBills; - - @Inject() - private deleteBillService: DeleteBill; - - @Inject() - private getDueBillsService: GetDueBills; - - @Inject() - private openBillService: OpenBill; - - @Inject() - private getBillPaymentsService: GetBillPayments; - - /** - * Creates a new bill with associated GL entries. - * @param {number} tenantId - * @param {IBillDTO} billDTO - * @param {ISystemUser} authorizedUser - * @returns - */ - public createBill( - tenantId: number, - billDTO: IBillDTO, - authorizedUser: ISystemUser - ): Promise { - return this.createBillService.createBill(tenantId, billDTO, authorizedUser); - } - - /** - * Edits the given bill with associated GL entries. - * @param {number} tenantId - * @param {number} billId - * @param {IBillEditDTO} billDTO - * @param {ISystemUser} authorizedUser - * @returns - */ - public editBill( - tenantId: number, - billId: number, - billDTO: IBillEditDTO, - authorizedUser: ISystemUser - ): Promise { - return this.editBillService.editBill( - tenantId, - billId, - billDTO, - authorizedUser - ); - } - - /** - * Deletes the given bill with associated GL entries. - * @param {number} tenantId - * @param {number} billId - * @returns {Promise} - */ - public deleteBill(tenantId: number, billId: number) { - return this.deleteBillService.deleteBill(tenantId, billId); - } - - /** - * Retrieve bills data table list. - * @param {number} tenantId - - * @param {IBillsFilter} billsFilter - - */ - public getBills( - tenantId: number, - filterDTO: IBillsFilter - ): Promise<{ - bills: IBill[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - return this.getBillsService.getBills(tenantId, filterDTO); - } - - /** - * Retrieves the given bill details. - * @param {number} tenantId - * @param {number} billId - * @returns - */ - public getBill(tenantId: number, billId: number): Promise { - return this.getBillService.getBill(tenantId, billId); - } - - /** - * Open the given bill. - * @param {number} tenantId - * @param {number} billId - * @returns {Promise} - */ - public openBill(tenantId: number, billId: number): Promise { - return this.openBillService.openBill(tenantId, billId); - } - - /** - * Retrieves due bills of the given vendor. - * @param {number} tenantId - * @param {number} vendorId - * @returns - */ - public getDueBills(tenantId: number, vendorId?: number) { - return this.getDueBillsService.getDueBills(tenantId, vendorId); - } - - /** - * Retrieve the specific bill associated payment transactions. - * @param {number} tenantId - * @param {number} billId - */ - public getBillPayments = async (tenantId: number, billId: number) => { - return this.getBillPaymentsService.getBillPayments(tenantId, billId); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/BillsExportable.ts b/packages/server/src/services/Purchases/Bills/BillsExportable.ts deleted file mode 100644 index e6a49e01a..000000000 --- a/packages/server/src/services/Purchases/Bills/BillsExportable.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IBillsFilter } from '@/interfaces'; -import { Exportable } from '@/services/Export/Exportable'; -import { BillsApplication } from './BillsApplication'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; -import Objection from 'objection'; - -@Service() -export class BillsExportable extends Exportable { - @Inject() - private billsApplication: BillsApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: IBillsFilter) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - query.withGraphFetched('warehouse'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery, - } as IBillsFilter; - - return this.billsApplication - .getBills(tenantId, parsedQuery) - .then((output) => output.bills); - } -} diff --git a/packages/server/src/services/Purchases/Bills/BillsImportable.ts b/packages/server/src/services/Purchases/Bills/BillsImportable.ts deleted file mode 100644 index c356d3348..000000000 --- a/packages/server/src/services/Purchases/Bills/BillsImportable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { Importable } from '@/services/Import/Importable'; -import { CreateBill } from './CreateBill'; -import { IBillDTO } from '@/interfaces'; -import { BillsSampleData } from './constants'; - -@Service() -export class BillsImportable extends Importable { - @Inject() - private createBillService: CreateBill; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: IBillDTO, - trx?: Knex.Transaction - ) { - return this.createBillService.createBill( - tenantId, - createAccountDTO, - {}, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return BillsSampleData; - } -} diff --git a/packages/server/src/services/Purchases/Bills/BillsValidators.ts b/packages/server/src/services/Purchases/Bills/BillsValidators.ts deleted file mode 100644 index b9ff8989e..000000000 --- a/packages/server/src/services/Purchases/Bills/BillsValidators.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ERRORS } from './constants'; -import { IItemEntryDTO } from '@/interfaces'; -import { transformToMap } from '@/utils'; -import { Bill } from '@/models'; - -@Service() -export class BillsValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates the bill existance. - * @param {Bill | undefined | null} bill - */ - public validateBillExistance(bill: Bill | undefined | null) { - if (!bill) { - throw new ServiceError(ERRORS.BILL_NOT_FOUND); - } - } - - /** - * Validates the bill amount is bigger than paid amount. - * @param {number} billAmount - * @param {number} paidAmount - */ - public validateBillAmountBiggerPaidAmount( - billAmount: number, - paidAmount: number - ) { - if (billAmount < paidAmount) { - throw new ServiceError(ERRORS.BILL_AMOUNT_SMALLER_THAN_PAID_AMOUNT); - } - } - - /** - * Validates the bill number existance. - */ - public async validateBillNumberExists( - tenantId: number, - billNumber: string, - notBillId?: number - ) { - const { Bill } = this.tenancy.models(tenantId); - const foundBills = await Bill.query() - .where('bill_number', billNumber) - .onBuild((builder) => { - if (notBillId) { - builder.whereNot('id', notBillId); - } - }); - - if (foundBills.length > 0) { - throw new ServiceError( - ERRORS.BILL_NUMBER_EXISTS, - 'The bill number is not unique.' - ); - } - } - - /** - * Validate the bill has no payment entries. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Bill id. - */ - public async validateBillHasNoEntries(tenantId, billId: number) { - const { BillPaymentEntry } = this.tenancy.models(tenantId); - - // Retireve the bill associate payment made entries. - const entries = await BillPaymentEntry.query().where('bill_id', billId); - - if (entries.length > 0) { - throw new ServiceError(ERRORS.BILL_HAS_ASSOCIATED_PAYMENT_ENTRIES); - } - return entries; - } - - /** - * Validate the bill number require. - * @param {string} billNo - - */ - public validateBillNoRequire(billNo: string) { - if (!billNo) { - throw new ServiceError(ERRORS.BILL_NO_IS_REQUIRED); - } - } - - /** - * Validate bill transaction has no associated allocated landed cost transactions. - * @param {number} tenantId - * @param {number} billId - */ - public async validateBillHasNoLandedCost(tenantId: number, billId: number) { - const { BillLandedCost } = this.tenancy.models(tenantId); - - const billLandedCosts = await BillLandedCost.query().where( - 'billId', - billId - ); - if (billLandedCosts.length > 0) { - throw new ServiceError(ERRORS.BILL_HAS_ASSOCIATED_LANDED_COSTS); - } - } - - /** - * Validate transaction entries that have landed cost type should not be - * inventory items. - * @param {number} tenantId - - * @param {IItemEntryDTO[]} newEntriesDTO - - */ - public async validateCostEntriesShouldBeInventoryItems( - tenantId: number, - newEntriesDTO: IItemEntryDTO[] - ) { - const { Item } = this.tenancy.models(tenantId); - - const entriesItemsIds = newEntriesDTO.map((e) => e.itemId); - const entriesItems = await Item.query().whereIn('id', entriesItemsIds); - - const entriesItemsById = transformToMap(entriesItems, 'id'); - - // Filter the landed cost entries that not associated with inventory item. - const nonInventoryHasCost = newEntriesDTO.filter((entry) => { - const item = entriesItemsById.get(entry.itemId); - - return entry.landedCost && item.type !== 'inventory'; - }); - if (nonInventoryHasCost.length > 0) { - throw new ServiceError( - ERRORS.LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS - ); - } - } - - /** - * - * @param {number} tenantId - * @param {number} billId - */ - public validateBillHasNoAppliedToCredit = async ( - tenantId: number, - billId: number - ) => { - const { VendorCreditAppliedBill } = this.tenancy.models(tenantId); - - const appliedTransactions = await VendorCreditAppliedBill.query().where( - 'billId', - billId - ); - if (appliedTransactions.length > 0) { - throw new ServiceError(ERRORS.BILL_HAS_APPLIED_TO_VENDOR_CREDIT); - } - }; - - /** - * Validate the given vendor has no associated bills transactions. - * @param {number} tenantId - * @param {number} vendorId - Vendor id. - */ - public async validateVendorHasNoBills(tenantId: number, vendorId: number) { - const { Bill } = this.tenancy.models(tenantId); - - const bills = await Bill.query().where('vendor_id', vendorId); - - if (bills.length > 0) { - throw new ServiceError(ERRORS.VENDOR_HAS_BILLS); - } - } -} diff --git a/packages/server/src/services/Purchases/Bills/CreateBill.ts b/packages/server/src/services/Purchases/Bills/CreateBill.ts deleted file mode 100644 index 2bb317ff6..000000000 --- a/packages/server/src/services/Purchases/Bills/CreateBill.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IBillDTO, - IBill, - ISystemUser, - IBillCreatedPayload, - IBillCreatingPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { BillsValidators } from './BillsValidators'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import { BillDTOTransformer } from './BillDTOTransformer'; - -@Service() -export class CreateBill { - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: BillsValidators; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private transformerDTO: BillDTOTransformer; - - /** - * Creates a new bill and stored it to the storage. - * ---- - * Precedures. - * ---- - * - Insert bill transactions to the storage. - * - Insert bill entries to the storage. - * - Increment the given vendor id. - * - Record bill journal transactions on the given accounts. - * - Record bill items inventory transactions. - * ---- - * @param {number} tenantId - The given tenant id. - * @param {IBillDTO} billDTO - - * @return {Promise} - */ - public async createBill( - tenantId: number, - billDTO: IBillDTO, - authorizedUser: ISystemUser, - trx?: Knex.Transaction - ): Promise { - const { Bill, Contact } = this.tenancy.models(tenantId); - - // Retrieves the given bill vendor or throw not found error. - const vendor = await Contact.query() - .modify('vendor') - .findById(billDTO.vendorId) - .throwIfNotFound(); - - // Validate the bill number uniqiness on the storage. - await this.validators.validateBillNumberExists( - tenantId, - billDTO.billNumber - ); - // Validate items IDs existance. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - billDTO.entries - ); - // Validate non-purchasable items. - await this.itemsEntriesService.validateNonPurchasableEntriesItems( - tenantId, - billDTO.entries - ); - // Validates the cost entries should be with inventory items. - await this.validators.validateCostEntriesShouldBeInventoryItems( - tenantId, - billDTO.entries - ); - // Transform the bill DTO to model object. - const billObj = await this.transformerDTO.billDTOToModel( - tenantId, - billDTO, - vendor, - authorizedUser - ); - // Write new bill transaction with associated transactions under UOW env. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onBillCreating` event. - await this.eventPublisher.emitAsync(events.bill.onCreating, { - trx, - billDTO, - tenantId, - } as IBillCreatingPayload); - - // Inserts the bill graph object to the storage. - const bill = await Bill.query(trx).upsertGraph(billObj); - - // Triggers `onBillCreated` event. - await this.eventPublisher.emitAsync(events.bill.onCreated, { - tenantId, - bill, - billId: bill.id, - billDTO, - trx, - } as IBillCreatedPayload); - - return bill; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Purchases/Bills/DeleteBill.ts b/packages/server/src/services/Purchases/Bills/DeleteBill.ts deleted file mode 100644 index 6cb47e9d5..000000000 --- a/packages/server/src/services/Purchases/Bills/DeleteBill.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IBIllEventDeletedPayload, - IBillEventDeletingPayload, -} from '@/interfaces'; -import { BillsValidators } from './BillsValidators'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class DeleteBill { - @Inject() - private validators: BillsValidators; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Deletes the bill with associated entries. - * @param {number} billId - * @return {void} - */ - public async deleteBill(tenantId: number, billId: number) { - const { ItemEntry, Bill } = this.tenancy.models(tenantId); - - // Retrieve the given bill or throw not found error. - const oldBill = await Bill.query() - .findById(billId) - .withGraphFetched('entries'); - - // Validates the bill existance. - this.validators.validateBillExistance(oldBill); - - // Validate the givne bill has no associated landed cost transactions. - await this.validators.validateBillHasNoLandedCost(tenantId, billId); - - // Validate the purchase bill has no associated payments transactions. - await this.validators.validateBillHasNoEntries(tenantId, billId); - - // Validate the given bill has no associated reconciled with vendor credits. - await this.validators.validateBillHasNoAppliedToCredit(tenantId, billId); - - // Deletes bill transaction with associated transactions under - // unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBillDeleting` event. - await this.eventPublisher.emitAsync(events.bill.onDeleting, { - trx, - tenantId, - oldBill, - } as IBillEventDeletingPayload); - - // Delete all associated bill entries. - await ItemEntry.query(trx) - .where('reference_type', 'Bill') - .where('reference_id', billId) - .delete(); - - // Delete the bill transaction. - await Bill.query(trx).findById(billId).delete(); - - // Triggers `onBillDeleted` event. - await this.eventPublisher.emitAsync(events.bill.onDeleted, { - tenantId, - billId, - oldBill, - trx, - } as IBIllEventDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Purchases/Bills/EditBill.ts b/packages/server/src/services/Purchases/Bills/EditBill.ts deleted file mode 100644 index 4bb61f4f5..000000000 --- a/packages/server/src/services/Purchases/Bills/EditBill.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { - IBill, - IBillEditDTO, - IBillEditedPayload, - IBillEditingPayload, - ISystemUser, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { BillsValidators } from './BillsValidators'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import EntriesService from '@/services/Entries'; -import { BillDTOTransformer } from './BillDTOTransformer'; - -@Service() -export class EditBill { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: BillsValidators; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private entriesService: EntriesService; - - @Inject() - private transformerDTO: BillDTOTransformer; - - /** - * Edits details of the given bill id with associated entries. - * - * Precedures: - * ------- - * - Update the bill transaction on the storage. - * - Update the bill entries on the storage and insert the not have id and delete - * once that not presented. - * - Increment the diff amount on the given vendor id. - * - Re-write the inventory transactions. - * - Re-write the bill journal transactions. - * ------ - * @param {number} tenantId - The given tenant id. - * @param {Integer} billId - The given bill id. - * @param {IBillEditDTO} billDTO - The given new bill details. - * @return {Promise} - */ - public async editBill( - tenantId: number, - billId: number, - billDTO: IBillEditDTO, - authorizedUser: ISystemUser - ): Promise { - const { Bill, Contact } = this.tenancy.models(tenantId); - - // Retrieve the given bill or throw not found error. - const oldBill = await Bill.query() - .findById(billId) - .withGraphFetched('entries'); - - // Validate bill existance. - this.validators.validateBillExistance(oldBill); - - // Retrieve vendor details or throw not found service error. - const vendor = await Contact.query() - .findById(billDTO.vendorId) - .modify('vendor') - .throwIfNotFound(); - - // Validate bill number uniqiness on the storage. - if (billDTO.billNumber) { - await this.validators.validateBillNumberExists( - tenantId, - billDTO.billNumber, - billId - ); - } - // Validate the entries ids existance. - await this.itemsEntriesService.validateEntriesIdsExistance( - tenantId, - billId, - 'Bill', - billDTO.entries - ); - // Validate the items ids existance on the storage. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - billDTO.entries - ); - // Accept the purchasable items only. - await this.itemsEntriesService.validateNonPurchasableEntriesItems( - tenantId, - billDTO.entries - ); - - // Transforms the bill DTO to model object. - const billObj = await this.transformerDTO.billDTOToModel( - tenantId, - billDTO, - vendor, - authorizedUser, - oldBill - ); - // Validate bill total amount should be bigger than paid amount. - this.validators.validateBillAmountBiggerPaidAmount( - billObj.amount, - oldBill.paymentAmount - ); - // Validate landed cost entries that have allocated cost could not be deleted. - await this.entriesService.validateLandedCostEntriesNotDeleted( - oldBill.entries, - billObj.entries - ); - // Validate new landed cost entries should be bigger than new entries. - await this.entriesService.validateLocatedCostEntriesSmallerThanNewEntries( - oldBill.entries, - billObj.entries - ); - // Edits bill transactions and associated transactions under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onBillEditing` event. - await this.eventPublisher.emitAsync(events.bill.onEditing, { - trx, - tenantId, - oldBill, - billDTO, - } as IBillEditingPayload); - - // Update the bill transaction. - const bill = await Bill.query(trx).upsertGraphAndFetch({ - id: billId, - ...billObj, - }); - // Triggers event `onBillEdited`. - await this.eventPublisher.emitAsync(events.bill.onEdited, { - tenantId, - billId, - oldBill, - bill, - billDTO, - trx, - } as IBillEditedPayload); - - return bill; - }); - } -} diff --git a/packages/server/src/services/Purchases/Bills/GetBill.ts b/packages/server/src/services/Purchases/Bills/GetBill.ts deleted file mode 100644 index 0efc5dfd1..000000000 --- a/packages/server/src/services/Purchases/Bills/GetBill.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { IBill } from '@/interfaces'; -import { BillsValidators } from './BillsValidators'; -import { PurchaseInvoiceTransformer } from './PurchaseInvoiceTransformer'; - -@Service() -export class GetBill { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private validators: BillsValidators; - - /** - * Retrieve the given bill details with associated items entries. - * @param {Integer} billId - Specific bill. - * @returns {Promise} - */ - public async getBill(tenantId: number, billId: number): Promise { - const { Bill } = this.tenancy.models(tenantId); - - const bill = await Bill.query() - .findById(billId) - .withGraphFetched('vendor') - .withGraphFetched('entries.item') - .withGraphFetched('branch') - .withGraphFetched('taxes.taxRate') - .withGraphFetched('attachments'); - - // Validates the bill existance. - this.validators.validateBillExistance(bill); - - return this.transformer.transform( - tenantId, - bill, - new PurchaseInvoiceTransformer() - ); - } -} diff --git a/packages/server/src/services/Purchases/Bills/GetBillPayments.ts b/packages/server/src/services/Purchases/Bills/GetBillPayments.ts deleted file mode 100644 index 7b99d73e8..000000000 --- a/packages/server/src/services/Purchases/Bills/GetBillPayments.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { BillPaymentTransactionTransformer } from '../BillPayments/BillPaymentTransactionTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetBillPayments { - @Inject() - private tenancy: TenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the specific bill associated payment transactions. - * @param {number} tenantId - * @param {number} billId - * @returns {} - */ - public getBillPayments = async (tenantId: number, billId: number) => { - const { BillPaymentEntry } = this.tenancy.models(tenantId); - - const billsEntries = await BillPaymentEntry.query() - .where('billId', billId) - .withGraphJoined('payment.paymentAccount') - .withGraphJoined('bill') - .orderBy('payment:paymentDate', 'ASC'); - - return this.transformer.transform( - tenantId, - billsEntries, - new BillPaymentTransactionTransformer() - ); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/GetBills.ts b/packages/server/src/services/Purchases/Bills/GetBills.ts deleted file mode 100644 index b68c0018f..000000000 --- a/packages/server/src/services/Purchases/Bills/GetBills.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { - IBill, - IBillsFilter, - IFilterMeta, - IPaginationMeta, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { PurchaseInvoiceTransformer } from './PurchaseInvoiceTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; - -@Service() -export class GetBills { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Retrieve bills data table list. - * @param {number} tenantId - - * @param {IBillsFilter} billsFilter - - */ - public async getBills( - tenantId: number, - filterDTO: IBillsFilter - ): Promise<{ - bills: IBill; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { Bill } = this.tenancy.models(tenantId); - - // Parses bills list filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - Bill, - filter - ); - const { results, pagination } = await Bill.query() - .onBuild((builder) => { - builder.withGraphFetched('vendor'); - builder.withGraphFetched('entries.item'); - dynamicFilter.buildQuery()(builder); - - // Filter query. - filterDTO?.filterQuery && filterDTO?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Tranform the bills to POJO. - const bills = await this.transformer.transform( - tenantId, - results, - new PurchaseInvoiceTransformer() - ); - return { - bills, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - } - - /** - * Parses bills list filter DTO. - * @param filterDTO - - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Purchases/Bills/GetDueBills.ts b/packages/server/src/services/Purchases/Bills/GetDueBills.ts deleted file mode 100644 index 87792ae49..000000000 --- a/packages/server/src/services/Purchases/Bills/GetDueBills.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { IBill } from '@/interfaces'; - -@Service() -export class GetDueBills { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve all due bills or for specific given vendor id. - * @param {number} tenantId - - * @param {number} vendorId - - */ - public async getDueBills( - tenantId: number, - vendorId?: number - ): Promise { - const { Bill } = this.tenancy.models(tenantId); - - const dueBills = await Bill.query().onBuild((query) => { - query.orderBy('bill_date', 'DESC'); - query.modify('dueBills'); - - if (vendorId) { - query.where('vendor_id', vendorId); - } - }); - return dueBills; - } -} diff --git a/packages/server/src/services/Purchases/Bills/OpenBill.ts b/packages/server/src/services/Purchases/Bills/OpenBill.ts deleted file mode 100644 index 25a0da22e..000000000 --- a/packages/server/src/services/Purchases/Bills/OpenBill.ts +++ /dev/null @@ -1,69 +0,0 @@ -import moment from 'moment'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { BillsValidators } from './BillsValidators'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { IBillOpenedPayload, IBillOpeningPayload } from '@/interfaces'; - -@Service() -export class OpenBill { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: BillsValidators; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Mark the bill as open. - * @param {number} tenantId - * @param {number} billId - */ - public async openBill(tenantId: number, billId: number): Promise { - const { Bill } = this.tenancy.models(tenantId); - - // Retrieve the given bill or throw not found error. - const oldBill = await Bill.query() - .findById(billId) - .withGraphFetched('entries'); - - // Validates the bill existance. - this.validators.validateBillExistance(oldBill); - - if (oldBill.isOpen) { - throw new ServiceError(ERRORS.BILL_ALREADY_OPEN); - } - return this.uow.withTransaction(tenantId, async (trx) => { - // Triggers `onBillCreating` event. - await this.eventPublisher.emitAsync(events.bill.onOpening, { - trx, - tenantId, - oldBill, - } as IBillOpeningPayload); - - // Save the bill opened at on the storage. - const bill = await Bill.query(trx) - .patchAndFetchById(billId, { - openedAt: moment().toMySqlDateTime(), - }) - .withGraphFetched('entries'); - - // Triggers `onBillCreating` event. - await this.eventPublisher.emitAsync(events.bill.onOpened, { - trx, - bill, - oldBill, - tenantId, - } as IBillOpenedPayload); - }); - } -} diff --git a/packages/server/src/services/Purchases/Bills/PurchaseInvoiceTransformer.ts b/packages/server/src/services/Purchases/Bills/PurchaseInvoiceTransformer.ts deleted file mode 100644 index 05aa0311d..000000000 --- a/packages/server/src/services/Purchases/Bills/PurchaseInvoiceTransformer.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { IBill } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; -import { ItemEntryTransformer } from '@/services/Sales/Invoices/ItemEntryTransformer'; -import { SaleInvoiceTaxEntryTransformer } from '@/services/Sales/Invoices/SaleInvoiceTaxEntryTransformer'; -import { formatNumber } from 'utils'; - -export class PurchaseInvoiceTransformer extends Transformer { - /** - * Include these attributes to sale bill object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedBillDate', - 'formattedDueDate', - 'formattedCreatedAt', - 'formattedAmount', - 'formattedPaymentAmount', - 'formattedBalance', - 'formattedDueAmount', - 'formattedExchangeRate', - - 'subtotalFormatted', - 'subtotalLocalFormatted', - - 'subtotalExcludingTaxFormatted', - 'taxAmountWithheldLocalFormatted', - - 'discountAmountFormatted', - 'discountAmountLocalFormatted', - - 'discountPercentageFormatted', - - 'adjustmentFormatted', - 'adjustmentLocalFormatted', - - 'totalFormatted', - 'totalLocalFormatted', - 'taxes', - 'entries', - 'attachments', - ]; - }; - - /** - * Excluded attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['amount', 'amountLocal', 'localAmount']; - }; - - /** - * Retrieve formatted bill date. - * @param {IBill} bill - * @returns {String} - */ - protected formattedBillDate = (bill: IBill): string => { - return this.formatDate(bill.billDate); - }; - - /** - * Retrieve formatted bill date. - * @param {IBill} bill - * @returns {String} - */ - protected formattedDueDate = (bill: IBill): string => { - return this.formatDate(bill.dueDate); - }; - - /** - * Retrieve the formatted created at date. - * @param {IBill} bill - * @returns {string} - */ - protected formattedCreatedAt = (bill: IBill): string => { - return this.formatDate(bill.createdAt); - }; - - /** - * Retrieve formatted bill amount. - * @param {IBill} bill - * @returns {string} - */ - protected formattedAmount = (bill): string => { - return formatNumber(bill.amount, { currencyCode: bill.currencyCode }); - }; - - /** - * Retrieve formatted bill amount. - * @param {IBill} bill - * @returns {string} - */ - protected formattedPaymentAmount = (bill): string => { - return formatNumber(bill.paymentAmount, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieve formatted bill amount. - * @param {IBill} bill - * @returns {string} - */ - protected formattedDueAmount = (bill): string => { - return formatNumber(bill.dueAmount, { currencyCode: bill.currencyCode }); - }; - - /** - * Retrieve formatted bill balance. - * @param {IBill} bill - * @returns {string} - */ - protected formattedBalance = (bill): string => { - return formatNumber(bill.balance, { currencyCode: bill.currencyCode }); - }; - - /** - * Retrieve the formatted exchange rate. - * @param {IBill} bill - * @returns {string} - */ - protected formattedExchangeRate = (bill): string => { - return formatNumber(bill.exchangeRate, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieves the formatted subtotal. - * @param {IBill} bill - * @returns {string} - */ - protected subtotalFormatted = (bill): string => { - return formatNumber(bill.subtotal, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieves the local subtotal formatted. - * @param {IBill} bill - * @returns {string} - */ - protected subtotalLocalFormatted = (bill): string => { - return formatNumber(bill.subtotalLocal, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieves the formatted subtotal tax excluded. - * @param {IBill} bill - * @returns {string} - */ - protected subtotalExcludingTaxFormatted = (bill): string => { - return formatNumber(bill.subtotalExludingTax, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieves the local formatted tax amount withheld - * @param {IBill} bill - * @returns {string} - */ - protected taxAmountWithheldLocalFormatted = (bill): string => { - return formatNumber(bill.taxAmountWithheldLocal, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieves the formatted discount amount. - * @param {IBill} bill - * @returns {string} - */ - protected discountAmountFormatted = (bill): string => { - return formatNumber(bill.discountAmount, { - currencyCode: bill.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted discount amount in local currency. - * @param {IBill} bill - * @returns {string} - */ - protected discountAmountLocalFormatted = (bill): string => { - return formatNumber(bill.discountAmountLocal, { - currencyCode: this.context.organization.baseCurrency, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted discount percentage. - * @param {IBill} bill - * @returns {string} - */ - protected discountPercentageFormatted = (bill): string => { - return bill.discountPercentage ? `${bill.discountPercentage}%` : ''; - }; - - /** - * Retrieves the formatted adjustment amount. - * @param {IBill} bill - * @returns {string} - */ - protected adjustmentFormatted = (bill): string => { - return formatNumber(bill.adjustment, { - currencyCode: bill.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted adjustment amount in local currency. - * @param {IBill} bill - * @returns {string} - */ - protected adjustmentLocalFormatted = (bill): string => { - return formatNumber(bill.adjustmentLocal, { - currencyCode: this.context.organization.baseCurrency, - excerptZero: true, - }); - }; - - /** - * Retrieves the total formatted. - * @param {IBill} bill - * @returns {string} - */ - protected totalFormatted = (bill): string => { - return formatNumber(bill.total, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieves the local total formatted. - * @param {IBill} bill - * @returns {string} - */ - protected totalLocalFormatted = (bill): string => { - return formatNumber(bill.totalLocal, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieve the taxes lines of bill. - * @param {Bill} bill - */ - protected taxes = (bill) => { - return this.item(bill.taxes, new SaleInvoiceTaxEntryTransformer(), { - subtotal: bill.subtotal, - isInclusiveTax: bill.isInclusiveTax, - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieves the entries of the bill. - * @param {Bill} credit - * @returns {} - */ - protected entries = (bill) => { - return this.item(bill.entries, new ItemEntryTransformer(), { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieves the bill attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (bill) => { - return this.item(bill.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/Purchases/Bills/constants.ts b/packages/server/src/services/Purchases/Bills/constants.ts deleted file mode 100644 index fe61c5857..000000000 --- a/packages/server/src/services/Purchases/Bills/constants.ts +++ /dev/null @@ -1,123 +0,0 @@ -export const ERRORS = { - BILL_NOT_FOUND: 'BILL_NOT_FOUND', - BILL_VENDOR_NOT_FOUND: 'BILL_VENDOR_NOT_FOUND', - BILL_ITEMS_NOT_PURCHASABLE: 'BILL_ITEMS_NOT_PURCHASABLE', - BILL_NUMBER_EXISTS: 'BILL_NUMBER_EXISTS', - BILL_ITEMS_NOT_FOUND: 'BILL_ITEMS_NOT_FOUND', - BILL_ENTRIES_IDS_NOT_FOUND: 'BILL_ENTRIES_IDS_NOT_FOUND', - NOT_PURCHASE_ABLE_ITEMS: 'NOT_PURCHASE_ABLE_ITEMS', - BILL_ALREADY_OPEN: 'BILL_ALREADY_OPEN', - BILL_NO_IS_REQUIRED: 'BILL_NO_IS_REQUIRED', - BILL_HAS_ASSOCIATED_PAYMENT_ENTRIES: 'BILL_HAS_ASSOCIATED_PAYMENT_ENTRIES', - VENDOR_HAS_BILLS: 'VENDOR_HAS_BILLS', - BILL_HAS_ASSOCIATED_LANDED_COSTS: 'BILL_HAS_ASSOCIATED_LANDED_COSTS', - BILL_ENTRIES_ALLOCATED_COST_COULD_DELETED: - 'BILL_ENTRIES_ALLOCATED_COST_COULD_DELETED', - LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES: - 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES', - LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS: - 'LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS', - BILL_HAS_APPLIED_TO_VENDOR_CREDIT: 'BILL_HAS_APPLIED_TO_VENDOR_CREDIT', - BILL_AMOUNT_SMALLER_THAN_PAID_AMOUNT: 'BILL_AMOUNT_SMALLER_THAN_PAID_AMOUNT', -}; - -export const DEFAULT_VIEW_COLUMNS = []; - -export const DEFAULT_VIEWS = [ - { - name: 'Draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Opened', - slug: 'opened', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'opened' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Unpaid', - slug: 'unpaid', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'unpaid' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Overdue', - slug: 'overdue', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'overdue' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Partially paid', - slug: 'partially-paid', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'partially-paid', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const BillsSampleData = [ - { - 'Bill No.': 'B-101', - 'Reference No.': 'REF0', - Date: '2024-01-01', - 'Due Date': '2024-03-01', - Vendor: 'Gabriel Kovacek', - 'Exchange Rate': 1, - Note: 'Vel in sit sint.', - Open: 'T', - Item: 'VonRueden, Ruecker and Hettinger', - Quantity: 100, - Rate: 100, - 'Line Description': 'Id a vel quis vel aut.', - }, - { - 'Bill No.': 'B-102', - 'Reference No.': 'REF0', - Date: '2024-01-01', - 'Due Date': '2024-03-01', - Vendor: 'Gabriel Kovacek', - 'Exchange Rate': 1, - Note: 'Quia ut dolorem qui sint velit.', - Open: 'T', - Item: 'Thompson - Reichert', - Quantity: 200, - Rate: 50, - 'Line Description': - 'Nesciunt in adipisci quia ab reiciendis nam sed saepe consequatur.', - }, - { - 'Bill No.': 'B-103', - 'Reference No.': 'REF0', - Date: '2024-01-01', - 'Due Date': '2024-03-01', - Vendor: 'Gabriel Kovacek', - 'Exchange Rate': 1, - Note: 'Dolore aut voluptatem minus pariatur alias pariatur.', - Open: 'T', - Item: 'VonRueden, Ruecker and Hettinger', - Quantity: 100, - Rate: 100, - 'Line Description': 'Quam eligendi provident.', - }, -]; diff --git a/packages/server/src/services/Purchases/LandedCost/AllocateLandedCost.ts b/packages/server/src/services/Purchases/LandedCost/AllocateLandedCost.ts deleted file mode 100644 index 958fb3370..000000000 --- a/packages/server/src/services/Purchases/LandedCost/AllocateLandedCost.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - IAllocatedLandedCostCreatedPayload, - IBillLandedCost, - ILandedCostDTO, -} from '@/interfaces'; -import BaseLandedCostService from './BaseLandedCost'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export default class AllocateLandedCost extends BaseLandedCostService { - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * ================================= - * - Allocate landed cost. - * ================================= - * - Validates the allocate cost not the same purchase invoice id. - * - Get the given bill (purchase invoice) or throw not found error. - * - Get the given landed cost transaction or throw not found error. - * - Validate landed cost transaction has enough unallocated cost amount. - * - Validate landed cost transaction entry has enough unallocated cost amount. - * - Validate allocate entries existance and associated with cost bill transaction. - * - Writes inventory landed cost transaction. - * - Increment the allocated landed cost transaction. - * - Increment the allocated landed cost transaction entry. - * -------------------------------- - * @param {ILandedCostDTO} landedCostDTO - Landed cost DTO. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Purchase invoice id. - */ - public allocateLandedCost = async ( - tenantId: number, - allocateCostDTO: ILandedCostDTO, - billId: number - ): Promise => { - const { BillLandedCost, Bill } = this.tenancy.models(tenantId); - - // Retrieve total cost of allocated items. - const amount = this.getAllocateItemsCostTotal(allocateCostDTO); - - // Retrieve the purchase invoice or throw not found error. - const bill = await Bill.query() - .findById(billId) - .withGraphFetched('entries') - .throwIfNotFound(); - - // Retrieve landed cost transaction or throw not found service error. - const costTransaction = await this.getLandedCostOrThrowError( - tenantId, - allocateCostDTO.transactionType, - allocateCostDTO.transactionId - ); - // Retrieve landed cost transaction entries. - const costTransactionEntry = await this.getLandedCostEntry( - tenantId, - allocateCostDTO.transactionType, - allocateCostDTO.transactionId, - allocateCostDTO.transactionEntryId - ); - // Validates allocate cost items association with the purchase invoice entries. - this.validateAllocateCostItems(bill.entries, allocateCostDTO.items); - - // Validate the amount of cost with unallocated landed cost. - this.validateLandedCostEntryAmount( - costTransactionEntry.unallocatedCostAmount, - amount - ); - // Transformes DTO to bill landed cost model object. - const billLandedCostObj = this.transformToBillLandedCost( - allocateCostDTO, - bill, - costTransaction, - costTransactionEntry - ); - // Saves landed cost transactions with associated tranasctions under - // unit-of-work eniverment. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Save the bill landed cost model. - const billLandedCost = await BillLandedCost.query(trx).insertGraph( - billLandedCostObj - ); - // Triggers `onBillLandedCostCreated` event. - await this.eventPublisher.emitAsync(events.billLandedCost.onCreated, { - tenantId, - bill, - billLandedCostId: billLandedCost.id, - billLandedCost, - costTransaction, - costTransactionEntry, - trx, - } as IAllocatedLandedCostCreatedPayload); - - return billLandedCost; - }); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/BaseLandedCost.ts b/packages/server/src/services/Purchases/LandedCost/BaseLandedCost.ts deleted file mode 100644 index c133a7205..000000000 --- a/packages/server/src/services/Purchases/LandedCost/BaseLandedCost.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { difference, sumBy } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import { - IItemEntry, - IBill, - ILandedCostItemDTO, - ILandedCostDTO, - IBillLandedCostTransaction, - ILandedCostTransaction, - ILandedCostTransactionEntry, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import TransactionLandedCost from './TransctionLandedCost'; -import { ERRORS, CONFIG } from './utils'; - -@Service() -export default class BaseLandedCostService { - @Inject() - public tenancy: HasTenancyService; - - @Inject() - public transactionLandedCost: TransactionLandedCost; - - /** - * Validates allocate cost items association with the purchase invoice entries. - * @param {IItemEntry[]} purchaseInvoiceEntries - * @param {ILandedCostItemDTO[]} landedCostItems - */ - protected validateAllocateCostItems = ( - purchaseInvoiceEntries: IItemEntry[], - landedCostItems: ILandedCostItemDTO[] - ): void => { - // Purchase invoice entries items ids. - const purchaseInvoiceItems = purchaseInvoiceEntries.map((e) => e.id); - const landedCostItemsIds = landedCostItems.map((item) => item.entryId); - - // Not found items ids. - const notFoundItemsIds = difference( - purchaseInvoiceItems, - landedCostItemsIds - ); - // Throw items ids not found service error. - if (notFoundItemsIds.length > 0) { - throw new ServiceError(ERRORS.LANDED_COST_ITEMS_IDS_NOT_FOUND); - } - }; - - /** - * Transformes DTO to bill landed cost model object. - * @param {ILandedCostDTO} landedCostDTO - * @param {IBill} bill - * @param {ILandedCostTransaction} costTransaction - * @param {ILandedCostTransactionEntry} costTransactionEntry - * @returns - */ - protected transformToBillLandedCost( - landedCostDTO: ILandedCostDTO, - bill: IBill, - costTransaction: ILandedCostTransaction, - costTransactionEntry: ILandedCostTransactionEntry - ) { - const amount = sumBy(landedCostDTO.items, 'cost'); - - return { - billId: bill.id, - - fromTransactionType: landedCostDTO.transactionType, - fromTransactionId: landedCostDTO.transactionId, - fromTransactionEntryId: landedCostDTO.transactionEntryId, - - amount, - currencyCode: costTransaction.currencyCode, - exchangeRate: costTransaction.exchangeRate || 1, - - allocationMethod: landedCostDTO.allocationMethod, - allocateEntries: landedCostDTO.items, - - description: landedCostDTO.description, - costAccountId: costTransactionEntry.costAccountId, - }; - } - - /** - * Retrieve the cost transaction or throw not found error. - * @param {number} tenantId - * @param {transactionType} transactionType - - * @param {transactionId} transactionId - - */ - public getLandedCostOrThrowError = async ( - tenantId: number, - transactionType: string, - transactionId: number - ) => { - const Model = this.transactionLandedCost.getModel( - tenantId, - transactionType - ); - const model = await Model.query().findById(transactionId); - - if (!model) { - throw new ServiceError(ERRORS.LANDED_COST_TRANSACTION_NOT_FOUND); - } - return this.transactionLandedCost.transformToLandedCost( - transactionType, - model - ); - }; - - /** - * Retrieve the landed cost entries. - * @param {number} tenantId - * @param {string} transactionType - * @param {number} transactionId - * @returns - */ - public getLandedCostEntry = async ( - tenantId: number, - transactionType: string, - transactionId: number, - transactionEntryId: number - ): Promise => { - const Model = this.transactionLandedCost.getModel( - tenantId, - transactionType - ); - const relation = CONFIG.COST_TYPES[transactionType].entries; - - const entry = await Model.relatedQuery(relation) - .for(transactionId) - .findOne('id', transactionEntryId) - .where('landedCost', true) - .onBuild((q) => { - if (transactionType === 'Bill') { - q.withGraphFetched('item'); - } else if (transactionType === 'Expense') { - q.withGraphFetched('expenseAccount'); - } - }); - - if (!entry) { - throw new ServiceError(ERRORS.LANDED_COST_ENTRY_NOT_FOUND); - } - return this.transactionLandedCost.transformToLandedCostEntry( - transactionType, - entry - ); - }; - - /** - * Retrieve allocate items cost total. - * @param {ILandedCostDTO} landedCostDTO - * @returns {number} - */ - protected getAllocateItemsCostTotal = ( - landedCostDTO: ILandedCostDTO - ): number => { - return sumBy(landedCostDTO.items, 'cost'); - }; - - /** - * Validates the landed cost entry amount. - * @param {number} unallocatedCost - - * @param {number} amount - - */ - protected validateLandedCostEntryAmount = ( - unallocatedCost: number, - amount: number - ): void => { - if (unallocatedCost < amount) { - throw new ServiceError(ERRORS.COST_AMOUNT_BIGGER_THAN_UNALLOCATED_AMOUNT); - } - }; - - /** - * Retrieve the give bill landed cost or throw not found service error. - * @param {number} tenantId - Tenant id. - * @param {number} landedCostId - Landed cost id. - * @returns {Promise} - */ - public getBillLandedCostOrThrowError = async ( - tenantId: number, - landedCostId: number - ): Promise => { - const { BillLandedCost } = this.tenancy.models(tenantId); - - // Retrieve the bill landed cost model. - const billLandedCost = await BillLandedCost.query().findById(landedCostId); - - if (!billLandedCost) { - throw new ServiceError(ERRORS.BILL_LANDED_COST_NOT_FOUND); - } - return billLandedCost; - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/BillAllocatedLandedCostTransactions.ts b/packages/server/src/services/Purchases/LandedCost/BillAllocatedLandedCostTransactions.ts deleted file mode 100644 index 29b843e7a..000000000 --- a/packages/server/src/services/Purchases/LandedCost/BillAllocatedLandedCostTransactions.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { omit } from 'lodash'; -import * as R from 'ramda'; -import * as qim from 'qim'; -import { IBillLandedCostTransaction } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { formatNumber } from 'utils'; -import I18nService from '@/services/I18n/I18nService'; - -@Service() -export default class BillAllocatedLandedCostTransactions { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private i18nService: I18nService; - - /** - * Retrieve the bill associated landed cost transactions. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Bill id. - * @return {Promise} - */ - public getBillLandedCostTransactions = async ( - tenantId: number, - billId: number - ): Promise => { - const { BillLandedCost, Bill } = this.tenancy.models(tenantId); - - // Retrieve the given bill id or throw not found service error. - const bill = await Bill.query().findById(billId).throwIfNotFound(); - - // Retrieve the bill associated allocated landed cost with bill and expense entry. - const landedCostTransactions = await BillLandedCost.query() - .where('bill_id', billId) - .withGraphFetched('allocateEntries') - .withGraphFetched('allocatedFromBillEntry.item') - .withGraphFetched('allocatedFromExpenseEntry.expenseAccount') - .withGraphFetched('bill'); - - const transactionsJson = this.i18nService.i18nApply( - [[qim.$each, 'allocationMethodFormatted']], - landedCostTransactions.map((a) => a.toJSON()), - tenantId - ); - return this.transformBillLandedCostTransactions(transactionsJson); - }; - - /** - * - * @param {IBillLandedCostTransaction[]} landedCostTransactions - * @returns - */ - private transformBillLandedCostTransactions = ( - landedCostTransactions: IBillLandedCostTransaction[] - ) => { - return landedCostTransactions.map(this.transformBillLandedCostTransaction); - }; - - /** - * - * @param {IBillLandedCostTransaction} transaction - * @returns - */ - private transformBillLandedCostTransaction = ( - transaction: IBillLandedCostTransaction - ) => { - const getTransactionName = R.curry(this.condBillLandedTransactionName)( - transaction.fromTransactionType - ); - const getTransactionDesc = R.curry( - this.condBillLandedTransactionDescription - )(transaction.fromTransactionType); - - return { - formattedAmount: formatNumber(transaction.amount, { - currencyCode: transaction.currencyCode, - }), - ...omit(transaction, [ - 'allocatedFromBillEntry', - 'allocatedFromExpenseEntry', - ]), - name: getTransactionName(transaction), - description: getTransactionDesc(transaction), - formattedLocalAmount: formatNumber(transaction.localAmount, { - currencyCode: 'USD', - }), - }; - }; - - /** - * Retrieve bill landed cost tranaction name based on the given transaction type. - * @param transactionType - * @param transaction - * @returns - */ - private condBillLandedTransactionName = ( - transactionType: string, - transaction - ) => { - return R.cond([ - [ - R.always(R.equals(transactionType, 'Bill')), - this.getLandedBillTransactionName, - ], - [ - R.always(R.equals(transactionType, 'Expense')), - this.getLandedExpenseTransactionName, - ], - ])(transaction); - }; - - /** - * - * @param transaction - * @returns - */ - private getLandedBillTransactionName = (transaction): string => { - return transaction.allocatedFromBillEntry.item.name; - }; - - /** - * - * @param transaction - * @returns - */ - private getLandedExpenseTransactionName = (transaction): string => { - return transaction.allocatedFromExpenseEntry.expenseAccount.name; - }; - - /** - * Retrieve landed cost. - * @param transaction - * @returns - */ - private getLandedBillTransactionDescription = (transaction): string => { - return transaction.allocatedFromBillEntry.description; - }; - - /** - * - * @param transaction - * @returns - */ - private getLandedExpenseTransactionDescription = (transaction): string => { - return transaction.allocatedFromExpenseEntry.description; - }; - - /** - * Retrieve the bill landed cost transaction description based on transaction type. - * @param {string} tranasctionType - * @param transaction - * @returns - */ - private condBillLandedTransactionDescription = ( - tranasctionType: string, - transaction - ) => { - return R.cond([ - [ - R.always(R.equals(tranasctionType, 'Bill')), - this.getLandedBillTransactionDescription, - ], - [ - R.always(R.equals(tranasctionType, 'Expense')), - this.getLandedExpenseTransactionDescription, - ], - ])(transaction); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/BillLandedCost.ts b/packages/server/src/services/Purchases/LandedCost/BillLandedCost.ts deleted file mode 100644 index ebe8b308b..000000000 --- a/packages/server/src/services/Purchases/LandedCost/BillLandedCost.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import { - IBill, - IItem, - ILandedCostTransactionEntry, - ILandedCostTransaction, - IItemEntry, -} from '@/interfaces'; - -@Service() -export default class BillLandedCost { - /** - * Retrieve the landed cost transaction from the given bill transaction. - * @param {IBill} bill - Bill transaction. - * @returns {ILandedCostTransaction} - Landed cost transaction. - */ - public transformToLandedCost = (bill: IBill): ILandedCostTransaction => { - const name = bill.billNumber || bill.referenceNo; - - return { - id: bill.id, - name, - allocatedCostAmount: bill.allocatedCostAmount, - amount: bill.landedCostAmount, - unallocatedCostAmount: bill.unallocatedCostAmount, - transactionType: 'Bill', - currencyCode: bill.currencyCode, - exchangeRate: bill.exchangeRate, - - ...(!isEmpty(bill.entries) && { - entries: bill.entries.map(this.transformToLandedCostEntry), - }), - }; - }; - - /** - * Transformes bill entry to landed cost entry. - * @param {IBill} bill - Bill model. - * @param {IItemEntry} billEntry - Bill entry. - * @return {ILandedCostTransactionEntry} - */ - public transformToLandedCostEntry( - billEntry: IItemEntry & { item: IItem } - ): ILandedCostTransactionEntry { - return { - id: billEntry.id, - name: billEntry.item.name, - code: billEntry.item.code, - amount: billEntry.amount, - - unallocatedCostAmount: billEntry.unallocatedCostAmount, - allocatedCostAmount: billEntry.allocatedCostAmount, - description: billEntry.description, - costAccountId: billEntry.costAccountId || billEntry.item.costAccountId, - }; - } -} diff --git a/packages/server/src/services/Purchases/LandedCost/ExpenseLandedCost.ts b/packages/server/src/services/Purchases/LandedCost/ExpenseLandedCost.ts deleted file mode 100644 index b9d1c3613..000000000 --- a/packages/server/src/services/Purchases/LandedCost/ExpenseLandedCost.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Service } from 'typedi'; -import { isEmpty } from 'lodash'; -import * as R from 'ramda'; -import { - IExpense, - ILandedCostTransactionEntry, - IExpenseCategory, - IAccount, - ILandedCostTransaction, -} from '@/interfaces'; - -@Service() -export default class ExpenseLandedCost { - /** - * Retrieve the landed cost transaction from the given expense transaction. - * @param {IExpense} expense - * @returns {ILandedCostTransaction} - */ - public transformToLandedCost = ( - expense: IExpense - ): ILandedCostTransaction => { - const name = 'EXP-100'; - - return { - id: expense.id, - name, - amount: expense.landedCostAmount, - allocatedCostAmount: expense.allocatedCostAmount, - unallocatedCostAmount: expense.unallocatedCostAmount, - transactionType: 'Expense', - currencyCode: expense.currencyCode, - exchangeRate: expense.exchangeRate || 1, - - ...(!isEmpty(expense.categories) && { - entries: expense.categories.map(this.transformToLandedCostEntry), - }), - }; - }; - - /** - * Transformes expense entry to landed cost entry. - * @param {IExpenseCategory & { expenseAccount: IAccount }} expenseEntry - - * @return {ILandedCostTransactionEntry} - */ - public transformToLandedCostEntry = ( - expenseEntry: IExpenseCategory & { expenseAccount: IAccount } - ): ILandedCostTransactionEntry => { - return { - id: expenseEntry.id, - name: expenseEntry.expenseAccount.name, - code: expenseEntry.expenseAccount.code, - amount: expenseEntry.amount, - description: expenseEntry.description, - allocatedCostAmount: expenseEntry.allocatedCostAmount, - unallocatedCostAmount: expenseEntry.unallocatedCostAmount, - costAccountId: expenseEntry.expenseAccount.id, - }; - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostGLEntries.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostGLEntries.ts deleted file mode 100644 index ec007ff03..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostGLEntries.ts +++ /dev/null @@ -1,249 +0,0 @@ -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { - AccountNormal, - IBill, - IBillLandedCost, - IBillLandedCostEntry, - ILandedCostTransactionEntry, - ILedger, - ILedgerEntry, -} from '@/interfaces'; -import JournalPosterService from '@/services/Sales/JournalPosterService'; -import { Service, Inject } from 'typedi'; -import LedgerRepository from '@/services/Ledger/LedgerRepository'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import BaseLandedCostService from './BaseLandedCost'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export default class LandedCostGLEntries extends BaseLandedCostService { - @Inject() - private journalService: JournalPosterService; - - @Inject() - private ledgerRepository: LedgerRepository; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the landed cost GL common entry. - * @param {IBill} bill - * @param {IBillLandedCost} allocatedLandedCost - * @returns - */ - private getLandedCostGLCommonEntry = ( - bill: IBill, - allocatedLandedCost: IBillLandedCost - ) => { - return { - date: bill.billDate, - currencyCode: allocatedLandedCost.currencyCode, - exchangeRate: allocatedLandedCost.exchangeRate, - - transactionType: 'LandedCost', - transactionId: allocatedLandedCost.id, - transactionNumber: bill.billNumber, - - referenceNumber: bill.referenceNo, - - credit: 0, - debit: 0, - }; - }; - - /** - * Retrieves the landed cost GL inventory entry. - * @param {IBill} bill - * @param {IBillLandedCost} allocatedLandedCost - * @param {IBillLandedCostEntry} allocatedEntry - * @returns {ILedgerEntry} - */ - private getLandedCostGLInventoryEntry = ( - bill: IBill, - allocatedLandedCost: IBillLandedCost, - allocatedEntry: IBillLandedCostEntry - ): ILedgerEntry => { - const commonEntry = this.getLandedCostGLCommonEntry( - bill, - allocatedLandedCost - ); - return { - ...commonEntry, - debit: allocatedLandedCost.localAmount, - accountId: allocatedEntry.itemEntry.item.inventoryAccountId, - index: 1, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieves the landed cost GL cost entry. - * @param {IBill} bill - * @param {IBillLandedCost} allocatedLandedCost - * @param {ILandedCostTransactionEntry} fromTransactionEntry - * @returns {ILedgerEntry} - */ - private getLandedCostGLCostEntry = ( - bill: IBill, - allocatedLandedCost: IBillLandedCost, - fromTransactionEntry: ILandedCostTransactionEntry - ): ILedgerEntry => { - const commonEntry = this.getLandedCostGLCommonEntry( - bill, - allocatedLandedCost - ); - return { - ...commonEntry, - credit: allocatedLandedCost.localAmount, - accountId: fromTransactionEntry.costAccountId, - index: 2, - accountNormal: AccountNormal.CREDIT, - }; - }; - - /** - * Retrieve allocated landed cost entry GL entries. - * @param {IBill} bill - * @param {IBillLandedCost} allocatedLandedCost - * @param {ILandedCostTransactionEntry} fromTransactionEntry - * @param {IBillLandedCostEntry} allocatedEntry - * @returns {ILedgerEntry} - */ - private getLandedCostGLAllocateEntry = R.curry( - ( - bill: IBill, - allocatedLandedCost: IBillLandedCost, - fromTransactionEntry: ILandedCostTransactionEntry, - allocatedEntry: IBillLandedCostEntry - ): ILedgerEntry[] => { - const inventoryEntry = this.getLandedCostGLInventoryEntry( - bill, - allocatedLandedCost, - allocatedEntry - ); - const costEntry = this.getLandedCostGLCostEntry( - bill, - allocatedLandedCost, - fromTransactionEntry - ); - return [inventoryEntry, costEntry]; - } - ); - - /** - * Compose the landed cost GL entries. - * @param {IBillLandedCost} allocatedLandedCost - * @param {IBill} bill - * @param {ILandedCostTransactionEntry} fromTransactionEntry - * @returns {ILedgerEntry[]} - */ - public getLandedCostGLEntries = ( - allocatedLandedCost: IBillLandedCost, - bill: IBill, - fromTransactionEntry: ILandedCostTransactionEntry - ): ILedgerEntry[] => { - const getEntry = this.getLandedCostGLAllocateEntry( - bill, - allocatedLandedCost, - fromTransactionEntry - ); - return allocatedLandedCost.allocateEntries.map(getEntry).flat(); - }; - - /** - * Retrieves the landed cost GL ledger. - * @param {IBillLandedCost} allocatedLandedCost - * @param {IBill} bill - * @param {ILandedCostTransactionEntry} fromTransactionEntry - * @returns {ILedger} - */ - public getLandedCostLedger = ( - allocatedLandedCost: IBillLandedCost, - bill: IBill, - fromTransactionEntry: ILandedCostTransactionEntry - ): ILedger => { - const entries = this.getLandedCostGLEntries( - allocatedLandedCost, - bill, - fromTransactionEntry - ); - return new Ledger(entries); - }; - - /** - * Writes landed cost GL entries to the storage layer. - * @param {number} tenantId - - */ - public writeLandedCostGLEntries = async ( - tenantId: number, - allocatedLandedCost: IBillLandedCost, - bill: IBill, - fromTransactionEntry: ILandedCostTransactionEntry, - trx?: Knex.Transaction - ) => { - const ledgerEntries = this.getLandedCostGLEntries( - allocatedLandedCost, - bill, - fromTransactionEntry - ); - await this.ledgerRepository.saveLedgerEntries(tenantId, ledgerEntries, trx); - }; - - /** - * Generates and writes GL entries of the given landed cost. - * @param {number} tenantId - * @param {number} billLandedCostId - * @param {Knex.Transaction} trx - */ - public createLandedCostGLEntries = async ( - tenantId: number, - billLandedCostId: number, - trx?: Knex.Transaction - ) => { - const { BillLandedCost } = this.tenancy.models(tenantId); - - // Retrieve the bill landed cost transacion with associated - // allocated entries and items. - const allocatedLandedCost = await BillLandedCost.query(trx) - .findById(billLandedCostId) - .withGraphFetched('bill') - .withGraphFetched('allocateEntries.itemEntry.item'); - - // Retrieve the allocated from transactione entry. - const transactionEntry = await this.getLandedCostEntry( - tenantId, - allocatedLandedCost.fromTransactionType, - allocatedLandedCost.fromTransactionId, - allocatedLandedCost.fromTransactionEntryId - ); - // Writes the given landed cost GL entries to the storage layer. - await this.writeLandedCostGLEntries( - tenantId, - allocatedLandedCost, - allocatedLandedCost.bill, - transactionEntry, - trx - ); - }; - - /** - * Reverts GL entries of the given allocated landed cost transaction. - * @param {number} tenantId - * @param {number} landedCostId - * @param {Knex.Transaction} trx - */ - public revertLandedCostGLEntries = async ( - tenantId: number, - landedCostId: number, - trx: Knex.Transaction - ) => { - await this.journalService.revertJournalTransactions( - tenantId, - landedCostId, - 'LandedCost', - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostGLEntriesSubscriber.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostGLEntriesSubscriber.ts deleted file mode 100644 index 1218334bd..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostGLEntriesSubscriber.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import LandedCostGLEntries from './LandedCostGLEntries'; -import { - IAllocatedLandedCostCreatedPayload, - IAllocatedLandedCostDeletedPayload, -} from '@/interfaces'; - -@Service() -export default class LandedCostGLEntriesSubscriber { - @Inject() - billLandedCostGLEntries: LandedCostGLEntries; - - attach(bus) { - bus.subscribe( - events.billLandedCost.onCreated, - this.writeGLEntriesOnceLandedCostCreated - ); - bus.subscribe( - events.billLandedCost.onDeleted, - this.revertGLEnteriesOnceLandedCostDeleted - ); - } - - /** - * Writes GL entries once landed cost transaction created. - * @param {IAllocatedLandedCostCreatedPayload} payload - - */ - private writeGLEntriesOnceLandedCostCreated = async ({ - tenantId, - billLandedCost, - trx, - }: IAllocatedLandedCostCreatedPayload) => { - await this.billLandedCostGLEntries.createLandedCostGLEntries( - tenantId, - billLandedCost.id, - trx - ); - }; - - /** - * Reverts GL entries associated to landed cost transaction once deleted. - * @param {IAllocatedLandedCostDeletedPayload} payload - - */ - private revertGLEnteriesOnceLandedCostDeleted = async ({ - tenantId, - oldBillLandedCost, - billId, - trx, - }: IAllocatedLandedCostDeletedPayload) => { - await this.billLandedCostGLEntries.revertLandedCostGLEntries( - tenantId, - oldBillLandedCost.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactions.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactions.ts deleted file mode 100644 index 8fe1b5893..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactions.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IBill, IBillLandedCostTransaction } from '@/interfaces'; -import InventoryService from '@/services/Inventory/Inventory'; -import { mergeLocatedWithBillEntries } from './utils'; - -@Service() -export default class LandedCostInventoryTransactions { - @Inject() - public inventoryService: InventoryService; - - /** - * Records inventory transactions. - * @param {number} tenantId - * @param {IBillLandedCostTransaction} billLandedCost - * @param {IBill} bill - - */ - public recordInventoryTransactions = async ( - tenantId: number, - billLandedCost: IBillLandedCostTransaction, - bill: IBill, - trx?: Knex.Transaction - ) => { - // Retrieve the merged allocated entries with bill entries. - const allocateEntries = mergeLocatedWithBillEntries( - billLandedCost.allocateEntries, - bill.entries - ); - // Mappes the allocate cost entries to inventory transactions. - const inventoryTransactions = allocateEntries.map((allocateEntry) => ({ - date: bill.billDate, - itemId: allocateEntry.entry.itemId, - direction: 'IN', - quantity: null, - rate: allocateEntry.cost, - transactionType: 'LandedCost', - transactionId: billLandedCost.id, - entryId: allocateEntry.entryId, - })); - // Writes inventory transactions. - return this.inventoryService.recordInventoryTransactions( - tenantId, - inventoryTransactions, - false, - trx - ); - }; - - /** - * Deletes the inventory transaction. - * @param {number} tenantId - Tenant id. - * @param {number} landedCostId - Landed cost id. - * @param {Knex.Transaction} trx - Knex transactions. - * @returns - */ - public removeInventoryTransactions = ( - tenantId: number, - landedCostId: number, - trx?: Knex.Transaction - ) => { - return this.inventoryService.deleteInventoryTransactions( - tenantId, - landedCostId, - 'LandedCost', - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber.ts deleted file mode 100644 index 4a295e89f..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IAllocatedLandedCostCreatedPayload, - IAllocatedLandedCostDeletedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import LandedCostInventoryTransactions from './LandedCostInventoryTransactions'; - -@Service() -export default class LandedCostInventoryTransactionsSubscriber { - @Inject() - landedCostInventory: LandedCostInventoryTransactions; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.billLandedCost.onCreated, - this.writeInventoryTransactionsOnceCreated - ); - bus.subscribe( - events.billLandedCost.onDeleted, - this.revertInventoryTransactionsOnceDeleted - ); - } - - /** - * Writes inventory transactions of the landed cost transaction once created. - * @param {IAllocatedLandedCostCreatedPayload} payload - - */ - private writeInventoryTransactionsOnceCreated = async ({ - billLandedCost, - tenantId, - trx, - bill, - }: IAllocatedLandedCostCreatedPayload) => { - // Records the inventory transactions. - await this.landedCostInventory.recordInventoryTransactions( - tenantId, - billLandedCost, - bill, - trx - ); - }; - - /** - * Reverts inventory transactions of the landed cost transaction once deleted. - * @param {IAllocatedLandedCostDeletedPayload} payload - - */ - private revertInventoryTransactionsOnceDeleted = async ({ - tenantId, - oldBillLandedCost, - trx, - }: IAllocatedLandedCostDeletedPayload) => { - // Removes the inventory transactions. - await this.landedCostInventory.removeInventoryTransactions( - tenantId, - oldBillLandedCost.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactions.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactions.ts deleted file mode 100644 index 55a6fe61c..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactions.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import TransactionLandedCost from './TransctionLandedCost'; -import { CONFIG } from './utils'; - -@Service() -export default class LandedCostSyncCostTransactions { - @Inject() - transactionLandedCost: TransactionLandedCost; - - /** - * Allocate the landed cost amount to cost transactions. - * @param {number} tenantId - - * @param {string} transactionType - * @param {number} transactionId - */ - public incrementLandedCostAmount = async ( - tenantId: number, - transactionType: string, - transactionId: number, - transactionEntryId: number, - amount: number, - trx?: Knex.Transaction - ): Promise => { - const Model = this.transactionLandedCost.getModel( - tenantId, - transactionType - ); - const relation = CONFIG.COST_TYPES[transactionType].entries; - - // Increment the landed cost transaction amount. - await Model.query(trx) - .where('id', transactionId) - .increment('allocatedCostAmount', amount); - - // Increment the landed cost entry. - await Model.relatedQuery(relation, trx) - .for(transactionId) - .where('id', transactionEntryId) - .increment('allocatedCostAmount', amount); - }; - - /** - * Reverts the landed cost amount to cost transaction. - * @param {number} tenantId - Tenant id. - * @param {string} transactionType - Transaction type. - * @param {number} transactionId - Transaction id. - * @param {number} transactionEntryId - Transaction entry id. - * @param {number} amount - Amount - */ - public revertLandedCostAmount = async ( - tenantId: number, - transactionType: string, - transactionId: number, - transactionEntryId: number, - amount: number, - trx?: Knex.Transaction - ) => { - const Model = this.transactionLandedCost.getModel( - tenantId, - transactionType - ); - const relation = CONFIG.COST_TYPES[transactionType].entries; - - // Decrement the allocate cost amount of cost transaction. - await Model.query(trx) - .where('id', transactionId) - .decrement('allocatedCostAmount', amount); - - // Decrement the allocated cost amount cost transaction entry. - await Model.relatedQuery(relation, trx) - .for(transactionId) - .where('id', transactionEntryId) - .decrement('allocatedCostAmount', amount); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber.ts deleted file mode 100644 index 6b9526e43..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IAllocatedLandedCostCreatedPayload, - IAllocatedLandedCostDeletedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import LandedCostSyncCostTransactions from './LandedCostSyncCostTransactions'; - -@Service() -export default class LandedCostSyncCostTransactionsSubscriber { - @Inject() - private landedCostSyncCostTransaction: LandedCostSyncCostTransactions; - - /** - * Attaches events with handlers. - */ - attach(bus) { - bus.subscribe( - events.billLandedCost.onCreated, - this.incrementCostTransactionsOnceCreated - ); - bus.subscribe( - events.billLandedCost.onDeleted, - this.decrementCostTransactionsOnceDeleted - ); - } - - /** - * Increment cost transactions once the landed cost allocated. - * @param {IAllocatedLandedCostCreatedPayload} payload - - */ - private incrementCostTransactionsOnceCreated = async ({ - tenantId, - billLandedCost, - trx, - }: IAllocatedLandedCostCreatedPayload) => { - // Increment landed cost amount on transaction and entry. - await this.landedCostSyncCostTransaction.incrementLandedCostAmount( - tenantId, - billLandedCost.fromTransactionType, - billLandedCost.fromTransactionId, - billLandedCost.fromTransactionEntryId, - billLandedCost.amount, - trx - ); - }; - - /** - * Decrement cost transactions once the allocated landed cost reverted. - * @param {IAllocatedLandedCostDeletedPayload} payload - - */ - private decrementCostTransactionsOnceDeleted = async ({ - oldBillLandedCost, - tenantId, - trx, - }: IAllocatedLandedCostDeletedPayload) => { - // Reverts the landed cost amount to the cost transaction. - await this.landedCostSyncCostTransaction.revertLandedCostAmount( - tenantId, - oldBillLandedCost.fromTransactionType, - oldBillLandedCost.fromTransactionId, - oldBillLandedCost.fromTransactionEntryId, - oldBillLandedCost.amount, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/LandedCostTransactions.ts b/packages/server/src/services/Purchases/LandedCost/LandedCostTransactions.ts deleted file mode 100644 index 5195ea368..000000000 --- a/packages/server/src/services/Purchases/LandedCost/LandedCostTransactions.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ref } from 'objection'; -import * as R from 'ramda'; -import { - ILandedCostTransactionsQueryDTO, - ILandedCostTransaction, - ILandedCostTransactionDOJO, - ILandedCostTransactionEntry, - ILandedCostTransactionEntryDOJO, -} from '@/interfaces'; -import TransactionLandedCost from './TransctionLandedCost'; -import { formatNumber } from 'utils'; - -@Service() -export default class LandedCostTranasctions { - @Inject() - private transactionLandedCost: TransactionLandedCost; - - /** - * Retrieve the landed costs based on the given query. - * @param {number} tenantId - * @param {ILandedCostTransactionsQueryDTO} query - * @returns {Promise} - */ - public getLandedCostTransactions = async ( - tenantId: number, - query: ILandedCostTransactionsQueryDTO - ): Promise => { - const { transactionType } = query; - const Model = this.transactionLandedCost.getModel( - tenantId, - query.transactionType - ); - // Retrieve the model entities. - const transactions = await Model.query().onBuild((q) => { - q.where('allocated_cost_amount', '<', ref('landed_cost_amount')); - - if (query.transactionType === 'Bill') { - q.withGraphFetched('entries.item'); - } else if (query.transactionType === 'Expense') { - q.withGraphFetched('categories.expenseAccount'); - } - }); - const transformLandedCost = - this.transactionLandedCost.transformToLandedCost(transactionType); - - return R.compose( - this.transformLandedCostTransactions, - R.map(transformLandedCost) - )(transactions); - }; - - /** - * - * @param transactions - * @returns - */ - public transformLandedCostTransactions = ( - transactions: ILandedCostTransaction[] - ) => { - return R.map(this.transformLandedCostTransaction)(transactions); - }; - - /** - * Transformes the landed cost transaction. - * @param {ILandedCostTransaction} transaction - */ - public transformLandedCostTransaction = ( - transaction: ILandedCostTransaction - ): ILandedCostTransactionDOJO => { - const { currencyCode } = transaction; - - // Formatted transaction amount. - const formattedAmount = formatNumber(transaction.amount, { currencyCode }); - - // Formatted transaction unallocated cost amount. - const formattedUnallocatedCostAmount = formatNumber( - transaction.unallocatedCostAmount, - { currencyCode } - ); - // Formatted transaction allocated cost amount. - const formattedAllocatedCostAmount = formatNumber( - transaction.allocatedCostAmount, - { currencyCode } - ); - - return { - ...transaction, - formattedAmount, - formattedUnallocatedCostAmount, - formattedAllocatedCostAmount, - entries: R.map(this.transformLandedCostEntry(transaction))( - transaction.entries - ), - }; - }; - - /** - * - * @param {ILandedCostTransaction} transaction - * @param {ILandedCostTransactionEntry} entry - * @returns {ILandedCostTransactionEntryDOJO} - */ - public transformLandedCostEntry = R.curry( - ( - transaction: ILandedCostTransaction, - entry: ILandedCostTransactionEntry - ): ILandedCostTransactionEntryDOJO => { - const { currencyCode } = transaction; - - // Formatted entry amount. - const formattedAmount = formatNumber(entry.amount, { currencyCode }); - - // Formatted entry unallocated cost amount. - const formattedUnallocatedCostAmount = formatNumber( - entry.unallocatedCostAmount, - { currencyCode } - ); - // Formatted entry allocated cost amount. - const formattedAllocatedCostAmount = formatNumber( - entry.allocatedCostAmount, - { currencyCode } - ); - return { - ...entry, - formattedAmount, - formattedUnallocatedCostAmount, - formattedAllocatedCostAmount, - }; - } - ); -} diff --git a/packages/server/src/services/Purchases/LandedCost/RevertAllocatedLandedCost.ts b/packages/server/src/services/Purchases/LandedCost/RevertAllocatedLandedCost.ts deleted file mode 100644 index df18b6065..000000000 --- a/packages/server/src/services/Purchases/LandedCost/RevertAllocatedLandedCost.ts +++ /dev/null @@ -1,78 +0,0 @@ -import Knex from 'knex'; -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import BaseLandedCost from './BaseLandedCost'; -import { IAllocatedLandedCostDeletedPayload } from '@/interfaces'; - -@Service() -export default class RevertAllocatedLandedCost extends BaseLandedCost { - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Deletes the allocated landed cost. - * ================================== - * - Delete bill landed cost transaction with associated allocate entries. - * - Delete the associated inventory transactions. - * - Decrement allocated amount of landed cost transaction and entry. - * - Revert journal entries. - * ---------------------------------- - * @param {number} tenantId - Tenant id. - * @param {number} landedCostId - Landed cost id. - * @return {Promise} - */ - public deleteAllocatedLandedCost = async ( - tenantId: number, - landedCostId: number - ): Promise<{ - landedCostId: number; - }> => { - // Retrieves the bill landed cost. - const oldBillLandedCost = await this.getBillLandedCostOrThrowError( - tenantId, - landedCostId - ); - // Deletes landed cost with associated transactions. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Delete landed cost transaction with associated locate entries. - await this.deleteLandedCost(tenantId, landedCostId, trx); - - // Triggers the event `onBillLandedCostCreated`. - await this.eventPublisher.emitAsync(events.billLandedCost.onDeleted, { - tenantId, - oldBillLandedCost: oldBillLandedCost, - billId: oldBillLandedCost.billId, - trx, - } as IAllocatedLandedCostDeletedPayload); - - return { landedCostId }; - }); - }; - - /** - * Deletes the landed cost transaction with associated allocate entries. - * @param {number} tenantId - Tenant id. - * @param {number} landedCostId - Landed cost id. - */ - public deleteLandedCost = async ( - tenantId: number, - landedCostId: number, - trx?: Knex.Transaction - ): Promise => { - const { BillLandedCost, BillLandedCostEntry } = - this.tenancy.models(tenantId); - - // Deletes the bill landed cost allocated entries associated to landed cost. - await BillLandedCostEntry.query(trx) - .where('bill_located_cost_id', landedCostId) - .delete(); - - // Delete the bill landed cost from the storage. - await BillLandedCost.query(trx).where('id', landedCostId).delete(); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/TransctionLandedCost.ts b/packages/server/src/services/Purchases/LandedCost/TransctionLandedCost.ts deleted file mode 100644 index 9a8741887..000000000 --- a/packages/server/src/services/Purchases/LandedCost/TransctionLandedCost.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { Model } from 'objection'; -import { - IBill, - IExpense, - ILandedCostTransaction, - ILandedCostTransactionEntry, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import BillLandedCost from './BillLandedCost'; -import ExpenseLandedCost from './ExpenseLandedCost'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './utils'; - -@Service() -export default class TransactionLandedCost { - @Inject() - private billLandedCost: BillLandedCost; - - @Inject() - private expenseLandedCost: ExpenseLandedCost; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve the cost transaction code model. - * @param {number} tenantId - Tenant id. - * @param {string} transactionType - Transaction type. - * @returns - */ - public getModel = (tenantId: number, transactionType: string): Model => { - const Models = this.tenancy.models(tenantId); - const Model = Models[transactionType]; - - if (!Model) { - throw new ServiceError(ERRORS.COST_TYPE_UNDEFINED); - } - return Model; - }; - - /** - * Mappes the given expense or bill transaction to landed cost transaction. - * @param {string} transactionType - Transaction type. - * @param {IBill|IExpense} transaction - Expense or bill transaction. - * @returns {ILandedCostTransaction} - */ - public transformToLandedCost = R.curry( - ( - transactionType: string, - transaction: IBill | IExpense - ): ILandedCostTransaction => { - return R.compose( - R.when( - R.always(transactionType === 'Bill'), - this.billLandedCost.transformToLandedCost - ), - R.when( - R.always(transactionType === 'Expense'), - this.expenseLandedCost.transformToLandedCost - ) - )(transaction); - } - ); - - /** - * Transformes the given expense or bill entry to landed cost transaction entry. - * @param {string} transactionType - * @param {} transactionEntry - * @returns {ILandedCostTransactionEntry} - */ - public transformToLandedCostEntry = ( - transactionType: 'Bill' | 'Expense', - transactionEntry - ): ILandedCostTransactionEntry => { - return R.compose( - R.when( - R.always(transactionType === 'Bill'), - this.billLandedCost.transformToLandedCostEntry - ), - R.when( - R.always(transactionType === 'Expense'), - this.expenseLandedCost.transformToLandedCostEntry - ) - )(transactionEntry); - }; -} diff --git a/packages/server/src/services/Purchases/LandedCost/utils.ts b/packages/server/src/services/Purchases/LandedCost/utils.ts deleted file mode 100644 index f7ea7da07..000000000 --- a/packages/server/src/services/Purchases/LandedCost/utils.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { IItemEntry, IBillLandedCostTransactionEntry } from '@/interfaces'; -import { transformToMap } from 'utils'; - -export const ERRORS = { - COST_TYPE_UNDEFINED: 'COST_TYPE_UNDEFINED', - LANDED_COST_ITEMS_IDS_NOT_FOUND: 'LANDED_COST_ITEMS_IDS_NOT_FOUND', - COST_TRANSACTION_HAS_NO_ENOUGH_TO_LOCATE: - 'COST_TRANSACTION_HAS_NO_ENOUGH_TO_LOCATE', - BILL_LANDED_COST_NOT_FOUND: 'BILL_LANDED_COST_NOT_FOUND', - COST_ENTRY_ID_NOT_FOUND: 'COST_ENTRY_ID_NOT_FOUND', - LANDED_COST_TRANSACTION_NOT_FOUND: 'LANDED_COST_TRANSACTION_NOT_FOUND', - LANDED_COST_ENTRY_NOT_FOUND: 'LANDED_COST_ENTRY_NOT_FOUND', - COST_AMOUNT_BIGGER_THAN_UNALLOCATED_AMOUNT: - 'COST_AMOUNT_BIGGER_THAN_UNALLOCATED_AMOUNT', - ALLOCATE_COST_SHOULD_NOT_BE_BILL: 'ALLOCATE_COST_SHOULD_NOT_BE_BILL', -}; - -/** - * Merges item entry to bill located landed cost entry. - * @param {IBillLandedCostTransactionEntry[]} locatedEntries - - * @param {IItemEntry[]} billEntries - - * @returns {(IBillLandedCostTransactionEntry & { entry: IItemEntry })[]} - */ -export const mergeLocatedWithBillEntries = ( - locatedEntries: IBillLandedCostTransactionEntry[], - billEntries: IItemEntry[] -): (IBillLandedCostTransactionEntry & { entry: IItemEntry })[] => { - const billEntriesByEntryId = transformToMap(billEntries, 'id'); - - return locatedEntries.map((entry) => ({ - ...entry, - entry: billEntriesByEntryId.get(entry.entryId), - })); -}; - - -export const CONFIG = { - COST_TYPES: { - Expense: { - entries: 'categories', - }, - Bill: { - entries: 'entries', - }, - }, -}; \ No newline at end of file diff --git a/packages/server/src/services/Purchases/PurchasesTransactionsLocking.ts b/packages/server/src/services/Purchases/PurchasesTransactionsLocking.ts deleted file mode 100644 index 6dc8b029d..000000000 --- a/packages/server/src/services/Purchases/PurchasesTransactionsLocking.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TransactionsLockingValidator from '@/services/TransactionsLocking/TransactionsLockingGuard'; -import { TransactionsLockingGroup } from '@/interfaces'; - -@Service() -export default class PurchasesTransactionsLocking { - @Inject() - transactionLockingValidator: TransactionsLockingValidator; - - /** - * Validates the all and partial purchases transactions locking. - * @param {number} tenantId - * @param {Date} transactionDate - * @throws {ServiceError(TRANSACTIONS_DATE_LOCKED)} - */ - public transactionLockingGuard = ( - tenantId: number, - transactionDate: Date - ) => { - // Validates the all transcation locking. - this.transactionLockingValidator.validateTransactionsLocking( - tenantId, - transactionDate, - TransactionsLockingGroup.Purchases - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBills.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBills.ts deleted file mode 100644 index c6f617c60..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBills.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import Bluebird from 'bluebird'; -import { IVendorCreditAppliedBill } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class ApplyVendorCreditSyncBills { - @Inject() - private tenancy: HasTenancyService; - - /** - * Increment bills credited amount. - * @param {number} tenantId - * @param {IVendorCreditAppliedBill[]} vendorCreditAppliedBills - * @param {Knex.Transaction} trx - */ - public incrementBillsCreditedAmount = async ( - tenantId: number, - vendorCreditAppliedBills: IVendorCreditAppliedBill[], - trx?: Knex.Transaction - ) => { - const { Bill } = this.tenancy.models(tenantId); - - await Bluebird.each( - vendorCreditAppliedBills, - (vendorCreditAppliedBill: IVendorCreditAppliedBill) => { - return Bill.query(trx) - .where('id', vendorCreditAppliedBill.billId) - .increment('creditedAmount', vendorCreditAppliedBill.amount); - } - ); - }; - - /** - * Decrement bill credited amount. - * @param {number} tenantId - * @param {IVendorCreditAppliedBill} vendorCreditAppliedBill - * @param {Knex.Transaction} trx - */ - public decrementBillCreditedAmount = async ( - tenantId: number, - vendorCreditAppliedBill: IVendorCreditAppliedBill, - trx?: Knex.Transaction - ) => { - const { Bill } = this.tenancy.models(tenantId); - - await Bill.query(trx) - .findById(vendorCreditAppliedBill.billId) - .decrement('creditedAmount', vendorCreditAppliedBill.amount); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBillsSubscriber.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBillsSubscriber.ts deleted file mode 100644 index 7ef32860b..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncBillsSubscriber.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - IVendorCreditApplyToBillDeletedPayload, - IVendorCreditApplyToBillsCreatedPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import ApplyVendorCreditSyncBills from './ApplyVendorCreditSyncBills'; - -@Service() -export default class ApplyVendorCreditSyncBillsSubscriber { - @Inject() - tenancy: HasTenancyService; - - @Inject() - syncBillsWithVendorCredit: ApplyVendorCreditSyncBills; - - /** - * Attaches events with handlers. - */ - attach(bus) { - bus.subscribe( - events.vendorCredit.onApplyToInvoicesCreated, - this.incrementAppliedBillsOnceCreditCreated - ); - bus.subscribe( - events.vendorCredit.onApplyToInvoicesDeleted, - this.decrementAppliedBillsOnceCreditDeleted - ); - } - - /** - * Increment credited amount of applied bills once the vendor credit - * transaction created. - * @param {IVendorCreditApplyToBillsCreatedPayload} paylaod - - */ - private incrementAppliedBillsOnceCreditCreated = async ({ - tenantId, - vendorCreditAppliedBills, - trx, - }: IVendorCreditApplyToBillsCreatedPayload) => { - await this.syncBillsWithVendorCredit.incrementBillsCreditedAmount( - tenantId, - vendorCreditAppliedBills, - trx - ); - }; - - /** - * Decrement credited amount of applied bills once the vendor credit - * transaction delted. - * @param {IVendorCreditApplyToBillDeletedPayload} payload - */ - private decrementAppliedBillsOnceCreditDeleted = async ({ - oldCreditAppliedToBill, - tenantId, - trx, - }: IVendorCreditApplyToBillDeletedPayload) => { - await this.syncBillsWithVendorCredit.decrementBillCreditedAmount( - tenantId, - oldCreditAppliedToBill, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoiced.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoiced.ts deleted file mode 100644 index 0b720b407..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoiced.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class ApplyVendorCreditSyncInvoiced { - @Inject() - tenancy: HasTenancyService; - - /** - * Increment vendor credit invoiced amount. - * @param {number} tenantId - * @param {number} vendorCreditId - * @param {number} amount - * @param {Knex.Transaction} trx - */ - public incrementVendorCreditInvoicedAmount = async ( - tenantId: number, - vendorCreditId: number, - amount: number, - trx?: Knex.Transaction - ) => { - const { VendorCredit } = this.tenancy.models(tenantId); - - await VendorCredit.query(trx) - .findById(vendorCreditId) - .increment('invoicedAmount', amount); - }; - - /** - * Decrement credit note invoiced amount. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {number} invoicesAppliedAmount - */ - public decrementVendorCreditInvoicedAmount = async ( - tenantId: number, - vendorCreditId: number, - amount: number, - trx?: Knex.Transaction - ) => { - const { VendorCredit } = this.tenancy.models(tenantId); - - await VendorCredit.query(trx) - .findById(vendorCreditId) - .decrement('invoicedAmount', amount); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoicedSubscriber.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoicedSubscriber.ts deleted file mode 100644 index c0b834255..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditSyncInvoicedSubscriber.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { sumBy } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import ApplyVendorCreditSyncInvoiced from './ApplyVendorCreditSyncInvoiced'; -import events from '@/subscribers/events'; -import { - IVendorCreditApplyToBillDeletedPayload, - IVendorCreditApplyToBillsCreatedPayload, -} from '@/interfaces'; - -@Service() -export default class ApplyVendorCreditSyncInvoicedSubscriber { - @Inject() - tenancy: HasTenancyService; - - @Inject() - syncCreditWithInvoiced: ApplyVendorCreditSyncInvoiced; - - /** - * Attaches events with handlers. - */ - attach(bus) { - bus.subscribe( - events.vendorCredit.onApplyToInvoicesCreated, - this.incrementBillInvoicedOnceCreditApplied - ); - bus.subscribe( - events.vendorCredit.onApplyToInvoicesDeleted, - this.decrementBillInvoicedOnceCreditApplyDeleted - ); - } - - /** - * Increment vendor credit invoiced amount once the apply transaction created. - * @param {IVendorCreditApplyToBillsCreatedPayload} payload - - */ - private incrementBillInvoicedOnceCreditApplied = async ({ - vendorCredit, - tenantId, - vendorCreditAppliedBills, - trx, - }: IVendorCreditApplyToBillsCreatedPayload) => { - const amount = sumBy(vendorCreditAppliedBills, 'amount'); - - await this.syncCreditWithInvoiced.incrementVendorCreditInvoicedAmount( - tenantId, - vendorCredit.id, - amount, - trx - ); - }; - - /** - * Decrement vendor credit invoiced amount once the apply transaction deleted. - * @param {IVendorCreditApplyToBillDeletedPayload} payload - - */ - private decrementBillInvoicedOnceCreditApplyDeleted = async ({ - tenantId, - vendorCredit, - oldCreditAppliedToBill, - trx, - }: IVendorCreditApplyToBillDeletedPayload) => { - await this.syncCreditWithInvoiced.decrementVendorCreditInvoicedAmount( - tenantId, - oldCreditAppliedToBill.vendorCreditId, - oldCreditAppliedToBill.amount, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditToBills.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditToBills.ts deleted file mode 100644 index 1fa7a5628..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/ApplyVendorCreditToBills.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { sumBy } from 'lodash'; -import { - IVendorCredit, - IVendorCreditApplyToBillsCreatedPayload, - IVendorCreditApplyToInvoicesDTO, - IVendorCreditApplyToInvoicesModel, - IBill, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import VendorCredit from '../BaseVendorCredit'; -import { ServiceError } from '@/exceptions'; -import { BillPaymentValidators } from '../../BillPayments/BillPaymentValidators'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from '../constants'; - -@Service() -export default class ApplyVendorCreditToBills extends VendorCredit { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private billPaymentValidators: BillPaymentValidators; - - /** - * Apply credit note to the given invoices. - * @param {number} tenantId - * @param {number} creditNoteId - * @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO - */ - public applyVendorCreditToBills = async ( - tenantId: number, - vendorCreditId: number, - applyCreditToBillsDTO: IVendorCreditApplyToInvoicesDTO - ): Promise => { - const { VendorCreditAppliedBill } = this.tenancy.models(tenantId); - - // Retrieves the vendor credit or throw not found service error. - const vendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - vendorCreditId - ); - // Transfomes credit apply to bills DTO to model object. - const vendorCreditAppliedModel = this.transformApplyDTOToModel( - applyCreditToBillsDTO, - vendorCredit - ); - // Validate bills entries existance. - const appliedBills = - await this.billPaymentValidators.validateBillsExistance( - tenantId, - vendorCreditAppliedModel.entries, - vendorCredit.vendorId - ); - // Validate bills has remaining amount to apply. - this.validateBillsRemainingAmount( - appliedBills, - vendorCreditAppliedModel.amount - ); - // Validate vendor credit remaining credit amount. - this.validateCreditRemainingAmount( - vendorCredit, - vendorCreditAppliedModel.amount - ); - // Saves vendor credit applied to bills under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Inserts vendor credit applied to bills graph to the storage layer. - const vendorCreditAppliedBills = - await VendorCreditAppliedBill.query().insertGraph( - vendorCreditAppliedModel.entries - ); - // Triggers `IVendorCreditApplyToBillsCreatedPayload` event. - await this.eventPublisher.emitAsync( - events.vendorCredit.onApplyToInvoicesCreated, - { - trx, - tenantId, - vendorCredit, - vendorCreditAppliedBills, - } as IVendorCreditApplyToBillsCreatedPayload - ); - }); - }; - - /** - * Transformes apply DTO to model. - * @param {IApplyCreditToInvoicesDTO} applyDTO - * @param {ICreditNote} creditNote - * @returns {IVendorCreditApplyToInvoicesModel} - */ - private transformApplyDTOToModel = ( - applyDTO: IVendorCreditApplyToInvoicesDTO, - vendorCredit: IVendorCredit - ): IVendorCreditApplyToInvoicesModel => { - const entries = applyDTO.entries.map((entry) => ({ - billId: entry.billId, - amount: entry.amount, - vendorCreditId: vendorCredit.id, - })); - const amount = sumBy(applyDTO.entries, 'amount'); - - return { - amount, - entries, - }; - }; - - /** - * Validate bills remaining amount. - * @param {IBill[]} bills - * @param {number} amount - */ - private validateBillsRemainingAmount = (bills: IBill[], amount: number) => { - const invalidBills = bills.filter((bill) => bill.dueAmount < amount); - if (invalidBills.length > 0) { - throw new ServiceError(ERRORS.BILLS_HAS_NO_REMAINING_AMOUNT); - } - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/DeleteApplyVendorCreditToBill.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/DeleteApplyVendorCreditToBill.ts deleted file mode 100644 index 2216845c5..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/DeleteApplyVendorCreditToBill.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { IVendorCreditApplyToBillDeletedPayload } from '@/interfaces'; -import Knex from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Service, Inject } from 'typedi'; -import BaseVendorCredit from '../BaseVendorCredit'; -import { ERRORS } from '../constants'; - -@Service() -export default class DeleteApplyVendorCreditToBill extends BaseVendorCredit { - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Delete apply vendor credit to bill transaction. - * @param {number} tenantId - * @param {number} appliedCreditToBillId - * @returns {Promise} - */ - public deleteApplyVendorCreditToBills = async ( - tenantId: number, - appliedCreditToBillId: number - ) => { - const { VendorCreditAppliedBill } = this.tenancy.models(tenantId); - - const oldCreditAppliedToBill = - await VendorCreditAppliedBill.query().findById(appliedCreditToBillId); - - if (!oldCreditAppliedToBill) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND); - } - // Retrieve the vendor credit or throw not found service error. - const vendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - oldCreditAppliedToBill.vendorCreditId - ); - // Deletes vendor credit apply under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Delete vendor credit applied to bill transaction. - await VendorCreditAppliedBill.query(trx) - .findById(appliedCreditToBillId) - .delete(); - - // Triggers `onVendorCreditApplyToInvoiceDeleted` event. - await this.eventPublisher.emitAsync( - events.vendorCredit.onApplyToInvoicesDeleted, - { - tenantId, - vendorCredit, - oldCreditAppliedToBill, - trx, - } as IVendorCreditApplyToBillDeletedPayload - ); - }); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetAppliedBillsToVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetAppliedBillsToVendorCredit.ts deleted file mode 100644 index 44b1bdc8a..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetAppliedBillsToVendorCredit.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { Service, Inject } from 'typedi'; -import BaseVendorCredit from '../BaseVendorCredit'; -import { VendorCreditAppliedBillTransformer } from './VendorCreditAppliedBillTransformer'; - -@Service() -export default class GetAppliedBillsToVendorCredit extends BaseVendorCredit { - @Inject() - private transformer: TransformerInjectable; - - /** - * - * @param {number} tenantId - * @param {number} vendorCreditId - * @returns - */ - public getAppliedBills = async (tenantId: number, vendorCreditId: number) => { - const { VendorCreditAppliedBill } = this.tenancy.models(tenantId); - - const vendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - vendorCreditId - ); - const appliedToBills = await VendorCreditAppliedBill.query() - .where('vendorCreditId', vendorCreditId) - .withGraphFetched('bill') - .withGraphFetched('vendorCredit'); - - // Transformes the models to POJO. - return this.transformer.transform( - tenantId, - appliedToBills, - new VendorCreditAppliedBillTransformer() - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetVendorCreditToApplyBills.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetVendorCreditToApplyBills.ts deleted file mode 100644 index 8dfb02a75..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/GetVendorCreditToApplyBills.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { Service, Inject } from 'typedi'; -import BaseVendorCredit from '../BaseVendorCredit'; -import { VendorCreditToApplyBillTransformer } from './VendorCreditToApplyBillTransformer'; - -@Service() -export default class GetVendorCreditToApplyBills extends BaseVendorCredit { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve bills that valid apply to the given vendor credit. - * @param {number} tenantId - * @param {number} vendorCreditId - * @returns - */ - public getCreditToApplyBills = async ( - tenantId: number, - vendorCreditId: number - ) => { - const { Bill } = this.tenancy.models(tenantId); - - // Retrieve vendor credit or throw not found service error. - const vendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - vendorCreditId - ); - // Retrieive open bills associated to the given vendor. - const openBills = await Bill.query() - .where('vendor_id', vendorCredit.vendorId) - .modify('dueBills') - .modify('published'); - - // Transformes the bills to POJO. - return this.transformer.transform( - tenantId, - openBills, - new VendorCreditToApplyBillTransformer() - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditAppliedBillTransformer.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditAppliedBillTransformer.ts deleted file mode 100644 index 72b42a8e8..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditAppliedBillTransformer.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class VendorCreditAppliedBillTransformer extends Transformer { - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'vendorCreditNumber', - 'vendorCreditDate', - 'billNumber', - 'billReferenceNo', - 'formattedVendorCreditDate', - 'formattedBillDate', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['bill', 'vendorCredit']; - }; - - protected formattedAmount = (item) => { - return formatNumber(item.amount, { - currencyCode: item.vendorCredit.currencyCode, - }); - }; - - protected vendorCreditNumber = (item) => { - return item.vendorCredit.vendorCreditNumber; - }; - - protected vendorCreditDate = (item) => { - return item.vendorCredit.vendorCreditDate; - }; - - protected formattedVendorCreditDate = (item) => { - return this.formatDate(item.vendorCredit.vendorCreditDate); - }; - - protected billNumber = (item) => { - return item.bill.billNo; - }; - - protected billReferenceNo = (item) => { - return item.bill.referenceNo; - }; - - protected BillDate = (item) => { - return item.bill.billDate; - }; - - protected formattedBillDate = (item) => { - return this.formatDate(item.bill.billDate); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditToApplyBillTransformer.ts b/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditToApplyBillTransformer.ts deleted file mode 100644 index b4f8ebe06..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ApplyVendorCreditToBills/VendorCreditToApplyBillTransformer.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { IBill } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class VendorCreditToApplyBillTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedBillDate', - 'formattedDueDate', - 'formattedAmount', - 'formattedDueAmount', - 'formattedPaymentAmount', - ]; - }; - - /** - * Retrieve formatted bill date. - * @param {IBill} bill - * @returns {String} - */ - protected formattedBillDate = (bill: IBill): string => { - return this.formatDate(bill.billDate); - }; - - /** - * Retrieve formatted due date. - * @param {IBill} bill - * @returns {string} - */ - protected formattedDueDate = (bill: IBill): string => { - return this.formatDate(bill.dueDate); - }; - - /** - * Retrieve formatted bill amount. - * @param {IBill} bill - * @returns {string} - */ - protected formattedAmount = (bill: IBill): string => { - return formatNumber(bill.amount, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieve formatted bill due amount. - * @param {IBill} bill - * @returns {string} - */ - protected formattedDueAmount = (bill: IBill): string => { - return formatNumber(bill.dueAmount, { - currencyCode: bill.currencyCode, - }); - }; - - /** - * Retrieve formatted payment amount. - * @param {IBill} bill - * @returns {string} - */ - protected formattedPaymentAmount = (bill: IBill): string => { - return formatNumber(bill.paymentAmount, { - currencyCode: bill.currencyCode, - }); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/BaseVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/BaseVendorCredit.ts deleted file mode 100644 index c6e9a1d54..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/BaseVendorCredit.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { Inject, Service } from 'typedi'; -import moment from 'moment'; -import { omit } from 'lodash'; -import * as R from 'ramda'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { ServiceError } from '@/exceptions'; -import { - IVendorCredit, - IVendorCreditCreateDTO, - IVendorCreditEditDTO, - IVendorCreditEntryDTO, -} from '@/interfaces'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; - -@Service() -export default class BaseVendorCredit { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - /** - * Transformes the credit/edit vendor credit DTO to model. - * @param {number} tenantId - - * @param {IVendorCreditCreateDTO | IVendorCreditEditDTO} vendorCreditDTO - * @param {string} vendorCurrencyCode - - * @param {IVendorCredit} oldVendorCredit - - * @returns {IVendorCredit} - */ - public transformCreateEditDTOToModel = ( - tenantId: number, - vendorCreditDTO: IVendorCreditCreateDTO | IVendorCreditEditDTO, - vendorCurrencyCode: string, - oldVendorCredit?: IVendorCredit - ): IVendorCredit => { - // Calculates the total amount of items entries. - const amount = this.itemsEntriesService.getTotalItemsEntries( - vendorCreditDTO.entries - ); - - const entries = R.compose( - // Associate the default index to each item entry. - assocItemEntriesDefaultIndex, - - // Associate the reference type to item entries. - R.map((entry: IVendorCreditEntryDTO) => ({ - referenceType: 'VendorCredit', - ...entry, - })) - )(vendorCreditDTO.entries); - - // Retreive the next vendor credit number. - const autoNextNumber = this.getNextCreditNumber(tenantId); - - // Detarmines the credit note number. - const vendorCreditNumber = - vendorCreditDTO.vendorCreditNumber || - oldVendorCredit?.vendorCreditNumber || - autoNextNumber; - - const initialDTO = { - ...omit(vendorCreditDTO, ['open', 'attachments']), - amount, - currencyCode: vendorCurrencyCode, - exchangeRate: vendorCreditDTO.exchangeRate || 1, - vendorCreditNumber, - entries, - ...(vendorCreditDTO.open && - !oldVendorCredit?.openedAt && { - openedAt: moment().toMySqlDateTime(), - }), - }; - return R.compose( - this.branchDTOTransform.transformDTO(tenantId), - this.warehouseDTOTransform.transformDTO(tenantId) - )(initialDTO); - }; - - /** - * Retrieve the vendor credit or throw not found service error. - * @param {number} tenantId - * @param {number} vendorCreditId - */ - public getVendorCreditOrThrowError = async ( - tenantId: number, - vendorCreditId: number - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - const vendorCredit = await VendorCredit.query().findById(vendorCreditId); - - if (!vendorCredit) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_NOT_FOUND); - } - return vendorCredit; - }; - - /** - * Retrieve the next unique credit number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - private getNextCreditNumber = (tenantId: number): string => { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'vendor_credit' - ); - }; - - /** - * Increment the vendor credit serial next number. - * @param {number} tenantId - - */ - public incrementSerialNumber = (tenantId: number) => { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'vendor_credit' - ); - }; - - /** - * Validate the credit note remaining amount. - * @param {ICreditNote} creditNote - * @param {number} amount - */ - public validateCreditRemainingAmount = ( - vendorCredit: IVendorCredit, - amount: number - ) => { - if (vendorCredit.creditsRemaining < amount) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT); - } - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/CreateVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/CreateVendorCredit.ts deleted file mode 100644 index f66c6d834..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/CreateVendorCredit.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - IVendorCreditCreatedPayload, - IVendorCreditCreateDTO, - IVendorCreditCreatingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import BaseVendorCredit from './BaseVendorCredit'; - -@Service() -export default class CreateVendorCredit extends BaseVendorCredit { - @Inject() - private uow: UnitOfWork; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates a new vendor credit. - * @param {number} tenantId - - * @param {IVendorCreditCreateDTO} vendorCreditCreateDTO - - * @param {Knex.Transaction} trx - - */ - public newVendorCredit = async ( - tenantId: number, - vendorCreditCreateDTO: IVendorCreditCreateDTO, - trx?: Knex.Transaction - ) => { - const { VendorCredit, Vendor } = this.tenancy.models(tenantId); - - // Triggers `onVendorCreditCreate` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onCreate, { - tenantId, - vendorCreditCreateDTO, - }); - // Retrieve the given vendor or throw not found service error. - const vendor = await Vendor.query() - .findById(vendorCreditCreateDTO.vendorId) - .throwIfNotFound(); - - // Validate items should be sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - vendorCreditCreateDTO.entries - ); - // Transformes the credit DTO to storage layer. - const vendorCreditModel = this.transformCreateEditDTOToModel( - tenantId, - vendorCreditCreateDTO, - vendor.currencyCode - ); - // Saves the vendor credit transactions under UOW envirement. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onVendorCreditCreating` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onCreating, { - tenantId, - vendorCreditCreateDTO, - trx, - } as IVendorCreditCreatingPayload); - - // Saves the vendor credit graph. - const vendorCredit = await VendorCredit.query(trx).upsertGraphAndFetch({ - ...vendorCreditModel, - }); - // Triggers `onVendorCreditCreated` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onCreated, { - tenantId, - vendorCredit, - vendorCreditCreateDTO, - trx, - } as IVendorCreditCreatedPayload); - - return vendorCredit; - }, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/DeleteVendorAssociatedVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/DeleteVendorAssociatedVendorCredit.ts deleted file mode 100644 index ac974cee9..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/DeleteVendorAssociatedVendorCredit.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { IVendorEventDeletingPayload } from '@/interfaces'; - -const ERRORS = { - VENDOR_HAS_TRANSACTIONS: 'VENDOR_HAS_TRANSACTIONS', -}; - -@Service() -export default class DeleteVendorAssociatedVendorCredit { - @Inject() - tenancy: TenancyService; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach = (bus) => { - bus.subscribe( - events.vendors.onDeleting, - this.validateVendorHasNoCreditsTransactionsOnceDeleting - ); - }; - - /** - * Validate vendor has no associated credit transaction once the vendor deleting. - * @param {IVendorEventDeletingPayload} payload - - */ - public validateVendorHasNoCreditsTransactionsOnceDeleting = async ({ - tenantId, - vendorId, - }: IVendorEventDeletingPayload) => { - await this.validateVendorHasNoCreditsTransactions(tenantId, vendorId); - }; - - /** - * Validate the given vendor has no associated vendor credit transactions. - * @param {number} tenantId - * @param {number} vendorId - */ - public validateVendorHasNoCreditsTransactions = async ( - tenantId: number, - vendorId: number - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - const associatedVendors = await VendorCredit.query().where( - 'vendorId', - vendorId - ); - if (associatedVendors.length > 0) { - throw new ServiceError(ERRORS.VENDOR_HAS_TRANSACTIONS); - } - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/DeleteVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/DeleteVendorCredit.ts deleted file mode 100644 index 479527687..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/DeleteVendorCredit.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import BaseVendorCredit from './BaseVendorCredit'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IVendorCreditDeletedPayload, - IVendorCreditDeletingPayload, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class DeleteVendorCredit extends BaseVendorCredit { - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - tenancy: HasTenancyService; - - /** - * Deletes the given vendor credit. - * @param {number} tenantId - Tenant id. - * @param {number} vendorCreditId - Vendor credit id. - */ - public deleteVendorCredit = async ( - tenantId: number, - vendorCreditId: number - ) => { - const { VendorCredit, ItemEntry } = this.tenancy.models(tenantId); - - // Retrieve the old vendor credit. - const oldVendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - vendorCreditId - ); - // Validates vendor credit has no associate refund transactions. - await this.validateVendorCreditHasNoRefundTransactions( - tenantId, - vendorCreditId - ); - // Validates vendor credit has no associated applied to bills transactions. - await this.validateVendorCreditHasNoApplyBillsTransactions( - tenantId, - vendorCreditId - ); - // Deletes the vendor credit transactions under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onVendorCreditEditing` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onDeleting, { - tenantId, - oldVendorCredit, - trx, - } as IVendorCreditDeletingPayload); - - // Deletes the associated credit note entries. - await ItemEntry.query(trx) - .where('reference_id', vendorCreditId) - .where('reference_type', 'VendorCredit') - .delete(); - - // Deletes the credit note transaction. - await VendorCredit.query(trx).findById(vendorCreditId).delete(); - - // Triggers `onVendorCreditDeleted` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onDeleted, { - tenantId, - vendorCreditId, - oldVendorCredit, - trx, - } as IVendorCreditDeletedPayload); - }); - }; - - /** - * Validates vendor credit has no refund transactions. - * @param {number} tenantId - * @param {number} vendorCreditId - */ - private validateVendorCreditHasNoRefundTransactions = async ( - tenantId: number, - vendorCreditId: number - ): Promise => { - const { RefundVendorCredit } = this.tenancy.models(tenantId); - - const refundCredits = await RefundVendorCredit.query().where( - 'vendorCreditId', - vendorCreditId - ); - if (refundCredits.length > 0) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS); - } - }; - - /** - * Validate vendor credit has no applied transactions to bills. - * @param {number} tenantId - * @param {number} vendorCreditId - */ - private validateVendorCreditHasNoApplyBillsTransactions = async ( - tenantId: number, - vendorCreditId: number - ): Promise => { - const { VendorCreditAppliedBill } = this.tenancy.models(tenantId); - - const appliedTransactions = await VendorCreditAppliedBill.query().where( - 'vendorCreditId', - vendorCreditId - ); - if (appliedTransactions.length > 0) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_HAS_APPLIED_BILLS); - } - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/EditVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/EditVendorCredit.ts deleted file mode 100644 index 1ec313852..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/EditVendorCredit.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IVendorCreditEditDTO, - IVendorCreditEditedPayload, - IVendorCreditEditingPayload, -} from '@/interfaces'; -import BaseVendorCredit from './BaseVendorCredit'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class EditVendorCredit extends BaseVendorCredit { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Deletes the given vendor credit. - * @param {number} tenantId - Tenant id. - * @param {number} vendorCreditId - Vendor credit id. - */ - public editVendorCredit = async ( - tenantId: number, - vendorCreditId: number, - vendorCreditDTO: IVendorCreditEditDTO - ) => { - const { VendorCredit, Contact } = this.tenancy.models(tenantId); - - // Retrieve the vendor credit or throw not found service error. - const oldVendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - vendorCreditId - ); - // Validate customer existance. - const vendor = await Contact.query() - .modify('vendor') - .findById(vendorCreditDTO.vendorId) - .throwIfNotFound(); - - // Validate items ids existance. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - vendorCreditDTO.entries - ); - // Validate non-sellable entries items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - vendorCreditDTO.entries - ); - // Validate the items entries existance. - await this.itemsEntriesService.validateEntriesIdsExistance( - tenantId, - vendorCreditId, - 'VendorCredit', - vendorCreditDTO.entries - ); - // Transformes edit DTO to model storage layer. - const vendorCreditModel = this.transformCreateEditDTOToModel( - tenantId, - vendorCreditDTO, - vendor.currencyCode, - oldVendorCredit - ); - // Edits the vendor credit graph under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx) => { - // Triggers `onVendorCreditEditing` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onEditing, { - tenantId, - oldVendorCredit, - vendorCreditDTO, - trx, - } as IVendorCreditEditingPayload); - - // Saves the vendor credit graph to the storage. - const vendorCredit = await VendorCredit.query(trx).upsertGraphAndFetch({ - id: vendorCreditId, - ...vendorCreditModel, - }); - // Triggers `onVendorCreditEdited event. - await this.eventPublisher.emitAsync(events.vendorCredit.onEdited, { - tenantId, - oldVendorCredit, - vendorCredit, - vendorCreditId, - vendorCreditDTO, - trx, - } as IVendorCreditEditedPayload); - - return vendorCredit; - }); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/GetVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/GetVendorCredit.ts deleted file mode 100644 index 5a1f373f0..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/GetVendorCredit.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { VendorCreditTransformer } from './VendorCreditTransformer'; -import { Inject, Service } from 'typedi'; -import { ERRORS } from './constants'; - -@Service() -export default class GetVendorCredit { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the given vendor credit. - * @param {number} tenantId - Tenant id. - * @param {number} vendorCreditId - Vendor credit id. - */ - public getVendorCredit = async (tenantId: number, vendorCreditId: number) => { - const { VendorCredit } = this.tenancy.models(tenantId); - - // Retrieve the vendor credit model graph. - const vendorCredit = await VendorCredit.query() - .findById(vendorCreditId) - .withGraphFetched('entries.item') - .withGraphFetched('vendor') - .withGraphFetched('branch') - .withGraphFetched('attachments'); - - if (!vendorCredit) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_NOT_FOUND); - } - return this.transformer.transform( - tenantId, - vendorCredit, - new VendorCreditTransformer() - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/ListVendorCredits.ts b/packages/server/src/services/Purchases/VendorCredits/ListVendorCredits.ts deleted file mode 100644 index ff0e0ee30..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/ListVendorCredits.ts +++ /dev/null @@ -1,70 +0,0 @@ -import * as R from 'ramda'; -import { Service, Inject } from 'typedi'; -import BaseVendorCredit from './BaseVendorCredit'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { IVendorCreditsQueryDTO } from '@/interfaces'; -import { VendorCreditTransformer } from './VendorCreditTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class ListVendorCredits extends BaseVendorCredit { - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Parses the sale invoice list filter DTO. - * @param {IVendorCreditsQueryDTO} filterDTO - * @returns - */ - private parseListFilterDTO = (filterDTO: IVendorCreditsQueryDTO) => { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - }; - - /** - * Retrieve the vendor credits list. - * @param {number} tenantId - Tenant id. - * @param {IVendorCreditsQueryDTO} vendorCreditQuery - - */ - public getVendorCredits = async ( - tenantId: number, - vendorCreditQuery: IVendorCreditsQueryDTO - ) => { - const { VendorCredit } = this.tenancy.models(tenantId); - - // Parses stringified filter roles. - const filter = this.parseListFilterDTO(vendorCreditQuery); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - VendorCredit, - filter - ); - const { results, pagination } = await VendorCredit.query() - .onBuild((builder) => { - builder.withGraphFetched('entries'); - builder.withGraphFetched('vendor'); - dynamicFilter.buildQuery()(builder); - - // Gives ability to inject custom query to filter results. - vendorCreditQuery?.filterQuery && - vendorCreditQuery?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transformes the vendor credits models to POJO. - const vendorCredits = await this.transformer.transform( - tenantId, - results, - new VendorCreditTransformer() - ); - return { - vendorCredits, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/OpenVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/OpenVendorCredit.ts deleted file mode 100644 index f60350ccc..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/OpenVendorCredit.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { - IVendorCredit, - IVendorCreditOpenedPayload, - IVendorCreditOpeningPayload, - IVendorCreditOpenPayload, -} from '@/interfaces'; -import Knex from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; -import BaseVendorCredit from './BaseVendorCredit'; -import { ERRORS } from './constants'; - -@Service() -export default class OpenVendorCredit extends BaseVendorCredit { - @Inject() - eventPublisher: EventPublisher; - - @Inject() - uow: UnitOfWork; - - /** - * Opens the given credit note. - * @param {number} tenantId - - * @param {ICreditNoteEditDTO} creditNoteEditDTO - - * @returns {Promise} - */ - public openVendorCredit = async ( - tenantId: number, - vendorCreditId: number - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - // Retrieve the vendor credit or throw not found service error. - const oldVendorCredit = await this.getVendorCreditOrThrowError( - tenantId, - vendorCreditId - ); - // Throw service error if the credit note is already open. - this.throwErrorIfAlreadyOpen(oldVendorCredit); - - // Triggers `onVendorCreditOpen` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onOpen, { - tenantId, - vendorCreditId, - oldVendorCredit, - } as IVendorCreditOpenPayload); - - // Sales the credit note transactions with associated entries. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - tenantId, - vendorCreditId, - oldVendorCredit, - trx, - } as IVendorCreditOpeningPayload; - - // Triggers `onCreditNoteOpening` event. - await this.eventPublisher.emitAsync( - events.creditNote.onOpening, - eventPayload as IVendorCreditOpeningPayload - ); - // Saves the vendor credit graph to the storage. - const vendorCredit = await VendorCredit.query(trx) - .findById(vendorCreditId) - .update({ - openedAt: new Date(), - }); - // Triggers `onVendorCreditOpened` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onOpened, { - ...eventPayload, - vendorCredit, - } as IVendorCreditOpenedPayload); - - return vendorCredit; - }); - }; - - /** - * Throw error if the vendor credit is already open. - * @param {IVendorCredit} vendorCredit - */ - public throwErrorIfAlreadyOpen = (vendorCredit: IVendorCredit) => { - if (vendorCredit.openedAt) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_ALREADY_OPENED); - } - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/CreateRefundVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/CreateRefundVendorCredit.ts deleted file mode 100644 index 3a6ef0451..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/CreateRefundVendorCredit.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import * as R from 'ramda'; -import { - IRefundVendorCredit, - IRefundVendorCreditCreatedPayload, - IRefundVendorCreditCreatingPayload, - IRefundVendorCreditDTO, - IVendorCredit, - IVendorCreditCreatePayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import RefundVendorCredit from './RefundVendorCredit'; -import events from '@/subscribers/events'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; - -@Service() -export default class CreateRefundVendorCredit extends RefundVendorCredit { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - /** - * Creates a refund vendor credit. - * @param {number} tenantId - * @param {number} vendorCreditId - * @param {IRefundVendorCreditDTO} refundVendorCreditDTO - * @returns {Promise} - */ - public createRefund = async ( - tenantId: number, - vendorCreditId: number, - refundVendorCreditDTO: IRefundVendorCreditDTO - ): Promise => { - const { RefundVendorCredit, Account, VendorCredit } = - this.tenancy.models(tenantId); - - // Retrieve the vendor credit or throw not found service error. - const vendorCredit = await VendorCredit.query() - .findById(vendorCreditId) - .throwIfNotFound(); - - // Retrieve the deposit account or throw not found service error. - const depositAccount = await Account.query() - .findById(refundVendorCreditDTO.depositAccountId) - .throwIfNotFound(); - - // Validate vendor credit has remaining credit. - this.validateVendorCreditRemainingCredit( - vendorCredit, - refundVendorCreditDTO.amount - ); - // Validate refund deposit account type. - this.validateRefundDepositAccountType(depositAccount); - - // Triggers `onVendorCreditRefundCreate` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onRefundCreate, { - tenantId, - vendorCreditId, - refundVendorCreditDTO, - } as IVendorCreditCreatePayload); - - const refundCreditObj = this.transformDTOToModel( - tenantId, - vendorCredit, - refundVendorCreditDTO - ); - // Saves refund vendor credit with associated transactions. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - vendorCredit, - trx, - tenantId, - refundVendorCreditDTO, - } as IRefundVendorCreditCreatingPayload; - - // Triggers `onVendorCreditRefundCreating` event. - await this.eventPublisher.emitAsync( - events.vendorCredit.onRefundCreating, - eventPayload as IRefundVendorCreditCreatingPayload - ); - // Inserts refund vendor credit to the storage layer. - const refundVendorCredit = - await RefundVendorCredit.query().insertAndFetch({ - ...refundCreditObj, - }); - // Triggers `onVendorCreditCreated` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onRefundCreated, { - ...eventPayload, - refundVendorCredit, - } as IRefundVendorCreditCreatedPayload); - - return refundVendorCredit; - }); - }; - - /** - * Transformes the refund DTO to refund vendor credit model. - * @param {IVendorCredit} vendorCredit - - * @param {IRefundVendorCreditDTO} vendorCreditDTO - * @returns {IRefundVendorCredit} - */ - public transformDTOToModel = ( - tenantId: number, - vendorCredit: IVendorCredit, - vendorCreditDTO: IRefundVendorCreditDTO - ) => { - const initialDTO = { - vendorCreditId: vendorCredit.id, - ...vendorCreditDTO, - currencyCode: vendorCredit.currencyCode, - exchangeRate: vendorCreditDTO.exchangeRate || 1, - }; - return R.compose(this.branchDTOTransform.transformDTO(tenantId))( - initialDTO - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/DeleteRefundVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/DeleteRefundVendorCredit.ts deleted file mode 100644 index 76ea7ff1c..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/DeleteRefundVendorCredit.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Knex } from 'knex'; -import { - IRefundVendorCreditDeletedPayload, - IRefundVendorCreditDeletePayload, - IRefundVendorCreditDeletingPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { Inject, Service } from 'typedi'; -import RefundVendorCredit from './RefundVendorCredit'; - -@Service() -export default class DeleteRefundVendorCredit extends RefundVendorCredit { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - Tenant id. - * @param {number} creditNoteId - Credit note id. - * @returns {Promise} - */ - public deleteRefundVendorCreditRefund = async ( - tenantId: number, - refundCreditId: number - ): Promise => { - const { RefundVendorCredit } = this.tenancy.models(tenantId); - - // Retrieve the old credit note or throw not found service error. - const oldRefundCredit = await this.getRefundVendorCreditOrThrowError( - tenantId, - refundCreditId - ); - // Triggers `onVendorCreditRefundDelete` event. - await this.eventPublisher.emitAsync(events.vendorCredit.onRefundDelete, { - refundCreditId, - oldRefundCredit, - tenantId, - } as IRefundVendorCreditDeletePayload); - - // Deletes the refund vendor credit under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - trx, - refundCreditId, - oldRefundCredit, - tenantId, - } as IRefundVendorCreditDeletingPayload; - - // Triggers `onVendorCreditRefundDeleting` event. - await this.eventPublisher.emitAsync( - events.vendorCredit.onRefundDeleting, - eventPayload - ); - // Deletes the refund vendor credit graph from the storage. - await RefundVendorCredit.query(trx).findById(refundCreditId).delete(); - - // Triggers `onVendorCreditRefundDeleted` event. - await this.eventPublisher.emitAsync( - events.vendorCredit.onRefundDeleted, - eventPayload as IRefundVendorCreditDeletedPayload - ); - }); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/GetRefundVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/GetRefundVendorCredit.ts deleted file mode 100644 index 2e891781c..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/GetRefundVendorCredit.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { RefundVendorCreditTransformer } from './RefundVendorCreditTransformer'; -import RefundVendorCredit from './RefundVendorCredit'; -import { IRefundVendorCredit } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class GetRefundVendorCredit extends RefundVendorCredit { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve refund vendor credit transaction. - * @param {number} tenantId - * @param {number} refundId - * @returns {Promise} - */ - public getRefundCreditTransaction = async ( - tenantId: number, - refundId: number - ): Promise => { - const { RefundVendorCredit } = this.tenancy.models(tenantId); - - await this.getRefundVendorCreditOrThrowError(tenantId, refundId); - - // Retrieve refund transactions associated to the given vendor credit. - const refundVendorTransactions = await RefundVendorCredit.query() - .findById(refundId) - .withGraphFetched('vendorCredit') - .withGraphFetched('depositAccount'); - - // Transformes refund vendor credit models to POJO objects. - return this.transformer.transform( - tenantId, - refundVendorTransactions, - new RefundVendorCreditTransformer() - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/ListRefundVendorCredits.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/ListRefundVendorCredits.ts deleted file mode 100644 index ebca28fca..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/ListRefundVendorCredits.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { IRefundVendorCreditPOJO } from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import RefundVendorCredit from './RefundVendorCredit'; -import { RefundVendorCreditTransformer } from './RefundVendorCreditTransformer'; - -@Service() -export default class ListVendorCreditRefunds extends RefundVendorCredit { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the credit note graph. - * @param {number} tenantId - * @param {number} creditNoteId - * @returns {Promise} - */ - public getVendorCreditRefunds = async ( - tenantId: number, - vendorCreditId: number - ): Promise => { - const { RefundVendorCredit } = this.tenancy.models(tenantId); - - // Retrieve refund transactions associated to the given vendor credit. - const refundVendorTransactions = await RefundVendorCredit.query() - .where('vendorCreditId', vendorCreditId) - .withGraphFetched('vendorCredit') - .withGraphFetched('depositAccount'); - - // Transformes refund vendor credit models to POJO objects. - return this.transformer.transform( - tenantId, - refundVendorTransactions, - new RefundVendorCreditTransformer() - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundCreditSyncBills.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundCreditSyncBills.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncCreditRefundedAmount.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncCreditRefundedAmount.ts deleted file mode 100644 index 2ff7abcfb..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncCreditRefundedAmount.ts +++ /dev/null @@ -1,47 +0,0 @@ -import Knex from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; - -@Service() -export default class RefundSyncCreditRefundedAmount { - @Inject() - tenancy: HasTenancyService; - - /** - * Increment vendor credit refunded amount. - * @param {number} tenantId - Tenant id. - * @param {number} amount - Amount. - * @param {Knex.Transaction} trx - Knex transaction. - */ - public incrementCreditRefundedAmount = async ( - tenantId: number, - vendorCreditId: number, - amount: number, - trx?: Knex.Transaction - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - await VendorCredit.query(trx) - .findById(vendorCreditId) - .increment('refundedAmount', amount); - }; - - /** - * Decrement vendor credit refunded amount. - * @param {number} tenantId - * @param {number} amount - * @param {Knex.Transaction} trx - */ - public decrementCreditNoteRefundAmount = async ( - tenantId: number, - vendorCreditId: number, - amount: number, - trx?: Knex.Transaction - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - await VendorCredit.query(trx) - .findById(vendorCreditId) - .decrement('refundedAmount', amount); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalance.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalance.ts deleted file mode 100644 index 0d09fd59b..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalance.ts +++ /dev/null @@ -1,48 +0,0 @@ -import Knex from 'knex'; -import { IRefundVendorCredit } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; - -@Service() -export default class RefundSyncVendorCreditBalance { - @Inject() - tenancy: HasTenancyService; - - /** - * Increment vendor credit refunded amount. - * @param {number} tenantId - - * @param {IRefundVendorCredit} refundCreditNote - - * @param {Knex.Transaction} trx - - */ - public incrementVendorCreditRefundAmount = async ( - tenantId: number, - refundVendorCredit: IRefundVendorCredit, - trx?: Knex.Transaction - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - await VendorCredit.query(trx).increment( - 'refundedAmount', - refundVendorCredit.amount - ); - }; - - /** - * Decrement vendor credit refunded amount. - * @param {number} tenantId - * @param {IRefundVendorCredit} refundCreditNote - * @param {Knex.Transaction} trx - */ - public decrementVendorCreditRefundAmount = async ( - tenantId: number, - refundVendorCredit: IRefundVendorCredit, - trx?: Knex.Transaction - ): Promise => { - const { VendorCredit } = this.tenancy.models(tenantId); - - await VendorCredit.query(trx).decrement( - 'refundedAmount', - refundVendorCredit.amount - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalanceSubscriber.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalanceSubscriber.ts deleted file mode 100644 index dbce1c3dc..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundSyncVendorCreditBalanceSubscriber.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IRefundVendorCreditCreatedPayload, - IRefundVendorCreditDeletedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import RefundSyncCreditRefundedAmount from './RefundSyncCreditRefundedAmount'; - -@Service() -export default class RefundSyncVendorCreditBalanceSubscriber { - @Inject() - refundSyncCreditRefunded: RefundSyncCreditRefundedAmount; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.vendorCredit.onRefundCreated, - this.incrementRefundedAmountOnceRefundCreated - ); - bus.subscribe( - events.vendorCredit.onRefundDeleted, - this.decrementRefundedAmountOnceRefundDeleted - ); - }; - - /** - * Increment refunded vendor credit amount once refund transaction created. - * @param {IRefundVendorCreditCreatedPayload} payload - - */ - private incrementRefundedAmountOnceRefundCreated = async ({ - refundVendorCredit, - vendorCredit, - tenantId, - trx, - }: IRefundVendorCreditCreatedPayload) => { - await this.refundSyncCreditRefunded.incrementCreditRefundedAmount( - tenantId, - refundVendorCredit.vendorCreditId, - refundVendorCredit.amount, - trx - ); - }; - - /** - * Decrement refunded vendor credit amount once refund transaction deleted. - * @param {IRefundVendorCreditDeletedPayload} payload - - */ - private decrementRefundedAmountOnceRefundDeleted = async ({ - trx, - oldRefundCredit, - tenantId, - }: IRefundVendorCreditDeletedPayload) => { - await this.refundSyncCreditRefunded.decrementCreditNoteRefundAmount( - tenantId, - oldRefundCredit.vendorCreditId, - oldRefundCredit.amount, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCredit.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCredit.ts deleted file mode 100644 index d5e372f9c..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCredit.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { IAccount, IVendorCredit } from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import BaseVendorCredit from '../BaseVendorCredit'; -import { ERRORS } from './constants'; - -@Service() -export default class RefundVendorCredit extends BaseVendorCredit { - /** - * Retrieve the vendor credit refund or throw not found service error. - * @param {number} tenantId - * @param {number} vendorCreditId - * @returns - */ - public getRefundVendorCreditOrThrowError = async ( - tenantId: number, - refundVendorCreditId: number - ) => { - const { RefundVendorCredit } = this.tenancy.models(tenantId); - - const refundCredit = await RefundVendorCredit.query().findById( - refundVendorCreditId - ); - if (!refundCredit) { - throw new ServiceError(ERRORS.REFUND_VENDOR_CREDIT_NOT_FOUND); - } - return refundCredit; - }; - - /** - * Validate the deposit refund account type. - * @param {IAccount} account - */ - public validateRefundDepositAccountType = (account: IAccount): void => { - const supportedTypes = ['bank', 'cash', 'fixed-asset']; - - if (supportedTypes.indexOf(account.accountType) === -1) { - throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_INVALID_TYPE); - } - }; - - /** - * Validate vendor credit has remaining credits. - * @param {IVendorCredit} vendorCredit - * @param {number} amount - */ - public validateVendorCreditRemainingCredit = ( - vendorCredit: IVendorCredit, - amount: number - ) => { - if (vendorCredit.creditsRemaining < amount) { - throw new ServiceError(ERRORS.VENDOR_CREDIT_HAS_NO_CREDITS_REMAINING); - } - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntries.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntries.ts deleted file mode 100644 index 05dd7f319..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntries.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { AccountNormal, ILedgerEntry } from '@/interfaces'; -import { IRefundVendorCredit } from '@/interfaces'; -import JournalPosterService from '@/services/Sales/JournalPosterService'; -import LedgerRepository from '@/services/Ledger/LedgerRepository'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class RefundVendorCreditGLEntries { - @Inject() - private journalService: JournalPosterService; - - @Inject() - private ledgerRepository: LedgerRepository; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the refund credit common GL entry. - * @param {IRefundVendorCredit} refundCredit - */ - private getRefundCreditGLCommonEntry = ( - refundCredit: IRefundVendorCredit - ) => { - return { - exchangeRate: refundCredit.exchangeRate, - currencyCode: refundCredit.currencyCode, - - transactionType: 'RefundVendorCredit', - transactionId: refundCredit.id, - - date: refundCredit.date, - userId: refundCredit.userId, - referenceNumber: refundCredit.referenceNo, - createdAt: refundCredit.createdAt, - indexGroup: 10, - - credit: 0, - debit: 0, - - note: refundCredit.description, - branchId: refundCredit.branchId, - }; - }; - - /** - * Retrieves the refund credit payable GL entry. - * @param {IRefundVendorCredit} refundCredit - * @param {number} APAccountId - * @returns {ILedgerEntry} - */ - private getRefundCreditGLPayableEntry = ( - refundCredit: IRefundVendorCredit, - APAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getRefundCreditGLCommonEntry(refundCredit); - - return { - ...commonEntry, - credit: refundCredit.amount, - accountId: APAccountId, - contactId: refundCredit.vendorCredit.vendorId, - index: 1, - accountNormal: AccountNormal.CREDIT, - }; - }; - - /** - * Retrieves the refund credit deposit GL entry. - * @param {IRefundVendorCredit} refundCredit - * @returns {ILedgerEntry} - */ - private getRefundCreditGLDepositEntry = ( - refundCredit: IRefundVendorCredit - ): ILedgerEntry => { - const commonEntry = this.getRefundCreditGLCommonEntry(refundCredit); - - return { - ...commonEntry, - debit: refundCredit.amount, - accountId: refundCredit.depositAccountId, - index: 2, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieve refund vendor credit GL entries. - * @param {IRefundVendorCredit} refundCredit - * @param {number} APAccountId - * @returns {ILedgerEntry[]} - */ - public getRefundCreditGLEntries = ( - refundCredit: IRefundVendorCredit, - APAccountId: number - ): ILedgerEntry[] => { - const payableEntry = this.getRefundCreditGLPayableEntry( - refundCredit, - APAccountId - ); - const depositEntry = this.getRefundCreditGLDepositEntry(refundCredit); - - return [payableEntry, depositEntry]; - }; - - /** - * Saves refund credit note GL entries. - * @param {number} tenantId - * @param {IRefundVendorCredit} refundCredit - - * @param {Knex.Transaction} trx - - * @return {Promise} - */ - public saveRefundCreditGLEntries = async ( - tenantId: number, - refundCreditId: number, - trx?: Knex.Transaction - ): Promise => { - const { Account, RefundVendorCredit } = this.tenancy.models(tenantId); - - // Retireve refund with associated vendor credit entity. - const refundCredit = await RefundVendorCredit.query() - .findById(refundCreditId) - .withGraphFetched('vendorCredit'); - - const payableAccount = await Account.query().findOne( - 'slug', - 'accounts-payable' - ); - // Generates the GL entries of the given refund credit. - const entries = this.getRefundCreditGLEntries( - refundCredit, - payableAccount.id - ); - // Saves the ledegr to the storage. - await this.ledgerRepository.saveLedgerEntries(tenantId, entries, trx); - }; - - /** - * Reverts refund credit note GL entries. - * @param {number} tenantId - * @param {number} refundCreditId - * @param {Knex.Transaction} trx - * @return {Promise} - */ - public revertRefundCreditGLEntries = async ( - tenantId: number, - refundCreditId: number, - trx?: Knex.Transaction - ) => { - await this.journalService.revertJournalTransactions( - tenantId, - refundCreditId, - 'RefundVendorCredit', - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntriesSubscriber.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntriesSubscriber.ts deleted file mode 100644 index 1b973035c..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditGLEntriesSubscriber.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import RefundVendorCreditGLEntries from './RefundVendorCreditGLEntries'; -import { - IRefundCreditNoteDeletedPayload, - IRefundVendorCreditCreatedPayload, -} from '@/interfaces'; - -@Service() -export default class RefundVendorCreditGLEntriesSubscriber { - @Inject() - refundVendorGLEntries: RefundVendorCreditGLEntries; - - /** - * Attaches events with handlers. - */ - attach(bus) { - bus.subscribe( - events.vendorCredit.onRefundCreated, - this.writeRefundVendorCreditGLEntriesOnceCreated - ); - bus.subscribe( - events.vendorCredit.onRefundDeleted, - this.revertRefundVendorCreditOnceDeleted - ); - } - - /** - * Writes refund vendor credit GL entries once the transaction created. - * @param {IRefundCreditNoteCreatedPayload} payload - - */ - private writeRefundVendorCreditGLEntriesOnceCreated = async ({ - tenantId, - trx, - refundVendorCredit, - }: IRefundVendorCreditCreatedPayload) => { - await this.refundVendorGLEntries.saveRefundCreditGLEntries( - tenantId, - refundVendorCredit.id, - trx - ); - }; - - /** - * Reverts refund vendor credit GL entries once the transaction deleted. - * @param {IRefundCreditNoteDeletedPayload} payload - - */ - private revertRefundVendorCreditOnceDeleted = async ({ - tenantId, - trx, - refundCreditId, - }: IRefundCreditNoteDeletedPayload) => { - await this.refundVendorGLEntries.revertRefundCreditGLEntries( - tenantId, - refundCreditId, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditTransformer.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditTransformer.ts deleted file mode 100644 index 3ee54b737..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/RefundVendorCreditTransformer.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class RefundVendorCreditTransformer extends Transformer { - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return ['formttedAmount', 'formattedDate']; - }; - - /** - * Formatted amount. - * @returns {string} - */ - protected formttedAmount = (item) => { - return formatNumber(item.amount, { - currencyCode: item.currencyCode, - }); - }; - - /** - * Formatted date. - * @returns {string} - */ - protected formattedDate = (item) => { - return this.formatDate(item.date); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/constants.ts b/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/constants.ts deleted file mode 100644 index 21f355ed3..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/RefundVendorCredits/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const ERRORS = { - REFUND_VENDOR_CREDIT_NOT_FOUND: 'REFUND_VENDOR_CREDIT_NOT_FOUND', - DEPOSIT_ACCOUNT_INVALID_TYPE: 'DEPOSIT_ACCOUNT_INVALID_TYPE', - VENDOR_CREDIT_HAS_NO_CREDITS_REMAINING: 'VENDOR_CREDIT_HAS_NO_CREDITS_REMAINING' -} \ No newline at end of file diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditAutoSerialSubscriber.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditAutoSerialSubscriber.ts deleted file mode 100644 index ba4c34578..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditAutoSerialSubscriber.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import BaseVendorCredit from './BaseVendorCredit'; -import { IVendorCreditCreatedPayload } from '@/interfaces'; - -@Service() -export default class VendorCreditAutoSerialSubscriber { - @Inject() - vendorCreditService: BaseVendorCredit; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe(events.vendorCredit.onCreated, this.autoIncrementOnceCreated); - } - - /** - * Auto serial increment once the vendor credit created. - * @param {IVendorCreditCreatedPayload} payload - */ - private autoIncrementOnceCreated = ({ - tenantId, - }: IVendorCreditCreatedPayload) => { - this.vendorCreditService.incrementSerialNumber(tenantId); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntries.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntries.ts deleted file mode 100644 index eca22e2e5..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntries.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import * as R from 'ramda'; -import { - IVendorCredit, - ILedgerEntry, - AccountNormal, - IItemEntry, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export default class VendorCreditGLEntries { - @Inject() - private ledgerStorage: LedgerStorageService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve the vendor credit GL common entry. - * @param {IVendorCredit} vendorCredit - * @returns {} - */ - public getVendorCreditGLCommonEntry = (vendorCredit: IVendorCredit) => { - return { - date: vendorCredit.vendorCreditDate, - currencyCode: vendorCredit.currencyCode, - exchangeRate: vendorCredit.exchangeRate, - - transactionId: vendorCredit.id, - transactionType: 'VendorCredit', - transactionNumber: vendorCredit.vendorCreditNumber, - referenceNumber: vendorCredit.referenceNo, - - credit: 0, - debit: 0, - - branchId: vendorCredit.branchId, - }; - }; - - /** - * Retrieves the vendor credit payable GL entry. - * @param {IVendorCredit} vendorCredit - * @param {number} APAccountId - * @returns {ILedgerEntry} - */ - public getVendorCreditPayableGLEntry = ( - vendorCredit: IVendorCredit, - APAccountId: number - ): ILedgerEntry => { - const commonEntity = this.getVendorCreditGLCommonEntry(vendorCredit); - - return { - ...commonEntity, - debit: vendorCredit.totalLocal, - accountId: APAccountId, - contactId: vendorCredit.vendorId, - accountNormal: AccountNormal.CREDIT, - index: 1, - }; - }; - - /** - * Retrieves the vendor credit item GL entry. - * @param {IVendorCredit} vendorCredit - * @param {IItemEntry} entry - * @returns {ILedgerEntry} - */ - public getVendorCreditGLItemEntry = R.curry( - ( - vendorCredit: IVendorCredit, - entry: IItemEntry, - index: number - ): ILedgerEntry => { - const commonEntity = this.getVendorCreditGLCommonEntry(vendorCredit); - const totalLocal = entry.totalExcludingTax * vendorCredit.exchangeRate; - - return { - ...commonEntity, - credit: totalLocal, - index: index + 2, - itemId: entry.itemId, - itemQuantity: entry.quantity, - accountId: - 'inventory' === entry.item.type - ? entry.item.inventoryAccountId - : entry.costAccountId || entry.item.costAccountId, - accountNormal: AccountNormal.DEBIT, - }; - } - ); - - /** - * Retrieves the vendor credit discount GL entry. - * @param {IVendorCredit} vendorCredit - * @param {number} discountAccountId - * @returns {ILedgerEntry} - */ - public getDiscountEntry = ( - vendorCredit: IVendorCredit, - purchaseDiscountAccountId: number - ) => { - const commonEntry = this.getVendorCreditGLCommonEntry(vendorCredit); - - return { - ...commonEntry, - debit: vendorCredit.discountAmountLocal, - accountId: purchaseDiscountAccountId, - accountNormal: AccountNormal.DEBIT, - index: 1, - indexGroup: 40, - }; - }; - - /** - * Retrieves the vendor credit adjustment GL entry. - * @param {IVendorCredit} vendorCredit - * @param {number} adjustmentAccountId - * @returns {ILedgerEntry} - */ - public getAdjustmentEntry = ( - vendorCredit: IVendorCredit, - otherExpensesAccountId: number - ) => { - const commonEntry = this.getVendorCreditGLCommonEntry(vendorCredit); - const adjustmentAmount = Math.abs(vendorCredit.adjustmentLocal); - - return { - ...commonEntry, - credit: vendorCredit.adjustmentLocal > 0 ? adjustmentAmount : 0, - debit: vendorCredit.adjustmentLocal < 0 ? adjustmentAmount : 0, - accountId: otherExpensesAccountId, - accountNormal: AccountNormal.DEBIT, - index: 1, - indexGroup: 40, - }; - }; - - /** - * Retrieve the vendor credit GL entries. - * @param {IVendorCredit} vendorCredit - - * @param {number} receivableAccount - - * @return {ILedgerEntry[]} - */ - public getVendorCreditGLEntries = ( - vendorCredit: IVendorCredit, - payableAccountId: number, - purchaseDiscountAccountId: number, - otherExpensesAccountId: number - ): ILedgerEntry[] => { - const payableEntry = this.getVendorCreditPayableGLEntry( - vendorCredit, - payableAccountId - ); - const getItemEntry = this.getVendorCreditGLItemEntry(vendorCredit); - const itemsEntries = vendorCredit.entries.map(getItemEntry); - - const discountEntry = this.getDiscountEntry( - vendorCredit, - purchaseDiscountAccountId - ); - const adjustmentEntry = this.getAdjustmentEntry( - vendorCredit, - otherExpensesAccountId - ); - return [payableEntry, discountEntry, adjustmentEntry, ...itemsEntries]; - }; - - /** - * Reverts the vendor credit associated GL entries. - * @param {number} tenantId - * @param {number} vendorCreditId - * @param {Knex.Transaction} trx - */ - public revertVendorCreditGLEntries = async ( - tenantId: number, - vendorCreditId: number, - trx?: Knex.Transaction - ): Promise => { - await this.ledgerStorage.deleteByReference( - tenantId, - vendorCreditId, - 'VendorCredit', - trx - ); - }; - - /** - * Creates vendor credit associated GL entries. - * @param {number} tenantId - * @param {number} vendorCreditId - * @param {Knex.Transaction} trx - */ - public writeVendorCreditGLEntries = async ( - tenantId: number, - vendorCreditId: number, - trx?: Knex.Transaction - ) => { - const { accountRepository } = this.tenancy.repositories(tenantId); - const { VendorCredit } = this.tenancy.models(tenantId); - - // Vendor credit with entries items. - const vendorCredit = await VendorCredit.query(trx) - .findById(vendorCreditId) - .withGraphFetched('entries.item'); - - // Retrieve the payable account (A/P) account. - const APAccount = await accountRepository.findOrCreateAccountsPayable( - vendorCredit.currencyCode, - {}, - trx - ); - const purchaseDiscountAccount = - await accountRepository.findOrCreatePurchaseDiscountAccount({}, trx); - - const otherExpensesAccount = - await accountRepository.findOrCreateOtherExpensesAccount({}, trx); - // Saves the vendor credit GL entries. - const ledgerEntries = this.getVendorCreditGLEntries( - vendorCredit, - APAccount.id, - purchaseDiscountAccount.id, - otherExpensesAccount.id - ); - const ledger = new Ledger(ledgerEntries); - - // Commits the ledger entries to the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Edits vendor credit associated GL entries. - * @param {number} tenantId - * @param {number} vendorCreditId - * @param {Knex.Transaction} trx - */ - public rewriteVendorCreditGLEntries = async ( - tenantId: number, - vendorCreditId: number, - trx?: Knex.Transaction - ) => { - // Reverts the GL entries. - await this.revertVendorCreditGLEntries(tenantId, vendorCreditId, trx); - - // Re-write the GL entries. - await this.writeVendorCreditGLEntries(tenantId, vendorCreditId, trx); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntriesSubscriber.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntriesSubscriber.ts deleted file mode 100644 index 0c7761701..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditGLEntriesSubscriber.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - IVendorCreditCreatedPayload, - IVendorCreditDeletedPayload, - IVendorCreditEditedPayload, - IVendorCreditOpenedPayload, -} from '@/interfaces'; -import VendorCreditGLEntries from './VendorCreditGLEntries'; - -@Service() -export default class VendorCreditGlEntriesSubscriber { - @Inject() - private vendorCreditGLEntries: VendorCreditGLEntries; - - /*** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.vendorCredit.onCreated, - this.writeGLEntriesOnceVendorCreditCreated - ); - bus.subscribe( - events.vendorCredit.onOpened, - this.writeGLEntgriesOnceVendorCreditOpened - ); - bus.subscribe( - events.vendorCredit.onEdited, - this.editGLEntriesOnceVendorCreditEdited - ); - bus.subscribe( - events.vendorCredit.onDeleted, - this.revertGLEntriesOnceDeleted - ); - } - - /** - * Writes GL entries of vendor credit once the transaction created. - * @param {IVendorCreditCreatedPayload} payload - - */ - private writeGLEntriesOnceVendorCreditCreated = async ({ - tenantId, - vendorCredit, - trx, - }: IVendorCreditCreatedPayload): Promise => { - // Can't continue if the vendor credit is not open yet. - if (!vendorCredit.isPublished) return; - - await this.vendorCreditGLEntries.writeVendorCreditGLEntries( - tenantId, - vendorCredit.id, - trx - ); - }; - - /** - * Writes Gl entries of vendor credit once the transaction opened. - * @param {IVendorCreditOpenedPayload} payload - - */ - private writeGLEntgriesOnceVendorCreditOpened = async ({ - tenantId, - vendorCreditId, - trx, - }: IVendorCreditOpenedPayload) => { - await this.vendorCreditGLEntries.writeVendorCreditGLEntries( - tenantId, - vendorCreditId, - trx - ); - }; - - /** - * Edits associated GL entries once vendor credit edited. - * @param {IVendorCreditEditedPayload} payload - */ - private editGLEntriesOnceVendorCreditEdited = async ({ - tenantId, - vendorCreditId, - vendorCredit, - trx, - }: IVendorCreditEditedPayload) => { - // Can't continue if the vendor credit is not open yet. - if (!vendorCredit.isPublished) return; - - await this.vendorCreditGLEntries.rewriteVendorCreditGLEntries( - tenantId, - vendorCreditId, - trx - ); - }; - - /** - * Reverts the GL entries once vendor credit deleted. - * @param {IVendorCreditDeletedPayload} payload - - */ - private revertGLEntriesOnceDeleted = async ({ - vendorCreditId, - tenantId, - oldVendorCredit, - }: IVendorCreditDeletedPayload): Promise => { - // Can't continue of the vendor credit is not open yet. - if (!oldVendorCredit.isPublished) return; - - await this.vendorCreditGLEntries.revertVendorCreditGLEntries( - tenantId, - vendorCreditId - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactions.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactions.ts deleted file mode 100644 index e7dfbcea8..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactions.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { IVendorCredit } from '@/interfaces'; -import InventoryService from '@/services/Inventory/Inventory'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; - -@Service() -export default class VendorCreditInventoryTransactions { - @Inject() - inventoryService: InventoryService; - - @Inject() - itemsEntriesService: ItemsEntriesService; - - /** - * Creates vendor credit associated inventory transactions. - * @param {number} tenantId - * @param {IVnedorCredit} vendorCredit - * @param {Knex.Transaction} trx - */ - public createInventoryTransactions = async ( - vendorCredit: IVendorCredit, - trx: Knex.Transaction - ): Promise => { - // Loads the inventory items entries of the given sale invoice. - const inventoryEntries = - await this.itemsEntriesService.filterInventoryEntries( - vendorCredit.entries - ); - - const transaction = { - transactionId: vendorCredit.id, - transactionType: 'VendorCredit', - transactionNumber: vendorCredit.vendorCreditNumber, - exchangeRate: vendorCredit.exchangeRate, - date: vendorCredit.vendorCreditDate, - direction: 'OUT', - entries: inventoryEntries, - warehouseId: vendorCredit.warehouseId, - createdAt: vendorCredit.createdAt, - }; - // Writes inventory tranactions. - await this.inventoryService.recordInventoryTransactionsFromItemsEntries( - transaction, - false, - trx - ); - }; - - /** - * Edits vendor credit associated inventory transactions. - * @param {number} vendorCreditId - Vendor credit id. - * @param {IVendorCredit} vendorCredit - Vendor credit. - * @param {Knex.Transactions} trx - Knex transaction. - */ - public async editInventoryTransactions( - vendorCreditId: number, - vendorCredit: IVendorCredit, - trx?: Knex.Transaction - ): Promise { - // Deletes inventory transactions. - await this.deleteInventoryTransactions(vendorCreditId, trx); - - // Re-write inventory transactions. - await this.createInventoryTransactions(vendorCredit, trx); - }; - - /** - * Deletes credit note associated inventory transactions. - * @param {number} vendorCreditId - Vendor credit id. - * @param {Knex.Transaction} trx - Knex transaction. - */ - public async deleteInventoryTransactions( - vendorCreditId: number, - trx?: Knex.Transaction - ): Promise { - // Deletes the inventory transactions by the given reference id and type. - await this.inventoryService.deleteInventoryTransactions( - vendorCreditId, - 'VendorCredit', - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactionsSusbcriber.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactionsSusbcriber.ts deleted file mode 100644 index bae3adc23..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditInventoryTransactionsSusbcriber.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - IVendorCreditCreatedPayload, - IVendorCreditDeletedPayload, - IVendorCreditEditedPayload, -} from '@/interfaces'; -import VendorCreditInventoryTransactions from './VendorCreditInventoryTransactions'; - -@Service() -export default class VendorCreditInventoryTransactionsSubscriber { - @Inject() - private inventoryTransactions: VendorCreditInventoryTransactions; - - /** - * Attaches events with handlers. - * @param bus - */ - attach(bus) { - bus.subscribe( - events.vendorCredit.onCreated, - this.writeInventoryTransactionsOnceCreated - ); - bus.subscribe( - events.vendorCredit.onOpened, - this.writeInventoryTransactionsOnceCreated - ); - bus.subscribe( - events.vendorCredit.onEdited, - this.rewriteInventroyTransactionsOnceEdited - ); - bus.subscribe( - events.vendorCredit.onDeleted, - this.revertInventoryTransactionsOnceDeleted - ); - } - - /** - * Writes inventory transactions once vendor created created. - * @param {IVendorCreditCreatedPayload} payload - - */ - private writeInventoryTransactionsOnceCreated = async ({ - tenantId, - vendorCredit, - trx, - }: IVendorCreditCreatedPayload) => { - // Can't continue if vendor credit is not opened. - if (!vendorCredit.openedAt) return null; - - await this.inventoryTransactions.createInventoryTransactions( - tenantId, - vendorCredit, - trx - ); - }; - - /** - * Rewrites inventory transactions once vendor credit edited. - * @param {IVendorCreditEditedPayload} payload - - */ - private rewriteInventroyTransactionsOnceEdited = async ({ - tenantId, - vendorCreditId, - vendorCredit, - trx, - }: IVendorCreditEditedPayload) => { - // Can't continue if vendor credit is not opened. - if (!vendorCredit.openedAt) return null; - - await this.inventoryTransactions.editInventoryTransactions( - tenantId, - vendorCreditId, - vendorCredit, - trx - ); - }; - - /** - * Reverts inventory transactions once vendor credit deleted. - * @param {IVendorCreditDeletedPayload} payload - - */ - private revertInventoryTransactionsOnceDeleted = async ({ - tenantId, - vendorCreditId, - trx, - }: IVendorCreditDeletedPayload) => { - await this.inventoryTransactions.deleteInventoryTransactions( - tenantId, - vendorCreditId, - trx - ); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditTransformer.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditTransformer.ts deleted file mode 100644 index 61e4d6736..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditTransformer.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { IVendorCredit } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; -import { ItemEntryTransformer } from '@/services/Sales/Invoices/ItemEntryTransformer'; -import { formatNumber } from 'utils'; - -export class VendorCreditTransformer extends Transformer { - /** - * Include these attributes to vendor credit object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedAmount', - 'formattedSubtotal', - 'formattedVendorCreditDate', - 'formattedCreatedAt', - 'formattedCreditsRemaining', - 'formattedInvoicedAmount', - - 'discountAmountFormatted', - 'discountPercentageFormatted', - 'discountAmountLocalFormatted', - - 'adjustmentFormatted', - 'adjustmentLocalFormatted', - - 'totalFormatted', - 'entries', - 'attachments', - ]; - }; - - /** - * Retrieve formatted vendor credit date. - * @param {IVendorCredit} credit - * @returns {String} - */ - protected formattedVendorCreditDate = (vendorCredit): string => { - return this.formatDate(vendorCredit.vendorCreditDate); - }; - - /** - * Retireve formatted created at date. - * @param vendorCredit - * @returns {string} - */ - protected formattedCreatedAt = (vendorCredit): string => { - return this.formatDate(vendorCredit.createdAt); - }; - - /** - * Retrieve formatted vendor credit amount. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected formattedAmount = (vendorCredit): string => { - return formatNumber(vendorCredit.amount, { - currencyCode: vendorCredit.currencyCode, - }); - }; - - /** - * Retrieves the vendor credit formatted subtotal. - * @param {IVendorCredit} vendorCredit - * @returns {string} - */ - protected formattedSubtotal = (vendorCredit): string => { - return formatNumber(vendorCredit.amount, { money: false }); - }; - - /** - * Retrieve formatted credits remaining. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected formattedCreditsRemaining = (credit) => { - return formatNumber(credit.creditsRemaining, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieves the formatted discount amount. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected discountAmountFormatted = (credit): string => { - return formatNumber(credit.discountAmount, { - currencyCode: credit.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted discount amount in local currency. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected discountAmountLocalFormatted = (credit): string => { - return formatNumber(credit.discountAmountLocal, { - currencyCode: this.context.organization.baseCurrency, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted discount percentage. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected discountPercentageFormatted = (credit): string => { - return credit.discountPercentage ? `${credit.discountPercentage}%` : ''; - }; - - /** - * Retrieves the formatted adjustment amount. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected adjustmentFormatted = (credit): string => { - return formatNumber(credit.adjustment, { - currencyCode: credit.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted adjustment amount in local currency. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected adjustmentLocalFormatted = (credit): string => { - return formatNumber(credit.adjustmentLocal, { - currencyCode: this.context.organization.baseCurrency, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted invoiced amount. - * @param credit - * @returns {string} - */ - protected formattedInvoicedAmount = (credit) => { - return formatNumber(credit.invoicedAmount, { - currencyCode: credit.currencyCode, - }); - }; - - /** - * Retrieves the formatted total. - * @param {IVendorCredit} credit - * @returns {string} - */ - protected totalFormatted = (credit) => { - return formatNumber(credit.total, { currencyCode: credit.currencyCode }); - }; - - /** - * Retrieves the entries of the bill. - * @param {IVendorCredit} vendorCredit - * @returns {} - */ - protected entries = (vendorCredit) => { - return this.item(vendorCredit.entries, new ItemEntryTransformer(), { - currencyCode: vendorCredit.currencyCode, - }); - }; - - /** - * Retrieves the vendor credit attachments. - * @param {IVendorCredit} invoice - * @returns - */ - protected attachments = (vendorCredit) => { - return this.item(vendorCredit.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditsExportable.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditsExportable.ts deleted file mode 100644 index e1919a9ef..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditsExportable.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IVendorCreditsQueryDTO } from '@/interfaces'; -import ListVendorCredits from './ListVendorCredits'; -import { Exportable } from '@/services/Export/Exportable'; -import { QueryBuilder } from 'knex'; - -@Service() -export class VendorCreditsExportable extends Exportable { - @Inject() - private getVendorCredits: ListVendorCredits; - - /** - * Retrieves the vendor credits data to exportable sheet. - * @param {number} tenantId - - * @param {IVendorCreditsQueryDTO} query - - * @returns {} - */ - public exportable(tenantId: number, query: IVendorCreditsQueryDTO) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - query.withGraphFetched('warehouse'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: 12000, - filterQuery, - } as IVendorCreditsQueryDTO; - - return this.getVendorCredits - .getVendorCredits(tenantId, parsedQuery) - .then((output) => output.vendorCredits); - } -} diff --git a/packages/server/src/services/Purchases/VendorCredits/VendorCreditsImportable.ts b/packages/server/src/services/Purchases/VendorCredits/VendorCreditsImportable.ts deleted file mode 100644 index b267ef353..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/VendorCreditsImportable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { Importable } from '@/services/Import/Importable'; -import CreateVendorCredit from './CreateVendorCredit'; -import { IVendorCreditCreateDTO } from '@/interfaces'; -import { VendorCreditsSampleData } from './constants'; - -@Service() -export class VendorCreditsImportable extends Importable { - @Inject() - private createVendorCreditService: CreateVendorCredit; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createPaymentDTO: IVendorCreditCreateDTO, - trx?: Knex.Transaction - ) { - return this.createVendorCreditService.newVendorCredit( - tenantId, - createPaymentDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return VendorCreditsSampleData; - } -} diff --git a/packages/server/src/services/Purchases/VendorCredits/constants.ts b/packages/server/src/services/Purchases/VendorCredits/constants.ts deleted file mode 100644 index d686669d8..000000000 --- a/packages/server/src/services/Purchases/VendorCredits/constants.ts +++ /dev/null @@ -1,82 +0,0 @@ -export const ERRORS = { - VENDOR_CREDIT_NOT_FOUND: 'VENDOR_CREDIT_NOT_FOUND', - VENDOR_CREDIT_ALREADY_OPENED: 'VENDOR_CREDIT_ALREADY_OPENED', - VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT: - 'VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT', - VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND: - 'VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND', - BILLS_HAS_NO_REMAINING_AMOUNT: 'BILLS_HAS_NO_REMAINING_AMOUNT', - VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS: - 'VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS', - VENDOR_CREDIT_HAS_APPLIED_BILLS: 'VENDOR_CREDIT_HAS_APPLIED_BILLS', -}; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'vendor_credit.view.draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'vendor_credit.view.published', - slug: 'published', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'published', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'vendor_credit.view.open', - slug: 'open', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'open', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'vendor_credit.view.closed', - slug: 'closed', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'closed', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const VendorCreditsSampleData = [ - { - Vendor: 'Randall Kohler VENDOR', - 'Vendor Credit Date': '2024-01-01', - 'Vendor Credit No.': 'VC-0001', - 'Reference No.': 'REF-00001', - 'Exchange Rate': '', - Note: 'Note', - Open: 'T', - 'Item Name': 'Hettinger, Schumm and Bartoletti', - Quantity: 100, - Rate: 100, - }, -]; diff --git a/packages/server/src/services/Resource/ResourceService.ts b/packages/server/src/services/Resource/ResourceService.ts deleted file mode 100644 index 0ecc36950..000000000 --- a/packages/server/src/services/Resource/ResourceService.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { camelCase, upperFirst, pickBy, isEmpty } from 'lodash'; -import * as qim from 'qim'; -import pluralize from 'pluralize'; -import { - Features, - IModelMeta, - IModelMetaField, - IModelMetaField2, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import I18nService from '@/services/I18n/I18nService'; -import { WarehousesSettings } from '../Warehouses/WarehousesSettings'; -import { BranchesSettings } from '../Branches/BranchesSettings'; - -const ERRORS = { - RESOURCE_MODEL_NOT_FOUND: 'RESOURCE_MODEL_NOT_FOUND', -}; - -@Service() -export default class ResourceService { - @Inject() - tenancy: TenancyService; - - @Inject() - i18nService: I18nService; - - @Inject() - private branchesSettings: BranchesSettings; - - @Inject() - private warehousesSettings: WarehousesSettings; - - /** - * Transform resource to model name. - * @param {string} resourceName - */ - public resourceToModelName(resourceName: string): string { - return upperFirst(camelCase(pluralize.singular(resourceName))); - } - - /** - * Retrieve resource model object. - * @param {number} tenantId - - * @param {string} inputModelName - - */ - public getResourceModel(tenantId: number, inputModelName: string) { - const modelName = this.resourceToModelName(inputModelName); - const Models = this.tenancy.models(tenantId); - - if (!Models[modelName]) { - throw new ServiceError(ERRORS.RESOURCE_MODEL_NOT_FOUND); - } - return Models[modelName]; - } - - /** - * Retrieve the resource meta. - * @param {number} tenantId - * @param {string} modelName - * @returns {IModelMeta} - */ - public getResourceMeta( - tenantId: number, - modelName: string, - metakey?: string - ): IModelMeta { - const resourceModel = this.getResourceModel(tenantId, modelName); - - // Retrieve the resource meta. - const resourceMeta = resourceModel.getMeta(metakey); - - // Localization the fields names. - return this.getResourceMetaLocalized(resourceMeta, tenantId); - } - - /** - * - */ - public getResourceFields( - tenantId: number, - modelName: string - ): { [key: string]: IModelMetaField } { - const meta = this.getResourceMeta(tenantId, modelName); - - return meta.fields; - } - - public filterSupportFeatures = ( - tenantId, - fields: { [key: string]: IModelMetaField2 } - ) => { - const isMultiFeaturesEnabled = - this.branchesSettings.isMultiBranchesActive(tenantId); - const isMultiWarehousesEnabled = - this.warehousesSettings.isMultiWarehousesActive(tenantId); - - return pickBy(fields, (field) => { - if ( - !isMultiWarehousesEnabled && - field.features?.includes(Features.WAREHOUSES) - ) { - return false; - } - if ( - !isMultiFeaturesEnabled && - field.features?.includes(Features.BRANCHES) - ) { - return false; - } - return true; - }); - }; - - public getResourceFields2( - tenantId: number, - modelName: string - ): { [key: string]: IModelMetaField2 } { - const meta = this.getResourceMeta(tenantId, modelName); - - return this.filterSupportFeatures(tenantId, meta.fields2); - } - - public getResourceColumns(tenantId: number, modelName: string) { - const meta = this.getResourceMeta(tenantId, modelName); - - return this.filterSupportFeatures(tenantId, meta.columns); - } - - /** - * - * @param {number} tenantId - * @param {string} modelName - * @returns - */ - public getResourceImportableFields( - tenantId: number, - modelName: string - ): { [key: string]: IModelMetaField } { - const fields = this.getResourceFields(tenantId, modelName); - - return pickBy(fields, (field) => field.importable); - } - - /** - * Retrieve the resource meta localized based on the current user language. - */ - public getResourceMetaLocalized(meta, tenantId) { - const $enumerationType = (field) => - field.fieldType === 'enumeration' ? field : undefined; - - const $hasFields = (field) => - 'undefined' !== typeof field.fields ? field : undefined; - - const $ColumnHasColumns = (column) => - 'undefined' !== typeof column.columns ? column : undefined; - - const $hasColumns = (columns) => - 'undefined' !== typeof columns ? columns : undefined; - - const naviagations = [ - ['fields', qim.$each, 'name'], - ['fields', qim.$each, $enumerationType, 'options', qim.$each, 'label'], - ['fields2', qim.$each, 'name'], - ['fields2', qim.$each, $enumerationType, 'options', qim.$each, 'label'], - ['fields2', qim.$each, $hasFields, 'fields', qim.$each, 'name'], - ['columns', $hasColumns, qim.$each, 'name'], - [ - 'columns', - $hasColumns, - qim.$each, - $ColumnHasColumns, - 'columns', - qim.$each, - 'name', - ], - ]; - return this.i18nService.i18nApply(naviagations, meta, tenantId); - } -} diff --git a/packages/server/src/services/Roles/AbilitySchema.ts b/packages/server/src/services/Roles/AbilitySchema.ts deleted file mode 100644 index ec3de5363..000000000 --- a/packages/server/src/services/Roles/AbilitySchema.ts +++ /dev/null @@ -1,339 +0,0 @@ -import { - ReportsAction, - ISubjectAbilitiesSchema, - ISubjectAbilitySchema, - AbilitySubject, - ManualJournalAction, - AccountAction, - SaleInvoiceAction, - ItemAction, - VendorAction, - CustomerAction, - ExpenseAction, - PaymentReceiveAction, - InventoryAdjustmentAction, - SaleEstimateAction, - BillAction, - SaleReceiptAction, - IPaymentMadeAction, - CashflowAction, - PreferencesAction, - CreditNoteAction, - VendorCreditAction, -} from '@/interfaces'; - -export const AbilitySchema: ISubjectAbilitiesSchema[] = [ - { - subject: AbilitySubject.Account, - subjectLabel: 'ability.accounts', - abilities: [ - { key: AccountAction.VIEW, label: 'ability.view' }, - { key: AccountAction.CREATE, label: 'ability.create' }, - { key: AccountAction.EDIT, label: 'ability.edit' }, - { key: AccountAction.DELETE, label: 'ability.delete' }, - ], - extraAbilities: [ - { - key: AccountAction.TransactionsLocking, - label: 'ability.transactions_locking', - }, - ], - }, - { - subject: AbilitySubject.ManualJournal, - subjectLabel: 'ability.manual_journal', - abilities: [ - { key: ManualJournalAction.View, label: 'ability.view' }, - { key: ManualJournalAction.Create, label: 'ability.create' }, - { key: ManualJournalAction.Edit, label: 'ability.edit' }, - { key: ManualJournalAction.Delete, label: 'ability.delete' }, - ], - }, - { - subject: AbilitySubject.Cashflow, - subjectLabel: 'ability.cashflow', - abilities: [ - { key: CashflowAction.View, label: 'ability.view' }, - { key: CashflowAction.Create, label: 'ability.create' }, - { key: CashflowAction.Delete, label: 'ability.delete' }, - ], - }, - { - subject: AbilitySubject.Item, - subjectLabel: 'ability.items', - abilities: [ - { key: ItemAction.VIEW, label: 'ability.view', default: true }, - { key: ItemAction.CREATE, label: 'ability.create', default: true }, - { key: ItemAction.EDIT, label: 'ability.edit', default: true }, - { key: ItemAction.DELETE, label: 'ability.delete', default: true }, - ], - }, - { - subject: AbilitySubject.InventoryAdjustment, - subjectLabel: 'ability.inventory_adjustment', - abilities: [ - { - key: InventoryAdjustmentAction.VIEW, - label: 'ability.view', - default: true, - }, - { - key: InventoryAdjustmentAction.CREATE, - label: 'ability.create', - default: true, - }, - { - key: InventoryAdjustmentAction.EDIT, - label: 'ability.edit', - default: true, - }, - { key: InventoryAdjustmentAction.DELETE, label: 'ability.delete' }, - ], - }, - { - subject: AbilitySubject.Customer, - subjectLabel: 'ability.customers', - // description: 'Description is here', - abilities: [ - { key: CustomerAction.View, label: 'ability.view', default: true }, - { key: CustomerAction.Create, label: 'ability.create', default: true }, - { key: CustomerAction.Edit, label: 'ability.edit', default: true }, - { key: CustomerAction.Delete, label: 'ability.delete', default: true }, - ], - }, - { - subject: AbilitySubject.Vendor, - subjectLabel: 'ability.vendors', - abilities: [ - { key: VendorAction.View, label: 'ability.view', default: true }, - { key: VendorAction.Create, label: 'ability.create', default: true }, - { key: VendorAction.Edit, label: 'ability.edit', default: true }, - { key: VendorAction.Delete, label: 'ability.delete', default: true }, - ], - }, - { - subject: AbilitySubject.SaleEstimate, - subjectLabel: 'ability.sale_estimates', - abilities: [ - { key: SaleEstimateAction.View, label: 'ability.view', default: true }, - { - key: SaleEstimateAction.Create, - label: 'ability.create', - default: true, - }, - { key: SaleEstimateAction.Edit, label: 'ability.edit', default: true }, - { - key: SaleEstimateAction.Delete, - label: 'ability.delete', - default: true, - }, - ], - }, - { - subject: AbilitySubject.SaleInvoice, - subjectLabel: 'ability.sale_invoices', - abilities: [ - { key: SaleInvoiceAction.View, label: 'ability.view', default: true }, - { key: SaleInvoiceAction.Create, label: 'ability.create', default: true }, - { key: SaleInvoiceAction.Edit, label: 'ability.edit', default: true }, - { key: SaleInvoiceAction.Delete, label: 'ability.delete', default: true }, - ], - extraAbilities: [{ key: 'bad-debt', label: 'Due amount to bad debit' }], - }, - { - subject: AbilitySubject.SaleReceipt, - subjectLabel: 'ability.sale_receipts', - abilities: [ - { key: SaleReceiptAction.View, label: 'ability.view', default: true }, - { key: SaleReceiptAction.Create, label: 'ability.create', default: true }, - { key: SaleReceiptAction.Edit, label: 'ability.edit', default: true }, - { key: SaleReceiptAction.Delete, label: 'ability.delete', default: true }, - ], - }, - { - subject: AbilitySubject.CreditNote, - subjectLabel: 'ability.credit_note', - abilities: [ - { key: CreditNoteAction.View, label: 'ability.view', default: true }, - { key: CreditNoteAction.Create, label: 'ability.create', default: true }, - { key: CreditNoteAction.Edit, label: 'ability.edit', default: true }, - { key: CreditNoteAction.Delete, label: 'ability.delete', default: true }, - { key: CreditNoteAction.Refund, label: 'ability.refund', default: true }, - ], - }, - { - subject: AbilitySubject.PaymentReceive, - subjectLabel: 'ability.payments_receive', - abilities: [ - { key: PaymentReceiveAction.View, label: 'ability.view', default: true }, - { - key: PaymentReceiveAction.Create, - label: 'ability.create', - default: true, - }, - { key: PaymentReceiveAction.Edit, label: 'ability.edit', default: true }, - { - key: PaymentReceiveAction.Delete, - label: 'ability.delete', - default: true, - }, - ], - }, - { - subject: AbilitySubject.Bill, - subjectLabel: 'ability.purchase_invoices', - abilities: [ - { key: BillAction.View, label: 'ability.view', default: true }, - { key: BillAction.Create, label: 'ability.create', default: true }, - { key: BillAction.Edit, label: 'ability.edit', default: true }, - { key: BillAction.Delete, label: 'ability.delete', default: true }, - ], - }, - { - subject: AbilitySubject.VendorCredit, - subjectLabel: 'ability.vendor_credit', - abilities: [ - { key: VendorCreditAction.View, label: 'ability.view', default: true }, - { - key: VendorCreditAction.Create, - label: 'ability.create', - default: true, - }, - { key: VendorCreditAction.Edit, label: 'ability.edit', default: true }, - { - key: VendorCreditAction.Delete, - label: 'ability.delete', - default: true, - }, - { - key: VendorCreditAction.Refund, - label: 'ability.refund', - default: true, - }, - ], - }, - { - subject: AbilitySubject.PaymentMade, - subjectLabel: 'ability.payments_made', - abilities: [ - { key: IPaymentMadeAction.View, label: 'ability.view', default: true }, - { - key: IPaymentMadeAction.Create, - label: 'ability.create', - default: true, - }, - { key: IPaymentMadeAction.Edit, label: 'ability.edit', default: true }, - { - key: IPaymentMadeAction.Delete, - label: 'ability.delete', - default: true, - }, - ], - }, - { - subject: AbilitySubject.Expense, - subjectLabel: 'ability.expenses', - abilities: [ - { key: ExpenseAction.View, label: 'ability.view', default: true }, - { key: ExpenseAction.Create, label: 'ability.create', default: true }, - { key: ExpenseAction.Edit, label: 'ability.edit', default: true }, - { key: ExpenseAction.Delete, label: 'ability.delete', default: true }, - ], - }, - { - subject: AbilitySubject.Report, - subjectLabel: 'ability.all_reports', - extraAbilities: [ - { - key: ReportsAction.READ_BALANCE_SHEET, - label: 'ability.balance_sheet_report', - }, - { - key: ReportsAction.READ_PROFIT_LOSS, - label: 'ability.profit_loss_sheet', - }, - { key: ReportsAction.READ_JOURNAL, label: 'ability.journal' }, - { - key: ReportsAction.READ_GENERAL_LEDGET, - label: 'ability.general_ledger', - }, - { key: ReportsAction.READ_CASHFLOW, label: 'ability.cashflow_report' }, - { - key: ReportsAction.READ_AR_AGING_SUMMARY, - label: 'ability.AR_aging_summary_report', - }, - { - key: ReportsAction.READ_AP_AGING_SUMMARY, - label: 'ability.AP_aging_summary_report', - }, - { - key: ReportsAction.READ_PURCHASES_BY_ITEMS, - label: 'ability.purchases_by_items', - }, - { - key: ReportsAction.READ_SALES_BY_ITEMS, - label: 'ability.sales_by_items_report', - }, - { - key: ReportsAction.READ_CUSTOMERS_TRANSACTIONS, - label: 'ability.customers_transactions_report', - }, - { - key: ReportsAction.READ_VENDORS_TRANSACTIONS, - label: 'ability.vendors_transactions_report', - }, - { - key: ReportsAction.READ_CUSTOMERS_SUMMARY_BALANCE, - label: 'ability.customers_summary_balance_report', - }, - { - key: ReportsAction.READ_VENDORS_SUMMARY_BALANCE, - label: 'ability.vendors_summary_balance_report', - }, - { - key: ReportsAction.READ_INVENTORY_VALUATION_SUMMARY, - label: 'ability.inventory_valuation_summary', - }, - { - key: ReportsAction.READ_INVENTORY_ITEM_DETAILS, - label: 'ability.inventory_items_details', - }, - ], - }, - { - subject: AbilitySubject.Preferences, - subjectLabel: 'ability.preferences', - extraAbilities: [ - { - key: PreferencesAction.Mutate, - label: 'ability.mutate_system_preferences', - }, - ], - }, -]; - -/** - * Retrieve the permissions subject. - * @param {string} key - * @returns {ISubjectAbilitiesSchema | null} - */ -export const getPermissionsSubject = ( - key: string -): ISubjectAbilitiesSchema | null => { - return AbilitySchema.find((subject) => subject.subject === key); -}; - -/** - * Retrieve the permission subject ability. - * @param {String} subjectKey - * @param {string} abilityKey - * @returns - */ -export const getPermissionAbility = ( - subjectKey: string, - abilityKey: string -): ISubjectAbilitySchema | null => { - const subject = getPermissionsSubject(subjectKey); - - return subject?.abilities.find((ability) => ability.key === abilityKey); -}; diff --git a/packages/server/src/services/Roles/PurgeAuthorizedUser.ts b/packages/server/src/services/Roles/PurgeAuthorizedUser.ts deleted file mode 100644 index 0c1370f4b..000000000 --- a/packages/server/src/services/Roles/PurgeAuthorizedUser.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Service } from 'typedi'; -import events from '@/subscribers/events'; -import { ABILITIES_CACHE } from '../../api/middleware/AuthorizationMiddleware'; - -@Service() -export default class PurgeAuthorizedUserOnceRoleMutate { - /** - * Attaches events with handlers. - * @param bus - */ - attach(bus) { - bus.subscribe(events.roles.onEdited, this.purgeAuthedUserOnceRoleMutated); - bus.subscribe(events.roles.onDeleted, this.purgeAuthedUserOnceRoleMutated); - } - - /** - * Purges authorized user once role edited or deleted. - */ - purgeAuthedUserOnceRoleMutated({}) { - ABILITIES_CACHE.reset(); - } -} diff --git a/packages/server/src/services/Roles/RolePermissionsSchema.ts b/packages/server/src/services/Roles/RolePermissionsSchema.ts deleted file mode 100644 index 81ca73f2f..000000000 --- a/packages/server/src/services/Roles/RolePermissionsSchema.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as qim from 'qim'; - -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { AbilitySchema } from './AbilitySchema'; -import I18nService from '@/services/I18n/I18nService'; - -@Service() -export default class RolePermissionsSchema { - @Inject() - tenancy: HasTenancyService; - - @Inject() - i18nService: I18nService; - - /** - * Retrieve the role permissions schema. - * @param {number} tenantId - */ - getRolePermissionsSchema(tenantId: number) { - const $abilities = (f) => (f.abilities ? f : undefined); - const $extraAbilities = (f) => (f.extraAbilities ? f : undefined); - - const naviagations = [ - [qim.$each, 'subjectLabel'], - [qim.$each, $abilities, 'abilities', qim.$each, 'label'], - [qim.$each, $extraAbilities, 'extraAbilities', qim.$each, 'label'], - ]; - return this.i18nService.i18nApply(naviagations, AbilitySchema, tenantId); - } -} diff --git a/packages/server/src/services/Roles/RoleTransformer.ts b/packages/server/src/services/Roles/RoleTransformer.ts deleted file mode 100644 index b5ab678f1..000000000 --- a/packages/server/src/services/Roles/RoleTransformer.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class RoleTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['name', 'description']; - }; - - /** - * Retrieves the localized role name if is predefined or stored name. - * @param role - * @returns {string} - */ - public name(role) { - return role.predefined ? this.context.i18n.__(role.name) : role.name; - } - - /** - * Retrieves the localized role description if is predefined or stored description. - * @param role - * @returns {string} - */ - public description(role) { - return role.predefined - ? this.context.i18n.__(role.description) - : role.description; - } -} diff --git a/packages/server/src/services/Roles/RolesService.ts b/packages/server/src/services/Roles/RolesService.ts deleted file mode 100644 index 7296af53c..000000000 --- a/packages/server/src/services/Roles/RolesService.ts +++ /dev/null @@ -1,291 +0,0 @@ -import { Service, Inject } from 'typedi'; -import Knex from 'knex'; -import { - ICreateRoleDTO, - ICreateRolePermissionDTO, - IEditRoleDTO, - IEditRolePermissionDTO, - IRole, - IRoleCreatedPayload, - IRoleDeletedPayload, - IRoleEditedPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { AbilitySchema } from './AbilitySchema'; -import { getInvalidPermissions } from './utils'; -import UnitOfWork from '@/services/UnitOfWork'; -import { ERRORS } from './constants'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { RoleTransformer } from './RoleTransformer'; - -@Service() -export default class RolesService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Creates a new role and store it to the storage. - * @param {number} tenantId - * @param {ICreateRoleDTO} createRoleDTO - * @returns - */ - public createRole = async ( - tenantId: number, - createRoleDTO: ICreateRoleDTO - ) => { - const { Role } = this.tenancy.models(tenantId); - - // Validates the invalid permissions. - this.validateInvalidPermissions(createRoleDTO.permissions); - - // Transformes the permissions DTO. - const permissions = this.tranaformPermissionsDTO(createRoleDTO.permissions); - - // Creates a new role with associated entries under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Creates a new role to the storage. - const role = await Role.query(trx).upsertGraph({ - name: createRoleDTO.roleName, - description: createRoleDTO.roleDescription, - permissions, - }); - // Triggers `onRoleCreated` event. - await this.eventPublisher.emitAsync(events.roles.onCreated, { - tenantId, - createRoleDTO, - role, - trx, - } as IRoleCreatedPayload); - return role; - }); - }; - - /** - * Edits details of the given role on the storage. - * @param {number} tenantId - - * @param {number} roleId - - * @param {IEditRoleDTO} editRoleDTO - Edit role DTO. - */ - public editRole = async ( - tenantId: number, - roleId: number, - editRoleDTO: IEditRoleDTO - ) => { - const { Role } = this.tenancy.models(tenantId); - - // Validates the invalid permissions. - this.validateInvalidPermissions(editRoleDTO.permissions); - - // Retrieve the given role or throw not found serice error. - const oldRole = await this.getRoleOrThrowError(tenantId, roleId); - - const permissions = this.tranaformEditPermissionsDTO( - editRoleDTO.permissions - ); - // Updates the role on the storage. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Updates the given role to the storage. - const role = await Role.query(trx).upsertGraph({ - id: roleId, - name: editRoleDTO.roleName, - description: editRoleDTO.roleDescription, - permissions, - }); - // Triggers `onRoleEdited` event. - await this.eventPublisher.emitAsync(events.roles.onEdited, { - editRoleDTO, - oldRole, - role, - trx, - } as IRoleEditedPayload); - - return role; - }); - }; - - /** - * Retrieve the role or throw not found service error. - * @param {number} tenantId - * @param {number} roleId - * @returns {Promise} - */ - public getRoleOrThrowError = async ( - tenantId: number, - roleId: number - ): Promise => { - const { Role } = this.tenancy.models(tenantId); - - const role = await Role.query().findById(roleId); - - this.throwRoleNotFound(role); - - return role; - }; - - /** - * Throw role not found service error if the role is not found. - * @param {IRole|null} role - */ - private throwRoleNotFound(role: IRole | null) { - if (!role) { - throw new ServiceError(ERRORS.ROLE_NOT_FOUND); - } - } - - /** - * Deletes the given role from the storage. - * @param {number} tenantId - - * @param {number} roleId - Role id. - */ - public deleteRole = async ( - tenantId: number, - roleId: number - ): Promise => { - const { Role, RolePermission } = this.tenancy.models(tenantId); - - // Retrieve the given role or throw not found serice error. - const oldRole = await this.getRoleOrThrowError(tenantId, roleId); - - // Validate role is not predefined. - this.validateRoleNotPredefined(oldRole); - - // Validates the given role is not associated to any user. - await this.validateRoleNotAssociatedToUser(tenantId, roleId); - - // Deletes the given role and associated models under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Deletes the role associated permissions from the storage. - await RolePermission.query(trx).where('roleId', roleId).delete(); - - // Deletes the role object form the storage. - await Role.query(trx).findById(roleId).delete(); - - // Triggers `onRoleDeleted` event. - await this.eventPublisher.emitAsync(events.roles.onDeleted, { - oldRole, - roleId, - tenantId, - trx, - } as IRoleDeletedPayload); - }); - }; - - /** - * Retrieve the roles list. - * @param {number} tenantId - * @param {Promise} - */ - public listRoles = async (tenantId: number): Promise => { - const { Role } = this.tenancy.models(tenantId); - - const roles = await Role.query().withGraphFetched('permissions'); - - return this.transformer.transform(tenantId, roles, new RoleTransformer()); - }; - - /** - * Retrieve the given role metadata. - * @param {number} tenantId - * @param {number} roleId - Role id. - * @returns {Promise} - */ - public getRole = async (tenantId: number, roleId: number): Promise => { - const { Role } = this.tenancy.models(tenantId); - - const role = await Role.query() - .findById(roleId) - .withGraphFetched('permissions'); - - this.throwRoleNotFound(role); - - return this.transformer.transform(tenantId, role, new RoleTransformer()); - }; - - /** - * Valdiates role is not predefined. - * @param {IRole} role - Role object. - */ - private validateRoleNotPredefined(role: IRole) { - if (role.predefined) { - throw new ServiceError(ERRORS.ROLE_PREFINED); - } - } - - /** - * Validates the invalid given permissions. - * @param {ICreateRolePermissionDTO[]} permissions - - */ - public validateInvalidPermissions = ( - permissions: ICreateRolePermissionDTO[] - ) => { - const invalidPerms = getInvalidPermissions(AbilitySchema, permissions); - - if (invalidPerms.length > 0) { - throw new ServiceError(ERRORS.INVALIDATE_PERMISSIONS, null, { - invalidPermissions: invalidPerms, - }); - } - }; - - /** - * Transformes new permissions DTO. - * @param {ICreateRolePermissionDTO[]} permissions - * @returns {ICreateRolePermissionDTO[]} - */ - private tranaformPermissionsDTO = ( - permissions: ICreateRolePermissionDTO[] - ) => { - return permissions.map((permission: ICreateRolePermissionDTO) => ({ - subject: permission.subject, - ability: permission.ability, - value: permission.value, - })); - }; - - /** - * Transformes edit permissions DTO. - * @param {ICreateRolePermissionDTO[]} permissions - * @returns {IEditRolePermissionDTO[]} - */ - private tranaformEditPermissionsDTO = ( - permissions: IEditRolePermissionDTO[] - ) => { - return permissions.map((permission: IEditRolePermissionDTO) => ({ - permissionId: permission.permissionId, - subject: permission.subject, - ability: permission.ability, - value: permission.value, - })); - }; - - /** - * Validates the given role is not associated to any tenant users. - * @param {number} tenantId - * @param {number} roleId - */ - private validateRoleNotAssociatedToUser = async ( - tenantId: number, - roleId: number - ) => { - const { User } = this.tenancy.models(tenantId); - - const userAssociatedRole = await User.query().where('roleId', roleId); - - // Throw service error if the role has associated users. - if (userAssociatedRole.length > 0) { - throw new ServiceError(ERRORS.CANNT_DELETE_ROLE_ASSOCIATED_TO_USERS); - } - }; -} diff --git a/packages/server/src/services/Roles/constants.ts b/packages/server/src/services/Roles/constants.ts deleted file mode 100644 index 39d1d768f..000000000 --- a/packages/server/src/services/Roles/constants.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const ERRORS = { - ROLE_NOT_FOUND: 'ROLE_NOT_FOUND', - ROLE_PREFINED: 'ROLE_PREFINED', - INVALIDATE_PERMISSIONS: 'INVALIDATE_PERMISSIONS', - CANNT_DELETE_ROLE_ASSOCIATED_TO_USERS: 'CANNT_DELETE_ROLE_ASSOCIATED_TO_USERS' -}; diff --git a/packages/server/src/services/Roles/utils.ts b/packages/server/src/services/Roles/utils.ts deleted file mode 100644 index e391d68e2..000000000 --- a/packages/server/src/services/Roles/utils.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { keyBy } from 'lodash'; -import { ISubjectAbilitiesSchema } from '@/interfaces'; - -/** - * Transformes ability schema to map. - */ -export function transformAbilitySchemaToMap(schema: ISubjectAbilitiesSchema[]) { - return keyBy( - schema.map((item) => ({ - ...item, - abilities: keyBy(item.abilities, 'key'), - extraAbilities: keyBy(item.extraAbilities, 'key'), - })), - 'subject' - ); -} - -/** - * Retrieve the invalid permissions from the given defined schema. - * @param {ISubjectAbilitiesSchema[]} schema - * @param permissions - * @returns - */ -export function getInvalidPermissions( - schema: ISubjectAbilitiesSchema[], - permissions -) { - const schemaMap = transformAbilitySchemaToMap(schema); - - return permissions.filter((permission) => { - const { subject, ability } = permission; - - if ( - !schemaMap[subject] || - (!schemaMap[subject].abilities[ability] && - !schemaMap[subject].extraAbilities[ability]) - ) { - return true; - } - return false; - }); -} diff --git a/packages/server/src/services/SMSClient/EasySmsClient.ts b/packages/server/src/services/SMSClient/EasySmsClient.ts deleted file mode 100644 index 6081ac0da..000000000 --- a/packages/server/src/services/SMSClient/EasySmsClient.ts +++ /dev/null @@ -1,60 +0,0 @@ -import axios from 'axios'; -import SMSClientInterface from '@/services/SMSClient/SMSClientInterfaces'; -import config from '@/config'; - -export default class EasySMSClient implements SMSClientInterface { - token: string; - clientName: string = 'easysms'; - - /** - * - * @param {string} token - */ - constructor(token: string) { - this.token = token; - } - - /** - * Normalizes the phone number string. - * @param {string} phoneNumber - * @returns {string} - */ - normlizePhoneNumber = (phoneNumber: string) => { - let normalized = phoneNumber; - - normalized = normalized.replace(/^00/, ''); - normalized = normalized.replace(/^0/, ''); - normalized = normalized.replace(/^218/, ''); - - return normalized; - }; - - /** - * Send message to given phone number via easy SMS client. - * @param {string} to - * @param {string} message - */ - send = (to: string, message: string) => { - const API_KEY = this.token; - const parsedTo = this.normlizePhoneNumber(to); - const encodedMessage = encodeURIComponent(message); - const encodeTo = encodeURIComponent(parsedTo); - - const params = `action=send-sms&api_key=${API_KEY}&to=${encodeTo}&sms=${encodedMessage}&unicode=1`; - - return new Promise((resolve, reject) => { - axios - .get(`https://easysms.devs.ly/sms/api?${params}`) - .then((response) => { - if (response.data.code === 'ok') { - resolve(response); - } else { - reject(response.data); - } - }) - .catch((error) => { - reject(error); - }); - }); - }; -} diff --git a/packages/server/src/services/SMSClient/SMSAPI.ts b/packages/server/src/services/SMSClient/SMSAPI.ts deleted file mode 100644 index 152cc7d36..000000000 --- a/packages/server/src/services/SMSClient/SMSAPI.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Container } from 'typedi'; -import SMSClientInterface from '@/services/SMSClient/SMSClientInterface'; -import { thomsonCrossSectionDependencies } from 'mathjs'; - -export default class SMSAPI { - smsClient: SMSClientInterface; - - constructor(smsClient: SMSClientInterface) { - this.smsClient = smsClient; - } - - /** - * Sends the message to the target via the client. - * @param {string} to - * @param {string} message - * @param {array} extraParams - * @param {array} extraHeaders - */ - sendMessage( - to: string, - message: string, - extraParams?: [], - extraHeaders?: [] - ) { - return this.smsClient.send(to, message); - } - - /** - * - * @param to - * @param message - * @returns - */ - sendMessageJob(to: string, message: string) { - const agenda = Container.get('agenda'); - - return agenda.now('sms-notification', { to, message }); - } -} diff --git a/packages/server/src/services/SMSClient/SMSClientInterface.ts b/packages/server/src/services/SMSClient/SMSClientInterface.ts deleted file mode 100644 index 8e1c0978b..000000000 --- a/packages/server/src/services/SMSClient/SMSClientInterface.ts +++ /dev/null @@ -1,5 +0,0 @@ - -export default interface SMSClientInterface { - clientName: string; - send(to: string, message: string): boolean; -} \ No newline at end of file diff --git a/packages/server/src/services/SMSClient/index.ts b/packages/server/src/services/SMSClient/index.ts deleted file mode 100644 index ae92b9bbc..000000000 --- a/packages/server/src/services/SMSClient/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import SMSAPI from './SMSAPI'; - -export default SMSAPI; \ No newline at end of file diff --git a/packages/server/src/services/Sales/AutoIncrementOrdersService.ts b/packages/server/src/services/Sales/AutoIncrementOrdersService.ts deleted file mode 100644 index a78acaa91..000000000 --- a/packages/server/src/services/Sales/AutoIncrementOrdersService.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { transactionIncrement, parseBoolean } from 'utils'; - -/** - * Auto increment orders service. - */ -@Service() -export default class AutoIncrementOrdersService { - @Inject() - tenancy: TenancyService; - - autoIncrementEnabled = (tenantId: number, settingsGroup: string): boolean => { - const settings = this.tenancy.settings(tenantId); - const group = settingsGroup; - - // Settings service transaction number and prefix. - return settings.get({ group, key: 'auto_increment' }, false); - }; - - /** - * Retrieve the next service transaction number. - * @param {number} tenantId - * @param {string} settingsGroup - * @param {Function} getMaxTransactionNo - * @return {Promise} - */ - getNextTransactionNumber(tenantId: number, group: string): string { - const settings = this.tenancy.settings(tenantId); - - // Settings service transaction number and prefix. - const autoIncrement = this.autoIncrementEnabled(tenantId, group); - - const settingNo = settings.get({ group, key: 'next_number' }, ''); - const settingPrefix = settings.get({ group, key: 'number_prefix' }, ''); - - return autoIncrement ? `${settingPrefix}${settingNo}` : ''; - } - - /** - * Increment setting next number. - * @param {number} tenantId - - * @param {string} orderGroup - Order group. - * @param {string} orderNumber -Order number. - */ - async incrementSettingsNextNumber(tenantId: number, group: string) { - const settings = this.tenancy.settings(tenantId); - - const settingNo = settings.get({ group, key: 'next_number' }); - const autoIncrement = settings.get({ group, key: 'auto_increment' }); - - // Can't continue if the auto-increment of the service was disabled. - if (!autoIncrement) { - return; - } - - settings.set( - { group, key: 'next_number' }, - transactionIncrement(settingNo) - ); - await settings.save(); - } -} diff --git a/packages/server/src/services/Sales/Estimates/ApproveSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/ApproveSaleEstimate.ts deleted file mode 100644 index e83009096..000000000 --- a/packages/server/src/services/Sales/Estimates/ApproveSaleEstimate.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { - ISaleEstimateApprovedEvent, - ISaleEstimateApprovingEvent, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { ERRORS } from './constants'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import moment from 'moment'; - -@Service() -export class ApproveSaleEstimate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Mark the sale estimate as approved from the customer. - * @param {number} tenantId - * @param {number} saleEstimateId - */ - public async approveSaleEstimate( - tenantId: number, - saleEstimateId: number - ): Promise { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Retrieve details of the given sale estimate id. - const oldSaleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .throwIfNotFound(); - - // Throws error in case the sale estimate still not delivered to customer. - if (!oldSaleEstimate.isDelivered) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_NOT_DELIVERED); - } - // Throws error in case the sale estimate already approved. - if (oldSaleEstimate.isApproved) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_ALREADY_APPROVED); - } - // Triggers `onSaleEstimateApproving` event. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleEstimateApproving` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onApproving, { - trx, - tenantId, - oldSaleEstimate, - } as ISaleEstimateApprovingEvent); - - // Update estimate as approved. - const saleEstimate = await SaleEstimate.query(trx) - .where('id', saleEstimateId) - .patch({ - approvedAt: moment().toMySqlDateTime(), - rejectedAt: null, - }); - // Triggers `onSaleEstimateApproved` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onApproved, { - trx, - tenantId, - oldSaleEstimate, - saleEstimate, - } as ISaleEstimateApprovedEvent); - }); - } -} diff --git a/packages/server/src/services/Sales/Estimates/ConvetSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/ConvetSaleEstimate.ts deleted file mode 100644 index 64a730f96..000000000 --- a/packages/server/src/services/Sales/Estimates/ConvetSaleEstimate.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { Knex } from 'knex'; -import moment from 'moment'; -import { Inject, Service } from 'typedi'; - -@Service() -export class ConvertSaleEstimate { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Converts estimate to invoice. - * @param {number} tenantId - - * @param {number} estimateId - - * @return {Promise} - */ - public async convertEstimateToInvoice( - tenantId: number, - estimateId: number, - invoiceId: number, - trx?: Knex.Transaction - ): Promise { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Retrieve details of the given sale estimate. - const saleEstimate = await SaleEstimate.query() - .findById(estimateId) - .throwIfNotFound(); - - // Marks the estimate as converted from the givne invoice. - await SaleEstimate.query(trx).where('id', estimateId).patch({ - convertedToInvoiceId: invoiceId, - convertedToInvoiceAt: moment().toMySqlDateTime(), - }); - // Triggers `onSaleEstimateConvertedToInvoice` event. - await this.eventPublisher.emitAsync( - events.saleEstimate.onConvertedToInvoice, - {} - ); - } -} diff --git a/packages/server/src/services/Sales/Estimates/CreateSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/CreateSaleEstimate.ts deleted file mode 100644 index c7fed6e36..000000000 --- a/packages/server/src/services/Sales/Estimates/CreateSaleEstimate.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { - ISaleEstimate, - ISaleEstimateCreatedPayload, - ISaleEstimateCreatingPayload, - ISaleEstimateDTO, -} from '@/interfaces'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { SaleEstimateDTOTransformer } from './SaleEstimateDTOTransformer'; -import events from '@/subscribers/events'; -import { SaleEstimateValidators } from './SaleEstimateValidators'; - -@Service() -export class CreateSaleEstimate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private transformerDTO: SaleEstimateDTOTransformer; - - @Inject() - private validators: SaleEstimateValidators; - - /** - * Creates a new estimate with associated entries. - * @async - * @param {number} tenantId - The tenant id. - * @param {EstimateDTO} estimate - * @return {Promise} - */ - public async createEstimate( - tenantId: number, - estimateDTO: ISaleEstimateDTO, - trx?: Knex.Transaction - ): Promise { - const { SaleEstimate, Contact } = this.tenancy.models(tenantId); - - // Retrieve the given customer or throw not found service error. - const customer = await Contact.query() - .modify('customer') - .findById(estimateDTO.customerId) - .throwIfNotFound(); - - // Transform DTO object ot model object. - const estimateObj = await this.transformerDTO.transformDTOToModel( - tenantId, - estimateDTO, - customer - ); - // Validate estimate number uniquiness on the storage. - await this.validators.validateEstimateNumberExistance( - tenantId, - estimateObj.estimateNumber - ); - // Validate items IDs existance on the storage. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - estimateDTO.entries - ); - // Validate non-sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - estimateDTO.entries - ); - // Creates a sale estimate transaction with associated transactions as UOW. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onSaleEstimateCreating` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onCreating, { - estimateDTO, - tenantId, - trx, - } as ISaleEstimateCreatingPayload); - - // Upsert the sale estimate graph to the storage. - const saleEstimate = await SaleEstimate.query(trx).upsertGraphAndFetch({ - ...estimateObj, - }); - // Triggers `onSaleEstimateCreated` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onCreated, { - tenantId, - saleEstimate, - saleEstimateId: saleEstimate.id, - saleEstimateDTO: estimateDTO, - trx, - } as ISaleEstimateCreatedPayload); - - return saleEstimate; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Sales/Estimates/DeleteSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/DeleteSaleEstimate.ts deleted file mode 100644 index 4cc17e926..000000000 --- a/packages/server/src/services/Sales/Estimates/DeleteSaleEstimate.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { - ISaleEstimateDeletedPayload, - ISaleEstimateDeletingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { ERRORS } from './constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { Knex } from 'knex'; - -@Service() -export class DeleteSaleEstimate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the given estimate id with associated entries. - * @async - * @param {number} tenantId - The tenant id. - * @param {IEstimate} estimateId - * @return {void} - */ - public async deleteEstimate( - tenantId: number, - estimateId: number - ): Promise { - const { SaleEstimate, ItemEntry } = this.tenancy.models(tenantId); - - // Retrieve sale estimate or throw not found service error. - const oldSaleEstimate = await SaleEstimate.query() - .findById(estimateId) - .throwIfNotFound(); - - // Throw error if the sale estimate converted to sale invoice. - if (oldSaleEstimate.convertedToInvoiceId) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_CONVERTED_TO_INVOICE); - } - // Updates the estimate with associated transactions under UOW enivrement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleEstimatedDeleting` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onDeleting, { - trx, - tenantId, - oldSaleEstimate, - } as ISaleEstimateDeletingPayload); - - // Delete sale estimate entries. - await ItemEntry.query(trx) - .where('reference_id', estimateId) - .where('reference_type', 'SaleEstimate') - .delete(); - - // Delete sale estimate transaction. - await SaleEstimate.query(trx).where('id', estimateId).delete(); - - // Triggers `onSaleEstimatedDeleted` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onDeleted, { - tenantId, - saleEstimateId: estimateId, - oldSaleEstimate, - trx, - } as ISaleEstimateDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/Estimates/DeliverSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/DeliverSaleEstimate.ts deleted file mode 100644 index 926715a5c..000000000 --- a/packages/server/src/services/Sales/Estimates/DeliverSaleEstimate.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { - ISaleEstimateEventDeliveredPayload, - ISaleEstimateEventDeliveringPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import moment from 'moment'; - -@Service() -export class DeliverSaleEstimate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Mark the sale estimate as delivered. - * @param {number} tenantId - Tenant id. - * @param {number} saleEstimateId - Sale estimate id. - */ - public async deliverSaleEstimate( - tenantId: number, - saleEstimateId: number - ): Promise { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Retrieve details of the given sale estimate id. - const oldSaleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .throwIfNotFound(); - - // Throws error in case the sale estimate already published. - if (oldSaleEstimate.isDelivered) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_ALREADY_DELIVERED); - } - // Updates the sale estimate transaction with assocaited transactions - // under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleEstimateDelivering` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onDelivering, { - oldSaleEstimate, - trx, - tenantId, - } as ISaleEstimateEventDeliveringPayload); - - // Record the delivered at on the storage. - const saleEstimate = await SaleEstimate.query(trx).patchAndFetchById( - saleEstimateId, - { - deliveredAt: moment().toMySqlDateTime(), - } - ); - // Triggers `onSaleEstimateDelivered` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onDelivered, { - tenantId, - saleEstimate, - trx, - } as ISaleEstimateEventDeliveredPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/Estimates/EditSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/EditSaleEstimate.ts deleted file mode 100644 index bbc73902c..000000000 --- a/packages/server/src/services/Sales/Estimates/EditSaleEstimate.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleEstimate, - ISaleEstimateDTO, - ISaleEstimateEditedPayload, - ISaleEstimateEditingPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { SaleEstimateValidators } from './SaleEstimateValidators'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { SaleEstimateDTOTransformer } from './SaleEstimateDTOTransformer'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import events from '@/subscribers/events'; - -@Service() -export class EditSaleEstimate { - @Inject() - private validators: SaleEstimateValidators; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private transformerDTO: SaleEstimateDTOTransformer; - - /** - * Edit details of the given estimate with associated entries. - * @async - * @param {number} tenantId - The tenant id. - * @param {Integer} estimateId - * @param {EstimateDTO} estimate - * @return {Promise} - */ - public async editEstimate( - tenantId: number, - estimateId: number, - estimateDTO: ISaleEstimateDTO - ): Promise { - const { SaleEstimate, Contact } = this.tenancy.models(tenantId); - - // Retrieve details of the given sale estimate id. - const oldSaleEstimate = await SaleEstimate.query().findById(estimateId); - - // Validates the given estimate existance. - this.validators.validateEstimateExistance(oldSaleEstimate); - - // Retrieve the given customer or throw not found service error. - const customer = await Contact.query() - .modify('customer') - .findById(estimateDTO.customerId) - .throwIfNotFound(); - - // Transform DTO object ot model object. - const estimateObj = await this.transformerDTO.transformDTOToModel( - tenantId, - estimateDTO, - oldSaleEstimate, - customer - ); - // Validate estimate number uniquiness on the storage. - if (estimateDTO.estimateNumber) { - await this.validators.validateEstimateNumberExistance( - tenantId, - estimateDTO.estimateNumber, - estimateId - ); - } - // Validate sale estimate entries existance. - await this.itemsEntriesService.validateEntriesIdsExistance( - tenantId, - estimateId, - 'SaleEstimate', - estimateDTO.entries - ); - // Validate items IDs existance on the storage. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - estimateDTO.entries - ); - // Validate non-sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - estimateDTO.entries - ); - // Edits estimate transaction with associated transactions - // under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx) => { - // Trigger `onSaleEstimateEditing` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onEditing, { - tenantId, - oldSaleEstimate, - estimateDTO, - trx, - } as ISaleEstimateEditingPayload); - - // Upsert the estimate graph to the storage. - const saleEstimate = await SaleEstimate.query(trx).upsertGraphAndFetch({ - id: estimateId, - ...estimateObj, - }); - // Trigger `onSaleEstimateEdited` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onEdited, { - tenantId, - estimateId, - saleEstimate, - oldSaleEstimate, - estimateDTO, - trx, - } as ISaleEstimateEditedPayload); - - return saleEstimate; - }); - } -} diff --git a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplate.ts b/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplate.ts deleted file mode 100644 index 11fb01bd0..000000000 --- a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplate.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - renderEstimateEmailTemplate, - EstimatePaymentEmailProps, -} from '@bigcapital/email-components'; -import { GetSaleEstimate } from './GetSaleEstimate'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetEstimateMailTemplateAttributesTransformer } from './GetEstimateMailTemplateAttributesTransformer'; -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; - -@Service() -export class GetEstimateMailTemplate { - @Inject() - private getEstimateService: GetSaleEstimate; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private getBrandingTemplate: GetPdfTemplate; - - /** - * Retrieves the mail template attributes of the given estimate. - * Estimate template attributes are composed of the estimate and branding template attributes. - * @param {number} tenantId - * @param {number} estimateId - Estimate id. - * @returns {Promise} - */ - public async getMailTemplateAttributes( - tenantId: number, - estimateId: number - ): Promise { - const estimate = await this.getEstimateService.getEstimate( - tenantId, - estimateId - ); - const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate( - tenantId, - estimate.pdfTemplateId - ); - const mailTemplateAttributes = await this.transformer.transform( - tenantId, - estimate, - new GetEstimateMailTemplateAttributesTransformer(), - { - estimate, - brandingTemplate, - } - ); - return mailTemplateAttributes; - } - - /** - * Rertieves the mail template html content. - * @param {number} tenantId - * @param {number} estimateId - * @param overrideAttributes - * @returns - */ - public async getMailTemplate( - tenantId: number, - estimateId: number, - overrideAttributes?: Partial - ): Promise { - const attributes = await this.getMailTemplateAttributes( - tenantId, - estimateId - ); - const mergedAttributes = { - ...attributes, - ...overrideAttributes, - }; - return renderEstimateEmailTemplate(mergedAttributes); - } -} diff --git a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts b/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts deleted file mode 100644 index 81d6d9a6c..000000000 --- a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetEstimateMailTemplateAttributesTransformer extends Transformer { - public includeAttributes = (): string[] => { - return [ - 'companyLogoUri', - 'companyName', - - 'estimateAmount', - - 'primaryColor', - - 'estimateAmount', - 'estimateMessage', - - 'dueDate', - 'dueDateLabel', - - 'estimateNumber', - 'estimateNumberLabel', - - 'total', - 'totalLabel', - - 'subtotal', - 'subtotalLabel', - - 'discount', - 'discountLabel', - - 'adjustment', - 'adjustmentLabel', - - 'dueAmount', - 'dueAmountLabel', - - 'viewEstimateButtonLabel', - 'viewEstimateButtonUrl', - - 'items', - ]; - }; - - /** - * Exclude all attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Company logo uri. - * @returns {string} - */ - public companyLogoUri(): string { - return this.options.brandingTemplate?.companyLogoUri; - } - - /** - * Company name. - * @returns {string} - */ - public companyName(): string { - return this.context.organization.name; - } - - /** - * Primary color. - * @returns {string} - */ - public primaryColor(): string { - return this.options?.brandingTemplate?.attributes?.primaryColor; - } - - /** - * Estimate number. - * @returns {string} - */ - public estimateNumber(): string { - return this.options.estimate.estimateNumber; - } - - /** - * Estimate number label. - * @returns {string} - */ - public estimateNumberLabel(): string { - return 'Estimate No: {estimateNumber}'; - } - - /** - * Expiration date. - * @returns {string} - */ - public expirationDate(): string { - return this.options.estimate.formattedExpirationDate; - } - - /** - * Expiration date label. - * @returns {string} - */ - public expirationDateLabel(): string { - return 'Expiration Date: {expirationDate}'; - } - - /** - * Estimate total. - */ - public total(): string { - return this.options.estimate.totalFormatted; - } - - /** - * Estimate total label. - * @returns {string} - */ - public totalLabel(): string { - return 'Total'; - } - - /** - * Estimate discount. - * @returns {string} - */ - public discount(): string { - return this.options.estimate?.discountAmountFormatted; - } - - /** - * Estimate discount label. - * @returns {string} - */ - public discountLabel(): string { - return 'Discount'; - } - - /** - * Estimate adjustment. - * @returns {string} - */ - public adjustment(): string { - return this.options.estimate?.adjustmentFormatted; - } - - /** - * Estimate adjustment label. - * @returns {string} - */ - public adjustmentLabel(): string { - return 'Adjustment'; - } - - /** - * Estimate subtotal. - */ - public subtotal(): string { - return this.options.estimate.formattedSubtotal; - } - - /** - * Estimate subtotal label. - * @returns {string} - */ - public subtotalLabel(): string { - return 'Subtotal'; - } - - /** - * Estimate mail items attributes. - */ - public items(): any[] { - return this.item( - this.options.estimate.entries, - new GetEstimateMailTemplateEntryAttributesTransformer() - ); - } -} - -class GetEstimateMailTemplateEntryAttributesTransformer extends Transformer { - public includeAttributes = (): string[] => { - return ['label', 'quantity', 'rate', 'total']; - }; - - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public label(entry): string { - return entry?.item?.name; - } - - public quantity(entry): string { - return entry?.quantity; - } - - public rate(entry): string { - return entry?.rateFormatted; - } - - public total(entry): string { - return entry?.totalFormatted; - } -} diff --git a/packages/server/src/services/Sales/Estimates/GetSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/GetSaleEstimate.ts deleted file mode 100644 index 644950188..000000000 --- a/packages/server/src/services/Sales/Estimates/GetSaleEstimate.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { SaleEstimateTransfromer } from './SaleEstimateTransformer'; -import { SaleEstimateValidators } from './SaleEstimateValidators'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class GetSaleEstimate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private validators: SaleEstimateValidators; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve the estimate details with associated entries. - * @async - * @param {number} tenantId - The tenant id. - * @param {Integer} estimateId - */ - public async getEstimate(tenantId: number, estimateId: number) { - const { SaleEstimate } = this.tenancy.models(tenantId); - - const estimate = await SaleEstimate.query() - .findById(estimateId) - .withGraphFetched('entries.item') - .withGraphFetched('customer') - .withGraphFetched('branch') - .withGraphFetched('attachments'); - - // Validates the estimate existance. - this.validators.validateEstimateExistance(estimate); - - // Transformes sale estimate model to POJO. - const transformed = await this.transformer.transform( - tenantId, - estimate, - new SaleEstimateTransfromer() - ); - const eventPayload = { tenantId, saleEstimateId: estimateId }; - - // Triggers `onSaleEstimateViewed` event. - await this.eventPublisher.emitAsync( - events.saleEstimate.onViewed, - eventPayload - ); - return transformed; - } -} diff --git a/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailState.ts b/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailState.ts deleted file mode 100644 index bc5e2f227..000000000 --- a/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailState.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { SendSaleEstimateMail } from './SendSaleEstimateMail'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { GetSaleEstimateMailStateTransformer } from './GetSaleEstimateMailStateTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetSaleEstimateMailState { - @Inject() - private estimateMail: SendSaleEstimateMail; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the estimate mail state of the given sale estimate. - * Estimate mail state includes the mail options, branding attributes and the estimate details. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - async getEstimateMailState( - tenantId: number, - saleEstimateId: number - ): Promise { - const { SaleEstimate } = this.tenancy.models(tenantId); - - const saleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .withGraphFetched('customer') - .withGraphFetched('entries.item') - .withGraphFetched('pdfTemplate') - .throwIfNotFound(); - - const mailOptions = await this.estimateMail.getMailOptions( - tenantId, - saleEstimateId - ); - const transformed = await this.transformer.transform( - tenantId, - saleEstimate, - new GetSaleEstimateMailStateTransformer(), - { - mailOptions, - } - ); - return transformed; - } -} diff --git a/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts b/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts deleted file mode 100644 index 06fdf5436..000000000 --- a/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { ItemEntryTransformer } from '../Invoices/ItemEntryTransformer'; -import { SaleEstimateTransfromer } from './SaleEstimateTransformer'; - -export class GetSaleEstimateMailStateTransformer extends SaleEstimateTransfromer { - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public includeAttributes = (): string[] => { - return [ - 'estimateDate', - 'estimateDateFormatted', - - 'expirationDate', - 'expirationDateFormatted', - - 'total', - 'totalFormatted', - - 'subtotal', - 'subtotalFormatted', - - 'discountAmount', - 'discountAmountFormatted', - 'discountPercentage', - 'discountPercentageFormatted', - 'discountLabel', - - 'adjustment', - 'adjustmentFormatted', - 'adjustmentLabel', - - 'estimateNumber', - 'entries', - - 'companyName', - 'companyLogoUri', - - 'primaryColor', - 'customerName', - ]; - }; - - /** - * Retrieves the customer name of the invoice. - * @returns {string} - */ - protected customerName = (invoice) => { - return invoice.customer.displayName; - }; - - /** - * Retrieves the company name. - * @returns {string} - */ - protected companyName = () => { - return this.context.organization.name; - }; - - /** - * Retrieves the company logo uri. - * @returns {string | null} - */ - protected companyLogoUri = (invoice) => { - return invoice.pdfTemplate?.companyLogoUri || null; - }; - - /** - * Retrieves the primary color. - * @returns {string} - */ - protected primaryColor = (invoice) => { - return invoice.pdfTemplate?.attributes?.primaryColor || null; - }; - - /** - * Retrieves the estimate number. - */ - protected estimateDateFormatted = (estimate) => { - return this.formattedEstimateDate(estimate); - }; - - /** - * Retrieves the expiration date of the estimate. - * @param estimate - * @returns {string} - */ - protected expirationDateFormatted = (estimate) => { - return this.formattedExpirationDate(estimate); - }; - - /** - * Retrieves the total amount of the estimate. - * @param estimate - * @returns - */ - protected total(estimate) { - return estimate.amount; - } - - /** - * Retrieves the subtotal amount of the estimate. - * @param estimate - * @returns {number} - */ - protected subtotal(estimate) { - return estimate.amount; - } - - /** - * Retrieves the discount label of the estimate. - * @param estimate - * @returns {string} - */ - protected discountLabel(estimate) { - return estimate.discountType === 'percentage' - ? `Discount [${estimate.discountPercentageFormatted}]` - : 'Discount'; - } - - /** - * Retrieves the formatted subtotal of the estimate. - * @param estimate - * @returns {string} - */ - protected subtotalFormatted = (estimate) => { - return this.formattedSubtotal(estimate); - }; - - /** - * Retrieves the estimate entries. - * @param invoice - * @returns {Array} - */ - protected entries = (invoice) => { - return this.item( - invoice.entries, - new GetSaleEstimateMailStateEntryTransformer(), - { - currencyCode: invoice.currencyCode, - } - ); - }; - - /** - * Merges the mail options with the invoice object. - */ - public transform = (object: any) => { - return { - ...this.options.mailOptions, - ...object, - }; - }; -} - -class GetSaleEstimateMailStateEntryTransformer extends ItemEntryTransformer { - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Item name. - * @param entry - * @returns - */ - public name = (entry) => { - return entry.item.name; - }; - - public includeAttributes = (): string[] => { - return [ - 'name', - 'quantity', - 'unitPrice', - 'unitPriceFormatted', - 'total', - 'totalFormatted', - ]; - }; -} diff --git a/packages/server/src/services/Sales/Estimates/GetSaleEstimateState.ts b/packages/server/src/services/Sales/Estimates/GetSaleEstimateState.ts deleted file mode 100644 index 146f1a405..000000000 --- a/packages/server/src/services/Sales/Estimates/GetSaleEstimateState.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISaleEstimateState } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class GetSaleEstimateState { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the create/edit sale estimate state. - * @param {Number} saleEstimateId - - * @return {Promise} - */ - public async getSaleEstimateState( - tenantId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const defaultPdfTemplate = await PdfTemplate.query() - .findOne({ resource: 'SaleEstimate' }) - .modify('default'); - - return { - defaultTemplateId: defaultPdfTemplate?.id, - }; - } -} diff --git a/packages/server/src/services/Sales/Estimates/GetSaleEstimates.ts b/packages/server/src/services/Sales/Estimates/GetSaleEstimates.ts deleted file mode 100644 index c530dc857..000000000 --- a/packages/server/src/services/Sales/Estimates/GetSaleEstimates.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as R from 'ramda'; -import { Inject, Service } from 'typedi'; -import { - IFilterMeta, - IPaginationMeta, - ISaleEstimate, - ISalesEstimatesFilter, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { SaleEstimateDTOTransformer } from './SaleEstimateDTOTransformer'; -import { SaleEstimateTransfromer } from './SaleEstimateTransformer'; - -@Service() -export class GetSaleEstimates { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves estimates filterable and paginated list. - * @param {number} tenantId - - * @param {IEstimatesFilter} estimatesFilter - - */ - public async getEstimates( - tenantId: number, - filterDTO: ISalesEstimatesFilter - ): Promise<{ - salesEstimates: ISaleEstimate[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Parses filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - SaleEstimate, - filter - ); - const { results, pagination } = await SaleEstimate.query() - .onBuild((builder) => { - builder.withGraphFetched('customer'); - builder.withGraphFetched('entries'); - builder.withGraphFetched('entries.item'); - dynamicFilter.buildQuery()(builder); - filterDTO?.filterQuery && filterDTO?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - const transformedEstimates = await this.transformer.transform( - tenantId, - results, - new SaleEstimateTransfromer() - ); - return { - salesEstimates: transformedEstimates, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - } - - /** - * Parses the sale receipts list filter DTO. - * @param filterDTO - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Sales/Estimates/RejectSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/RejectSaleEstimate.ts deleted file mode 100644 index 2ded056ef..000000000 --- a/packages/server/src/services/Sales/Estimates/RejectSaleEstimate.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class RejectSaleEstimate { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Mark the sale estimate as rejected from the customer. - * @param {number} tenantId - * @param {number} saleEstimateId - */ - public async rejectSaleEstimate( - tenantId: number, - saleEstimateId: number - ): Promise { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Retrieve details of the given sale estimate id. - const saleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .throwIfNotFound(); - - // Throws error in case the sale estimate still not delivered to customer. - if (!saleEstimate.isDelivered) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_NOT_DELIVERED); - } - // Throws error in case the sale estimate already rejected. - if (saleEstimate.isRejected) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_ALREADY_REJECTED); - } - // - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Mark the sale estimate as reject on the storage. - await SaleEstimate.query(trx).where('id', saleEstimateId).patch({ - rejectedAt: moment().toMySqlDateTime(), - approvedAt: null, - }); - // Triggers `onSaleEstimateRejected` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onRejected, {}); - }); - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimateDTOTransformer.ts b/packages/server/src/services/Sales/Estimates/SaleEstimateDTOTransformer.ts deleted file mode 100644 index 32b1245bd..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimateDTOTransformer.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as R from 'ramda'; -import { Inject, Service } from 'typedi'; -import { omit, sumBy } from 'lodash'; -import composeAsync from 'async/compose'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ICustomer, ISaleEstimate, ISaleEstimateDTO } from '@/interfaces'; -import { SaleEstimateValidators } from './SaleEstimateValidators'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import { formatDateFields } from '@/utils'; -import moment from 'moment'; -import { SaleEstimateIncrement } from './SaleEstimateIncrement'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; -import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer'; - -@Service() -export class SaleEstimateDTOTransformer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: SaleEstimateValidators; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - @Inject() - private estimateIncrement: SaleEstimateIncrement; - - @Inject() - private brandingTemplatesTransformer: BrandingTemplateDTOTransformer; - - /** - * Transform create DTO object ot model object. - * @param {number} tenantId - * @param {ISaleEstimateDTO} saleEstimateDTO - Sale estimate DTO. - * @return {ISaleEstimate} - */ - async transformDTOToModel( - tenantId: number, - estimateDTO: ISaleEstimateDTO, - paymentCustomer: ICustomer, - oldSaleEstimate?: ISaleEstimate - ): Promise { - const { ItemEntry, Contact } = this.tenancy.models(tenantId); - - const amount = sumBy(estimateDTO.entries, (e) => ItemEntry.calcAmount(e)); - - // Retreive the next invoice number. - const autoNextNumber = - this.estimateIncrement.getNextEstimateNumber(tenantId); - - // Retreive the next estimate number. - const estimateNumber = - estimateDTO.estimateNumber || - oldSaleEstimate?.estimateNumber || - autoNextNumber; - - // Validate the sale estimate number require. - this.validators.validateEstimateNoRequire(estimateNumber); - - const entries = R.compose( - // Associate the reference type to item entries. - R.map((entry) => R.assoc('reference_type', 'SaleEstimate', entry)), - - // Associate default index to item entries. - assocItemEntriesDefaultIndex - )(estimateDTO.entries); - - const initialDTO = { - amount, - ...formatDateFields( - omit(estimateDTO, ['delivered', 'entries', 'attachments']), - ['estimateDate', 'expirationDate'] - ), - currencyCode: paymentCustomer.currencyCode, - exchangeRate: estimateDTO.exchangeRate || 1, - ...(estimateNumber ? { estimateNumber } : {}), - entries, - // Avoid rewrite the deliver date in edit mode when already published. - ...(estimateDTO.delivered && - !oldSaleEstimate?.deliveredAt && { - deliveredAt: moment().toMySqlDateTime(), - }), - }; - const initialAsyncDTO = await composeAsync( - // Assigns the default branding template id to the invoice DTO. - this.brandingTemplatesTransformer.assocDefaultBrandingTemplate( - tenantId, - 'SaleEstimate' - ) - )(initialDTO); - - return R.compose( - this.branchDTOTransform.transformDTO(tenantId), - this.warehouseDTOTransform.transformDTO(tenantId) - )(initialAsyncDTO); - } - - /** - * Retrieve estimate number to object model. - * @param {number} tenantId - * @param {ISaleEstimateDTO} saleEstimateDTO - * @param {ISaleEstimate} oldSaleEstimate - */ - public transformEstimateNumberToModel( - tenantId: number, - saleEstimateDTO: ISaleEstimateDTO, - oldSaleEstimate?: ISaleEstimate - ): string { - // Retreive the next invoice number. - const autoNextNumber = - this.estimateIncrement.getNextEstimateNumber(tenantId); - - if (saleEstimateDTO.estimateNumber) { - return saleEstimateDTO.estimateNumber; - } - return oldSaleEstimate ? oldSaleEstimate.estimateNumber : autoNextNumber; - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimateIncrement.ts b/packages/server/src/services/Sales/Estimates/SaleEstimateIncrement.ts deleted file mode 100644 index d3928b06e..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimateIncrement.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import AutoIncrementOrdersService from '../AutoIncrementOrdersService'; - -@Service() -export class SaleEstimateIncrement { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - /** - * Retrieve the next unique estimate number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - public getNextEstimateNumber(tenantId: number): string { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'sales_estimates' - ); - } - - /** - * Increment the estimate next number. - * @param {number} tenantId - - */ - public incrementNextEstimateNumber(tenantId: number) { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'sales_estimates' - ); - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimateSmsNotify.ts b/packages/server/src/services/Sales/Estimates/SaleEstimateSmsNotify.ts deleted file mode 100644 index d90d11769..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimateSmsNotify.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import SaleNotifyBySms from '../SaleNotifyBySms'; -import SmsNotificationsSettingsService from '@/services/Settings/SmsNotificationsSettings'; -import { - ICustomer, - IPaymentReceivedSmsDetails, - ISaleEstimate, - SMS_NOTIFICATION_KEY, -} from '@/interfaces'; -import { Tenant, TenantMetadata } from '@/system/models'; -import { formatNumber, formatSmsMessage } from 'utils'; -import { ServiceError } from '@/exceptions'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -const ERRORS = { - SALE_ESTIMATE_NOT_FOUND: 'SALE_ESTIMATE_NOT_FOUND', -}; - -@Service() -export class SaleEstimateNotifyBySms { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private saleSmsNotification: SaleNotifyBySms; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private smsNotificationsSettings: SmsNotificationsSettingsService; - - /** - * - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public notifyBySms = async ( - tenantId: number, - saleEstimateId: number - ): Promise => { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const saleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .withGraphFetched('customer'); - - // Validates the estimate transaction existance. - this.validateEstimateExistance(saleEstimate); - - // Validate the customer phone number existance and number validation. - this.saleSmsNotification.validateCustomerPhoneNumber( - saleEstimate.customer.personalPhone - ); - // Triggers `onSaleEstimateNotifySms` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onNotifySms, { - tenantId, - saleEstimate, - }); - await this.sendSmsNotification(tenantId, saleEstimate); - - // Triggers `onSaleEstimateNotifySms` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onNotifiedSms, { - tenantId, - saleEstimate, - }); - return saleEstimate; - }; - - /** - * - * @param {number} tenantId - * @param {ISaleEstimate} saleEstimate - * @returns - */ - private sendSmsNotification = async ( - tenantId: number, - saleEstimate: ISaleEstimate & { customer: ICustomer } - ) => { - const smsClient = this.tenancy.smsClient(tenantId); - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieve the formatted sms notification message for estimate details. - const formattedSmsMessage = this.formattedEstimateDetailsMessage( - tenantId, - saleEstimate, - tenantMetadata - ); - const phoneNumber = saleEstimate.customer.personalPhone; - - // Runs the send message job. - return smsClient.sendMessageJob(phoneNumber, formattedSmsMessage); - }; - - /** - * Notify via SMS message after estimate creation. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public notifyViaSmsNotificationAfterCreation = async ( - tenantId: number, - saleEstimateId: number - ): Promise => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.SALE_ESTIMATE_DETAILS - ); - // Can't continue if the sms auto-notification is not enabled. - if (!notification.isNotificationEnabled) return; - - await this.notifyBySms(tenantId, saleEstimateId); - }; - - /** - * - * @param {number} tenantId - * @param {ISaleEstimate} saleEstimate - * @param {TenantMetadata} tenantMetadata - * @returns {string} - */ - private formattedEstimateDetailsMessage = ( - tenantId: number, - saleEstimate: ISaleEstimate, - tenantMetadata: TenantMetadata - ): string => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.SALE_ESTIMATE_DETAILS - ); - return this.formateEstimateDetailsMessage( - notification.smsMessage, - saleEstimate, - tenantMetadata - ); - }; - - /** - * Formattes the estimate sms notification details message. - * @param {string} smsMessage - * @param {ISaleEstimate} saleEstimate - * @param {TenantMetadata} tenantMetadata - * @returns {string} - */ - private formateEstimateDetailsMessage = ( - smsMessage: string, - saleEstimate: ISaleEstimate & { customer: ICustomer }, - tenantMetadata: TenantMetadata - ) => { - const formattedAmount = formatNumber(saleEstimate.amount, { - currencyCode: saleEstimate.currencyCode, - }); - - return formatSmsMessage(smsMessage, { - EstimateNumber: saleEstimate.estimateNumber, - ReferenceNumber: saleEstimate.reference, - EstimateDate: moment(saleEstimate.estimateDate).format('YYYY/MM/DD'), - ExpirationDate: saleEstimate.expirationDate - ? moment(saleEstimate.expirationDate).format('YYYY/MM/DD') - : '', - CustomerName: saleEstimate.customer.displayName, - Amount: formattedAmount, - CompanyName: tenantMetadata.name, - }); - }; - - /** - * Retrieve the SMS details of the given payment receive transaction. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public smsDetails = async ( - tenantId: number, - saleEstimateId: number - ): Promise => { - const { SaleEstimate } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const saleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .withGraphFetched('customer'); - - // Validates the estimate existance. - this.validateEstimateExistance(saleEstimate); - - // Retrieve the current tenant metadata. - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieve the formatted sms message from the given estimate model. - const formattedSmsMessage = this.formattedEstimateDetailsMessage( - tenantId, - saleEstimate, - tenantMetadata - ); - return { - customerName: saleEstimate.customer.displayName, - customerPhoneNumber: saleEstimate.customer.personalPhone, - smsMessage: formattedSmsMessage, - }; - }; - - /** - * Validates the sale estimate existance. - * @param {ISaleEstimate} saleEstimate - - */ - private validateEstimateExistance(saleEstimate: ISaleEstimate) { - if (!saleEstimate) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts b/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts deleted file mode 100644 index 91e7d0ab5..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { ISaleEstimate } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { ItemEntryTransformer } from '../Invoices/ItemEntryTransformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; - -export class SaleEstimateTransfromer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'formattedSubtotal', - 'formattedAmount', - 'formattedEstimateDate', - 'formattedExpirationDate', - 'formattedDeliveredAtDate', - 'formattedApprovedAtDate', - 'formattedRejectedAtDate', - 'discountAmountFormatted', - 'discountPercentageFormatted', - 'adjustmentFormatted', - 'totalFormatted', - 'totalLocalFormatted', - 'formattedCreatedAt', - 'entries', - 'attachments', - ]; - }; - - /** - * Retrieve formatted estimate date. - * @param {ISaleEstimate} invoice - * @returns {String} - */ - protected formattedEstimateDate = (estimate: ISaleEstimate): string => { - return this.formatDate(estimate.estimateDate); - }; - - /** - * Retrieve formatted estimate date. - * @param {ISaleEstimate} invoice - * @returns {String} - */ - protected formattedExpirationDate = (estimate: ISaleEstimate): string => { - return this.formatDate(estimate.expirationDate); - }; - - /** - * Retrieves the formatted estimate created at. - * @param {ISaleEstimate} estimate - - * @returns {string} - */ - protected formattedCreatedAt = (estimate: ISaleEstimate): string => { - return this.formatDate(estimate.createdAt); - }; - - /** - * Retrieve formatted estimate date. - * @param {ISaleEstimate} invoice - * @returns {String} - */ - protected formattedDeliveredAtDate = (estimate: ISaleEstimate): string => { - return this.formatDate(estimate.deliveredAt); - }; - - /** - * Retrieve formatted estimate date. - * @param {ISaleEstimate} invoice - * @returns {String} - */ - protected formattedApprovedAtDate = (estimate: ISaleEstimate): string => { - return this.formatDate(estimate.approvedAt); - }; - - /** - * Retrieve formatted estimate date. - * @param {ISaleEstimate} invoice - * @returns {String} - */ - protected formattedRejectedAtDate = (estimate: ISaleEstimate): string => { - return this.formatDate(estimate.rejectedAt); - }; - - /** - * Retrieve formatted invoice amount. - * @param {ISaleEstimate} estimate - * @returns {string} - */ - protected formattedAmount = (estimate: ISaleEstimate): string => { - return formatNumber(estimate.amount, { - currencyCode: estimate.currencyCode, - }); - }; - - /** - * Retrieves the formatted invoice subtotal. - * @param {ISaleEstimate} estimate - * @returns {string} - */ - protected formattedSubtotal = (estimate: ISaleEstimate): string => { - return formatNumber(estimate.amount, { money: false }); - }; - - /** - * Retrieves formatted discount amount. - * @param estimate - * @returns {string} - */ - protected discountAmountFormatted = (estimate: ISaleEstimate): string => { - return formatNumber(estimate.discountAmount, { - currencyCode: estimate.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves formatted discount percentage. - * @param estimate - * @returns {string} - */ - protected discountPercentageFormatted = (estimate: ISaleEstimate): string => { - return estimate.discountPercentage - ? `${estimate.discountPercentage}%` - : ''; - }; - - /** - * Retrieves formatted adjustment amount. - * @param estimate - * @returns {string} - */ - protected adjustmentFormatted = (estimate: ISaleEstimate): string => { - return this.formatMoney(estimate.adjustment, { - currencyCode: estimate.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the formatted estimate total. - * @returns {string} - */ - protected totalFormatted = (estimate: ISaleEstimate): string => { - return this.formatMoney(estimate.total, { - currencyCode: estimate.currencyCode, - }); - }; - - /** - * Retrieves the formatted estimate total in local currency. - * @param estimate - * @returns {string} - */ - protected totalLocalFormatted = (estimate: ISaleEstimate): string => { - return this.formatMoney(estimate.totalLocal, { - currencyCode: estimate.currencyCode, - }); - }; - - /** - * Retrieves the entries of the sale estimate. - * @param {ISaleEstimate} estimate - * @returns {} - */ - protected entries = (estimate: ISaleEstimate) => { - return this.item(estimate.entries, new ItemEntryTransformer(), { - currencyCode: estimate.currencyCode, - }); - }; - - /** - * Retrieves the sale estimate attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (estimate: ISaleEstimate) => { - return this.item(estimate.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimateValidators.ts b/packages/server/src/services/Sales/Estimates/SaleEstimateValidators.ts deleted file mode 100644 index b37ca1298..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimateValidators.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ISaleEstimate } from '@/interfaces'; -import { ERRORS } from './constants'; -import { SaleEstimate } from '@/models'; - -@Service() -export class SaleEstimateValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates the given estimate existance. - * @param {SaleEstimate | undefined | null} estimate - - */ - public validateEstimateExistance(estimate: SaleEstimate | undefined | null) { - if (!estimate) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_NOT_FOUND); - } - } - - /** - * Validate the estimate number unique on the storage. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - public async validateEstimateNumberExistance( - tenantId: number, - estimateNumber: string, - notEstimateId?: number - ) { - const { SaleEstimate } = this.tenancy.models(tenantId); - - const foundSaleEstimate = await SaleEstimate.query() - .findOne('estimate_number', estimateNumber) - .onBuild((builder) => { - if (notEstimateId) { - builder.whereNot('id', notEstimateId); - } - }); - if (foundSaleEstimate) { - throw new ServiceError( - ERRORS.SALE_ESTIMATE_NUMBER_EXISTANCE, - 'The given sale estimate is not unique.' - ); - } - } - - /** - * Validates the given sale estimate not already converted to invoice. - * @param {ISaleEstimate} saleEstimate - - */ - public validateEstimateNotConverted(saleEstimate: ISaleEstimate) { - if (saleEstimate.isConvertedToInvoice) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_CONVERTED_TO_INVOICE); - } - } - - /** - * Validate the sale estimate number require. - * @param {ISaleEstimate} saleInvoiceObj - */ - public validateEstimateNoRequire(estimateNumber: string) { - if (!estimateNumber) { - throw new ServiceError(ERRORS.SALE_ESTIMATE_NO_IS_REQUIRED); - } - } - - /** - * Validate the given customer has no sales estimates. - * @param {number} tenantId - * @param {number} customerId - Customer id. - */ - public async validateCustomerHasNoEstimates( - tenantId: number, - customerId: number - ) { - const { SaleEstimate } = this.tenancy.models(tenantId); - - const estimates = await SaleEstimate.query().where( - 'customer_id', - customerId - ); - if (estimates.length > 0) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_SALES_ESTIMATES); - } - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimatesApplication.ts b/packages/server/src/services/Sales/Estimates/SaleEstimatesApplication.ts deleted file mode 100644 index ec7c6afa8..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimatesApplication.ts +++ /dev/null @@ -1,297 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CreateSaleEstimate } from './CreateSaleEstimate'; -import { - IFilterMeta, - IPaginationMeta, - IPaymentReceivedSmsDetails, - ISaleEstimate, - ISaleEstimateDTO, - ISalesEstimatesFilter, - SaleEstimateMailOptions, - SaleEstimateMailOptionsDTO, -} from '@/interfaces'; -import { EditSaleEstimate } from './EditSaleEstimate'; -import { DeleteSaleEstimate } from './DeleteSaleEstimate'; -import { GetSaleEstimate } from './GetSaleEstimate'; -import { GetSaleEstimates } from './GetSaleEstimates'; -import { DeliverSaleEstimate } from './DeliverSaleEstimate'; -import { ApproveSaleEstimate } from './ApproveSaleEstimate'; -import { RejectSaleEstimate } from './RejectSaleEstimate'; -import { SaleEstimateNotifyBySms } from './SaleEstimateSmsNotify'; -import { SaleEstimatesPdf } from './SaleEstimatesPdf'; -import { SendSaleEstimateMail } from './SendSaleEstimateMail'; -import { GetSaleEstimateState } from './GetSaleEstimateState'; -import { GetSaleEstimateMailState } from './GetSaleEstimateMailState'; - -@Service() -export class SaleEstimatesApplication { - @Inject() - private createSaleEstimateService: CreateSaleEstimate; - - @Inject() - private editSaleEstimateService: EditSaleEstimate; - - @Inject() - private deleteSaleEstimateService: DeleteSaleEstimate; - - @Inject() - private getSaleEstimateService: GetSaleEstimate; - - @Inject() - private getSaleEstimatesService: GetSaleEstimates; - - @Inject() - private deliverSaleEstimateService: DeliverSaleEstimate; - - @Inject() - private approveSaleEstimateService: ApproveSaleEstimate; - - @Inject() - private rejectSaleEstimateService: RejectSaleEstimate; - - @Inject() - private saleEstimateNotifyBySmsService: SaleEstimateNotifyBySms; - - @Inject() - private saleEstimatesPdfService: SaleEstimatesPdf; - - @Inject() - private sendEstimateMailService: SendSaleEstimateMail; - - @Inject() - private getSaleEstimateMailStateService: GetSaleEstimateMailState; - - @Inject() - private getSaleEstimateStateService: GetSaleEstimateState; - - /** - * Create a sale estimate. - * @param {number} tenantId - The tenant id. - * @param {EstimateDTO} estimate - * @return {Promise} - */ - public createSaleEstimate( - tenantId: number, - estimateDTO: ISaleEstimateDTO - ): Promise { - return this.createSaleEstimateService.createEstimate(tenantId, estimateDTO); - } - - /** - * Edit the given sale estimate. - * @param {number} tenantId - The tenant id. - * @param {Integer} estimateId - * @param {EstimateDTO} estimate - * @return {Promise} - */ - public editSaleEstimate( - tenantId: number, - estimateId: number, - estimateDTO: ISaleEstimateDTO - ): Promise { - return this.editSaleEstimateService.editEstimate( - tenantId, - estimateId, - estimateDTO - ); - } - - /** - * Deletes the given sale estimate. - * @param {number} tenantId - - * @param {number} estimateId - - * @return {Promise} - */ - public deleteSaleEstimate( - tenantId: number, - estimateId: number - ): Promise { - return this.deleteSaleEstimateService.deleteEstimate(tenantId, estimateId); - } - - /** - * Retrieves the given sale estimate. - * @param {number} tenantId - * @param {number} estimateId - */ - public getSaleEstimate(tenantId: number, estimateId: number) { - return this.getSaleEstimateService.getEstimate(tenantId, estimateId); - } - - /** - * Retrieves the sale estimate. - * @param {number} tenantId - * @param {ISalesEstimatesFilter} filterDTO - * @returns - */ - public getSaleEstimates( - tenantId: number, - filterDTO: ISalesEstimatesFilter - ): Promise<{ - salesEstimates: ISaleEstimate[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - return this.getSaleEstimatesService.getEstimates(tenantId, filterDTO); - } - - /** - * Deliver the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public deliverSaleEstimate(tenantId: number, saleEstimateId: number) { - return this.deliverSaleEstimateService.deliverSaleEstimate( - tenantId, - saleEstimateId - ); - } - - /** - * Approve the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public approveSaleEstimate( - tenantId: number, - saleEstimateId: number - ): Promise { - return this.approveSaleEstimateService.approveSaleEstimate( - tenantId, - saleEstimateId - ); - } - - /** - * Mark the sale estimate as rejected from the customer. - * @param {number} tenantId - * @param {number} saleEstimateId - */ - public async rejectSaleEstimate( - tenantId: number, - saleEstimateId: number - ): Promise { - return this.rejectSaleEstimateService.rejectSaleEstimate( - tenantId, - saleEstimateId - ); - } - - /** - * Notify the customer of the given sale estimate by SMS. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public notifySaleEstimateBySms = async ( - tenantId: number, - saleEstimateId: number - ): Promise => { - return this.saleEstimateNotifyBySmsService.notifyBySms( - tenantId, - saleEstimateId - ); - }; - - /** - * Retrieve the SMS details of the given payment receive transaction. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public getSaleEstimateSmsDetails = ( - tenantId: number, - saleEstimateId: number - ): Promise => { - return this.saleEstimateNotifyBySmsService.smsDetails( - tenantId, - saleEstimateId - ); - }; - - /** - * Retrieve the PDF content of the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns - */ - public getSaleEstimatePdf(tenantId: number, saleEstimateId: number) { - return this.saleEstimatesPdfService.getSaleEstimatePdf( - tenantId, - saleEstimateId - ); - } - - /** - * Retrieve the HTML content of the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - */ - public getSaleEstimateHtml(tenantId: number, saleEstimateId: number) { - return this.saleEstimatesPdfService.saleEstimateHtml( - tenantId, - saleEstimateId - ); - } - - /** - * Send the reminder mail of the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public sendSaleEstimateMail( - tenantId: number, - saleEstimateId: number, - saleEstimateMailOpts: SaleEstimateMailOptionsDTO - ): Promise { - return this.sendEstimateMailService.triggerMail( - tenantId, - saleEstimateId, - saleEstimateMailOpts - ); - } - - /** - * Retrieves the sale estimate mail state. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public getSaleEstimateMailState( - tenantId: number, - saleEstimateId: number - ): Promise { - return this.getSaleEstimateMailStateService.getEstimateMailState( - tenantId, - saleEstimateId - ); - } - - /** - * Retrieves the default mail options of the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public getSaleEstimateMail( - tenantId: number, - saleEstimateId: number - ): Promise { - return this.sendEstimateMailService.getMailOptions( - tenantId, - saleEstimateId - ); - } - - /** - * Retrieves the current state of the sale estimate. - * @param {number} tenantId - The ID of the tenant. - * @returns {Promise} - A promise resolving to the sale estimate state. - */ - public getSaleEstimateState(tenantId: number) { - return this.getSaleEstimateStateService.getSaleEstimateState(tenantId); - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimatesExportable.ts b/packages/server/src/services/Sales/Estimates/SaleEstimatesExportable.ts deleted file mode 100644 index b4ddafabf..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimatesExportable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISalesInvoicesFilter } from '@/interfaces'; -import { Exportable } from '@/services/Export/Exportable'; -import { SaleEstimatesApplication } from './SaleEstimatesApplication'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class SaleEstimatesExportable extends Exportable { - @Inject() - private saleEstimatesApplication: SaleEstimatesApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: ISalesInvoicesFilter) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - query.withGraphFetched('warehouse'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery, - } as ISalesInvoicesFilter; - - return this.saleEstimatesApplication - .getSaleEstimates(tenantId, parsedQuery) - .then((output) => output.salesEstimates); - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimatesImportable.ts b/packages/server/src/services/Sales/Estimates/SaleEstimatesImportable.ts deleted file mode 100644 index d0bcdaf9e..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimatesImportable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ISaleEstimateDTO } from '@/interfaces'; -import { CreateSaleEstimate } from './CreateSaleEstimate'; -import { Importable } from '@/services/Import/Importable'; -import { SaleEstimatesSampleData } from './constants'; - -@Service() -export class SaleEstimatesImportable extends Importable { - @Inject() - private createEstimateService: CreateSaleEstimate; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createEstimateDTO: ISaleEstimateDTO, - trx?: Knex.Transaction - ) { - return this.createEstimateService.createEstimate( - tenantId, - createEstimateDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return SaleEstimatesSampleData; - } -} diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts b/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts deleted file mode 100644 index 4cb6c8f3b..000000000 --- a/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy'; -import { GetSaleEstimate } from './GetSaleEstimate'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { SaleEstimatePdfTemplate } from '../Invoices/SaleEstimatePdfTemplate'; -import { transformEstimateToPdfTemplate } from './utils'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { renderEstimatePaperTemplateHtml, EstimatePaperTemplateProps } from '@bigcapital/pdf-templates'; - -@Service() -export class SaleEstimatesPdf { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - @Inject() - private getSaleEstimate: GetSaleEstimate; - - @Inject() - private estimatePdfTemplate: SaleEstimatePdfTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve sale estimate html content. - * @param {number} tenantId - - * @param {number} invoiceId - - */ - public async saleEstimateHtml( - tenantId: number, - estimateId: number - ): Promise { - const brandingAttributes = await this.getEstimateBrandingAttributes( - tenantId, - estimateId - ); - return renderEstimatePaperTemplateHtml({ ...brandingAttributes }); - } - - /** - * Retrieve sale invoice pdf content. - * @param {number} tenantId - - * @param {ISaleInvoice} saleInvoice - - */ - public async getSaleEstimatePdf( - tenantId: number, - saleEstimateId: number - ): Promise<[Buffer, string]> { - const filename = await this.getSaleEstimateFilename( - tenantId, - saleEstimateId - ); - // Retireves the sale estimate html. - const htmlContent = await this.saleEstimateHtml(tenantId, saleEstimateId); - - // Converts the html content to pdf. - const content = await this.chromiumlyTenancy.convertHtmlContent( - tenantId, - htmlContent - ); - const eventPayload = { tenantId, saleEstimateId }; - - // Triggers the `onSaleEstimatePdfViewed` event. - await this.eventPublisher.emitAsync( - events.saleEstimate.onPdfViewed, - eventPayload - ); - return [content, filename]; - } - - /** - * Retrieves the filename file document of the given estimate. - * @param {number} tenantId - * @param {number} estimateId - * @returns {Promise} - */ - private async getSaleEstimateFilename(tenantId: number, estimateId: number) { - const { SaleEstimate } = this.tenancy.models(tenantId); - - const estimate = await SaleEstimate.query().findById(estimateId); - - return `Estimate-${estimate.estimateNumber}`; - } - - /** - * Retrieves the given estimate branding attributes. - * @param {number} tenantId - Tenant id. - * @param {number} estimateId - Estimate id. - * @returns {Promise} - */ - async getEstimateBrandingAttributes( - tenantId: number, - estimateId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - const saleEstimate = await this.getSaleEstimate.getEstimate( - tenantId, - estimateId - ); - // Retrieve the invoice template id of not found get the default template id. - const templateId = - saleEstimate.pdfTemplateId ?? - ( - await PdfTemplate.query().findOne({ - resource: 'SaleEstimate', - default: true, - }) - )?.id; - const brandingTemplate = - await this.estimatePdfTemplate.getEstimatePdfTemplate( - tenantId, - templateId - ); - return { - ...brandingTemplate.attributes, - ...transformEstimateToPdfTemplate(saleEstimate), - }; - } -} diff --git a/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts b/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts deleted file mode 100644 index db5b66713..000000000 --- a/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { Inject, Service } from 'typedi'; -import Mail from '@/lib/Mail'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT, - DEFAULT_ESTIMATE_REMINDER_MAIL_SUBJECT, -} from './constants'; -import { SaleEstimatesPdf } from './SaleEstimatesPdf'; -import { GetSaleEstimate } from './GetSaleEstimate'; -import { - ISaleEstimateMailPresendEvent, - SaleEstimateMailOptions, - SaleEstimateMailOptionsDTO, -} from '@/interfaces'; -import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; -import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { transformEstimateToMailDataArgs } from './utils'; -import { GetEstimateMailTemplate } from './GetEstimateMailTemplate'; - -@Service() -export class SendSaleEstimateMail { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private estimatePdf: SaleEstimatesPdf; - - @Inject() - private getSaleEstimateService: GetSaleEstimate; - - @Inject() - private contactMailNotification: ContactMailNotification; - - @Inject() - private getEstimateMailTemplate: GetEstimateMailTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject('agenda') - private agenda: any; - - /** - * Triggers the reminder mail of the given sale estimate. - * @param {number} tenantId - - * @param {number} saleEstimateId - - * @param {SaleEstimateMailOptionsDTO} messageOptions - - * @returns {Promise} - */ - public async triggerMail( - tenantId: number, - saleEstimateId: number, - messageOptions: SaleEstimateMailOptionsDTO - ): Promise { - const payload = { - tenantId, - saleEstimateId, - messageOptions, - }; - await this.agenda.now('sale-estimate-mail-send', payload); - - // Triggers `onSaleEstimatePreMailSend` event. - await this.eventPublisher.emitAsync(events.saleEstimate.onPreMailSend, { - tenantId, - saleEstimateId, - messageOptions, - } as ISaleEstimateMailPresendEvent); - } - - /** - * Formate the text of the mail. - * @param {number} tenantId - Tenant id. - * @param {number} estimateId - Estimate id. - * @returns {Promise>} - */ - public formatterArgs = async (tenantId: number, estimateId: number) => { - const estimate = await this.getSaleEstimateService.getEstimate( - tenantId, - estimateId - ); - const commonArgs = await this.contactMailNotification.getCommonFormatArgs( - tenantId - ); - return { - ...commonArgs, - ...transformEstimateToMailDataArgs(estimate), - }; - }; - - /** - * Retrieves the mail options. - * @param {number} tenantId - * @param {number} saleEstimateId - * @returns {Promise} - */ - public getMailOptions = async ( - tenantId: number, - saleEstimateId: number, - defaultSubject: string = DEFAULT_ESTIMATE_REMINDER_MAIL_SUBJECT, - defaultMessage: string = DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT - ): Promise => { - const { SaleEstimate } = this.tenancy.models(tenantId); - - const saleEstimate = await SaleEstimate.query() - .findById(saleEstimateId) - .throwIfNotFound(); - - const formatArgs = await this.formatterArgs(tenantId, saleEstimateId); - - const mailOptions = - await this.contactMailNotification.getDefaultMailOptions( - tenantId, - saleEstimate.customerId - ); - return { - ...mailOptions, - message: defaultMessage, - subject: defaultSubject, - attachEstimate: true, - formatArgs, - }; - }; - - /** - * Formats the given mail options. - * @param {number} tenantId - * @param {number} saleEstimateId - * @param {SaleEstimateMailOptions} mailOptions - * @returns {Promise} - */ - public formatMailOptions = async ( - tenantId: number, - saleEstimateId: number, - mailOptions: SaleEstimateMailOptions - ): Promise => { - const formatterArgs = await this.formatterArgs(tenantId, saleEstimateId); - const formattedOptions = - await this.contactMailNotification.formatMailOptions( - tenantId, - mailOptions, - formatterArgs - ); - // Retrieves the estimate mail template. - const message = await this.getEstimateMailTemplate.getMailTemplate( - tenantId, - saleEstimateId, - { - message: formattedOptions.message, - preview: formattedOptions.message, - } - ); - return { ...formattedOptions, message }; - }; - - /** - * Retrieves the formatted mail options. - * @param {number} tenantId - * @param {number} saleEstimateId - * @param {SaleEstimateMailOptionsDTO} messageOptions - * @returns - */ - public async getFormattedMailOptions( - tenantId: number, - saleEstimateId: number, - messageOptions: SaleEstimateMailOptionsDTO - ): Promise { - const defaultMessageOptions = await this.getMailOptions( - tenantId, - saleEstimateId - ); - const parsedMessageOptions = mergeAndValidateMailOptions( - defaultMessageOptions, - messageOptions - ); - return this.formatMailOptions( - tenantId, - saleEstimateId, - parsedMessageOptions - ); - } - - /** - * Sends the mail notification of the given sale estimate. - * @param {number} tenantId - * @param {number} saleEstimateId - * @param {SaleEstimateMailOptions} messageOptions - * @returns {Promise} - */ - public async sendMail( - tenantId: number, - saleEstimateId: number, - messageOptions: SaleEstimateMailOptionsDTO - ): Promise { - const formattedOptions = await this.getFormattedMailOptions( - tenantId, - saleEstimateId, - messageOptions - ); - const mail = new Mail() - .setSubject(formattedOptions.subject) - .setTo(formattedOptions.to) - .setCC(formattedOptions.cc) - .setBCC(formattedOptions.bcc) - .setContent(formattedOptions.message); - - // Attaches the estimate pdf to the mail. - if (formattedOptions.attachEstimate) { - // Retrieves the estimate pdf and attaches it to the mail. - const [estimatePdfBuffer, estimateFilename] = - await this.estimatePdf.getSaleEstimatePdf(tenantId, saleEstimateId); - - mail.setAttachments([ - { - filename: `${estimateFilename}.pdf`, - content: estimatePdfBuffer, - }, - ]); - } - const eventPayload = { - tenantId, - saleEstimateId, - messageOptions, - formattedOptions, - }; - // Triggers `onSaleEstimateMailSend` event. - await this.eventPublisher.emitAsync( - events.saleEstimate.onMailSend, - eventPayload as ISaleEstimateMailPresendEvent - ); - await mail.send(); - - // Triggers `onSaleEstimateMailSent` event. - await this.eventPublisher.emitAsync( - events.saleEstimate.onMailSent, - eventPayload as ISaleEstimateMailPresendEvent - ); - } -} diff --git a/packages/server/src/services/Sales/Estimates/SendSaleEstimateMailJob.ts b/packages/server/src/services/Sales/Estimates/SendSaleEstimateMailJob.ts deleted file mode 100644 index b5e8eda39..000000000 --- a/packages/server/src/services/Sales/Estimates/SendSaleEstimateMailJob.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Container, { Service } from 'typedi'; -import { SendSaleEstimateMail } from './SendSaleEstimateMail'; - -@Service() -export class SendSaleEstimateMailJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'sale-estimate-mail-send', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, saleEstimateId, messageOptions } = job.attrs.data; - const sendSaleEstimateMail = Container.get(SendSaleEstimateMail); - - try { - await sendSaleEstimateMail.sendMail( - tenantId, - saleEstimateId, - messageOptions - ); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Sales/Estimates/UnlinkConvertedSaleEstimate.ts b/packages/server/src/services/Sales/Estimates/UnlinkConvertedSaleEstimate.ts deleted file mode 100644 index 0f2b6c28f..000000000 --- a/packages/server/src/services/Sales/Estimates/UnlinkConvertedSaleEstimate.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class UnlinkConvertedSaleEstimate { - @Inject() - private tenancy: HasTenancyService; - - /** - * Unlink the converted sale estimates from the given sale invoice. - * @param {number} tenantId - - * @param {number} invoiceId - - * @return {Promise} - */ - public async unlinkConvertedEstimateFromInvoice( - tenantId: number, - invoiceId: number, - trx?: Knex.Transaction - ): Promise { - const { SaleEstimate } = this.tenancy.models(tenantId); - - await SaleEstimate.query(trx) - .where({ - convertedToInvoiceId: invoiceId, - }) - .patch({ - convertedToInvoiceId: null, - convertedToInvoiceAt: null, - }); - } -} diff --git a/packages/server/src/services/Sales/Estimates/constants.ts b/packages/server/src/services/Sales/Estimates/constants.ts deleted file mode 100644 index 7580c260c..000000000 --- a/packages/server/src/services/Sales/Estimates/constants.ts +++ /dev/null @@ -1,295 +0,0 @@ -export const DEFAULT_ESTIMATE_REMINDER_MAIL_SUBJECT = - 'Estimate {Estimate Number} is awaiting your approval'; -export const DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT = `Hi {Customer Name}, - -Here's estimate # {Estimate Number} for {Estimate Amount} - -This estimate is valid until {Estimate Expiration Date}, and we’re happy to discuss any adjustments you or questions may have. - -Please find your estimate attached to this email for your reference. - -If you have any questions, please let us know. - -Thanks, -{Company Name}`; - -export const ERRORS = { - SALE_ESTIMATE_NOT_FOUND: 'SALE_ESTIMATE_NOT_FOUND', - SALE_ESTIMATE_NUMBER_EXISTANCE: 'SALE_ESTIMATE_NUMBER_EXISTANCE', - SALE_ESTIMATE_CONVERTED_TO_INVOICE: 'SALE_ESTIMATE_CONVERTED_TO_INVOICE', - SALE_ESTIMATE_NOT_DELIVERED: 'SALE_ESTIMATE_NOT_DELIVERED', - SALE_ESTIMATE_ALREADY_REJECTED: 'SALE_ESTIMATE_ALREADY_REJECTED', - CUSTOMER_HAS_SALES_ESTIMATES: 'CUSTOMER_HAS_SALES_ESTIMATES', - SALE_ESTIMATE_NO_IS_REQUIRED: 'SALE_ESTIMATE_NO_IS_REQUIRED', - SALE_ESTIMATE_ALREADY_DELIVERED: 'SALE_ESTIMATE_ALREADY_DELIVERED', - SALE_ESTIMATE_ALREADY_APPROVED: 'SALE_ESTIMATE_ALREADY_APPROVED', -}; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'Draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Delivered', - slug: 'delivered', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'delivered', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Approved', - slug: 'approved', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'approved', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Rejected', - slug: 'rejected', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'rejected', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Invoiced', - slug: 'invoiced', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'invoiced', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Expired', - slug: 'expired', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'expired', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Closed', - slug: 'closed', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'closed', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const SaleEstimatesSampleData = [ - { - Customer: 'Ambrose Olson', - 'Estimate Date': '2024-01-01', - 'Expiration Date': '2025-01-01', - 'Estimate No.': 'EST-0001', - 'Reference No.': 'REF-0001', - Currency: '', - 'Exchange Rate': '', - Note: 'Vel autem quis aut ab.', - 'Terms & Conditions': 'Provident illo architecto sit iste in.', - Delivered: 'T', - 'Item Name': 'Hettinger, Schumm and Bartoletti', - Quantity: 1000, - Rate: 20, - 'Line Description': 'Rem esse doloremque praesentium harum maiores.', - }, - { - Customer: 'Ambrose Olson', - 'Estimate Date': '2024-01-02', - 'Expiration Date': '2025-01-02', - 'Estimate No.': 'EST-0002', - 'Reference No.': 'REF-0002', - Currency: '', - 'Exchange Rate': '', - Note: 'Tempora voluptas odio deleniti rerum vitae consequatur nihil quis sunt.', - 'Terms & Conditions': 'Ut eum incidunt quibusdam rerum vero.', - Delivered: 'T', - 'Item Name': 'Hettinger, Schumm and Bartoletti', - Quantity: 1000, - Rate: 20, - 'Line Description': 'Qui voluptate aliquam maxime aliquam.', - }, - { - Customer: 'Ambrose Olson', - 'Estimate Date': '2024-01-03', - 'Expiration Date': '2025-01-03', - 'Estimate No.': 'EST-0003', - 'Reference No.': 'REF-0003', - Currency: '', - 'Exchange Rate': '', - Note: 'Quia voluptatem delectus doloremque.', - 'Terms & Conditions': 'Facilis porro vitae ratione.', - Delivered: 'T', - 'Item Name': 'Hettinger, Schumm and Bartoletti', - Quantity: 1000, - Rate: 20, - 'Line Description': 'Qui suscipit ducimus qui qui.', - }, -]; - -export const defaultEstimatePdfBrandingAttributes = { - primaryColor: '#000', - secondaryColor: '#000', - - // # Company logo - showCompanyLogo: true, - companyLogoUri: '', - companyLogoKey: '', - - companyName: '', - - customerAddress: '', - companyAddress: '', - showCustomerAddress: true, - showCompanyAddress: true, - billedToLabel: 'Billed To', - - total: '$1000.00', - totalLabel: 'Total', - showTotal: true, - - subtotal: '1000/00', - subtotalLabel: 'Subtotal', - showSubtotal: true, - - showCustomerNote: true, - customerNote: - 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.', - customerNoteLabel: 'Customer Note', - - showTermsConditions: true, - termsConditions: - 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.', - termsConditionsLabel: 'Terms & Conditions', - - lines: [ - { - item: 'Simply dummy text', - description: 'Simply dummy text of the printing and typesetting', - rate: '1', - quantity: '1000', - total: '$1000.00', - }, - ], - showEstimateNumber: true, - estimateNumberLabel: 'Estimate Number', - estimateNumebr: '346D3D40-0001', - - estimateDate: 'September 3, 2024', - showEstimateDate: true, - estimateDateLabel: 'Estimate Date', - - expirationDateLabel: 'Expiration Date', - showExpirationDate: true, - expirationDate: 'September 3, 2024', -}; - -interface EstimatePdfBrandingLineItem { - item: string; - description: string; - rate: string; - quantity: string; - total: string; -} - -export interface EstimatePdfBrandingAttributes { - primaryColor: string; - secondaryColor: string; - showCompanyLogo: boolean; - companyLogo: string; - companyName: string; - - // Customer Address - showCustomerAddress: boolean; - customerAddress: string; - - // Company Address - showCompanyAddress: boolean; - companyAddress: string; - billedToLabel: string; - - // # Total - total: string; - totalLabel: string; - showTotal: boolean; - - // # Discount - discount: string; - showDiscount: boolean; - discountLabel: string; - - // # Subtotal - subtotal: string; - subtotalLabel: string; - showSubtotal: boolean; - - // # Customer Note - showCustomerNote: boolean; - customerNote: string; - customerNoteLabel: string; - - // # Terms & Conditions - showTermsConditions: boolean; - termsConditions: string; - termsConditionsLabel: string; - - lines: EstimatePdfBrandingLineItem[]; - - showEstimateNumber: boolean; - estimateNumberLabel: string; - estimateNumebr: string; - - estimateDate: string; - showEstimateDate: boolean; - estimateDateLabel: string; - - expirationDateLabel: string; - showExpirationDate: boolean; - expirationDate: string; -} diff --git a/packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts b/packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts deleted file mode 100644 index 99caa3952..000000000 --- a/packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { ISaleEstimateMailPresendEvent } from '@/interfaces'; -import { DeliverSaleEstimate } from '../DeliverSaleEstimate'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from '../constants'; - -@Service() -export class SaleEstimateMarkApprovedOnMailSent { - @Inject() - private deliverEstimateService: DeliverSaleEstimate; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe(events.saleEstimate.onPreMailSend, this.markEstimateApproved); - } - - /** - * Marks the given estimate approved on submitting mail. - * @param {ISaleEstimateMailPresendEvent} - */ - private markEstimateApproved = async ({ - tenantId, - saleEstimateId, - }: ISaleEstimateMailPresendEvent) => { - try { - await this.deliverEstimateService.deliverSaleEstimate( - tenantId, - saleEstimateId - ); - } catch (error) { - if ( - error instanceof ServiceError && - error.errorType === ERRORS.SALE_ESTIMATE_ALREADY_DELIVERED - ) { - } else { - throw error; - } - } - }; -} diff --git a/packages/server/src/services/Sales/Estimates/utils.ts b/packages/server/src/services/Sales/Estimates/utils.ts deleted file mode 100644 index e67a3e235..000000000 --- a/packages/server/src/services/Sales/Estimates/utils.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { EstimatePaperTemplateProps } from '@bigcapital/pdf-templates'; -import { contactAddressTextFormat } from '@/utils/address-text-format'; - -export const transformEstimateToPdfTemplate = ( - estimate -): Partial => { - return { - expirationDate: estimate.formattedExpirationDate, - estimateNumebr: estimate.estimateNumber, - estimateDate: estimate.formattedEstimateDate, - lines: estimate.entries.map((entry) => ({ - item: entry.item.name, - description: entry.description, - rate: entry.rateFormatted, - quantity: entry.quantityFormatted, - discount: entry.discountFormatted, - total: entry.totalFormatted, - })), - total: estimate.totalFormatted, - subtotal: estimate.formattedSubtotal, - adjustment: estimate.adjustmentFormatted, - customerNote: estimate.note, - termsConditions: estimate.termsConditions, - customerAddress: contactAddressTextFormat(estimate.customer), - showLineDiscount: estimate.entries.some((entry) => entry.discountFormatted), - discount: estimate.discountAmountFormatted, - discountLabel: estimate.discountPercentageFormatted - ? `Discount [${estimate.discountPercentageFormatted}]` - : 'Discount', - }; -}; - -export const transformEstimateToMailDataArgs = (estimate: any) => { - return { - 'Customer Name': estimate.customer.displayName, - 'Estimate Number': estimate.estimateNumber, - 'Estimate Date': estimate.formattedEstimateDate, - 'Estimate Amount': estimate.formattedAmount, - 'Estimate Expiration Date': estimate.formattedExpirationDate, - }; -}; diff --git a/packages/server/src/services/Sales/HasItemsEntries.ts b/packages/server/src/services/Sales/HasItemsEntries.ts deleted file mode 100644 index 9208c893d..000000000 --- a/packages/server/src/services/Sales/HasItemsEntries.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { difference, omit } from 'lodash'; -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ItemEntry } from 'models'; - -@Service() -export default class HasItemEntries { - @Inject() - tenancy: TenancyService; - - filterNonInventoryEntries(entries: [], items: []) { - const nonInventoryItems = items.filter((item: any) => item.type !== 'inventory'); - const nonInventoryItemsIds = nonInventoryItems.map((i: any) => i.id); - - return entries - .filter((entry: any) => ( - (nonInventoryItemsIds.indexOf(entry.item_id)) !== -1 - )); - } - - filterInventoryEntries(entries: [], items: []) { - const inventoryItems = items.filter((item: any) => item.type === 'inventory'); - const inventoryItemsIds = inventoryItems.map((i: any) => i.id); - - return entries - .filter((entry: any) => ( - (inventoryItemsIds.indexOf(entry.item_id)) !== -1 - )); - } -} \ No newline at end of file diff --git a/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts b/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts deleted file mode 100644 index bf428e6b0..000000000 --- a/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit, sumBy } from 'lodash'; -import * as R from 'ramda'; -import moment from 'moment'; -import composeAsync from 'async/compose'; -import { - ISaleInvoice, - ISaleInvoiceCreateDTO, - ISaleInvoiceEditDTO, - ICustomer, - ITenantUser, -} from '@/interfaces'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; -import { SaleInvoiceIncrement } from './SaleInvoiceIncrement'; -import { formatDateFields } from 'utils'; -import { ItemEntriesTaxTransactions } from '@/services/TaxRates/ItemEntriesTaxTransactions'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; -import { ItemEntry } from '@/models'; -import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer'; - -@Service() -export class CommandSaleInvoiceDTOTransformer { - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - @Inject() - private invoiceIncrement: SaleInvoiceIncrement; - - @Inject() - private taxDTOTransformer: ItemEntriesTaxTransactions; - - @Inject() - private brandingTemplatesTransformer: BrandingTemplateDTOTransformer; - - /** - * Transformes the create DTO to invoice object model. - * @param {ISaleInvoiceCreateDTO} saleInvoiceDTO - Sale invoice DTO. - * @param {ISaleInvoice} oldSaleInvoice - Old sale invoice. - * @return {ISaleInvoice} - */ - public async transformDTOToModel( - tenantId: number, - customer: ICustomer, - saleInvoiceDTO: ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO, - authorizedUser: ITenantUser, - oldSaleInvoice?: ISaleInvoice - ): Promise { - const entriesModels = this.transformDTOEntriesToModels(saleInvoiceDTO); - const amount = this.getDueBalanceItemEntries(entriesModels); - - // Retreive the next invoice number. - const autoNextNumber = this.invoiceIncrement.getNextInvoiceNumber(tenantId); - - // Invoice number. - const invoiceNo = - saleInvoiceDTO.invoiceNo || oldSaleInvoice?.invoiceNo || autoNextNumber; - - // Validate the invoice is required. - this.validators.validateInvoiceNoRequire(invoiceNo); - - const initialEntries = saleInvoiceDTO.entries.map((entry) => ({ - referenceType: 'SaleInvoice', - isInclusiveTax: saleInvoiceDTO.isInclusiveTax, - ...entry, - })); - const asyncEntries = await composeAsync( - // Associate tax rate from tax id to entries. - this.taxDTOTransformer.assocTaxRateFromTaxIdToEntries(tenantId), - // Associate tax rate id from tax code to entries. - this.taxDTOTransformer.assocTaxRateIdFromCodeToEntries(tenantId), - // Sets default cost and sell account to invoice items entries. - this.itemsEntriesService.setItemsEntriesDefaultAccounts(tenantId) - )(initialEntries); - - const entries = R.compose( - // Remove tax code from entries. - R.map(R.omit(['taxCode'])), - - // Associate the default index for each item entry lin. - assocItemEntriesDefaultIndex - )(asyncEntries); - - const initialDTO = { - ...formatDateFields( - omit(saleInvoiceDTO, [ - 'delivered', - 'entries', - 'fromEstimateId', - 'attachments', - ]), - ['invoiceDate', 'dueDate'] - ), - // Avoid rewrite the deliver date in edit mode when already published. - balance: amount, - currencyCode: customer.currencyCode, - exchangeRate: saleInvoiceDTO.exchangeRate || 1, - ...(saleInvoiceDTO.delivered && - !oldSaleInvoice?.deliveredAt && { - deliveredAt: moment().toMySqlDateTime(), - }), - // Avoid override payment amount in edit mode. - ...(!oldSaleInvoice && { paymentAmount: 0 }), - ...(invoiceNo ? { invoiceNo } : {}), - entries, - userId: authorizedUser.id, - } as ISaleInvoice; - - const initialAsyncDTO = await composeAsync( - // Assigns the default branding template id to the invoice DTO. - this.brandingTemplatesTransformer.assocDefaultBrandingTemplate( - tenantId, - 'SaleInvoice' - ) - )(initialDTO); - - return R.compose( - this.taxDTOTransformer.assocTaxAmountWithheldFromEntries, - this.branchDTOTransform.transformDTO(tenantId), - this.warehouseDTOTransform.transformDTO(tenantId) - )(initialAsyncDTO); - } - - /** - * Transforms the DTO entries to invoice entries models. - * @param {ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO} entries - * @returns {IItemEntry[]} - */ - private transformDTOEntriesToModels = ( - saleInvoiceDTO: ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO - ): ItemEntry[] => { - return saleInvoiceDTO.entries.map((entry) => { - return ItemEntry.fromJson({ - ...entry, - isInclusiveTax: saleInvoiceDTO.isInclusiveTax, - }); - }); - }; - - /** - * Gets the due balance from the invoice entries. - * @param {IItemEntry[]} entries - * @returns {number} - */ - private getDueBalanceItemEntries = (entries: ItemEntry[]) => { - return sumBy(entries, (e) => e.total); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceValidators.ts b/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceValidators.ts deleted file mode 100644 index c0786ad4b..000000000 --- a/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceValidators.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { SaleInvoice } from '@/models'; -import { ERRORS } from './constants'; - -@Service() -export class CommandSaleInvoiceValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates the given invoice is existance. - * @param {SaleInvoice | undefined} invoice - */ - public validateInvoiceExistance(invoice: SaleInvoice | undefined) { - if (!invoice) { - throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND); - } - } - - /** - * Validate whether sale invoice number unqiue on the storage. - * @param {number} tenantId - - * @param {string} invoiceNumber - - * @param {number} notInvoiceId - - */ - public async validateInvoiceNumberUnique( - tenantId: number, - invoiceNumber: string, - notInvoiceId?: number - ) { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const saleInvoice = await SaleInvoice.query() - .findOne('invoice_no', invoiceNumber) - .onBuild((builder) => { - if (notInvoiceId) { - builder.whereNot('id', notInvoiceId); - } - }); - - if (saleInvoice) { - throw new ServiceError(ERRORS.INVOICE_NUMBER_NOT_UNIQUE); - } - } - - /** - * Validate the invoice amount is bigger than payment amount before edit the invoice. - * @param {number} saleInvoiceAmount - * @param {number} paymentAmount - */ - public validateInvoiceAmountBiggerPaymentAmount( - saleInvoiceAmount: number, - paymentAmount: number - ) { - if (saleInvoiceAmount < paymentAmount) { - throw new ServiceError(ERRORS.INVOICE_AMOUNT_SMALLER_THAN_PAYMENT_AMOUNT); - } - } - - /** - * Validate the invoice number require. - * @param {ISaleInvoice} saleInvoiceObj - */ - public validateInvoiceNoRequire(invoiceNo: string) { - if (!invoiceNo) { - throw new ServiceError(ERRORS.SALE_INVOICE_NO_IS_REQUIRED); - } - } - - /** - * Validate the given customer has no sales invoices. - * @param {number} tenantId - * @param {number} customerId - Customer id. - */ - public async validateCustomerHasNoInvoices( - tenantId: number, - customerId: number - ) { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const invoices = await SaleInvoice.query().where('customer_id', customerId); - - if (invoices.length > 0) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_SALES_INVOICES); - } - } -} diff --git a/packages/server/src/services/Sales/Invoices/CreateSaleInvoice.ts b/packages/server/src/services/Sales/Invoices/CreateSaleInvoice.ts deleted file mode 100644 index 38ac09e8f..000000000 --- a/packages/server/src/services/Sales/Invoices/CreateSaleInvoice.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ICustomer, - ISaleInvoice, - ISaleInvoiceCreateDTO, - ISaleInvoiceCreatedPayload, - ISaleInvoiceCreatingPaylaod, - ITenantUser, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; -import { CommandSaleInvoiceDTOTransformer } from './CommandSaleInvoiceDTOTransformer'; -import { SaleEstimateValidators } from '../Estimates/SaleEstimateValidators'; - -@Service() -export class CreateSaleInvoice { - @Inject() - private tenancy: TenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - @Inject() - private transformerDTO: CommandSaleInvoiceDTOTransformer; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private commandEstimateValidators: SaleEstimateValidators; - - /** - * Creates a new sale invoices and store it to the storage - * with associated to entries and journal transactions. - * @async - * @param {number} tenantId - Tenant id. - * @param {ISaleInvoice} saleInvoiceDTO - Sale invoice object DTO. - * @return {Promise} - */ - public createSaleInvoice = async ( - tenantId: number, - saleInvoiceDTO: ISaleInvoiceCreateDTO, - authorizedUser: ITenantUser, - trx?: Knex.Transaction - ): Promise => { - const { SaleInvoice, SaleEstimate, Contact } = - this.tenancy.models(tenantId); - - // Validate customer existance. - const customer = await Contact.query() - .modify('customer') - .findById(saleInvoiceDTO.customerId) - .throwIfNotFound(); - - // Validate the from estimate id exists on the storage. - if (saleInvoiceDTO.fromEstimateId) { - const fromEstimate = await SaleEstimate.query() - .findById(saleInvoiceDTO.fromEstimateId) - .throwIfNotFound(); - - // Validate the sale estimate is not already converted to invoice. - this.commandEstimateValidators.validateEstimateNotConverted(fromEstimate); - } - // Validate items ids existance. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - saleInvoiceDTO.entries - ); - // Validate items should be sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - saleInvoiceDTO.entries - ); - // Transform DTO object to model object. - const saleInvoiceObj = await this.transformCreateDTOToModel( - tenantId, - customer, - saleInvoiceDTO, - authorizedUser - ); - // Validate sale invoice number uniquiness. - if (saleInvoiceObj.invoiceNo) { - await this.validators.validateInvoiceNumberUnique( - tenantId, - saleInvoiceObj.invoiceNo - ); - } - // Creates a new sale invoice and associated transactions under unit of work env. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onSaleInvoiceCreating` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onCreating, { - saleInvoiceDTO, - tenantId, - trx, - } as ISaleInvoiceCreatingPaylaod); - - // Create sale invoice graph to the storage. - const saleInvoice = await SaleInvoice.query(trx).upsertGraph( - saleInvoiceObj - ); - const eventPayload: ISaleInvoiceCreatedPayload = { - tenantId, - saleInvoice, - saleInvoiceDTO, - saleInvoiceId: saleInvoice.id, - authorizedUser, - trx, - }; - // Triggers the event `onSaleInvoiceCreated`. - await this.eventPublisher.emitAsync( - events.saleInvoice.onCreated, - eventPayload - ); - return saleInvoice; - }, - trx - ); - }; - - /** - * Transformes create DTO to model. - * @param {number} tenantId - - * @param {ICustomer} customer - - * @param {ISaleInvoiceCreateDTO} saleInvoiceDTO - - */ - private transformCreateDTOToModel = async ( - tenantId: number, - customer: ICustomer, - saleInvoiceDTO: ISaleInvoiceCreateDTO, - authorizedUser: ITenantUser - ) => { - return this.transformerDTO.transformDTOToModel( - tenantId, - customer, - saleInvoiceDTO, - authorizedUser - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/DeleteSaleInvoice.ts b/packages/server/src/services/Sales/Invoices/DeleteSaleInvoice.ts deleted file mode 100644 index 7d7ec3544..000000000 --- a/packages/server/src/services/Sales/Invoices/DeleteSaleInvoice.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - ISystemUser, - ISaleInvoiceDeletePayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceDeletingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import { UnlinkConvertedSaleEstimate } from '../Estimates/UnlinkConvertedSaleEstimate'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class DeleteSaleInvoice { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private unlockEstimateFromInvoice: UnlinkConvertedSaleEstimate; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Validate the sale invoice has no payment entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - */ - private async validateInvoiceHasNoPaymentEntries( - tenantId: number, - saleInvoiceId: number - ) { - const { PaymentReceiveEntry } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice associated payment receive entries. - const entries = await PaymentReceiveEntry.query().where( - 'invoice_id', - saleInvoiceId - ); - if (entries.length > 0) { - throw new ServiceError(ERRORS.INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES); - } - return entries; - } - - /** - * Validate the sale invoice has no applied to credit note transaction. - * @param {number} tenantId - * @param {number} invoiceId - * @returns {Promise} - */ - public validateInvoiceHasNoAppliedToCredit = async ( - tenantId: number, - invoiceId: number - ): Promise => { - const { CreditNoteAppliedInvoice } = this.tenancy.models(tenantId); - - const appliedTransactions = await CreditNoteAppliedInvoice.query().where( - 'invoiceId', - invoiceId - ); - if (appliedTransactions.length > 0) { - throw new ServiceError(ERRORS.SALE_INVOICE_HAS_APPLIED_TO_CREDIT_NOTES); - } - }; - - /** - * Validate whether sale invoice exists on the storage. - * @param {Request} req - * @param {Response} res - * @param {Function} next - */ - private async getInvoiceOrThrowError( - tenantId: number, - saleInvoiceId: number - ) { - const { saleInvoiceRepository } = this.tenancy.repositories(tenantId); - - const saleInvoice = await saleInvoiceRepository.findOneById(saleInvoiceId, [ - 'entries', - 'paymentMethods', - ]); - if (!saleInvoice) { - throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND); - } - return saleInvoice; - } - - /** - * Deletes the given sale invoice with associated entries - * and journal transactions. - * @param {number} tenantId - Tenant id. - * @param {Number} saleInvoiceId - The given sale invoice id. - * @param {ISystemUser} authorizedUser - - */ - public async deleteSaleInvoice( - tenantId: number, - saleInvoiceId: number, - authorizedUser: ISystemUser - ): Promise { - const { ItemEntry, SaleInvoice } = this.tenancy.models(tenantId); - - // Retrieve the given sale invoice with associated entries - // or throw not found error. - const oldSaleInvoice = await this.getInvoiceOrThrowError( - tenantId, - saleInvoiceId - ); - // Validate the sale invoice has no associated payment entries. - await this.validateInvoiceHasNoPaymentEntries(tenantId, saleInvoiceId); - - // Validate the sale invoice has applied to credit note transaction. - await this.validateInvoiceHasNoAppliedToCredit(tenantId, saleInvoiceId); - - // Triggers `onSaleInvoiceDelete` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onDelete, { - tenantId, - oldSaleInvoice, - saleInvoiceId, - } as ISaleInvoiceDeletePayload); - - // Deletes sale invoice transaction and associate transactions with UOW env. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleInvoiceDeleting` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onDeleting, { - tenantId, - oldSaleInvoice, - saleInvoiceId, - trx, - } as ISaleInvoiceDeletingPayload); - - // Unlink the converted sale estimates from the given sale invoice. - await this.unlockEstimateFromInvoice.unlinkConvertedEstimateFromInvoice( - tenantId, - saleInvoiceId, - trx - ); - await ItemEntry.query(trx) - .where('reference_id', saleInvoiceId) - .where('reference_type', 'SaleInvoice') - .delete(); - - await SaleInvoice.query(trx).findById(saleInvoiceId).delete(); - - // Triggers `onSaleInvoiceDeleted` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onDeleted, { - tenantId, - oldSaleInvoice, - saleInvoiceId, - authorizedUser, - trx, - } as ISaleInvoiceDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/Invoices/DeliverSaleInvoice.ts b/packages/server/src/services/Sales/Invoices/DeliverSaleInvoice.ts deleted file mode 100644 index f5500a03a..000000000 --- a/packages/server/src/services/Sales/Invoices/DeliverSaleInvoice.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Knex } from 'knex'; -import moment from 'moment'; -import { ServiceError } from '@/exceptions'; -import { - ISaleInvoiceDeliveringPayload, - ISaleInvoiceEventDeliveredPayload, -} from '@/interfaces'; -import { ERRORS } from './constants'; -import { Inject, Service } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; - -@Service() -export class DeliverSaleInvoice { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - /** - * Deliver the given sale invoice. - * @param {number} tenantId - Tenant id. - * @param {number} saleInvoiceId - Sale invoice id. - * @return {Promise} - */ - public async deliverSaleInvoice( - tenantId: number, - saleInvoiceId: number - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Retrieve details of the given sale invoice id. - const oldSaleInvoice = await SaleInvoice.query().findById(saleInvoiceId); - - // Validates the given invoice existance. - this.validators.validateInvoiceExistance(oldSaleInvoice); - - // Throws error in case the sale invoice already published. - if (oldSaleInvoice.isDelivered) { - throw new ServiceError(ERRORS.SALE_INVOICE_ALREADY_DELIVERED); - } - // Update sale invoice transaction with assocaite transactions - // under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleInvoiceDelivering` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onDelivering, { - tenantId, - oldSaleInvoice, - trx, - } as ISaleInvoiceDeliveringPayload); - - // Record the delivered at on the storage. - const saleInvoice = await SaleInvoice.query(trx) - .patchAndFetchById(saleInvoiceId, { - deliveredAt: moment().toMySqlDateTime(), - }) - .withGraphFetched('entries'); - - // Triggers `onSaleInvoiceDelivered` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onDelivered, { - tenantId, - saleInvoiceId, - saleInvoice, - trx, - } as ISaleInvoiceEventDeliveredPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/Invoices/EditSaleInvoice.ts b/packages/server/src/services/Sales/Invoices/EditSaleInvoice.ts deleted file mode 100644 index 5b0638be0..000000000 --- a/packages/server/src/services/Sales/Invoices/EditSaleInvoice.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - ICustomer, - ISaleInvoice, - ISaleInvoiceEditDTO, - ISaleInvoiceEditedPayload, - ISaleInvoiceEditingPayload, - ISystemUser, - ITenantUser, -} from '@/interfaces'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; -import { CommandSaleInvoiceDTOTransformer } from './CommandSaleInvoiceDTOTransformer'; -import events from '@/subscribers/events'; - -@Service() -export class EditSaleInvoice { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - @Inject() - private transformerDTO: CommandSaleInvoiceDTOTransformer; - - @Inject() - private uow: UnitOfWork; - - /** - * Edit the given sale invoice. - * @async - * @param {number} tenantId - Tenant id. - * @param {Number} saleInvoiceId - Sale invoice id. - * @param {ISaleInvoice} saleInvoice - Sale invoice DTO object. - * @return {Promise} - */ - public async editSaleInvoice( - tenantId: number, - saleInvoiceId: number, - saleInvoiceDTO: ISaleInvoiceEditDTO, - authorizedUser: ISystemUser - ): Promise { - const { SaleInvoice, Contact } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const oldSaleInvoice = await SaleInvoice.query() - .findById(saleInvoiceId) - .withGraphJoined('entries'); - - // Validates the given invoice existance. - this.validators.validateInvoiceExistance(oldSaleInvoice); - - // Validate customer existance. - const customer = await Contact.query() - .findById(saleInvoiceDTO.customerId) - .modify('customer') - .throwIfNotFound(); - - // Validate items ids existance. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - saleInvoiceDTO.entries - ); - // Validate non-sellable entries items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - saleInvoiceDTO.entries - ); - // Validate the items entries existance. - await this.itemsEntriesService.validateEntriesIdsExistance( - tenantId, - saleInvoiceId, - 'SaleInvoice', - saleInvoiceDTO.entries - ); - // Transform DTO object to model object. - const saleInvoiceObj = await this.tranformEditDTOToModel( - tenantId, - customer, - saleInvoiceDTO, - oldSaleInvoice, - authorizedUser - ); - // Validate sale invoice number uniquiness. - if (saleInvoiceObj.invoiceNo) { - await this.validators.validateInvoiceNumberUnique( - tenantId, - saleInvoiceObj.invoiceNo, - saleInvoiceId - ); - } - // Validate the invoice amount is not smaller than the invoice payment amount. - this.validators.validateInvoiceAmountBiggerPaymentAmount( - saleInvoiceObj.balance, - oldSaleInvoice.paymentAmount - ); - // Edit sale invoice transaction in UOW envirment. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleInvoiceEditing` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onEditing, { - trx, - oldSaleInvoice, - tenantId, - saleInvoiceDTO, - } as ISaleInvoiceEditingPayload); - - // Upsert the the invoice graph to the storage. - const saleInvoice: ISaleInvoice = - await SaleInvoice.query().upsertGraphAndFetch({ - id: saleInvoiceId, - ...saleInvoiceObj, - }); - // Edit event payload. - const editEventPayload: ISaleInvoiceEditedPayload = { - tenantId, - saleInvoiceId, - saleInvoice, - saleInvoiceDTO, - oldSaleInvoice, - authorizedUser, - trx, - }; - // Triggers `onSaleInvoiceEdited` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onEdited, - editEventPayload - ); - return saleInvoice; - }); - } - - /** - * Transformes edit DTO to model. - * @param {number} tennatId - - * @param {ICustomer} customer - - * @param {ISaleInvoiceEditDTO} saleInvoiceDTO - - * @param {ISaleInvoice} oldSaleInvoice - */ - private tranformEditDTOToModel = async ( - tenantId: number, - customer: ICustomer, - saleInvoiceDTO: ISaleInvoiceEditDTO, - oldSaleInvoice: ISaleInvoice, - authorizedUser: ITenantUser - ) => { - return this.transformerDTO.transformDTOToModel( - tenantId, - customer, - saleInvoiceDTO, - authorizedUser, - oldSaleInvoice - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/GeneratePaymentLinkTransformer.ts b/packages/server/src/services/Sales/Invoices/GeneratePaymentLinkTransformer.ts deleted file mode 100644 index bd2e83b69..000000000 --- a/packages/server/src/services/Sales/Invoices/GeneratePaymentLinkTransformer.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { PUBLIC_PAYMENT_LINK } from './constants'; - -export class GeneratePaymentLinkTransformer extends Transformer { - /** - * Exclude these attributes from payment link object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['linkId']; - }; - - /** - * Included attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return ['link']; - }; - - /** - * Retrieves the public/private payment linl - * @returns {string} - */ - public link(link) { - return PUBLIC_PAYMENT_LINK?.replace('{PAYMENT_LINK_ID}', link.linkId); - } -} diff --git a/packages/server/src/services/Sales/Invoices/GenerateeInvoicePaymentLink.ts b/packages/server/src/services/Sales/Invoices/GenerateeInvoicePaymentLink.ts deleted file mode 100644 index 79f9f7702..000000000 --- a/packages/server/src/services/Sales/Invoices/GenerateeInvoicePaymentLink.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { v4 as uuidv4 } from 'uuid'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { PaymentLink } from '@/system/models'; -import { GeneratePaymentLinkTransformer } from './GeneratePaymentLinkTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GenerateShareLink { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Generates private or public payment link for the given sale invoice. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Sale invoice id. - * @param {string} publicOrPrivate - Public or private. - * @param {string} expiryTime - Expiry time. - */ - async generatePaymentLink( - tenantId: number, - saleInvoiceId: number, - publicity: string = 'private', - expiryTime: string = '' - ) { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const foundInvoice = await SaleInvoice.query() - .findById(saleInvoiceId) - .throwIfNotFound(); - - // Generate unique uuid for sharable link. - const linkId = uuidv4() as string; - - const commonEventPayload = { - tenantId, - saleInvoiceId, - publicity, - expiryTime, - }; - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onPublicSharableLinkGenerating` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onPublicLinkGenerating, - { ...commonEventPayload, trx } - ); - const paymentLink = await PaymentLink.query().insert({ - linkId, - tenantId, - publicity, - resourceId: foundInvoice.id, - resourceType: 'SaleInvoice', - }); - // Triggers `onPublicSharableLinkGenerated` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onPublicLinkGenerated, - { - ...commonEventPayload, - paymentLink, - trx, - } - ); - return this.transformer.transform( - tenantId, - paymentLink, - new GeneratePaymentLinkTransformer() - ); - }); - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts deleted file mode 100644 index d86ffb04d..000000000 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { Transform } from 'form-data'; -import { ItemEntryTransformer } from './ItemEntryTransformer'; -import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer'; -import { SaleInvoiceTransformer } from './SaleInvoiceTransformer'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { contactAddressTextFormat } from '@/utils/address-text-format'; -import { GetPdfTemplateTransformer } from '@/services/PdfTemplate/GetPdfTemplateTransformer'; - -export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer { - /** - * Exclude these attributes from payment link object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Included attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return [ - 'customerName', - 'dueAmount', - 'dueDateFormatted', - 'invoiceDateFormatted', - 'total', - 'totalFormatted', - 'totalLocalFormatted', - 'subtotal', - 'subtotalFormatted', - 'subtotalLocalFormatted', - 'dueAmount', - 'dueAmountFormatted', - 'paymentAmount', - 'paymentAmountFormatted', - 'dueDate', - 'dueDateFormatted', - 'invoiceNo', - 'invoiceMessage', - 'termsConditions', - 'entries', - 'taxes', - 'organization', - 'isReceivable', - 'hasStripePaymentMethod', - 'formattedCustomerAddress', - 'brandingTemplate', - ]; - }; - - public customerName(invoice) { - return invoice.customer.displayName; - } - - /** - * Retrieves the organization metadata for the payment link. - * @returns - */ - public organization(invoice) { - return this.item( - this.context.organization, - new GetPaymentLinkOrganizationMetaTransformer() - ); - } - - /** - * Retrieves the branding template for the payment link. - * @param {} invoice - * @returns - */ - public brandingTemplate(invoice) { - return this.item( - invoice.pdfTemplate, - new GetInvoicePaymentLinkBrandingTemplate() - ); - } - - /** - * Retrieves the entries of the sale invoice. - * @param {ISaleInvoice} invoice - * @returns {} - */ - protected entries = (invoice) => { - return this.item( - invoice.entries, - new GetInvoicePaymentLinkEntryMetaTransformer(), - { - currencyCode: invoice.currencyCode, - } - ); - }; - - /** - * Retrieves the sale invoice entries. - * @returns {} - */ - protected taxes = (invoice) => { - return this.item( - invoice.taxes, - new GetInvoicePaymentLinkTaxEntryTransformer(), - { - subtotal: invoice.subtotal, - isInclusiveTax: invoice.isInclusiveTax, - currencyCode: invoice.currencyCode, - } - ); - }; - - protected isReceivable(invoice) { - return invoice.dueAmount > 0; - } - - protected hasStripePaymentMethod(invoice) { - return invoice.paymentMethods.some( - (paymentMethod) => paymentMethod.paymentIntegration.service === 'Stripe' - ); - } - - get customerAddressFormat() { - return `{ADDRESS_1} -{ADDRESS_2} -{CITY} {STATE} {POSTAL_CODE} -{COUNTRY} -{PHONE}`; - } - - /** - * Retrieves the formatted customer address. - * @param invoice - * @returns {string} - */ - protected formattedCustomerAddress(invoice) { - return contactAddressTextFormat( - invoice.customer, - this.customerAddressFormat - ); - } -} - -class GetPaymentLinkOrganizationMetaTransformer extends Transformer { - /** - * Include these attributes to item entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'primaryColor', - 'name', - 'address', - 'logoUri', - 'addressTextFormatted', - ]; - }; - - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieves the formatted text of organization address. - * @returns {string} - */ - public addressTextFormatted() { - return this.context.organization.addressTextFormatted; - } -} - -class GetInvoicePaymentLinkEntryMetaTransformer extends ItemEntryTransformer { - /** - * Include these attributes to item entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'quantity', - 'quantityFormatted', - 'rate', - 'rateFormatted', - 'total', - 'totalFormatted', - 'itemName', - 'description', - ]; - }; - - public itemName(entry) { - return entry.item.name; - } - - /** - * Exclude these attributes from payment link object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; -} - -class GetInvoicePaymentLinkTaxEntryTransformer extends SaleInvoiceTaxEntryTransformer { - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['name', 'taxRateCode', 'taxRateAmount', 'taxRateAmountFormatted']; - }; -} - -class GetInvoicePaymentLinkBrandingTemplate extends GetPdfTemplateTransformer { - public includeAttributes = (): string[] => { - return ['companyLogoUri', 'primaryColor']; - }; - - public excludeAttributes = (): string[] => { - return ['*']; - }; - - primaryColor = (template) => { - return template.attributes?.primaryColor; - }; -} diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMail.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMail.ts deleted file mode 100644 index 4e13e7d02..000000000 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMail.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { GetSaleInvoice } from './GetSaleInvoice'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { - InvoicePaymentEmailProps, - renderInvoicePaymentEmail, -} from '@bigcapital/email-components'; -import { GetInvoiceMailTemplateAttributesTransformer } from './GetInvoicePaymentMailAttributesTransformer'; - -@Service() -export class GetInvoicePaymentMail { - @Inject() - private getSaleInvoiceService: GetSaleInvoice; - - @Inject() - private getBrandingTemplate: GetPdfTemplate; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the mail template attributes of the given invoice. - * Invoice template attributes are composed of the invoice and branding template attributes. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Invoice id. - */ - public async getMailTemplateAttributes(tenantId: number, invoiceId: number) { - const invoice = await this.getSaleInvoiceService.getSaleInvoice( - tenantId, - invoiceId - ); - const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate( - tenantId, - invoice.pdfTemplateId - ); - const mailTemplateAttributes = await this.transformer.transform( - tenantId, - invoice, - new GetInvoiceMailTemplateAttributesTransformer(), - { - invoice, - brandingTemplate, - } - ); - return mailTemplateAttributes; - } - - /** - * Retrieves the mail template html content. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Invoice id. - */ - public async getMailTemplate( - tenantId: number, - invoiceId: number, - overrideAttributes?: Partial - ): Promise { - const attributes = await this.getMailTemplateAttributes( - tenantId, - invoiceId - ); - const mergedAttributes = { ...attributes, ...overrideAttributes }; - - return renderInvoicePaymentEmail(mergedAttributes); - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts deleted file mode 100644 index 749295371..000000000 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetInvoiceMailTemplateAttributesTransformer extends Transformer { - /** - * Include these attributes to item entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'companyLogoUri', - 'companyName', - - 'invoiceAmount', - - 'primaryColor', - - 'invoiceAmount', - 'invoiceMessage', - - 'dueDate', - 'dueDateLabel', - - 'invoiceNumber', - 'invoiceNumberLabel', - - 'subtotal', - 'subtotalLabel', - - 'discount', - 'discountLabel', - - 'adjustment', - 'adjustmentLabel', - - 'total', - 'totalLabel', - - 'dueAmount', - 'dueAmountLabel', - - 'viewInvoiceButtonLabel', - 'viewInvoiceButtonUrl', - - 'items', - ]; - }; - - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public companyLogoUri(): string { - return this.options.brandingTemplate?.companyLogoUri; - } - - public companyName(): string { - return this.context.organization.name; - } - - public invoiceAmount(): string { - return this.options.invoice.totalFormatted; - } - - public primaryColor(): string { - return this.options?.brandingTemplate?.attributes?.primaryColor; - } - - public invoiceMessage(): string { - return ''; - } - - public dueDate(): string { - return this.options?.invoice?.dueDateFormatted; - } - - public dueDateLabel(): string { - return 'Due {dueDate}'; - } - - public invoiceNumber(): string { - return this.options?.invoice?.invoiceNo; - } - - public invoiceNumberLabel(): string { - return 'Invoice # {invoiceNumber}'; - } - - public subtotal(): string { - return this.options.invoice?.subtotalFormatted; - } - - public subtotalLabel(): string { - return 'Subtotal'; - } - - public discount(): string { - return this.options.invoice?.discountAmountFormatted; - } - - public discountLabel(): string { - return 'Discount'; - } - - public adjustment(): string { - return this.options.invoice?.adjustmentFormatted; - } - - public adjustmentLabel(): string { - return 'Adjustment'; - } - - public total(): string { - return this.options.invoice?.totalFormatted; - } - - public totalLabel(): string { - return 'Total'; - } - - public dueAmount(): string { - return this.options?.invoice.dueAmountFormatted; - } - - public dueAmountLabel(): string { - return 'Due Amount'; - } - - public viewInvoiceButtonLabel(): string { - return 'View Invoice'; - } - - public viewInvoiceButtonUrl(): string { - return ''; - } - - public items(): Array { - return this.item( - this.options.invoice?.entries, - new GetInvoiceMailTemplateItemAttrsTransformer() - ); - } -} - -class GetInvoiceMailTemplateItemAttrsTransformer extends Transformer { - /** - * Include these attributes to item entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['quantity', 'label', 'rate']; - }; - - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public quantity(entry): string { - return entry?.quantity; - } - - public label(entry): string { - console.log(entry); - return entry?.item?.name; - } - - public rate(entry): string { - return entry?.rateFormatted; - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentsService.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentsService.ts deleted file mode 100644 index 05b3b7f9e..000000000 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentsService.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { InvoicePaymentTransactionTransformer } from './InvoicePaymentTransactionTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetInvoicePaymentsService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve the invoice associated payments transactions. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Invoice id. - */ - public getInvoicePayments = async (tenantId: number, invoiceId: number) => { - const { PaymentReceiveEntry } = this.tenancy.models(tenantId); - - const paymentsEntries = await PaymentReceiveEntry.query() - .where('invoiceId', invoiceId) - .withGraphJoined('payment.depositAccount') - .withGraphJoined('invoice') - .orderBy('payment:paymentDate', 'ASC'); - - return this.transformer.transform( - tenantId, - paymentsEntries, - new InvoicePaymentTransactionTransformer() - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoice.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoice.ts deleted file mode 100644 index 0cad1e952..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoice.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISaleInvoice, ISystemUser } from '@/interfaces'; -import { SaleInvoiceTransformer } from './SaleInvoiceTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class GetSaleInvoice { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve sale invoice with associated entries. - * @param {Number} saleInvoiceId - - * @param {ISystemUser} authorizedUser - - * @return {Promise} - */ - public async getSaleInvoice( - tenantId: number, - saleInvoiceId: number - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const saleInvoice = await SaleInvoice.query() - .findById(saleInvoiceId) - .withGraphFetched('entries.item') - .withGraphFetched('entries.tax') - .withGraphFetched('customer') - .withGraphFetched('branch') - .withGraphFetched('taxes.taxRate') - .withGraphFetched('attachments') - .withGraphFetched('paymentMethods'); - - // Validates the given sale invoice existance. - this.validators.validateInvoiceExistance(saleInvoice); - - const transformed = await this.transformer.transform( - tenantId, - saleInvoice, - new SaleInvoiceTransformer() - ); - const eventPayload = { - tenantId, - saleInvoiceId, - }; - // Triggers the `onSaleInvoiceItemViewed` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onViewed, - eventPayload - ); - return transformed; - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailReminder.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailReminder.ts deleted file mode 100644 index 2a65d316e..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailReminder.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class GetSaleInvoiceMailReminder { - public getInvoiceMailReminder(tenantId: number, saleInvoiceId: number) {} -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts deleted file mode 100644 index 6f00dd08d..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { SaleInvoiceMailOptions, SaleInvoiceMailState } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject } from 'typedi'; -import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetSaleInvoiceMailStateTransformer } from './GetSaleInvoiceMailStateTransformer'; - -export class GetSaleInvoiceMailState { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private invoiceMail: SendSaleInvoiceMailCommon; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the invoice mail state of the given sale invoice. - * Invoice mail state includes the mail options, branding attributes and the invoice details. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {Promise} - */ - async getInvoiceMailState( - tenantId: number, - saleInvoiceId: number - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const saleInvoice = await SaleInvoice.query() - .findById(saleInvoiceId) - .withGraphFetched('customer') - .withGraphFetched('entries.item') - .withGraphFetched('pdfTemplate') - .throwIfNotFound(); - - const mailOptions = await this.invoiceMail.getInvoiceMailOptions( - tenantId, - saleInvoiceId - ); - // Transforms the sale invoice mail state. - const transformed = await this.transformer.transform( - tenantId, - saleInvoice, - new GetSaleInvoiceMailStateTransformer(), - { - mailOptions, - } - ); - return transformed; - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts deleted file mode 100644 index 259ea31e7..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { SaleInvoiceTransformer } from './SaleInvoiceTransformer'; -import { ItemEntryTransformer } from './ItemEntryTransformer'; - -export class GetSaleInvoiceMailStateTransformer extends SaleInvoiceTransformer { - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'invoiceDate', - 'invoiceDateFormatted', - - 'dueDate', - 'dueDateFormatted', - - 'dueAmount', - 'dueAmountFormatted', - - 'total', - 'totalFormatted', - - 'discountAmount', - 'discountAmountFormatted', - 'discountPercentage', - 'discountPercentageFormatted', - 'discountLabel', - - 'adjustment', - 'adjustmentFormatted', - - 'subtotal', - 'subtotalFormatted', - - 'invoiceNo', - - 'entries', - - 'companyName', - 'companyLogoUri', - - 'primaryColor', - - 'customerName', - ]; - }; - - /** - * Retrieves the customer name of the invoice. - * @returns {string} - */ - protected customerName = (invoice) => { - return invoice.customer.displayName; - }; - - /** - * Retrieves the company name. - * @returns {string} - */ - protected companyName = () => { - return this.context.organization.name; - }; - - /** - * Retrieves the company logo uri. - * @returns {string | null} - */ - protected companyLogoUri = (invoice) => { - return invoice.pdfTemplate?.companyLogoUri; - }; - - /** - * Retrieves the primary color. - * @returns {string} - */ - protected primaryColor = (invoice) => { - return invoice.pdfTemplate?.attributes?.primaryColor; - }; - - /** - * Retrieves the discount label of the estimate. - * @param estimate - * @returns {string} - */ - protected discountLabel(invoice) { - return invoice.discountType === 'percentage' - ? `Discount [${invoice.discountPercentageFormatted}]` - : 'Discount'; - } - - /** - * - * @param invoice - * @returns - */ - protected entries = (invoice) => { - return this.item( - invoice.entries, - new GetSaleInvoiceMailStateEntryTransformer(), - { - currencyCode: invoice.currencyCode, - } - ); - }; - - /** - * Merges the mail options with the invoice object. - */ - public transform = (object: any) => { - return { - ...this.options.mailOptions, - ...object, - }; - }; -} - -class GetSaleInvoiceMailStateEntryTransformer extends ItemEntryTransformer { - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public name = (entry) => { - return entry.item.name; - }; - - public includeAttributes = (): string[] => { - return [ - 'name', - 'quantity', - 'quantityFormatted', - 'rate', - 'rateFormatted', - 'total', - 'totalFormatted', - ]; - }; -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceState.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceState.ts deleted file mode 100644 index 9f6934618..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceState.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISaleInvocieState } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class GetSaleInvoiceState { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the create/edit invoice state. - * @param {Number} saleInvoiceId - - * @return {Promise} - */ - public async getSaleInvoiceState( - tenantId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const defaultPdfTemplate = await PdfTemplate.query() - .findOne({ resource: 'SaleInvoice' }) - .modify('default'); - - return { - defaultTemplateId: defaultPdfTemplate?.id, - }; - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoices.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoices.ts deleted file mode 100644 index 9fe410883..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoices.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { - IFilterMeta, - IPaginationMeta, - ISaleInvoice, - ISalesInvoicesFilter, -} from '@/interfaces'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { SaleInvoiceTransformer } from './SaleInvoiceTransformer'; - -@Service() -export class GetSaleInvoices { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve sales invoices filterable and paginated list. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - public async getSaleInvoices( - tenantId: number, - filterDTO: ISalesInvoicesFilter - ): Promise<{ - salesInvoices: ISaleInvoice[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Parses stringified filter roles. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - SaleInvoice, - filter - ); - const { results, pagination } = await SaleInvoice.query() - .onBuild((builder) => { - builder.withGraphFetched('entries.item'); - builder.withGraphFetched('customer'); - dynamicFilter.buildQuery()(builder); - filterDTO?.filterQuery && filterDTO?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Retrieves the transformed sale invoices. - const salesInvoices = await this.transformer.transform( - tenantId, - results, - new SaleInvoiceTransformer() - ); - - return { - salesInvoices, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - } - - /** - * Parses the sale invoice list filter DTO. - * @param filterDTO - * @returns - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoicesPayable.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoicesPayable.ts deleted file mode 100644 index c81174376..000000000 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoicesPayable.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISaleInvoice } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class GetSaleInvoicesPayable { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieve due sales invoices. - * @param {number} tenantId - * @param {number} customerId - */ - public async getPayableInvoices( - tenantId: number, - customerId?: number - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const salesInvoices = await SaleInvoice.query().onBuild((query) => { - query.modify('dueInvoices'); - query.modify('delivered'); - - if (customerId) { - query.where('customer_id', customerId); - } - }); - return salesInvoices; - } -} diff --git a/packages/server/src/services/Sales/Invoices/InvoiceGLEntries.ts b/packages/server/src/services/Sales/Invoices/InvoiceGLEntries.ts deleted file mode 100644 index 570da2566..000000000 --- a/packages/server/src/services/Sales/Invoices/InvoiceGLEntries.ts +++ /dev/null @@ -1,354 +0,0 @@ -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { - ISaleInvoice, - IItemEntry, - ILedgerEntry, - AccountNormal, - ILedger, -} from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; - -@Service() -export class SaleInvoiceGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledegrRepository: LedgerStorageService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - /** - * Writes a sale invoice GL entries. - * @param {number} tenantId - Tenant id. - * @param {number} saleInvoiceId - Sale invoice id. - * @param {Knex.Transaction} trx - */ - public writeInvoiceGLEntries = async ( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ) => { - const { SaleInvoice } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - const saleInvoice = await SaleInvoice.query(trx) - .findById(saleInvoiceId) - .withGraphFetched('entries.item'); - - // Find or create the A/R account. - const ARAccount = await accountRepository.findOrCreateAccountReceivable( - saleInvoice.currencyCode, - {}, - trx - ); - // Find or create tax payable account. - const taxPayableAccount = await accountRepository.findOrCreateTaxPayable( - {}, - trx - ); - // Find or create the discount expense account. - const discountAccount = await accountRepository.findOrCreateDiscountAccount( - {}, - trx - ); - // Find or create the other charges account. - const otherChargesAccount = - await accountRepository.findOrCreateOtherChargesAccount({}, trx); - - // Retrieves the ledger of the invoice. - const ledger = this.getInvoiceGLedger( - saleInvoice, - ARAccount.id, - taxPayableAccount.id, - discountAccount.id, - otherChargesAccount.id - ); - // Commits the ledger entries to the storage as UOW. - await this.ledegrRepository.commit(tenantId, ledger, trx); - }; - - /** - * Rewrites the given invoice GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {Knex.Transaction} trx - */ - public rewritesInvoiceGLEntries = async ( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ) => { - // Reverts the invoice GL entries. - await this.revertInvoiceGLEntries(tenantId, saleInvoiceId, trx); - - // Writes the invoice GL entries. - await this.writeInvoiceGLEntries(tenantId, saleInvoiceId, trx); - }; - - /** - * Reverts the given invoice GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {Knex.Transaction} trx - */ - public revertInvoiceGLEntries = async ( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ) => { - await this.ledegrRepository.deleteByReference( - tenantId, - saleInvoiceId, - 'SaleInvoice', - trx - ); - }; - - /** - * Retrieves the given invoice ledger. - * @param {ISaleInvoice} saleInvoice - * @param {number} ARAccountId - * @returns {ILedger} - */ - public getInvoiceGLedger = ( - saleInvoice: ISaleInvoice, - ARAccountId: number, - taxPayableAccountId: number, - discountAccountId: number, - otherChargesAccountId: number - ): ILedger => { - const entries = this.getInvoiceGLEntries( - saleInvoice, - ARAccountId, - taxPayableAccountId, - discountAccountId, - otherChargesAccountId - ); - return new Ledger(entries); - }; - - /** - * Retrieves the invoice GL common entry. - * @param {ISaleInvoice} saleInvoice - * @returns {Partial} - */ - private getInvoiceGLCommonEntry = ( - saleInvoice: ISaleInvoice - ): Partial => ({ - credit: 0, - debit: 0, - - currencyCode: saleInvoice.currencyCode, - exchangeRate: saleInvoice.exchangeRate, - - transactionType: 'SaleInvoice', - transactionId: saleInvoice.id, - - date: saleInvoice.invoiceDate, - userId: saleInvoice.userId, - - transactionNumber: saleInvoice.invoiceNo, - referenceNumber: saleInvoice.referenceNo, - - createdAt: saleInvoice.createdAt, - indexGroup: 10, - - branchId: saleInvoice.branchId, - }); - - /** - * Retrieve receivable entry of the given invoice. - * @param {ISaleInvoice} saleInvoice - * @param {number} ARAccountId - * @returns {ILedgerEntry} - */ - private getInvoiceReceivableEntry = ( - saleInvoice: ISaleInvoice, - ARAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getInvoiceGLCommonEntry(saleInvoice); - - return { - ...commonEntry, - debit: saleInvoice.totalLocal, - accountId: ARAccountId, - contactId: saleInvoice.customerId, - accountNormal: AccountNormal.DEBIT, - index: 1, - } as ILedgerEntry; - }; - - /** - * Retrieve item income entry of the given invoice. - * @param {ISaleInvoice} saleInvoice - - * @param {IItemEntry} entry - - * @param {number} index - - * @returns {ILedgerEntry} - */ - private getInvoiceItemEntry = R.curry( - ( - saleInvoice: ISaleInvoice, - entry: IItemEntry, - index: number - ): ILedgerEntry => { - const commonEntry = this.getInvoiceGLCommonEntry(saleInvoice); - const localAmount = entry.totalExcludingTax * saleInvoice.exchangeRate; - - return { - ...commonEntry, - credit: localAmount, - accountId: entry.sellAccountId, - note: entry.description, - index: index + 2, - itemId: entry.itemId, - itemQuantity: entry.quantity, - accountNormal: AccountNormal.CREDIT, - projectId: entry.projectId || saleInvoice.projectId, - taxRateId: entry.taxRateId, - taxRate: entry.taxRate, - }; - } - ); - - /** - * Retreives the GL entry of tax payable. - * @param {ISaleInvoice} saleInvoice - - * @param {number} taxPayableAccountId - - * @returns {ILedgerEntry} - */ - private getInvoiceTaxEntry = R.curry( - ( - saleInvoice: ISaleInvoice, - taxPayableAccountId: number, - entry: IItemEntry, - index: number - ): ILedgerEntry => { - const commonEntry = this.getInvoiceGLCommonEntry(saleInvoice); - - return { - ...commonEntry, - credit: entry.taxAmount, - accountId: taxPayableAccountId, - index: index + 1, - indexGroup: 30, - accountNormal: AccountNormal.CREDIT, - taxRateId: entry.taxRateId, - taxRate: entry.taxRate, - }; - } - ); - - /** - * Retrieves the invoice tax GL entries. - * @param {ISaleInvoice} saleInvoice - * @param {number} taxPayableAccountId - * @returns {ILedgerEntry[]} - */ - private getInvoiceTaxEntries = ( - saleInvoice: ISaleInvoice, - taxPayableAccountId: number - ): ILedgerEntry[] => { - // Retrieves the non-zero tax entries. - const nonZeroTaxEntries = this.itemsEntriesService.getNonZeroEntries( - saleInvoice.entries - ); - const transformTaxEntry = this.getInvoiceTaxEntry( - saleInvoice, - taxPayableAccountId - ); - // Transforms the non-zero tax entries to GL entries. - return nonZeroTaxEntries.map(transformTaxEntry); - }; - - /** - * Retrieves the invoice discount GL entry. - * @param {ISaleInvoice} saleInvoice - * @param {number} discountAccountId - * @returns {ILedgerEntry} - */ - private getInvoiceDiscountEntry = ( - saleInvoice: ISaleInvoice, - discountAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getInvoiceGLCommonEntry(saleInvoice); - - return { - ...commonEntry, - debit: saleInvoice.discountAmountLocal, - accountId: discountAccountId, - accountNormal: AccountNormal.CREDIT, - index: 1, - } as ILedgerEntry; - }; - - /** - * Retrieves the invoice adjustment GL entry. - * @param {ISaleInvoice} saleInvoice - * @param {number} adjustmentAccountId - * @returns {ILedgerEntry} - */ - private getAdjustmentEntry = ( - saleInvoice: ISaleInvoice, - otherChargesAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getInvoiceGLCommonEntry(saleInvoice); - const adjustmentAmount = Math.abs(saleInvoice.adjustmentLocal); - - return { - ...commonEntry, - debit: saleInvoice.adjustmentLocal < 0 ? adjustmentAmount : 0, - credit: saleInvoice.adjustmentLocal > 0 ? adjustmentAmount : 0, - accountId: otherChargesAccountId, - accountNormal: AccountNormal.CREDIT, - index: 1, - }; - }; - - /** - * Retrieves the invoice GL entries. - * @param {ISaleInvoice} saleInvoice - * @param {number} ARAccountId - * @returns {ILedgerEntry[]} - */ - public getInvoiceGLEntries = ( - saleInvoice: ISaleInvoice, - ARAccountId: number, - taxPayableAccountId: number, - discountAccountId: number, - otherChargesAccountId: number - ): ILedgerEntry[] => { - const receivableEntry = this.getInvoiceReceivableEntry( - saleInvoice, - ARAccountId - ); - const transformItemEntry = this.getInvoiceItemEntry(saleInvoice); - const creditEntries = saleInvoice.entries.map(transformItemEntry); - - const taxEntries = this.getInvoiceTaxEntries( - saleInvoice, - taxPayableAccountId - ); - const discountEntry = this.getInvoiceDiscountEntry( - saleInvoice, - discountAccountId - ); - const adjustmentEntry = this.getAdjustmentEntry( - saleInvoice, - otherChargesAccountId - ); - return [ - receivableEntry, - ...creditEntries, - ...taxEntries, - discountEntry, - adjustmentEntry, - ]; - }; -} diff --git a/packages/server/src/services/Sales/Invoices/InvoiceInventoryTransactions.ts b/packages/server/src/services/Sales/Invoices/InvoiceInventoryTransactions.ts deleted file mode 100644 index 4a6618727..000000000 --- a/packages/server/src/services/Sales/Invoices/InvoiceInventoryTransactions.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ISaleInvoice } from '@/interfaces'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import InventoryService from '@/services/Inventory/Inventory'; - -@Service() -export class InvoiceInventoryTransactions { - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private inventoryService: InventoryService; - - /** - * Records the inventory transactions of the given sale invoice in case - * the invoice has inventory entries only. - * - * @param {number} tenantId - Tenant id. - * @param {SaleInvoice} saleInvoice - Sale invoice DTO. - * @param {number} saleInvoiceId - Sale invoice id. - * @param {boolean} override - Allow to override old transactions. - * @return {Promise} - */ - public async recordInventoryTranscactions( - tenantId: number, - saleInvoice: ISaleInvoice, - override?: boolean, - trx?: Knex.Transaction - ): Promise { - // Loads the inventory items entries of the given sale invoice. - const inventoryEntries = - await this.itemsEntriesService.filterInventoryEntries( - tenantId, - saleInvoice.entries, - trx - ); - const transaction = { - transactionId: saleInvoice.id, - transactionType: 'SaleInvoice', - transactionNumber: saleInvoice.invoiceNo, - - exchangeRate: saleInvoice.exchangeRate, - warehouseId: saleInvoice.warehouseId, - - date: saleInvoice.invoiceDate, - direction: 'OUT', - entries: inventoryEntries, - createdAt: saleInvoice.createdAt, - }; - await this.inventoryService.recordInventoryTransactionsFromItemsEntries( - tenantId, - transaction, - override, - trx - ); - } - /** - * Reverting the inventory transactions once the invoice deleted. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Bill id. - * @return {Promise} - */ - public async revertInventoryTransactions( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ): Promise { - // Delete the inventory transaction of the given sale invoice. - const { oldInventoryTransactions } = - await this.inventoryService.deleteInventoryTransactions( - tenantId, - saleInvoiceId, - 'SaleInvoice', - trx - ); - } -} diff --git a/packages/server/src/services/Sales/Invoices/InvoicePaymentTransactionTransformer.ts b/packages/server/src/services/Sales/Invoices/InvoicePaymentTransactionTransformer.ts deleted file mode 100644 index 23d548a0f..000000000 --- a/packages/server/src/services/Sales/Invoices/InvoicePaymentTransactionTransformer.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class InvoicePaymentTransactionTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['formattedPaymentAmount', 'formattedPaymentDate']; - }; - - /** - * Retrieve formatted invoice amount. - * @param {ICreditNote} credit - * @returns {string} - */ - protected formattedPaymentAmount = (entry): string => { - return formatNumber(entry.paymentAmount, { - currencyCode: entry.payment.currencyCode, - }); - }; - - /** - * Formatted payment date. - * @param entry - * @returns {string} - */ - protected formattedPaymentDate = (entry): string => { - return this.formatDate(entry.payment.paymentDate); - }; - - /** - * - * @param entry - * @returns - */ - public transform = (entry) => { - return { - invoiceId: entry.invoiceId, - paymentReceiveId: entry.paymentReceiveId, - - paymentDate: entry.payment.paymentDate, - formattedPaymentDate: entry.formattedPaymentDate, - - paymentAmount: entry.paymentAmount, - formattedPaymentAmount: entry.formattedPaymentAmount, - currencyCode: entry.payment.currencyCode, - - paymentNumber: entry.payment.paymentReceiveNo, - paymentReferenceNo: entry.payment.referenceNo, - - invoiceNumber: entry.invoice.invoiceNo, - invoiceReferenceNo: entry.invoice.referenceNo, - - depositAccountId: entry.payment.depositAccountId, - depositAccountName: entry.payment.depositAccount.name, - depositAccountSlug: entry.payment.depositAccount.slug, - }; - }; -} diff --git a/packages/server/src/services/Sales/Invoices/InvoicePaymentsGLRewrite.ts b/packages/server/src/services/Sales/Invoices/InvoicePaymentsGLRewrite.ts deleted file mode 100644 index 9e9998647..000000000 --- a/packages/server/src/services/Sales/Invoices/InvoicePaymentsGLRewrite.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Knex } from 'knex'; -import async from 'async'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { PaymentReceivedGLEntries } from '../PaymentReceived/PaymentReceivedGLEntries'; - -@Service() -export class InvoicePaymentsGLEntriesRewrite { - @Inject() - public tenancy: HasTenancyService; - - @Inject() - public paymentGLEntries: PaymentReceivedGLEntries; - - /** - * Rewrites the payment GL entries task. - * @param {{ tenantId: number, paymentId: number, trx: Knex?.Transaction }} - * @returns {Promise} - */ - public rewritePaymentsGLEntriesTask = async ({ - tenantId, - paymentId, - trx, - }) => { - await this.paymentGLEntries.rewritePaymentGLEntries( - tenantId, - paymentId, - trx - ); - }; - - /** - * Rewrites the payment GL entries of the given payments ids. - * @param {number} tenantId - * @param {number[]} paymentsIds - * @param {Knex.Transaction} trx - */ - public rewritePaymentsGLEntriesQueue = async ( - tenantId: number, - paymentsIds: number[], - trx?: Knex.Transaction - ) => { - // Initiate a new queue for accounts balance mutation. - const rewritePaymentGL = async.queue(this.rewritePaymentsGLEntriesTask, 10); - - paymentsIds.forEach((paymentId: number) => { - rewritePaymentGL.push({ paymentId, trx, tenantId }); - }); - if (paymentsIds.length > 0) { - await rewritePaymentGL.drain(); - } - }; - - /** - * Rewrites the payments GL entries that associated to the given invoice. - * @param {number} tenantId - * @param {number} invoiceId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public invoicePaymentsGLEntriesRewrite = async ( - tenantId: number, - invoiceId: number, - trx?: Knex.Transaction - ) => { - const { PaymentReceiveEntry } = this.tenancy.models(tenantId); - - const invoicePaymentEntries = await PaymentReceiveEntry.query().where( - 'invoiceId', - invoiceId - ); - const paymentsIds = invoicePaymentEntries.map((e) => e.paymentReceiveId); - - await this.rewritePaymentsGLEntriesQueue(tenantId, paymentsIds, trx); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/ItemEntryTransformer.ts b/packages/server/src/services/Sales/Invoices/ItemEntryTransformer.ts deleted file mode 100644 index 5fcf33b85..000000000 --- a/packages/server/src/services/Sales/Invoices/ItemEntryTransformer.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { DiscountType, IItemEntry } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from '@/utils'; - -export class ItemEntryTransformer extends Transformer { - /** - * Include these attributes to item entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'quantityFormatted', - 'rateFormatted', - 'totalFormatted', - 'discountFormatted', - 'discountAmountFormatted', - ]; - }; - - /** - * Retrieves the formatted quantitty of item entry. - * @param {IItemEntry} entry - * @returns {string} - */ - protected quantityFormatted = (entry: IItemEntry): string => { - return formatNumber(entry.quantity, { money: false }); - }; - - /** - * Retrieves the formatted rate of item entry. - * @param {IItemEntry} itemEntry - - * @returns {string} - */ - protected rateFormatted = (entry: IItemEntry): string => { - return formatNumber(entry.rate, { - currencyCode: this.context.currencyCode, - money: false, - }); - }; - - /** - * Retrieves the formatted total of item entry. - * @param {IItemEntry} entry - * @returns {string} - */ - protected totalFormatted = (entry: IItemEntry): string => { - return formatNumber(entry.total, { - currencyCode: this.context.currencyCode, - money: false, - }); - }; - - /** - * Retrieves the formatted discount of item entry. - * @param {IItemEntry} entry - * @returns {string} - */ - protected discountFormatted = (entry: IItemEntry): string => { - if (!entry.discount) { - return ''; - } - return entry.discountType === DiscountType.Percentage - ? `${entry.discount}%` - : formatNumber(entry.discount, { - currencyCode: this.context.currencyCode, - money: false, - }); - }; - - /** - * Retrieves the formatted discount amount of item entry. - * @param {IItemEntry} entry - * @returns {string} - */ - protected discountAmountFormatted = (entry: IItemEntry): string => { - return formatNumber(entry.discountAmount, { - currencyCode: this.context.currencyCode, - money: false, - excerptZero: true, - }); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts b/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts deleted file mode 100644 index 544468b49..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { mergePdfTemplateWithDefaultAttributes } from './utils'; -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { defaultEstimatePdfBrandingAttributes } from '../Estimates/constants'; -import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes'; - -@Service() -export class SaleEstimatePdfTemplate { - @Inject() - private getPdfTemplateService: GetPdfTemplate; - - @Inject() - private getOrgBrandingAttrs: GetOrganizationBrandingAttributes; - - /** - * Retrieves the estimate pdf template. - * @param {number} tenantId - * @param {number} invoiceTemplateId - * @returns - */ - async getEstimatePdfTemplate(tenantId: number, estimateTemplateId: number) { - const template = await this.getPdfTemplateService.getPdfTemplate( - tenantId, - estimateTemplateId - ); - // Retreives the organization branding attributes. - const commonOrgBrandingAttrs = - await this.getOrgBrandingAttrs.getOrganizationBrandingAttributes( - tenantId - ); - // Merge the default branding attributes with organization attrs. - const orgainizationBrandingAttrs = { - ...defaultEstimatePdfBrandingAttributes, - ...commonOrgBrandingAttrs, - }; - const brandingTemplateAttrs = { - ...template.attributes, - companyLogoUri: template.companyLogoUri, - }; - const attributes = mergePdfTemplateWithDefaultAttributes( - brandingTemplateAttrs, - orgainizationBrandingAttrs - ); - return { - ...template, - attributes, - }; - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceCostGLEntries.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceCostGLEntries.ts deleted file mode 100644 index ff480fe28..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceCostGLEntries.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { AccountNormal, IInventoryLotCost, ILedgerEntry } from '@/interfaces'; -import { increment } from 'utils'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import { groupInventoryTransactionsByTypeId } from '../../Inventory/utils'; - -@Service() -export class SaleInvoiceCostGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Writes journal entries from sales invoices. - * @param {number} tenantId - The tenant id. - * @param {Date} startingDate - Starting date. - * @param {boolean} override - */ - public writeInventoryCostJournalEntries = async ( - tenantId: number, - startingDate: Date, - trx?: Knex.Transaction - ): Promise => { - const { InventoryCostLotTracker } = this.tenancy.models(tenantId); - - const inventoryCostLotTrans = await InventoryCostLotTracker.query() - .where('direction', 'OUT') - .where('transaction_type', 'SaleInvoice') - .where('cost', '>', 0) - .modify('filterDateRange', startingDate) - .orderBy('date', 'ASC') - .withGraphFetched('invoice') - .withGraphFetched('item'); - - const ledger = this.getInventoryCostLotsLedger(inventoryCostLotTrans); - - // Commit the ledger to the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Retrieves the inventory cost lots ledger. - * @param {IInventoryLotCost[]} inventoryCostLots - * @returns {Ledger} - */ - private getInventoryCostLotsLedger = ( - inventoryCostLots: IInventoryLotCost[] - ) => { - // Groups the inventory cost lots transactions. - const inventoryTransactions = - groupInventoryTransactionsByTypeId(inventoryCostLots); - - const entries = inventoryTransactions - .map(this.getSaleInvoiceCostGLEntries) - .flat(); - return new Ledger(entries); - }; - - /** - * - * @param {IInventoryLotCost} inventoryCostLot - * @returns {} - */ - private getInvoiceCostGLCommonEntry = ( - inventoryCostLot: IInventoryLotCost - ) => { - return { - currencyCode: inventoryCostLot.invoice.currencyCode, - exchangeRate: inventoryCostLot.invoice.exchangeRate, - - transactionType: inventoryCostLot.transactionType, - transactionId: inventoryCostLot.transactionId, - - date: inventoryCostLot.date, - indexGroup: 20, - costable: true, - createdAt: inventoryCostLot.createdAt, - - debit: 0, - credit: 0, - - branchId: inventoryCostLot.invoice.branchId, - }; - }; - - /** - * Retrieves the inventory cost GL entry. - * @param {IInventoryLotCost} inventoryLotCost - * @returns {ILedgerEntry[]} - */ - private getInventoryCostGLEntry = R.curry( - ( - getIndexIncrement, - inventoryCostLot: IInventoryLotCost - ): ILedgerEntry[] => { - const commonEntry = this.getInvoiceCostGLCommonEntry(inventoryCostLot); - const costAccountId = - inventoryCostLot.costAccountId || inventoryCostLot.item.costAccountId; - - // XXX Debit - Cost account. - const costEntry = { - ...commonEntry, - debit: inventoryCostLot.cost, - accountId: costAccountId, - accountNormal: AccountNormal.DEBIT, - itemId: inventoryCostLot.itemId, - index: getIndexIncrement(), - }; - // XXX Credit - Inventory account. - const inventoryEntry = { - ...commonEntry, - credit: inventoryCostLot.cost, - accountId: inventoryCostLot.item.inventoryAccountId, - accountNormal: AccountNormal.DEBIT, - itemId: inventoryCostLot.itemId, - index: getIndexIncrement(), - }; - return [costEntry, inventoryEntry]; - } - ); - - /** - * Writes journal entries for given sale invoice. - * ----- - * - Cost of goods sold -> Debit -> YYYY - * - Inventory assets -> Credit -> YYYY - *----- - * @param {ISaleInvoice} saleInvoice - * @param {JournalPoster} journal - */ - public getSaleInvoiceCostGLEntries = ( - inventoryCostLots: IInventoryLotCost[] - ): ILedgerEntry[] => { - const getIndexIncrement = increment(0); - const getInventoryLotEntry = - this.getInventoryCostGLEntry(getIndexIncrement); - - return inventoryCostLots.map(getInventoryLotEntry).flat(); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceIncrement.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceIncrement.ts deleted file mode 100644 index 887ee31a2..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceIncrement.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import AutoIncrementOrdersService from '../AutoIncrementOrdersService'; - -@Service() -export class SaleInvoiceIncrement { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - /** - * Retrieves the next unique invoice number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - public getNextInvoiceNumber(tenantId: number): string { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'sales_invoices' - ); - } - - /** - * Increment the invoice next number. - * @param {number} tenantId - - */ - public incrementNextInvoiceNumber(tenantId: number) { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'sales_invoices' - ); - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceNotifyBySms.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceNotifyBySms.ts deleted file mode 100644 index 1eff51f6e..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceNotifyBySms.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { - ISaleInvoice, - ISaleInvoiceSmsDetailsDTO, - ISaleInvoiceSmsDetails, - SMS_NOTIFICATION_KEY, - InvoiceNotificationType, - ICustomer, -} from '@/interfaces'; -import SmsNotificationsSettingsService from '@/services/Settings/SmsNotificationsSettings'; -import { formatSmsMessage, formatNumber } from 'utils'; -import { TenantMetadata } from '@/system/models'; -import SaleNotifyBySms from '../SaleNotifyBySms'; -import { ServiceError } from '@/exceptions'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { ERRORS } from './constants'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; - -@Service() -export class SaleInvoiceNotifyBySms { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private smsNotificationsSettings: SmsNotificationsSettingsService; - - @Inject() - private saleSmsNotification: SaleNotifyBySms; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - /** - * Notify customer via sms about sale invoice. - * @param {number} tenantId - Tenant id. - * @param {number} saleInvoiceId - Sale invoice id. - */ - public notifyBySms = async ( - tenantId: number, - saleInvoiceId: number, - invoiceNotificationType: InvoiceNotificationType - ) => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const saleInvoice = await SaleInvoice.query() - .findById(saleInvoiceId) - .withGraphFetched('customer'); - - // Validates the givne invoice existance. - this.validators.validateInvoiceExistance(saleInvoice); - - // Validate the customer phone number existance and number validation. - this.saleSmsNotification.validateCustomerPhoneNumber( - saleInvoice.customer.personalPhone - ); - // Transformes the invoice notification key to sms notification key. - const notificationKey = this.transformDTOKeyToNotificationKey( - invoiceNotificationType - ); - // Triggers `onSaleInvoiceNotifySms` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onNotifySms, { - tenantId, - saleInvoice, - }); - // Formattes the sms message and sends sms notification. - await this.sendSmsNotification(tenantId, notificationKey, saleInvoice); - - // Triggers `onSaleInvoiceNotifySms` event. - await this.eventPublisher.emitAsync(events.saleInvoice.onNotifiedSms, { - tenantId, - saleInvoice, - }); - return saleInvoice; - }; - - /** - * Notify invoice details by sms notification after invoice creation. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {Promise} - */ - public notifyDetailsBySmsAfterCreation = async ( - tenantId: number, - saleInvoiceId: number - ): Promise => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS - ); - // Can't continue if the sms auto-notification is not enabled. - if (!notification.isNotificationEnabled) return; - - await this.notifyBySms(tenantId, saleInvoiceId, 'details'); - }; - - /** - * Sends SMS notification. - * @param {ISaleInvoice} invoice - * @param {ICustomer} customer - * @returns {Promise} - */ - private sendSmsNotification = async ( - tenantId: number, - notificationType: - | SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS - | SMS_NOTIFICATION_KEY.SALE_INVOICE_REMINDER, - invoice: ISaleInvoice & { customer: ICustomer } - ): Promise => { - const smsClient = this.tenancy.smsClient(tenantId); - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Formates the given sms message. - const message = this.formattedInvoiceDetailsMessage( - tenantId, - notificationType, - invoice, - tenantMetadata - ); - const phoneNumber = invoice.customer.personalPhone; - - // Run the send sms notification message job. - await smsClient.sendMessageJob(phoneNumber, message); - }; - - /** - * Formates the invoice details sms message. - * @param {number} tenantId - * @param {ISaleInvoice} invoice - * @param {ICustomer} customer - * @returns {string} - */ - private formattedInvoiceDetailsMessage = ( - tenantId: number, - notificationKey: - | SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS - | SMS_NOTIFICATION_KEY.SALE_INVOICE_REMINDER, - invoice: ISaleInvoice, - tenantMetadata: TenantMetadata - ): string => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - notificationKey - ); - return this.formatInvoiceDetailsMessage( - notification.smsMessage, - invoice, - tenantMetadata - ); - }; - - /** - * Formattees the given invoice details sms message. - * @param {string} smsMessage - * @param {ISaleInvoice} invoice - * @param {ICustomer} customer - * @param {TenantMetadata} tenantMetadata - */ - private formatInvoiceDetailsMessage = ( - smsMessage: string, - invoice: ISaleInvoice & { customer: ICustomer }, - tenantMetadata: TenantMetadata - ) => { - const formattedDueAmount = formatNumber(invoice.dueAmount, { - currencyCode: invoice.currencyCode, - }); - const formattedAmount = formatNumber(invoice.balance, { - currencyCode: invoice.currencyCode, - }); - - return formatSmsMessage(smsMessage, { - InvoiceNumber: invoice.invoiceNo, - ReferenceNumber: invoice.referenceNo, - CustomerName: invoice.customer.displayName, - DueAmount: formattedDueAmount, - DueDate: moment(invoice.dueDate).format('YYYY/MM/DD'), - Amount: formattedAmount, - CompanyName: tenantMetadata.name, - }); - }; - - /** - * Retrieve the SMS details of the given invoice. - * @param {number} tenantId - Tenant id. - * @param {number} saleInvoiceId - Sale invoice id. - */ - public smsDetails = async ( - tenantId: number, - saleInvoiceId: number, - invoiceSmsDetailsDTO: ISaleInvoiceSmsDetailsDTO - ): Promise => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Retrieve the sale invoice or throw not found service error. - const saleInvoice = await SaleInvoice.query() - .findById(saleInvoiceId) - .withGraphFetched('customer'); - - // Validates the sale invoice existance. - this.validateSaleInvoiceExistance(saleInvoice); - - // Current tenant metadata. - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Transformes the invoice notification key to sms notification key. - const notificationKey = this.transformDTOKeyToNotificationKey( - invoiceSmsDetailsDTO.notificationKey - ); - // Formates the given sms message. - const smsMessage = this.formattedInvoiceDetailsMessage( - tenantId, - notificationKey, - saleInvoice, - tenantMetadata - ); - - return { - customerName: saleInvoice.customer.displayName, - customerPhoneNumber: saleInvoice.customer.personalPhone, - smsMessage, - }; - }; - - /** - * Transformes the invoice notification key DTO to notification key. - * @param {string} invoiceNotifKey - * @returns {SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS - * | SMS_NOTIFICATION_KEY.SALE_INVOICE_REMINDER} - */ - private transformDTOKeyToNotificationKey = ( - invoiceNotifKey: string - ): - | SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS - | SMS_NOTIFICATION_KEY.SALE_INVOICE_REMINDER => { - const invoiceNotifKeyPairs = { - details: SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS, - reminder: SMS_NOTIFICATION_KEY.SALE_INVOICE_REMINDER, - }; - return ( - invoiceNotifKeyPairs[invoiceNotifKey] || - SMS_NOTIFICATION_KEY.SALE_INVOICE_DETAILS - ); - }; - - /** - * Validates the sale invoice existance. - * @param {ISaleInvoice|null} saleInvoice - */ - private validateSaleInvoiceExistance(saleInvoice: ISaleInvoice | null) { - if (!saleInvoice) { - throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicePdf.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicePdf.ts deleted file mode 100644 index 1c492b9ce..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicePdf.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - renderInvoicePaperTemplateHtml, - InvoicePaperTemplateProps, -} from '@bigcapital/pdf-templates'; -import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy'; -import { GetSaleInvoice } from './GetSaleInvoice'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { transformInvoiceToPdfTemplate } from './utils'; -import { SaleInvoicePdfTemplate } from './SaleInvoicePdfTemplate'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class SaleInvoicePdf { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - @Inject() - private getInvoiceService: GetSaleInvoice; - - @Inject() - private invoiceBrandingTemplateService: SaleInvoicePdfTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieve sale invoice html content. - * @param {number} tenantId - Tenant Id. - * @param {ISaleInvoice} saleInvoice - - * @returns {Promise} - */ - public async saleInvoiceHtml( - tenantId: number, - invoiceId: number - ): Promise { - const brandingAttributes = await this.getInvoiceBrandingAttributes( - tenantId, - invoiceId - ); - return renderInvoicePaperTemplateHtml({ - ...brandingAttributes, - }); - } - - /** - * Retrieve sale invoice pdf content. - * @param {number} tenantId - Tenant Id. - * @param {ISaleInvoice} saleInvoice - - * @returns {Promise<[Buffer, string]>} - */ - public async saleInvoicePdf( - tenantId: number, - invoiceId: number - ): Promise<[Buffer, string]> { - const filename = await this.getInvoicePdfFilename(tenantId, invoiceId); - - const htmlContent = await this.saleInvoiceHtml(tenantId, invoiceId); - - // Converts the given html content to pdf document. - const buffer = await this.chromiumlyTenancy.convertHtmlContent( - tenantId, - htmlContent - ); - const eventPayload = { tenantId, saleInvoiceId: invoiceId }; - - // Triggers the `onSaleInvoicePdfViewed` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onPdfViewed, - eventPayload - ); - return [buffer, filename]; - } - - /** - * Retrieves the filename pdf document of the given invoice. - * @param {number} tenantId - * @param {number} invoiceId - * @returns {Promise} - */ - private async getInvoicePdfFilename( - tenantId: number, - invoiceId: number - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const invoice = await SaleInvoice.query().findById(invoiceId); - - return `Invoice-${invoice.invoiceNo}`; - } - - /** - * Retrieves the branding attributes of the given sale invoice. - * @param {number} tenantId - * @param {number} invoiceId - * @returns {Promise} - */ - async getInvoiceBrandingAttributes( - tenantId: number, - invoiceId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const invoice = await this.getInvoiceService.getSaleInvoice( - tenantId, - invoiceId - ); - // Retrieve the invoice template id of not found get the default template id. - const templateId = - invoice.pdfTemplateId ?? - ( - await PdfTemplate.query().findOne({ - resource: 'SaleInvoice', - default: true, - }) - )?.id; - // Getting the branding template attributes. - const brandingTemplate = - await this.invoiceBrandingTemplateService.getInvoicePdfTemplate( - tenantId, - templateId - ); - // Merge the branding template attributes with the invoice. - return { - ...brandingTemplate.attributes, - ...transformInvoiceToPdfTemplate(invoice), - }; - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts deleted file mode 100644 index e7cffd69f..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { mergePdfTemplateWithDefaultAttributes } from './utils'; -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { defaultInvoicePdfTemplateAttributes } from './constants'; -import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes'; - -@Service() -export class SaleInvoicePdfTemplate { - @Inject() - private getPdfTemplateService: GetPdfTemplate; - - @Inject() - private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; - - /** - * Retrieves the invoice pdf template. - * @param {number} tenantId - * @param {number} invoiceTemplateId - * @returns - */ - async getInvoicePdfTemplate(tenantId: number, invoiceTemplateId: number) { - const template = await this.getPdfTemplateService.getPdfTemplate( - tenantId, - invoiceTemplateId - ); - // Retrieves the organization branding attributes. - const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes( - tenantId - ); - const organizationBrandingAttrs = { - ...defaultInvoicePdfTemplateAttributes, - ...commonOrgBrandingAttrs, - }; - const brandingTemplateAttrs = { - ...template.attributes, - companyLogoUri: template.companyLogoUri, - }; - const attributes = mergePdfTemplateWithDefaultAttributes( - brandingTemplateAttrs, - organizationBrandingAttrs - ); - return { - ...template, - attributes, - }; - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceTaxEntryTransformer.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceTaxEntryTransformer.ts deleted file mode 100644 index ae4e9c87e..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceTaxEntryTransformer.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from '@/utils'; -import { getExlusiveTaxAmount, getInclusiveTaxAmount } from '@/utils/taxRate'; -import { format } from 'mathjs'; - -export class SaleInvoiceTaxEntryTransformer extends Transformer { - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'name', - 'taxRateCode', - 'taxRate', - 'taxRateId', - 'taxRateAmount', - 'taxRateAmountFormatted', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieve tax rate code. - * @param taxEntry - * @returns {string} - */ - protected taxRateCode = (taxEntry) => { - return taxEntry.taxRate.code; - }; - - /** - * Retrieve tax rate id. - * @param taxEntry - * @returns {number} - */ - protected taxRate = (taxEntry) => { - return taxEntry.taxAmount || taxEntry.taxRate.rate; - }; - - /** - * Retrieve tax rate name. - * @param taxEntry - * @returns {string} - */ - protected name = (taxEntry) => { - return taxEntry.taxRate.name; - }; - - /** - * Retrieve tax rate amount. - * @param taxEntry - */ - protected taxRateAmount = (taxEntry) => { - const taxRate = this.taxRate(taxEntry); - - return this.options.isInclusiveTax - ? getInclusiveTaxAmount(this.options.subtotal, taxRate) - : getExlusiveTaxAmount(this.options.subtotal, taxRate); - }; - - /** - * Retrieve formatted tax rate amount. - * @returns {string} - */ - protected taxRateAmountFormatted = (taxEntry) => { - return formatNumber(this.taxRateAmount(taxEntry), { - currencyCode: this.options.currencyCode, - }); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceTransformer.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceTransformer.ts deleted file mode 100644 index 05dce98b7..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceTransformer.ts +++ /dev/null @@ -1,253 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer'; -import { ItemEntryTransformer } from './ItemEntryTransformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; -import { DiscountType } from '@/interfaces'; - -export class SaleInvoiceTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'invoiceDateFormatted', - 'dueDateFormatted', - 'createdAtFormatted', - 'dueAmountFormatted', - 'paymentAmountFormatted', - 'balanceAmountFormatted', - 'exchangeRateFormatted', - 'subtotalFormatted', - 'subtotalLocalFormatted', - 'subtotalExludingTaxFormatted', - 'taxAmountWithheldFormatted', - 'taxAmountWithheldLocalFormatted', - 'discountAmountFormatted', - 'discountPercentageFormatted', - 'adjustmentFormatted', - 'totalFormatted', - 'totalLocalFormatted', - 'taxes', - 'entries', - 'attachments', - ]; - }; - - /** - * Retrieve formatted invoice date. - * @param {ISaleInvoice} invoice - * @returns {String} - */ - protected invoiceDateFormatted = (invoice): string => { - return this.formatDate(invoice.invoiceDate); - }; - - /** - * Retrieve formatted due date. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected dueDateFormatted = (invoice): string => { - return this.formatDate(invoice.dueDate); - }; - - /** - * Retrieve the formatted created at date. - * @param invoice - * @returns {string} - */ - protected createdAtFormatted = (invoice): string => { - return this.formatDate(invoice.createdAt); - }; - - /** - * Retrieve formatted invoice due amount. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected dueAmountFormatted = (invoice): string => { - return formatNumber(invoice.dueAmount, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieve formatted payment amount. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected paymentAmountFormatted = (invoice): string => { - return formatNumber(invoice.paymentAmount, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieve the formatted invoice balance. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected balanceAmountFormatted = (invoice): string => { - return formatNumber(invoice.balanceAmount, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieve the formatted exchange rate. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected exchangeRateFormatted = (invoice): string => { - return formatNumber(invoice.exchangeRate, { money: false }); - }; - - /** - * Retrieves formatted subtotal in base currency. - * (Tax inclusive if the tax inclusive is enabled) - * @param invoice - * @returns {string} - */ - protected subtotalFormatted = (invoice): string => { - return formatNumber(invoice.subtotal, { - currencyCode: this.context.organization.baseCurrency, - money: false, - }); - }; - - /** - * Retrieves formatted subtotal in foreign currency. - * (Tax inclusive if the tax inclusive is enabled) - * @param invoice - * @returns {string} - */ - protected subtotalLocalFormatted = (invoice): string => { - return formatNumber(invoice.subtotalLocal, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieves formatted subtotal excluding tax in foreign currency. - * @param invoice - * @returns {string} - */ - protected subtotalExludingTaxFormatted = (invoice): string => { - return formatNumber(invoice.subtotalExludingTax, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieves formatted tax amount withheld in foreign currency. - * @param invoice - * @returns {string} - */ - protected taxAmountWithheldFormatted = (invoice): string => { - return formatNumber(invoice.taxAmountWithheld, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieves formatted tax amount withheld in base currency. - * @param invoice - * @returns {string} - */ - protected taxAmountWithheldLocalFormatted = (invoice): string => { - return formatNumber(invoice.taxAmountWithheldLocal, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieves formatted discount amount. - * @param invoice - * @returns {string} - */ - protected discountAmountFormatted = (invoice): string => { - return formatNumber(invoice.discountAmount, { - currencyCode: invoice.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves formatted discount percentage. - * @param invoice - * @returns {string} - */ - protected discountPercentageFormatted = (invoice): string => { - return invoice.discountType === DiscountType.Percentage - ? `${invoice.discount}%` - : ''; - }; - - /** - * Retrieves formatted adjustment amount. - * @param invoice - * @returns {string} - */ - protected adjustmentFormatted = (invoice): string => { - return this.formatMoney(invoice.adjustment, { - currencyCode: invoice.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves formatted total in foreign currency. - * @param invoice - * @returns {string} - */ - protected totalFormatted = (invoice): string => { - return formatNumber(invoice.total, { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieves formatted total in base currency. - * @param invoice - * @returns {string} - */ - protected totalLocalFormatted = (invoice): string => { - return formatNumber(invoice.totalLocal, { - currencyCode: this.context.organization.baseCurrency, - }); - }; - - /** - * Retrieve the taxes lines of sale invoice. - * @param {ISaleInvoice} invoice - */ - protected taxes = (invoice) => { - return this.item(invoice.taxes, new SaleInvoiceTaxEntryTransformer(), { - subtotal: invoice.subtotal, - isInclusiveTax: invoice.isInclusiveTax, - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieves the entries of the sale invoice. - * @param {ISaleInvoice} invoice - * @returns {} - */ - protected entries = (invoice) => { - return this.item(invoice.entries, new ItemEntryTransformer(), { - currencyCode: invoice.currencyCode, - }); - }; - - /** - * Retrieves the sale invoice attachments. - * @param {ISaleInvoice} invoice - * @returns - */ - protected attachments = (invoice) => { - return this.item(invoice.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLEntries.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLEntries.ts deleted file mode 100644 index 75225d95f..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLEntries.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Service } from 'typedi'; -import { ISaleInvoice, AccountNormal, ILedgerEntry, ILedger } from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export class SaleInvoiceWriteoffGLEntries { - /** - * Retrieves the invoice write-off common GL entry. - * @param {ISaleInvoice} saleInvoice - */ - private getInvoiceWriteoffGLCommonEntry = (saleInvoice: ISaleInvoice) => { - return { - date: saleInvoice.invoiceDate, - - currencyCode: saleInvoice.currencyCode, - exchangeRate: saleInvoice.exchangeRate, - - transactionId: saleInvoice.id, - transactionType: 'InvoiceWriteOff', - transactionNumber: saleInvoice.invoiceNo, - - referenceNo: saleInvoice.referenceNo, - branchId: saleInvoice.branchId, - }; - }; - - /** - * Retrieves the invoice write-off receiveable GL entry. - * @param {number} ARAccountId - * @param {ISaleInvoice} saleInvoice - * @returns {ILedgerEntry} - */ - private getInvoiceWriteoffGLReceivableEntry = ( - ARAccountId: number, - saleInvoice: ISaleInvoice - ): ILedgerEntry => { - const commontEntry = this.getInvoiceWriteoffGLCommonEntry(saleInvoice); - - return { - ...commontEntry, - credit: saleInvoice.localWrittenoffAmount, - accountId: ARAccountId, - contactId: saleInvoice.customerId, - debit: 0, - index: 1, - indexGroup: 300, - accountNormal: saleInvoice.writtenoffExpenseAccount.accountNormal, - }; - }; - - /** - * Retrieves the invoice write-off expense GL entry. - * @param {ISaleInvoice} saleInvoice - * @returns {ILedgerEntry} - */ - private getInvoiceWriteoffGLExpenseEntry = ( - saleInvoice: ISaleInvoice - ): ILedgerEntry => { - const commontEntry = this.getInvoiceWriteoffGLCommonEntry(saleInvoice); - - return { - ...commontEntry, - debit: saleInvoice.localWrittenoffAmount, - accountId: saleInvoice.writtenoffExpenseAccountId, - credit: 0, - index: 2, - indexGroup: 300, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieves the invoice write-off GL entries. - * @param {number} ARAccountId - * @param {ISaleInvoice} saleInvoice - * @returns {ILedgerEntry[]} - */ - public getInvoiceWriteoffGLEntries = ( - ARAccountId: number, - saleInvoice: ISaleInvoice - ): ILedgerEntry[] => { - const creditEntry = this.getInvoiceWriteoffGLExpenseEntry(saleInvoice); - const debitEntry = this.getInvoiceWriteoffGLReceivableEntry( - ARAccountId, - saleInvoice - ); - return [debitEntry, creditEntry]; - }; - - /** - * Retrieves the invoice write-off ledger. - * @param {number} ARAccountId - * @param {ISaleInvoice} saleInvoice - * @returns {Ledger} - */ - public getInvoiceWriteoffLedger = ( - ARAccountId: number, - saleInvoice: ISaleInvoice - ): ILedger => { - const entries = this.getInvoiceWriteoffGLEntries(ARAccountId, saleInvoice); - - return new Ledger(entries); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLStorage.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLStorage.ts deleted file mode 100644 index be58388b7..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffGLStorage.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Knex } from 'knex'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; -import { SaleInvoiceWriteoffGLEntries } from './SaleInvoiceWriteoffGLEntries'; - -@Service() -export class SaleInvoiceWriteoffGLStorage { - @Inject() - private invoiceWriteoffLedger: SaleInvoiceWriteoffGLEntries; - - @Inject() - private ledgerStorage: LedgerStorageService; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Writes the invoice write-off GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public writeInvoiceWriteoffEntries = async ( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ) => { - const { SaleInvoice } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Retrieves the sale invoice. - const saleInvoice = await SaleInvoice.query(trx) - .findById(saleInvoiceId) - .withGraphFetched('writtenoffExpenseAccount'); - - // Find or create the A/R account. - const ARAccount = await accountRepository.findOrCreateAccountReceivable( - saleInvoice.currencyCode, - {}, - trx - ); - // Retrieves the invoice write-off ledger. - const ledger = this.invoiceWriteoffLedger.getInvoiceWriteoffLedger( - ARAccount.id, - saleInvoice - ); - return this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Rewrites the invoice write-off GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {Knex.Transactio} actiontrx - * @returns {Promise} - */ - public rewriteInvoiceWriteoffEntries = async ( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ) => { - await this.revertInvoiceWriteoffEntries(tenantId, saleInvoiceId, trx); - - await this.writeInvoiceWriteoffEntries(tenantId, saleInvoiceId, trx); - }; - - /** - * Reverts the invoice write-off GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public revertInvoiceWriteoffEntries = async ( - tenantId: number, - saleInvoiceId: number, - trx?: Knex.Transaction - ) => { - await this.ledgerStorage.deleteByReference( - tenantId, - saleInvoiceId, - 'InvoiceWriteOff', - trx - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffSubscriber.ts b/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffSubscriber.ts deleted file mode 100644 index e2e4b0f0d..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoiceWriteoffSubscriber.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceWriteoffCreatePayload, - ISaleInvoiceWrittenOffCanceledPayload, -} from '@/interfaces'; -import { SaleInvoiceWriteoffGLStorage } from './SaleInvoiceWriteoffGLStorage'; - -@Service() -export default class SaleInvoiceWriteoffSubscriber { - @Inject() - writeGLStorage: SaleInvoiceWriteoffGLStorage; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onWrittenoff, - this.writeJournalEntriesOnceWriteoffCreate - ); - bus.subscribe( - events.saleInvoice.onWrittenoffCanceled, - this.revertJournalEntriesOnce - ); - } - /** - * Write the written-off sale invoice journal entries. - * @param {ISaleInvoiceWriteoffCreatePayload} - */ - private writeJournalEntriesOnceWriteoffCreate = async ({ - tenantId, - saleInvoice, - trx, - }: ISaleInvoiceWriteoffCreatePayload) => { - await this.writeGLStorage.writeInvoiceWriteoffEntries( - tenantId, - saleInvoice.id, - trx - ); - }; - - /** - * Reverts the written-of sale invoice jounral entries. - * @param {ISaleInvoiceWrittenOffCanceledPayload} - */ - private revertJournalEntriesOnce = async ({ - tenantId, - saleInvoice, - trx, - }: ISaleInvoiceWrittenOffCanceledPayload) => { - await this.writeGLStorage.revertInvoiceWriteoffEntries( - tenantId, - saleInvoice.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts deleted file mode 100644 index c57e9777e..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts +++ /dev/null @@ -1,389 +0,0 @@ -import { - IFilterMeta, - IPaginationMeta, - ISaleInvoice, - ISaleInvoiceCreateDTO, - ISaleInvoiceEditDTO, - ISaleInvoiceSmsDetails, - ISaleInvoiceSmsDetailsDTO, - ISaleInvoiceWriteoffDTO, - ISalesInvoicesFilter, - ISystemUser, - ITenantUser, - InvoiceNotificationType, - SaleInvoiceMailState, - SendInvoiceMailDTO, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { CreateSaleInvoice } from './CreateSaleInvoice'; -import { DeleteSaleInvoice } from './DeleteSaleInvoice'; -import { GetSaleInvoice } from './GetSaleInvoice'; -import { EditSaleInvoice } from './EditSaleInvoice'; -import { GetSaleInvoices } from './GetSaleInvoices'; -import { DeliverSaleInvoice } from './DeliverSaleInvoice'; -import { GetSaleInvoicesPayable } from './GetSaleInvoicesPayable'; -import { WriteoffSaleInvoice } from './WriteoffSaleInvoice'; -import { SaleInvoicePdf } from './SaleInvoicePdf'; -import { GetInvoicePaymentsService } from './GetInvoicePaymentsService'; -import { SaleInvoiceNotifyBySms } from './SaleInvoiceNotifyBySms'; -import { SendInvoiceMailReminder } from './SendSaleInvoiceMailReminder'; -import { SendSaleInvoiceMail } from './SendSaleInvoiceMail'; -import { GetSaleInvoiceState } from './GetSaleInvoiceState'; -import { GetSaleInvoiceMailState } from './GetSaleInvoiceMailState'; - -@Service() -export class SaleInvoiceApplication { - @Inject() - private createSaleInvoiceService: CreateSaleInvoice; - - @Inject() - private deleteSaleInvoiceService: DeleteSaleInvoice; - - @Inject() - private getSaleInvoiceService: GetSaleInvoice; - - @Inject() - private getSaleInvoicesService: GetSaleInvoices; - - @Inject() - private editSaleInvoiceService: EditSaleInvoice; - - @Inject() - private deliverSaleInvoiceService: DeliverSaleInvoice; - - @Inject() - private getReceivableSaleInvoicesService: GetSaleInvoicesPayable; - - @Inject() - private writeoffInvoiceService: WriteoffSaleInvoice; - - @Inject() - private getInvoicePaymentsService: GetInvoicePaymentsService; - - @Inject() - private pdfSaleInvoiceService: SaleInvoicePdf; - - @Inject() - private invoiceSms: SaleInvoiceNotifyBySms; - - @Inject() - private sendInvoiceReminderService: SendInvoiceMailReminder; - - @Inject() - private sendSaleInvoiceMailService: SendSaleInvoiceMail; - - @Inject() - private getSaleInvoiceMailStateService: GetSaleInvoiceMailState; - - @Inject() - private getSaleInvoiceStateService: GetSaleInvoiceState; - - /** - * Creates a new sale invoice with associated GL entries. - * @param {number} tenantId - * @param {ISaleInvoiceCreateDTO} saleInvoiceDTO - * @param {ITenantUser} authorizedUser - * @returns {Promise} - */ - public createSaleInvoice( - tenantId: number, - saleInvoiceDTO: ISaleInvoiceCreateDTO, - authorizedUser: ITenantUser - ): Promise { - return this.createSaleInvoiceService.createSaleInvoice( - tenantId, - saleInvoiceDTO, - authorizedUser - ); - } - - /** - * Edits the given sale invoice with associated GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {ISaleInvoiceEditDTO} saleInvoiceDTO - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public editSaleInvoice( - tenantId: number, - saleInvoiceId: number, - saleInvoiceDTO: ISaleInvoiceEditDTO, - authorizedUser: ISystemUser - ) { - return this.editSaleInvoiceService.editSaleInvoice( - tenantId, - saleInvoiceId, - saleInvoiceDTO, - authorizedUser - ); - } - - /** - * Deletes the given sale invoice with given associated GL entries. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {ISystemUser} authorizedUser - * @returns {Promise} - */ - public deleteSaleInvoice( - tenantId: number, - saleInvoiceId: number, - authorizedUser: ISystemUser - ): Promise { - return this.deleteSaleInvoiceService.deleteSaleInvoice( - tenantId, - saleInvoiceId, - authorizedUser - ); - } - - /** - * Retrieves the given sale invoice details. - * @param {number} tenantId - * @param {ISalesInvoicesFilter} filterDTO - * @returns - */ - public getSaleInvoices( - tenantId: number, - filterDTO: ISalesInvoicesFilter - ): Promise<{ - salesInvoices: ISaleInvoice[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - return this.getSaleInvoicesService.getSaleInvoices(tenantId, filterDTO); - } - - /** - * Retrieves sale invoice details. - * @param {number} tenantId - - * @param {number} saleInvoiceId - - * @param {ISystemUser} authorizedUser - - * @return {Promise} - */ - public getSaleInvoice( - tenantId: number, - saleInvoiceId: number, - authorizedUser: ISystemUser - ) { - return this.getSaleInvoiceService.getSaleInvoice( - tenantId, - saleInvoiceId, - authorizedUser - ); - } - - /** - * Retrieves the sale invoice state. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns - */ - public getSaleInvoiceState(tenantId: number) { - return this.getSaleInvoiceStateService.getSaleInvoiceState(tenantId); - } - - /** - * Mark the given sale invoice as delivered. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {ISystemUser} authorizedUser - * @returns {} - */ - public deliverSaleInvoice( - tenantId: number, - saleInvoiceId: number, - authorizedUser: ISystemUser - ) { - return this.deliverSaleInvoiceService.deliverSaleInvoice( - tenantId, - saleInvoiceId, - authorizedUser - ); - } - - /** - * Retrieves the receivable sale invoices of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @returns - */ - public getReceivableSaleInvoices(tenantId: number, customerId?: number) { - return this.getReceivableSaleInvoicesService.getPayableInvoices( - tenantId, - customerId - ); - } - - /** - * Writes-off the sale invoice on bad debt expense account. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {ISaleInvoiceWriteoffDTO} writeoffDTO - * @return {Promise} - */ - public writeOff = async ( - tenantId: number, - saleInvoiceId: number, - writeoffDTO: ISaleInvoiceWriteoffDTO - ): Promise => { - return this.writeoffInvoiceService.writeOff( - tenantId, - saleInvoiceId, - writeoffDTO - ); - }; - - /** - * Cancels the written-off sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {Promise} - */ - public cancelWrittenoff = ( - tenantId: number, - saleInvoiceId: number - ): Promise => { - return this.writeoffInvoiceService.cancelWrittenoff( - tenantId, - saleInvoiceId - ); - }; - - /** - * Retrieve the invoice assocaited payments transactions. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Invoice id. - */ - public getInvoicePayments = async (tenantId: number, invoiceId: number) => { - return this.getInvoicePaymentsService.getInvoicePayments( - tenantId, - invoiceId - ); - }; - - /** - * Retrieves the pdf buffer of the given sale invoice. - * @param {number} tenantId - Tenant id. - * @param {number} saleInvoice - * @returns {Promise} - */ - public saleInvoicePdf(tenantId: number, saleInvoiceId: number) { - return this.pdfSaleInvoiceService.saleInvoicePdf(tenantId, saleInvoiceId); - } - - /** - * Retrieves the html content of the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {Promise} - */ - public saleInvoiceHtml( - tenantId: number, - saleInvoiceId: number - ): Promise { - return this.pdfSaleInvoiceService.saleInvoiceHtml(tenantId, saleInvoiceId); - } - - /** - * - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {InvoiceNotificationType} invoiceNotificationType - */ - public notifySaleInvoiceBySms = async ( - tenantId: number, - saleInvoiceId: number, - invoiceNotificationType: InvoiceNotificationType - ) => { - return this.invoiceSms.notifyBySms( - tenantId, - saleInvoiceId, - invoiceNotificationType - ); - }; - - /** - * Retrieves the SMS details of the given invoice. - * @param {number} tenantId - Tenant id. - * @param {number} saleInvoiceId - Sale invoice id. - */ - public getSaleInvoiceSmsDetails = async ( - tenantId: number, - saleInvoiceId: number, - invoiceSmsDetailsDTO: ISaleInvoiceSmsDetailsDTO - ): Promise => { - return this.invoiceSms.smsDetails( - tenantId, - saleInvoiceId, - invoiceSmsDetailsDTO - ); - }; - - /** - * Retrieves the metadata of invoice mail reminder. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {} - */ - public getSaleInvoiceMailReminder(tenantId: number, saleInvoiceId: number) { - return this.sendInvoiceReminderService.getMailOption( - tenantId, - saleInvoiceId - ); - } - - /** - * Sends reminder of the given invoice to the invoice's customer. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {} - */ - public sendSaleInvoiceMailReminder( - tenantId: number, - saleInvoiceId: number, - messageDTO: SendInvoiceMailDTO - ) { - return this.sendInvoiceReminderService.triggerMail( - tenantId, - saleInvoiceId, - messageDTO - ); - } - - /** - * Sends the invoice mail of the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {SendInvoiceMailDTO} messageDTO - * @returns {Promise} - */ - public sendSaleInvoiceMail( - tenantId: number, - saleInvoiceId: number, - messageDTO: SendInvoiceMailDTO - ) { - return this.sendSaleInvoiceMailService.triggerMail( - tenantId, - saleInvoiceId, - messageDTO - ); - } - - /** - * Retrieves the default mail options of the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceid - * @returns {Promise} - */ - public getSaleInvoiceMailState( - tenantId: number, - saleInvoiceid: number - ): Promise { - return this.getSaleInvoiceMailStateService.getInvoiceMailState( - tenantId, - saleInvoiceid - ); - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicesExportable.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicesExportable.ts deleted file mode 100644 index a68098a19..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicesExportable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISalesInvoicesFilter } from '@/interfaces'; -import { SaleInvoiceApplication } from './SaleInvoicesApplication'; -import { Exportable } from '@/services/Export/Exportable'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class SaleInvoicesExportable extends Exportable { - @Inject() - private saleInvoicesApplication: SaleInvoiceApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: ISalesInvoicesFilter) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - query.withGraphFetched('warehouse'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery, - } as ISalesInvoicesFilter; - - return this.saleInvoicesApplication - .getSaleInvoices(tenantId, parsedQuery) - .then((output) => output.salesInvoices); - } -} diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicesImportable.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicesImportable.ts deleted file mode 100644 index f6ce215ca..000000000 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicesImportable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ISaleInvoiceCreateDTO } from '@/interfaces'; -import { CreateSaleInvoice } from './CreateSaleInvoice'; -import { Importable } from '@/services/Import/Importable'; -import { SaleInvoicesSampleData } from './constants'; - -@Service() -export class SaleInvoicesImportable extends Importable { - @Inject() - private createInvoiceService: CreateSaleInvoice; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: ISaleInvoiceCreateDTO, - trx?: Knex.Transaction - ) { - return this.createInvoiceService.createSaleInvoice( - tenantId, - createAccountDTO, - {}, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return SaleInvoicesSampleData; - } -} diff --git a/packages/server/src/services/Sales/Invoices/SalesInvoicesCost.ts b/packages/server/src/services/Sales/Invoices/SalesInvoicesCost.ts deleted file mode 100644 index 4e69e2a03..000000000 --- a/packages/server/src/services/Sales/Invoices/SalesInvoicesCost.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Mutex } from 'async-mutex'; -import { Container, Service, Inject } from 'typedi'; -import { chain } from 'lodash'; -import moment from 'moment'; -import { Knex } from 'knex'; -import InventoryService from '@/services/Inventory/Inventory'; -import { - IInventoryCostLotsGLEntriesWriteEvent, - IInventoryTransaction, -} from '@/interfaces'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class SaleInvoicesCost { - @Inject() - private inventoryService: InventoryService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Schedule sale invoice re-compute based on the item - * cost method and starting date. - * @param {number[]} itemIds - Inventory items ids. - * @param {Date} startingDate - Starting compute cost date. - * @return {Promise} - */ - async scheduleComputeCostByItemsIds( - tenantId: number, - inventoryItemsIds: number[], - startingDate: Date - ): Promise { - const mutex = new Mutex(); - - const asyncOpers = inventoryItemsIds.map( - async (inventoryItemId: number) => { - // @todo refactor the lock acquire to be distrbuted using Redis - // and run the cost schedule job after running invoice transaction. - const release = await mutex.acquire(); - - try { - await this.inventoryService.scheduleComputeItemCost( - tenantId, - inventoryItemId, - startingDate - ); - } finally { - release(); - } - } - ); - await Promise.all(asyncOpers); - } - - /** - * Retrieve the max dated inventory transactions in the transactions that - * have the same item id. - * @param {IInventoryTransaction[]} inventoryTransactions - * @return {IInventoryTransaction[]} - */ - getMaxDateInventoryTransactions( - inventoryTransactions: IInventoryTransaction[] - ): IInventoryTransaction[] { - return chain(inventoryTransactions) - .reduce((acc: any, transaction) => { - const compatatorDate = acc[transaction.itemId]; - - if ( - !compatatorDate || - moment(compatatorDate.date).isBefore(transaction.date) - ) { - return { - ...acc, - [transaction.itemId]: { - ...transaction, - }, - }; - } - return acc; - }, {}) - .values() - .value(); - } - - /** - * Computes items costs by the given inventory transaction. - * @param {number} tenantId - * @param {IInventoryTransaction[]} inventoryTransactions - */ - async computeItemsCostByInventoryTransactions( - tenantId: number, - inventoryTransactions: IInventoryTransaction[] - ) { - const mutex = new Mutex(); - const reducedTransactions = this.getMaxDateInventoryTransactions( - inventoryTransactions - ); - const asyncOpers = reducedTransactions.map(async (transaction) => { - const release = await mutex.acquire(); - - try { - await this.inventoryService.scheduleComputeItemCost( - tenantId, - transaction.itemId, - transaction.date - ); - } finally { - release(); - } - }); - await Promise.all([...asyncOpers]); - } - - /** - * Schedule writing journal entries. - * @param {Date} startingDate - * @return {Promise} - */ - scheduleWriteJournalEntries(tenantId: number, startingDate?: Date) { - const agenda = Container.get('agenda'); - - return agenda.schedule('in 3 seconds', 'rewrite-invoices-journal-entries', { - startingDate, - tenantId, - }); - } - - /** - * Writes cost GL entries from the inventory cost lots. - * @param {number} tenantId - - * @param {Date} startingDate - - * @returns {Promise} - */ - public writeCostLotsGLEntries = (tenantId: number, startingDate: Date) => { - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers event `onInventoryCostLotsGLEntriesBeforeWrite`. - await this.eventPublisher.emitAsync( - events.inventory.onCostLotsGLEntriesBeforeWrite, - { - tenantId, - startingDate, - trx, - } as IInventoryCostLotsGLEntriesWriteEvent - ); - // Triggers event `onInventoryCostLotsGLEntriesWrite`. - await this.eventPublisher.emitAsync( - events.inventory.onCostLotsGLEntriesWrite, - { - tenantId, - startingDate, - trx, - } as IInventoryCostLotsGLEntriesWriteEvent - ); - }); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SendInvoiceInvoiceMailCommon.ts b/packages/server/src/services/Sales/Invoices/SendInvoiceInvoiceMailCommon.ts deleted file mode 100644 index 519cf3a0c..000000000 --- a/packages/server/src/services/Sales/Invoices/SendInvoiceInvoiceMailCommon.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { SaleInvoiceMailOptions } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { GetSaleInvoice } from './GetSaleInvoice'; -import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; -import { - DEFAULT_INVOICE_MAIL_CONTENT, - DEFAULT_INVOICE_MAIL_SUBJECT, -} from './constants'; -import { GetInvoicePaymentMail } from './GetInvoicePaymentMail'; -import { GenerateShareLink } from './GenerateeInvoicePaymentLink'; - -@Service() -export class SendSaleInvoiceMailCommon { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private getSaleInvoiceService: GetSaleInvoice; - - @Inject() - private contactMailNotification: ContactMailNotification; - - @Inject() - private getInvoicePaymentMail: GetInvoicePaymentMail; - - @Inject() - private generatePaymentLinkService: GenerateShareLink; - - /** - * Retrieves the mail options. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Invoice id. - * @param {string} defaultSubject - Subject text. - * @param {string} defaultBody - Subject body. - * @returns {Promise} - */ - public async getInvoiceMailOptions( - tenantId: number, - invoiceId: number, - defaultSubject: string = DEFAULT_INVOICE_MAIL_SUBJECT, - defaultMessage: string = DEFAULT_INVOICE_MAIL_CONTENT - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const saleInvoice = await SaleInvoice.query() - .findById(invoiceId) - .throwIfNotFound(); - - const contactMailDefaultOptions = - await this.contactMailNotification.getDefaultMailOptions( - tenantId, - saleInvoice.customerId - ); - const formatArgs = await this.getInvoiceFormatterArgs(tenantId, invoiceId); - - return { - ...contactMailDefaultOptions, - subject: defaultSubject, - message: defaultMessage, - attachInvoice: true, - formatArgs, - }; - } - - /** - * Formats the given invoice mail options. - * @param {number} tenantId - * @param {number} invoiceId - * @param {SaleInvoiceMailOptions} mailOptions - * @returns {Promise} - */ - public async formatInvoiceMailOptions( - tenantId: number, - invoiceId: number, - mailOptions: SaleInvoiceMailOptions - ): Promise { - const formatterArgs = await this.getInvoiceFormatterArgs( - tenantId, - invoiceId - ); - const formattedOptions = - await this.contactMailNotification.formatMailOptions( - tenantId, - mailOptions, - formatterArgs - ); - // Generates the a new payment link for the given invoice. - const paymentLink = - await this.generatePaymentLinkService.generatePaymentLink( - tenantId, - invoiceId, - 'public' - ); - const message = await this.getInvoicePaymentMail.getMailTemplate( - tenantId, - invoiceId, - { - // # Invoice message - invoiceMessage: formattedOptions.message, - preview: formattedOptions.message, - - // # Payment link - viewInvoiceButtonUrl: paymentLink.link, - } - ); - return { ...formattedOptions, message }; - } - - /** - * Retrieves the formatted text of the given sale invoice. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Sale invoice id. - * @param {string} text - The given text. - * @returns {Promise} - */ - public getInvoiceFormatterArgs = async ( - tenantId: number, - invoiceId: number - ): Promise> => { - const invoice = await this.getSaleInvoiceService.getSaleInvoice( - tenantId, - invoiceId - ); - const commonArgs = await this.contactMailNotification.getCommonFormatArgs( - tenantId - ); - return { - ...commonArgs, - 'Customer Name': invoice.customer.displayName, - 'Invoice Number': invoice.invoiceNo, - 'Invoice Due Amount': invoice.dueAmountFormatted, - 'Invoice Due Date': invoice.dueDateFormatted, - 'Invoice Date': invoice.invoiceDateFormatted, - 'Invoice Amount': invoice.totalFormatted, - 'Overdue Days': invoice.overdueDays, - }; - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMail.ts b/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMail.ts deleted file mode 100644 index baa85968b..000000000 --- a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMail.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { Inject, Service } from 'typedi'; -import Mail from '@/lib/Mail'; -import { - ISaleInvoiceMailSend, - SaleInvoiceMailOptions, - SendInvoiceMailDTO, -} from '@/interfaces'; -import { SaleInvoicePdf } from './SaleInvoicePdf'; -import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon'; -import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class SendSaleInvoiceMail { - @Inject() - private invoicePdf: SaleInvoicePdf; - - @Inject() - private invoiceMail: SendSaleInvoiceMailCommon; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject('agenda') - private agenda: any; - - /** - * Sends the invoice mail of the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {SendInvoiceMailDTO} messageDTO - */ - public async triggerMail( - tenantId: number, - saleInvoiceId: number, - messageOptions: SendInvoiceMailDTO - ) { - const payload = { - tenantId, - saleInvoiceId, - messageOptions, - }; - await this.agenda.now('sale-invoice-mail-send', payload); - - // Triggers the event `onSaleInvoicePreMailSend`. - await this.eventPublisher.emitAsync(events.saleInvoice.onPreMailSend, { - tenantId, - saleInvoiceId, - messageOptions, - } as ISaleInvoiceMailSend); - } - - /** - * Retrieves the formatted mail options. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {SendInvoiceMailDTO} messageOptions - * @returns {Promise} - */ - async getFormattedMailOptions( - tenantId: number, - saleInvoiceId: number, - messageOptions: SendInvoiceMailDTO - ): Promise { - const defaultMessageOptions = await this.invoiceMail.getInvoiceMailOptions( - tenantId, - saleInvoiceId - ); - // Merges message options with default options and parses the options values. - const parsedMessageOptions = mergeAndValidateMailOptions( - defaultMessageOptions, - messageOptions - ); - return this.invoiceMail.formatInvoiceMailOptions( - tenantId, - saleInvoiceId, - parsedMessageOptions - ); - } - - /** - * Triggers the mail invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {SendInvoiceMailDTO} messageDTO - * @returns {Promise} - */ - public async sendMail( - tenantId: number, - saleInvoiceId: number, - messageOptions: SendInvoiceMailDTO - ) { - const formattedMessageOptions = await this.getFormattedMailOptions( - tenantId, - saleInvoiceId, - messageOptions - ); - const mail = new Mail() - .setSubject(formattedMessageOptions.subject) - .setTo(formattedMessageOptions.to) - .setCC(formattedMessageOptions.cc) - .setBCC(formattedMessageOptions.bcc) - .setContent(formattedMessageOptions.message); - - // Attach invoice document. - if (formattedMessageOptions.attachInvoice) { - // Retrieves document buffer of the invoice pdf document. - const [invoicePdfBuffer, invoiceFilename] = - await this.invoicePdf.saleInvoicePdf(tenantId, saleInvoiceId); - - mail.setAttachments([ - { filename: `${invoiceFilename}.pdf`, content: invoicePdfBuffer }, - ]); - } - const eventPayload = { - tenantId, - saleInvoiceId, - messageOptions, - formattedMessageOptions, - } as ISaleInvoiceMailSend; - - // Triggers the event `onSaleInvoiceSend`. - await this.eventPublisher.emitAsync( - events.saleInvoice.onMailSend, - eventPayload - ); - await mail.send(); - - // Triggers the event `onSaleInvoiceSend`. - await this.eventPublisher.emitAsync( - events.saleInvoice.onMailSent, - eventPayload - ); - } -} diff --git a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailJob.ts b/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailJob.ts deleted file mode 100644 index 9de941f5f..000000000 --- a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailJob.ts +++ /dev/null @@ -1,33 +0,0 @@ -import Container, { Service } from 'typedi'; -import events from '@/subscribers/events'; -import { SendSaleInvoiceMail } from './SendSaleInvoiceMail'; - -@Service() -export class SendSaleInvoiceMailJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'sale-invoice-mail-send', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, saleInvoiceId, messageOptions } = job.attrs.data; - const sendInvoiceMail = Container.get(SendSaleInvoiceMail); - - try { - await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageOptions); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminder.ts b/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminder.ts deleted file mode 100644 index 7829a3bf2..000000000 --- a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminder.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleInvoiceMailSend, - ISaleInvoiceMailSent, - SendInvoiceMailDTO, -} from '@/interfaces'; -import Mail from '@/lib/Mail'; -import { SaleInvoicePdf } from './SaleInvoicePdf'; -import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon'; -import { - DEFAULT_INVOICE_REMINDER_MAIL_CONTENT, - DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT, -} from './constants'; -import { parseAndValidateMailOptions } from '@/services/MailNotification/utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class SendInvoiceMailReminder { - @Inject('agenda') - private agenda: any; - - @Inject() - private invoicePdf: SaleInvoicePdf; - - @Inject() - private invoiceCommonMail: SendSaleInvoiceMailCommon; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Triggers the reminder mail of the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - */ - public async triggerMail( - tenantId: number, - saleInvoiceId: number, - messageOptions: SendInvoiceMailDTO - ) { - const payload = { - tenantId, - saleInvoiceId, - messageOptions, - }; - await this.agenda.now('sale-invoice-reminder-mail-send', payload); - } - - /** - * Retrieves the mail options of the given sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {Promise} - */ - public async getMailOption(tenantId: number, saleInvoiceId: number) { - return this.invoiceCommonMail.getMailOption( - tenantId, - saleInvoiceId, - DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT, - DEFAULT_INVOICE_REMINDER_MAIL_CONTENT - ); - } - - /** - * Triggers the mail invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {SendInvoiceMailDTO} messageOptions - * @returns {Promise} - */ - public async sendMail( - tenantId: number, - saleInvoiceId: number, - messageOptions: SendInvoiceMailDTO - ) { - const localMessageOpts = await this.getMailOption(tenantId, saleInvoiceId); - - const messageOpts = parseAndValidateMailOptions( - localMessageOpts, - messageOptions - ); - const mail = new Mail() - .setSubject(messageOpts.subject) - .setTo(messageOpts.to) - .setContent(messageOpts.body); - - if (messageOpts.attachInvoice) { - // Retrieves document buffer of the invoice pdf document. - const invoicePdfBuffer = await this.invoicePdf.saleInvoicePdf( - tenantId, - saleInvoiceId - ); - mail.setAttachments([ - { filename: 'invoice.pdf', content: invoicePdfBuffer }, - ]); - } - // Triggers the event `onSaleInvoiceSend`. - await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSend, { - saleInvoiceId, - messageOptions, - } as ISaleInvoiceMailSend); - - await mail.send(); - - // Triggers the event `onSaleInvoiceSent`. - await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSent, { - saleInvoiceId, - messageOptions, - } as ISaleInvoiceMailSent); - } -} diff --git a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminderJob.ts b/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminderJob.ts deleted file mode 100644 index 6570a153f..000000000 --- a/packages/server/src/services/Sales/Invoices/SendSaleInvoiceMailReminderJob.ts +++ /dev/null @@ -1,32 +0,0 @@ -import Container, { Service } from 'typedi'; -import { SendInvoiceMailReminder } from './SendSaleInvoiceMailReminder'; - -@Service() -export class SendSaleInvoiceReminderMailJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'sale-invoice-reminder-mail-send', - { priority: 'high', concurrency: 1 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, saleInvoiceId, messageOptions } = job.attrs.data; - const sendInvoiceMail = Container.get(SendInvoiceMailReminder); - - try { - await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageOptions); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Sales/Invoices/WriteoffSaleInvoice.ts b/packages/server/src/services/Sales/Invoices/WriteoffSaleInvoice.ts deleted file mode 100644 index 7069e7635..000000000 --- a/packages/server/src/services/Sales/Invoices/WriteoffSaleInvoice.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - ISaleInvoice, - ISaleInvoiceWriteoffCreatePayload, - ISaleInvoiceWriteoffDTO, - ISaleInvoiceWrittenOffCanceledPayload, - ISaleInvoiceWrittenOffCancelPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { ServiceError } from '@/exceptions'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators'; -import { ERRORS } from './constants'; - -@Service() -export class WriteoffSaleInvoice { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandSaleInvoiceValidators; - - /** - * Writes-off the sale invoice on bad debt expense account. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {ISaleInvoiceWriteoffDTO} writeoffDTO - * @return {Promise} - */ - public writeOff = async ( - tenantId: number, - saleInvoiceId: number, - writeoffDTO: ISaleInvoiceWriteoffDTO - ): Promise => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const saleInvoice = await SaleInvoice.query().findById(saleInvoiceId); - - // Validates the given invoice existance. - this.validators.validateInvoiceExistance(saleInvoice); - - // Validate the sale invoice whether already written-off. - this.validateSaleInvoiceAlreadyWrittenoff(saleInvoice); - - // Saves the invoice write-off transaction with associated transactions - // under unit-of-work envirmenet. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - tenantId, - saleInvoiceId, - saleInvoice, - writeoffDTO, - trx, - } as ISaleInvoiceWriteoffCreatePayload; - - // Triggers `onSaleInvoiceWriteoff` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onWriteoff, - eventPayload - ); - // Mark the sale invoice as written-off. - const newSaleInvoice = await SaleInvoice.query(trx) - .patch({ - writtenoffExpenseAccountId: writeoffDTO.expenseAccountId, - writtenoffAmount: saleInvoice.dueAmount, - writtenoffAt: new Date(), - }) - .findById(saleInvoiceId); - - // Triggers `onSaleInvoiceWrittenoff` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onWrittenoff, - eventPayload - ); - return newSaleInvoice; - }); - }; - - /** - * Cancels the written-off sale invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - * @returns {Promise} - */ - public cancelWrittenoff = async ( - tenantId: number, - saleInvoiceId: number - ): Promise => { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Validate the sale invoice existance. - // Retrieve the sale invoice or throw not found service error. - const saleInvoice = await SaleInvoice.query().findById(saleInvoiceId); - - // Validate the sale invoice existance. - this.validators.validateInvoiceExistance(saleInvoice); - - // Validate the sale invoice whether already written-off. - this.validateSaleInvoiceNotWrittenoff(saleInvoice); - - // Cancels the invoice written-off and removes the associated transactions. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleInvoiceWrittenoffCancel` event. - await this.eventPublisher.emitAsync( - events.saleInvoice.onWrittenoffCancel, - { - tenantId, - saleInvoice, - trx, - } as ISaleInvoiceWrittenOffCancelPayload - ); - // Mark the sale invoice as written-off. - const newSaleInvoice = await SaleInvoice.query(trx) - .patch({ - writtenoffAmount: null, - writtenoffAt: null, - }) - .findById(saleInvoiceId); - - // Triggers `onSaleInvoiceWrittenoffCanceled`. - await this.eventPublisher.emitAsync( - events.saleInvoice.onWrittenoffCanceled, - { - tenantId, - saleInvoice, - trx, - } as ISaleInvoiceWrittenOffCanceledPayload - ); - return newSaleInvoice; - }); - }; - - /** - * Should sale invoice not be written-off. - * @param {ISaleInvoice} saleInvoice - */ - private validateSaleInvoiceNotWrittenoff(saleInvoice: ISaleInvoice) { - if (!saleInvoice.isWrittenoff) { - throw new ServiceError(ERRORS.SALE_INVOICE_NOT_WRITTEN_OFF); - } - } - - /** - * Should sale invoice already written-off. - * @param {ISaleInvoice} saleInvoice - */ - private validateSaleInvoiceAlreadyWrittenoff(saleInvoice: ISaleInvoice) { - if (saleInvoice.isWrittenoff) { - throw new ServiceError(ERRORS.SALE_INVOICE_ALREADY_WRITTEN_OFF); - } - } -} diff --git a/packages/server/src/services/Sales/Invoices/constants.ts b/packages/server/src/services/Sales/Invoices/constants.ts deleted file mode 100644 index 0e2b9989c..000000000 --- a/packages/server/src/services/Sales/Invoices/constants.ts +++ /dev/null @@ -1,238 +0,0 @@ -import config from '@/config'; - -export const DEFAULT_INVOICE_MAIL_SUBJECT = - 'Invoice {Invoice Number} from {Company Name} for {Customer Name}'; -export const DEFAULT_INVOICE_MAIL_CONTENT = `Hi {Customer Name}, - -Here's invoice # {Invoice Number} for {Invoice Amount} - -The amount outstanding of {Invoice Due Amount} is due on {Invoice Due Date}. - -From your online payment page you can print a PDF or view your outstanding bills. - -If you have any questions, please let us know. - -Thanks, -{Company Name} -`; - -export const DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT = - 'Invoice {InvoiceNumber} reminder from {CompanyName}'; -export const DEFAULT_INVOICE_REMINDER_MAIL_CONTENT = ` -

Dear {CustomerName}

-

You might have missed the payment date and the invoice is now overdue by {OverdueDays} days.

-

Invoice #{InvoiceNumber}
-Due Date : {InvoiceDueDate}
-Amount : {InvoiceAmount}

- -

-Regards
-{CompanyName} -

-`; - -export const PUBLIC_PAYMENT_LINK = `${config.baseURL}/payment/{PAYMENT_LINK_ID}`; - -export const ERRORS = { - INVOICE_NUMBER_NOT_UNIQUE: 'INVOICE_NUMBER_NOT_UNIQUE', - SALE_INVOICE_NOT_FOUND: 'SALE_INVOICE_NOT_FOUND', - SALE_INVOICE_ALREADY_DELIVERED: 'SALE_INVOICE_ALREADY_DELIVERED', - ENTRIES_ITEMS_IDS_NOT_EXISTS: 'ENTRIES_ITEMS_IDS_NOT_EXISTS', - NOT_SELLABLE_ITEMS: 'NOT_SELLABLE_ITEMS', - SALE_INVOICE_NO_NOT_UNIQUE: 'SALE_INVOICE_NO_NOT_UNIQUE', - INVOICE_AMOUNT_SMALLER_THAN_PAYMENT_AMOUNT: - 'INVOICE_AMOUNT_SMALLER_THAN_PAYMENT_AMOUNT', - INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES: - 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES', - SALE_INVOICE_NO_IS_REQUIRED: 'SALE_INVOICE_NO_IS_REQUIRED', - CUSTOMER_HAS_SALES_INVOICES: 'CUSTOMER_HAS_SALES_INVOICES', - SALE_INVOICE_HAS_APPLIED_TO_CREDIT_NOTES: - 'SALE_INVOICE_HAS_APPLIED_TO_CREDIT_NOTES', - PAYMENT_ACCOUNT_CURRENCY_INVALID: 'PAYMENT_ACCOUNT_CURRENCY_INVALID', - SALE_INVOICE_ALREADY_WRITTEN_OFF: 'SALE_INVOICE_ALREADY_WRITTEN_OFF', - SALE_INVOICE_NOT_WRITTEN_OFF: 'SALE_INVOICE_NOT_WRITTEN_OFF', - NO_INVOICE_CUSTOMER_EMAIL_ADDR: 'NO_INVOICE_CUSTOMER_EMAIL_ADDR', -}; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'Draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Delivered', - slug: 'delivered', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'delivered', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Unpaid', - slug: 'unpaid', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'unpaid' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Partially paid', - slug: 'partially-paid', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'partially-paid', - }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Paid', - slug: 'paid', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'paid' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const SaleInvoicesSampleData = [ - { - 'Invoice No.': 'B-101', - 'Reference No.': 'REF0', - 'Invoice Date': '2024-01-01', - 'Due Date': '2024-03-01', - Customer: 'Harley Veum', - 'Exchange Rate': 1, - 'Invoice Message': 'Aspernatur doloremque amet quia aut.', - 'Terms & Conditions': 'Quia illum aut dolores.', - Delivered: 'T', - Item: 'VonRueden, Ruecker and Hettinger', - Quantity: 100, - Rate: 100, - Description: 'Description', - }, - { - 'Invoice No.': 'B-102', - 'Reference No.': 'REF0', - 'Invoice Date': '2024-01-01', - 'Due Date': '2024-03-01', - Customer: 'Harley Veum', - 'Exchange Rate': 1, - 'Invoice Message': 'Est omnis enim vel.', - 'Terms & Conditions': 'Iusto et sint nobis sit.', - Delivered: 'T', - Item: 'Thompson - Reichert', - Quantity: 200, - Rate: 50, - Description: 'Description', - }, - { - 'Invoice No.': 'B-103', - 'Reference No.': 'REF0', - 'Invoice Date': '2024-01-01', - 'Due Date': '2024-03-01', - Customer: 'Harley Veum', - 'Exchange Rate': 1, - 'Invoice Message': - 'Repudiandae voluptatibus repellat minima voluptatem rerum veniam.', - 'Terms & Conditions': 'Id quod inventore ex rerum velit sed.', - Delivered: 'T', - Item: 'VonRueden, Ruecker and Hettinger', - Quantity: 100, - Rate: 100, - Description: 'Description', - }, -]; - -export const defaultInvoicePdfTemplateAttributes = { - primaryColor: 'red', - secondaryColor: 'red', - - companyName: 'Bigcapital Technology, Inc.', - - showCompanyLogo: true, - companyLogoKey: '', - companyLogoUri: '', - - dueDateLabel: 'Date due', - showDueDate: true, - - dateIssueLabel: 'Date of issue', - showDateIssue: true, - - // # Invoice number, - invoiceNumberLabel: 'Invoice number', - showInvoiceNumber: true, - - // # Customer address - showCustomerAddress: true, - customerAddress: '', - - // # Company address - showCompanyAddress: true, - companyAddress: '', - billedToLabel: 'Billed To', - - // Entries - lineItemLabel: 'Item', - lineQuantityLabel: 'Qty', - lineRateLabel: 'Rate', - lineTotalLabel: 'Total', - - totalLabel: 'Total', - subtotalLabel: 'Subtotal', - discountLabel: 'Discount', - paymentMadeLabel: 'Payment Made', - balanceDueLabel: 'Balance Due', - - // Totals - showTotal: true, - showSubtotal: true, - showDiscount: true, - showTaxes: true, - showPaymentMade: true, - showDueAmount: true, - showBalanceDue: true, - - discount: '0.00', - - // Footer paragraphs. - termsConditionsLabel: 'Terms & Conditions', - showTermsConditions: true, - - lines: [ - { - item: 'Simply dummy text', - description: 'Simply dummy text of the printing and typesetting', - rate: '1', - quantity: '1000', - total: '$1000.00', - }, - ], - taxes: [ - { label: 'Sample Tax1 (4.70%)', amount: '11.75' }, - { label: 'Sample Tax2 (7.00%)', amount: '21.74' }, - ], - - // # Statement - statementLabel: 'Statement', - showStatement: true, -}; diff --git a/packages/server/src/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts b/packages/server/src/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts deleted file mode 100644 index fc4392777..000000000 --- a/packages/server/src/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { ISaleInvoiceMailSent } from '@/interfaces'; -import { DeliverSaleInvoice } from '../DeliverSaleInvoice'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from '../constants'; - -@Service() -export class InvoiceChangeStatusOnMailSentSubscriber { - @Inject() - private markInvoiceDelivedService: DeliverSaleInvoice; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe(events.saleInvoice.onPreMailSend, this.markInvoiceDelivered); - bus.subscribe( - events.saleInvoice.onMailReminderSent, - this.markInvoiceDelivered - ); - } - - /** - * Marks the invoice delivered once the invoice mail sent. - * @param {ISaleInvoiceMailSent} - * @returns {Promise} - */ - private markInvoiceDelivered = async ({ - tenantId, - saleInvoiceId, - messageOptions, - }: ISaleInvoiceMailSent) => { - try { - await this.markInvoiceDelivedService.deliverSaleInvoice( - tenantId, - saleInvoiceId - ); - } catch (error) { - if ( - error instanceof ServiceError && - error.errorType === ERRORS.SALE_INVOICE_ALREADY_DELIVERED - ) { - } else { - throw error; - } - } - }; -} diff --git a/packages/server/src/services/Sales/Invoices/subscribers/InvoiceCostGLEntriesSubscriber.ts b/packages/server/src/services/Sales/Invoices/subscribers/InvoiceCostGLEntriesSubscriber.ts deleted file mode 100644 index e18c8cf78..000000000 --- a/packages/server/src/services/Sales/Invoices/subscribers/InvoiceCostGLEntriesSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IInventoryCostLotsGLEntriesWriteEvent } from '@/interfaces'; -import { SaleInvoiceCostGLEntries } from '../SaleInvoiceCostGLEntries'; - -@Service() -export class InvoiceCostGLEntriesSubscriber { - @Inject() - invoiceCostEntries: SaleInvoiceCostGLEntries; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe( - events.inventory.onCostLotsGLEntriesWrite, - this.writeInvoicesCostEntriesOnCostLotsWritten - ); - } - - /** - * Writes the invoices cost GL entries once the inventory cost lots be written. - * @param {IInventoryCostLotsGLEntriesWriteEvent} - */ - private writeInvoicesCostEntriesOnCostLotsWritten = async ({ - trx, - startingDate, - tenantId, - }: IInventoryCostLotsGLEntriesWriteEvent) => { - await this.invoiceCostEntries.writeInventoryCostJournalEntries( - tenantId, - startingDate, - trx - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts b/packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts deleted file mode 100644 index d40a6538c..000000000 --- a/packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentGLRewriteSubscriber.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { ISaleInvoiceEditingPayload } from '@/interfaces'; -import { InvoicePaymentsGLEntriesRewrite } from '../InvoicePaymentsGLRewrite'; - -@Service() -export class InvoicePaymentGLRewriteSubscriber { - @Inject() - private invoicePaymentsRewriteGLEntries: InvoicePaymentsGLEntriesRewrite; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.saleInvoice.onEdited, - this.paymentGLEntriesRewriteOnPaymentEdit - ); - return bus; - }; - - /** - * Writes associated invoiceso of payment receive once edit. - * @param {ISaleInvoiceEditingPayload} - - */ - private paymentGLEntriesRewriteOnPaymentEdit = async ({ - tenantId, - oldSaleInvoice, - trx, - }: ISaleInvoiceEditingPayload) => { - await this.invoicePaymentsRewriteGLEntries.invoicePaymentsGLEntriesRewrite( - tenantId, - oldSaleInvoice.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentIntegrationSubscriber.ts b/packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentIntegrationSubscriber.ts deleted file mode 100644 index 8e167729e..000000000 --- a/packages/server/src/services/Sales/Invoices/subscribers/InvoicePaymentIntegrationSubscriber.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit } from 'lodash'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletingPayload, - PaymentIntegrationTransactionLink, - PaymentIntegrationTransactionLinkDeleteEventPayload, - PaymentIntegrationTransactionLinkEventPayload, -} from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class InvoicePaymentIntegrationSubscriber { - @Inject() - private eventPublisher: EventPublisher; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleCreatePaymentIntegrationEvents - ); - bus.subscribe( - events.saleInvoice.onDeleting, - this.handleCreatePaymentIntegrationEventsOnDeleteInvoice - ); - return bus; - }; - - /** - * Handles the creation of payment integration events when a sale invoice is created. - * This method filters enabled payment methods from the invoice and emits a payment - * integration link event for each method. - * @param {ISaleInvoiceCreatedPayload} payload - The payload containing sale invoice creation details. - */ - private handleCreatePaymentIntegrationEvents = ({ - tenantId, - saleInvoiceDTO, - saleInvoice, - trx, - }: ISaleInvoiceCreatedPayload) => { - const paymentMethods = - saleInvoice.paymentMethods?.filter((method) => method.enable) || []; - - paymentMethods.map( - async (paymentMethod: PaymentIntegrationTransactionLink) => { - const payload = { - ...omit(paymentMethod, ['id']), - tenantId, - saleInvoiceId: saleInvoice.id, - trx, - }; - await this.eventPublisher.emitAsync( - events.paymentIntegrationLink.onPaymentIntegrationLink, - payload as PaymentIntegrationTransactionLinkEventPayload - ); - } - ); - }; - - /** - * - * @param {ISaleInvoiceDeletingPayload} payload - */ - private handleCreatePaymentIntegrationEventsOnDeleteInvoice = ({ - tenantId, - oldSaleInvoice, - trx, - }: ISaleInvoiceDeletingPayload) => { - const paymentMethods = - oldSaleInvoice.paymentMethods?.filter((method) => method.enable) || []; - - paymentMethods.map( - async (paymentMethod: PaymentIntegrationTransactionLink) => { - const payload = { - ...omit(paymentMethod, ['id']), - tenantId, - oldSaleInvoiceId: oldSaleInvoice.id, - trx, - } as PaymentIntegrationTransactionLinkDeleteEventPayload; - - // Triggers `onPaymentIntegrationDeleteLink` event. - await this.eventPublisher.emitAsync( - events.paymentIntegrationLink.onPaymentIntegrationDeleteLink, - payload - ); - } - ); - }; -} diff --git a/packages/server/src/services/Sales/Invoices/utils.ts b/packages/server/src/services/Sales/Invoices/utils.ts deleted file mode 100644 index 0de33fc81..000000000 --- a/packages/server/src/services/Sales/Invoices/utils.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { pickBy } from 'lodash'; -import { ISaleInvoice } from '@/interfaces'; -import { contactAddressTextFormat } from '@/utils/address-text-format'; -import { InvoicePaperTemplateProps } from '@bigcapital/pdf-templates'; - -export const mergePdfTemplateWithDefaultAttributes = ( - brandingTemplate?: Record, - defaultAttributes: Record = {} -) => { - const brandingAttributes = pickBy( - brandingTemplate, - (val, key) => val !== null && Object.keys(defaultAttributes).includes(key) - ); - return { - ...defaultAttributes, - ...brandingAttributes, - }; -}; - -export const transformInvoiceToPdfTemplate = ( - invoice: ISaleInvoice -): Partial => { - return { - dueDate: invoice.dueDateFormatted, - dateIssue: invoice.invoiceDateFormatted, - invoiceNumber: invoice.invoiceNo, - - total: invoice.totalFormatted, - subtotal: invoice.subtotalFormatted, - paymentMade: invoice.paymentAmountFormatted, - dueAmount: invoice.dueAmountFormatted, - discount: invoice.discountAmountFormatted, - adjustment: invoice.adjustmentFormatted, - discountLabel: invoice.discountPercentageFormatted - ? `Discount [${invoice.discountPercentageFormatted}]` - : 'Discount', - - termsConditions: invoice.termsConditions, - statement: invoice.invoiceMessage, - - lines: invoice.entries.map((entry) => ({ - item: entry.item.name, - description: entry.description, - rate: entry.rateFormatted, - quantity: entry.quantityFormatted, - discount: entry.discountFormatted, - total: entry.totalFormatted, - })), - taxes: invoice.taxes.map((tax) => ({ - label: tax.name, - amount: tax.taxRateAmountFormatted, - })), - showLineDiscount: invoice.entries.some((entry) => entry.discountFormatted), - customerAddress: contactAddressTextFormat(invoice.customer), - }; -}; diff --git a/packages/server/src/services/Sales/JournalPosterService.ts b/packages/server/src/services/Sales/JournalPosterService.ts deleted file mode 100644 index c688ced2a..000000000 --- a/packages/server/src/services/Sales/JournalPosterService.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import JournalPoster from '@/services/Accounting/JournalPoster'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import JournalCommands from '@/services/Accounting/JournalCommands'; - -@Service() -export default class JournalPosterService { - @Inject() - tenancy: TenancyService; - - /** - * Deletes the journal transactions that associated to the given reference id. - * @param {number} tenantId - The given tenant id. - * @param {number} referenceId - The transaction reference id. - * @param {string} referenceType - The transaction reference type. - * @return {Promise} - */ - async revertJournalTransactions( - tenantId: number, - referenceId: number|number[], - referenceType: string|string[], - trx?: Knex.Transaction - ): Promise { - const journal = new JournalPoster(tenantId, null, trx); - const journalCommand = new JournalCommands(journal); - - await journalCommand.revertJournalEntries(referenceId, referenceType); - - await Promise.all([ - journal.deleteEntries(), - journal.saveBalance(), - journal.saveContactsBalance(), - ]); - } -} \ No newline at end of file diff --git a/packages/server/src/services/Sales/PaymentReceived/CreatePaymentReceived.ts b/packages/server/src/services/Sales/PaymentReceived/CreatePaymentReceived.ts deleted file mode 100644 index 89af2dd6e..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/CreatePaymentReceived.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ICustomer, - IPaymentReceivedCreateDTO, - IPaymentReceivedCreatedPayload, - IPaymentReceivedCreatingPayload, - ISystemUser, -} from '@/interfaces'; -import { PaymentReceivedValidators } from './PaymentReceivedValidators'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { PaymentReceiveDTOTransformer } from './PaymentReceivedDTOTransformer'; -import { TenantMetadata } from '@/system/models'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class CreatePaymentReceived { - @Inject() - private validators: PaymentReceivedValidators; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private transformer: PaymentReceiveDTOTransformer; - - /** - * Creates a new payment receive and store it to the storage - * with associated invoices payment and journal transactions. - * @async - * @param {number} tenantId - Tenant id. - * @param {IPaymentReceived} paymentReceive - */ - public async createPaymentReceived( - tenantId: number, - paymentReceiveDTO: IPaymentReceivedCreateDTO, - authorizedUser: ISystemUser, - trx?: Knex.Transaction - ) { - const { PaymentReceive, Contact } = this.tenancy.models(tenantId); - - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Validate customer existance. - const paymentCustomer = await Contact.query() - .modify('customer') - .findById(paymentReceiveDTO.customerId) - .throwIfNotFound(); - - // Transformes the payment receive DTO to model. - const paymentReceiveObj = await this.transformCreateDTOToModel( - tenantId, - paymentCustomer, - paymentReceiveDTO - ); - // Validate payment receive number uniquiness. - await this.validators.validatePaymentReceiveNoExistance( - tenantId, - paymentReceiveObj.paymentReceiveNo - ); - // Validate the deposit account existance and type. - const depositAccount = await this.validators.getDepositAccountOrThrowError( - tenantId, - paymentReceiveDTO.depositAccountId - ); - // Validate payment receive invoices IDs existance. - await this.validators.validateInvoicesIDsExistance( - tenantId, - paymentReceiveDTO.customerId, - paymentReceiveDTO.entries - ); - // Validate invoice payment amount. - await this.validators.validateInvoicesPaymentsAmount( - tenantId, - paymentReceiveDTO.entries - ); - // Validates the payment account currency code. - this.validators.validatePaymentAccountCurrency( - depositAccount.currencyCode, - paymentCustomer.currencyCode, - tenantMeta.baseCurrency - ); - // Creates a payment receive transaction under UOW envirment. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onPaymentReceiveCreating` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onCreating, { - trx, - paymentReceiveDTO, - tenantId, - } as IPaymentReceivedCreatingPayload); - - // Inserts the payment receive transaction. - const paymentReceive = await PaymentReceive.query( - trx - ).insertGraphAndFetch({ - ...paymentReceiveObj, - }); - // Triggers `onPaymentReceiveCreated` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onCreated, { - tenantId, - paymentReceive, - paymentReceiveId: paymentReceive.id, - paymentReceiveDTO, - authorizedUser, - trx, - } as IPaymentReceivedCreatedPayload); - - return paymentReceive; - }, - trx - ); - } - - /** - * Transform the create payment receive DTO. - * @param {number} tenantId - * @param {ICustomer} customer - * @param {IPaymentReceivedCreateDTO} paymentReceiveDTO - * @returns - */ - private transformCreateDTOToModel = async ( - tenantId: number, - customer: ICustomer, - paymentReceiveDTO: IPaymentReceivedCreateDTO - ) => { - return this.transformer.transformPaymentReceiveDTOToModel( - tenantId, - customer, - paymentReceiveDTO - ); - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/DeletePaymentReceived.ts b/packages/server/src/services/Sales/PaymentReceived/DeletePaymentReceived.ts deleted file mode 100644 index d1bc62590..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/DeletePaymentReceived.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - IPaymentReceivedDeletedPayload, - IPaymentReceivedDeletingPayload, - ISystemUser, -} from '@/interfaces'; -import UnitOfWork from '@/services/UnitOfWork'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; - -@Service() -export class DeletePaymentReceived { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - /** - * Deletes the given payment receive with associated entries - * and journal transactions. - * ----- - * - Deletes the payment receive transaction. - * - Deletes the payment receive associated entries. - * - Deletes the payment receive associated journal transactions. - * - Revert the customer balance. - * - Revert the payment amount of the associated invoices. - * @async - * @param {number} tenantId - Tenant id. - * @param {Integer} paymentReceiveId - Payment receive id. - * @param {IPaymentReceived} paymentReceive - Payment receive object. - */ - public async deletePaymentReceive( - tenantId: number, - paymentReceiveId: number, - authorizedUser: ISystemUser - ) { - const { PaymentReceive, PaymentReceiveEntry } = - this.tenancy.models(tenantId); - - // Retreive payment receive or throw not found service error. - const oldPaymentReceive = await PaymentReceive.query() - .withGraphFetched('entries') - .findById(paymentReceiveId) - .throwIfNotFound(); - - // Delete payment receive transaction and associate transactions under UOW env. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onPaymentReceiveDeleting` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onDeleting, { - tenantId, - oldPaymentReceive, - trx, - } as IPaymentReceivedDeletingPayload); - - // Deletes the payment receive associated entries. - await PaymentReceiveEntry.query(trx) - .where('payment_receive_id', paymentReceiveId) - .delete(); - - // Deletes the payment receive transaction. - await PaymentReceive.query(trx).findById(paymentReceiveId).delete(); - - // Triggers `onPaymentReceiveDeleted` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onDeleted, { - tenantId, - paymentReceiveId, - oldPaymentReceive, - authorizedUser, - trx, - } as IPaymentReceivedDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/EditPaymentReceived.ts b/packages/server/src/services/Sales/PaymentReceived/EditPaymentReceived.ts deleted file mode 100644 index 1e508c094..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/EditPaymentReceived.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ICustomer, - IPaymentReceived, - IPaymentReceivedEditDTO, - IPaymentReceivedEditedPayload, - IPaymentReceivedEditingPayload, - ISystemUser, -} from '@/interfaces'; -import { PaymentReceiveDTOTransformer } from './PaymentReceivedDTOTransformer'; -import { PaymentReceivedValidators } from './PaymentReceivedValidators'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import UnitOfWork from '@/services/UnitOfWork'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class EditPaymentReceived { - @Inject() - private transformer: PaymentReceiveDTOTransformer; - - @Inject() - private validators: PaymentReceivedValidators; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Edit details the given payment receive with associated entries. - * ------ - * - Update the payment receive transactions. - * - Insert the new payment receive entries. - * - Update the given payment receive entries. - * - Delete the not presented payment receive entries. - * - Re-insert the journal transactions and update the different accounts balance. - * - Update the different customer balances. - * - Update the different invoice payment amount. - * @async - * @param {number} tenantId - - * @param {Integer} paymentReceiveId - - * @param {IPaymentReceived} paymentReceive - - */ - public async editPaymentReceive( - tenantId: number, - paymentReceiveId: number, - paymentReceiveDTO: IPaymentReceivedEditDTO, - authorizedUser: ISystemUser - ) { - const { PaymentReceive, Contact } = this.tenancy.models(tenantId); - - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Validate the payment receive existance. - const oldPaymentReceive = await PaymentReceive.query() - .withGraphFetched('entries') - .findById(paymentReceiveId) - .throwIfNotFound(); - - // Validates the payment existance. - this.validators.validatePaymentExistance(oldPaymentReceive); - - // Validate customer existance. - const customer = await Contact.query() - .modify('customer') - .findById(paymentReceiveDTO.customerId) - .throwIfNotFound(); - - // Transformes the payment receive DTO to model. - const paymentReceiveObj = await this.transformEditDTOToModel( - tenantId, - customer, - paymentReceiveDTO, - oldPaymentReceive - ); - // Validate customer whether modified. - this.validators.validateCustomerNotModified( - paymentReceiveDTO, - oldPaymentReceive - ); - // Validate payment receive number uniquiness. - if (paymentReceiveDTO.paymentReceiveNo) { - await this.validators.validatePaymentReceiveNoExistance( - tenantId, - paymentReceiveDTO.paymentReceiveNo, - paymentReceiveId - ); - } - // Validate the deposit account existance and type. - const depositAccount = await this.validators.getDepositAccountOrThrowError( - tenantId, - paymentReceiveDTO.depositAccountId - ); - // Validate the entries ids existance on payment receive type. - await this.validators.validateEntriesIdsExistance( - tenantId, - paymentReceiveId, - paymentReceiveDTO.entries - ); - // Validate payment receive invoices IDs existance and associated - // to the given customer id. - await this.validators.validateInvoicesIDsExistance( - tenantId, - oldPaymentReceive.customerId, - paymentReceiveDTO.entries - ); - // Validate invoice payment amount. - await this.validators.validateInvoicesPaymentsAmount( - tenantId, - paymentReceiveDTO.entries, - oldPaymentReceive.entries - ); - // Validates the payment account currency code. - this.validators.validatePaymentAccountCurrency( - depositAccount.currencyCode, - customer.currencyCode, - tenantMeta.baseCurrency - ); - // Creates payment receive transaction under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onPaymentReceiveEditing` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onEditing, { - trx, - tenantId, - oldPaymentReceive, - paymentReceiveDTO, - } as IPaymentReceivedEditingPayload); - - // Update the payment receive transaction. - const paymentReceive = await PaymentReceive.query( - trx - ).upsertGraphAndFetch({ - id: paymentReceiveId, - ...paymentReceiveObj, - }); - // Triggers `onPaymentReceiveEdited` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onEdited, { - tenantId, - paymentReceiveId, - paymentReceive, - oldPaymentReceive, - paymentReceiveDTO, - authorizedUser, - trx, - } as IPaymentReceivedEditedPayload); - - return paymentReceive; - }); - } - - /** - * Transform the edit payment receive DTO. - * @param {number} tenantId - * @param {ICustomer} customer - * @param {IPaymentReceivedEditDTO} paymentReceiveDTO - * @param {IPaymentReceived} oldPaymentReceive - * @returns - */ - private transformEditDTOToModel = async ( - tenantId: number, - customer: ICustomer, - paymentReceiveDTO: IPaymentReceivedEditDTO, - oldPaymentReceive: IPaymentReceived - ) => { - return this.transformer.transformPaymentReceiveDTOToModel( - tenantId, - customer, - paymentReceiveDTO, - oldPaymentReceive - ); - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceived.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceived.ts deleted file mode 100644 index 36ba5c06b..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceived.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import { IPaymentReceived } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { ERRORS } from './constants'; -import { PaymentReceiveTransfromer } from './PaymentReceivedTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetPaymentReceived { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve payment receive details. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveId - Payment receive id. - * @return {Promise} - */ - public async getPaymentReceive( - tenantId: number, - paymentReceiveId: number - ): Promise { - const { PaymentReceive } = this.tenancy.models(tenantId); - - const paymentReceive = await PaymentReceive.query() - .withGraphFetched('customer') - .withGraphFetched('depositAccount') - .withGraphFetched('entries.invoice') - .withGraphFetched('transactions') - .withGraphFetched('branch') - .findById(paymentReceiveId); - - if (!paymentReceive) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS); - } - return this.transformer.transform( - tenantId, - paymentReceive, - new PaymentReceiveTransfromer() - ); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedInvoices.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedInvoices.ts deleted file mode 100644 index d573406ce..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedInvoices.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { PaymentReceivedValidators } from './PaymentReceivedValidators'; - -@Service() -export class GetPaymentReceivedInvoices { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: PaymentReceivedValidators; - - /** - * Retrieve sale invoices that assocaited to the given payment receive. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveId - Payment receive id. - * @return {Promise} - */ - public async getPaymentReceiveInvoices( - tenantId: number, - paymentReceiveId: number - ) { - const { SaleInvoice, PaymentReceive } = this.tenancy.models(tenantId); - - const paymentReceive = await PaymentReceive.query() - .findById(paymentReceiveId) - .withGraphFetched('entries'); - - // Validates the payment receive existance. - this.validators.validatePaymentExistance(paymentReceive); - - const paymentReceiveInvoicesIds = paymentReceive.entries.map( - (entry) => entry.invoiceId - ); - const saleInvoices = await SaleInvoice.query().whereIn( - 'id', - paymentReceiveInvoicesIds - ); - return saleInvoices; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailState.tsx b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailState.tsx deleted file mode 100644 index b2910e4e0..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailState.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { PaymentReceiveMailOpts } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { GetPaymentReceivedMailStateTransformer } from './GetPaymentReceivedMailStateTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { Inject, Service } from 'typedi'; -import { SendPaymentReceiveMailNotification } from './PaymentReceivedMailNotification'; - -@Service() -export class GetPaymentReceivedMailState { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private paymentReceivedMail: SendPaymentReceiveMailNotification; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the default payment mail options. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveId - Payment receive id. - * @returns {Promise} - */ - public getMailOptions = async ( - tenantId: number, - paymentId: number - ): Promise => { - const { PaymentReceive } = this.tenancy.models(tenantId); - - const paymentReceive = await PaymentReceive.query() - .findById(paymentId) - .withGraphFetched('customer') - .withGraphFetched('entries.invoice') - .withGraphFetched('pdfTemplate') - .throwIfNotFound(); - - const mailOptions = await this.paymentReceivedMail.getMailOptions( - tenantId, - paymentId - ); - const transformed = await this.transformer.transform( - tenantId, - paymentReceive, - new GetPaymentReceivedMailStateTransformer(), - { - mailOptions, - } - ); - return transformed; - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailStateTransformer.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailStateTransformer.ts deleted file mode 100644 index 20a53ff74..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailStateTransformer.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { PaymentReceiveEntry } from '@/models'; -import { PaymentReceiveTransfromer } from './PaymentReceivedTransformer'; -import { PaymentReceivedEntryTransfromer } from './PaymentReceivedEntryTransformer'; - -export class GetPaymentReceivedMailStateTransformer extends PaymentReceiveTransfromer { - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'paymentDate', - 'paymentDateFormatted', - - 'paymentAmount', - 'paymentAmountFormatted', - - 'total', - 'totalFormatted', - - 'subtotal', - 'subtotalFormatted', - - 'paymentNumber', - - 'entries', - - 'companyName', - 'companyLogoUri', - - 'primaryColor', - - 'customerName', - ]; - }; - - /** - * Retrieves the customer name of the payment. - * @returns {string} - */ - protected customerName = (payment) => { - return payment.customer.displayName; - }; - - /** - * Retrieves the company name. - * @returns {string} - */ - protected companyName = () => { - return this.context.organization.name; - }; - - /** - * Retrieves the company logo uri. - * @returns {string | null} - */ - protected companyLogoUri = (payment) => { - return payment.pdfTemplate?.companyLogoUri; - }; - - /** - * Retrieves the primary color. - * @returns {string} - */ - protected primaryColor = (payment) => { - return payment.pdfTemplate?.attributes?.primaryColor; - }; - - /** - * Retrieves the formatted payment date. - * @returns {string} - */ - protected paymentDateFormatted = (payment) => { - return this.formatDate(payment.paymentDate); - }; - - /** - * Retrieves the payment amount. - * @param payment - * @returns {number} - */ - protected total = (payment) => { - return this.formatNumber(payment.amount, { - money: false, - }); - }; - - /** - * Retrieves the formatted payment amount. - * @returns {string} - */ - protected totalFormatted = (payment) => { - return this.formatMoney(payment.amount); - }; - - /** - * Retrieves the payment amount. - * @param payment - * @returns {number} - */ - protected subtotal = (payment) => { - return this.formatNumber(payment.amount, { - money: false, - }); - }; - - /** - * Retrieves the formatted payment amount. - * @returns {string} - */ - protected subtotalFormatted = (payment) => { - return this.formatMoney(payment.amount); - }; - - /** - * Retrieves the payment number. - * @param payment - * @returns {string} - */ - protected paymentNumber = (payment) => { - return payment.paymentReceiveNo; - }; - - /** - * Retrieves the payment entries. - * @param {IPaymentReceived} payment - * @returns {IPaymentReceivedEntry[]} - */ - protected entries = (payment) => { - return this.item(payment.entries, new GetPaymentReceivedEntryMailState()); - }; - - /** - * Merges the mail options with the invoice object. - */ - public transform = (object: any) => { - return { - ...this.options.mailOptions, - ...object, - }; - }; -} - -export class GetPaymentReceivedEntryMailState extends PaymentReceivedEntryTransfromer { - /** - * Include these attributes to payment receive entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['paidAmount', 'invoiceNumber']; - }; - - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Retrieves the paid amount. - * @param entry - * @returns {string} - */ - public paidAmount = (entry) => { - return this.paymentAmountFormatted(entry); - }; - - /** - * Retrieves the invoice number. - * @param entry - * @returns {string} - */ - public invoiceNumber = (entry) => { - return entry.invoice.invoiceNo; - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplate.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplate.ts deleted file mode 100644 index 8e5f1cf5c..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplate.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { GetPaymentReceived } from './GetPaymentReceived'; -import { GetPaymentReceivedMailTemplateAttrsTransformer } from './GetPaymentReceivedMailTemplateAttrsTransformer'; -import { - PaymentReceivedEmailTemplateProps, - renderPaymentReceivedEmailTemplate, -} from '@bigcapital/email-components'; - -@Service() -export class GetPaymentReceivedMailTemplate { - @Inject() - private getPaymentReceivedService: GetPaymentReceived; - - @Inject() - private getBrandingTemplate: GetPdfTemplate; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the mail template attributes of the given payment received. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceivedId - Payment received id. - * @returns {Promise} - */ - public async getMailTemplateAttributes( - tenantId: number, - paymentReceivedId: number - ): Promise { - const paymentReceived = - await this.getPaymentReceivedService.getPaymentReceive( - tenantId, - paymentReceivedId - ); - const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate( - tenantId, - paymentReceived.pdfTemplateId - ); - const mailTemplateAttributes = await this.transformer.transform( - tenantId, - paymentReceived, - new GetPaymentReceivedMailTemplateAttrsTransformer(), - { - paymentReceived, - brandingTemplate, - } - ); - return mailTemplateAttributes; - } - - /** - * Retrieves the mail template html content. - * @param {number} tenantId - * @param {number} paymentReceivedId - * @param {Partial} overrideAttributes - * @returns - */ - public async getMailTemplate( - tenantId: number, - paymentReceivedId: number, - overrideAttributes?: Partial - ): Promise { - const mailTemplateAttributes = await this.getMailTemplateAttributes( - tenantId, - paymentReceivedId - ); - const mergedAttributes = { - ...mailTemplateAttributes, - ...overrideAttributes, - }; - return renderPaymentReceivedEmailTemplate(mergedAttributes); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts deleted file mode 100644 index d4f4f8e02..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetPaymentReceivedMailTemplateAttrsTransformer extends Transformer { - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'companyLogoUri', - 'companyName', - 'primaryColor', - 'total', - 'totalLabel', - 'subtotal', - 'subtotalLabel', - 'paymentNumberLabel', - 'paymentNumber', - 'items', - ]; - }; - - /** - * Exclude all attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Company logo uri. - * @returns {string} - */ - public companyLogoUri(): string { - return this.options.brandingTemplate?.companyLogoUri; - } - - /** - * Company name. - * @returns {string} - */ - public companyName(): string { - return this.context.organization.name; - } - - /** - * Primary color - * @returns {string} - */ - public primaryColor(): string { - return this.options?.brandingTemplate?.attributes?.primaryColor; - } - - /** - * Total. - * @returns {string} - */ - public total(): string { - return this.options.paymentReceived.formattedAmount; - } - - /** - * Total label. - * @returns {string} - */ - public totalLabel(): string { - return 'Total'; - } - - /** - * Subtotal. - * @returns {string} - */ - public subtotal(): string { - return this.options.paymentReceived.formattedAmount; - } - - /** - * Subtotal label. - * @returns {string} - */ - public subtotalLabel(): string { - return 'Subtotal'; - } - - /** - * Payment number label. - * @returns {string} - */ - public paymentNumberLabel(): string { - return 'Payment # {paymentNumber}'; - } - - /** - * Payment number. - * @returns {string} - */ - public paymentNumber(): string { - return this.options.paymentReceived.paymentReceiveNumber; - } - - /** - * Items. - * @returns - */ - public items() { - return this.item( - this.options.paymentReceived.entries, - new GetPaymentReceivedMailTemplateItemAttrsTransformer() - ); - } -} - -class GetPaymentReceivedMailTemplateItemAttrsTransformer extends Transformer { - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = () => { - return ['label', 'total']; - }; - - /** - * Excluded attributes. - * @returns {string[]} - */ - public excludeAttributes = () => { - return ['*']; - }; - - /** - * - * @param entry - * @returns - */ - public label(entry) { - return entry.invoice.invoiceNo; - } - - /** - * - * @param entry - * @returns - */ - public total(entry) { - return entry.paymentAmountFormatted; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedPdf.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedPdf.ts deleted file mode 100644 index 36533961c..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedPdf.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { renderPaymentReceivedPaperTemplateHtml } from '@bigcapital/pdf-templates'; -import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy'; -import { GetPaymentReceived } from './GetPaymentReceived'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { PaymentReceivedBrandingTemplate } from './PaymentReceivedBrandingTemplate'; -import { transformPaymentReceivedToPdfTemplate } from './utils'; -import { PaymentReceivedPdfTemplateAttributes } from '@/interfaces'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export default class GetPaymentReceivedPdf { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - @Inject() - private getPaymentService: GetPaymentReceived; - - @Inject() - private paymentBrandingTemplateService: PaymentReceivedBrandingTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieves payment received html content. - * @param {number} tenantId - * @param {number} paymentReceivedId - * @returns {Promise} - */ - public async getPaymentReceivedHtml( - tenantId: number, - paymentReceivedId: number - ): Promise { - const brandingAttributes = await this.getPaymentBrandingAttributes( - tenantId, - paymentReceivedId - ); - return renderPaymentReceivedPaperTemplateHtml(brandingAttributes); - } - - /** - * Retrieve sale invoice pdf content. - * @param {number} tenantId - - * @param {IPaymentReceived} paymentReceive - - * @returns {Promise} - */ - async getPaymentReceivePdf( - tenantId: number, - paymentReceivedId: number - ): Promise<[Buffer, string]> { - const htmlContent = await this.getPaymentReceivedHtml( - tenantId, - paymentReceivedId - ); - const filename = await this.getPaymentReceivedFilename( - tenantId, - paymentReceivedId - ); - // Converts the given html content to pdf document. - const content = await this.chromiumlyTenancy.convertHtmlContent( - tenantId, - htmlContent - ); - const eventPayload = { tenantId, paymentReceivedId }; - - // Triggers the `onCreditNotePdfViewed` event. - await this.eventPublisher.emitAsync( - events.paymentReceive.onPdfViewed, - eventPayload - ); - return [content, filename]; - } - - /** - * Retrieves the filename of the given payment. - * @param {number} tenantId - * @param {number} paymentReceivedId - * @returns {Promise} - */ - private async getPaymentReceivedFilename( - tenantId: number, - paymentReceivedId: number - ): Promise { - const { PaymentReceive } = this.tenancy.models(tenantId); - - const payment = await PaymentReceive.query().findById(paymentReceivedId); - - return `Payment-${payment.paymentReceiveNo}`; - } - - /** - * Retrieves the given payment received branding attributes. - * @param {number} tenantId - * @param {number} paymentReceivedId - * @returns {Promise} - */ - async getPaymentBrandingAttributes( - tenantId: number, - paymentReceivedId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const paymentReceived = await this.getPaymentService.getPaymentReceive( - tenantId, - paymentReceivedId - ); - const templateId = - paymentReceived?.pdfTemplateId ?? - ( - await PdfTemplate.query().findOne({ - resource: 'PaymentReceive', - default: true, - }) - )?.id; - - const brandingTemplate = - await this.paymentBrandingTemplateService.getPaymentReceivedPdfTemplate( - tenantId, - templateId - ); - return { - ...brandingTemplate.attributes, - ...transformPaymentReceivedToPdfTemplate(paymentReceived), - }; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedState.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedState.ts deleted file mode 100644 index 8ee564393..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedState.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IPaymentReceivedState } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class GetPaymentReceivedState { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the create/edit initial state of the payment received. - * @param {number} tenantId - The ID of the tenant. - * @returns {Promise} - A promise resolving to the payment received state. - */ - public async getPaymentReceivedState( - tenantId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const defaultPdfTemplate = await PdfTemplate.query() - .findOne({ resource: 'PaymentReceive' }) - .modify('default'); - - return { - defaultTemplateId: defaultPdfTemplate?.id, - }; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentsReceived.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentsReceived.ts deleted file mode 100644 index daa20a6d0..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentsReceived.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { - IFilterMeta, - IPaginationMeta, - IPaymentReceived, - IPaymentsReceivedFilter, -} from '@/interfaces'; -import { PaymentReceiveTransfromer } from './PaymentReceivedTransformer'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; - -@Service() -export class GetPaymentReceives { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve payment receives paginated and filterable list. - * @param {number} tenantId - * @param {IPaymentsReceivedFilter} paymentReceivesFilter - */ - public async getPaymentReceives( - tenantId: number, - filterDTO: IPaymentsReceivedFilter - ): Promise<{ - paymentReceives: IPaymentReceived[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { PaymentReceive } = this.tenancy.models(tenantId); - - // Parses filter DTO. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicList = await this.dynamicListService.dynamicList( - tenantId, - PaymentReceive, - filter - ); - const { results, pagination } = await PaymentReceive.query() - .onBuild((builder) => { - builder.withGraphFetched('customer'); - builder.withGraphFetched('depositAccount'); - - dynamicList.buildQuery()(builder); - filterDTO?.filterQuery && filterDTO.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transformer the payment receives models to POJO. - const transformedPayments = await this.transformer.transform( - tenantId, - results, - new PaymentReceiveTransfromer() - ); - return { - paymentReceives: transformedPayments, - pagination, - filterMeta: dynamicList.getResponseMeta(), - }; - } - - /** - * Parses payments receive list filter DTO. - * @param filterDTO - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedApplication.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedApplication.ts deleted file mode 100644 index a2bac86fa..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedApplication.ts +++ /dev/null @@ -1,264 +0,0 @@ -import { - IFilterMeta, - IPaginationMeta, - IPaymentReceived, - IPaymentReceivedCreateDTO, - IPaymentReceivedEditDTO, - IPaymentReceivedSmsDetails, - IPaymentsReceivedFilter, - ISystemUser, - PaymentReceiveMailOptsDTO, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { CreatePaymentReceived } from './CreatePaymentReceived'; -import { EditPaymentReceived } from './EditPaymentReceived'; -import { DeletePaymentReceived } from './DeletePaymentReceived'; -import { GetPaymentReceives } from './GetPaymentsReceived'; -import { GetPaymentReceived } from './GetPaymentReceived'; -import { GetPaymentReceivedInvoices } from './GetPaymentReceivedInvoices'; -import { PaymentReceiveNotifyBySms } from './PaymentReceivedSmsNotify'; -import GetPaymentReceivedPdf from './GetPaymentReceivedPdf'; -import { SendPaymentReceiveMailNotification } from './PaymentReceivedMailNotification'; -import { GetPaymentReceivedState } from './GetPaymentReceivedState'; -import { GetPaymentReceivedMailState } from './GetPaymentReceivedMailState'; - -@Service() -export class PaymentReceivesApplication { - @Inject() - private createPaymentReceivedService: CreatePaymentReceived; - - @Inject() - private editPaymentReceivedService: EditPaymentReceived; - - @Inject() - private deletePaymentReceivedService: DeletePaymentReceived; - - @Inject() - private getPaymentsReceivedService: GetPaymentReceives; - - @Inject() - private getPaymentReceivedService: GetPaymentReceived; - - @Inject() - private getPaymentReceiveInvoicesService: GetPaymentReceivedInvoices; - - @Inject() - private paymentSmsNotify: PaymentReceiveNotifyBySms; - - @Inject() - private paymentMailNotify: SendPaymentReceiveMailNotification; - - @Inject() - private getPaymentReceivePdfService: GetPaymentReceivedPdf; - - @Inject() - private getPaymentReceivedStateService: GetPaymentReceivedState; - - @Inject() - private getPaymentReceivedMailStateService: GetPaymentReceivedMailState; - - /** - * Creates a new payment receive. - * @param {number} tenantId - * @param {IPaymentReceivedCreateDTO} paymentReceiveDTO - * @param {ISystemUser} authorizedUser - * @returns - */ - public createPaymentReceived( - tenantId: number, - paymentReceiveDTO: IPaymentReceivedCreateDTO, - authorizedUser: ISystemUser - ) { - return this.createPaymentReceivedService.createPaymentReceived( - tenantId, - paymentReceiveDTO, - authorizedUser - ); - } - - /** - * Edit details the given payment receive with associated entries. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {IPaymentReceivedEditDTO} paymentReceiveDTO - * @param {ISystemUser} authorizedUser - * @returns - */ - public editPaymentReceive( - tenantId: number, - paymentReceiveId: number, - paymentReceiveDTO: IPaymentReceivedEditDTO, - authorizedUser: ISystemUser - ) { - return this.editPaymentReceivedService.editPaymentReceive( - tenantId, - paymentReceiveId, - paymentReceiveDTO, - authorizedUser - ); - } - - /** - * Deletes the given payment receive. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {ISystemUser} authorizedUser - * @returns - */ - public deletePaymentReceive( - tenantId: number, - paymentReceiveId: number, - authorizedUser: ISystemUser - ) { - return this.deletePaymentReceivedService.deletePaymentReceive( - tenantId, - paymentReceiveId, - authorizedUser - ); - } - - /** - * Retrieve payment receives paginated and filterable. - * @param {number} tenantId - * @param {IPaymentsReceivedFilter} filterDTO - * @returns - */ - public async getPaymentReceives( - tenantId: number, - filterDTO: IPaymentsReceivedFilter - ): Promise<{ - paymentReceives: IPaymentReceived[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - return this.getPaymentsReceivedService.getPaymentReceives( - tenantId, - filterDTO - ); - } - - /** - * Retrieves the given payment receive. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @returns {Promise} - */ - public async getPaymentReceive( - tenantId: number, - paymentReceiveId: number - ): Promise { - return this.getPaymentReceivedService.getPaymentReceive( - tenantId, - paymentReceiveId - ); - } - - /** - * Retrieves associated sale invoices of the given payment receive. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @returns - */ - public getPaymentReceiveInvoices(tenantId: number, paymentReceiveId: number) { - return this.getPaymentReceiveInvoicesService.getPaymentReceiveInvoices( - tenantId, - paymentReceiveId - ); - } - - /** - * Notify customer via sms about payment receive details. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveid - Payment receive id. - */ - public notifyPaymentBySms(tenantId: number, paymentReceiveid: number) { - return this.paymentSmsNotify.notifyBySms(tenantId, paymentReceiveid); - } - - /** - * Retrieve the SMS details of the given invoice. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveid - Payment receive id. - */ - public getPaymentSmsDetails = async ( - tenantId: number, - paymentReceiveId: number - ): Promise => { - return this.paymentSmsNotify.smsDetails(tenantId, paymentReceiveId); - }; - - /** - * Notify customer via mail about payment receive details. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {IPaymentReceiveMailOpts} messageOpts - * @returns {Promise} - */ - public notifyPaymentByMail( - tenantId: number, - paymentReceiveId: number, - messageOpts: PaymentReceiveMailOptsDTO - ): Promise { - return this.paymentMailNotify.triggerMail( - tenantId, - paymentReceiveId, - messageOpts - ); - } - - /** - * Retrieves the default mail options of the given payment transaction. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveId - Payment received id. - * @returns {Promise} - */ - public getPaymentMailOptions(tenantId: number, paymentReceiveId: number) { - return this.getPaymentReceivedMailStateService.getMailOptions( - tenantId, - paymentReceiveId - ); - } - - /** - * Retrieve pdf content of the given payment receive. - * @param {number} tenantId - * @param {PaymentReceive} paymentReceive - * @returns - */ - public getPaymentReceivePdf = ( - tenantId: number, - paymentReceiveId: number - ) => { - return this.getPaymentReceivePdfService.getPaymentReceivePdf( - tenantId, - paymentReceiveId - ); - }; - - /** - * Retrieves the given payment receive html document. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @returns {Promise} - */ - public getPaymentReceivedHtml = ( - tenantId: number, - paymentReceiveId: number - ) => { - return this.getPaymentReceivePdfService.getPaymentReceivedHtml( - tenantId, - paymentReceiveId - ); - }; - - /** - * Retrieves the create/edit initial state of the payment received. - * @param {number} tenantId - The ID of the tenant. - * @returns {Promise} - */ - public getPaymentReceivedState = (tenantId: number) => { - return this.getPaymentReceivedStateService.getPaymentReceivedState( - tenantId - ); - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts deleted file mode 100644 index d7a88bf6b..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { Inject, Service } from 'typedi'; -import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils'; -import { defaultPaymentReceivedPdfTemplateAttributes } from './constants'; -import { PdfTemplate } from '@/models/PdfTemplate'; -import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes'; - -@Service() -export class PaymentReceivedBrandingTemplate { - @Inject() - private getPdfTemplateService: GetPdfTemplate; - - @Inject() - private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; - - /** - * Retrieves the payment received pdf template. - * @param {number} tenantId - * @param {number} paymentTemplateId - * @returns - */ - public async getPaymentReceivedPdfTemplate( - tenantId: number, - paymentTemplateId: number - ) { - const template = await this.getPdfTemplateService.getPdfTemplate( - tenantId, - paymentTemplateId - ); - // Retrieves the organization branding attributes. - const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes( - tenantId - ); - // Merges the default branding attributes with common organization branding attrs. - const organizationBrandingAttrs = { - ...defaultPaymentReceivedPdfTemplateAttributes, - ...commonOrgBrandingAttrs, - }; - const brandingTemplateAttrs = { - ...template.attributes, - companyLogoUri: template.companyLogoUri, - }; - const attributes = mergePdfTemplateWithDefaultAttributes( - brandingTemplateAttrs, - organizationBrandingAttrs - ); - return { - ...template, - attributes, - }; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedDTOTransformer.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedDTOTransformer.ts deleted file mode 100644 index 047607df4..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedDTOTransformer.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as R from 'ramda'; -import { Inject, Service } from 'typedi'; -import { omit, sumBy } from 'lodash'; -import composeAsync from 'async/compose'; -import { - ICustomer, - IPaymentReceived, - IPaymentReceivedCreateDTO, - IPaymentReceivedEditDTO, -} from '@/interfaces'; -import { PaymentReceivedValidators } from './PaymentReceivedValidators'; -import { PaymentReceivedIncrement } from './PaymentReceivedIncrement'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import { formatDateFields } from '@/utils'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; -import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer'; - -@Service() -export class PaymentReceiveDTOTransformer { - @Inject() - private validators: PaymentReceivedValidators; - - @Inject() - private increments: PaymentReceivedIncrement; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private brandingTemplatesTransformer: BrandingTemplateDTOTransformer; - - /** - * Transformes the create payment receive DTO to model object. - * @param {number} tenantId - * @param {IPaymentReceivedCreateDTO|IPaymentReceivedEditDTO} paymentReceiveDTO - Payment receive DTO. - * @param {IPaymentReceived} oldPaymentReceive - - * @return {IPaymentReceived} - */ - public async transformPaymentReceiveDTOToModel( - tenantId: number, - customer: ICustomer, - paymentReceiveDTO: IPaymentReceivedCreateDTO | IPaymentReceivedEditDTO, - oldPaymentReceive?: IPaymentReceived - ): Promise { - const amount = - paymentReceiveDTO.amount ?? - sumBy(paymentReceiveDTO.entries, 'paymentAmount'); - - // Retreive the next invoice number. - const autoNextNumber = - this.increments.getNextPaymentReceiveNumber(tenantId); - - // Retrieve the next payment receive number. - const paymentReceiveNo = - paymentReceiveDTO.paymentReceiveNo || - oldPaymentReceive?.paymentReceiveNo || - autoNextNumber; - - this.validators.validatePaymentNoRequire(paymentReceiveNo); - - const entries = R.compose( - // Associate the default index to each item entry line. - assocItemEntriesDefaultIndex - )(paymentReceiveDTO.entries); - - const initialDTO = { - ...formatDateFields(omit(paymentReceiveDTO, ['entries', 'attachments']), [ - 'paymentDate', - ]), - amount, - currencyCode: customer.currencyCode, - ...(paymentReceiveNo ? { paymentReceiveNo } : {}), - exchangeRate: paymentReceiveDTO.exchangeRate || 1, - entries, - }; - const initialAsyncDTO = await composeAsync( - // Assigns the default branding template id to the invoice DTO. - this.brandingTemplatesTransformer.assocDefaultBrandingTemplate( - tenantId, - 'SaleInvoice' - ) - )(initialDTO); - - return R.compose( - this.branchDTOTransform.transformDTO(tenantId) - )(initialAsyncDTO); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedEntryTransformer.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedEntryTransformer.ts deleted file mode 100644 index b20d8801d..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedEntryTransformer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { SaleInvoiceTransformer } from '../Invoices/SaleInvoiceTransformer'; -import { formatNumber } from '@/utils'; - -export class PaymentReceivedEntryTransfromer extends Transformer { - /** - * Include these attributes to payment receive entry object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['paymentAmountFormatted', 'invoice']; - }; - - /** - * Retreives the payment amount formatted. - * @param entry - * @returns {string} - */ - protected paymentAmountFormatted(entry) { - return formatNumber(entry.paymentAmount, { money: false }); - } - - /** - * Retreives the transformed invoice. - */ - protected invoice(entry) { - return this.item(entry.invoice, new SaleInvoiceTransformer()); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedGLEntries.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedGLEntries.ts deleted file mode 100644 index 8c30c10f4..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedGLEntries.ts +++ /dev/null @@ -1,299 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { sumBy } from 'lodash'; -import { Knex } from 'knex'; -import Ledger from '@/services/Accounting/Ledger'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - IPaymentReceived, - ILedgerEntry, - AccountNormal, - IPaymentReceiveGLCommonEntry, -} from '@/interfaces'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import { TenantMetadata } from '@/system/models'; - -@Service() -export class PaymentReceivedGLEntries { - @Inject() - private tenancy: TenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Writes payment GL entries to the storage. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public writePaymentGLEntries = async ( - tenantId: number, - paymentReceiveId: number, - trx?: Knex.Transaction - ): Promise => { - const { PaymentReceive } = this.tenancy.models(tenantId); - - // Retrieves the given tenant metadata. - const tenantMeta = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieves the payment receive with associated entries. - const paymentReceive = await PaymentReceive.query(trx) - .findById(paymentReceiveId) - .withGraphFetched('entries.invoice'); - - // Retrives the payment receive ledger. - const ledger = await this.getPaymentReceiveGLedger( - tenantId, - paymentReceive, - tenantMeta.baseCurrency, - trx - ); - // Commit the ledger entries to the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Reverts the given payment receive GL entries. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {Knex.Transaction} trx - */ - public revertPaymentGLEntries = async ( - tenantId: number, - paymentReceiveId: number, - trx?: Knex.Transaction - ) => { - await this.ledgerStorage.deleteByReference( - tenantId, - paymentReceiveId, - 'PaymentReceive', - trx - ); - }; - - /** - * Rewrites the given payment receive GL entries. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {Knex.Transaction} trx - */ - public rewritePaymentGLEntries = async ( - tenantId: number, - paymentReceiveId: number, - trx?: Knex.Transaction - ) => { - // Reverts the payment GL entries. - await this.revertPaymentGLEntries(tenantId, paymentReceiveId, trx); - - // Writes the payment GL entries. - await this.writePaymentGLEntries(tenantId, paymentReceiveId, trx); - }; - - /** - * Retrieves the payment receive general ledger. - * @param {number} tenantId - - * @param {IPaymentReceived} paymentReceive - - * @param {string} baseCurrencyCode - - * @param {Knex.Transaction} trx - - * @returns {Ledger} - */ - public getPaymentReceiveGLedger = async ( - tenantId: number, - paymentReceive: IPaymentReceived, - baseCurrencyCode: string, - trx?: Knex.Transaction - ): Promise => { - const { Account } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Retrieve the A/R account of the given currency. - const receivableAccount = - await accountRepository.findOrCreateAccountReceivable( - paymentReceive.currencyCode - ); - // Exchange gain/loss account. - const exGainLossAccount = await Account.query(trx).modify( - 'findBySlug', - 'exchange-grain-loss' - ); - const ledgerEntries = this.getPaymentReceiveGLEntries( - paymentReceive, - receivableAccount.id, - exGainLossAccount.id, - baseCurrencyCode - ); - return new Ledger(ledgerEntries); - }; - - /** - * Calculates the payment total exchange gain/loss. - * @param {IBillPayment} paymentReceive - Payment receive with entries. - * @returns {number} - */ - private getPaymentExGainOrLoss = ( - paymentReceive: IPaymentReceived - ): number => { - return sumBy(paymentReceive.entries, (entry) => { - const paymentLocalAmount = - entry.paymentAmount * paymentReceive.exchangeRate; - const invoicePayment = entry.paymentAmount * entry.invoice.exchangeRate; - - return paymentLocalAmount - invoicePayment; - }); - }; - - /** - * Retrieves the common entry of payment receive. - * @param {IPaymentReceived} paymentReceive - * @returns {} - */ - private getPaymentReceiveCommonEntry = ( - paymentReceive: IPaymentReceived - ): IPaymentReceiveGLCommonEntry => { - return { - debit: 0, - credit: 0, - - currencyCode: paymentReceive.currencyCode, - exchangeRate: paymentReceive.exchangeRate, - - transactionId: paymentReceive.id, - transactionType: 'PaymentReceive', - - transactionNumber: paymentReceive.paymentReceiveNo, - referenceNumber: paymentReceive.referenceNo, - - date: paymentReceive.paymentDate, - userId: paymentReceive.userId, - createdAt: paymentReceive.createdAt, - - branchId: paymentReceive.branchId, - }; - }; - - /** - * Retrieves the payment exchange gain/loss entry. - * @param {IPaymentReceived} paymentReceive - - * @param {number} ARAccountId - - * @param {number} exchangeGainOrLossAccountId - - * @param {string} baseCurrencyCode - - * @returns {ILedgerEntry[]} - */ - private getPaymentExchangeGainLossEntry = ( - paymentReceive: IPaymentReceived, - ARAccountId: number, - exchangeGainOrLossAccountId: number, - baseCurrencyCode: string - ): ILedgerEntry[] => { - const commonJournal = this.getPaymentReceiveCommonEntry(paymentReceive); - const gainOrLoss = this.getPaymentExGainOrLoss(paymentReceive); - const absGainOrLoss = Math.abs(gainOrLoss); - - return gainOrLoss - ? [ - { - ...commonJournal, - currencyCode: baseCurrencyCode, - exchangeRate: 1, - debit: gainOrLoss > 0 ? absGainOrLoss : 0, - credit: gainOrLoss < 0 ? absGainOrLoss : 0, - accountId: ARAccountId, - contactId: paymentReceive.customerId, - index: 3, - accountNormal: AccountNormal.CREDIT, - }, - { - ...commonJournal, - currencyCode: baseCurrencyCode, - exchangeRate: 1, - credit: gainOrLoss > 0 ? absGainOrLoss : 0, - debit: gainOrLoss < 0 ? absGainOrLoss : 0, - accountId: exchangeGainOrLossAccountId, - index: 3, - accountNormal: AccountNormal.DEBIT, - }, - ] - : []; - }; - - /** - * Retrieves the payment deposit GL entry. - * @param {IPaymentReceived} paymentReceive - * @returns {ILedgerEntry} - */ - private getPaymentDepositGLEntry = ( - paymentReceive: IPaymentReceived - ): ILedgerEntry => { - const commonJournal = this.getPaymentReceiveCommonEntry(paymentReceive); - - return { - ...commonJournal, - debit: paymentReceive.localAmount, - accountId: paymentReceive.depositAccountId, - index: 2, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieves the payment receivable entry. - * @param {IPaymentReceived} paymentReceive - * @param {number} ARAccountId - * @returns {ILedgerEntry} - */ - private getPaymentReceivableEntry = ( - paymentReceive: IPaymentReceived, - ARAccountId: number - ): ILedgerEntry => { - const commonJournal = this.getPaymentReceiveCommonEntry(paymentReceive); - - return { - ...commonJournal, - credit: paymentReceive.localAmount, - contactId: paymentReceive.customerId, - accountId: ARAccountId, - index: 1, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Records payment receive journal transactions. - * - * Invoice payment journals. - * -------- - * - Account receivable -> Debit - * - Payment account [current asset] -> Credit - * - * @param {number} tenantId - * @param {IPaymentReceived} paymentRecieve - Payment receive model. - * @param {number} ARAccountId - A/R account id. - * @param {number} exGainOrLossAccountId - Exchange gain/loss account id. - * @param {string} baseCurrency - Base currency code. - * @returns {Promise} - */ - public getPaymentReceiveGLEntries = ( - paymentReceive: IPaymentReceived, - ARAccountId: number, - exGainOrLossAccountId: number, - baseCurrency: string - ): ILedgerEntry[] => { - // Retrieve the payment deposit entry. - const paymentDepositEntry = this.getPaymentDepositGLEntry(paymentReceive); - - // Retrieves the A/R entry. - const receivableEntry = this.getPaymentReceivableEntry( - paymentReceive, - ARAccountId - ); - // Exchange gain/loss entries. - const gainLossEntries = this.getPaymentExchangeGainLossEntry( - paymentReceive, - ARAccountId, - exGainOrLossAccountId, - baseCurrency - ); - return [paymentDepositEntry, receivableEntry, ...gainLossEntries]; - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedIncrement.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedIncrement.ts deleted file mode 100644 index 01cef7f48..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedIncrement.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import AutoIncrementOrdersService from '../AutoIncrementOrdersService'; - -@Service() -export class PaymentReceivedIncrement { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - /** - * Retrieve the next unique payment receive number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - public getNextPaymentReceiveNumber(tenantId: number): string { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'payment_receives' - ); - } - - /** - * Increment the payment receive next number. - * @param {number} tenantId - */ - public incrementNextPaymentReceiveNumber(tenantId: number) { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'payment_receives' - ); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedInvoiceSync.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedInvoiceSync.ts deleted file mode 100644 index 4cc51e60c..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedInvoiceSync.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IPaymentReceivedEntryDTO } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { entriesAmountDiff } from '@/utils'; - -@Service() -export class PaymentReceivedInvoiceSync { - @Inject() - private tenancy: HasTenancyService; - - /** - * Saves difference changing between old and new invoice payment amount. - * @async - * @param {number} tenantId - Tenant id. - * @param {Array} paymentReceiveEntries - * @param {Array} newPaymentReceiveEntries - * @return {Promise} - */ - public async saveChangeInvoicePaymentAmount( - tenantId: number, - newPaymentReceiveEntries: IPaymentReceivedEntryDTO[], - oldPaymentReceiveEntries?: IPaymentReceivedEntryDTO[], - trx?: Knex.Transaction - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - const opers: Promise[] = []; - - const diffEntries = entriesAmountDiff( - newPaymentReceiveEntries, - oldPaymentReceiveEntries, - 'paymentAmount', - 'invoiceId' - ); - diffEntries.forEach((diffEntry: any) => { - if (diffEntry.paymentAmount === 0) { - return; - } - const oper = SaleInvoice.changePaymentAmount( - diffEntry.invoiceId, - diffEntry.paymentAmount, - trx - ); - opers.push(oper); - }); - await Promise.all([...opers]); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotification.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotification.ts deleted file mode 100644 index daaa43c8c..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotification.ts +++ /dev/null @@ -1,237 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - PaymentReceiveMailOpts, - PaymentReceiveMailOptsDTO, - PaymentReceiveMailPresendEvent, - SendInvoiceMailDTO, -} from '@/interfaces'; -import Mail from '@/lib/Mail'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - DEFAULT_PAYMENT_MAIL_CONTENT, - DEFAULT_PAYMENT_MAIL_SUBJECT, -} from './constants'; -import { GetPaymentReceived } from './GetPaymentReceived'; -import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; -import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { transformPaymentReceivedToMailDataArgs } from './utils'; -import { GetPaymentReceivedMailTemplate } from './GetPaymentReceivedMailTemplate'; -import events from '@/subscribers/events'; - -@Service() -export class SendPaymentReceiveMailNotification { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private getPaymentService: GetPaymentReceived; - - @Inject() - private contactMailNotification: ContactMailNotification; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private paymentMailTemplate: GetPaymentReceivedMailTemplate; - - @Inject('agenda') - private agenda: any; - - /** - * Sends the mail of the given payment receive. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {PaymentReceiveMailOptsDTO} messageDTO - * @returns {Promise} - */ - public async triggerMail( - tenantId: number, - paymentReceiveId: number, - messageDTO: PaymentReceiveMailOptsDTO - ): Promise { - const payload = { - tenantId, - paymentReceiveId, - messageDTO, - }; - await this.agenda.now('payment-receive-mail-send', payload); - - // Triggers `onPaymentReceivePreMailSend` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onPreMailSend, { - tenantId, - paymentReceiveId, - messageOptions: messageDTO, - } as PaymentReceiveMailPresendEvent); - } - - /** - * Retrieves the formatted text of the given sale invoice. - * @param {number} tenantId - Tenant id. - * @param {number} invoiceId - Sale invoice id. - * @param {string} text - The given text. - * @returns {Promise} - */ - public textFormatter = async ( - tenantId: number, - invoiceId: number - ): Promise> => { - const payment = await this.getPaymentService.getPaymentReceive( - tenantId, - invoiceId - ); - const commonArgs = await this.contactMailNotification.getCommonFormatArgs( - tenantId - ); - const paymentArgs = transformPaymentReceivedToMailDataArgs(payment); - - return { - ...commonArgs, - ...paymentArgs, - }; - }; - - /** - * Retrieves the mail options of the given payment received. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceivedId - Payment received id. - * @param {string} defaultSubject - Default subject of the mail. - * @param {string} defaultContent - Default content of the mail. - * @returns - */ - public getMailOptions = async ( - tenantId: number, - paymentReceivedId: number, - defaultSubject: string = DEFAULT_PAYMENT_MAIL_SUBJECT, - defaultContent: string = DEFAULT_PAYMENT_MAIL_CONTENT - ): Promise => { - const { PaymentReceive } = this.tenancy.models(tenantId); - - const paymentReceived = await PaymentReceive.query().findById( - paymentReceivedId - ); - const formatArgs = await this.textFormatter(tenantId, paymentReceivedId); - - // Retrieves the default mail options. - const mailOptions = - await this.contactMailNotification.getDefaultMailOptions( - tenantId, - paymentReceived.customerId - ); - return { - ...mailOptions, - message: defaultContent, - subject: defaultSubject, - attachPdf: true, - formatArgs, - }; - }; - - /** - * Formats the mail options of the given payment receive. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {PaymentReceiveMailOpts} mailOptions - * @returns {Promise} - */ - public formattedMailOptions = async ( - tenantId: number, - paymentReceiveId: number, - mailOptions: PaymentReceiveMailOpts - ): Promise => { - const formatterArgs = await this.textFormatter(tenantId, paymentReceiveId); - const formattedOptions = - await this.contactMailNotification.formatMailOptions( - tenantId, - mailOptions, - formatterArgs - ); - // Retrieves the mail template. - const message = await this.paymentMailTemplate.getMailTemplate( - tenantId, - paymentReceiveId, - { - message: formattedOptions.message, - preview: formattedOptions.message, - } - ); - return { ...formattedOptions, message }; - }; - - /** - * Retrieves the formatted mail options of the given payment receive. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {SendInvoiceMailDTO} messageDTO - * @returns {Promise} - */ - public getFormattedMailOptions = async ( - tenantId: number, - paymentReceiveId: number, - messageDTO: SendInvoiceMailDTO - ) => { - const formatterArgs = await this.textFormatter(tenantId, paymentReceiveId); - - // Default message options. - const defaultMessageOpts = await this.getMailOptions( - tenantId, - paymentReceiveId - ); - // Parsed message opts with default options. - const parsedMessageOpts = mergeAndValidateMailOptions( - defaultMessageOpts, - messageDTO - ); - // Formats the message options. - return this.formattedMailOptions( - tenantId, - paymentReceiveId, - parsedMessageOpts - ); - }; - - /** - * Triggers the mail invoice. - * @param {number} tenantId - * @param {number} saleInvoiceId - Invoice id. - * @param {SendInvoiceMailDTO} messageDTO - Message options. - * @returns {Promise} - */ - public async sendMail( - tenantId: number, - paymentReceiveId: number, - messageDTO: SendInvoiceMailDTO - ): Promise { - // Retrieves the formatted mail options. - const formattedMessageOptions = await this.getFormattedMailOptions( - tenantId, - paymentReceiveId, - messageDTO - ); - const mail = new Mail() - .setSubject(formattedMessageOptions.subject) - .setTo(formattedMessageOptions.to) - .setCC(formattedMessageOptions.cc) - .setBCC(formattedMessageOptions.bcc) - .setContent(formattedMessageOptions.message); - - const eventPayload = { - tenantId, - paymentReceiveId, - messageOptions: formattedMessageOptions, - }; - // Triggers `onPaymentReceiveMailSend` event. - await this.eventPublisher.emitAsync( - events.paymentReceive.onMailSend, - eventPayload - ); - await mail.send(); - - // Triggers `onPaymentReceiveMailSent` event. - await this.eventPublisher.emitAsync( - events.paymentReceive.onMailSent, - eventPayload - ); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotificationJob.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotificationJob.ts deleted file mode 100644 index 4614ce9b4..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedMailNotificationJob.ts +++ /dev/null @@ -1,32 +0,0 @@ -import Container, { Service } from 'typedi'; -import { SendPaymentReceiveMailNotification } from './PaymentReceivedMailNotification'; - -@Service() -export class PaymentReceivedMailNotificationJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'payment-receive-mail-send', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending payment notification via mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, paymentReceiveId, messageDTO } = job.attrs.data; - const paymentMail = Container.get(SendPaymentReceiveMailNotification); - - try { - await paymentMail.sendMail(tenantId, paymentReceiveId, messageDTO); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsNotify.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsNotify.ts deleted file mode 100644 index 961bec572..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsNotify.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { - IPaymentReceivedSmsDetails, - SMS_NOTIFICATION_KEY, - IPaymentReceived, - IPaymentReceivedEntry, -} from '@/interfaces'; -import SmsNotificationsSettingsService from '@/services/Settings/SmsNotificationsSettings'; -import { formatNumber, formatSmsMessage } from 'utils'; -import { TenantMetadata } from '@/system/models'; -import SaleNotifyBySms from '../SaleNotifyBySms'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { PaymentReceivedValidators } from './PaymentReceivedValidators'; - -@Service() -export class PaymentReceiveNotifyBySms { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private smsNotificationsSettings: SmsNotificationsSettingsService; - - @Inject() - private saleSmsNotification: SaleNotifyBySms; - - @Inject() - private validators: PaymentReceivedValidators; - - /** - * Notify customer via sms about payment receive details. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveid - Payment receive id. - */ - public async notifyBySms(tenantId: number, paymentReceiveid: number) { - const { PaymentReceive } = this.tenancy.models(tenantId); - - // Retrieve the payment receive or throw not found service error. - const paymentReceive = await PaymentReceive.query() - .findById(paymentReceiveid) - .withGraphFetched('customer') - .withGraphFetched('entries.invoice'); - - // Validates the payment existance. - this.validators.validatePaymentExistance(paymentReceive); - - // Validate the customer phone number. - this.saleSmsNotification.validateCustomerPhoneNumber( - paymentReceive.customer.personalPhone - ); - // Triggers `onPaymentReceiveNotifySms` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onNotifySms, { - tenantId, - paymentReceive, - }); - // Sends the payment receive sms notification to the given customer. - await this.sendSmsNotification(tenantId, paymentReceive); - - // Triggers `onPaymentReceiveNotifiedSms` event. - await this.eventPublisher.emitAsync(events.paymentReceive.onNotifiedSms, { - tenantId, - paymentReceive, - }); - return paymentReceive; - } - - /** - * Sends the payment details sms notification of the given customer. - * @param {number} tenantId - * @param {IPaymentReceived} paymentReceive - * @param {ICustomer} customer - */ - private sendSmsNotification = async ( - tenantId: number, - paymentReceive: IPaymentReceived - ) => { - const smsClient = this.tenancy.smsClient(tenantId); - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieve the formatted payment details sms notification message. - const message = this.formattedPaymentDetailsMessage( - tenantId, - paymentReceive, - tenantMetadata - ); - // The target phone number. - const phoneNumber = paymentReceive.customer.personalPhone; - - await smsClient.sendMessageJob(phoneNumber, message); - }; - - /** - * Notify via SMS message after payment transaction creation. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @returns {Promise} - */ - public notifyViaSmsNotificationAfterCreation = async ( - tenantId: number, - paymentReceiveId: number - ): Promise => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.PAYMENT_RECEIVE_DETAILS - ); - // Can't continue if the sms auto-notification is not enabled. - if (!notification.isNotificationEnabled) return; - - await this.notifyBySms(tenantId, paymentReceiveId); - }; - - /** - * Formates the payment receive details sms message. - * @param {number} tenantId - - * @param {IPaymentReceived} payment - - * @param {ICustomer} customer - - */ - private formattedPaymentDetailsMessage = ( - tenantId: number, - payment: IPaymentReceived, - tenantMetadata: TenantMetadata - ) => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.PAYMENT_RECEIVE_DETAILS - ); - return this.formatPaymentDetailsMessage( - notification.smsMessage, - payment, - tenantMetadata - ); - }; - - /** - * Formattes the payment details sms notification messafge. - * @param {string} smsMessage - * @param {IPaymentReceived} payment - * @param {ICustomer} customer - * @param {TenantMetadata} tenantMetadata - * @returns {string} - */ - private formatPaymentDetailsMessage = ( - smsMessage: string, - payment: IPaymentReceived, - tenantMetadata: any - ): string => { - const invoiceNumbers = this.stringifyPaymentInvoicesNumber(payment); - - // Formattes the payment number variable. - const formattedPaymentNumber = formatNumber(payment.amount, { - currencyCode: payment.currencyCode, - }); - - return formatSmsMessage(smsMessage, { - Amount: formattedPaymentNumber, - ReferenceNumber: payment.referenceNo, - CustomerName: payment.customer.displayName, - PaymentNumber: payment.paymentReceiveNo, - InvoiceNumber: invoiceNumbers, - CompanyName: tenantMetadata.name, - }); - }; - - /** - * Stringify payment receive invoices to numbers as string. - * @param {IPaymentReceived} payment - * @returns {string} - */ - private stringifyPaymentInvoicesNumber(payment: IPaymentReceived) { - const invoicesNumberes = payment.entries.map( - (entry: IPaymentReceivedEntry) => entry.invoice.invoiceNo - ); - return invoicesNumberes.join(', '); - } - - /** - * Retrieve the SMS details of the given invoice. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveid - Payment receive id. - */ - public smsDetails = async ( - tenantId: number, - paymentReceiveid: number - ): Promise => { - const { PaymentReceive } = this.tenancy.models(tenantId); - - // Retrieve the payment receive or throw not found service error. - const paymentReceive = await PaymentReceive.query() - .findById(paymentReceiveid) - .withGraphFetched('customer') - .withGraphFetched('entries.invoice'); - - // Current tenant metadata. - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieve the formatted sms message of payment receive details. - const smsMessage = this.formattedPaymentDetailsMessage( - tenantId, - paymentReceive, - tenantMetadata - ); - - return { - customerName: paymentReceive.customer.displayName, - customerPhoneNumber: paymentReceive.customer.personalPhone, - smsMessage, - }; - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsSubscriber.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsSubscriber.ts deleted file mode 100644 index c6f4af9e3..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedSmsSubscriber.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Container } from 'typedi'; -import { On, EventSubscriber } from 'event-dispatch'; -import events from '@/subscribers/events'; -import { PaymentReceiveNotifyBySms } from './PaymentReceivedSmsNotify'; - -@EventSubscriber() -export default class SendSmsNotificationPaymentReceive { - paymentReceiveNotifyBySms: PaymentReceiveNotifyBySms; - - constructor() { - this.paymentReceiveNotifyBySms = Container.get(PaymentReceiveNotifyBySms); - } - - /** - * - */ - @On(events.paymentReceive.onNotifySms) - async sendSmsNotificationOnceInvoiceNotify({ - paymentReceive, - customer, - }) { - await this.paymentReceiveNotifyBySms.sendSmsNotification( - paymentReceive, - customer - ); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedTransformer.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedTransformer.ts deleted file mode 100644 index 2ab49dfe7..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedTransformer.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { IPaymentReceived, IPaymentReceivedEntry } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { PaymentReceivedEntryTransfromer } from './PaymentReceivedEntryTransformer'; - -export class PaymentReceiveTransfromer extends Transformer { - /** - * Include these attributes to payment receive object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'subtotalFormatted', - 'formattedPaymentDate', - 'formattedCreatedAt', - 'formattedAmount', - 'formattedExchangeRate', - 'entries', - ]; - }; - - /** - * Retrieve formatted payment receive date. - * @param {ISaleInvoice} invoice - * @returns {String} - */ - protected formattedPaymentDate = (payment: IPaymentReceived): string => { - return this.formatDate(payment.paymentDate); - }; - - /** - * Retrieves the formatted created at date. - * @param {IPaymentReceived} payment - * @returns {string} - */ - protected formattedCreatedAt = (payment: IPaymentReceived): string => { - return this.formatDate(payment.createdAt); - }; - - /** - * Retrieve the formatted payment subtotal. - * @param {IPaymentReceived} payment - * @returns {string} - */ - protected subtotalFormatted = (payment: IPaymentReceived): string => { - return formatNumber(payment.amount, { - currencyCode: payment.currencyCode, - money: false, - }); - }; - - /** - * Retrieve formatted payment amount. - * @param {ISaleInvoice} invoice - * @returns {string} - */ - protected formattedAmount = (payment: IPaymentReceived): string => { - return formatNumber(payment.amount, { currencyCode: payment.currencyCode }); - }; - - /** - * Retrieve the formatted exchange rate. - * @param {IPaymentReceived} payment - * @returns {string} - */ - protected formattedExchangeRate = (payment: IPaymentReceived): string => { - return formatNumber(payment.exchangeRate, { money: false }); - }; - - /** - * Retrieves the payment entries. - * @param {IPaymentReceived} payment - * @returns {IPaymentReceivedEntry[]} - */ - protected entries = (payment: IPaymentReceived): IPaymentReceivedEntry[] => { - return this.item(payment.entries, new PaymentReceivedEntryTransfromer()); - }; -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedValidators.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedValidators.ts deleted file mode 100644 index 4adbe8f6d..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedValidators.ts +++ /dev/null @@ -1,295 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { difference, sumBy } from 'lodash'; -import { - IAccount, - IPaymentReceived, - IPaymentReceivedEditDTO, - IPaymentReceivedEntry, - IPaymentReceivedEntryDTO, - ISaleInvoice, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { ACCOUNT_TYPE } from '@/data/AccountTypes'; -import { PaymentReceive } from '@/models'; - -@Service() -export class PaymentReceivedValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates the payment existance. - * @param {PaymentReceive | null | undefined} payment - */ - public validatePaymentExistance(payment: PaymentReceive | null | undefined) { - if (!payment) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS); - } - } - - /** - * Validates the payment receive number existance. - * @param {number} tenantId - - * @param {string} paymentReceiveNo - - */ - public async validatePaymentReceiveNoExistance( - tenantId: number, - paymentReceiveNo: string, - notPaymentReceiveId?: number - ): Promise { - const { PaymentReceive } = this.tenancy.models(tenantId); - - const paymentReceive = await PaymentReceive.query() - .findOne('payment_receive_no', paymentReceiveNo) - .onBuild((builder) => { - if (notPaymentReceiveId) { - builder.whereNot('id', notPaymentReceiveId); - } - }); - - if (paymentReceive) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NO_EXISTS); - } - } - - /** - * Validates the invoices IDs existance. - * @param {number} tenantId - - * @param {number} customerId - - * @param {IPaymentReceivedEntryDTO[]} paymentReceiveEntries - - */ - public async validateInvoicesIDsExistance( - tenantId: number, - customerId: number, - paymentReceiveEntries: { invoiceId: number }[] - ): Promise { - const { SaleInvoice } = this.tenancy.models(tenantId); - - const invoicesIds = paymentReceiveEntries.map( - (e: { invoiceId: number }) => e.invoiceId - ); - const storedInvoices = await SaleInvoice.query() - .whereIn('id', invoicesIds) - .where('customer_id', customerId); - - const storedInvoicesIds = storedInvoices.map((invoice) => invoice.id); - const notFoundInvoicesIDs = difference(invoicesIds, storedInvoicesIds); - - if (notFoundInvoicesIDs.length > 0) { - throw new ServiceError(ERRORS.INVOICES_IDS_NOT_FOUND); - } - // Filters the not delivered invoices. - const notDeliveredInvoices = storedInvoices.filter( - (invoice) => !invoice.isDelivered - ); - if (notDeliveredInvoices.length > 0) { - throw new ServiceError(ERRORS.INVOICES_NOT_DELIVERED_YET, null, { - notDeliveredInvoices, - }); - } - return storedInvoices; - } - - /** - * Validates entries invoice payment amount. - * @param {Request} req - - * @param {Response} res - - * @param {Function} next - - */ - public async validateInvoicesPaymentsAmount( - tenantId: number, - paymentReceiveEntries: IPaymentReceivedEntryDTO[], - oldPaymentEntries: IPaymentReceivedEntry[] = [] - ) { - const { SaleInvoice } = this.tenancy.models(tenantId); - const invoicesIds = paymentReceiveEntries.map( - (e: IPaymentReceivedEntryDTO) => e.invoiceId - ); - - const storedInvoices = await SaleInvoice.query().whereIn('id', invoicesIds); - - const storedInvoicesMap = new Map( - storedInvoices.map((invoice: ISaleInvoice) => { - const oldEntries = oldPaymentEntries.filter((entry) => entry.invoiceId); - const oldPaymentAmount = sumBy(oldEntries, 'paymentAmount') || 0; - - return [ - invoice.id, - { ...invoice, dueAmount: invoice.dueAmount + oldPaymentAmount }, - ]; - }) - ); - const hasWrongPaymentAmount: any[] = []; - - paymentReceiveEntries.forEach( - (entry: IPaymentReceivedEntryDTO, index: number) => { - const entryInvoice = storedInvoicesMap.get(entry.invoiceId); - const { dueAmount } = entryInvoice; - - if (dueAmount < entry.paymentAmount) { - hasWrongPaymentAmount.push({ index, due_amount: dueAmount }); - } - } - ); - if (hasWrongPaymentAmount.length > 0) { - throw new ServiceError(ERRORS.INVALID_PAYMENT_AMOUNT); - } - } - - /** - * Validate the payment receive number require. - * @param {IPaymentReceived} paymentReceiveObj - */ - public validatePaymentReceiveNoRequire(paymentReceiveObj: IPaymentReceived) { - if (!paymentReceiveObj.paymentReceiveNo) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NO_IS_REQUIRED); - } - } - - /** - * Validate the payment receive entries IDs existance. - * @param {number} tenantId - * @param {number} paymentReceiveId - * @param {IPaymentReceivedEntryDTO[]} paymentReceiveEntries - */ - public async validateEntriesIdsExistance( - tenantId: number, - paymentReceiveId: number, - paymentReceiveEntries: IPaymentReceivedEntryDTO[] - ) { - const { PaymentReceiveEntry } = this.tenancy.models(tenantId); - - const entriesIds = paymentReceiveEntries - .filter((entry) => entry.id) - .map((entry) => entry.id); - - const storedEntries = await PaymentReceiveEntry.query().where( - 'payment_receive_id', - paymentReceiveId - ); - const storedEntriesIds = storedEntries.map((entry: any) => entry.id); - const notFoundEntriesIds = difference(entriesIds, storedEntriesIds); - - if (notFoundEntriesIds.length > 0) { - throw new ServiceError(ERRORS.ENTRIES_IDS_NOT_EXISTS); - } - } - - /** - * Validates the payment receive number require. - * @param {string} paymentReceiveNo - */ - public validatePaymentNoRequire(paymentReceiveNo: string) { - if (!paymentReceiveNo) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NO_REQUIRED); - } - } - - /** - * Validate the payment customer whether modified. - * @param {IPaymentReceivedEditDTO} paymentReceiveDTO - * @param {IPaymentReceived} oldPaymentReceive - */ - public validateCustomerNotModified( - paymentReceiveDTO: IPaymentReceivedEditDTO, - oldPaymentReceive: IPaymentReceived - ) { - if (paymentReceiveDTO.customerId !== oldPaymentReceive.customerId) { - throw new ServiceError(ERRORS.PAYMENT_CUSTOMER_SHOULD_NOT_UPDATE); - } - } - - /** - * Validates the payment account currency code. The deposit account curreny - * should be equals the customer currency code or the base currency. - * @param {string} paymentAccountCurrency - * @param {string} customerCurrency - * @param {string} baseCurrency - * @throws {ServiceError(ERRORS.PAYMENT_ACCOUNT_CURRENCY_INVALID)} - */ - public validatePaymentAccountCurrency = ( - paymentAccountCurrency: string, - customerCurrency: string, - baseCurrency: string - ) => { - if ( - paymentAccountCurrency !== customerCurrency && - paymentAccountCurrency !== baseCurrency - ) { - throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_CURRENCY_INVALID); - } - }; - - /** - * Validates the payment receive existance. - * @param {number} tenantId - Tenant id. - * @param {number} paymentReceiveId - Payment receive id. - */ - async getPaymentReceiveOrThrowError( - tenantId: number, - paymentReceiveId: number - ): Promise { - const { PaymentReceive } = this.tenancy.models(tenantId); - const paymentReceive = await PaymentReceive.query() - .withGraphFetched('entries') - .findById(paymentReceiveId); - - if (!paymentReceive) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS); - } - return paymentReceive; - } - - /** - * Validate the deposit account id existance. - * @param {number} tenantId - Tenant id. - * @param {number} depositAccountId - Deposit account id. - * @return {Promise} - */ - async getDepositAccountOrThrowError( - tenantId: number, - depositAccountId: number - ): Promise { - const { accountRepository } = this.tenancy.repositories(tenantId); - - const depositAccount = await accountRepository.findOneById( - depositAccountId - ); - if (!depositAccount) { - throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_NOT_FOUND); - } - // Detarmines whether the account is cash, bank or other current asset. - if ( - !depositAccount.isAccountType([ - ACCOUNT_TYPE.CASH, - ACCOUNT_TYPE.BANK, - ACCOUNT_TYPE.OTHER_CURRENT_ASSET, - ]) - ) { - throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_INVALID_TYPE); - } - return depositAccount; - } - - /** - * Validate the given customer has no payments receives. - * @param {number} tenantId - * @param {number} customerId - Customer id. - */ - public async validateCustomerHasNoPayments( - tenantId: number, - customerId: number - ) { - const { PaymentReceive } = this.tenancy.models(tenantId); - - const paymentReceives = await PaymentReceive.query().where( - 'customer_id', - customerId - ); - if (paymentReceives.length > 0) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_PAYMENT_RECEIVES); - } - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedExportable.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedExportable.ts deleted file mode 100644 index 43881da9a..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedExportable.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAccountsStructureType, IPaymentsReceivedFilter } from '@/interfaces'; -import { Exportable } from '@/services/Export/Exportable'; -import { PaymentReceivesApplication } from './PaymentReceivedApplication'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class PaymentsReceivedExportable extends Exportable { - @Inject() - private paymentReceivedApp: PaymentReceivesApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @param {IPaymentsReceivedFilter} query - - * @returns - */ - public exportable(tenantId: number, query: IPaymentsReceivedFilter) { - const filterQuery = (builder) => { - builder.withGraphFetched('entries.invoice'); - builder.withGraphFetched('branch'); - }; - - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - inactiveMode: false, - ...query, - structure: IAccountsStructureType.Flat, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery, - } as IPaymentsReceivedFilter; - - return this.paymentReceivedApp - .getPaymentReceives(tenantId, parsedQuery) - .then((output) => output.paymentReceives); - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedImportable.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedImportable.ts deleted file mode 100644 index eeefd6ca0..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedImportable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IPaymentReceivedCreateDTO } from '@/interfaces'; -import { Importable } from '@/services/Import/Importable'; -import { CreatePaymentReceived } from './CreatePaymentReceived'; -import { PaymentsReceiveSampleData } from './constants'; - -@Service() -export class PaymentsReceivedImportable extends Importable { - @Inject() - private createPaymentReceiveService: CreatePaymentReceived; - - /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createPaymentDTO: IPaymentReceivedCreateDTO, - trx?: Knex.Transaction - ) { - return this.createPaymentReceiveService.createPaymentReceived( - tenantId, - createPaymentDTO, - {}, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return PaymentsReceiveSampleData; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedPages.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedPages.ts deleted file mode 100644 index 6fd52882f..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentsReceivedPages.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { omit } from 'lodash'; -import { - ISaleInvoice, - IPaymentReceivePageEntry, - IPaymentReceived, - ISystemUser, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -/** - * Payment receives edit/new pages service. - */ -@Service() -export default class PaymentsReceivedPages { - @Inject() - private tenancy: TenancyService; - - /** - * Retrive page invoices entries from the given sale invoices models. - * @param {ISaleInvoice[]} invoices - Invoices. - * @return {IPaymentReceivePageEntry} - */ - private invoiceToPageEntry(invoice: ISaleInvoice): IPaymentReceivePageEntry { - return { - entryType: 'invoice', - invoiceId: invoice.id, - invoiceNo: invoice.invoiceNo, - amount: invoice.balance, - dueAmount: invoice.dueAmount, - paymentAmount: invoice.paymentAmount, - totalPaymentAmount: invoice.paymentAmount, - currencyCode: invoice.currencyCode, - date: invoice.invoiceDate, - }; - } - - /** - * Retrieve payment receive new page receivable entries. - * @param {number} tenantId - Tenant id. - * @param {number} vendorId - Vendor id. - * @return {IPaymentReceivePageEntry[]} - */ - public async getNewPageEntries(tenantId: number, customerId: number) { - const { SaleInvoice } = this.tenancy.models(tenantId); - - // Retrieve due invoices. - const entries = await SaleInvoice.query() - .modify('delivered') - .modify('dueInvoices') - .where('customer_id', customerId) - .orderBy('invoice_date', 'ASC'); - - return entries.map(this.invoiceToPageEntry); - } - - /** - * Retrieve the payment receive details of the given id. - * @param {number} tenantId - Tenant id. - * @param {Integer} paymentReceiveId - Payment receive id. - */ - public async getPaymentReceiveEditPage( - tenantId: number, - paymentReceiveId: number - ): Promise<{ - paymentReceive: Omit; - entries: IPaymentReceivePageEntry[]; - }> { - const { PaymentReceive, SaleInvoice } = this.tenancy.models(tenantId); - - // Retrieve payment receive. - const paymentReceive = await PaymentReceive.query() - .findById(paymentReceiveId) - .withGraphFetched('entries.invoice') - .withGraphFetched('attachments'); - - // Throw not found the payment receive. - if (!paymentReceive) { - throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS); - } - const paymentEntries = paymentReceive.entries.map((entry) => ({ - ...this.invoiceToPageEntry(entry.invoice), - dueAmount: entry.invoice.dueAmount + entry.paymentAmount, - paymentAmount: entry.paymentAmount, - index: entry.index, - })); - // Retrieves all receivable bills that associated to the payment receive transaction. - const restReceivableInvoices = await SaleInvoice.query() - .modify('delivered') - .modify('dueInvoices') - .where('customer_id', paymentReceive.customerId) - .whereNotIn( - 'id', - paymentReceive.entries.map((entry) => entry.invoiceId) - ) - .orderBy('invoice_date', 'ASC'); - - const restReceivableEntries = restReceivableInvoices.map( - this.invoiceToPageEntry - ); - const entries = [...paymentEntries, ...restReceivableEntries]; - - return { - paymentReceive: omit(paymentReceive, ['entries']), - entries, - }; - } -} diff --git a/packages/server/src/services/Sales/PaymentReceived/constants.ts b/packages/server/src/services/Sales/PaymentReceived/constants.ts deleted file mode 100644 index 713d7218c..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/constants.ts +++ /dev/null @@ -1,94 +0,0 @@ -export const DEFAULT_PAYMENT_MAIL_SUBJECT = - ' Payment Confirmation from {Company Name} – Thank You!'; -export const DEFAULT_PAYMENT_MAIL_CONTENT = `Dear {Customer Name} - -Thank you for your payment. It was a pleasure doing business with you. We look forward to work together again! - -Payment Transaction: {Payment Number} -Payment Date : {Payment Date} -Amount : {Payment Amount} - -Regards, -{Company Name}`; - -export const ERRORS = { - PAYMENT_RECEIVE_NO_EXISTS: 'PAYMENT_RECEIVE_NO_EXISTS', - PAYMENT_RECEIVE_NOT_EXISTS: 'PAYMENT_RECEIVE_NOT_EXISTS', - DEPOSIT_ACCOUNT_NOT_FOUND: 'DEPOSIT_ACCOUNT_NOT_FOUND', - DEPOSIT_ACCOUNT_INVALID_TYPE: 'DEPOSIT_ACCOUNT_INVALID_TYPE', - INVALID_PAYMENT_AMOUNT: 'INVALID_PAYMENT_AMOUNT', - INVOICES_IDS_NOT_FOUND: 'INVOICES_IDS_NOT_FOUND', - ENTRIES_IDS_NOT_EXISTS: 'ENTRIES_IDS_NOT_EXISTS', - INVOICES_NOT_DELIVERED_YET: 'INVOICES_NOT_DELIVERED_YET', - PAYMENT_RECEIVE_NO_IS_REQUIRED: 'PAYMENT_RECEIVE_NO_IS_REQUIRED', - PAYMENT_RECEIVE_NO_REQUIRED: 'PAYMENT_RECEIVE_NO_REQUIRED', - PAYMENT_CUSTOMER_SHOULD_NOT_UPDATE: 'PAYMENT_CUSTOMER_SHOULD_NOT_UPDATE', - CUSTOMER_HAS_PAYMENT_RECEIVES: 'CUSTOMER_HAS_PAYMENT_RECEIVES', - PAYMENT_ACCOUNT_CURRENCY_INVALID: 'PAYMENT_ACCOUNT_CURRENCY_INVALID', - NO_INVOICE_CUSTOMER_EMAIL_ADDR: 'NO_INVOICE_CUSTOMER_EMAIL_ADDR', -}; - -export const DEFAULT_VIEWS = []; - -export const PaymentsReceiveSampleData = [ - { - Customer: 'Randall Kohler', - 'Payment Date': '2024-10-10', - 'Payment Receive No.': 'PAY-0001', - 'Reference No.': 'REF-0001', - 'Deposit Account': 'Petty Cash', - 'Exchange Rate': '', - Statement: 'Totam optio quisquam qui.', - Invoice: 'INV-00001', - 'Payment Amount': 850, - }, -]; - -export const defaultPaymentReceivedPdfTemplateAttributes = { - // # Colors - primaryColor: '#000', - secondaryColor: '#000', - - // # Company logo - showCompanyLogo: true, - companyLogoUri: '', - - // # Company name - companyName: 'Bigcapital Technology, Inc.', - - // # Customer address - showCustomerAddress: true, - customerAddress: '', - - // # Company address - showCompanyAddress: true, - companyAddress: '', - billedToLabel: 'Billed To', - - // Total - total: '$1000.00', - totalLabel: 'Total', - showTotal: true, - - // Subtotal - subtotal: '1000/00', - subtotalLabel: 'Subtotal', - showSubtotal: true, - - lines: [ - { - invoiceNumber: 'INV-00001', - invoiceAmount: '$1000.00', - paidAmount: '$1000.00', - }, - ], - // Payment received number - showPaymentReceivedNumber: true, - paymentReceivedNumberLabel: 'Payment Number', - paymentReceivedNumebr: '346D3D40-0001', - - // Payment date. - paymentReceivedDate: 'September 3, 2024', - showPaymentReceivedDate: true, - paymentReceivedDateLabel: 'Payment Date', -}; diff --git a/packages/server/src/services/Sales/PaymentReceived/utils.ts b/packages/server/src/services/Sales/PaymentReceived/utils.ts deleted file mode 100644 index 533783b77..000000000 --- a/packages/server/src/services/Sales/PaymentReceived/utils.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - IPaymentReceived, - PaymentReceivedPdfTemplateAttributes, -} from '@/interfaces'; -import { contactAddressTextFormat } from '@/utils/address-text-format'; - -export const transformPaymentReceivedToPdfTemplate = ( - payment: IPaymentReceived -): Partial => { - return { - total: payment.formattedAmount, - subtotal: payment.subtotalFormatted, - paymentReceivedNumebr: payment.paymentReceiveNo, - paymentReceivedDate: payment.formattedPaymentDate, - customerName: payment.customer.displayName, - lines: payment.entries.map((entry) => ({ - invoiceNumber: entry.invoice.invoiceNo, - invoiceAmount: entry.invoice.totalFormatted, - paidAmount: entry.paymentAmountFormatted, - })), - customerAddress: contactAddressTextFormat(payment.customer), - }; -}; - -export const transformPaymentReceivedToMailDataArgs = (payment: any) => { - return { - 'Customer Name': payment.customer.displayName, - 'Payment Number': payment.paymentReceiveNo, - 'Payment Date': payment.formattedPaymentDate, - 'Payment Amount': payment.formattedAmount, - }; -}; diff --git a/packages/server/src/services/Sales/Receipts/CloseSaleReceipt.ts b/packages/server/src/services/Sales/Receipts/CloseSaleReceipt.ts deleted file mode 100644 index b678884e3..000000000 --- a/packages/server/src/services/Sales/Receipts/CloseSaleReceipt.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { - ISaleReceiptEventClosedPayload, - ISaleReceiptEventClosingPayload, -} from '@/interfaces'; -import { SaleReceiptValidators } from './SaleReceiptValidators'; - -@Service() -export class CloseSaleReceipt { - @Inject() - private tenancy: TenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: SaleReceiptValidators; - - /** - * Mark the given sale receipt as closed. - * @param {number} tenantId - * @param {number} saleReceiptId - * @return {Promise} - */ - public async closeSaleReceipt( - tenantId: number, - saleReceiptId: number - ): Promise { - const { SaleReceipt } = this.tenancy.models(tenantId); - - // Retrieve sale receipt or throw not found service error. - const oldSaleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('entries') - .throwIfNotFound(); - - // Throw service error if the sale receipt already closed. - this.validators.validateReceiptNotClosed(oldSaleReceipt); - - // Updates the sale recept transaction under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleReceiptClosing` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onClosing, { - tenantId, - oldSaleReceipt, - trx, - } as ISaleReceiptEventClosingPayload); - - // Mark the sale receipt as closed on the storage. - const saleReceipt = await SaleReceipt.query(trx).patchAndFetchById( - saleReceiptId, - { - closedAt: moment().toMySqlDateTime(), - } - ); - // Triggers `onSaleReceiptClosed` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onClosed, { - saleReceiptId, - saleReceipt, - tenantId, - trx, - } as ISaleReceiptEventClosedPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts b/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts deleted file mode 100644 index b66fe7daf..000000000 --- a/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { - ISaleReceipt, - ISaleReceiptCreatedPayload, - ISaleReceiptCreatingPayload, - ISaleReceiptDTO, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { SaleReceiptDTOTransformer } from './SaleReceiptDTOTransformer'; -import { SaleReceiptValidators } from './SaleReceiptValidators'; - -@Service() -export class CreateSaleReceipt { - @Inject() - private tenancy: TenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private transformer: SaleReceiptDTOTransformer; - - @Inject() - private validators: SaleReceiptValidators; - - /** - * Creates a new sale receipt with associated entries. - * @async - * @param {ISaleReceipt} saleReceipt - * @return {Object} - */ - public async createSaleReceipt( - tenantId: number, - saleReceiptDTO: ISaleReceiptDTO, - trx?: Knex.Transaction - ): Promise { - const { SaleReceipt, Contact } = this.tenancy.models(tenantId); - - // Retireves the payment customer model. - const paymentCustomer = await Contact.query() - .modify('customer') - .findById(saleReceiptDTO.customerId) - .throwIfNotFound(); - - // Transform sale receipt DTO to model. - const saleReceiptObj = await this.transformer.transformDTOToModel( - tenantId, - saleReceiptDTO, - paymentCustomer - ); - // Validate receipt deposit account existance and type. - await this.validators.validateReceiptDepositAccountExistance( - tenantId, - saleReceiptDTO.depositAccountId - ); - // Validate items IDs existance on the storage. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - saleReceiptDTO.entries - ); - // Validate the sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - saleReceiptDTO.entries - ); - // Validate sale receipt number uniuqiness. - if (saleReceiptDTO.receiptNumber) { - await this.validators.validateReceiptNumberUnique( - tenantId, - saleReceiptDTO.receiptNumber - ); - } - // Creates a sale receipt transaction and associated transactions under UOW env. - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onSaleReceiptCreating` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onCreating, { - saleReceiptDTO, - tenantId, - trx, - } as ISaleReceiptCreatingPayload); - - // Inserts the sale receipt graph to the storage. - const saleReceipt = await SaleReceipt.query().upsertGraph({ - ...saleReceiptObj, - }); - // Triggers `onSaleReceiptCreated` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onCreated, { - tenantId, - saleReceipt, - saleReceiptId: saleReceipt.id, - saleReceiptDTO, - trx, - } as ISaleReceiptCreatedPayload); - - return saleReceipt; - }, - trx - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/DeleteSaleReceipt.ts b/packages/server/src/services/Sales/Receipts/DeleteSaleReceipt.ts deleted file mode 100644 index b972c8279..000000000 --- a/packages/server/src/services/Sales/Receipts/DeleteSaleReceipt.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ISaleReceiptDeletingPayload, - ISaleReceiptEventDeletedPayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { SaleReceiptValidators } from './SaleReceiptValidators'; - -@Service() -export class DeleteSaleReceipt { - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: SaleReceiptValidators; - - /** - * Deletes the sale receipt with associated entries. - * @param {Integer} saleReceiptId - * @return {void} - */ - public async deleteSaleReceipt(tenantId: number, saleReceiptId: number) { - const { SaleReceipt, ItemEntry } = this.tenancy.models(tenantId); - - const oldSaleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('entries'); - - // Validates the sale receipt existance. - this.validators.validateReceiptExistance(oldSaleReceipt); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleReceiptsDeleting` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onDeleting, { - trx, - oldSaleReceipt, - tenantId, - } as ISaleReceiptDeletingPayload); - - await ItemEntry.query(trx) - .where('reference_id', saleReceiptId) - .where('reference_type', 'SaleReceipt') - .delete(); - - // Delete the sale receipt transaction. - await SaleReceipt.query(trx).where('id', saleReceiptId).delete(); - - // Triggers `onSaleReceiptsDeleted` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onDeleted, { - tenantId, - saleReceiptId, - oldSaleReceipt, - trx, - } as ISaleReceiptEventDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/Sales/Receipts/EditSaleReceipt.ts b/packages/server/src/services/Sales/Receipts/EditSaleReceipt.ts deleted file mode 100644 index 793494199..000000000 --- a/packages/server/src/services/Sales/Receipts/EditSaleReceipt.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { - ISaleReceiptEditedPayload, - ISaleReceiptEditingPayload, -} from '@/interfaces'; -import { SaleReceiptValidators } from './SaleReceiptValidators'; -import { SaleReceiptDTOTransformer } from './SaleReceiptDTOTransformer'; - -@Service() -export class EditSaleReceipt { - @Inject() - private tenancy: TenancyService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: SaleReceiptValidators; - - @Inject() - private DTOTransformer: SaleReceiptDTOTransformer; - - /** - * Edit details sale receipt with associated entries. - * @param {Integer} saleReceiptId - * @param {ISaleReceipt} saleReceipt - * @return {void} - */ - public async editSaleReceipt( - tenantId: number, - saleReceiptId: number, - saleReceiptDTO: any - ) { - const { SaleReceipt, Contact } = this.tenancy.models(tenantId); - - // Retrieve sale receipt or throw not found service error. - const oldSaleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('entries'); - - // Validates the sale receipt existance. - this.validators.validateReceiptExistance(oldSaleReceipt); - - // Retrieves the payment customer model. - const paymentCustomer = await Contact.query() - .findById(saleReceiptDTO.customerId) - .modify('customer') - .throwIfNotFound(); - - // Transform sale receipt DTO to model. - const saleReceiptObj = await this.DTOTransformer.transformDTOToModel( - tenantId, - saleReceiptDTO, - paymentCustomer, - oldSaleReceipt - ); - // Validate receipt deposit account existance and type. - await this.validators.validateReceiptDepositAccountExistance( - tenantId, - saleReceiptDTO.depositAccountId - ); - // Validate items IDs existance on the storage. - await this.itemsEntriesService.validateItemsIdsExistance( - tenantId, - saleReceiptDTO.entries - ); - // Validate the sellable items. - await this.itemsEntriesService.validateNonSellableEntriesItems( - tenantId, - saleReceiptDTO.entries - ); - // Validate sale receipt number uniuqiness. - if (saleReceiptDTO.receiptNumber) { - await this.validators.validateReceiptNumberUnique( - tenantId, - saleReceiptDTO.receiptNumber, - saleReceiptId - ); - } - // Edits the sale receipt tranasctions with associated transactions under UOW env. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onSaleReceiptsEditing` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onEditing, { - tenantId, - oldSaleReceipt, - saleReceiptDTO, - trx, - } as ISaleReceiptEditingPayload); - - // Upsert the receipt graph to the storage. - const saleReceipt = await SaleReceipt.query(trx).upsertGraphAndFetch({ - id: saleReceiptId, - ...saleReceiptObj, - }); - // Triggers `onSaleReceiptEdited` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onEdited, { - tenantId, - oldSaleReceipt, - saleReceipt, - saleReceiptId, - saleReceiptDTO, - trx, - } as ISaleReceiptEditedPayload); - - return saleReceipt; - }); - } -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceipt.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceipt.ts deleted file mode 100644 index c66a93019..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceipt.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { SaleReceiptTransformer } from './SaleReceiptTransformer'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { SaleReceiptValidators } from './SaleReceiptValidators'; - -@Service() -export class GetSaleReceipt { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private validators: SaleReceiptValidators; - - /** - * Retrieve sale receipt with associated entries. - * @param {Integer} saleReceiptId - * @return {ISaleReceipt} - */ - public async getSaleReceipt(tenantId: number, saleReceiptId: number) { - const { SaleReceipt } = this.tenancy.models(tenantId); - - const saleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('entries.item') - .withGraphFetched('customer') - .withGraphFetched('depositAccount') - .withGraphFetched('branch') - .withGraphFetched('attachments'); - - // Valdiates the sale receipt existance. - this.validators.validateReceiptExistance(saleReceipt); - - return this.transformer.transform( - tenantId, - saleReceipt, - new SaleReceiptTransformer() - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailState.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailState.ts deleted file mode 100644 index bc0e810c7..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailState.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { SaleReceiptMailNotification } from './SaleReceiptMailNotification'; -import { GetSaleReceiptMailStateTransformer } from './GetSaleReceiptMailStateTransformer'; - -@Service() -export class GetSaleReceiptMailState { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private receiptMail: SaleReceiptMailNotification; - - /** - * Retrieves the sale receipt mail state of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - */ - public async getMailState(tenantId: number, saleReceiptId: number) { - const { SaleReceipt } = this.tenancy.models(tenantId); - - const saleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('entries.item') - .withGraphFetched('customer') - .throwIfNotFound(); - - const mailOptions = await this.receiptMail.getMailOptions( - tenantId, - saleReceiptId - ); - return this.transformer.transform( - tenantId, - saleReceipt, - new GetSaleReceiptMailStateTransformer(), - { - mailOptions, - } - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailStateTransformer.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailStateTransformer.ts deleted file mode 100644 index 1f6126f52..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailStateTransformer.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { ItemEntryTransformer } from '../Invoices/ItemEntryTransformer'; -import { DiscountType } from '@/interfaces'; -import { SaleReceiptTransformer } from './SaleReceiptTransformer'; - -export class GetSaleReceiptMailStateTransformer extends SaleReceiptTransformer { - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Included attributes. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'companyName', - 'companyLogoUri', - 'primaryColor', - 'customerName', - - 'total', - 'totalFormatted', - - 'discountAmount', - 'discountAmountFormatted', - 'discountPercentage', - 'discountPercentageFormatted', - 'discountLabel', - - 'adjustment', - 'adjustmentFormatted', - - 'subtotal', - 'subtotalFormatted', - - 'receiptDate', - 'receiptDateFormatted', - - 'closedAtDate', - 'closedAtDateFormatted', - - 'receiptNumber', - 'entries', - ]; - }; - - /** - * Retrieves the customer name of the invoice. - * @returns {string} - */ - protected customerName = (receipt) => { - return receipt.customer.displayName; - }; - - /** - * Retrieves the company name. - * @returns {string} - */ - protected companyName = () => { - return this.context.organization.name; - }; - - /** - * Retrieves the company logo uri. - * @returns {string | null} - */ - protected companyLogoUri = (receipt) => { - return receipt.pdfTemplate?.companyLogoUri; - }; - - /** - * Retrieves the primary color. - * @returns {string} - */ - protected primaryColor = (receipt) => { - return receipt.pdfTemplate?.attributes?.primaryColor; - }; - - /** - * Retrieves the total amount. - * @param receipt - * @returns - */ - protected total = (receipt) => { - return receipt.total; - }; - - /** - * Retrieves the formatted total amount. - * @param receipt - * @returns {string} - */ - protected totalFormatted = (receipt) => { - return this.formatMoney(receipt.total, { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieves the discount label of the estimate. - * @param estimate - * @returns {string} - */ - protected discountLabel(receipt) { - return receipt.discountType === DiscountType.Percentage - ? `Discount [${receipt.discountPercentageFormatted}]` - : 'Discount'; - } - - /** - * Retrieves the subtotal of the receipt. - * @param receipt - * @returns - */ - protected subtotal = (receipt) => { - return receipt.subtotal; - }; - - /** - * Retrieves the formatted subtotal of the receipt. - * @param receipt - * @returns - */ - protected subtotalFormatted = (receipt) => { - return this.formatMoney(receipt.subtotal, { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieves the receipt date. - * @param receipt - * @returns - */ - protected receiptDate = (receipt): string => { - return receipt.receiptDate; - }; - - /** - * Retrieves the formatted receipt date. - * @param {ISaleReceipt} invoice - * @returns {string} - */ - protected receiptDateFormatted = (receipt): string => { - return this.formatDate(receipt.receiptDate); - }; - - /** - * - * @param receipt - * @returns - */ - protected closedAtDate = (receipt): string => { - return receipt.closedAt; - }; - - /** - * Retrieve formatted estimate closed at date. - * @param {ISaleReceipt} invoice - * @returns {String} - */ - protected closedAtDateFormatted = (receipt): string => { - return this.formatDate(receipt.closedAt); - }; - - /** - * - * @param invoice - * @returns - */ - protected entries = (receipt) => { - return this.item( - receipt.entries, - new GetSaleReceiptEntryMailStateTransformer(), - { - currencyCode: receipt.currencyCode, - } - ); - }; - - /** - * Merges the mail options with the invoice object. - */ - public transform = (object: any) => { - return { - ...this.options.mailOptions, - ...object, - }; - }; -} - -class GetSaleReceiptEntryMailStateTransformer extends ItemEntryTransformer { - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public name = (entry) => { - return entry.item.name; - }; - - public includeAttributes = (): string[] => { - return [ - 'name', - 'quantity', - 'quantityFormatted', - 'rate', - 'rateFormatted', - 'total', - 'totalFormatted', - ]; - }; -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplate.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplate.ts deleted file mode 100644 index 2a46e27c9..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplate.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - ReceiptEmailTemplateProps, - renderReceiptEmailTemplate, -} from '@bigcapital/email-components'; -import { Inject, Service } from 'typedi'; -import { GetSaleReceipt } from './GetSaleReceipt'; -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetSaleReceiptMailTemplateAttributesTransformer } from './GetSaleReceiptMailTemplateAttributesTransformer'; - -@Service() -export class GetSaleReceiptMailTemplate { - @Inject() - private getReceiptService: GetSaleReceipt; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private getBrandingTemplate: GetPdfTemplate; - - /** - * Retrieves the mail template attributes of the given estimate. - * Estimate template attributes are composed of the estimate and branding template attributes. - * @param {number} tenantId - * @param {number} receiptId - Receipt id. - * @returns {Promise} - */ - public async getMailTemplateAttributes( - tenantId: number, - receiptId: number - ): Promise { - const receipt = await this.getReceiptService.getSaleReceipt( - tenantId, - receiptId - ); - const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate( - tenantId, - receipt.pdfTemplateId - ); - const mailTemplateAttributes = await this.transformer.transform( - tenantId, - receipt, - new GetSaleReceiptMailTemplateAttributesTransformer(), - { - receipt, - brandingTemplate, - } - ); - return mailTemplateAttributes; - } - - /** - * Retrieves the mail template html content. - * @param {number} tenantId - * @param {number} estimateId - * @param overrideAttributes - * @returns - */ - public async getMailTemplate( - tenantId: number, - estimateId: number, - overrideAttributes?: Partial - ): Promise { - const attributes = await this.getMailTemplateAttributes( - tenantId, - estimateId - ); - const mergedAttributes = { - ...attributes, - ...overrideAttributes, - }; - return renderReceiptEmailTemplate(mergedAttributes); - } -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts deleted file mode 100644 index 43a212425..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetSaleReceiptMailTemplateAttributesTransformer extends Transformer { - public includeAttributes = (): string[] => { - return [ - 'companyLogoUri', - 'companyName', - - 'primaryColor', - - 'receiptAmount', - 'receiptMessage', - - 'date', - 'dateLabel', - - 'receiptNumber', - 'receiptNumberLabel', - - 'total', - 'totalLabel', - - 'discount', - 'discountLabel', - - 'adjustment', - 'adjustmentLabel', - - 'subtotal', - 'subtotalLabel', - - 'paidAmount', - 'paidAmountLabel', - - 'items', - ]; - }; - - /** - * Exclude all attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['*']; - }; - - /** - * Company logo uri. - * @returns {string} - */ - public companyLogoUri(): string { - return this.options.brandingTemplate?.companyLogoUri; - } - - /** - * Company name. - * @returns {string} - */ - public companyName(): string { - return this.context.organization.name; - } - - /** - * Primary color - * @returns {string} - */ - public primaryColor(): string { - return this.options?.brandingTemplate?.attributes?.primaryColor; - } - - /** - * Receipt number. - * @returns {string} - */ - public receiptNumber(): string { - return this.options.receipt.receiptNumber; - } - - /** - * Receipt number label. - * @returns {string} - */ - public receiptNumberLabel(): string { - return 'Receipt # {receiptNumber}'; - } - - /** - * Date. - * @returns {string} - */ - public date(): string { - return this.options.receipt.date; - } - - /** - * Date label. - * @returns {string} - */ - public dateLabel(): string { - return 'Date'; - } - - /** - * Receipt total. - */ - public total(): string { - return this.options.receipt.totalFormatted; - } - - /** - * Receipt total label. - * @returns {string} - */ - public totalLabel(): string { - return 'Total'; - } - - /** - * Receipt discount. - * @returns {string} - */ - public discount(): string { - return this.options.receipt?.discountAmountFormatted; - } - - /** - * Receipt discount label. - * @returns {string} - */ - public discountLabel(): string { - return 'Discount'; - } - - /** - * Receipt adjustment. - * @returns {string} - */ - public adjustment(): string { - return this.options.receipt?.adjustmentFormatted; - } - - /** - * Receipt adjustment label. - * @returns {string} - */ - public adjustmentLabel(): string { - return 'Adjustment'; - } - - /** - * Receipt subtotal. - * @returns {string} - */ - public subtotal(): string { - return this.options.receipt.subtotalFormatted; - } - - /** - * Receipt subtotal label. - * @returns {string} - */ - public subtotalLabel(): string { - return 'Subtotal'; - } - - /** - * Receipt mail items attributes. - */ - public items(): any[] { - return this.item( - this.options.receipt.entries, - new GetSaleReceiptMailTemplateEntryAttributesTransformer() - ); - } -} - -class GetSaleReceiptMailTemplateEntryAttributesTransformer extends Transformer { - public includeAttributes = (): string[] => { - return ['label', 'quantity', 'rate', 'total']; - }; - - public excludeAttributes = (): string[] => { - return ['*']; - }; - - public label(entry): string { - return entry?.item?.name; - } - - public quantity(entry): string { - return entry?.quantity; - } - - public rate(entry): string { - return entry?.rateFormatted; - } - - public total(entry): string { - return entry?.totalFormatted; - } -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceiptState.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceiptState.ts deleted file mode 100644 index cde274978..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceiptState.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISaleReceiptState } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class GetSaleReceiptState { - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves the sale receipt state. - * @param {Number} tenantId - - * @return {Promise} - */ - public async getSaleReceiptState( - tenantId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const defaultPdfTemplate = await PdfTemplate.query() - .findOne({ resource: 'SaleReceipt' }) - .modify('default'); - - return { - defaultTemplateId: defaultPdfTemplate?.id, - }; - } -} diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceipts.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceipts.ts deleted file mode 100644 index d38c58c61..000000000 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceipts.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as R from 'ramda'; -import { - IFilterMeta, - IPaginationMeta, - ISaleReceipt, - ISalesReceiptsFilter, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { SaleReceiptTransformer } from './SaleReceiptTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; - -interface GetSaleReceiptsSettings { - fetchEntriesGraph?: boolean; -} -@Service() -export class GetSaleReceipts { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - @Inject() - private dynamicListService: DynamicListingService; - - /** - * Retrieve sales receipts paginated and filterable list. - * @param {number} tenantId - * @param {ISaleReceiptFilter} salesReceiptsFilter - */ - public async getSaleReceipts( - tenantId: number, - filterDTO: ISalesReceiptsFilter - ): Promise<{ - data: ISaleReceipt[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - const { SaleReceipt } = this.tenancy.models(tenantId); - - // Parses the stringified filter roles. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - SaleReceipt, - filter - ); - const { results, pagination } = await SaleReceipt.query() - .onBuild((builder) => { - builder.withGraphFetched('depositAccount'); - builder.withGraphFetched('customer'); - builder.withGraphFetched('entries.item'); - - dynamicFilter.buildQuery()(builder); - filterDTO?.filterQuery && filterDTO?.filterQuery(builder); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Transformes the estimates models to POJO. - const salesEstimates = await this.transformer.transform( - tenantId, - results, - new SaleReceiptTransformer() - ); - return { - data: salesEstimates, - pagination, - filterMeta: dynamicFilter.getResponseMeta(), - }; - } - - /** - * Parses the sale invoice list filter DTO. - * @param filterDTO - * @returns - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptApplication.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptApplication.ts deleted file mode 100644 index 5fbcd78cc..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptApplication.ts +++ /dev/null @@ -1,257 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { CreateSaleReceipt } from './CreateSaleReceipt'; -import { - IFilterMeta, - IPaginationMeta, - ISaleReceipt, - ISaleReceiptState, - ISalesReceiptsFilter, - SaleReceiptMailOpts, - SaleReceiptMailOptsDTO, -} from '@/interfaces'; -import { EditSaleReceipt } from './EditSaleReceipt'; -import { GetSaleReceipt } from './GetSaleReceipt'; -import { DeleteSaleReceipt } from './DeleteSaleReceipt'; -import { GetSaleReceipts } from './GetSaleReceipts'; -import { CloseSaleReceipt } from './CloseSaleReceipt'; -import { SaleReceiptsPdf } from './SaleReceiptsPdfService'; -import { SaleReceiptNotifyBySms } from './SaleReceiptNotifyBySms'; -import { SaleReceiptMailNotification } from './SaleReceiptMailNotification'; -import { GetSaleReceiptState } from './GetSaleReceiptState'; -import { GetSaleReceiptMailState } from './GetSaleReceiptMailState'; - -@Service() -export class SaleReceiptApplication { - @Inject() - private createSaleReceiptService: CreateSaleReceipt; - - @Inject() - private editSaleReceiptService: EditSaleReceipt; - - @Inject() - private getSaleReceiptService: GetSaleReceipt; - - @Inject() - private deleteSaleReceiptService: DeleteSaleReceipt; - - @Inject() - private getSaleReceiptsService: GetSaleReceipts; - - @Inject() - private closeSaleReceiptService: CloseSaleReceipt; - - @Inject() - private getSaleReceiptPdfService: SaleReceiptsPdf; - - @Inject() - private saleReceiptNotifyBySmsService: SaleReceiptNotifyBySms; - - @Inject() - private saleReceiptNotifyByMailService: SaleReceiptMailNotification; - - @Inject() - private getSaleReceiptStateService: GetSaleReceiptState; - - @Inject() - private getSaleReceiptMailStateService: GetSaleReceiptMailState; - - /** - * Creates a new sale receipt with associated entries. - * @param {number} tenantId - * @param {} saleReceiptDTO - * @returns {Promise} - */ - public async createSaleReceipt( - tenantId: number, - saleReceiptDTO: any - ): Promise { - return this.createSaleReceiptService.createSaleReceipt( - tenantId, - saleReceiptDTO - ); - } - - /** - * Edit details sale receipt with associated entries. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {} saleReceiptDTO - * @returns - */ - public async editSaleReceipt( - tenantId: number, - saleReceiptId: number, - saleReceiptDTO: any - ) { - return this.editSaleReceiptService.editSaleReceipt( - tenantId, - saleReceiptId, - saleReceiptDTO - ); - } - - /** - * Retrieve sale receipt with associated entries. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns - */ - public async getSaleReceipt(tenantId: number, saleReceiptId: number) { - return this.getSaleReceiptService.getSaleReceipt(tenantId, saleReceiptId); - } - - /** - * Deletes the sale receipt with associated entries. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns - */ - public async deleteSaleReceipt(tenantId: number, saleReceiptId: number) { - return this.deleteSaleReceiptService.deleteSaleReceipt( - tenantId, - saleReceiptId - ); - } - - /** - * Retrieve sales receipts paginated and filterable list. - * @param {number} tenantId - * @param {ISalesReceiptsFilter} filterDTO - * @returns - */ - public async getSaleReceipts( - tenantId: number, - filterDTO: ISalesReceiptsFilter - ): Promise<{ - data: ISaleReceipt[]; - pagination: IPaginationMeta; - filterMeta: IFilterMeta; - }> { - return this.getSaleReceiptsService.getSaleReceipts(tenantId, filterDTO); - } - - /** - * Closes the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns {Promise} - */ - public async closeSaleReceipt(tenantId: number, saleReceiptId: number) { - return this.closeSaleReceiptService.closeSaleReceipt( - tenantId, - saleReceiptId - ); - } - - /** - * Retrieves the given sale receipt pdf. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns - */ - public getSaleReceiptPdf(tenantId: number, saleReceiptId: number) { - return this.getSaleReceiptPdfService.saleReceiptPdf( - tenantId, - saleReceiptId - ); - } - - /** - * Retrieves the given sale receipt html. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns {Promise} - */ - public getSaleReceiptHtml(tenantId: number, saleReceiptId: number) { - return this.getSaleReceiptPdfService.saleReceiptHtml( - tenantId, - saleReceiptId - ); - } - - /** - * Notify receipt customer by SMS of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns - */ - public saleReceiptNotifyBySms(tenantId: number, saleReceiptId: number) { - return this.saleReceiptNotifyBySmsService.notifyBySms( - tenantId, - saleReceiptId - ); - } - - /** - * Retrieves sms details of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns - */ - public getSaleReceiptSmsDetails(tenantId: number, saleReceiptId: number) { - return this.saleReceiptNotifyBySmsService.smsDetails( - tenantId, - saleReceiptId - ); - } - - /** - * Sends the receipt mail of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {SaleReceiptMailOptsDTO} messageOpts - * @returns {Promise} - */ - public sendSaleReceiptMail( - tenantId: number, - saleReceiptId: number, - messageOpts: SaleReceiptMailOptsDTO - ): Promise { - return this.saleReceiptNotifyByMailService.triggerMail( - tenantId, - saleReceiptId, - messageOpts - ); - } - - /** - * Retrieves the default mail options of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns {Promise} - */ - public getSaleReceiptMail( - tenantId: number, - saleReceiptId: number - ): Promise { - return this.saleReceiptNotifyByMailService.getMailOptions( - tenantId, - saleReceiptId - ); - } - - /** - * Retrieves the current state of the sale receipt. - * @param {number} tenantId - The ID of the tenant. - * @returns {Promise} - A promise resolving to the sale receipt state. - */ - public getSaleReceiptState(tenantId: number): Promise { - return this.getSaleReceiptStateService.getSaleReceiptState(tenantId); - } - - /** - * Retrieves the mail state of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns - */ - public getSaleReceiptMailState( - tenantId: number, - saleReceiptId: number - ): Promise { - return this.getSaleReceiptMailStateService.getMailState( - tenantId, - saleReceiptId - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts deleted file mode 100644 index 12689d7cd..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; -import { Inject, Service } from 'typedi'; -import { defaultSaleReceiptBrandingAttributes } from './constants'; -import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils'; -import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes'; - -@Service() -export class SaleReceiptBrandingTemplate { - @Inject() - private getPdfTemplateService: GetPdfTemplate; - - @Inject() - private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; - - /** - * Retrieves the sale receipt branding template. - * @param {number} tenantId - The ID of the tenant. - * @param {number} templateId - The ID of the PDF template. - * @returns {Promise} The sale receipt branding template with merged attributes. - */ - public async getSaleReceiptBrandingTemplate( - tenantId: number, - templateId: number - ) { - const template = await this.getPdfTemplateService.getPdfTemplate( - tenantId, - templateId - ); - // Retrieves the organization branding attributes. - const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes( - tenantId - ); - - // Merges the default branding attributes with organization common branding attrs. - const organizationBrandingAttrs = { - ...defaultSaleReceiptBrandingAttributes, - ...commonOrgBrandingAttrs, - }; - const brandingTemplateAttrs = { - ...template.attributes, - companyLogoUri: template.companyLogoUri, - }; - const attributes = mergePdfTemplateWithDefaultAttributes( - brandingTemplateAttrs, - organizationBrandingAttrs - ); - return { - ...template, - attributes, - }; - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptCostGLEntries.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptCostGLEntries.ts deleted file mode 100644 index 1ec69625b..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptCostGLEntries.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import { Knex } from 'knex'; -import { AccountNormal, IInventoryLotCost, ILedgerEntry } from '@/interfaces'; -import { increment } from 'utils'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import Ledger from '@/services/Accounting/Ledger'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import { groupInventoryTransactionsByTypeId } from '../../Inventory/utils'; - -@Service() -export class SaleReceiptCostGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Writes journal entries from sales invoices. - * @param {number} tenantId - The tenant id. - * @param {Date} startingDate - Starting date. - * @param {boolean} override - */ - public writeInventoryCostJournalEntries = async ( - tenantId: number, - startingDate: Date, - trx?: Knex.Transaction - ): Promise => { - const { InventoryCostLotTracker } = this.tenancy.models(tenantId); - - const inventoryCostLotTrans = await InventoryCostLotTracker.query() - .where('direction', 'OUT') - .where('transaction_type', 'SaleReceipt') - .where('cost', '>', 0) - .modify('filterDateRange', startingDate) - .orderBy('date', 'ASC') - .withGraphFetched('receipt') - .withGraphFetched('item'); - - const ledger = this.getInventoryCostLotsLedger(inventoryCostLotTrans); - - // Commit the ledger to the storage. - await this.ledgerStorage.commit(tenantId, ledger, trx); - }; - - /** - * Retrieves the inventory cost lots ledger. - * @param {} inventoryCostLots - * @returns {Ledger} - */ - private getInventoryCostLotsLedger = ( - inventoryCostLots: IInventoryLotCost[] - ) => { - // Groups the inventory cost lots transactions. - const inventoryTransactions = - groupInventoryTransactionsByTypeId(inventoryCostLots); - - // - const entries = inventoryTransactions - .map(this.getSaleInvoiceCostGLEntries) - .flat(); - - return new Ledger(entries); - }; - - /** - * - * @param {IInventoryLotCost} inventoryCostLot - * @returns {} - */ - private getInvoiceCostGLCommonEntry = ( - inventoryCostLot: IInventoryLotCost - ) => { - return { - currencyCode: inventoryCostLot.receipt.currencyCode, - exchangeRate: inventoryCostLot.receipt.exchangeRate, - - transactionType: inventoryCostLot.transactionType, - transactionId: inventoryCostLot.transactionId, - - date: inventoryCostLot.date, - indexGroup: 20, - costable: true, - createdAt: inventoryCostLot.createdAt, - - debit: 0, - credit: 0, - - branchId: inventoryCostLot.receipt.branchId, - }; - }; - - /** - * Retrieves the inventory cost GL entry. - * @param {IInventoryLotCost} inventoryLotCost - * @returns {ILedgerEntry[]} - */ - private getInventoryCostGLEntry = R.curry( - ( - getIndexIncrement, - inventoryCostLot: IInventoryLotCost - ): ILedgerEntry[] => { - const commonEntry = this.getInvoiceCostGLCommonEntry(inventoryCostLot); - const costAccountId = - inventoryCostLot.costAccountId || inventoryCostLot.item.costAccountId; - - // XXX Debit - Cost account. - const costEntry = { - ...commonEntry, - debit: inventoryCostLot.cost, - accountId: costAccountId, - accountNormal: AccountNormal.DEBIT, - itemId: inventoryCostLot.itemId, - index: getIndexIncrement(), - }; - // XXX Credit - Inventory account. - const inventoryEntry = { - ...commonEntry, - credit: inventoryCostLot.cost, - accountId: inventoryCostLot.item.inventoryAccountId, - accountNormal: AccountNormal.DEBIT, - itemId: inventoryCostLot.itemId, - index: getIndexIncrement(), - }; - return [costEntry, inventoryEntry]; - } - ); - - /** - * Writes journal entries for given sale invoice. - * ------- - * - Cost of goods sold -> Debit -> YYYY - * - Inventory assets -> Credit -> YYYY - * -------- - * @param {ISaleInvoice} saleInvoice - * @param {JournalPoster} journal - */ - public getSaleInvoiceCostGLEntries = ( - inventoryCostLots: IInventoryLotCost[] - ): ILedgerEntry[] => { - const getIndexIncrement = increment(0); - const getInventoryLotEntry = - this.getInventoryCostGLEntry(getIndexIncrement); - - return inventoryCostLots.map(getInventoryLotEntry).flat(); - }; -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptDTOTransformer.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptDTOTransformer.ts deleted file mode 100644 index 78d14b3b8..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptDTOTransformer.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { Inject, Service } from 'typedi'; -import * as R from 'ramda'; -import { sumBy, omit } from 'lodash'; -import composeAsync from 'async/compose'; -import moment from 'moment'; -import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; -import { SaleReceiptValidators } from './SaleReceiptValidators'; -import { ICustomer, ISaleReceipt, ISaleReceiptDTO } from '@/interfaces'; -import { formatDateFields } from '@/utils'; -import { SaleReceiptIncrement } from './SaleReceiptIncrement'; -import { ItemEntry } from '@/models'; -import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; -import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer'; - -@Service() -export class SaleReceiptDTOTransformer { - @Inject() - private itemsEntriesService: ItemsEntriesService; - - @Inject() - private branchDTOTransform: BranchTransactionDTOTransform; - - @Inject() - private warehouseDTOTransform: WarehouseTransactionDTOTransform; - - @Inject() - private validators: SaleReceiptValidators; - - @Inject() - private receiptIncrement: SaleReceiptIncrement; - - @Inject() - private brandingTemplatesTransformer: BrandingTemplateDTOTransformer; - - /** - * Transform create DTO object to model object. - * @param {ISaleReceiptDTO} saleReceiptDTO - - * @param {ISaleReceipt} oldSaleReceipt - - * @returns {ISaleReceipt} - */ - async transformDTOToModel( - tenantId: number, - saleReceiptDTO: ISaleReceiptDTO, - paymentCustomer: ICustomer, - oldSaleReceipt?: ISaleReceipt - ): Promise { - const amount = sumBy(saleReceiptDTO.entries, (e) => - ItemEntry.calcAmount(e) - ); - // Retreive the next invoice number. - const autoNextNumber = this.receiptIncrement.getNextReceiptNumber(tenantId); - - // Retreive the receipt number. - const receiptNumber = - saleReceiptDTO.receiptNumber || - oldSaleReceipt?.receiptNumber || - autoNextNumber; - - // Validate receipt number require. - this.validators.validateReceiptNoRequire(receiptNumber); - - const initialEntries = saleReceiptDTO.entries.map((entry) => ({ - reference_type: 'SaleReceipt', - ...entry, - })); - - const asyncEntries = await composeAsync( - // Sets default cost and sell account to receipt items entries. - this.itemsEntriesService.setItemsEntriesDefaultAccounts(tenantId) - )(initialEntries); - - const entries = R.compose( - // Associate the default index for each item entry. - assocItemEntriesDefaultIndex - )(asyncEntries); - - const initialDTO = { - amount, - ...formatDateFields( - omit(saleReceiptDTO, ['closed', 'entries', 'attachments']), - ['receiptDate'] - ), - currencyCode: paymentCustomer.currencyCode, - exchangeRate: saleReceiptDTO.exchangeRate || 1, - receiptNumber, - // Avoid rewrite the deliver date in edit mode when already published. - ...(saleReceiptDTO.closed && - !oldSaleReceipt?.closedAt && { - closedAt: moment().toMySqlDateTime(), - }), - entries, - }; - const initialAsyncDTO = await composeAsync( - // Assigns the default branding template id to the invoice DTO. - this.brandingTemplatesTransformer.assocDefaultBrandingTemplate( - tenantId, - 'SaleReceipt' - ) - )(initialDTO); - - return R.compose( - this.branchDTOTransform.transformDTO(tenantId), - this.warehouseDTOTransform.transformDTO(tenantId) - )(initialAsyncDTO); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptGLEntries.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptGLEntries.ts deleted file mode 100644 index 3cb4d9d0e..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptGLEntries.ts +++ /dev/null @@ -1,258 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import * as R from 'ramda'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -import { - AccountNormal, - ILedgerEntry, - ISaleReceipt, - IItemEntry, -} from '@/interfaces'; -import Ledger from '@/services/Accounting/Ledger'; - -@Service() -export class SaleReceiptGLEntries { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private ledgerStorage: LedgerStorageService; - - /** - * Creates income GL entries. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {Knex.Transaction} trx - */ - public writeIncomeGLEntries = async ( - tenantId: number, - saleReceiptId: number, - trx?: Knex.Transaction - ): Promise => { - const { SaleReceipt } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - const saleReceipt = await SaleReceipt.query(trx) - .findById(saleReceiptId) - .withGraphFetched('entries.item'); - - // Find or create the discount expense account. - const discountAccount = await accountRepository.findOrCreateDiscountAccount( - {}, - trx - ); - // Find or create the other charges account. - const otherChargesAccount = - await accountRepository.findOrCreateOtherChargesAccount({}, trx); - - // Retrieve the income entries ledger. - const incomeLedger = this.getIncomeEntriesLedger( - saleReceipt, - discountAccount.id, - otherChargesAccount.id - ); - - // Commits the ledger entries to the storage. - await this.ledgerStorage.commit(tenantId, incomeLedger, trx); - }; - - /** - * Reverts the receipt GL entries. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public revertReceiptGLEntries = async ( - tenantId: number, - saleReceiptId: number, - trx?: Knex.Transaction - ): Promise => { - await this.ledgerStorage.deleteByReference( - tenantId, - saleReceiptId, - 'SaleReceipt', - trx - ); - }; - - /** - * Rewrites the receipt GL entries. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public rewriteReceiptGLEntries = async ( - tenantId: number, - saleReceiptId: number, - trx?: Knex.Transaction - ): Promise => { - // Reverts the receipt GL entries. - await this.revertReceiptGLEntries(tenantId, saleReceiptId, trx); - - // Writes the income GL entries. - await this.writeIncomeGLEntries(tenantId, saleReceiptId, trx); - }; - - /** - * Retrieves the income GL ledger. - * @param {ISaleReceipt} saleReceipt - * @returns {Ledger} - */ - private getIncomeEntriesLedger = ( - saleReceipt: ISaleReceipt, - discountAccountId: number, - otherChargesAccountId: number - ): Ledger => { - const entries = this.getIncomeGLEntries( - saleReceipt, - discountAccountId, - otherChargesAccountId - ); - - return new Ledger(entries); - }; - - /** - * Retireves the income GL common entry. - * @param {ISaleReceipt} saleReceipt - - */ - private getIncomeGLCommonEntry = (saleReceipt: ISaleReceipt) => { - return { - currencyCode: saleReceipt.currencyCode, - exchangeRate: saleReceipt.exchangeRate, - - transactionType: 'SaleReceipt', - transactionId: saleReceipt.id, - - date: saleReceipt.receiptDate, - - transactionNumber: saleReceipt.receiptNumber, - referenceNumber: saleReceipt.referenceNo, - - createdAt: saleReceipt.createdAt, - - credit: 0, - debit: 0, - - userId: saleReceipt.userId, - branchId: saleReceipt.branchId, - }; - }; - - /** - * Retrieve receipt income item G/L entry. - * @param {ISaleReceipt} saleReceipt - - * @param {IItemEntry} entry - - * @param {number} index - - * @returns {ILedgerEntry} - */ - private getReceiptIncomeItemEntry = R.curry( - ( - saleReceipt: ISaleReceipt, - entry: IItemEntry, - index: number - ): ILedgerEntry => { - const commonEntry = this.getIncomeGLCommonEntry(saleReceipt); - const totalLocal = entry.totalExcludingTax * saleReceipt.exchangeRate; - - return { - ...commonEntry, - credit: totalLocal, - accountId: entry.item.sellAccountId, - note: entry.description, - index: index + 2, - itemId: entry.itemId, - itemQuantity: entry.quantity, - accountNormal: AccountNormal.CREDIT, - }; - } - ); - - /** - * Retrieves the receipt deposit GL deposit entry. - * @param {ISaleReceipt} saleReceipt - * @returns {ILedgerEntry} - */ - private getReceiptDepositEntry = ( - saleReceipt: ISaleReceipt - ): ILedgerEntry => { - const commonEntry = this.getIncomeGLCommonEntry(saleReceipt); - - return { - ...commonEntry, - debit: saleReceipt.totalLocal, - accountId: saleReceipt.depositAccountId, - index: 1, - accountNormal: AccountNormal.DEBIT, - }; - }; - - /** - * Retrieves the discount GL entry. - * @param {ISaleReceipt} saleReceipt - * @param {number} discountAccountId - * @returns {ILedgerEntry} - */ - private getDiscountEntry = ( - saleReceipt: ISaleReceipt, - discountAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getIncomeGLCommonEntry(saleReceipt); - - return { - ...commonEntry, - debit: saleReceipt.discountAmountLocal, - accountId: discountAccountId, - index: 1, - accountNormal: AccountNormal.CREDIT, - }; - }; - - /** - * Retrieves the adjustment GL entry. - * @param {ISaleReceipt} saleReceipt - * @param {number} adjustmentAccountId - * @returns {ILedgerEntry} - */ - private getAdjustmentEntry = ( - saleReceipt: ISaleReceipt, - adjustmentAccountId: number - ): ILedgerEntry => { - const commonEntry = this.getIncomeGLCommonEntry(saleReceipt); - const adjustmentAmount = Math.abs(saleReceipt.adjustmentLocal); - - return { - ...commonEntry, - debit: saleReceipt.adjustmentLocal < 0 ? adjustmentAmount : 0, - credit: saleReceipt.adjustmentLocal > 0 ? adjustmentAmount : 0, - accountId: adjustmentAccountId, - accountNormal: AccountNormal.CREDIT, - index: 1, - }; - }; - - /** - * Retrieves the income GL entries. - * @param {ISaleReceipt} saleReceipt - - * @returns {ILedgerEntry[]} - */ - private getIncomeGLEntries = ( - saleReceipt: ISaleReceipt, - discountAccountId: number, - otherChargesAccountId: number - ): ILedgerEntry[] => { - const getItemEntry = this.getReceiptIncomeItemEntry(saleReceipt); - - const creditEntries = saleReceipt.entries.map(getItemEntry); - const depositEntry = this.getReceiptDepositEntry(saleReceipt); - const discountEntry = this.getDiscountEntry(saleReceipt, discountAccountId); - const adjustmentEntry = this.getAdjustmentEntry( - saleReceipt, - otherChargesAccountId - ); - return [depositEntry, ...creditEntries, discountEntry, adjustmentEntry]; - }; -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptIncrement.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptIncrement.ts deleted file mode 100644 index eae263044..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptIncrement.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import AutoIncrementOrdersService from '../AutoIncrementOrdersService'; - -@Service() -export class SaleReceiptIncrement { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - /** - * Retrieve the next unique receipt number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - public getNextReceiptNumber(tenantId: number): string { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'sales_receipts' - ); - } - - /** - * Increment the receipt next number. - * @param {number} tenantId - - */ - public incrementNextReceiptNumber(tenantId: number) { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'sales_receipts' - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptInventoryTransactions.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptInventoryTransactions.ts deleted file mode 100644 index fccf91418..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptInventoryTransactions.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { ISaleReceipt } from '@/interfaces'; -import InventoryService from '@/services/Inventory/Inventory'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; - -@Service() -export class SaleReceiptInventoryTransactions { - @Inject() - private inventoryService: InventoryService; - - @Inject() - private itemsEntriesService: ItemsEntriesService; - - /** - * Records the inventory transactions from the given bill input. - * @param {Bill} bill - Bill model object. - * @param {number} billId - Bill id. - * @return {Promise} - */ - public async recordInventoryTransactions( - tenantId: number, - saleReceipt: ISaleReceipt, - override?: boolean, - trx?: Knex.Transaction - ): Promise { - // Loads the inventory items entries of the given sale invoice. - const inventoryEntries = - await this.itemsEntriesService.filterInventoryEntries( - tenantId, - saleReceipt.entries - ); - const transaction = { - transactionId: saleReceipt.id, - transactionType: 'SaleReceipt', - transactionNumber: saleReceipt.receiptNumber, - exchangeRate: saleReceipt.exchangeRate, - - date: saleReceipt.receiptDate, - direction: 'OUT', - entries: inventoryEntries, - createdAt: saleReceipt.createdAt, - - warehouseId: saleReceipt.warehouseId, - }; - return this.inventoryService.recordInventoryTransactionsFromItemsEntries( - tenantId, - transaction, - override, - trx - ); - } - - /** - * Reverts the inventory transactions of the given bill id. - * @param {number} tenantId - Tenant id. - * @param {number} billId - Bill id. - * @return {Promise} - */ - public async revertInventoryTransactions( - tenantId: number, - receiptId: number, - trx?: Knex.Transaction - ) { - return this.inventoryService.deleteInventoryTransactions( - tenantId, - receiptId, - 'SaleReceipt', - trx - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts deleted file mode 100644 index d9d6d7f15..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts +++ /dev/null @@ -1,238 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import Mail from '@/lib/Mail'; -import { GetSaleReceipt } from './GetSaleReceipt'; -import { SaleReceiptsPdf } from './SaleReceiptsPdfService'; -import { - DEFAULT_RECEIPT_MAIL_CONTENT, - DEFAULT_RECEIPT_MAIL_SUBJECT, -} from './constants'; -import { - ISaleReceiptMailPresend, - SaleReceiptMailOpts, - SaleReceiptMailOptsDTO, -} from '@/interfaces'; -import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; -import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { transformReceiptToMailDataArgs } from './utils'; -import { GetSaleReceiptMailTemplate } from './GetSaleReceiptMailTemplate'; - -@Service() -export class SaleReceiptMailNotification { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private getSaleReceiptService: GetSaleReceipt; - - @Inject() - private receiptPdfService: SaleReceiptsPdf; - - @Inject() - private contactMailNotification: ContactMailNotification; - - @Inject() - private getReceiptMailTemplate: GetSaleReceiptMailTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject('agenda') - private agenda: any; - - /** - * Sends the receipt mail of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {SaleReceiptMailOptsDTO} messageDTO - */ - public async triggerMail( - tenantId: number, - saleReceiptId: number, - messageOptions: SaleReceiptMailOptsDTO - ) { - const payload = { - tenantId, - saleReceiptId, - messageOpts: messageOptions, - }; - await this.agenda.now('sale-receipt-mail-send', payload); - - // Triggers the event `onSaleReceiptPreMailSend`. - await this.eventPublisher.emitAsync(events.saleReceipt.onPreMailSend, { - tenantId, - saleReceiptId, - messageOptions, - } as ISaleReceiptMailPresend); - } - - /** - * Retrieves the mail options of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @returns {Promise} - */ - public async getMailOptions( - tenantId: number, - saleReceiptId: number - ): Promise { - const { SaleReceipt } = this.tenancy.models(tenantId); - - const saleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .throwIfNotFound(); - - const formatArgs = await this.textFormatterArgs(tenantId, saleReceiptId); - - const mailOptions = - await this.contactMailNotification.getDefaultMailOptions( - tenantId, - saleReceipt.customerId - ); - return { - ...mailOptions, - message: DEFAULT_RECEIPT_MAIL_CONTENT, - subject: DEFAULT_RECEIPT_MAIL_SUBJECT, - attachReceipt: true, - formatArgs, - }; - } - - /** - * Retrieves the formatted text of the given sale receipt. - * @param {number} tenantId - Tenant id. - * @param {number} receiptId - Sale receipt id. - * @param {string} text - The given text. - * @returns {Promise} - */ - public textFormatterArgs = async ( - tenantId: number, - receiptId: number - ): Promise> => { - const receipt = await this.getSaleReceiptService.getSaleReceipt( - tenantId, - receiptId - ); - const commonArgs = await this.contactMailNotification.getCommonFormatArgs( - tenantId - ); - return { - ...commonArgs, - ...transformReceiptToMailDataArgs(receipt), - }; - }; - - /** - * Formats the mail options of the given sale receipt. - * @param {number} tenantId - * @param {number} receiptId - * @param {SaleReceiptMailOpts} mailOptions - * @returns {Promise} - */ - public async formatEstimateMailOptions( - tenantId: number, - receiptId: number, - mailOptions: SaleReceiptMailOpts - ): Promise { - const formatterArgs = await this.textFormatterArgs(tenantId, receiptId); - const formattedOptions = - (await this.contactMailNotification.formatMailOptions( - tenantId, - mailOptions, - formatterArgs - )) as SaleReceiptMailOpts; - - const message = await this.getReceiptMailTemplate.getMailTemplate( - tenantId, - receiptId, - { - message: formattedOptions.message, - } - ); - return { ...formattedOptions, message }; - } - - /** - * Retrieves the formatted mail options of the given sale receipt. - * @param {number} tenantId - * @param {number} saleReceiptId - * @param {SaleReceiptMailOptsDTO} messageOpts - * @returns {Promise} - */ - public getFormatMailOptions = async ( - tenantId: number, - saleReceiptId: number, - messageOpts: SaleReceiptMailOptsDTO - ): Promise => { - const defaultMessageOptions = await this.getMailOptions( - tenantId, - saleReceiptId - ); - // Merges message opts with default options. - const parsedMessageOpts = mergeAndValidateMailOptions( - defaultMessageOptions, - messageOpts - ) as SaleReceiptMailOpts; - - // Formats the message options. - return this.formatEstimateMailOptions( - tenantId, - saleReceiptId, - parsedMessageOpts - ); - }; - - /** - * Triggers the mail notification of the given sale receipt. - * @param {number} tenantId - Tenant id. - * @param {number} saleReceiptId - Sale receipt id. - * @param {SaleReceiptMailOpts} messageDTO - message options. - * @returns {Promise} - */ - public async sendMail( - tenantId: number, - saleReceiptId: number, - messageOpts: SaleReceiptMailOptsDTO - ) { - // Formats the message options. - const formattedMessageOptions = await this.getFormatMailOptions( - tenantId, - saleReceiptId, - messageOpts - ); - const mail = new Mail() - .setSubject(formattedMessageOptions.subject) - .setTo(formattedMessageOptions.to) - .setCC(formattedMessageOptions.cc) - .setBCC(formattedMessageOptions.bcc) - .setContent(formattedMessageOptions.message); - - // Attaches the receipt pdf document. - if (formattedMessageOptions.attachReceipt) { - // Retrieves document buffer of the receipt pdf document. - const [receiptPdfBuffer, filename] = - await this.receiptPdfService.saleReceiptPdf(tenantId, saleReceiptId); - - mail.setAttachments([ - { filename: `${filename}.pdf`, content: receiptPdfBuffer }, - ]); - } - const eventPayload = { - tenantId, - saleReceiptId, - messageOptions: {}, - }; - await this.eventPublisher.emitAsync( - events.saleReceipt.onMailSend, - eventPayload - ); - await mail.send(); - - await this.eventPublisher.emitAsync( - events.saleReceipt.onMailSent, - eventPayload - ); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotificationJob.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotificationJob.ts deleted file mode 100644 index f32325114..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotificationJob.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Container, { Service } from 'typedi'; -import { SaleReceiptMailNotification } from './SaleReceiptMailNotification'; - -@Service() -export class SaleReceiptMailNotificationJob { - /** - * Constructor method. - */ - constructor(agenda) { - agenda.define( - 'sale-receipt-mail-send', - { priority: 'high', concurrency: 2 }, - this.handler - ); - } - - /** - * Triggers sending invoice mail. - */ - private handler = async (job, done: Function) => { - const { tenantId, saleReceiptId, messageOpts } = job.attrs.data; - const receiveMailNotification = Container.get(SaleReceiptMailNotification); - - try { - await receiveMailNotification.sendMail( - tenantId, - saleReceiptId, - messageOpts - ); - done(); - } catch (error) { - console.log(error); - done(error); - } - }; -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptNotifyBySms.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptNotifyBySms.ts deleted file mode 100644 index b53c4a472..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptNotifyBySms.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { - ISaleReceiptSmsDetails, - ISaleReceipt, - SMS_NOTIFICATION_KEY, - ICustomer, -} from '@/interfaces'; -import SmsNotificationsSettingsService from '@/services/Settings/SmsNotificationsSettings'; -import { formatNumber, formatSmsMessage } from 'utils'; -import { TenantMetadata } from '@/system/models'; -import { ServiceError } from '@/exceptions'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import SaleNotifyBySms from '../SaleNotifyBySms'; -import { ERRORS } from './constants'; - -@Service() -export class SaleReceiptNotifyBySms { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private smsNotificationsSettings: SmsNotificationsSettingsService; - - @Inject() - private saleSmsNotification: SaleNotifyBySms; - - /** - * Notify customer via sms about sale receipt. - * @param {number} tenantId - Tenant id. - * @param {number} saleReceiptId - Sale receipt id. - */ - public async notifyBySms(tenantId: number, saleReceiptId: number) { - const { SaleReceipt } = this.tenancy.models(tenantId); - - // Retrieve the sale receipt or throw not found service error. - const saleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('customer'); - - // Validates the receipt receipt existance. - this.validateSaleReceiptExistance(saleReceipt); - - // Validate the customer phone number. - this.saleSmsNotification.validateCustomerPhoneNumber( - saleReceipt.customer.personalPhone - ); - // Triggers `onSaleReceiptNotifySms` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onNotifySms, { - tenantId, - saleReceipt, - }); - // Sends the payment receive sms notification to the given customer. - await this.sendSmsNotification(tenantId, saleReceipt); - - // Triggers `onSaleReceiptNotifiedSms` event. - await this.eventPublisher.emitAsync(events.saleReceipt.onNotifiedSms, { - tenantId, - saleReceipt, - }); - return saleReceipt; - } - - /** - * Sends SMS notification. - * @param {ISaleReceipt} invoice - * @param {ICustomer} customer - * @returns - */ - public sendSmsNotification = async ( - tenantId: number, - saleReceipt: ISaleReceipt & { customer: ICustomer } - ) => { - const smsClient = this.tenancy.smsClient(tenantId); - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieve formatted sms notification message of receipt details. - const formattedSmsMessage = this.formattedReceiptDetailsMessage( - tenantId, - saleReceipt, - tenantMetadata - ); - const phoneNumber = saleReceipt.customer.personalPhone; - - // Run the send sms notification message job. - return smsClient.sendMessageJob(phoneNumber, formattedSmsMessage); - }; - - /** - * Notify via SMS message after receipt creation. - * @param {number} tenantId - * @param {number} receiptId - * @returns {Promise} - */ - public notifyViaSmsAfterCreation = async ( - tenantId: number, - receiptId: number - ): Promise => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.SALE_RECEIPT_DETAILS - ); - // Can't continue if the sms auto-notification is not enabled. - if (!notification.isNotificationEnabled) return; - - await this.notifyBySms(tenantId, receiptId); - }; - - /** - * Retrieve the formatted sms notification message of the given sale receipt. - * @param {number} tenantId - * @param {ISaleReceipt} saleReceipt - * @param {TenantMetadata} tenantMetadata - * @returns {string} - */ - private formattedReceiptDetailsMessage = ( - tenantId: number, - saleReceipt: ISaleReceipt & { customer: ICustomer }, - tenantMetadata: TenantMetadata - ): string => { - const notification = this.smsNotificationsSettings.getSmsNotificationMeta( - tenantId, - SMS_NOTIFICATION_KEY.SALE_RECEIPT_DETAILS - ); - return this.formatReceiptDetailsMessage( - notification.smsMessage, - saleReceipt, - tenantMetadata - ); - }; - - /** - * Formattes the receipt sms notification message. - * @param {string} smsMessage - * @param {ISaleReceipt} saleReceipt - * @param {TenantMetadata} tenantMetadata - * @returns {string} - */ - private formatReceiptDetailsMessage = ( - smsMessage: string, - saleReceipt: ISaleReceipt & { customer: ICustomer }, - tenantMetadata: TenantMetadata - ): string => { - // Format the receipt amount. - const formattedAmount = formatNumber(saleReceipt.amount, { - currencyCode: saleReceipt.currencyCode, - }); - - return formatSmsMessage(smsMessage, { - ReceiptNumber: saleReceipt.receiptNumber, - ReferenceNumber: saleReceipt.referenceNo, - CustomerName: saleReceipt.customer.displayName, - Amount: formattedAmount, - CompanyName: tenantMetadata.name, - }); - }; - - /** - * Retrieve the SMS details of the given invoice. - * @param {number} tenantId - - * @param {number} saleReceiptId - Sale receipt id. - */ - public smsDetails = async ( - tenantId: number, - saleReceiptId: number - ): Promise => { - const { SaleReceipt } = this.tenancy.models(tenantId); - - // Retrieve the sale receipt or throw not found service error. - const saleReceipt = await SaleReceipt.query() - .findById(saleReceiptId) - .withGraphFetched('customer'); - - // Validates the receipt receipt existance. - this.validateSaleReceiptExistance(saleReceipt); - - // Current tenant metadata. - const tenantMetadata = await TenantMetadata.query().findOne({ tenantId }); - - // Retrieve the sale receipt formatted sms notification message. - const formattedSmsMessage = this.formattedReceiptDetailsMessage( - tenantId, - saleReceipt, - tenantMetadata - ); - return { - customerName: saleReceipt.customer.displayName, - customerPhoneNumber: saleReceipt.customer.personalPhone, - smsMessage: formattedSmsMessage, - }; - }; - - /** - * Validates the receipt receipt existance. - * @param {ISaleReceipt|null} saleReceipt - */ - private validateSaleReceiptExistance(saleReceipt: ISaleReceipt | null) { - if (!saleReceipt) { - throw new ServiceError(ERRORS.SALE_RECEIPT_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptTransformer.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptTransformer.ts deleted file mode 100644 index eb833b344..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptTransformer.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { Service } from 'typedi'; -import { ISaleReceipt } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; -import { ItemEntryTransformer } from '../Invoices/ItemEntryTransformer'; -import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer'; - -@Service() -export class SaleReceiptTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'discountAmountFormatted', - 'discountPercentageFormatted', - 'discountAmountLocalFormatted', - - 'subtotalFormatted', - 'subtotalLocalFormatted', - - 'totalFormatted', - 'totalLocalFormatted', - - 'adjustmentFormatted', - 'adjustmentLocalFormatted', - - 'formattedAmount', - 'formattedReceiptDate', - 'formattedClosedAtDate', - 'formattedCreatedAt', - 'paidFormatted', - 'entries', - 'attachments', - ]; - }; - - /** - * Retrieve formatted receipt date. - * @param {ISaleReceipt} invoice - * @returns {String} - */ - protected formattedReceiptDate = (receipt: ISaleReceipt): string => { - return this.formatDate(receipt.receiptDate); - }; - - /** - * Retrieve formatted estimate closed at date. - * @param {ISaleReceipt} invoice - * @returns {String} - */ - protected formattedClosedAtDate = (receipt: ISaleReceipt): string => { - return this.formatDate(receipt.closedAt); - }; - - /** - * Retrieve formatted receipt created at date. - * @param receipt - * @returns {string} - */ - protected formattedCreatedAt = (receipt: ISaleReceipt): string => { - return this.formatDate(receipt.createdAt); - }; - - /** - * Retrieves the estimate formatted subtotal. - * @param {ISaleReceipt} receipt - * @returns {string} - */ - protected subtotalFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.subtotal, { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieves the estimate formatted subtotal in local currency. - * @param {ISaleReceipt} receipt - * @returns {string} - */ - protected subtotalLocalFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.subtotalLocal, { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieves the receipt formatted total. - * @param receipt - * @returns {string} - */ - protected totalFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.total, { currencyCode: receipt.currencyCode }); - }; - - /** - * Retrieves the receipt formatted total in local currency. - * @param receipt - * @returns {string} - */ - protected totalLocalFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.totalLocal, { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieve formatted invoice amount. - * @param {ISaleReceipt} estimate - * @returns {string} - */ - protected amountFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.amount, { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieves formatted discount amount. - * @param receipt - * @returns {string} - */ - protected discountAmountFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.discountAmount, { - currencyCode: receipt.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves formatted discount percentage. - * @param receipt - * @returns {string} - */ - protected discountPercentageFormatted = (receipt: ISaleReceipt): string => { - return receipt.discountPercentage ? `${receipt.discountPercentage}%` : ''; - }; - - /** - * Retrieves formatted paid amount. - * @param receipt - * @returns {string} - */ - protected paidFormatted = (receipt: ISaleReceipt): string => { - return formatNumber(receipt.paid, { - currencyCode: receipt.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves formatted adjustment amount. - * @param receipt - * @returns {string} - */ - protected adjustmentFormatted = (receipt: ISaleReceipt): string => { - return this.formatMoney(receipt.adjustment, { - currencyCode: receipt.currencyCode, - excerptZero: true, - }); - }; - - /** - * Retrieves the entries of the credit note. - * @param {ISaleReceipt} credit - * @returns {} - */ - protected entries = (receipt) => { - return this.item(receipt.entries, new ItemEntryTransformer(), { - currencyCode: receipt.currencyCode, - }); - }; - - /** - * Retrieves the sale receipt attachments. - * @param {ISaleReceipt} invoice - * @returns - */ - protected attachments = (receipt) => { - return this.item(receipt.attachments, new AttachmentTransformer()); - }; -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptValidators.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptValidators.ts deleted file mode 100644 index 910d78383..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptValidators.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ACCOUNT_PARENT_TYPE } from '@/data/AccountTypes'; -import { ERRORS } from './constants'; -import { SaleEstimate, SaleReceipt } from '@/models'; - -@Service() -export class SaleReceiptValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates the sale receipt existance. - * @param {SaleEstimate | undefined | null} estimate - */ - public validateReceiptExistance(receipt: SaleReceipt | undefined | null) { - if (!receipt) { - throw new ServiceError(ERRORS.SALE_RECEIPT_NOT_FOUND); - } - } - - /** - * Validates the receipt not closed. - * @param {SaleReceipt} receipt - */ - public validateReceiptNotClosed(receipt: SaleReceipt) { - if (receipt.isClosed) { - throw new ServiceError(ERRORS.SALE_RECEIPT_IS_ALREADY_CLOSED); - } - } - - /** - * Validate whether sale receipt deposit account exists on the storage. - * @param {number} tenantId - Tenant id. - * @param {number} accountId - Account id. - */ - public async validateReceiptDepositAccountExistance( - tenantId: number, - accountId: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - const depositAccount = await accountRepository.findOneById(accountId); - - if (!depositAccount) { - throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_NOT_FOUND); - } - if (!depositAccount.isParentType(ACCOUNT_PARENT_TYPE.CURRENT_ASSET)) { - throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_NOT_CURRENT_ASSET); - } - } - - /** - * Validate sale receipt number uniquiness on the storage. - * @param {number} tenantId - - * @param {string} receiptNumber - - * @param {number} notReceiptId - - */ - public async validateReceiptNumberUnique( - tenantId: number, - receiptNumber: string, - notReceiptId?: number - ) { - const { SaleReceipt } = this.tenancy.models(tenantId); - - const saleReceipt = await SaleReceipt.query() - .findOne('receipt_number', receiptNumber) - .onBuild((builder) => { - if (notReceiptId) { - builder.whereNot('id', notReceiptId); - } - }); - - if (saleReceipt) { - throw new ServiceError(ERRORS.SALE_RECEIPT_NUMBER_NOT_UNIQUE); - } - } - - /** - * Validate the sale receipt number require. - * @param {ISaleReceipt} saleReceipt - */ - public validateReceiptNoRequire(receiptNumber: string) { - if (!receiptNumber) { - throw new ServiceError(ERRORS.SALE_RECEIPT_NO_IS_REQUIRED); - } - } - - /** - * Validate the given customer has no sales receipts. - * @param {number} tenantId - * @param {number} customerId - Customer id. - */ - public async validateCustomerHasNoReceipts( - tenantId: number, - customerId: number - ) { - const { SaleReceipt } = this.tenancy.models(tenantId); - - const receipts = await SaleReceipt.query().where('customer_id', customerId); - - if (receipts.length > 0) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_SALES_INVOICES); - } - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptsExportable.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptsExportable.ts deleted file mode 100644 index 619841e8d..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptsExportable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ISalesReceiptsFilter } from '@/interfaces'; -import { Exportable } from '@/services/Export/Exportable'; -import { SaleReceiptApplication } from './SaleReceiptApplication'; -import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -@Service() -export class SaleReceiptsExportable extends Exportable { - @Inject() - private saleReceiptsApp: SaleReceiptApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number, query: ISalesReceiptsFilter) { - const filterQuery = (query) => { - query.withGraphFetched('branch'); - query.withGraphFetched('warehouse'); - }; - const parsedQuery = { - sortOrder: 'desc', - columnSortBy: 'created_at', - ...query, - page: 1, - pageSize: EXPORT_SIZE_LIMIT, - filterQuery, - } as ISalesReceiptsFilter; - - return this.saleReceiptsApp - .getSaleReceipts(tenantId, parsedQuery) - .then((output) => output.data); - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts deleted file mode 100644 index 2aecec404..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { IAccountCreateDTO, ISaleReceiptDTO } from '@/interfaces'; -import { CreateSaleReceipt } from './CreateSaleReceipt'; -import { Importable } from '@/services/Import/Importable'; -import { SaleReceiptsSampleData } from './constants'; - -@Service() -export class SaleReceiptsImportable extends Importable { - @Inject() - private createReceiptService: CreateSaleReceipt; - - /** - * Importing to sale receipts service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: ISaleReceiptDTO, - trx?: Knex.Transaction - ) { - return this.createReceiptService.createSaleReceipt( - tenantId, - createAccountDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return SaleReceiptsSampleData; - } -} diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptsPdfService.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptsPdfService.ts deleted file mode 100644 index 2aab47659..000000000 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptsPdfService.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy'; -import { - renderReceiptPaperTemplateHtml, - ReceiptPaperTemplateProps, -} from '@bigcapital/pdf-templates'; -import { GetSaleReceipt } from './GetSaleReceipt'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { SaleReceiptBrandingTemplate } from './SaleReceiptBrandingTemplate'; -import { transformReceiptToBrandingTemplateAttributes } from './utils'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class SaleReceiptsPdf { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private chromiumlyTenancy: ChromiumlyTenancy; - - @Inject() - private getSaleReceiptService: GetSaleReceipt; - - @Inject() - private saleReceiptBrandingTemplate: SaleReceiptBrandingTemplate; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Retrieves sale receipt html content. - * @param {number} tennatId - * @param {number} saleReceiptId - */ - public async saleReceiptHtml(tennatId: number, saleReceiptId: number) { - const brandingAttributes = await this.getReceiptBrandingAttributes( - tennatId, - saleReceiptId - ); - return renderReceiptPaperTemplateHtml(brandingAttributes); - } - - /** - * Retrieves sale invoice pdf content. - * @param {number} tenantId - - * @param {number} saleInvoiceId - - * @returns {Promise} - */ - public async saleReceiptPdf( - tenantId: number, - saleReceiptId: number - ): Promise<[Buffer, string]> { - const filename = await this.getSaleReceiptFilename(tenantId, saleReceiptId); - - // Converts the receipt template to html content. - const htmlContent = await this.saleReceiptHtml(tenantId, saleReceiptId); - - // Renders the html content to pdf document. - const content = await this.chromiumlyTenancy.convertHtmlContent( - tenantId, - htmlContent - ); - const eventPayload = { tenantId, saleReceiptId }; - - // Triggers the `onSaleReceiptPdfViewed` event. - await this.eventPublisher.emitAsync( - events.saleReceipt.onPdfViewed, - eventPayload - ); - return [content, filename]; - } - - /** - * Retrieves the filename file document of the given sale receipt. - * @param {number} tenantId - * @param {number} receiptId - * @returns {Promise} - */ - public async getSaleReceiptFilename( - tenantId: number, - receiptId: number - ): Promise { - const { SaleReceipt } = this.tenancy.models(tenantId); - - const receipt = await SaleReceipt.query().findById(receiptId); - - return `Receipt-${receipt.receiptNumber}`; - } - - /** - * Retrieves receipt branding attributes. - * @param {number} tenantId - * @param {number} receiptId - * @returns {Promise} - */ - public async getReceiptBrandingAttributes( - tenantId: number, - receiptId: number - ): Promise { - const { PdfTemplate } = this.tenancy.models(tenantId); - - const saleReceipt = await this.getSaleReceiptService.getSaleReceipt( - tenantId, - receiptId - ); - // Retrieve the invoice template id of not found get the default template id. - const templateId = - saleReceipt.pdfTemplateId ?? - ( - await PdfTemplate.query().findOne({ - resource: 'SaleReceipt', - default: true, - }) - )?.id; - // Retrieves the receipt branding template. - const brandingTemplate = - await this.saleReceiptBrandingTemplate.getSaleReceiptBrandingTemplate( - tenantId, - templateId - ); - return { - ...brandingTemplate.attributes, - ...transformReceiptToBrandingTemplateAttributes(saleReceipt), - }; - } -} diff --git a/packages/server/src/services/Sales/Receipts/constants.ts b/packages/server/src/services/Sales/Receipts/constants.ts deleted file mode 100644 index f8e821edb..000000000 --- a/packages/server/src/services/Sales/Receipts/constants.ts +++ /dev/null @@ -1,122 +0,0 @@ -export const DEFAULT_RECEIPT_MAIL_SUBJECT = - 'Receipt {Receipt Number} from {Company Name}'; -export const DEFAULT_RECEIPT_MAIL_CONTENT = `Hi {Customer Name}, - -Here's receipt # {Receipt Number} for Receipt {Receipt Amount} - -The receipt paid on {Receipt Date}, and the total amount paid is {Receipt Amount}. - -Please find your sale receipt attached to this email for your reference - -If you have any questions, please let us know. - -Thanks, -{Company Name}`; - -export const ERRORS = { - SALE_RECEIPT_NOT_FOUND: 'SALE_RECEIPT_NOT_FOUND', - DEPOSIT_ACCOUNT_NOT_FOUND: 'DEPOSIT_ACCOUNT_NOT_FOUND', - DEPOSIT_ACCOUNT_NOT_CURRENT_ASSET: 'DEPOSIT_ACCOUNT_NOT_CURRENT_ASSET', - SALE_RECEIPT_NUMBER_NOT_UNIQUE: 'SALE_RECEIPT_NUMBER_NOT_UNIQUE', - SALE_RECEIPT_IS_ALREADY_CLOSED: 'SALE_RECEIPT_IS_ALREADY_CLOSED', - SALE_RECEIPT_NO_IS_REQUIRED: 'SALE_RECEIPT_NO_IS_REQUIRED', - CUSTOMER_HAS_SALES_INVOICES: 'CUSTOMER_HAS_SALES_INVOICES', - NO_INVOICE_CUSTOMER_EMAIL_ADDR: 'NO_INVOICE_CUSTOMER_EMAIL_ADDR', -}; - -export const DEFAULT_VIEW_COLUMNS = []; -export const DEFAULT_VIEWS = [ - { - name: 'Draft', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, - { - name: 'Closed', - slug: 'closed', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'closed' }, - ], - columns: DEFAULT_VIEW_COLUMNS, - }, -]; - -export const SaleReceiptsSampleData = [ - { - 'Receipt Date': '2023-01-01', - Customer: 'Randall Kohler', - 'Deposit Account': 'Petty Cash', - 'Exchange Rate': '', - 'Receipt Number': 'REC-00001', - 'Reference No.': 'REF-0001', - Statement: 'Delectus unde aut soluta et accusamus placeat.', - 'Receipt Message': 'Vitae asperiores dicta.', - Closed: 'T', - Item: 'Schmitt Group', - Quantity: 100, - Rate: 200, - 'Line Description': - 'Distinctio distinctio sit veritatis consequatur iste quod veritatis.', - }, -]; - -export const defaultSaleReceiptBrandingAttributes = { - primaryColor: '', - secondaryColor: '', - companyName: 'Bigcapital Technology, Inc.', - - // # Company logo - showCompanyLogo: true, - companyLogoUri: '', - companyLogoKey: '', - - // # Customer address - showCustomerAddress: true, - customerAddress: '', - - // # Company address - showCompanyAddress: true, - companyAddress: '', - billedToLabel: 'Billed To', - - // # Total - total: '$1000.00', - totalLabel: 'Total', - showTotal: true, - - subtotal: '1000/00', - subtotalLabel: 'Subtotal', - showSubtotal: true, - - showCustomerNote: true, - customerNote: - 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.', - customerNoteLabel: 'Customer Note', - - showTermsConditions: true, - termsConditions: - 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.', - termsConditionsLabel: 'Terms & Conditions', - - lines: [ - { - item: 'Simply dummy text', - description: 'Simply dummy text of the printing and typesetting', - rate: '1', - quantity: '1000', - total: '$1000.00', - }, - ], - showReceiptNumber: true, - receiptNumberLabel: 'Receipt Number', - receiptNumebr: '346D3D40-0001', - - receiptDate: 'September 3, 2024', - showReceiptDate: true, - receiptDateLabel: 'Receipt Date', -}; diff --git a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts b/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts deleted file mode 100644 index 39590198b..000000000 --- a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IInventoryCostLotsGLEntriesWriteEvent } from '@/interfaces'; -import { SaleReceiptCostGLEntries } from '../SaleReceiptCostGLEntries'; - -@Service() -export class SaleReceiptCostGLEntriesSubscriber { - @Inject() - private saleReceiptCostEntries: SaleReceiptCostGLEntries; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe( - events.inventory.onCostLotsGLEntriesWrite, - this.writeJournalEntriesOnceWriteoffCreate - ); - } - - /** - * Writes the receipts cost GL entries once the inventory cost lots be written. - * @param {IInventoryCostLotsGLEntriesWriteEvent} - */ - private writeJournalEntriesOnceWriteoffCreate = async ({ - trx, - startingDate, - tenantId, - }: IInventoryCostLotsGLEntriesWriteEvent) => { - await this.saleReceiptCostEntries.writeInventoryCostJournalEntries( - tenantId, - startingDate, - trx - ); - }; -} diff --git a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts b/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts deleted file mode 100644 index 3a8d26394..000000000 --- a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ISaleReceiptMailPresend } from '@/interfaces'; -import events from '@/subscribers/events'; -import { CloseSaleReceipt } from '../CloseSaleReceipt'; -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from '../constants'; - -@Service() -export class SaleReceiptMarkClosedOnMailSentSubcriber { - @Inject() - private closeReceiptService: CloseSaleReceipt; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe(events.saleReceipt.onPreMailSend, this.markReceiptClosed); - } - - /** - * Marks the sale receipt closed on submitting mail. - * @param {ISaleReceiptMailPresend} - */ - private markReceiptClosed = async ({ - tenantId, - saleReceiptId, - messageOptions, - }: ISaleReceiptMailPresend) => { - try { - await this.closeReceiptService.closeSaleReceipt(tenantId, saleReceiptId); - } catch (error) { - if ( - error instanceof ServiceError && - error.errorType === ERRORS.SALE_RECEIPT_IS_ALREADY_CLOSED - ) { - } else { - throw error; - } - } - }; -} diff --git a/packages/server/src/services/Sales/Receipts/utils.ts b/packages/server/src/services/Sales/Receipts/utils.ts deleted file mode 100644 index f29c0189a..000000000 --- a/packages/server/src/services/Sales/Receipts/utils.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { contactAddressTextFormat } from '@/utils/address-text-format'; -import { ReceiptPaperTemplateProps } from '@bigcapital/pdf-templates'; - -export const transformReceiptToBrandingTemplateAttributes = ( - saleReceipt -): Partial => { - return { - total: saleReceipt.totalFormatted, - subtotal: saleReceipt.subtotalFormatted, - lines: saleReceipt.entries?.map((entry) => ({ - item: entry.item.name, - description: entry.description, - rate: entry.rateFormatted, - quantity: entry.quantityFormatted, - discount: entry.discountFormatted, - total: entry.totalFormatted, - })), - receiptNumber: saleReceipt.receiptNumber, - receiptDate: saleReceipt.formattedReceiptDate, - discount: saleReceipt.discountAmountFormatted, - discountLabel: saleReceipt.discountPercentageFormatted - ? `Discount [${saleReceipt.discountPercentageFormatted}]` - : 'Discount', - showLineDiscount: saleReceipt.entries.some( - (entry) => entry.discountFormatted - ), - adjustment: saleReceipt.adjustmentFormatted, - customerAddress: contactAddressTextFormat(saleReceipt.customer), - }; -}; - -export const transformReceiptToMailDataArgs = (saleReceipt: any) => { - return { - 'Customer Name': saleReceipt.customer.displayName, - 'Receipt Number': saleReceipt.receiptNumber, - 'Receipt Date': saleReceipt.formattedReceiptDate, - 'Receipt Amount': saleReceipt.formattedAmount, - }; -}; diff --git a/packages/server/src/services/Sales/SaleNotifyBySms.ts b/packages/server/src/services/Sales/SaleNotifyBySms.ts deleted file mode 100644 index 6bece44a7..000000000 --- a/packages/server/src/services/Sales/SaleNotifyBySms.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceError } from '@/exceptions'; -import parsePhoneNumber from 'libphonenumber-js'; -import { Service } from 'typedi'; - -const ERRORS = { - CUSTOMER_HAS_NO_PHONE_NUMBER: 'CUSTOMER_HAS_NO_PHONE_NUMBER', - CUSTOMER_SMS_NOTIFY_PHONE_INVALID: 'CUSTOMER_SMS_NOTIFY_PHONE_INVALID', -}; - -@Service() -export default class SaleNotifyBySms { - /** - * Validate the customer phone number. - * @param {ICustomer} customer - */ - public validateCustomerPhoneNumber = (personalPhone: string) => { - if (!personalPhone) { - throw new ServiceError(ERRORS.CUSTOMER_HAS_NO_PHONE_NUMBER); - } - this.validateCustomerPhoneNumberLocally(personalPhone); - }; - - /** - * - * @param {string} personalPhone - */ - public validateCustomerPhoneNumberLocally = (personalPhone: string) => { - const phoneNumber = parsePhoneNumber(personalPhone, 'LY'); - - if (!phoneNumber || !phoneNumber.isValid()) { - throw new ServiceError(ERRORS.CUSTOMER_SMS_NOTIFY_PHONE_INVALID); - } - }; -} diff --git a/packages/server/src/services/Sales/SalesTransactionsLocking.ts b/packages/server/src/services/Sales/SalesTransactionsLocking.ts deleted file mode 100644 index 2fec2a0c8..000000000 --- a/packages/server/src/services/Sales/SalesTransactionsLocking.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TransactionsLockingValidator from '@/services/TransactionsLocking/TransactionsLockingGuard'; -import { TransactionsLockingGroup } from '@/interfaces'; - -@Service() -export default class SalesTransactionsLocking { - @Inject() - transactionLockingValidator: TransactionsLockingValidator; - - /** - * Validates the all and partial sales transactions locking. - * @param {number} tenantId - * @param {Date} transactionDate - */ - public validateTransactionsLocking = ( - tenantId: number, - transactionDate: Date - ) => { - // Validates the all transcation locking. - this.transactionLockingValidator.validateTransactionsLocking( - tenantId, - transactionDate, - TransactionsLockingGroup.All - ); - // Validates the partial sales transcation locking. - // this.transactionLockingValidator.validateTransactionsLocking( - // tenantId, - // transactionDate, - // TransactionsLockingGroup.Sales - // ); - }; -} diff --git a/packages/server/src/services/Sales/ServiceItemsEntries.js b/packages/server/src/services/Sales/ServiceItemsEntries.js deleted file mode 100644 index 95d2cd6c4..000000000 --- a/packages/server/src/services/Sales/ServiceItemsEntries.js +++ /dev/null @@ -1,16 +0,0 @@ -import { difference } from "lodash"; - - -export default class ServiceItemsEntries { - - static entriesShouldDeleted(storedEntries, entries) { - const storedEntriesIds = storedEntries.map((e) => e.id); - const entriesIds = entries.map((e) => e.id); - - return difference( - storedEntriesIds, - entriesIds, - ); - } - -} \ No newline at end of file diff --git a/packages/server/src/services/SessionModel/SessionQueryBuilder.js b/packages/server/src/services/SessionModel/SessionQueryBuilder.js deleted file mode 100644 index 74c642fbe..000000000 --- a/packages/server/src/services/SessionModel/SessionQueryBuilder.js +++ /dev/null @@ -1,13 +0,0 @@ -import SessionModel from '@/services/SessionModel'; - -export default class SessionQueryBuilder extends SessionModel.QueryBuilder { - /** - * Add a custom method that stores a session object to the query context. - * @param {*} session - - */ - session(session) { - return this.mergeContext({ - session, - }); - } -} diff --git a/packages/server/src/services/SessionModel/index.js b/packages/server/src/services/SessionModel/index.js deleted file mode 100644 index e99fee588..000000000 --- a/packages/server/src/services/SessionModel/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import SessionQueryBuilder from '@/services/SessionModel/SessionQueryBuilder'; - -export default class SessionModel { - /** - * Constructor method. - * @param {Object} options - - */ - constructor(options) { - this.options = { ...options, ...SessionModel.defaultOptions }; - } - - static get defaultOptions() { - return { - setModifiedBy: true, - setModifiedAt: true, - setCreatedBy: true, - setCreatedAt: true, - }; - } - - static get QueryBuilder() { - return SessionQueryBuilder; - } -} diff --git a/packages/server/src/services/Settings/SettingsService.ts b/packages/server/src/services/Settings/SettingsService.ts deleted file mode 100644 index b3e3fd11f..000000000 --- a/packages/server/src/services/Settings/SettingsService.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export default class SettingsService { - @Inject() - tenancy: TenancyService; - - @Inject('logger') - logger: any; - - /** - * Increment next number based on the given find query. - * @param {number} tenantId - * @param {any} findQuery - */ - async incrementNextNumber(tenantId: number, findQuery: any): Promise { - const settings = this.tenancy.settings(tenantId); - - this.logger.info('[settings] increment the next number.', { - tenantId, - findQuery, - }); - const currentNumber = settings.find(findQuery); - - if (currentNumber) { - const nextNumber = parseInt(currentNumber.value, 10) + 1; - settings.set(findQuery, nextNumber); - - await settings.save(); - } - } - - /** - * Validates the given options is defined or either not. - * @param {Array} options - * @return {Boolean} - */ - validateNotDefinedSettings(tenantId: number, options) { - const notDefined = []; - - const settings = this.tenancy.settings(tenantId); - - options.forEach((option) => { - const setting = settings.config.getMetaConfig(option.key, option.group); - - if (!setting) { - notDefined.push(option); - } - }); - return notDefined; - } -} diff --git a/packages/server/src/services/Settings/SettingsStore.ts b/packages/server/src/services/Settings/SettingsStore.ts deleted file mode 100644 index e70ffc31d..000000000 --- a/packages/server/src/services/Settings/SettingsStore.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Knex from 'knex'; -import MetableStoreDB from '@/lib/Metable/MetableStoreDB'; -import Setting from 'models/Setting'; - -export default class SettingsStore extends MetableStoreDB { - /** - * Constructor method. - * @param {number} tenantId - */ - constructor(repository) { - super(); - this.setExtraColumns(['group']); - this.setRepository(repository); - } -} \ No newline at end of file diff --git a/packages/server/src/services/Settings/SmsNotificationsSettings.ts b/packages/server/src/services/Settings/SmsNotificationsSettings.ts deleted file mode 100644 index 3061aa2ba..000000000 --- a/packages/server/src/services/Settings/SmsNotificationsSettings.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { isUndefined, omit, keyBy } from 'lodash'; -import { - ISmsNotificationDefined, - ISmsNotificationMeta, - IEditSmsNotificationDTO, - ISmsNotificationAllowedVariable, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import SMSNotificationsConfig from 'config/smsNotifications'; -import { ServiceError } from '@/exceptions'; - -const ERRORS = { - SMS_NOTIFICATION_KEY_NOT_FOUND: 'SMS_NOTIFICATION_KEY_NOT_FOUND', - UNSUPPORTED_SMS_MESSAGE_VARIABLES: 'UNSUPPORTED_SMS_MESSAGE_VARIABLES', -}; - -@Service() -export default class SmsNotificationsSettingsService { - @Inject() - private tenancy: TenancyService; - - /** - * Retrieve sms notification meta from the given notification key. - * @param {string} notificationKey - Notification key. - * @returns {ISmsNotificationMeta} - */ - public getSmsNotificationMeta = ( - tenantId: number, - notificationKey: string - ): ISmsNotificationMeta => { - const notificationsByKey = keyBy(SMSNotificationsConfig, 'key'); - const notification = notificationsByKey[notificationKey]; - - // Validates sms notification exists. - this.validateSmsNotificationExists(notification); - - return this.transformSmsNotifConfigToMeta(tenantId, notification); - }; - - /** - * Transformes the sms notification config to notificatin meta. - * @param {Settings} settings - * @param {ISmsNotificationDefined} smsNotification - * @returns {ISmsNotificationMeta} - */ - private transformSmsNotifConfigToMeta = ( - tenantId: number, - smsNotification: ISmsNotificationDefined - ): ISmsNotificationMeta => { - const settings = this.tenancy.settings(tenantId); - const i18n = this.tenancy.i18n(tenantId); - const group = 'sms-notification'; - - const defaultSmsMessage = i18n.__(smsNotification.defaultSmsMessage); - - return { - ...omit(smsNotification, [ - 'defaultSmsMessage', - 'defaultIsNotificationEnabled', - ]), - notificationLabel: i18n.__(smsNotification.notificationLabel), - notificationDescription: i18n.__(smsNotification.notificationDescription), - moduleFormatted: i18n.__(smsNotification.moduleFormatted), - allowedVariables: smsNotification.allowedVariables.map( - (notification) => ({ - ...notification, - description: i18n.__(notification.description), - }) - ), - defaultSmsMessage, - smsMessage: settings.get( - { - key: `sms-message.${smsNotification.key}`, - group, - }, - defaultSmsMessage - ), - isNotificationEnabled: settings.get( - { - key: `sms-notification-enable.${smsNotification.key}`, - group, - }, - smsNotification.defaultIsNotificationEnabled - ), - }; - }; - - /** - * Retrieve the sms notifications list. - * @param {number} tenantId - */ - public smsNotificationsList = ( - tenantId: number - ): Promise => { - return SMSNotificationsConfig.map((notification) => { - return this.transformSmsNotifConfigToMeta(tenantId, notification); - }); - }; - - /** - * Edits/Mutates the sms notification message text. - * @param {number} tenantId - Tenant id. - * @param {IEditSmsNotificationDTO} editSmsNotificationDTO - Edit SMS notification DTO. - */ - public editSmsNotificationMessage = ( - tenantId: number, - editDTO: IEditSmsNotificationDTO - ): ISmsNotificationMeta => { - const settings = this.tenancy.settings(tenantId); - - const notification = this.getSmsNotificationMeta( - tenantId, - editDTO.notificationKey - ); - const group = 'sms-notification'; - - if (editDTO.messageText) { - this.validateSmsMessageVariables( - editDTO.messageText, - notification.allowedVariables - ); - settings.set({ - key: `sms-message.${editDTO.notificationKey}`, - value: editDTO.messageText, - group, - }); - } - if (!isUndefined(editDTO.isNotificationEnabled)) { - settings.set({ - key: `sms-notification-enable.${editDTO.notificationKey}`, - value: editDTO.isNotificationEnabled, - group, - }); - } - return notification; - }; - - /** - * Vaidates the sms notification key existance. - * @param {string} notificationKey - */ - private validateSmsNotificationExists = ( - notificationDefined: ISmsNotificationDefined | null - ): void => { - if (!notificationDefined) { - throw new ServiceError(ERRORS.SMS_NOTIFICATION_KEY_NOT_FOUND); - } - }; - - /** - * Retrieve unspported message arguments. - * @param {string} smsMessage - SMS message. - * @param {string[]} args - - * @returns {string[]} - */ - private getUnsupportedMessageArgs = ( - smsMessage: string, - args: string[] - ): string[] => { - const matchedVariables = smsMessage.match(/\{(.*?)\}/g).map((matched) => { - return matched.replace('{', '').replace('}', ''); - }); - const invalidVariables = matchedVariables.filter( - (variable) => args.indexOf(variable) === -1 - ); - return invalidVariables; - }; - - /** - * Validates the sms message variables. - * @param {string} smsMessage - * @param {string[]} args - */ - private validateSmsMessageVariables( - smsMessage: string, - allowedVariables: ISmsNotificationAllowedVariable[] - ) { - const allowedVariablesKeys = allowedVariables.map( - (allowed) => allowed.variable - ); - const unsupportedArgs = this.getUnsupportedMessageArgs( - smsMessage, - allowedVariablesKeys - ); - - if (unsupportedArgs.length > 0) { - throw new ServiceError(ERRORS.UNSUPPORTED_SMS_MESSAGE_VARIABLES, null, { - unsupportedArgs, - }); - } - } -} diff --git a/packages/server/src/services/Setup/SetupService.ts b/packages/server/src/services/Setup/SetupService.ts deleted file mode 100644 index a00933fd6..000000000 --- a/packages/server/src/services/Setup/SetupService.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Service, Inject } from 'typedi'; -import Currencies from 'js-money/lib/currency'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { IOrganizationSetupDTO, ITenant } from '@/interfaces'; - -import CurrenciesService from '@/services/Currencies/CurrenciesService'; -import TenantsManagerService from '@/services/Tenancy/TenantsManager'; -import { ServiceError } from '@/exceptions'; - -const ERRORS = { - TENANT_IS_ALREADY_SETUPED: 'TENANT_IS_ALREADY_SETUPED', - BASE_CURRENCY_INVALID: 'BASE_CURRENCY_INVALID', -}; - -@Service() -export default class SetupService { - @Inject() - tenancy: HasTenancyService; - - @Inject() - currenciesService: CurrenciesService; - - @Inject() - tenantsManager: TenantsManagerService; - - @Inject('repositories') - sysRepositories: any; - - /** - * Transformes the setup DTO to settings. - * @param {IOrganizationSetupDTO} setupDTO - * @returns - */ - private transformSetupDTOToOptions(setupDTO: IOrganizationSetupDTO) { - return [ - { key: 'name', value: setupDTO.organizationName }, - { key: 'base_currency', value: setupDTO.baseCurrency }, - { key: 'time_zone', value: setupDTO.timeZone }, - { key: 'industry', value: setupDTO.industry }, - ]; - } - - /** - * Sets organization setup settings. - * @param {number} tenantId - * @param {IOrganizationSetupDTO} organizationSetupDTO - */ - private setOrganizationSetupSettings( - tenantId: number, - organizationSetupDTO: IOrganizationSetupDTO - ) { - const settings = this.tenancy.settings(tenantId); - - // Can't continue if app is already configured. - if (settings.get('app_configured')) { return; } - - settings.set([ - ...this.transformSetupDTOToOptions(organizationSetupDTO) - .filter((option) => typeof option.value !== 'undefined') - .map((option) => ({ - ...option, - group: 'organization', - })), - { key: 'app_configured', value: true }, - ]); - } - - /** - * Validates the base currency code. - * @param {string} baseCurrency - */ - public validateBaseCurrencyCode(baseCurrency: string) { - if (typeof Currencies[baseCurrency] === 'undefined') { - throw new ServiceError(ERRORS.BASE_CURRENCY_INVALID); - } - } - - /** - * Organization setup DTO. - * @param {IOrganizationSetupDTO} organizationSetupDTO - * @return {Promise} - */ - public async organizationSetup( - tenantId: number, - organizationSetupDTO: IOrganizationSetupDTO, - ): Promise { - const { tenantRepository } = this.sysRepositories; - - // Find tenant model by the given id. - const tenant = await tenantRepository.findOneById(tenantId); - - // Validate base currency code. - this.validateBaseCurrencyCode(organizationSetupDTO.baseCurrency); - - // Validate tenant not already seeded. - this.validateTenantNotSeeded(tenant); - - // Seeds the base currency to the currencies list. - this.currenciesService.seedBaseCurrency( - tenantId, - organizationSetupDTO.baseCurrency - ); - // Sets organization setup settings. - await this.setOrganizationSetupSettings(tenantId, organizationSetupDTO); - - // Seed tenant. - await this.tenantsManager.seedTenant(tenant); - } - - /** - * Validates tenant not seeded. - * @param {ITenant} tenant - */ - private validateTenantNotSeeded(tenant: ITenant) { - if (tenant.seededAt) { - throw new ServiceError(ERRORS.TENANT_IS_ALREADY_SETUPED); - } - } -} diff --git a/packages/server/src/services/SmsIntegration/EasySmsIntegration.ts b/packages/server/src/services/SmsIntegration/EasySmsIntegration.ts deleted file mode 100644 index 5010ebdd0..000000000 --- a/packages/server/src/services/SmsIntegration/EasySmsIntegration.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; - -interface IEasysmsIntegrateDTO { - token: string; -} - -const ERRORS = { - SMS_GATEWAY_NOT_INTEGRATED: 'SMS_GATEWAY_NOT_INTEGRATED', -}; - -const easysmsSettingsQuery = { - group: 'sms_integration', - key: 'easysms_token', -}; - -@Service() -export default class EasySmsIntegration { - @Inject() - tenancy: HasTenancyService; - - /** - * Integrate Easysms SMS gateway with the system. - * @param {number} tenantId - - * @param {IEasysmsIntegrateDTO} easysmsIntegrateDTO - - */ - public integrate = ( - tenantId: number, - easysmsIntegrateDTO: IEasysmsIntegrateDTO - ) => { - const settings = this.tenancy.settings(tenantId); - - settings.set({ - ...easysmsSettingsQuery, - value: easysmsIntegrateDTO.token, - }); - }; - - /** - * Disconnects Easysms integration from the system. - * @param {number} tenantId - */ - public disconnect = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); - - settings.remove({ ...easysmsSettingsQuery }); - }; - - /** - * Retrieve the Easysms metadata. - * @param {number} tenantId - */ - public getIntegrationMeta = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); - - const token = settings.get(easysmsSettingsQuery); - - return { - active: !!token, - }; - }; -} diff --git a/packages/server/src/services/StripePayment/CreatePaymentReceivedStripePayment.ts b/packages/server/src/services/StripePayment/CreatePaymentReceivedStripePayment.ts deleted file mode 100644 index d6ae6eb72..000000000 --- a/packages/server/src/services/StripePayment/CreatePaymentReceivedStripePayment.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { GetSaleInvoice } from '../Sales/Invoices/GetSaleInvoice'; -import { CreatePaymentReceived } from '../Sales/PaymentReceived/CreatePaymentReceived'; -import HasTenancyService from '../Tenancy/TenancyService'; -import UnitOfWork from '../UnitOfWork'; - -@Service() -export class CreatePaymentReceiveStripePayment { - constructor( - private readonly getSaleInvoiceService: GetSaleInvoice, - private readonly createPaymentReceivedService: CreatePaymentReceived, - private readonly uow: UnitOfWork - ) {} - - /** - * - * @param {number} tenantId - * @param {number} saleInvoiceId - * @param {number} paidAmount - */ - async createPaymentReceived( - tenantId: number, - saleInvoiceId: number, - paidAmount: number - ) { - const { accountRepository } = this.tenancy.repositories(tenantId); - - // Create a payment received transaction under UOW envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Finds or creates a new stripe payment clearing account (current asset). - const stripeClearingAccount = - await accountRepository.findOrCreateStripeClearing({}, trx); - - // Retrieves the given invoice to create payment transaction associated to it. - const invoice = await this.getSaleInvoiceService.getSaleInvoice( - tenantId, - saleInvoiceId - ); - const paymentReceivedDTO = { - customerId: invoice.customerId, - paymentDate: new Date(), - amount: paidAmount, - exchangeRate: 1, - referenceNo: '', - statement: '', - depositAccountId: stripeClearingAccount.id, - entries: [{ invoiceId: saleInvoiceId, paymentAmount: paidAmount }], - }; - // Create a payment received transaction associated to the given invoice. - await this.createPaymentReceivedService.createPaymentReceived( - tenantId, - paymentReceivedDTO, - {}, - trx - ); - }); - } -} diff --git a/packages/server/src/services/StripePayment/CreateStripeAccountLink.ts b/packages/server/src/services/StripePayment/CreateStripeAccountLink.ts deleted file mode 100644 index c28522d27..000000000 --- a/packages/server/src/services/StripePayment/CreateStripeAccountLink.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { StripePaymentService } from './StripePaymentService'; - -@Service() -export class CreateStripeAccountLinkService { - @Inject() - private stripePaymentService: StripePaymentService; - - /** - * Creates a new Stripe account id. - * @param {number} tenantId - */ - public createAccountLink(tenantId: number, stripeAccountId: string) { - return this.stripePaymentService.createAccountLink(stripeAccountId); - } -} diff --git a/packages/server/src/services/StripePayment/CreateStripeAccountService.ts b/packages/server/src/services/StripePayment/CreateStripeAccountService.ts deleted file mode 100644 index 243cb0ee4..000000000 --- a/packages/server/src/services/StripePayment/CreateStripeAccountService.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { StripePaymentService } from '@/services/StripePayment/StripePaymentService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CreateStripeAccountDTO } from './types'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -@Service() -export class CreateStripeAccountService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private stripePaymentService: StripePaymentService; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Creates a new Stripe account. - * @param {number} tenantI - * @param {CreateStripeAccountDTO} stripeAccountDTO - * @returns {Promise} - */ - async createStripeAccount( - tenantId: number, - stripeAccountDTO?: CreateStripeAccountDTO - ): Promise { - const { PaymentIntegration } = this.tenancy.models(tenantId); - const stripeAccount = await this.stripePaymentService.createAccount(); - const stripeAccountId = stripeAccount.id; - - const parsedStripeAccountDTO = { - name: 'Stripe', - ...stripeAccountDTO, - }; - // Stores the details of the Stripe account. - await PaymentIntegration.query().insert({ - name: parsedStripeAccountDTO.name, - accountId: stripeAccountId, - active: false, // Active will turn true after onboarding. - service: 'Stripe', - }); - // Triggers `onStripeIntegrationAccountCreated` event. - await this.eventPublisher.emitAsync( - events.stripeIntegration.onAccountCreated, - { - tenantId, - stripeAccountDTO, - stripeAccountId, - } - ); - return stripeAccountId; - } -} diff --git a/packages/server/src/services/StripePayment/ExchangeStripeOauthToken.ts b/packages/server/src/services/StripePayment/ExchangeStripeOauthToken.ts deleted file mode 100644 index 97091ec65..000000000 --- a/packages/server/src/services/StripePayment/ExchangeStripeOauthToken.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { StripePaymentService } from './StripePaymentService'; -import events from '@/subscribers/events'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '../UnitOfWork'; -import { Knex } from 'knex'; -import { StripeOAuthCodeGrantedEventPayload } from './types'; - -@Service() -export class ExchangeStripeOAuthTokenService { - @Inject() - private stripePaymentService: StripePaymentService; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - /** - * Exchange stripe oauth authorization code to access token and user id. - * @param {number} tenantId - * @param {string} authorizationCode - */ - public async excahngeStripeOAuthToken( - tenantId: number, - authorizationCode: string - ) { - const { PaymentIntegration } = this.tenancy.models(tenantId); - const stripe = this.stripePaymentService.stripe; - - const response = await stripe.oauth.token({ - grant_type: 'authorization_code', - code: authorizationCode, - }); - // const accessToken = response.access_token; - // const refreshToken = response.refresh_token; - const stripeUserId = response.stripe_user_id; - - // Retrieves details of the Stripe account. - const account = await stripe.accounts.retrieve(stripeUserId, { - expand: ['business_profile'], - }); - const companyName = account.business_profile?.name || 'Unknow name'; - const paymentEnabled = account.charges_enabled; - const payoutEnabled = account.payouts_enabled; - - // - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Stores the details of the Stripe account. - const paymentIntegration = await PaymentIntegration.query(trx).insert({ - name: companyName, - service: 'Stripe', - accountId: stripeUserId, - paymentEnabled, - payoutEnabled, - }); - // Triggers `onStripeOAuthCodeGranted` event. - await this.eventPublisher.emitAsync( - events.stripeIntegration.onOAuthCodeGranted, - { - tenantId, - paymentIntegrationId: paymentIntegration.id, - trx, - } as StripeOAuthCodeGrantedEventPayload - ); - }); - } -} diff --git a/packages/server/src/services/StripePayment/GetStripeAuthorizationLink.ts b/packages/server/src/services/StripePayment/GetStripeAuthorizationLink.ts deleted file mode 100644 index 026fde40b..000000000 --- a/packages/server/src/services/StripePayment/GetStripeAuthorizationLink.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Service } from 'typedi'; -import config from '@/config'; - -@Service() -export class GetStripeAuthorizationLinkService { - public getStripeAuthLink() { - const clientId = config.stripePayment.clientId; - const redirectUrl = config.stripePayment.redirectTo; - - const authorizationUri = `https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=${clientId}&scope=read_write&redirect_uri=${redirectUrl}`; - - return authorizationUri; - } -} diff --git a/packages/server/src/services/StripePayment/StripePaymentApplication.ts b/packages/server/src/services/StripePayment/StripePaymentApplication.ts deleted file mode 100644 index 23aa73546..000000000 --- a/packages/server/src/services/StripePayment/StripePaymentApplication.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject } from 'typedi'; -import { CreateStripeAccountService } from './CreateStripeAccountService'; -import { CreateStripeAccountLinkService } from './CreateStripeAccountLink'; -import { CreateStripeAccountDTO } from './types'; -import { ExchangeStripeOAuthTokenService } from './ExchangeStripeOauthToken'; -import { GetStripeAuthorizationLinkService } from './GetStripeAuthorizationLink'; - -export class StripePaymentApplication { - @Inject() - private createStripeAccountService: CreateStripeAccountService; - - @Inject() - private createStripeAccountLinkService: CreateStripeAccountLinkService; - - @Inject() - private exchangeStripeOAuthTokenService: ExchangeStripeOAuthTokenService; - - @Inject() - private getStripeConnectLinkService: GetStripeAuthorizationLinkService; - - /** - * Creates a new Stripe account for Bigcapital. - * @param {number} tenantId - * @param {number} createStripeAccountDTO - */ - public createStripeAccount( - tenantId: number, - createStripeAccountDTO: CreateStripeAccountDTO = {} - ) { - return this.createStripeAccountService.createStripeAccount( - tenantId, - createStripeAccountDTO - ); - } - - /** - * Creates a new Stripe account link of the given Stripe accoun.. - * @param {number} tenantId - * @param {string} stripeAccountId - * @returns {} - */ - public createAccountLink(tenantId: number, stripeAccountId: string) { - return this.createStripeAccountLinkService.createAccountLink( - tenantId, - stripeAccountId - ); - } - - /** - * Retrieves Stripe OAuth2 connect link. - * @returns {string} - */ - public getStripeConnectLink() { - return this.getStripeConnectLinkService.getStripeAuthLink(); - } - - /** - * Exchanges the given Stripe authorization code to Stripe user id and access token. - * @param {string} authorizationCode - * @returns - */ - public exchangeStripeOAuthToken(tenantId: number, authorizationCode: string) { - return this.exchangeStripeOAuthTokenService.excahngeStripeOAuthToken( - tenantId, - authorizationCode - ); - } -} diff --git a/packages/server/src/services/StripePayment/StripePaymentService.ts b/packages/server/src/services/StripePayment/StripePaymentService.ts deleted file mode 100644 index caf44dca4..000000000 --- a/packages/server/src/services/StripePayment/StripePaymentService.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Service } from 'typedi'; -import stripe from 'stripe'; -import config from '@/config'; - -const origin = 'https://cfdf-102-164-97-88.ngrok-free.app'; - -@Service() -export class StripePaymentService { - public stripe: stripe; - - constructor() { - this.stripe = new stripe(config.stripePayment.secretKey, { - apiVersion: '2024-06-20', - }); - } - - /** - * - * @param {number} accountId - * @returns {Promise} - */ - public async createAccountSession(accountId: string): Promise { - try { - const accountSession = await this.stripe.accountSessions.create({ - account: accountId, - components: { - account_onboarding: { enabled: true }, - }, - }); - return accountSession.client_secret; - } catch (error) { - throw new Error( - 'An error occurred when calling the Stripe API to create an account session' - ); - } - } - - /** - * - * @param {number} accountId - * @returns - */ - public async createAccountLink(accountId: string) { - try { - const accountLink = await this.stripe.accountLinks.create({ - account: accountId, - return_url: `${origin}/return/${accountId}`, - refresh_url: `${origin}/refresh/${accountId}`, - type: 'account_onboarding', - }); - return accountLink; - } catch (error) { - throw new Error( - 'An error occurred when calling the Stripe API to create an account link:' - ); - } - } - - /** - * - * @returns {Promise} - */ - public async createAccount(): Promise { - try { - const account = await this.stripe.accounts.create({ - type: 'standard', - }); - return account; - } catch (error) { - throw new Error( - 'An error occurred when calling the Stripe API to create an account' - ); - } - } -} diff --git a/packages/server/src/services/StripePayment/events/SeedStripeAccounts.ts b/packages/server/src/services/StripePayment/events/SeedStripeAccounts.ts deleted file mode 100644 index 3708b95e1..000000000 --- a/packages/server/src/services/StripePayment/events/SeedStripeAccounts.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { StripeOAuthCodeGrantedEventPayload } from '../types'; - -@Service() -export class SeedStripeAccountsOnOAuthGrantedSubscriber { - @Inject() - private tenancy: HasTenancyService; - - /** - * Attaches the subscriber to the event dispatcher. - */ - public attach(bus) { - bus.subscribe( - events.stripeIntegration.onOAuthCodeGranted, - this.handleSeedStripeAccount.bind(this) - ); - } - - /** - * Seeds the default integration settings once oauth authorization code granted. - * @param {StripeCheckoutSessionCompletedEventPayload} payload - - */ - async handleSeedStripeAccount({ - tenantId, - paymentIntegrationId, - trx, - }: StripeOAuthCodeGrantedEventPayload) { - const { PaymentIntegration } = this.tenancy.models(tenantId); - const { accountRepository } = this.tenancy.repositories(tenantId); - - const clearingAccount = await accountRepository.findOrCreateStripeClearing( - {}, - trx - ); - const bankAccount = await accountRepository.findBySlug('bank-account'); - - // Patch the Stripe integration default settings. - await PaymentIntegration.query(trx) - .findById(paymentIntegrationId) - .patch({ - options: { - bankAccountId: bankAccount.id, - clearingAccountId: clearingAccount.id, - }, - }); - } -} diff --git a/packages/server/src/services/StripePayment/events/StripeWebhooksSubscriber.ts b/packages/server/src/services/StripePayment/events/StripeWebhooksSubscriber.ts deleted file mode 100644 index d21072df1..000000000 --- a/packages/server/src/services/StripePayment/events/StripeWebhooksSubscriber.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { CreatePaymentReceiveStripePayment } from '../CreatePaymentReceivedStripePayment'; -import { - StripeCheckoutSessionCompletedEventPayload, - StripeWebhookEventPayload, -} from '@/interfaces/StripePayment'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Tenant } from '@/system/models'; -import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection'; -import { initializeTenantSettings } from '@/api/middleware/SettingsMiddleware'; - -@Service() -export class StripeWebhooksSubscriber { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private createPaymentReceiveStripePayment: CreatePaymentReceiveStripePayment; - - /** - * Attaches the subscriber to the event dispatcher. - */ - public attach(bus) { - bus.subscribe( - events.stripeWebhooks.onCheckoutSessionCompleted, - this.handleCheckoutSessionCompleted.bind(this) - ); - bus.subscribe( - events.stripeWebhooks.onAccountUpdated, - this.handleAccountUpdated.bind(this) - ); - } - - /** - * Handles the checkout session completed webhook event. - * @param {StripeCheckoutSessionCompletedEventPayload} payload - - */ - async handleCheckoutSessionCompleted({ - event, - }: StripeCheckoutSessionCompletedEventPayload) { - const { metadata } = event.data.object; - const tenantId = parseInt(metadata.tenantId, 10); - const saleInvoiceId = parseInt(metadata.saleInvoiceId, 10); - - await initalizeTenantServices(tenantId); - await initializeTenantSettings(tenantId); - - // Get the amount from the event - const amount = event.data.object.amount_total; - - // Convert from Stripe amount (cents) to normal amount (dollars) - const amountInDollars = amount / 100; - - // Creates a new payment received transaction. - await this.createPaymentReceiveStripePayment.createPaymentReceived( - tenantId, - saleInvoiceId, - amountInDollars - ); - } - - /** - * Handles the account updated. - * @param {StripeWebhookEventPayload} - */ - async handleAccountUpdated({ event }: StripeWebhookEventPayload) { - const { metadata } = event.data.object; - const account = event.data.object; - const tenantId = parseInt(metadata.tenantId, 10); - - if (!metadata?.paymentIntegrationId || !metadata.tenantId) return; - - // Find the tenant or throw not found error. - await Tenant.query().findById(tenantId).throwIfNotFound(); - - // Check if the account capabilities are active - if (account.capabilities.card_payments === 'active') { - const { PaymentIntegration } = this.tenancy.models(tenantId); - - // Marks the payment method integration as active. - await PaymentIntegration.query() - .findById(metadata?.paymentIntegrationId) - .patch({ - active: true, - }); - } - } -} diff --git a/packages/server/src/services/StripePayment/types.ts b/packages/server/src/services/StripePayment/types.ts deleted file mode 100644 index 3260b68fa..000000000 --- a/packages/server/src/services/StripePayment/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Knex } from 'knex'; - - -export interface CreateStripeAccountDTO { - name?: string; -} -export interface StripeOAuthCodeGrantedEventPayload { - tenantId: number; - paymentIntegrationId: number; - trx?: Knex.Transaction -} \ No newline at end of file diff --git a/packages/server/src/services/Subscription/GetSubscriptionsTransformer.ts b/packages/server/src/services/Subscription/GetSubscriptionsTransformer.ts deleted file mode 100644 index 28e267d89..000000000 --- a/packages/server/src/services/Subscription/GetSubscriptionsTransformer.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class GetSubscriptionsTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'canceledAtFormatted', - 'endsAtFormatted', - 'trialStartsAtFormatted', - 'trialEndsAtFormatted', - 'statusFormatted', - 'planName', - 'planSlug', - 'planPrice', - 'planPriceCurrency', - 'planPriceFormatted', - 'planPeriod', - 'lemonUrls', - ]; - }; - - /** - * Exclude attributes. - * @returns {string[]} - */ - public excludeAttributes = (): string[] => { - return ['id', 'plan']; - }; - - /** - * Retrieves the canceled at formatted. - * @param subscription - * @returns {string} - */ - public canceledAtFormatted = (subscription) => { - return subscription.canceledAt - ? this.formatDate(subscription.canceledAt) - : null; - }; - - /** - * Retrieves the ends at date formatted. - * @param subscription - * @returns {string} - */ - public endsAtFormatted = (subscription) => { - return subscription.cancelsAt - ? this.formatDate(subscription.endsAt) - : null; - }; - - /** - * Retrieves the trial starts at formatted date. - * @returns {string} - */ - public trialStartsAtFormatted = (subscription) => { - return subscription.trialStartsAt - ? this.formatDate(subscription.trialStartsAt) - : null; - }; - - /** - * Retrieves the trial ends at formatted date. - * @returns {string} - */ - public trialEndsAtFormatted = (subscription) => { - return subscription.trialEndsAt - ? this.formatDate(subscription.trialEndsAt) - : null; - }; - - /** - * Retrieves the Lemon subscription metadata. - * @param subscription - * @returns - */ - public lemonSubscription = (subscription) => { - return ( - this.options.lemonSubscriptions[subscription.lemonSubscriptionId] || null - ); - }; - - /** - * Retrieves the formatted subscription status. - * @param subscription - * @returns {string} - */ - public statusFormatted = (subscription) => { - const pairs = { - canceled: 'Canceled', - active: 'Active', - inactive: 'Inactive', - expired: 'Expired', - on_trial: 'On Trial', - }; - return pairs[subscription.status] || ''; - }; - - /** - * Retrieves the subscription plan name. - * @param subscription - * @returns {string} - */ - public planName(subscription) { - return subscription.plan?.name; - } - - /** - * Retrieves the subscription plan slug. - * @param subscription - * @returns {string} - */ - public planSlug(subscription) { - return subscription.plan?.slug; - } - - /** - * Retrieves the subscription plan price. - * @param subscription - * @returns {number} - */ - public planPrice(subscription) { - return subscription.plan?.price; - } - - /** - * Retrieves the subscription plan price currency. - * @param subscription - * @returns {string} - */ - public planPriceCurrency(subscription) { - return subscription.plan?.currency; - } - - /** - * Retrieves the subscription plan formatted price. - * @param subscription - * @returns {string} - */ - public planPriceFormatted(subscription) { - return this.formatMoney(subscription.plan?.price, { - currencyCode: subscription.plan?.currency, - precision: 0 - }); - } - - /** - * Retrieves the subscription plan period. - * @param subscription - * @returns {string} - */ - public planPeriod(subscription) { - return subscription?.plan?.period; - } - - /** - * Retrieve the subscription Lemon Urls. - * @param subscription - * @returns - */ - public lemonUrls = (subscription) => { - const lemonSusbcription = this.lemonSubscription(subscription); - return lemonSusbcription?.data?.attributes?.urls; - }; -} diff --git a/packages/server/src/services/Subscription/LemonCancelSubscription.ts b/packages/server/src/services/Subscription/LemonCancelSubscription.ts deleted file mode 100644 index 97f369197..000000000 --- a/packages/server/src/services/Subscription/LemonCancelSubscription.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { cancelSubscription } from '@lemonsqueezy/lemonsqueezy.js'; -import { configureLemonSqueezy } from './utils'; -import { PlanSubscription } from '@/system/models'; -import { ServiceError } from '@/exceptions'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { ERRORS, IOrganizationSubscriptionCancel } from './types'; -import events from '@/subscribers/events'; - -@Service() -export class LemonCancelSubscription { - @Inject() - private eventPublisher: EventPublisher; - - /** - * Cancels the subscription of the given tenant. - * @param {number} tenantId - * @param {number} subscriptionId - * @returns {Promise} - */ - public async cancelSubscription( - tenantId: number, - subscriptionSlug: string = 'main' - ) { - configureLemonSqueezy(); - - const subscription = await PlanSubscription.query().findOne({ - tenantId, - slug: subscriptionSlug, - }); - if (!subscription) { - throw new ServiceError(ERRORS.SUBSCRIPTION_ID_NOT_ASSOCIATED_TO_TENANT); - } - const lemonSusbcriptionId = subscription.lemonSubscriptionId; - const subscriptionId = subscription.id; - const cancelledSub = await cancelSubscription(lemonSusbcriptionId); - - if (cancelledSub.error) { - throw new Error(cancelledSub.error.message); - } - // Triggers `onSubscriptionCancelled` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionCancel, - { tenantId, subscriptionId } as IOrganizationSubscriptionCancel - ); - } -} diff --git a/packages/server/src/services/Subscription/LemonChangeSubscriptionPlan.ts b/packages/server/src/services/Subscription/LemonChangeSubscriptionPlan.ts deleted file mode 100644 index 4cb451bd4..000000000 --- a/packages/server/src/services/Subscription/LemonChangeSubscriptionPlan.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { updateSubscription } from '@lemonsqueezy/lemonsqueezy.js'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { ServiceError } from '@/exceptions'; -import { PlanSubscription } from '@/system/models'; -import { configureLemonSqueezy } from './utils'; -import events from '@/subscribers/events'; -import { IOrganizationSubscriptionChanged } from './types'; - -@Service() -export class LemonChangeSubscriptionPlan { - @Inject() - private eventPublisher: EventPublisher; - - /** - * Changes the given organization subscription plan. - * @param {number} tenantId - Tenant id. - * @param {number} newVariantId - New variant id. - * @returns {Promise} - */ - public async changeSubscriptionPlan( - tenantId: number, - newVariantId: number, - subscriptionSlug: string = 'main' - ) { - configureLemonSqueezy(); - - const subscription = await PlanSubscription.query().findOne({ - tenantId, - slug: subscriptionSlug, - }); - const lemonSubscriptionId = subscription.lemonSubscriptionId; - - // Send request to Lemon Squeezy to change the subscription. - const updatedSub = await updateSubscription(lemonSubscriptionId, { - variantId: newVariantId, - invoiceImmediately: true, - }); - if (updatedSub.error) { - throw new ServiceError('SOMETHING_WENT_WRONG'); - } - // Triggers `onSubscriptionPlanChanged` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionPlanChange, - { - tenantId, - lemonSubscriptionId, - newVariantId, - } as IOrganizationSubscriptionChanged - ); - } -} diff --git a/packages/server/src/services/Subscription/LemonResumeSubscription.ts b/packages/server/src/services/Subscription/LemonResumeSubscription.ts deleted file mode 100644 index f4ea86a37..000000000 --- a/packages/server/src/services/Subscription/LemonResumeSubscription.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { updateSubscription } from '@lemonsqueezy/lemonsqueezy.js'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { configureLemonSqueezy } from './utils'; -import { PlanSubscription } from '@/system/models'; -import { ServiceError } from '@/exceptions'; -import { ERRORS, IOrganizationSubscriptionResume } from './types'; - -@Service() -export class LemonResumeSubscription { - @Inject() - private eventPublisher: EventPublisher; - - /** - * Resumes the main subscription of the given tenant. - * @param {number} tenantId - Tenant id. - * @param {string} subscriptionSlug - Subscription slug by default main subscription. - * @returns {Promise} - */ - public async resumeSubscription( - tenantId: number, - subscriptionSlug: string = 'main' - ) { - configureLemonSqueezy(); - - const subscription = await PlanSubscription.query().findOne({ - tenantId, - slug: subscriptionSlug, - }); - if (!subscription) { - throw new ServiceError(ERRORS.SUBSCRIPTION_ID_NOT_ASSOCIATED_TO_TENANT); - } - const subscriptionId = subscription.id; - const lemonSubscriptionId = subscription.lemonSubscriptionId; - const returnedSub = await updateSubscription(lemonSubscriptionId, { - cancelled: false, - }); - if (returnedSub.error) { - throw new ServiceError(ERRORS.SOMETHING_WENT_WRONG_WITH_LS); - } - // Triggers `onSubscriptionResume` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionResume, - { tenantId, subscriptionId } as IOrganizationSubscriptionResume - ); - } -} diff --git a/packages/server/src/services/Subscription/LemonSqueezyService.ts b/packages/server/src/services/Subscription/LemonSqueezyService.ts deleted file mode 100644 index 85231a446..000000000 --- a/packages/server/src/services/Subscription/LemonSqueezyService.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Service } from 'typedi'; -import { createCheckout } from '@lemonsqueezy/lemonsqueezy.js'; -import { SystemUser } from '@/system/models'; -import { configureLemonSqueezy } from './utils'; -import config from '@/config'; - -@Service() -export class LemonSqueezyService { - /** - * Retrieves the LemonSqueezy checkout url. - * @param {number} variantId - * @param {SystemUser} user - */ - async getCheckout(variantId: number, user: SystemUser) { - configureLemonSqueezy(); - - return createCheckout(process.env.LEMONSQUEEZY_STORE_ID!, variantId, { - checkoutOptions: { - embed: true, - media: true, - logo: true, - }, - checkoutData: { - email: user.email, - custom: { - user_id: user.id + '', - tenant_id: user.tenantId + '', - }, - }, - productOptions: { - enabledVariants: [variantId], - redirectUrl: config.lemonSqueezy.redirectTo, - receiptButtonText: 'Go to Dashboard', - receiptThankYouNote: 'Thank you for signing up to Lemon Stand!', - }, - }); - } -} diff --git a/packages/server/src/services/Subscription/LemonSqueezyWebhooks.ts b/packages/server/src/services/Subscription/LemonSqueezyWebhooks.ts deleted file mode 100644 index 3dcce2845..000000000 --- a/packages/server/src/services/Subscription/LemonSqueezyWebhooks.ts +++ /dev/null @@ -1,134 +0,0 @@ -import config from '@/config'; -import { Inject, Service } from 'typedi'; -import { - compareSignatures, - configureLemonSqueezy, - createHmacSignature, - webhookHasData, - webhookHasMeta, -} from './utils'; -import { Plan } from '@/system/models'; -import { Subscription } from './Subscription'; - -@Service() -export class LemonSqueezyWebhooks { - @Inject() - private subscriptionService: Subscription; - - /** - * Handles the Lemon Squeezy webhooks. - * @param {string} rawBody - * @param {string} signature - * @returns {Promise} - */ - public async handlePostWebhook( - rawData: any, - data: Record, - signature: string - ): Promise { - configureLemonSqueezy(); - - if (!config.lemonSqueezy.webhookSecret) { - throw new Error('Lemon Squeezy Webhook Secret not set in .env'); - } - if (!signature) { - throw new Error('Request signature is required.'); - } - const secret = config.lemonSqueezy.webhookSecret; - const hmacSignature = createHmacSignature(secret, rawData); - - if (!compareSignatures(hmacSignature, signature)) { - throw new Error('Invalid signature'); - } - // Type guard to check if the object has a 'meta' property. - if (webhookHasMeta(data)) { - // Non-blocking call to process the webhook event. - void this.processWebhookEvent(data); - } else { - throw new Error('Data invalid'); - } - } - - /** - * This action will process a webhook event in the database. - * @param {unknown} eventBody - - * @returns {Promise} - */ - private async processWebhookEvent(eventBody): Promise { - const webhookEvent = eventBody.meta.event_name; - - const userId = eventBody.meta.custom_data?.user_id; - const tenantId = eventBody.meta.custom_data?.tenant_id; - const subscriptionSlug = 'main'; - - if (!webhookHasMeta(eventBody)) { - throw new Error("Event body is missing the 'meta' property."); - } else if (webhookHasData(eventBody)) { - if (webhookEvent.startsWith('subscription_payment_')) { - // Marks the main subscription payment as succeed. - if (webhookEvent === 'subscription_payment_success') { - await this.subscriptionService.markSubscriptionPaymentSucceed( - tenantId, - subscriptionSlug - ); - // Marks the main subscription payment as failed. - } else if (webhookEvent === 'subscription_payment_failed') { - await this.subscriptionService.markSubscriptionPaymentFailed( - tenantId, - subscriptionSlug - ); - } - // Save subscription invoices; eventBody is a SubscriptionInvoice - // Not implemented. - } else if (webhookEvent.startsWith('subscription_')) { - // Save subscription events; obj is a Subscription - const attributes = eventBody.data.attributes; - const variantId = attributes.variant_id as string; - - // We assume that the Plan table is up to date. - const plan = await Plan.query().findOne('lemonVariantId', variantId); - - // Update the subscription in the database. - const priceId = attributes.first_subscription_item.price_id; - const subscriptionId = eventBody.data.id; - - // Throw error early if the given lemon variant id is not associated to any plan. - if (!plan) { - throw new Error(`Plan with variantId ${variantId} not found.`); - } - // Create a new subscription of the tenant. - if (webhookEvent === 'subscription_created') { - await this.subscriptionService.newSubscribtion( - tenantId, - plan.slug, - subscriptionSlug, - { lemonSqueezyId: subscriptionId } - ); - // Cancel the given subscription of the organization. - } else if (webhookEvent === 'subscription_cancelled') { - await this.subscriptionService.cancelSubscription( - tenantId, - subscriptionSlug - ); - } else if (webhookEvent === 'subscription_plan_changed') { - await this.subscriptionService.subscriptionPlanChanged( - tenantId, - plan.slug, - subscriptionSlug - ); - } else if (webhookEvent === 'subscription_resumed') { - await this.subscriptionService.resumeSubscription( - tenantId, - subscriptionSlug - ); - } - } else if (webhookEvent.startsWith('order_')) { - // Save orders; eventBody is a "Order" - /* Not implemented */ - } else if (webhookEvent.startsWith('license_')) { - // Save license keys; eventBody is a "License key" - /* Not implemented */ - } - } - } -} diff --git a/packages/server/src/services/Subscription/Subscription.ts b/packages/server/src/services/Subscription/Subscription.ts deleted file mode 100644 index ead569822..000000000 --- a/packages/server/src/services/Subscription/Subscription.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { NotAllowedChangeSubscriptionPlan, ServiceError } from '@/exceptions'; -import { Plan, PlanSubscription, Tenant } from '@/system/models'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { SubscriptionPayload, SubscriptionPaymentStatus } from '@/interfaces'; -import { ERRORS } from './types'; - -@Service() -export class Subscription { - @Inject() - private eventPublisher: EventPublisher; - - /** - * Give the tenant a new subscription. - * @param {number} tenantId - Tenant id. - * @param {string} planSlug - Plan slug of the new subscription. - * @param {string} subscriptionSlug - Subscription slug by default takes main subscription - * @param {SubscriptionPayload} payload - Subscription payload. - */ - public async newSubscribtion( - tenantId: number, - planSlug: string, - subscriptionSlug: string = 'main', - payload?: SubscriptionPayload - ): Promise { - const tenant = await Tenant.query().findById(tenantId).throwIfNotFound(); - const plan = await Plan.query().findOne('slug', planSlug).throwIfNotFound(); - - const isFree = plan.price === 0; - - // Take the invoice interval and period from the given plan. - const invoiceInterval = plan.invoiceInternal; - const invoicePeriod = isFree ? Infinity : plan.invoicePeriod; - - const subscription = await tenant - .$relatedQuery('subscriptions') - .modify('subscriptionBySlug', subscriptionSlug) - .first(); - - // No allowed to re-new the the subscription while the subscription is active. - if (subscription && subscription.active()) { - throw new NotAllowedChangeSubscriptionPlan(); - - // In case there is already subscription associated to the given tenant renew it. - } else if (subscription && subscription.inactive()) { - await subscription.renew(invoiceInterval, invoicePeriod); - - // No stored past tenant subscriptions create new one. - } else { - await tenant.newSubscription( - plan.id, - invoiceInterval, - invoicePeriod, - subscriptionSlug, - payload - ); - } - } - - /** - * Cancels the given tenant subscription. - * @param {number} tenantId - Tenant id. - * @param {string} subscriptionSlug - Subscription slug. - */ - async cancelSubscription( - tenantId: number, - subscriptionSlug: string = 'main' - ): Promise { - const tenant = await Tenant.query().findById(tenantId).throwIfNotFound(); - - const subscription = await PlanSubscription.query().findOne({ - tenantId, - slug: subscriptionSlug, - }); - // Throw error early if the subscription is not exist. - if (!subscription) { - throw new ServiceError(ERRORS.SUBSCRIPTION_NOT_EXIST); - } - // Throw error early if the subscription is already canceled. - if (subscription.canceled()) { - throw new ServiceError(ERRORS.SUBSCRIPTION_ALREADY_CANCELED); - } - await subscription.$query().patch({ canceledAt: new Date() }); - - // Triggers `onSubscriptionCancelled` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionCancelled, - { - tenantId, - subscriptionSlug, - } - ); - } - - /** - * Resumes the given tenant subscription. - * @param {number} tenantId - * @param {string} subscriptionSlug - Subscription slug by deafult main subscription. - * @returns {Promise} - */ - async resumeSubscription( - tenantId: number, - subscriptionSlug: string = 'main' - ) { - const tenant = await Tenant.query().findById(tenantId).throwIfNotFound(); - - const subscription = await PlanSubscription.query().findOne({ - tenantId, - slug: subscriptionSlug, - }); - // Throw error early if the subscription is not exist. - if (!subscription) { - throw new ServiceError(ERRORS.SUBSCRIPTION_NOT_EXIST); - } - // Throw error early if the subscription is not cancelled. - if (!subscription.canceled()) { - throw new ServiceError(ERRORS.SUBSCRIPTION_ALREADY_ACTIVE); - } - await subscription.$query().patch({ canceledAt: null }); - - // Triggers `onSubscriptionResumed` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionResumed, - { tenantId, subscriptionSlug } - ); - } - - /** - * Mark the given subscription payment of the tenant as succeed. - * @param {number} tenantId - * @param {string} newPlanSlug - * @param {string} subscriptionSlug - */ - async subscriptionPlanChanged( - tenantId: number, - newPlanSlug: string, - subscriptionSlug: string = 'main' - ): Promise { - const tenant = await Tenant.query().findById(tenantId).throwIfNotFound(); - const newPlan = await Plan.query() - .findOne('slug', newPlanSlug) - .throwIfNotFound(); - - const subscription = await PlanSubscription.query().findOne({ - tenantId, - slug: subscriptionSlug, - }); - if (subscription.planId === newPlan.id) { - throw new ServiceError(''); - } - await subscription.$query().patch({ planId: newPlan.id }); - - // Triggers `onSubscriptionPlanChanged` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionPlanChanged, - { - tenantId, - newPlanSlug, - subscriptionSlug, - } - ); - } - - /** - * Marks the subscription payment as succeed. - * @param {number} tenantId - Tenant id. - * @param {string} subscriptionSlug - Given subscription slug by default main subscription. - * @returns {Promise} - */ - async markSubscriptionPaymentSucceed( - tenantId: number, - subscriptionSlug: string = 'main' - ): Promise { - const subscription = await PlanSubscription.query() - .findOne({ tenantId, slug: subscriptionSlug }) - .throwIfNotFound(); - - await subscription - .$query() - .patch({ paymentStatus: SubscriptionPaymentStatus.Succeed }); - - // Triggers `onSubscriptionSucceed` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionPaymentSucceed, - { - tenantId, - subscriptionSlug, - } - ); - } - - /** - * Marks the given subscription payment of the tenant as failed. - * @param {number} tenantId - Tenant id. - * @param {string} subscriptionSlug - Given subscription slug. - * @returns {Prmise} - */ - async markSubscriptionPaymentFailed( - tenantId: number, - subscriptionSlug: string = 'main' - ): Promise { - const subscription = await PlanSubscription.query() - .findOne({ tenantId, slug: subscriptionSlug }) - .throwIfNotFound(); - - await subscription - .$query() - .patch({ paymentStatus: SubscriptionPaymentStatus.Failed }); - - // Triggers `onSubscriptionPaymentFailed` event. - await this.eventPublisher.emitAsync( - events.subscription.onSubscriptionPaymentFailed, - { - tenantId, - subscriptionSlug, - } - ); - } -} diff --git a/packages/server/src/services/Subscription/SubscriptionApplication.ts b/packages/server/src/services/Subscription/SubscriptionApplication.ts deleted file mode 100644 index c830607b7..000000000 --- a/packages/server/src/services/Subscription/SubscriptionApplication.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { LemonCancelSubscription } from './LemonCancelSubscription'; -import { LemonChangeSubscriptionPlan } from './LemonChangeSubscriptionPlan'; -import { LemonResumeSubscription } from './LemonResumeSubscription'; - -@Service() -export class SubscriptionApplication { - @Inject() - private cancelSubscriptionService: LemonCancelSubscription; - - @Inject() - private resumeSubscriptionService: LemonResumeSubscription; - - @Inject() - private changeSubscriptionPlanService: LemonChangeSubscriptionPlan; - - /** - * Cancels the subscription of the given tenant. - * @param {number} tenantId - * @param {string} id - * @returns {Promise} - */ - public cancelSubscription( - tenantId: number, - subscriptionSlug: string = 'main' - ) { - return this.cancelSubscriptionService.cancelSubscription( - tenantId, - subscriptionSlug - ); - } - - /** - * Resumes the subscription of the given tenant. - * @param {number} tenantId - * @returns {Promise} - */ - public resumeSubscription( - tenantId: number, - subscriptionSlug: string = 'main' - ) { - return this.resumeSubscriptionService.resumeSubscription( - tenantId, - subscriptionSlug - ); - } - - /** - * Changes the given organization subscription plan. - * @param {number} tenantId - * @param {number} newVariantId - * @returns {Promise} - */ - public changeSubscriptionPlan(tenantId: number, newVariantId: number) { - return this.changeSubscriptionPlanService.changeSubscriptionPlan( - tenantId, - newVariantId - ); - } -} diff --git a/packages/server/src/services/Subscription/SubscriptionPeriod.ts b/packages/server/src/services/Subscription/SubscriptionPeriod.ts deleted file mode 100644 index 41f608554..000000000 --- a/packages/server/src/services/Subscription/SubscriptionPeriod.ts +++ /dev/null @@ -1,49 +0,0 @@ -import moment, { unitOfTime } from 'moment'; - -export default class SubscriptionPeriod { - private start: Date; - private end: Date; - private interval: string; - private count: number; - - /** - * Constructor method. - * @param {string} interval - - * @param {number} count - - * @param {Date} start - - */ - constructor( - interval: unitOfTime.DurationConstructor = 'month', - count: number, - start?: Date - ) { - this.interval = interval; - this.count = count; - this.start = start; - - if (!start) { - this.start = moment().toDate(); - } - if (count === Infinity) { - this.end = null; - } else { - this.end = moment(start).add(count, interval).toDate(); - } - } - - getStartDate() { - return this.start; - } - - getEndDate() { - return this.end; - } - - getInterval() { - return this.interval; - } - - getIntervalCount() { - return this.count; - } -} diff --git a/packages/server/src/services/Subscription/SubscriptionService.ts b/packages/server/src/services/Subscription/SubscriptionService.ts deleted file mode 100644 index a61714af3..000000000 --- a/packages/server/src/services/Subscription/SubscriptionService.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { getSubscription } from '@lemonsqueezy/lemonsqueezy.js'; -import { PromisePool } from '@supercharge/promise-pool'; -import { PlanSubscription } from '@/system/models'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { GetSubscriptionsTransformer } from './GetSubscriptionsTransformer'; -import { configureLemonSqueezy } from './utils'; -import { fromPairs } from 'lodash'; - -@Service() -export default class SubscriptionService { - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve all subscription of the given tenant. - * @param {number} tenantId - */ - public async getSubscriptions(tenantId: number) { - configureLemonSqueezy(); - - const subscriptions = await PlanSubscription.query() - .where('tenant_id', tenantId) - .withGraphFetched('plan'); - - const lemonSubscriptionsResult = await PromisePool.withConcurrency(1) - .for(subscriptions) - .process(async (subscription, index, pool) => { - if (subscription.lemonSubscriptionId) { - const res = await getSubscription(subscription.lemonSubscriptionId); - - if (res.error) { - return; - } - return [subscription.lemonSubscriptionId, res.data]; - } - }); - const lemonSubscriptions = fromPairs( - lemonSubscriptionsResult?.results.filter((result) => !!result[1]) - ); - return this.transformer.transform( - tenantId, - subscriptions, - new GetSubscriptionsTransformer(), - { - lemonSubscriptions, - } - ); - } -} diff --git a/packages/server/src/services/Subscription/events/SubscribeFreeOnSignupCommunity.tsx b/packages/server/src/services/Subscription/events/SubscribeFreeOnSignupCommunity.tsx deleted file mode 100644 index f42a037b8..000000000 --- a/packages/server/src/services/Subscription/events/SubscribeFreeOnSignupCommunity.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IAuthSignedUpEventPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import config from '@/config'; -import { Subscription } from '../Subscription'; - -@Service() -export class SubscribeFreeOnSignupCommunity { - @Inject() - private subscriptionService: Subscription; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.auth.signUp, - this.subscribeFreeOnSigupCommunity.bind(this) - ); - }; - - /** - * Creates a new free subscription once the user signup if the app is self-hosted. - * @param {IAuthSignedUpEventPayload} - * @returns {Promise} - */ - private async subscribeFreeOnSigupCommunity({ - signupDTO, - tenant, - user, - }: IAuthSignedUpEventPayload) { - if (config.hostedOnBigcapitalCloud) return null; - - await this.subscriptionService.newSubscribtion(tenant.id, 'free'); - } -} diff --git a/packages/server/src/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange.tsx b/packages/server/src/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange.tsx deleted file mode 100644 index 8046efb5f..000000000 --- a/packages/server/src/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import events from '@/subscribers/events'; -import Container from 'typedi'; - -export class TriggerInvalidateCacheOnSubscriptionChange { - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.subscription.onSubscriptionCancelled, - this.triggerInvalidateCache.bind(this) - ); - bus.subscribe( - events.subscription.onSubscriptionResumed, - this.triggerInvalidateCache.bind(this) - ); - bus.subscribe( - events.subscription.onSubscriptionPlanChanged, - this.triggerInvalidateCache.bind(this) - ); - }; - - private triggerInvalidateCache() { - const io = Container.get('socket'); - - // Notify the frontend to reflect the new transactions changes. - io.emit('SUBSCRIPTION_CHANGED', { subscriptionSlug: 'main' }); - } -} diff --git a/packages/server/src/services/Subscription/types.ts b/packages/server/src/services/Subscription/types.ts deleted file mode 100644 index 2d8dc7b83..000000000 --- a/packages/server/src/services/Subscription/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -export const ERRORS = { - SUBSCRIPTION_ID_NOT_ASSOCIATED_TO_TENANT: - 'SUBSCRIPTION_ID_NOT_ASSOCIATED_TO_TENANT', - SUBSCRIPTION_NOT_EXIST: 'SUBSCRIPTION_NOT_EXIST', - SUBSCRIPTION_ALREADY_CANCELED: 'SUBSCRIPTION_ALREADY_CANCELED', - SUBSCRIPTION_ALREADY_ACTIVE: 'SUBSCRIPTION_ALREADY_ACTIVE', - SOMETHING_WENT_WRONG_WITH_LS: 'SOMETHING_WENT_WRONG_WITH_LS', -}; - -export interface IOrganizationSubscriptionChanged { - tenantId: number; - lemonSubscriptionId: string; - newVariantId: number; -} - -export interface IOrganizationSubscriptionCancel { - tenantId: number; - subscriptionId: string; -} - -export interface IOrganizationSubscriptionCancelled { - tenantId: number; - subscriptionId: string; -} - -export interface IOrganizationSubscriptionResume { - tenantId: number; - subscriptionId: number; -} -export interface IOrganizationSubscriptionResumed { - tenantId: number; - subscriptionId: number; -} diff --git a/packages/server/src/services/Subscription/utils.ts b/packages/server/src/services/Subscription/utils.ts deleted file mode 100644 index 56dc7e4b4..000000000 --- a/packages/server/src/services/Subscription/utils.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { lemonSqueezySetup } from '@lemonsqueezy/lemonsqueezy.js'; - -/** - * Ensures that required environment variables are set and sets up the Lemon - * Squeezy JS SDK. Throws an error if any environment variables are missing or - * if there's an error setting up the SDK. - */ -export function configureLemonSqueezy() { - const requiredVars = [ - 'LEMONSQUEEZY_API_KEY', - 'LEMONSQUEEZY_STORE_ID', - 'LEMONSQUEEZY_WEBHOOK_SECRET', - ]; - const missingVars = requiredVars.filter((varName) => !process.env[varName]); - - if (missingVars.length > 0) { - throw new Error( - `Missing required LEMONSQUEEZY env variables: ${missingVars.join( - ', ' - )}. Please, set them in your .env file.` - ); - } - lemonSqueezySetup({ - apiKey: process.env.LEMONSQUEEZY_API_KEY, - onError: (error) => { - // eslint-disable-next-line no-console -- allow logging - console.error(error); - throw new Error(`Lemon Squeezy API error: ${error.message}`); - }, - }); -} -/** - * Check if the value is an object. - */ -function isObject(value: unknown): value is Record { - return typeof value === 'object' && value !== null; -} - -/** - * Typeguard to check if the object has a 'meta' property - * and that the 'meta' property has the correct shape. - */ -export function webhookHasMeta(obj: unknown): obj is { - meta: { - event_name: string; - custom_data: { - user_id: string; - }; - }; -} { - if ( - isObject(obj) && - isObject(obj.meta) && - typeof obj.meta.event_name === 'string' && - isObject(obj.meta.custom_data) && - typeof obj.meta.custom_data.user_id === 'string' - ) { - return true; - } - return false; -} - -/** - * Typeguard to check if the object has a 'data' property and the correct shape. - * - * @param obj - The object to check. - * @returns True if the object has a 'data' property. - */ -export function webhookHasData(obj: unknown): obj is { - data: { - attributes: Record & { - first_subscription_item: { - id: number; - price_id: number; - is_usage_based: boolean; - }; - }; - id: string; - }; -} { - return ( - isObject(obj) && - 'data' in obj && - isObject(obj.data) && - 'attributes' in obj.data - ); -} - -export function createHmacSignature(secretKey, body) { - return require('crypto') - .createHmac('sha256', secretKey) - .update(body) - .digest('hex'); -} - -export function compareSignatures(signature, comparison_signature) { - const source = Buffer.from(signature, 'utf8'); - const comparison = Buffer.from(comparison_signature, 'utf8'); - return require('crypto').timingSafeEqual(source, comparison); -} diff --git a/packages/server/src/services/TaxRates/ActivateTaxRate.ts b/packages/server/src/services/TaxRates/ActivateTaxRate.ts deleted file mode 100644 index 2384b901d..000000000 --- a/packages/server/src/services/TaxRates/ActivateTaxRate.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { - ITaxRateActivatedPayload, - ITaxRateActivatingPayload, -} from '@/interfaces'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; -import events from '@/subscribers/events'; - -@Service() -export class ActivateTaxRateService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandTaxRatesValidators; - - /** - * Activates the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @param {IEditTaxRateDTO} taxRateEditDTO - * @returns {Promise} - */ - public activateTaxRate(tenantId: number, taxRateId: number) { - const { TaxRate } = this.tenancy.models(tenantId); - - const oldTaxRate = TaxRate.query().findById(taxRateId); - - // Validates the tax rate existance. - this.validators.validateTaxRateExistance(oldTaxRate); - - // Validates the tax rate inactive. - this.validators.validateTaxRateNotActive(oldTaxRate); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTaxRateActivating` event. - await this.eventPublisher.emitAsync(events.taxRates.onActivating, { - taxRateId, - tenantId, - trx, - } as ITaxRateActivatingPayload); - - const taxRate = await TaxRate.query(trx) - .findById(taxRateId) - .patch({ active: 1 }); - - // Triggers `onTaxRateCreated` event. - await this.eventPublisher.emitAsync(events.taxRates.onActivated, { - taxRateId, - tenantId, - trx, - } as ITaxRateActivatedPayload); - - return taxRate; - }); - } -} diff --git a/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts b/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts deleted file mode 100644 index decd41857..000000000 --- a/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { difference } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { IItemEntryDTO, ITaxRate } from '@/interfaces'; -import { ERRORS } from './constants'; - -@Service() -export class CommandTaxRatesValidators { - @Inject() - private tenancy: HasTenancyService; - - /** - * Validates the tax rate existance. - * @param {TaxRate | undefined | null} taxRate - */ - public validateTaxRateExistance(taxRate: ITaxRate | undefined | null) { - if (!taxRate) { - throw new ServiceError(ERRORS.TAX_RATE_NOT_FOUND); - } - } - - /** - * Validates the given tax rate active. - * @param {ITaxRate} taxRate - */ - public validateTaxRateNotActive(taxRate: ITaxRate) { - if (taxRate.active) { - throw new ServiceError(ERRORS.TAX_RATE_ALREADY_ACTIVE); - } - } - - /** - * Validates the given tax rate inactive. - * @param {ITaxRate} taxRate - */ - public validateTaxRateNotInactive(taxRate: ITaxRate) { - if (!taxRate.active) { - throw new ServiceError(ERRORS.TAX_RATE_ALREADY_INACTIVE); - } - } - - /** - * Validates the tax code uniquiness. - * @param {number} tenantId - * @param {string} taxCode - * @param {Knex.Transaction} trx - - */ - public async validateTaxCodeUnique( - tenantId: number, - taxCode: string, - trx?: Knex.Transaction - ) { - const { TaxRate } = this.tenancy.models(tenantId); - - const foundTaxCode = await TaxRate.query(trx).findOne({ code: taxCode }); - - if (foundTaxCode) { - throw new ServiceError(ERRORS.TAX_CODE_NOT_UNIQUE); - } - } - - /** - * Validates the tax codes of the given item entries DTO. - * @param {number} tenantId - * @param {IItemEntryDTO[]} itemEntriesDTO - * @throws {ServiceError} - */ - public async validateItemEntriesTaxCode( - tenantId: number, - itemEntriesDTO: IItemEntryDTO[] - ) { - const { TaxRate } = this.tenancy.models(tenantId); - - const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxCode); - const taxCodes = filteredTaxEntries.map((e) => e.taxCode); - - // Can't validate if there is no tax codes. - if (taxCodes.length === 0) return; - - const foundTaxCodes = await TaxRate.query().whereIn('code', taxCodes); - const foundCodes = foundTaxCodes.map((tax) => tax.code); - - const notFoundTaxCodes = difference(taxCodes, foundCodes); - - if (notFoundTaxCodes.length > 0) { - throw new ServiceError(ERRORS.ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND); - } - } - - /** - * Validates the tax rate id of the given item entries DTO. - * @param {number} tenantId - * @param {IItemEntryDTO[]} itemEntriesDTO - * @throws {ServiceError} - */ - public async validateItemEntriesTaxCodeId( - tenantId: number, - itemEntriesDTO: IItemEntryDTO[] - ) { - const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxRateId); - const taxRatesIds = filteredTaxEntries.map((e) => e.taxRateId); - - // Can't validate if there is no tax codes. - if (taxRatesIds.length === 0) return; - - const { TaxRate } = this.tenancy.models(tenantId); - const foundTaxCodes = await TaxRate.query().whereIn('id', taxRatesIds); - const foundTaxRatesIds = foundTaxCodes.map((tax) => tax.id); - - const notFoundTaxCodes = difference(taxRatesIds, foundTaxRatesIds); - - if (notFoundTaxCodes.length > 0) { - throw new ServiceError(ERRORS.ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/TaxRates/CreateTaxRate.ts b/packages/server/src/services/TaxRates/CreateTaxRate.ts deleted file mode 100644 index 9da05dded..000000000 --- a/packages/server/src/services/TaxRates/CreateTaxRate.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { - ICreateTaxRateDTO, - ITaxRateCreatedPayload, - ITaxRateCreatingPayload, -} from '@/interfaces'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '../Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; - -@Service() -export class CreateTaxRate { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandTaxRatesValidators; - - /** - * Creates a new tax rate. - * @param {number} tenantId - * @param {ICreateTaxRateDTO} createTaxRateDTO - */ - public async createTaxRate( - tenantId: number, - createTaxRateDTO: ICreateTaxRateDTO, - trx?: Knex.Transaction - ) { - const { TaxRate } = this.tenancy.models(tenantId); - - // Validates the tax code uniquiness. - await this.validators.validateTaxCodeUnique( - tenantId, - createTaxRateDTO.code, - trx - ); - return this.uow.withTransaction( - tenantId, - async (trx: Knex.Transaction) => { - // Triggers `onTaxRateCreating` event. - await this.eventPublisher.emitAsync(events.taxRates.onCreating, { - createTaxRateDTO, - tenantId, - trx, - } as ITaxRateCreatingPayload); - - const taxRate = await TaxRate.query(trx).insertAndFetch({ - ...createTaxRateDTO, - }); - // Triggers `onTaxRateCreated` event. - await this.eventPublisher.emitAsync(events.taxRates.onCreated, { - createTaxRateDTO, - taxRate, - tenantId, - trx, - } as ITaxRateCreatedPayload); - - return taxRate; - }, - trx - ); - } -} diff --git a/packages/server/src/services/TaxRates/DeleteTaxRate.ts b/packages/server/src/services/TaxRates/DeleteTaxRate.ts deleted file mode 100644 index 27c104de1..000000000 --- a/packages/server/src/services/TaxRates/DeleteTaxRate.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ITaxRateDeletedPayload, ITaxRateDeletingPayload } from '@/interfaces'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; -import events from '@/subscribers/events'; - -@Service() -export class DeleteTaxRateService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandTaxRatesValidators; - - /** - * Deletes the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @returns {Promise} - */ - public deleteTaxRate(tenantId: number, taxRateId: number) { - const { TaxRate } = this.tenancy.models(tenantId); - - const oldTaxRate = TaxRate.query().findById(taxRateId); - - // Validates the tax rate existance. - this.validators.validateTaxRateExistance(oldTaxRate); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTaxRateDeleting` event. - await this.eventPublisher.emitAsync(events.taxRates.onDeleting, { - oldTaxRate, - tenantId, - trx, - } as ITaxRateDeletingPayload); - - await TaxRate.query(trx).findById(taxRateId).delete(); - - // Triggers `onTaxRateDeleted` event. - await this.eventPublisher.emitAsync(events.taxRates.onDeleted, { - oldTaxRate, - tenantId, - trx, - } as ITaxRateDeletedPayload); - }); - } -} diff --git a/packages/server/src/services/TaxRates/EditTaxRate.ts b/packages/server/src/services/TaxRates/EditTaxRate.ts deleted file mode 100644 index 210529026..000000000 --- a/packages/server/src/services/TaxRates/EditTaxRate.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import { omit } from 'lodash'; -import { - IEditTaxRateDTO, - ITaxRate, - ITaxRateEditedPayload, - ITaxRateEditingPayload, -} from '@/interfaces'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; -import events from '@/subscribers/events'; - -@Service() -export class EditTaxRateService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandTaxRatesValidators; - - /** - * Detarmines whether the tax rate, name or code have been changed. - * @param {ITaxRate} taxRate - * @param {IEditTaxRateDTO} editTaxRateDTO - * @returns {boolean} - */ - private isTaxRateDTOChanged = ( - taxRate: ITaxRate, - editTaxRateDTO: IEditTaxRateDTO - ) => { - return ( - taxRate.rate !== editTaxRateDTO.rate || - taxRate.name !== editTaxRateDTO.name || - taxRate.code !== editTaxRateDTO.code - ); - }; - - /** - * Edits the given tax rate or creates a new if the rate or name have been changed. - * @param {number} tenantId - * @param {ITaxRate} oldTaxRate - * @param {IEditTaxRateDTO} editTaxRateDTO - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - private async editTaxRateOrCreate( - tenantId: number, - oldTaxRate: ITaxRate, - editTaxRateDTO: IEditTaxRateDTO, - trx?: Knex.Transaction - ) { - const { TaxRate } = this.tenancy.models(tenantId); - const isTaxDTOChanged = this.isTaxRateDTOChanged( - oldTaxRate, - editTaxRateDTO - ); - if (isTaxDTOChanged) { - // Soft deleting the old tax rate. - await TaxRate.query(trx).findById(oldTaxRate.id).delete(); - - // Create a new tax rate with new edited data. - return TaxRate.query(trx).insertAndFetch({ - ...omit(oldTaxRate, ['id']), - ...editTaxRateDTO, - }); - } else { - return TaxRate.query(trx).patchAndFetchById(oldTaxRate.id, { - ...editTaxRateDTO, - }); - } - } - - /** - * Edits the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @param {IEditTaxRateDTO} taxRateEditDTO - * @returns {Promise} - */ - public async editTaxRate( - tenantId: number, - taxRateId: number, - editTaxRateDTO: IEditTaxRateDTO - ) { - const { TaxRate } = this.tenancy.models(tenantId); - - const oldTaxRate = await TaxRate.query().findById(taxRateId); - - // Validates the tax rate existance. - this.validators.validateTaxRateExistance(oldTaxRate); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTaxRateEditing` event. - await this.eventPublisher.emitAsync(events.taxRates.onEditing, { - editTaxRateDTO, - tenantId, - trx, - } as ITaxRateEditingPayload); - - const taxRate = await this.editTaxRateOrCreate( - tenantId, - oldTaxRate, - editTaxRateDTO, - trx - ); - // Triggers `onTaxRateEdited` event. - await this.eventPublisher.emitAsync(events.taxRates.onEdited, { - editTaxRateDTO, - oldTaxRate, - taxRate, - tenantId, - trx, - } as ITaxRateEditedPayload); - - return taxRate; - }); - } -} diff --git a/packages/server/src/services/TaxRates/GetTaxRate.ts b/packages/server/src/services/TaxRates/GetTaxRate.ts deleted file mode 100644 index 5df27a87d..000000000 --- a/packages/server/src/services/TaxRates/GetTaxRate.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { TaxRateTransformer } from './TaxRateTransformer'; - -@Service() -export class GetTaxRateService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private validators: CommandTaxRatesValidators; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @returns {Promise} - */ - public async getTaxRate(tenantId: number, taxRateId: number) { - const { TaxRate } = this.tenancy.models(tenantId); - - const taxRate = await TaxRate.query().findById(taxRateId); - - // Validates the tax rate existance. - this.validators.validateTaxRateExistance(taxRate); - - // Transforms the tax rate. - return this.transformer.transform( - tenantId, - taxRate, - new TaxRateTransformer() - ); - } -} diff --git a/packages/server/src/services/TaxRates/GetTaxRates.ts b/packages/server/src/services/TaxRates/GetTaxRates.ts deleted file mode 100644 index 8fedb1c2d..000000000 --- a/packages/server/src/services/TaxRates/GetTaxRates.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { TaxRateTransformer } from './TaxRateTransformer'; - -@Service() -export class GetTaxRatesService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the tax rates list. - * @param {number} tenantId - * @returns {Promise} - */ - public async getTaxRates(tenantId: number) { - const { TaxRate } = this.tenancy.models(tenantId); - - // Retrieves the tax rates. - const taxRates = await TaxRate.query().orderBy('name', 'ASC'); - - // Transforms the tax rates. - return this.transformer.transform( - tenantId, - taxRates, - new TaxRateTransformer() - ); - } -} diff --git a/packages/server/src/services/TaxRates/InactivateTaxRate.ts b/packages/server/src/services/TaxRates/InactivateTaxRate.ts deleted file mode 100644 index 82ee30a89..000000000 --- a/packages/server/src/services/TaxRates/InactivateTaxRate.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - ITaxRateActivatedPayload, - ITaxRateActivatingPayload, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import UnitOfWork from '../UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { Knex } from 'knex'; -import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; -import events from '@/subscribers/events'; - -@Service() -export class InactivateTaxRateService { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private validators: CommandTaxRatesValidators; - - /** - * Edits the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @param {IEditTaxRateDTO} taxRateEditDTO - * @returns {Promise} - */ - public async inactivateTaxRate(tenantId: number, taxRateId: number) { - const { TaxRate } = this.tenancy.models(tenantId); - - const oldTaxRate = await TaxRate.query().findById(taxRateId); - - // Validates the tax rate existance. - this.validators.validateTaxRateExistance(oldTaxRate); - - // Validates the tax rate active. - this.validators.validateTaxRateNotInactive(oldTaxRate); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTaxRateActivating` event. - await this.eventPublisher.emitAsync(events.taxRates.onInactivating, { - taxRateId, - tenantId, - trx, - } as ITaxRateActivatingPayload); - - const taxRate = await TaxRate.query(trx) - .findById(taxRateId) - .patch({ active: 0 }); - - // Triggers `onTaxRateCreated` event. - await this.eventPublisher.emitAsync(events.taxRates.onInactivated, { - taxRateId, - tenantId, - trx, - } as ITaxRateActivatedPayload); - - return taxRate; - }); - } -} diff --git a/packages/server/src/services/TaxRates/ItemEntriesTaxTransactions.ts b/packages/server/src/services/TaxRates/ItemEntriesTaxTransactions.ts deleted file mode 100644 index 2f4adb0ce..000000000 --- a/packages/server/src/services/TaxRates/ItemEntriesTaxTransactions.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { keyBy, sumBy } from 'lodash'; -import { ItemEntry } from '@/models'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { IItemEntry } from '@/interfaces'; - -@Service() -export class ItemEntriesTaxTransactions { - @Inject() - private tenancy: HasTenancyService; - - /** - * Associates tax amount withheld to the model. - * @param model - * @returns - */ - public assocTaxAmountWithheldFromEntries(model: any) { - const entries = model.entries.map((entry) => ItemEntry.fromJson(entry)); - const taxAmountWithheld = sumBy(entries, 'taxAmount'); - - if (taxAmountWithheld) { - model.taxAmountWithheld = taxAmountWithheld; - } - return model; - } - - /** - * Associates tax rate id from tax code to entries. - * @param {number} tenantId - * @param {} model - */ - public assocTaxRateIdFromCodeToEntries = - (tenantId: number) => async (entries: any) => { - const entriesWithCode = entries.filter((entry) => entry.taxCode); - const taxCodes = entriesWithCode.map((entry) => entry.taxCode); - - const { TaxRate } = this.tenancy.models(tenantId); - const foundTaxCodes = await TaxRate.query().whereIn('code', taxCodes); - - const taxCodesMap = keyBy(foundTaxCodes, 'code'); - - return entries.map((entry) => { - if (entry.taxCode) { - entry.taxRateId = taxCodesMap[entry.taxCode]?.id; - } - return entry; - }); - }; - - /** - * Associates tax rate from tax id to entries. - * @param {number} tenantId - * @returns {Promise} - */ - public assocTaxRateFromTaxIdToEntries = - (tenantId: number) => async (entries: IItemEntry[]) => { - const entriesWithId = entries.filter((e) => e.taxRateId); - const taxRateIds = entriesWithId.map((e) => e.taxRateId); - - const { TaxRate } = this.tenancy.models(tenantId); - const foundTaxes = await TaxRate.query().whereIn('id', taxRateIds); - - const taxRatesMap = keyBy(foundTaxes, 'id'); - - return entries.map((entry) => { - if (entry.taxRateId) { - entry.taxRate = taxRatesMap[entry.taxRateId]?.rate; - } - return entry; - }); - }; -} diff --git a/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts b/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts deleted file mode 100644 index aed00f9b7..000000000 --- a/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Knex } from 'knex'; -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; - -@Service() -export class SyncItemTaxRateOnEditTaxRate { - @Inject() - private tenancy: HasTenancyService; - - /** - * Syncs the new tax rate created to item default sell tax rate. - * @param {number} tenantId - * @param {number} itemId - * @param {number} sellTaxRateId - */ - public updateItemSellTaxRate = async ( - tenantId: number, - oldSellTaxRateId: number, - sellTaxRateId: number, - trx?: Knex.Transaction - ) => { - const { Item } = this.tenancy.models(tenantId); - - // Can't continue if the old and new sell tax rate id are equal. - if (oldSellTaxRateId === sellTaxRateId) return; - - await Item.query().where('sellTaxRateId', oldSellTaxRateId).update({ - sellTaxRateId, - }); - }; - - /** - * Syncs the new tax rate created to item default purchase tax rate. - * @param {number} tenantId - * @param {number} itemId - * @param {number} purchaseTaxRateId - */ - public updateItemPurchaseTaxRate = async ( - tenantId: number, - oldPurchaseTaxRateId: number, - purchaseTaxRateId: number, - trx?: Knex.Transaction - ) => { - const { Item } = this.tenancy.models(tenantId); - - // Can't continue if the old and new sell tax rate id are equal. - if (oldPurchaseTaxRateId === purchaseTaxRateId) return; - - await Item.query(trx) - .where('purchaseTaxRateId', oldPurchaseTaxRateId) - .update({ - purchaseTaxRateId, - }); - }; -} diff --git a/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts b/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts deleted file mode 100644 index 4a7bc9263..000000000 --- a/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { SyncItemTaxRateOnEditTaxRate } from './SyncItemTaxRateOnEditTaxRate'; -import events from '@/subscribers/events'; -import { ITaxRateEditedPayload } from '@/interfaces'; -import { runAfterTransaction } from '../UnitOfWork/TransactionsHooks'; - -@Service() -export class SyncItemTaxRateOnEditTaxSubscriber { - @Inject() - private syncItemRateOnEdit: SyncItemTaxRateOnEditTaxRate; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe( - events.taxRates.onEdited, - this.handleSyncNewTaxRateToItemTaxRate - ); - } - - /** - * Syncs the new tax rate created to default item tax rates. - * @param {ITaxRateEditedPayload} payload - - */ - private handleSyncNewTaxRateToItemTaxRate = async ({ - taxRate, - tenantId, - oldTaxRate, - trx, - }: ITaxRateEditedPayload) => { - runAfterTransaction(trx, async () => { - await this.syncItemRateOnEdit.updateItemPurchaseTaxRate( - tenantId, - oldTaxRate.id, - taxRate.id - ); - await this.syncItemRateOnEdit.updateItemSellTaxRate( - tenantId, - oldTaxRate.id, - taxRate.id - ); - }); - }; -} diff --git a/packages/server/src/services/TaxRates/TaxRateTransformer.ts b/packages/server/src/services/TaxRates/TaxRateTransformer.ts deleted file mode 100644 index 8548245c0..000000000 --- a/packages/server/src/services/TaxRates/TaxRateTransformer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class TaxRateTransformer extends Transformer { - /** - * Include these attributes to tax rate object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['nameFormatted', 'rateFormatted']; - }; - - /** - * Retrieve the formatted rate. - * @param taxRate - * @returns {string} - */ - public rateFormatted = (taxRate): string => { - return `${taxRate.rate}%`; - }; - - /** - * Formats the tax rate name. - * @param taxRate - * @returns {string} - */ - protected nameFormatted = (taxRate): string => { - return `${taxRate.name} [${taxRate.rate}%]`; - }; -} diff --git a/packages/server/src/services/TaxRates/TaxRatesApplication.ts b/packages/server/src/services/TaxRates/TaxRatesApplication.ts deleted file mode 100644 index c237c7251..000000000 --- a/packages/server/src/services/TaxRates/TaxRatesApplication.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ICreateTaxRateDTO, IEditTaxRateDTO } from '@/interfaces'; -import { CreateTaxRate } from './CreateTaxRate'; -import { DeleteTaxRateService } from './DeleteTaxRate'; -import { EditTaxRateService } from './EditTaxRate'; -import { GetTaxRateService } from './GetTaxRate'; -import { GetTaxRatesService } from './GetTaxRates'; -import { ActivateTaxRateService } from './ActivateTaxRate'; -import { InactivateTaxRateService } from './InactivateTaxRate'; - -@Service() -export class TaxRatesApplication { - @Inject() - private createTaxRateService: CreateTaxRate; - - @Inject() - private editTaxRateService: EditTaxRateService; - - @Inject() - private deleteTaxRateService: DeleteTaxRateService; - - @Inject() - private getTaxRateService: GetTaxRateService; - - @Inject() - private getTaxRatesService: GetTaxRatesService; - - @Inject() - private activateTaxRateService: ActivateTaxRateService; - - @Inject() - private inactivateTaxRateService: InactivateTaxRateService; - - /** - * Creates a new tax rate. - * @param {number} tenantId - * @param {ICreateTaxRateDTO} createTaxRateDTO - * @returns {Promise} - */ - public createTaxRate(tenantId: number, createTaxRateDTO: ICreateTaxRateDTO) { - return this.createTaxRateService.createTaxRate(tenantId, createTaxRateDTO); - } - - /** - * Edits the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @param {IEditTaxRateDTO} taxRateEditDTO - * @returns {Promise} - */ - public editTaxRate( - tenantId: number, - taxRateId: number, - editTaxRateDTO: IEditTaxRateDTO - ) { - return this.editTaxRateService.editTaxRate( - tenantId, - taxRateId, - editTaxRateDTO - ); - } - - /** - * Deletes the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @returns {Promise} - */ - public deleteTaxRate(tenantId: number, taxRateId: number) { - return this.deleteTaxRateService.deleteTaxRate(tenantId, taxRateId); - } - - /** - * Retrieves the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - * @returns {Promise} - */ - public getTaxRate(tenantId: number, taxRateId: number) { - return this.getTaxRateService.getTaxRate(tenantId, taxRateId); - } - - /** - * Retrieves the tax rates list. - * @param {number} tenantId - * @returns {Promise} - */ - public getTaxRates(tenantId: number) { - return this.getTaxRatesService.getTaxRates(tenantId); - } - - /** - * Activates the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - */ - public activateTaxRate(tenantId: number, taxRateId: number) { - return this.activateTaxRateService.activateTaxRate(tenantId, taxRateId); - } - - /** - * Inactivates the given tax rate. - * @param {number} tenantId - * @param {number} taxRateId - */ - public inactivateTaxRate(tenantId: number, taxRateId: number) { - return this.inactivateTaxRateService.inactivateTaxRate(tenantId, taxRateId); - } -} diff --git a/packages/server/src/services/TaxRates/TaxRatesExportable.ts b/packages/server/src/services/TaxRates/TaxRatesExportable.ts deleted file mode 100644 index 096a36698..000000000 --- a/packages/server/src/services/TaxRates/TaxRatesExportable.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Exportable } from '../Export/Exportable'; -import { TaxRatesApplication } from './TaxRatesApplication'; - -@Service() -export class TaxRatesExportable extends Exportable { - @Inject() - private taxRatesApplication: TaxRatesApplication; - - /** - * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns - */ - public exportable(tenantId: number) { - return this.taxRatesApplication.getTaxRates(tenantId); - } -} diff --git a/packages/server/src/services/TaxRates/TaxRatesImportable.SampleData.ts b/packages/server/src/services/TaxRates/TaxRatesImportable.SampleData.ts deleted file mode 100644 index 0a7fe389d..000000000 --- a/packages/server/src/services/TaxRates/TaxRatesImportable.SampleData.ts +++ /dev/null @@ -1,18 +0,0 @@ -export const TaxRatesSampleData = [ - { - 'Tax Name': 'Value Added Tax', - Code: 'VAT-STD', - Rate: '20', - Description: 'Standard VAT rate applied to most goods and services.', - 'Is Non Recoverable': 'F', - Active: 'T', - }, - { - 'Tax Name': 'Luxury Goods Tax', - Code: 'TAX-LUXURY', - Rate: '25', - Description: 'Tax imposed on the sale of luxury items.', - 'Is Non Recoverable': 'T', - Active: 'T', - }, -]; diff --git a/packages/server/src/services/TaxRates/TaxRatesImportable.ts b/packages/server/src/services/TaxRates/TaxRatesImportable.ts deleted file mode 100644 index 5f0ab4185..000000000 --- a/packages/server/src/services/TaxRates/TaxRatesImportable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import { ICreateTaxRateDTO } from '@/interfaces'; -import { CreateTaxRate } from './CreateTaxRate'; -import { Importable } from '../Import/Importable'; -import { TaxRatesSampleData } from './TaxRatesImportable.SampleData'; - -@Service() -export class TaxRatesImportable extends Importable { - @Inject() - private createTaxRateService: CreateTaxRate; - - /** - * Importing to tax rate creating service. - * @param {number} tenantId - - * @param {ICreateTaxRateDTO} ICreateTaxRateDTO - - * @param {Knex.Transaction} trx - - * @returns - */ - public importable( - tenantId: number, - createAccountDTO: ICreateTaxRateDTO, - trx?: Knex.Transaction - ) { - return this.createTaxRateService.createTaxRate( - tenantId, - createAccountDTO, - trx - ); - } - - /** - * Concurrrency controlling of the importing process. - * @returns {number} - */ - public get concurrency() { - return 1; - } - - /** - * Retrieves the sample data that used to download accounts sample sheet. - */ - public sampleData(): any[] { - return TaxRatesSampleData; - } -} diff --git a/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts b/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts deleted file mode 100644 index 0e00471c8..000000000 --- a/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { sumBy, chain, keyBy } from 'lodash'; -import { IItemEntry, ITaxTransaction } from '@/interfaces'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; - -@Service() -export class WriteTaxTransactionsItemEntries { - @Inject() - private tenancy: HasTenancyService; - - /** - * Writes the tax transactions from the given item entries. - * @param {number} tenantId - * @param {IItemEntry[]} itemEntries - */ - public async writeTaxTransactionsFromItemEntries( - tenantId: number, - itemEntries: IItemEntry[], - trx?: Knex.Transaction - ) { - const { TaxRateTransaction, TaxRate } = this.tenancy.models(tenantId); - const aggregatedEntries = this.aggregateItemEntriesByTaxCode(itemEntries); - - const entriesTaxRateIds = aggregatedEntries.map((entry) => entry.taxRateId); - - const taxRates = await TaxRate.query(trx).whereIn('id', entriesTaxRateIds); - const taxRatesById = keyBy(taxRates, 'id'); - - const taxTransactions = aggregatedEntries.map((entry) => ({ - taxRateId: entry.taxRateId, - referenceType: entry.referenceType, - referenceId: entry.referenceId, - rate: entry.taxRate || taxRatesById[entry.taxRateId]?.rate, - })) as ITaxTransaction[]; - - await TaxRateTransaction.query(trx).upsertGraph(taxTransactions); - } - - /** - * Rewrites the tax rate transactions from the given item entries. - * @param {number} tenantId - * @param {IItemEntry[]} itemEntries - * @param {string} referenceType - * @param {number} referenceId - * @param {Knex.Transaction} trx - */ - public async rewriteTaxRateTransactionsFromItemEntries( - tenantId: number, - itemEntries: IItemEntry[], - referenceType: string, - referenceId: number, - trx?: Knex.Transaction - ) { - await Promise.all([ - this.removeTaxTransactionsFromItemEntries( - tenantId, - referenceId, - referenceType, - trx - ), - this.writeTaxTransactionsFromItemEntries(tenantId, itemEntries, trx), - ]); - } - - /** - * Aggregates by tax code id and sums the amount. - * @param {IItemEntry[]} itemEntries - * @returns {IItemEntry[]} - */ - private aggregateItemEntriesByTaxCode = ( - itemEntries: IItemEntry[] - ): IItemEntry[] => { - return chain(itemEntries.filter((item) => item.taxRateId)) - .groupBy((item) => item.taxRateId) - .values() - .map((group) => ({ ...group[0], amount: sumBy(group, 'amount') })) - .value(); - }; - - /** - * Removes the tax transactions from the given item entries. - * @param {number} tenantId - Tenant id. - * @param {string} referenceType - Reference type. - * @param {number} referenceId - Reference id. - */ - public async removeTaxTransactionsFromItemEntries( - tenantId: number, - referenceId: number, - referenceType: string, - trx?: Knex.Transaction - ) { - const { TaxRateTransaction } = this.tenancy.models(tenantId); - - await TaxRateTransaction.query(trx) - .where({ referenceType, referenceId }) - .delete(); - } -} diff --git a/packages/server/src/services/TaxRates/constants.ts b/packages/server/src/services/TaxRates/constants.ts deleted file mode 100644 index e1553f4ee..000000000 --- a/packages/server/src/services/TaxRates/constants.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const ERRORS = { - TAX_RATE_NOT_FOUND: 'TAX_RATE_NOT_FOUND', - TAX_CODE_NOT_UNIQUE: 'TAX_CODE_NOT_UNIQUE', - ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND: 'ITEM_ENTRY_TAX_RATE_CODE_NOT_FOUND', - ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND: 'ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND', - TAX_RATE_ALREADY_ACTIVE: 'TAX_RATE_ALREADY_ACTIVE', - TAX_RATE_ALREADY_INACTIVE: 'TAX_RATE_ALREADY_INACTIVE' -}; diff --git a/packages/server/src/services/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts deleted file mode 100644 index 9850e0648..000000000 --- a/packages/server/src/services/TaxRates/subscribers/BillTaxRateValidateSubscriber.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IBillCreatingPayload, IBillEditingPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandTaxRatesValidators } from '../CommandTaxRatesValidators'; - -@Service() -export class BillTaxRateValidateSubscriber { - @Inject() - private taxRateDTOValidator: CommandTaxRatesValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.bill.onCreating, - this.validateBillEntriesTaxCodeExistanceOnCreating - ); - bus.subscribe( - events.bill.onCreating, - this.validateBillEntriesTaxIdExistanceOnCreating - ); - bus.subscribe( - events.bill.onEditing, - this.validateBillEntriesTaxCodeExistanceOnEditing - ); - bus.subscribe( - events.bill.onEditing, - this.validateBillEntriesTaxIdExistanceOnEditing - ); - return bus; - } - - /** - * Validate bill entries tax rate code existance when creating. - * @param {IBillCreatingPayload} - */ - private validateBillEntriesTaxCodeExistanceOnCreating = async ({ - billDTO, - tenantId, - }: IBillCreatingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - billDTO.entries - ); - }; - - /** - * Validate the tax rate id existance when creating. - * @param {IBillCreatingPayload} - */ - private validateBillEntriesTaxIdExistanceOnCreating = async ({ - billDTO, - tenantId, - }: IBillCreatingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCodeId( - tenantId, - billDTO.entries - ); - }; - - /** - * Validate bill entries tax rate code existance when editing. - * @param {IBillEditingPayload} - */ - private validateBillEntriesTaxCodeExistanceOnEditing = async ({ - tenantId, - billDTO, - }: IBillEditingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - billDTO.entries - ); - }; - - /** - * Validates the bill entries tax rate id existance when editing. - * @param {ISaleInvoiceEditingPayload} payload - - */ - private validateBillEntriesTaxIdExistanceOnEditing = async ({ - tenantId, - billDTO, - }: IBillEditingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCodeId( - tenantId, - billDTO.entries - ); - }; -} diff --git a/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts deleted file mode 100644 index 9a120629c..000000000 --- a/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleInvoiceCreatingPaylaod, - ISaleInvoiceEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandTaxRatesValidators } from '../CommandTaxRatesValidators'; - -@Service() -export class SaleInvoiceTaxRateValidateSubscriber { - @Inject() - private taxRateDTOValidator: CommandTaxRatesValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreating, - this.validateSaleInvoiceEntriesTaxCodeExistanceOnCreating - ); - bus.subscribe( - events.saleInvoice.onCreating, - this.validateSaleInvoiceEntriesTaxIdExistanceOnCreating - ); - bus.subscribe( - events.saleInvoice.onEditing, - this.validateSaleInvoiceEntriesTaxCodeExistanceOnEditing - ); - bus.subscribe( - events.saleInvoice.onEditing, - this.validateSaleInvoiceEntriesTaxIdExistanceOnEditing - ); - return bus; - } - - /** - * Validate invoice entries tax rate code existance when creating. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private validateSaleInvoiceEntriesTaxCodeExistanceOnCreating = async ({ - saleInvoiceDTO, - tenantId, - }: ISaleInvoiceCreatingPaylaod) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - saleInvoiceDTO.entries - ); - }; - - /** - * Validate the tax rate id existance when creating. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private validateSaleInvoiceEntriesTaxIdExistanceOnCreating = async ({ - saleInvoiceDTO, - tenantId, - }: ISaleInvoiceCreatingPaylaod) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCodeId( - tenantId, - saleInvoiceDTO.entries - ); - }; - - /** - * Validate invoice entries tax rate code existance when editing. - * @param {ISaleInvoiceEditingPayload} - */ - private validateSaleInvoiceEntriesTaxCodeExistanceOnEditing = async ({ - tenantId, - saleInvoiceDTO, - }: ISaleInvoiceEditingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - saleInvoiceDTO.entries - ); - }; - - /** - * Validates the invoice entries tax rate id existance when editing. - * @param {ISaleInvoiceEditingPayload} payload - - */ - private validateSaleInvoiceEntriesTaxIdExistanceOnEditing = async ({ - tenantId, - saleInvoiceDTO, - }: ISaleInvoiceEditingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCodeId( - tenantId, - saleInvoiceDTO.entries - ); - }; -} diff --git a/packages/server/src/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts deleted file mode 100644 index fc74c0686..000000000 --- a/packages/server/src/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IBIllEventDeletedPayload, - IBillCreatedPayload, - IBillEditedPayload, - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WriteTaxTransactionsItemEntries } from '../WriteTaxTransactionsItemEntries'; - -@Service() -export class WriteBillTaxTransactionsSubscriber { - @Inject() - private writeTaxTransactions: WriteTaxTransactionsItemEntries; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.bill.onCreated, - this.writeInvoiceTaxTransactionsOnCreated - ); - bus.subscribe( - events.bill.onEdited, - this.rewriteInvoiceTaxTransactionsOnEdited - ); - bus.subscribe( - events.bill.onDeleted, - this.removeInvoiceTaxTransactionsOnDeleted - ); - return bus; - } - - /** - * Writes the bill tax transactions on invoice created. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private writeInvoiceTaxTransactionsOnCreated = async ({ - tenantId, - bill, - trx, - }: IBillCreatedPayload) => { - await this.writeTaxTransactions.writeTaxTransactionsFromItemEntries( - tenantId, - bill.entries, - trx - ); - }; - - /** - * Rewrites the bill tax transactions on invoice edited. - * @param {IBillEditedPayload} payload - - */ - private rewriteInvoiceTaxTransactionsOnEdited = async ({ - tenantId, - bill, - trx, - }: IBillEditedPayload) => { - await this.writeTaxTransactions.rewriteTaxRateTransactionsFromItemEntries( - tenantId, - bill.entries, - 'Bill', - bill.id, - trx - ); - }; - - /** - * Removes the invoice tax transactions on invoice deleted. - * @param {IBIllEventDeletedPayload} - */ - private removeInvoiceTaxTransactionsOnDeleted = async ({ - tenantId, - oldBill, - trx, - }: IBIllEventDeletedPayload) => { - await this.writeTaxTransactions.removeTaxTransactionsFromItemEntries( - tenantId, - oldBill.id, - 'Bill', - trx - ); - }; -} diff --git a/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts deleted file mode 100644 index b65dd7904..000000000 --- a/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WriteTaxTransactionsItemEntries } from '../WriteTaxTransactionsItemEntries'; - -@Service() -export class WriteInvoiceTaxTransactionsSubscriber { - @Inject() - private writeTaxTransactions: WriteTaxTransactionsItemEntries; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.writeInvoiceTaxTransactionsOnCreated - ); - bus.subscribe( - events.saleInvoice.onEdited, - this.rewriteInvoiceTaxTransactionsOnEdited - ); - bus.subscribe( - events.saleInvoice.onDelete, - this.removeInvoiceTaxTransactionsOnDeleted - ); - return bus; - } - - /** - * Writes the invoice tax transactions on invoice created. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private writeInvoiceTaxTransactionsOnCreated = async ({ - tenantId, - saleInvoice, - trx - }: ISaleInvoiceCreatedPayload) => { - await this.writeTaxTransactions.writeTaxTransactionsFromItemEntries( - tenantId, - saleInvoice.entries, - trx - ); - }; - - /** - * Rewrites the invoice tax transactions on invoice edited. - * @param {ISaleInvoiceEditedPayload} payload - - */ - private rewriteInvoiceTaxTransactionsOnEdited = async ({ - tenantId, - saleInvoice, - trx, - }: ISaleInvoiceEditedPayload) => { - await this.writeTaxTransactions.rewriteTaxRateTransactionsFromItemEntries( - tenantId, - saleInvoice.entries, - 'SaleInvoice', - saleInvoice.id, - trx - ); - }; - - /** - * Removes the invoice tax transactions on invoice deleted. - * @param {ISaleInvoiceEditingPayload} - */ - private removeInvoiceTaxTransactionsOnDeleted = async ({ - tenantId, - oldSaleInvoice, - trx - }: ISaleInvoiceDeletedPayload) => { - await this.writeTaxTransactions.removeTaxTransactionsFromItemEntries( - tenantId, - oldSaleInvoice.id, - 'SaleInvoice', - trx - ); - }; -} diff --git a/packages/server/src/services/TemplateInjectable/TemplateInjectable.ts b/packages/server/src/services/TemplateInjectable/TemplateInjectable.ts deleted file mode 100644 index 31e059ae3..000000000 --- a/packages/server/src/services/TemplateInjectable/TemplateInjectable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '../Tenancy/TenancyService'; -import { templateRender } from '@/utils'; -import { Tenant } from '@/system/models'; - -@Service() -export class TemplateInjectable { - @Inject() - private tenancy: HasTenancyService; - - /** - * Renders the given filename of the template. - * @param {number} tenantId - * @param {string} filename - * @returns {string} - */ - public async render( - tenantId: number, - filename: string, - options: Record - ) { - const i18n = this.tenancy.i18n(tenantId); - - const organization = await Tenant.query() - .findById(tenantId) - .withGraphFetched('metadata'); - - return templateRender(filename, { - organizationName: organization.metadata.name, - organizationEmail: organization.metadata.email, - __: i18n.__, - ...options - }); - } -} diff --git a/packages/server/src/services/Tenancy/SystemService.ts b/packages/server/src/services/Tenancy/SystemService.ts deleted file mode 100644 index d03aec13c..000000000 --- a/packages/server/src/services/Tenancy/SystemService.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Container from 'typedi'; -import { Service } from 'typedi'; - -@Service() -export default class HasSystemService implements SystemService { - private container(key: string) { - return Container.get(key); - } - - knex() { - return this.container('knex'); - } - - repositories() { - return this.container('repositories'); - } - - cache() { - return this.container('cache'); - } -} diff --git a/packages/server/src/services/Tenancy/TenancyService.ts b/packages/server/src/services/Tenancy/TenancyService.ts deleted file mode 100644 index 213b2d9c9..000000000 --- a/packages/server/src/services/Tenancy/TenancyService.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Container, Service, Inject } from 'typedi'; -import TenantsManagerService from '@/services/Tenancy/TenantsManager'; -import tenantModelsLoader from '@/loaders/tenantModels'; -import tenantRepositoriesLoader from '@/loaders/tenantRepositories'; -import tenantCacheLoader from '@/loaders/tenantCache'; -import SmsClientLoader from '@/loaders/smsClient'; - -@Service() -export default class HasTenancyService { - @Inject() - tenantsManager: TenantsManagerService; - - /** - * Retrieve the given tenant container. - * @param {number} tenantId - * @return {Container} - */ - tenantContainer(tenantId: number) { - return Container.of(`tenant-${tenantId}`); - } - - /** - * Singleton tenant service. - * @param {number} tenantId - Tenant id. - * @param {string} key - Service key. - * @param {Function} callback - */ - singletonService(tenantId: number, key: string, callback: Function) { - const container = this.tenantContainer(tenantId); - const Logger = Container.get('logger'); - const hasServiceInstnace = container.has(key); - - if (!hasServiceInstnace) { - const serviceInstance = callback(); - - container.set(key, serviceInstance); - Logger.info(`[tenant_DI] ${key} injected to tenant container.`, { - tenantId, - key, - }); - - return serviceInstance; - } else { - return container.get(key); - } - } - - /** - * Retrieve knex instance of the given tenant id. - * @param {number} tenantId - */ - knex(tenantId: number) { - return this.singletonService(tenantId, 'tenantManager', () => { - return this.tenantsManager.getKnexInstance(tenantId); - }); - } - - /** - * Retrieve models of the givne tenant id. - * @param {number} tenantId - The tenant id. - */ - models(tenantId: number) { - const knexInstance = this.knex(tenantId); - - return this.singletonService(tenantId, 'models', () => { - return tenantModelsLoader(knexInstance); - }); - } - - /** - * Retrieve repositories of the given tenant id. - * @param {number} tenantId - Tenant id. - */ - repositories(tenantId: number) { - return this.singletonService(tenantId, 'repositories', () => { - const cache = this.cache(tenantId); - const knex = this.knex(tenantId); - const i18n = this.i18n(tenantId); - - const repositories = tenantRepositoriesLoader(knex, cache, i18n); - - Object.values(repositories).forEach((repository) => { - repository.setTenantId(tenantId); - }); - return repositories; - }); - } - - /** - * Sets i18n locals function. - * @param {number} tenantId - * @param locals - */ - setI18nLocals(tenantId: number, locals: any) { - return this.singletonService(tenantId, 'i18n', () => { - return locals; - }); - } - - /** - * Retrieve i18n locales methods. - * @param {number} tenantId - Tenant id. - */ - i18n(tenantId: number) { - return this.singletonService(tenantId, 'i18n', () => { - throw new Error('I18n locals is not set yet.'); - }); - } - - /** - * Retrieve tenant cache instance. - * @param {number} tenantId - Tenant id. - */ - cache(tenantId: number) { - return this.singletonService(tenantId, 'cache', () => { - return tenantCacheLoader(tenantId); - }); - } - - settings(tenantId: number) { - return this.singletonService(tenantId, 'settings', () => { - throw new Error('Settings is not injected yet.'); - }); - } - - smsClient(tenantId: number) { - return this.singletonService(tenantId, 'smsClient', () => { - const settings = this.settings(tenantId); - - const token = settings.get({ - group: 'sms_integration', - key: 'easysms_token', - }); - return SmsClientLoader(token); - }); - } -} diff --git a/packages/server/src/services/Tenancy/TenantDBManager.ts b/packages/server/src/services/Tenancy/TenantDBManager.ts deleted file mode 100644 index a234e5c3b..000000000 --- a/packages/server/src/services/Tenancy/TenantDBManager.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Container } from 'typedi'; -import { Knex, knex } from 'knex'; -import { knexSnakeCaseMappers } from 'objection'; -import { tenantKnexConfig, tenantSeedConfig } from '@/config/knexConfig'; -import config from '@/config'; -import { ITenant, ITenantDBManager } from '@/interfaces'; -import SystemService from '@/services/Tenancy/SystemService'; -import { TenantDBAlreadyExists } from '@/exceptions'; -import { sanitizeDatabaseName } from '@/utils/sanitizers'; - -export default class TenantDBManager implements ITenantDBManager { - static knexCache: { [key: string]: Knex } = {}; - - // System knex instance. - sysKnex: Knex; - - /** - * Constructor method. - * @param {ITenant} tenant - */ - constructor() { - const systemService = Container.get(SystemService); - - this.sysKnex = systemService.knex(); - } - - /** - * Retrieve the tenant database name. - * @return {string} - */ - private getDatabaseName(tenant: ITenant) { - return sanitizeDatabaseName( - `${config.tenant.db_name_prefix}${tenant.organizationId}` - ); - } - - /** - * Detarmines the tenant database weather exists. - * @return {Promise} - */ - public async databaseExists(tenant: ITenant) { - const databaseName = this.getDatabaseName(tenant); - - const results = await this.sysKnex.raw( - 'SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = "' + - databaseName + - '"' - ); - return results[0].length > 0; - } - - /** - * Creates a tenant database. - * @throws {TenantAlreadyInitialized} - * @return {Promise} - */ - public async createDatabase(tenant: ITenant): Promise { - await this.throwErrorIfTenantDBExists(tenant); - - const databaseName = this.getDatabaseName(tenant); - await this.sysKnex.raw( - `CREATE DATABASE ${databaseName} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci` - ); - } - - /** - * Dropdowns the tenant database if it was exist. - * @param {ITenant} tenant - - */ - public async dropDatabaseIfExists(tenant: ITenant) { - const isExists = await this.databaseExists(tenant); - - if (!isExists) { - return; - } - await this.dropDatabase(tenant); - } - - /** - * dropdowns the tenant's database. - * @param {ITenant} tenant - */ - public async dropDatabase(tenant: ITenant) { - const databaseName = this.getDatabaseName(tenant); - - await this.sysKnex.raw(`DROP DATABASE IF EXISTS ${databaseName}`); - } - - /** - * Migrate tenant database schema to the latest version. - * @return {Promise} - */ - public async migrate(tenant: ITenant): Promise { - const knex = this.setupKnexInstance(tenant); - - await knex.migrate.latest(); - } - - /** - * Seeds initial data to the tenant database. - * @return {Promise} - */ - public async seed(tenant: ITenant): Promise { - const knex = this.setupKnexInstance(tenant); - - await knex.migrate.latest({ - ...tenantSeedConfig(tenant), - disableMigrationsListValidation: true, - }); - } - - /** - * Retrieve the knex instance of tenant. - * @return {Knex} - */ - public setupKnexInstance(tenant: ITenant) { - const key: string = `${tenant.id}`; - let knexInstance = TenantDBManager.knexCache[key]; - - if (!knexInstance) { - knexInstance = knex({ - ...tenantKnexConfig(tenant), - ...knexSnakeCaseMappers({ upperCase: true }), - }); - TenantDBManager.knexCache[key] = knexInstance; - } - return knexInstance; - } - - /** - * Retrieve knex instance from the givne tenant. - */ - public getKnexInstance(tenantId: number) { - const key: string = `${tenantId}`; - let knexInstance = TenantDBManager.knexCache[key]; - - if (!knexInstance) { - throw new Error('Knex instance is not initialized yut.'); - } - return knexInstance; - } - - /** - * Throws error if the tenant database already exists. - * @return {Promise} - */ - async throwErrorIfTenantDBExists(tenant: ITenant) { - const isExists = await this.databaseExists(tenant); - if (isExists) { - throw new TenantDBAlreadyExists(); - } - } -} diff --git a/packages/server/src/services/Tenancy/TenantService.ts b/packages/server/src/services/Tenancy/TenantService.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/src/services/Tenancy/TenantsManager.ts b/packages/server/src/services/Tenancy/TenantsManager.ts deleted file mode 100644 index f152fc6ad..000000000 --- a/packages/server/src/services/Tenancy/TenantsManager.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { Container, Inject, Service } from 'typedi'; -import { ITenantManager, ITenant, ITenantDBManager } from '@/interfaces'; -import { - EventDispatcherInterface, - EventDispatcher, -} from 'decorators/eventDispatcher'; -import { - TenantAlreadyInitialized, - TenantAlreadySeeded, - TenantDatabaseNotBuilt, -} from '@/exceptions'; -import TenantDBManager from '@/services/Tenancy/TenantDBManager'; -import events from '@/subscribers/events'; -import { Tenant } from '@/system/models'; -import { SeedMigration } from '@/lib/Seeder/SeedMigration'; -import i18n from '../../loaders/i18n'; - -const ERRORS = { - TENANT_ALREADY_CREATED: 'TENANT_ALREADY_CREATED', - TENANT_NOT_EXISTS: 'TENANT_NOT_EXISTS', -}; - -// Tenants manager service. -@Service() -export default class TenantsManagerService implements ITenantManager { - static instances: { [key: number]: ITenantManager } = {}; - - @EventDispatcher() - private eventDispatcher: EventDispatcherInterface; - - @Inject('repositories') - private sysRepositories: any; - - private tenantDBManager: ITenantDBManager; - - /** - * Constructor method. - */ - constructor() { - this.tenantDBManager = new TenantDBManager(); - } - - /** - * Creates a new teant with unique organization id. - * @param {ITenant} tenant - * @return {Promise} - */ - public async createTenant(): Promise { - const { tenantRepository } = this.sysRepositories; - const tenant = await tenantRepository.createWithUniqueOrgId(); - - return tenant; - } - - /** - * Creates a new tenant database. - * @param {ITenant} tenant - - * @return {Promise} - */ - public async createDatabase(tenant: ITenant): Promise { - this.throwErrorIfTenantAlreadyInitialized(tenant); - - await this.tenantDBManager.createDatabase(tenant); - - this.eventDispatcher.dispatch(events.tenantManager.databaseCreated); - } - - /** - * Drops the database if the given tenant. - * @param {number} tenantId - */ - async dropDatabaseIfExists(tenant: ITenant) { - // Drop the database if exists. - await this.tenantDBManager.dropDatabaseIfExists(tenant); - } - - /** - * Detarmines the tenant has database. - * @param {ITenant} tenant - * @returns {Promise} - */ - public async hasDatabase(tenant: ITenant): Promise { - return this.tenantDBManager.databaseExists(tenant); - } - - /** - * Migrates the tenant database. - * @param {ITenant} tenant - * @return {Promise} - */ - public async migrateTenant(tenant: ITenant): Promise { - // Throw error if the tenant already initialized. - this.throwErrorIfTenantAlreadyInitialized(tenant); - - // Migrate the database tenant. - await this.tenantDBManager.migrate(tenant); - - // Mark the tenant as initialized. - await Tenant.markAsInitialized(tenant.id); - - // Triggers `onTenantMigrated` event. - this.eventDispatcher.dispatch(events.tenantManager.tenantMigrated, { - tenantId: tenant.id, - }); - } - - /** - * Seeds the tenant database. - * @param {ITenant} tenant - * @return {Promise} - */ - public async seedTenant(tenant: ITenant, tenancyContext): Promise { - // Throw error if the tenant is not built yet. - this.throwErrorIfTenantNotBuilt(tenant); - - // Throw error if the tenant is not seeded yet. - this.throwErrorIfTenantAlreadySeeded(tenant); - - // Seeds the organization database data. - await new SeedMigration(tenancyContext.knex, tenancyContext).latest(); - - // Mark the tenant as seeded in specific date. - await Tenant.markAsSeeded(tenant.id); - - // Triggers `onTenantSeeded` event. - this.eventDispatcher.dispatch(events.tenantManager.tenantSeeded, { - tenantId: tenant.id, - }); - } - - /** - * Initialize knex instance or retrieve the instance of cache map. - * @param {ITenant} tenant - * @returns {Knex} - */ - public setupKnexInstance(tenant: ITenant) { - return this.tenantDBManager.setupKnexInstance(tenant); - } - - /** - * Retrieve tenant knex instance or throw error in case was not initialized. - * @param {number} tenantId - * @returns {Knex} - */ - public getKnexInstance(tenantId: number) { - return this.tenantDBManager.getKnexInstance(tenantId); - } - - /** - * Throws error if the tenant already seeded. - * @throws {TenantAlreadySeeded} - */ - private throwErrorIfTenantAlreadySeeded(tenant: ITenant) { - if (tenant.seededAt) { - throw new TenantAlreadySeeded(); - } - } - - /** - * Throws error if the tenant database is not built yut. - * @param {ITenant} tenant - */ - private throwErrorIfTenantNotBuilt(tenant: ITenant) { - if (!tenant.initializedAt) { - throw new TenantDatabaseNotBuilt(); - } - } - - /** - * Throws error if the tenant already migrated. - * @throws {TenantAlreadyInitialized} - */ - private throwErrorIfTenantAlreadyInitialized(tenant: ITenant) { - if (tenant.initializedAt) { - throw new TenantAlreadyInitialized(); - } - } - - /** - * Initialize seed migration contxt. - * @param {ITenant} tenant - * @returns - */ - public getSeedMigrationContext(tenant: ITenant) { - // Initialize the knex instance. - const knex = this.setupKnexInstance(tenant); - const i18nInstance = i18n(); - - i18nInstance.setLocale(tenant.metadata.language); - - return { - knex, - i18n: i18nInstance, - tenant, - }; - } -} diff --git a/packages/server/src/services/TransactionsLocking/CommandTransactionsLockingService.ts b/packages/server/src/services/TransactionsLocking/CommandTransactionsLockingService.ts deleted file mode 100644 index 23722822f..000000000 --- a/packages/server/src/services/TransactionsLocking/CommandTransactionsLockingService.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - ICancelTransactionsLockingDTO, - ITransactionLockingPartiallyDTO, - ITransactionMeta, - ITransactionsLockingAllDTO, - ITransactionsLockingCanceled, - ITransactionsLockingPartialUnlocked, - TransactionsLockingGroup, - TransactionsLockingType, -} from '@/interfaces'; -import TransactionsLockingRepository from './TransactionsLockingRepository'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; - -const Modules = ['all', 'sales', 'purchases', 'financial']; - -@Service() -export default class TransactionsLockingService { - @Inject() - tenancy: HasTenancyService; - - @Inject() - transactionsLockingRepo: TransactionsLockingRepository; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Enable/disable all transacations locking. - * @param {number} tenantId - * @param {TransactionsLockingGroup} moduleGroup - - * @param {Partial} allLockingDTO - * @returns {Promise} - */ - public commandTransactionsLocking = async ( - tenantId: number, - module: TransactionsLockingGroup = TransactionsLockingGroup.All, - transactionLockingDTO: Partial - ): Promise => { - // Validate the transaction locking module. - this.validateTransactionsLockingModule(module); - - // Saves all transactions locking settings. - await this.transactionsLockingRepo.saveTransactionsLocking( - tenantId, - module, - { - active: true, - lockToDate: transactionLockingDTO.lockToDate, - lockReason: transactionLockingDTO.reason, - } - ); - // Flag transactions locking type. - await this.transactionsLockingRepo.flagTransactionsLockingType( - tenantId, - module === TransactionsLockingGroup.All - ? TransactionsLockingType.All - : TransactionsLockingType.Partial - ); - // Triggers `onTransactionLockingPartialUnlocked` event. - await this.eventPublisher.emitAsync( - events.transactionsLocking.partialUnlocked, - { - tenantId, - module, - transactionLockingDTO, - } as ITransactionsLockingPartialUnlocked - ); - // Retrieve the transaction locking meta of the given - return this.transactionsLockingRepo.getTransactionsLocking( - tenantId, - module - ); - }; - - /** - * Cancels the full transactions locking. - * @param {number} tenantId - * @param {TransactionsLockingGroup} moduleGroup - * @param {ICancelTransactionsLockingDTO} cancelLockingDTO - * @returns {Promise} - */ - public cancelTransactionLocking = async ( - tenantId: number, - module: TransactionsLockingGroup = TransactionsLockingGroup.All, - cancelLockingDTO: ICancelTransactionsLockingDTO - ): Promise => { - // Validate the transaction locking module. - this.validateTransactionsLockingModule(module); - - // Saves transactions locking. - await this.transactionsLockingRepo.saveTransactionsLocking( - tenantId, - module, - { - active: false, - unlockFromDate: '', - unlockToDate: '', - unlockReason: cancelLockingDTO.reason, - } - ); - // Reset flag transactions locking type to partial. - await this.transactionsLockingRepo.flagTransactionsLockingType( - tenantId, - TransactionsLockingType.Partial - ); - // Triggers `onTransactionLockingPartialUnlocked` event. - await this.eventPublisher.emitAsync( - events.transactionsLocking.partialUnlocked, - { - tenantId, - module, - cancelLockingDTO, - } as ITransactionsLockingCanceled - ); - return this.transactionsLockingRepo.getTransactionsLocking( - tenantId, - module - ); - }; - - /** - * Unlock tranactions locking partially. - * @param {number} tenantId - * @param {TransactionsLockingGroup} moduleGroup - * @param {ITransactionLockingPartiallyDTO} partialTransactionLockingDTO - * @returns {Promise} - */ - public unlockTransactionsLockingPartially = async ( - tenantId: number, - moduleGroup: TransactionsLockingGroup = TransactionsLockingGroup.All, - partialTransactionLockingDTO: ITransactionLockingPartiallyDTO - ): Promise => { - // Validate the transaction locking module. - this.validateTransactionsLockingModule(moduleGroup); - - // Retrieve the current transactions locking type. - const lockingType = - this.transactionsLockingRepo.getTransactionsLockingType(tenantId); - - if (moduleGroup !== TransactionsLockingGroup.All) { - this.validateLockingTypeNotAll(lockingType); - } - // Saves transactions locking settings. - await this.transactionsLockingRepo.saveTransactionsLocking( - tenantId, - moduleGroup, - { - ...omit(partialTransactionLockingDTO, ['reason']), - partialUnlockReason: partialTransactionLockingDTO.reason, - } - ); - // Retrieve transaction locking meta of the given module. - return this.transactionsLockingRepo.getTransactionsLocking( - tenantId, - moduleGroup - ); - }; - - /** - * Cancel partial transactions unlocking. - * @param {number} tenantId - * @param {TransactionsLockingGroup} moduleGroup - */ - public cancelPartialTransactionsUnlock = async ( - tenantId: number, - module: TransactionsLockingGroup = TransactionsLockingGroup.All - ) => { - // Validate the transaction locking module. - this.validateTransactionsLockingModule(module); - - // Saves transactions locking settings. - await this.transactionsLockingRepo.saveTransactionsLocking( - tenantId, - module, - { unlockFromDate: '', unlockToDate: '', partialUnlockReason: '' } - ); - }; - - /** - * Validates the transaction locking type not partial. - * @param {number} tenantId - */ - public validateLockingTypeNotPartial = (lockingType: string) => { - if (lockingType === TransactionsLockingType.Partial) { - throw new ServiceError(ERRORS.TRANSACTION_LOCKING_PARTIAL); - } - }; - - /** - * Validates the transaction locking type not all. - * @param {number} tenantId - */ - public validateLockingTypeNotAll = (lockingType: string) => { - if (lockingType === TransactionsLockingType.All) { - throw new ServiceError(ERRORS.TRANSACTION_LOCKING_ALL); - } - }; - - /** - * Validate transactions locking module. - * @param {string} module - */ - public validateTransactionsLockingModule = (module: string) => { - if (Modules.indexOf(module) === -1) { - throw new ServiceError(ERRORS.TRANSACTIONS_LOCKING_MODULE_NOT_FOUND); - } - }; -} diff --git a/packages/server/src/services/TransactionsLocking/FinancialTransactionLockingGuard.ts b/packages/server/src/services/TransactionsLocking/FinancialTransactionLockingGuard.ts deleted file mode 100644 index 5cc2e8b45..000000000 --- a/packages/server/src/services/TransactionsLocking/FinancialTransactionLockingGuard.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TransactionsLockingGuard from './TransactionsLockingGuard'; -import { TransactionsLockingGroup } from '@/interfaces'; - -@Service() -export default class FinancialTransactionLocking { - @Inject() - transactionLockingGuardService: TransactionsLockingGuard; - - /** - * Validates the transaction locking of cashflow command action. - * @param {number} tenantId - * @param {Date} transactionDate - * @throws {ServiceError(TRANSACTIONS_DATE_LOCKED)} - */ - public transactionLockingGuard = ( - tenantId: number, - transactionDate: Date - ) => { - this.transactionLockingGuardService.transactionsLockingGuard( - tenantId, - transactionDate, - TransactionsLockingGroup.Financial - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/FinancialsTransactionLockingGuardSubscriber.ts b/packages/server/src/services/TransactionsLocking/FinancialsTransactionLockingGuardSubscriber.ts deleted file mode 100644 index 4ceb4dd76..000000000 --- a/packages/server/src/services/TransactionsLocking/FinancialsTransactionLockingGuardSubscriber.ts +++ /dev/null @@ -1,335 +0,0 @@ -import { Inject, Service } from 'typedi'; -import FinancialTransactionLocking from './FinancialTransactionLockingGuard'; -import events from '@/subscribers/events'; -import { - ICommandCashflowCreatingPayload, - ICommandCashflowDeletingPayload, - IExpenseCreatingPayload, - IExpenseDeletingPayload, - IExpenseEventEditingPayload, - IInventoryAdjustmentCreatingPayload, - IInventoryAdjustmentDeletingPayload, - IInventoryAdjustmentPublishingPayload, - IManualJournalCreatingPayload, - IExpensePublishingPayload, - IManualJournalEditingPayload, - IManualJournalPublishingPayload, -} from '@/interfaces'; - -@Service() -export default class FinancialTransactionLockingGuardSubscriber { - @Inject() - financialTransactionsLocking: FinancialTransactionLocking; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach = (bus) => { - // Manual journals. - bus.subscribe( - events.manualJournals.onCreating, - this.transactionsLockingGuardOnManualJournalCreating - ); - bus.subscribe( - events.manualJournals.onEditing, - this.transactionsLockingGuardOnManualJournalEditing - ); - bus.subscribe( - events.manualJournals.onDeleting, - this.transactionsLockingGuardOnManualJournalDeleting - ); - bus.subscribe( - events.manualJournals.onPublishing, - this.transactionsLockingGuardOnManualJournalPublishing - ); - // Expenses - bus.subscribe( - events.expenses.onCreating, - this.transactionsLockingGuardOnExpenseCreating - ); - bus.subscribe( - events.expenses.onEditing, - this.transactionsLockingGuardOnExpenseEditing - ); - bus.subscribe( - events.expenses.onDeleting, - this.transactionsLockingGuardOnExpenseDeleting - ); - bus.subscribe( - events.expenses.onPublishing, - this.transactionsLockingGuardOnExpensePublishing - ); - // Cashflow - bus.subscribe( - events.cashflow.onTransactionCreating, - this.transactionsLockingGuardOnCashflowTransactionCreating - ); - bus.subscribe( - events.cashflow.onTransactionDeleting, - this.transactionsLockingGuardOnCashflowTransactionDeleting - ); - // Inventory adjustment. - bus.subscribe( - events.inventoryAdjustment.onQuickCreating, - this.transactionsLockingGuardOnInventoryAdjCreating - ); - bus.subscribe( - events.inventoryAdjustment.onDeleting, - this.transactionLockingGuardOnInventoryAdjDeleting - ); - bus.subscribe( - events.inventoryAdjustment.onPublishing, - this.transactionLockingGuardOnInventoryAdjPublishing - ); - }; - - /** - * --------------------------------------------- - * - MANUAL JOURNALS SERVICE. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on manual journal creating. - * @param {IManualJournalCreatingPayload} payload - */ - private transactionsLockingGuardOnManualJournalCreating = async ({ - tenantId, - manualJournalDTO, - }: IManualJournalCreatingPayload) => { - // Can't continue if the new journal is not published yet. - if (!manualJournalDTO.publish) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - manualJournalDTO.date - ); - }; - - /** - * Transactions locking guard on manual journal deleting. - * @param {IManualJournalEditingPayload} payload - */ - private transactionsLockingGuardOnManualJournalDeleting = async ({ - tenantId, - oldManualJournal, - }: IManualJournalEditingPayload) => { - // Can't continue if the old journal is not published. - if (!oldManualJournal.isPublished) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldManualJournal.date - ); - }; - - /** - * Transactions locking guard on manual journal editing. - * @param {IManualJournalDeletingPayload} payload - */ - private transactionsLockingGuardOnManualJournalEditing = async ({ - tenantId, - oldManualJournal, - manualJournalDTO, - }: IManualJournalEditingPayload) => { - // Can't continue if the old and new journal are not published. - if (!oldManualJournal.isPublished && !manualJournalDTO.publish) return; - - // Validate the old journal date. - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldManualJournal.date - ); - // Validate the new journal date. - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - manualJournalDTO.date - ); - }; - - /** - * Transactions locking guard on manual journal publishing. - * @param {IManualJournalPublishingPayload} - */ - private transactionsLockingGuardOnManualJournalPublishing = async ({ - oldManualJournal, - tenantId, - }: IManualJournalPublishingPayload) => { - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldManualJournal.date - ); - }; - - /** - * --------------------------------------------- - * - EXPENSES SERVICE. - * --------------------------------------------- - */ - - /** - * Transactions locking guard on expense creating. - * @param {IExpenseCreatingPayload} payload - */ - private transactionsLockingGuardOnExpenseCreating = async ({ - expenseDTO, - tenantId, - }: IExpenseCreatingPayload) => { - // Can't continue if the new expense is not published yet. - if (!expenseDTO.publish) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - expenseDTO.paymentDate - ); - }; - - /** - * Transactions locking guard on expense deleting. - * @param {IExpenseDeletingPayload} payload - */ - private transactionsLockingGuardOnExpenseDeleting = async ({ - tenantId, - oldExpense, - }: IExpenseDeletingPayload) => { - // Can't continue if expense transaction is not published. - if (!oldExpense.isPublished) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldExpense.paymentDate - ); - }; - - /** - * Transactions locking guard on expense editing. - * @param {IExpenseEventEditingPayload} - */ - private transactionsLockingGuardOnExpenseEditing = async ({ - tenantId, - oldExpense, - expenseDTO, - }: IExpenseEventEditingPayload) => { - // Can't continue if the old and new expense is not published. - if (!oldExpense.isPublished && !expenseDTO.publish) return; - - // Validate the old expense date. - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldExpense.paymentDate - ); - // Validate the new expense date. - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - expenseDTO.paymentDate - ); - }; - - /** - * Transactions locking guard on expense publishing. - * @param {IExpensePublishingPayload} payload - - */ - private transactionsLockingGuardOnExpensePublishing = async ({ - tenantId, - oldExpense, - }: IExpensePublishingPayload) => { - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldExpense.paymentDate - ); - }; - - /** - * --------------------------------------------- - * - CASHFLOW SERVICE. - * --------------------------------------------- - */ - - /** - * Transactions locking guard on cashflow transaction creating. - * @param {ICommandCashflowCreatingPayload} - */ - private transactionsLockingGuardOnCashflowTransactionCreating = async ({ - tenantId, - newTransactionDTO, - }: ICommandCashflowCreatingPayload) => { - if (!newTransactionDTO.publish) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - newTransactionDTO.date - ); - }; - - /** - * Transactions locking guard on cashflow transaction deleting. - * @param {ICommandCashflowDeletingPayload} - */ - private transactionsLockingGuardOnCashflowTransactionDeleting = async ({ - tenantId, - oldCashflowTransaction, - }: ICommandCashflowDeletingPayload) => { - // Can't continue if the cashflow transaction is not published. - if (!oldCashflowTransaction.isPublished) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldCashflowTransaction.date - ); - }; - - /** - * --------------------------------------------- - * - INVENTORY ADJUSTMENT SERVICE. - * --------------------------------------------- - */ - - /** - * Transactions locking guard on inventory adjustment creating. - * @param {IInventoryAdjustmentCreatingPayload} payload - - */ - private transactionsLockingGuardOnInventoryAdjCreating = async ({ - tenantId, - quickAdjustmentDTO, - }: IInventoryAdjustmentCreatingPayload) => { - // Can't locking if the new adjustment is not published yet. - if (!quickAdjustmentDTO.publish) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - quickAdjustmentDTO.date - ); - }; - - /** - * Transaction locking guard on inventory adjustment deleting. - * @param {IInventoryAdjustmentDeletingPayload} payload - */ - private transactionLockingGuardOnInventoryAdjDeleting = async ({ - tenantId, - oldInventoryAdjustment, - }: IInventoryAdjustmentDeletingPayload) => { - // Can't locking if the adjustment is published yet. - if (!oldInventoryAdjustment.isPublished) return; - - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldInventoryAdjustment.date - ); - }; - - /** - * Transaction locking guard on inventory adjustment publishing. - * @param {IInventoryAdjustmentPublishingPayload} payload - */ - private transactionLockingGuardOnInventoryAdjPublishing = async ({ - tenantId, - oldInventoryAdjustment, - }: IInventoryAdjustmentPublishingPayload) => { - await this.financialTransactionsLocking.transactionLockingGuard( - tenantId, - oldInventoryAdjustment.date - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuard.ts b/packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuard.ts deleted file mode 100644 index 060ed51e1..000000000 --- a/packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuard.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TransactionsLockingGuard from './TransactionsLockingGuard'; -import { TransactionsLockingGroup } from '@/interfaces'; - -@Service() -export default class PurchasesTransactionLocking { - @Inject() - transactionLockingGuardService: TransactionsLockingGuard; - - /** - * Validates the transaction locking of purchases services commands. - * @param {number} tenantId - * @param {Date} transactionDate - */ - public transactionLockingGuard = async ( - tenantId: number, - transactionDate: Date - ) => { - this.transactionLockingGuardService.transactionsLockingGuard( - tenantId, - transactionDate, - TransactionsLockingGroup.Purchases - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuardSubscriber.ts b/packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuardSubscriber.ts deleted file mode 100644 index 96e537893..000000000 --- a/packages/server/src/services/TransactionsLocking/PurchasesTransactionLockingGuardSubscriber.ts +++ /dev/null @@ -1,286 +0,0 @@ -import { Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - IBillCreatingPayload, - IBillEditingPayload, - IBillEventDeletingPayload, - IBillPaymentCreatingPayload, - IBillPaymentDeletingPayload, - IBillPaymentEditingPayload, - IRefundVendorCreditCreatingPayload, - IRefundVendorCreditDeletingPayload, - IVendorCreditCreatingPayload, - IVendorCreditDeletingPayload, - IVendorCreditEditingPayload, -} from '@/interfaces'; -import PurchasesTransactionsLocking from './PurchasesTransactionLockingGuard'; - -export default class PurchasesTransactionLockingGuardSubscriber { - @Inject() - purchasesTransactionsLocking: PurchasesTransactionsLocking; - - /** - * Attaches events with handlers. - * @param bus - */ - public attach = (bus) => { - // Bills - bus.subscribe( - events.bill.onCreating, - this.transactionLockingGuardOnBillCreating - ); - bus.subscribe( - events.bill.onEditing, - this.transactionLockingGuardOnBillEditing - ); - bus.subscribe( - events.bill.onDeleting, - this.transactionLockingGuardOnBillDeleting - ); - // Payment mades. - bus.subscribe( - events.billPayment.onCreating, - this.transactionLockingGuardOnPaymentCreating - ); - bus.subscribe( - events.billPayment.onEditing, - this.transactionLockingGuardOnPaymentEditing - ); - bus.subscribe( - events.billPayment.onDeleting, - this.transactionLockingGuardOnPaymentDeleting - ); - // Vendor credits. - bus.subscribe( - events.vendorCredit.onCreating, - this.transactionLockingGuardOnVendorCreditCreating - ); - bus.subscribe( - events.vendorCredit.onDeleting, - this.transactionLockingGuardOnVendorCreditDeleting - ); - bus.subscribe( - events.vendorCredit.onEditing, - this.transactionLockingGuardOnVendorCreditEditing - ); - bus.subscribe( - events.vendorCredit.onRefundCreating, - this.transactionLockingGuardOnRefundVendorCredit - ); - bus.subscribe( - events.vendorCredit.onRefundDeleting, - this.transactionLockingGuardOnRefundCreditDeleting - ); - }; - - /** - * --------------------------------------------- - * PAYMENT MADES. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on payment editing. - * @param {IBillPaymentEditingPayload} - */ - private transactionLockingGuardOnPaymentEditing = async ({ - tenantId, - oldBillPayment, - billPaymentDTO, - }: IBillPaymentEditingPayload) => { - // Validate old payment date. - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldBillPayment.paymentDate - ); - // Validate the new payment date. - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - billPaymentDTO.paymentDate - ); - }; - - /** - * Transaction locking guard on payment creating. - * @param {IBillPaymentCreatingPayload} - */ - private transactionLockingGuardOnPaymentCreating = async ({ - tenantId, - billPaymentDTO, - }: IBillPaymentCreatingPayload) => { - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - billPaymentDTO.paymentDate - ); - }; - - /** - * Transaction locking guard on payment deleting. - * @param {IBillPaymentDeletingPayload} payload - - */ - private transactionLockingGuardOnPaymentDeleting = async ({ - tenantId, - oldBillPayment, - }: IBillPaymentDeletingPayload) => { - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldBillPayment.paymentDate - ); - }; - - /** - * --------------------------------------------- - * BILLS. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on bill creating. - * @param {IBillCreatingPayload} payload - */ - private transactionLockingGuardOnBillCreating = async ({ - tenantId, - billDTO, - }: IBillCreatingPayload) => { - // Can't continue if the new bill is not published. - if (!billDTO.open) return; - - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - billDTO.billDate - ); - }; - - /** - * Transaction locking guard on bill editing. - * @param {IBillEditingPayload} payload - */ - private transactionLockingGuardOnBillEditing = async ({ - oldBill, - tenantId, - billDTO, - }: IBillEditingPayload) => { - // Can't continue if the old and new bill are not published. - if (!oldBill.isOpen && !billDTO.open) return; - - // Validate the old bill date. - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldBill.billDate - ); - // Validate the new bill date. - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - billDTO.billDate - ); - }; - - /** - * Transaction locking guard on bill deleting. - * @param {IBillEventDeletingPayload} payload - */ - private transactionLockingGuardOnBillDeleting = async ({ - tenantId, - oldBill, - }: IBillEventDeletingPayload) => { - // Can't continue if the old bill is not published. - if (!oldBill.isOpen) return; - - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldBill.billDate - ); - }; - - /** - * --------------------------------------------- - * VENDOR CREDITS. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on vendor credit creating. - * @param {IVendorCreditCreatingPayload} payload - */ - private transactionLockingGuardOnVendorCreditCreating = async ({ - tenantId, - vendorCreditCreateDTO, - }: IVendorCreditCreatingPayload) => { - // Can't continue if the new vendor credit is not published. - if (!vendorCreditCreateDTO.open) return; - - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - vendorCreditCreateDTO.vendorCreditDate - ); - }; - - /** - * Transaction locking guard on vendor credit deleting. - * @param {IVendorCreditDeletingPayload} payload - */ - private transactionLockingGuardOnVendorCreditDeleting = async ({ - tenantId, - oldVendorCredit, - }: IVendorCreditDeletingPayload) => { - // Can't continue if the old vendor credit is not open. - if (!oldVendorCredit.isOpen) return; - - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldVendorCredit.vendorCreditDate - ); - }; - - /** - * Transaction locking guard on vendor credit editing. - * @param {IVendorCreditEditingPayload} payload - */ - private transactionLockingGuardOnVendorCreditEditing = async ({ - tenantId, - oldVendorCredit, - vendorCreditDTO, - }: IVendorCreditEditingPayload) => { - // Can't continue if the old and new vendor credit are not published. - if (!oldVendorCredit.isPublished && !vendorCreditDTO.open) return; - - // Validate the old credit date. - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldVendorCredit.vendorCreditDate - ); - // Validate the new credit date. - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - vendorCreditDTO.vendorCreditDate - ); - }; - - /** - * Transaction locking guard on refund vendor credit creating. - * @param {IRefundVendorCreditCreatingPayload} payload - - */ - private transactionLockingGuardOnRefundVendorCredit = async ({ - tenantId, - refundVendorCreditDTO, - }: IRefundVendorCreditCreatingPayload) => { - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - refundVendorCreditDTO.date - ); - }; - - /** - * Transaction locking guard on refund vendor credit deleting. - * @param {IRefundVendorCreditDeletingPayload} payload - */ - private transactionLockingGuardOnRefundCreditDeleting = async ({ - tenantId, - oldRefundCredit, - }: IRefundVendorCreditDeletingPayload) => { - await this.purchasesTransactionsLocking.transactionLockingGuard( - tenantId, - oldRefundCredit.date - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/QueryTransactionsLocking.ts b/packages/server/src/services/TransactionsLocking/QueryTransactionsLocking.ts deleted file mode 100644 index 4112f63b3..000000000 --- a/packages/server/src/services/TransactionsLocking/QueryTransactionsLocking.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - ITransactionLockingMetaPOJO, - ITransactionsLockingListPOJO, - ITransactionsLockingSchema, - TransactionsLockingGroup, -} from '@/interfaces'; -import { TRANSACTIONS_LOCKING_SCHEMA } from './constants'; -import TransactionsLockingMetaTransformer from './TransactionsLockingMetaTransformer'; -import TransactionsLockingRepository from './TransactionsLockingRepository'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export default class QueryTransactionsLocking { - @Inject() - private transactionsLockingRepo: TransactionsLockingRepository; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieve transactions locking modules. - * @param {number} tenantId - * @returns {ITransactionLockingMetaPOJO[]} - */ - public getTransactionsLockingModules = ( - tenantId: number - ): Promise => { - const modules = TRANSACTIONS_LOCKING_SCHEMA.map( - (schema: ITransactionsLockingSchema) => - this.getTransactionsLockingModuleMeta(tenantId, schema.module) - ); - return Promise.all(modules); - }; - - /** - * Retireve the transactions locking all module. - * @param {number} tenantId - * @returns {ITransactionLockingMetaPOJO} - */ - public getTransactionsLockingAll = ( - tenantId: number - ): Promise => { - return this.getTransactionsLockingModuleMeta( - tenantId, - TransactionsLockingGroup.All - ); - }; - - /** - * Retrieve the transactions locking module meta. - * @param {number} tenantId - - * @param {TransactionsLockingGroup} module - - * @returns {ITransactionLockingMetaPOJO} - */ - public getTransactionsLockingModuleMeta = ( - tenantId: number, - module: TransactionsLockingGroup - ): Promise => { - const meta = this.transactionsLockingRepo.getTransactionsLocking( - tenantId, - module - ); - return this.transformer.transform( - tenantId, - meta, - new TransactionsLockingMetaTransformer(), - { module } - ); - }; - - /** - * Retrieve transactions locking list. - * @param {number} tenantId - * @returns {Promise} - */ - public getTransactionsLockingList = async ( - tenantId: number - ): Promise => { - // Retrieve the current transactions locking type. - const lockingType = - this.transactionsLockingRepo.getTransactionsLockingType(tenantId); - - const all = await this.getTransactionsLockingAll(tenantId); - const modules = await this.getTransactionsLockingModules(tenantId); - - return { - lockingType, - all, - modules, - }; - }; -} diff --git a/packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuard.ts b/packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuard.ts deleted file mode 100644 index 2363fa296..000000000 --- a/packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuard.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TransactionsLockingGuard from './TransactionsLockingGuard'; -import { TransactionsLockingGroup } from '@/interfaces'; - -@Service() -export default class SalesTransactionLocking { - @Inject() - transactionLockingGuardService: TransactionsLockingGuard; - - /** - * Validates the transaction locking of sales services commands. - * @param {number} tenantId - * @param {Date} transactionDate - */ - public transactionLockingGuard = async ( - tenantId: number, - transactionDate: Date - ) => { - await this.transactionLockingGuardService.transactionsLockingGuard( - tenantId, - transactionDate, - TransactionsLockingGroup.Sales - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuardSubscriber.ts b/packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuardSubscriber.ts deleted file mode 100644 index 35f91d3ad..000000000 --- a/packages/server/src/services/TransactionsLocking/SalesTransactionLockingGuardSubscriber.ts +++ /dev/null @@ -1,503 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - ISaleReceiptCreatingPayload, - IRefundCreditNoteCreatingPayload, - ISaleInvoiceCreatingPaylaod, - ISaleReceiptDeletingPayload, - ICreditNoteDeletingPayload, - IPaymentReceivedCreatingPayload, - IRefundCreditNoteDeletingPayload, - IPaymentReceivedDeletingPayload, - ISaleEstimateDeletingPayload, - ISaleEstimateCreatingPayload, - ISaleEstimateEditingPayload, - ISaleInvoiceWriteoffCreatePayload, - ISaleInvoiceEditingPayload, - ISaleInvoiceDeletePayload, - ISaleInvoiceWrittenOffCancelPayload, - ICreditNoteEditingPayload, - ISaleReceiptEditingPayload, - IPaymentReceivedEditingPayload, - ISaleReceiptEventClosingPayload, - ICreditNoteCreatingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import SalesTransactionLockingGuard from './SalesTransactionLockingGuard'; - -@Service() -export default class SalesTransactionLockingGuardSubscriber { - @Inject() - salesLockingGuard: SalesTransactionLockingGuard; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - // Sale invoice. - bus.subscribe( - events.saleInvoice.onCreating, - this.transactionLockingGuardOnInvoiceCreating - ); - bus.subscribe( - events.saleInvoice.onEditing, - this.transactionLockingGuardOnInvoiceEditing - ); - bus.subscribe( - events.saleInvoice.onWriteoff, - this.transactionLockinGuardOnInvoiceWritingoff - ); - bus.subscribe( - events.saleInvoice.onWrittenoffCancel, - this.transactionLockinGuardOnInvoiceWritingoffCanceling - ); - bus.subscribe( - events.saleInvoice.onDelete, - this.transactionLockingGuardOnInvoiceDeleting - ); - - // Sale receipt - bus.subscribe( - events.saleReceipt.onCreating, - this.transactionLockingGuardOnReceiptCreating - ); - bus.subscribe( - events.saleReceipt.onDeleting, - this.transactionLockingGuardOnReceiptDeleting - ); - bus.subscribe( - events.saleReceipt.onEditing, - this.transactionLockingGuardOnReceiptEditing - ); - bus.subscribe( - events.saleReceipt.onClosing, - this.transactionLockingGuardOnReceiptClosing - ); - - // Payment receive - bus.subscribe( - events.paymentReceive.onCreating, - this.transactionLockingGuardOnPaymentCreating - ); - bus.subscribe( - events.paymentReceive.onEditing, - this.transactionLockingGuardOnPaymentEditing - ); - bus.subscribe( - events.paymentReceive.onDeleting, - this.transactionLockingGuardPaymentDeleting - ); - - // Credit note. - bus.subscribe( - events.creditNote.onCreating, - this.transactionLockingGuardOnCreditCreating - ); - bus.subscribe( - events.creditNote.onEditing, - this.transactionLockingGuardOnCreditEditing - ); - bus.subscribe( - events.creditNote.onDeleting, - this.transactionLockingGuardOnCreditDeleting - ); - bus.subscribe( - events.creditNote.onRefundCreating, - this.transactionLockingGuardOnCreditRefundCreating - ); - bus.subscribe( - events.creditNote.onRefundDeleting, - this.transactionLockingGuardOnCreditRefundDeleteing - ); - - // Sale Estimate - bus.subscribe( - events.saleEstimate.onCreating, - this.transactionLockingGuardOnEstimateCreating - ); - bus.subscribe( - events.saleEstimate.onDeleting, - this.transactionLockingGuardOnEstimateDeleting - ); - bus.subscribe( - events.saleEstimate.onEditing, - this.transactionLockingGuardOnEstimateEditing - ); - }; - - /** - * --------------------------------------------- - * SALES INVOICES. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on invoice creating. - * @param {ISaleInvoiceCreatingPaylaod} payload - */ - private transactionLockingGuardOnInvoiceCreating = async ({ - saleInvoiceDTO, - tenantId, - }: ISaleInvoiceCreatingPaylaod) => { - // Can't continue if the new invoice is not published yet. - if (!saleInvoiceDTO.delivered) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - saleInvoiceDTO.invoiceDate - ); - }; - - /** - * Transaction locking guard on invoice editing. - * @param {ISaleInvoiceEditingPayload} payload - */ - private transactionLockingGuardOnInvoiceEditing = async ({ - tenantId, - oldSaleInvoice, - saleInvoiceDTO, - }: ISaleInvoiceEditingPayload) => { - // Can't continue if the old and new invoice are not published yet. - if (!oldSaleInvoice.isDelivered && !saleInvoiceDTO.delivered) return; - - // Validate the old invoice date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleInvoice.invoiceDate - ); - // Validate the new invoice date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - saleInvoiceDTO.invoiceDate - ); - }; - - /** - * Transaction locking guard on invoice deleting. - * @param {ISaleInvoiceDeletePayload} payload - */ - private transactionLockingGuardOnInvoiceDeleting = async ({ - oldSaleInvoice, - tenantId, - }: ISaleInvoiceDeletePayload) => { - // Can't continue if the old invoice not published. - if (!oldSaleInvoice.isDelivered) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleInvoice.invoiceDate - ); - }; - - /** - * Transaction locking guard on invoice writingoff. - * @param {ISaleInvoiceWriteoffCreatePayload} payload - */ - private transactionLockinGuardOnInvoiceWritingoff = async ({ - tenantId, - saleInvoice, - }: ISaleInvoiceWriteoffCreatePayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - saleInvoice.invoiceDate - ); - }; - - /** - * Transaciton locking guard on canceling written-off invoice. - * @param {ISaleInvoiceWrittenOffCancelPayload} payload - */ - private transactionLockinGuardOnInvoiceWritingoffCanceling = async ({ - tenantId, - saleInvoice, - }: ISaleInvoiceWrittenOffCancelPayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - saleInvoice.invoiceDate - ); - }; - - /** - * --------------------------------------------- - * SALES RECEIPTS. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on receipt creating. - * @param {ISaleReceiptCreatingPayload} - */ - private transactionLockingGuardOnReceiptCreating = async ({ - tenantId, - saleReceiptDTO, - }: ISaleReceiptCreatingPayload) => { - // Can't continue if the sale receipt is not published. - if (!saleReceiptDTO.closed) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - saleReceiptDTO.receiptDate - ); - }; - - /** - * Transaction locking guard on receipt creating. - * @param {ISaleReceiptDeletingPayload} - */ - private transactionLockingGuardOnReceiptDeleting = async ({ - tenantId, - oldSaleReceipt, - }: ISaleReceiptDeletingPayload) => { - if (!oldSaleReceipt.isClosed) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleReceipt.receiptDate - ); - }; - - /** - * Transaction locking guard on sale receipt editing. - * @param {ISaleReceiptEditingPayload} payload - */ - private transactionLockingGuardOnReceiptEditing = async ({ - tenantId, - oldSaleReceipt, - saleReceiptDTO, - }: ISaleReceiptEditingPayload) => { - // Validate the old receipt date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleReceipt.receiptDate - ); - // Validate the new receipt date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - saleReceiptDTO.receiptDate - ); - }; - - /** - * Transaction locking guard on sale receipt closing. - * @param {ISaleReceiptEventClosingPayload} payload - */ - private transactionLockingGuardOnReceiptClosing = async ({ - tenantId, - oldSaleReceipt, - }: ISaleReceiptEventClosingPayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleReceipt.receiptDate - ); - }; - - /** - * --------------------------------------------- - * CREDIT NOTES. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on credit note deleting. - * @param {ICreditNoteDeletingPayload} payload - - */ - private transactionLockingGuardOnCreditDeleting = async ({ - oldCreditNote, - tenantId, - }: ICreditNoteDeletingPayload) => { - // Can't continue if the old credit is not published. - if (!oldCreditNote.isPublished) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldCreditNote.creditNoteDate - ); - }; - - /** - * Transaction locking guard on credit note creating. - * @param {ICreditNoteCreatingPayload} payload - */ - private transactionLockingGuardOnCreditCreating = async ({ - tenantId, - creditNoteDTO, - }: ICreditNoteCreatingPayload) => { - // Can't continue if the new credit is still draft. - if (!creditNoteDTO.open) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - creditNoteDTO.creditNoteDate - ); - }; - - /** - * Transaction locking guard on credit note editing. - * @param {ICreditNoteEditingPayload} payload - - */ - private transactionLockingGuardOnCreditEditing = async ({ - creditNoteEditDTO, - oldCreditNote, - tenantId, - }: ICreditNoteEditingPayload) => { - // Can't continue if the new and old credit note are not published yet. - if (!creditNoteEditDTO.open && !oldCreditNote.isPublished) return; - - // Validate the old credit date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldCreditNote.creditNoteDate - ); - // Validate the new credit date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - creditNoteEditDTO.creditNoteDate - ); - }; - - /** - * Transaction locking guard on payment deleting. - * @param {IRefundCreditNoteDeletingPayload} paylaod - - */ - private transactionLockingGuardOnCreditRefundDeleteing = async ({ - tenantId, - oldRefundCredit, - }: IRefundCreditNoteDeletingPayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldRefundCredit.date - ); - }; - - /** - * Transaction locking guard on refund credit note creating. - * @param {IRefundCreditNoteCreatingPayload} payload - - */ - private transactionLockingGuardOnCreditRefundCreating = async ({ - tenantId, - newCreditNoteDTO, - }: IRefundCreditNoteCreatingPayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - newCreditNoteDTO.date - ); - }; - - /** - * --------------------------------------------- - * SALES ESTIMATES. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on estimate creating. - * @param {ISaleEstimateCreatingPayload} payload - - */ - private transactionLockingGuardOnEstimateCreating = async ({ - estimateDTO, - tenantId, - }: ISaleEstimateCreatingPayload) => { - // Can't continue if the new estimate is not published yet. - if (!estimateDTO.delivered) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - estimateDTO.estimateDate - ); - }; - - /** - * Transaction locking guard on estimate deleting. - * @param {ISaleEstimateDeletingPayload} payload - */ - private transactionLockingGuardOnEstimateDeleting = async ({ - oldSaleEstimate, - tenantId, - }: ISaleEstimateDeletingPayload) => { - // Can't continue if the old estimate is not published. - if (!oldSaleEstimate.isDelivered) return; - - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleEstimate.estimateDate - ); - }; - - /** - * Transaction locking guard on estimate editing. - * @param {ISaleEstimateEditingPayload} payload - */ - private transactionLockingGuardOnEstimateEditing = async ({ - tenantId, - oldSaleEstimate, - estimateDTO, - }: ISaleEstimateEditingPayload) => { - // Can't continue if the new and old estimate transactions are not published yet. - if (!estimateDTO.delivered && !oldSaleEstimate.isDelivered) return; - - // Validate the old estimate date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldSaleEstimate.estimateDate - ); - // Validate the new estimate date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - estimateDTO.estimateDate - ); - }; - - /** - * --------------------------------------------- - * PAYMENT RECEIVES. - * --------------------------------------------- - */ - - /** - * Transaction locking guard on payment receive editing. - * @param {IPaymentReceivedEditingPayload} - */ - private transactionLockingGuardOnPaymentEditing = async ({ - tenantId, - oldPaymentReceive, - paymentReceiveDTO, - }: IPaymentReceivedEditingPayload) => { - // Validate the old payment date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldPaymentReceive.paymentDate - ); - // Validate the new payment date. - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - paymentReceiveDTO.paymentDate - ); - }; - - /** - * Transaction locking guard on payment creating. - * @param {IPaymentReceivedCreatingPayload} - */ - private transactionLockingGuardOnPaymentCreating = async ({ - tenantId, - paymentReceiveDTO, - }: IPaymentReceivedCreatingPayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - paymentReceiveDTO.paymentDate - ); - }; - - /** - * Transaction locking guard on payment deleting. - * @param {IPaymentReceivedDeletingPayload} payload - - */ - private transactionLockingGuardPaymentDeleting = async ({ - oldPaymentReceive, - tenantId, - }: IPaymentReceivedDeletingPayload) => { - await this.salesLockingGuard.transactionLockingGuard( - tenantId, - oldPaymentReceive.paymentDate - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/TransactionsLockingGuard.ts b/packages/server/src/services/TransactionsLocking/TransactionsLockingGuard.ts deleted file mode 100644 index ef6829679..000000000 --- a/packages/server/src/services/TransactionsLocking/TransactionsLockingGuard.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Service, Inject } from 'typedi'; -import moment from 'moment'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError, ServiceErrors } from '@/exceptions'; -import { TransactionsLockingGroup } from '@/interfaces'; -import TransactionsLockingRepository from './TransactionsLockingRepository'; -import { ERRORS } from './constants'; - -@Service() -export default class TransactionsLockingGuard { - @Inject() - tenancy: HasTenancyService; - - @Inject() - transactionsLockingRepo: TransactionsLockingRepository; - - /** - * Detarmines whether the transaction date between the locking date period. - * @param {number} tenantId - * @param {Date} transactionDate - * @param {TransactionsLockingGroup} lockingGroup - * @returns {boolean} - */ - public isTransactionsLocking = ( - tenantId: number, - transactionDate: Date, - lockingGroup: string = TransactionsLockingGroup.All - ): boolean => { - const { isEnabled, unlockFromDate, unlockToDate, lockToDate } = - this.transactionsLockingRepo.getTransactionsLocking( - tenantId, - lockingGroup - ); - // Returns false anyway in case if the transaction locking is disabled. - if (!isEnabled) return false; - - const inLockingDate = moment(transactionDate).isSameOrBefore(lockToDate); - const inUnlockDate = - unlockFromDate && unlockToDate - ? moment(transactionDate).isSameOrAfter(unlockFromDate) && - moment(transactionDate).isSameOrBefore(unlockFromDate) - : false; - - // Retruns true in case the transaction date between locking date - // and not between unlocking date. - return !!(isEnabled && inLockingDate && !inUnlockDate); - }; - - /** - * Validates the transaction date between the locking date period - * or throw service error. - * @param {number} tenantId - * @param {Date} transactionDate - * @param {TransactionsLockingGroup} lockingGroup - * - * @throws {ServiceError} - */ - public validateTransactionsLocking = ( - tenantId: number, - transactionDate: Date, - lockingGroup: TransactionsLockingGroup - ) => { - const isLocked = this.isTransactionsLocking( - tenantId, - transactionDate, - lockingGroup - ); - if (isLocked) { - this.throwTransactionsLockError(tenantId, lockingGroup); - } - }; - - /** - * Throws transactions locking error. - * @param {number} tenantId - * @param {TransactionsLockingGroup} lockingGroup - */ - public throwTransactionsLockError = ( - tenantId: number, - lockingGroup: TransactionsLockingGroup - ) => { - const { lockToDate } = this.transactionsLockingRepo.getTransactionsLocking( - tenantId, - lockingGroup - ); - throw new ServiceError(ERRORS.TRANSACTIONS_DATE_LOCKED, null, { - lockedToDate: lockToDate, - formattedLockedToDate: moment(lockToDate).format('YYYY/MM/DD'), - }); - }; - - /** - * Validate the transaction locking of the given locking group and transaction date. - * @param {number} tenantId - - * @param {TransactionsLockingGroup} lockingGroup - transaction group - * @param {Date} fromDate - - */ - public transactionsLockingGuard = ( - tenantId: number, - transactionDate: Date, - moduleType: TransactionsLockingGroup - ) => { - const lockingType = - this.transactionsLockingRepo.getTransactionsLockingType(tenantId); - - // - if (lockingType === TransactionsLockingGroup.All) { - return this.validateTransactionsLocking( - tenantId, - transactionDate, - TransactionsLockingGroup.All - ); - } - // - return this.validateTransactionsLocking( - tenantId, - transactionDate, - moduleType - ); - }; -} diff --git a/packages/server/src/services/TransactionsLocking/TransactionsLockingMetaTransformer.ts b/packages/server/src/services/TransactionsLocking/TransactionsLockingMetaTransformer.ts deleted file mode 100644 index f9a04e4ac..000000000 --- a/packages/server/src/services/TransactionsLocking/TransactionsLockingMetaTransformer.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { get } from 'lodash'; -import { TransactionsLockingGroup } from '@/interfaces'; -import { Transformer } from '@/lib/Transformer/Transformer'; -import { getTransactionsLockingSchemaMeta } from './constants'; - -export default class TransactionsLockingMetaTransformer extends Transformer { - /** - * Include these attributes to sale credit note object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'module', - 'formattedModule', - 'description', - 'formattedLockToDate', - 'formattedUnlockFromDate', - 'formattedUnlockToDate', - ]; - }; - - /** - * Module slug. - * @returns {string} - */ - protected module = () => { - return this.options.module; - }; - - /** - * Formatted module name. - * @returns {string} - */ - protected formattedModule = () => { - return this.options.module === TransactionsLockingGroup.All - ? this.context.i18n.__('transactions_locking.module.all_transactions') - : this.context.i18n.__( - get( - getTransactionsLockingSchemaMeta(this.options.module), - 'formattedModule' - ) - ); - }; - - /** - * Module description. - * @returns {string} - */ - protected description = () => { - return this.options.module === TransactionsLockingGroup.All - ? '' - : this.context.i18n.__( - get( - getTransactionsLockingSchemaMeta(this.options.module), - 'description' - ) - ); - }; - - /** - * Formatted unlock to date. - * @returns {string} - */ - protected formattedUnlockToDate = (item) => { - return item.unlockToDate ? this.formatDate(item.unlockToDate) : ''; - }; - - /** - * Formatted unlock from date. - * @returns {string} - */ - protected formattedUnlockFromDate = (item) => { - return item.unlockFromDate ? this.formatDate(item.unlockFromDate) : ''; - }; - - /** - * Formatted lock to date. - * @returns {string} - */ - protected formattedLockToDate = (item) => { - return item.lockToDate ? this.formatDate(item.lockToDate) : ''; - }; -} diff --git a/packages/server/src/services/TransactionsLocking/TransactionsLockingRepository.ts b/packages/server/src/services/TransactionsLocking/TransactionsLockingRepository.ts deleted file mode 100644 index 53bca9758..000000000 --- a/packages/server/src/services/TransactionsLocking/TransactionsLockingRepository.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { isUndefined } from 'lodash'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { - ITransactionMeta, - TransactionsLockingGroup, - TransactionsLockingType, -} from '@/interfaces'; -import { parseDate } from 'utils'; - -@Service() -export default class TransactionsLockingRepository { - @Inject() - tenancy: HasTenancyService; - - async saveTransactionsLocking( - tenantId: number, - lockingGroup: string = TransactionsLockingGroup.All, - transactionlocking - ) { - const settings = this.tenancy.settings(tenantId); - const group = `transactions-locking`; - - if (!isUndefined(transactionlocking.active)) { - settings.set({ - group, - key: `${lockingGroup}.active`, - value: transactionlocking.active, - }); - } - if (!isUndefined(transactionlocking.lockToDate)) { - settings.set({ - group, - key: `${lockingGroup}.lock_to_date`, - value: parseDate(transactionlocking.lockToDate), - }); - } - if (!isUndefined(transactionlocking.unlockFromDate)) { - settings.set({ - group, - key: `${lockingGroup}.unlock_from_date`, - value: parseDate(transactionlocking.unlockFromDate), - }); - } - if (!isUndefined(transactionlocking.unlockToDate)) { - settings.set({ - group, - key: `${lockingGroup}.unlock_to_date`, - value: parseDate(transactionlocking.unlockToDate), - }); - } - if (!isUndefined(transactionlocking.lockReason)) { - settings.set({ - group, - key: `${lockingGroup}.lock_reason`, - value: transactionlocking.lockReason, - }); - } - if (!isUndefined(transactionlocking.unlockReason)) { - settings.set({ - group, - key: `${lockingGroup}.unlock_reason`, - value: transactionlocking.unlockReason, - }); - } - if (!isUndefined(transactionlocking.partialUnlockReason)) { - settings.set({ - group, - key: `${lockingGroup}.partial_unlock_reason`, - value: transactionlocking.partialUnlockReason, - }); - } - - await settings.save(); - } - - getTransactionsLocking( - tenantId: number, - lockingGroup: string = TransactionsLockingGroup.All - ): ITransactionMeta { - const settings = this.tenancy.settings(tenantId); - const group = `transactions-locking`; - - const isEnabled = settings.get({ group, key: `${lockingGroup}.active` }); - - const lockFromDate = settings.get({ - group, - key: `${lockingGroup}.lock_from_date`, - }); - const lockToDate = settings.get({ - group, - key: `${lockingGroup}.lock_to_date`, - }); - - const unlockFromDate = settings.get({ - group, - key: `${lockingGroup}.unlock_from_date`, - }); - const unlockToDate = settings.get({ - group, - key: `${lockingGroup}.unlock_to_date`, - }); - - const lockReason = settings.get({ - group, - key: `${lockingGroup}.lock_reason`, - }); - const unlockReason = settings.get({ - group, - key: `${lockingGroup}.unlock_reason`, - }); - const partialUnlockReason = settings.get({ - group, - key: `${lockingGroup}.partial_unlock_reason`, - }); - - return { - isEnabled, - lockToDate: lockToDate || null, - unlockFromDate: unlockFromDate || null, - unlockToDate: unlockToDate || null, - isPartialUnlock: Boolean(unlockToDate && unlockFromDate), - lockReason: lockReason || '', - unlockReason: unlockReason || '', - partialUnlockReason: partialUnlockReason || '', - }; - } - - getTransactionsLockingType(tenantId: number) { - const settings = this.tenancy.settings(tenantId); - - const lockingType = settings.get({ - group: 'transactions-locking', - key: 'locking-type', - }); - return lockingType || 'partial'; - } - - flagTransactionsLockingType( - tenantId: number, - transactionsType: TransactionsLockingType - ) { - const settings = this.tenancy.settings(tenantId); - - settings.set({ - group: 'transactions-locking', - key: 'locking-type', - value: transactionsType, - }); - } -} diff --git a/packages/server/src/services/TransactionsLocking/constants.ts b/packages/server/src/services/TransactionsLocking/constants.ts deleted file mode 100644 index 01a2bd35e..000000000 --- a/packages/server/src/services/TransactionsLocking/constants.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { - ITransactionsLockingSchema, - TransactionsLockingGroup, -} from '@/interfaces'; - -export const ERRORS = { - TRANSACTIONS_DATE_LOCKED: 'TRANSACTIONS_DATE_LOCKED', - TRANSACTION_LOCKING_PARTIAL: 'TRANSACTION_LOCKING_PARTIAL', - TRANSACTION_LOCKING_ALL: 'TRANSACTION_LOCKING_ALL', - TRANSACTIONS_LOCKING_MODULE_NOT_FOUND: - 'TRANSACTIONS_LOCKING_MODULE_NOT_FOUND', -}; - -export const TRANSACTIONS_LOCKING_SCHEMA = [ - { - module: 'sales', - formattedModule: 'transactions_locking.module.sales.label', - description: 'transactions_locking.module.sales.desc', - }, - { - module: 'purchases', - formattedModule: 'transactions_locking.module.purchases.label', - description: 'transactions_locking.module.purchases.desc', - }, - { - module: 'financial', - formattedModule: 'transactions_locking.module.financial.label', - description: 'transactions_locking.module.financial.desc', - }, -] as ITransactionsLockingSchema[]; - -export function getTransactionsLockingSchemaMeta( - module: TransactionsLockingGroup -): ITransactionsLockingSchema { - return TRANSACTIONS_LOCKING_SCHEMA.find((schema) => schema.module === module); -} diff --git a/packages/server/src/services/UnitOfWork/TransactionsHooks.ts b/packages/server/src/services/UnitOfWork/TransactionsHooks.ts deleted file mode 100644 index 6cb75f726..000000000 --- a/packages/server/src/services/UnitOfWork/TransactionsHooks.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @param {any} maybeTrx - * @returns {maybeTrx is import('objection').TransactionOrKnex & { executionPromise: Promise }} - */ -function checkIsTransaction(maybeTrx) { - return Boolean(maybeTrx && maybeTrx.executionPromise); -} - -/** - * Wait for a transaction to be complete. - * @param {import('objection').TransactionOrKnex} [trx] - */ -export async function waitForTransaction(trx) { - return Promise.resolve(checkIsTransaction(trx) ? trx.executionPromise : null); -} - -/** - * Run a callback when the transaction is done. - * @param {import('objection').TransactionOrKnex | undefined} trx - * @param {Function} callback - */ -export function runAfterTransaction(trx, callback) { - waitForTransaction(trx).then( - () => { - // If transaction success, then run action - return Promise.resolve(callback()).catch((error) => { - setTimeout(() => { - throw error; - }); - }); - }, - () => { - // Ignore transaction error - } - ); -} diff --git a/packages/server/src/services/UnitOfWork/index.ts b/packages/server/src/services/UnitOfWork/index.ts deleted file mode 100644 index a13be95c6..000000000 --- a/packages/server/src/services/UnitOfWork/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Service, Inject } from 'typedi'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { Transaction } from 'objection'; - -/** - * Enumeration that represents transaction isolation levels for use with the {@link Transactional} annotation - */ -export enum IsolationLevel { - /** - * A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur. - */ - READ_UNCOMMITTED = 'read uncommitted', - /** - * A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur. - */ - READ_COMMITTED = 'read committed', - /** - * A constant indicating that dirty reads and non-repeatable reads are prevented; phantom reads can occur. - */ - REPEATABLE_READ = 'repeatable read', - /** - * A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented. - */ - SERIALIZABLE = 'serializable', -} - -@Service() -export default class UnitOfWork { - @Inject() - tenancy: TenancyService; - - /** - * - * @param {number} tenantId - * @param {} work - * @param {IsolationLevel} isolationLevel - * @returns {} - */ - public withTransaction = async ( - tenantId: number, - work, - trx?: Transaction, - isolationLevel: IsolationLevel = IsolationLevel.READ_UNCOMMITTED - ) => { - const knex = this.tenancy.knex(tenantId); - let _trx = trx; - - if (!_trx) { - _trx = await knex.transaction({ isolationLevel }); - } - try { - const result = await work(_trx); - - if (!trx) { - _trx.commit(); - } - return result; - } catch (error) { - if (!trx) { - _trx.rollback(); - } - throw error; - } - }; -} diff --git a/packages/server/src/services/Users/PurgeUserAbilityCache.ts b/packages/server/src/services/Users/PurgeUserAbilityCache.ts deleted file mode 100644 index 454306612..000000000 --- a/packages/server/src/services/Users/PurgeUserAbilityCache.ts +++ /dev/null @@ -1,39 +0,0 @@ -import events from '@/subscribers/events'; -import { - ITenantUserInactivatedPayload, - ITenantUserActivatedPayload, - ITenantUserDeletedPayload, - ITenantUserEditedPayload, -} from '@/interfaces'; -import { ABILITIES_CACHE } from '../../api/middleware/AuthorizationMiddleware'; - -export default class PurgeUserAbilityCache { - /** - * Attaches events with handlers. - * @param bus - */ - attach(bus) { - bus.subscribe(events.tenantUser.onEdited, this.purgeAuthorizedUserAbility); - bus.subscribe( - events.tenantUser.onActivated, - this.purgeAuthorizedUserAbility - ); - bus.subscribe( - events.tenantUser.onInactivated, - this.purgeAuthorizedUserAbility - ); - } - - /** - * Purges authorized user ability once the user mutate. - */ - purgeAuthorizedUserAbility({ - tenantUser, - }: - | ITenantUserInactivatedPayload - | ITenantUserActivatedPayload - | ITenantUserDeletedPayload - | ITenantUserEditedPayload) { - ABILITIES_CACHE.del(tenantUser.systemUserId); - } -} diff --git a/packages/server/src/services/Users/SyncTenantUserDeleted.ts b/packages/server/src/services/Users/SyncTenantUserDeleted.ts deleted file mode 100644 index 80b509f1b..000000000 --- a/packages/server/src/services/Users/SyncTenantUserDeleted.ts +++ /dev/null @@ -1,26 +0,0 @@ -import events from '@/subscribers/events'; -import { ITenantUserDeletedPayload } from '@/interfaces'; -import { SystemUser } from '@/system/models'; - -export class SyncTenantUserDelete { - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.tenantUser.onDeleted, - this.syncSystemUserOnceUserDeleted - ); - } - - /** - * Deletes the system user once tenant user be deleted. - * @param {ITenantUserDeletedPayload} payload - - */ - private syncSystemUserOnceUserDeleted = async ({ - tenantUser, - }: ITenantUserDeletedPayload) => { - await SystemUser.query().where('id', tenantUser.systemUserId).delete(); - }; -} diff --git a/packages/server/src/services/Users/SyncTenantUserSaved.ts b/packages/server/src/services/Users/SyncTenantUserSaved.ts deleted file mode 100644 index ab7f8224f..000000000 --- a/packages/server/src/services/Users/SyncTenantUserSaved.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { pick } from 'lodash'; -import { - ITenantUser, - ITenantUserActivatedPayload, - ITenantUserDeletedPayload, - ITenantUserEditedPayload, - ITenantUserInactivatedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { SystemUser } from '@/system/models'; - -export default class SyncTenantUserMutate { - /** - * Attaches events with handlers. - * @param bus - */ - attach(bus) { - bus.subscribe(events.tenantUser.onEdited, this.syncSystemUserOnceEdited); - bus.subscribe( - events.tenantUser.onActivated, - this.syncSystemUserOnceActivated - ); - bus.subscribe( - events.tenantUser.onInactivated, - this.syncSystemUserOnceInactivated - ); - } - /** - * - * @param tenantUser - */ - private syncSystemUserOnceEdited = async ({ - tenantUser, - }: ITenantUserEditedPayload) => { - await SystemUser.query() - .where('id', tenantUser.systemUserId) - .patch({ - ...pick(tenantUser, [ - 'firstName', - 'lastName', - 'email', - 'active', - 'phoneNumber', - ]), - }); - }; - - /** - * Syncs activate system user. - * @param {ITenantUserInactivatedPayload} payload - - */ - private syncSystemUserOnceActivated = async ({ - tenantUser, - }: ITenantUserInactivatedPayload) => { - await SystemUser.query().where('id', tenantUser.systemUserId).patch({ - active: true, - }); - }; - - /** - * Syncs inactivate system user. - * @param {ITenantUserActivatedPayload} payload - - */ - private syncSystemUserOnceInactivated = async ({ - tenantUser, - }: ITenantUserActivatedPayload) => { - await SystemUser.query().where('id', tenantUser.systemUserId).patch({ - active: false, - }); - }; -} diff --git a/packages/server/src/services/Users/UserTransformer.ts b/packages/server/src/services/Users/UserTransformer.ts deleted file mode 100644 index 958e71080..000000000 --- a/packages/server/src/services/Users/UserTransformer.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class UserTransformer extends Transformer { - /** - * Exclude these attributes from user object. - * @returns {Array} - */ - public excludeAttributes = (): string[] => { - return ['role']; - }; - - /** - * Includeded attributes. - * @returns {string[]} - */ - public includeAttributes = (): string[] => { - return ['roleName', 'roleDescription', 'roleSlug']; - }; - - /** - * Retrieves the localized role name if is predefined or stored name. - * @param role - * @returns {string} - */ - public roleName(user) { - return user.role.predefined - ? this.context.i18n.__(user.role.name) - : user.role.name; - } - - /** - * Retrieves the localized role description if is predefined or stored description. - * @param user - * @returns {string} - */ - public roleDescription(user) { - return user.role.predefined - ? this.context.i18n.__(user.role.description) - : user.role.description; - } - - /** - * Retrieves the role slug. - * @param user - * @returns {string} - */ - public roleSlug(user) { - return user.role.slug; - } -} diff --git a/packages/server/src/services/Users/UsersService.ts b/packages/server/src/services/Users/UsersService.ts deleted file mode 100644 index 3ee47c92f..000000000 --- a/packages/server/src/services/Users/UsersService.ts +++ /dev/null @@ -1,315 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { ServiceError } from '@/exceptions'; -import { - IEditUserDTO, - ISystemUser, - ITenantUser, - ITenantUserActivatedPayload, - ITenantUserDeletedPayload, - ITenantUserEditedPayload, - ITenantUserInactivatedPayload, -} from '@/interfaces'; -import RolesService from '@/services/Roles/RolesService'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ERRORS } from './constants'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; -import { UserTransformer } from './UserTransformer'; - -@Service() -export default class UsersService { - @Inject() - private rolesService: RolesService; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Creates a new user. - * @param {number} tenantId - Tenant id. - * @param {number} userId - User id. - * @param {IUserDTO} editUserDTO - Edit user DTO. - * @return {Promise} - */ - public async editUser( - tenantId: number, - userId: number, - editUserDTO: IEditUserDTO, - authorizedUser: ISystemUser - ): Promise { - const { User } = this.tenancy.models(tenantId); - const { email } = editUserDTO; - - // Retrieve the tenant user or throw not found service error. - const oldTenantUser = await this.getTenantUserOrThrowError( - tenantId, - userId - ); - // Validate cannot mutate the authorized user. - this.validateMutateRoleNotAuthorizedUser( - oldTenantUser, - editUserDTO, - authorizedUser - ); - // Validate user email should be unique. - await this.validateUserEmailUniquiness(tenantId, email, userId); - - // Retrieve the given role or throw not found service error. - const role = await this.rolesService.getRoleOrThrowError( - tenantId, - editUserDTO.roleId - ); - // Updates the tenant user. - const tenantUser = await User.query().updateAndFetchById(userId, { - ...editUserDTO, - }); - // Triggers `onTenantUserEdited` event. - await this.eventPublisher.emitAsync(events.tenantUser.onEdited, { - tenantId, - userId, - editUserDTO, - tenantUser, - oldTenantUser, - } as ITenantUserEditedPayload); - - return tenantUser; - } - - /** - * Deletes the given user id. - * @param {number} tenantId - Tenant id. - * @param {number} userId - User id. - */ - public async deleteUser(tenantId: number, userId: number): Promise { - const { User } = this.tenancy.models(tenantId); - - // Retrieve user details or throw not found service error. - const tenantUser = await this.getTenantUserOrThrowError(tenantId, userId); - - // Validate the delete user should not be the last active user. - if (tenantUser.isInviteAccepted) { - await this.validateNotLastUserDelete(tenantId); - } - // Delete user from the storage. - await User.query().findById(userId).delete(); - - // Triggers `onTenantUserDeleted` event. - await this.eventPublisher.emitAsync(events.tenantUser.onDeleted, { - tenantId, - userId, - tenantUser, - } as ITenantUserDeletedPayload); - } - - /** - * Activate the given user id. - * @param {number} tenantId - Tenant id. - * @param {number} userId - User id. - * @return {Promise} - */ - public async activateUser( - tenantId: number, - userId: number, - authorizedUser: ISystemUser - ): Promise { - const { User } = this.tenancy.models(tenantId); - - // Throw service error if the given user is equals the authorized user. - this.throwErrorIfUserSameAuthorizedUser(userId, authorizedUser); - - // Retrieve the user or throw not found service error. - const tenantUser = await this.getTenantUserOrThrowError(tenantId, userId); - - // Throw serivce error if the user is already activated. - this.throwErrorIfUserActive(tenantUser); - - // Marks the tenant user as active. - await User.query().findById(userId).update({ active: true }); - - // Triggers `onTenantUserActivated` event. - await this.eventPublisher.emitAsync(events.tenantUser.onActivated, { - tenantId, - userId, - authorizedUser, - tenantUser, - } as ITenantUserActivatedPayload); - } - - /** - * Inactivate the given user id. - * @param {number} tenantId - * @param {number} userId - * @return {Promise} - */ - public async inactivateUser( - tenantId: number, - userId: number, - authorizedUser: ISystemUser - ): Promise { - const { User } = this.tenancy.models(tenantId); - - // Throw service error if the given user is equals the authorized user. - this.throwErrorIfUserSameAuthorizedUser(userId, authorizedUser); - - // Retrieve the user or throw not found service error. - const tenantUser = await this.getTenantUserOrThrowError(tenantId, userId); - - // Throw serivce error if the user is already inactivated. - this.throwErrorIfUserInactive(tenantUser); - - // Marks the tenant user as active. - await User.query().findById(userId).update({ active: true }); - - // Triggers `onTenantUserActivated` event. - await this.eventPublisher.emitAsync(events.tenantUser.onInactivated, { - tenantId, - userId, - authorizedUser, - tenantUser, - } as ITenantUserInactivatedPayload); - } - - /** - * Retrieve users list based on the given filter. - * @param {number} tenantId - * @param {object} filter - */ - public async getList(tenantId: number) { - const { User } = this.tenancy.models(tenantId); - - const users = await User.query().withGraphFetched('role'); - - return this.transformer.transform(tenantId, users, new UserTransformer()); - } - - /** - * Retrieve the given user details. - * @param {number} tenantId - Tenant id. - * @param {number} userId - User id. - */ - public async getUser(tenantId: number, userId: number) { - // Retrieve the system user. - const user = await this.getTenantUserOrThrowError(tenantId, userId); - - return user; - } - - /** - * Validate user existance throw error in case user was not found., - * @param {number} tenantId - - * @param {number} userId - - * @returns {ISystemUser} - */ - async getTenantUserOrThrowError( - tenantId: number, - userId: number - ): Promise { - const { User } = this.tenancy.models(tenantId); - - const user = await User.query().findById(userId); - - if (!user) { - throw new ServiceError(ERRORS.USER_NOT_FOUND); - } - return user; - } - - /** - * Validate the delete user should not be the last user. - * @param {number} tenantId - */ - private async validateNotLastUserDelete(tenantId: number) { - const { User } = this.tenancy.models(tenantId); - - const inviteAcceptedUsers = await User.query() - .select(['id']) - .whereNotNull('invite_accepted_at'); - - if (inviteAcceptedUsers.length === 1) { - throw new ServiceError(ERRORS.CANNOT_DELETE_LAST_USER); - } - } - - /** - * Throws service error in case the user was already active. - * @param {ISystemUser} user - * @throws {ServiceError} - */ - private throwErrorIfUserActive(user: ISystemUser) { - if (user.active) { - throw new ServiceError(ERRORS.USER_ALREADY_ACTIVE); - } - } - - /** - * Throws service error in case the user was already inactive. - * @param {ISystemUser} user - * @throws {ServiceError} - */ - private throwErrorIfUserInactive(user: ITenantUser) { - if (!user.active) { - throw new ServiceError(ERRORS.USER_ALREADY_INACTIVE); - } - } - - /** - * Throw service error in case the given user same the authorized user. - * @param {number} userId - * @param {ISystemUser} authorizedUser - */ - private throwErrorIfUserSameAuthorizedUser( - userId: number, - authorizedUser: ISystemUser - ) { - if (userId === authorizedUser.id) { - throw new ServiceError(ERRORS.USER_SAME_THE_AUTHORIZED_USER); - } - } - - /** - * Validate the given user email should be unique in the storage. - * @param {string} email - * @param {number} userId - */ - private validateUserEmailUniquiness = async ( - tenantId: number, - email: string, - userId: number - ) => { - const { User } = this.tenancy.models(tenantId); - - const userByEmail = await User.query() - .findOne('email', email) - .whereNot('id', userId); - - if (userByEmail) { - throw new ServiceError(ERRORS.EMAIL_ALREADY_EXISTS); - } - }; - - /** - * Validate the authorized user cannot mutate its role. - * @param {ITenantUser} oldTenantUser - * @param {IEditUserDTO} editUserDTO - * @param {ISystemUser} authorizedUser - */ - validateMutateRoleNotAuthorizedUser( - oldTenantUser: ITenantUser, - editUserDTO: IEditUserDTO, - authorizedUser: ISystemUser - ) { - if ( - authorizedUser.id === oldTenantUser.systemUserId && - editUserDTO.roleId !== oldTenantUser.roleId - ) { - throw new ServiceError(ERRORS.CANNOT_AUTHORIZED_USER_MUTATE_ROLE); - } - } -} diff --git a/packages/server/src/services/Users/constants.ts b/packages/server/src/services/Users/constants.ts deleted file mode 100644 index e74dd0e21..000000000 --- a/packages/server/src/services/Users/constants.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const ERRORS = { - CANNOT_DELETE_LAST_USER: 'CANNOT_DELETE_LAST_USER', - USER_ALREADY_ACTIVE: 'USER_ALREADY_ACTIVE', - USER_ALREADY_INACTIVE: 'USER_ALREADY_INACTIVE', - EMAIL_ALREADY_EXISTS: 'EMAIL_ALREADY_EXISTS', - PHONE_NUMBER_ALREADY_EXIST: 'PHONE_NUMBER_ALREADY_EXIST', - USER_NOT_FOUND: 'USER_NOT_FOUND', - USER_SAME_THE_AUTHORIZED_USER: 'USER_SAME_THE_AUTHORIZED_USER', - CANNOT_AUTHORIZED_USER_MUTATE_ROLE: 'CANNOT_AUTHORIZED_USER_MUTATE_ROLE' -}; diff --git a/packages/server/src/services/Views/ViewsService.ts b/packages/server/src/services/Views/ViewsService.ts deleted file mode 100644 index d7426d527..000000000 --- a/packages/server/src/services/Views/ViewsService.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { - IViewsService, - IView, - IModel, -} from '@/interfaces'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import ResourceService from '@/services/Resource/ResourceService'; - -@Service() -export default class ViewsService implements IViewsService { - @Inject() - tenancy: TenancyService; - - @Inject('logger') - logger: any; - - @Inject() - resourceService: ResourceService; - - /** - * Listing resource views. - * @param {number} tenantId - - * @param {string} resourceModel - - */ - public async listResourceViews( - tenantId: number, - resourceModelName: string - ): Promise { - // Validate the resource model name is valid. - const resourceModel = this.getResourceModelOrThrowError( - tenantId, - resourceModelName - ); - // Default views. - const defaultViews = resourceModel.getDefaultViews(); - - return defaultViews; - } - - /** - * Retrieve resource model from resource name or throw not found error. - * @param {number} tenantId - * @param {number} resourceModel - */ - private getResourceModelOrThrowError( - tenantId: number, - resourceModel: string - ): IModel { - return this.resourceService.getResourceModel(tenantId, resourceModel); - } -} diff --git a/packages/server/src/services/Warehouses/Activate/BillWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/BillWarehousesActivate.ts deleted file mode 100644 index d436e3e78..000000000 --- a/packages/server/src/services/Warehouses/Activate/BillWarehousesActivate.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class BillActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all credit note transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateBillsWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { Bill, ItemEntry } = this.tenancy.models(tenantId); - - // Updates the sale estimates with primary warehouse. - await Bill.query().update({ warehouseId: primaryWarehouse.id }); - - // Update the sale estimates entries with primary warehouse. - await ItemEntry.query().where('referenceType', 'Bill').update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/Activate/CreditNoteWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/CreditNoteWarehousesActivate.ts deleted file mode 100644 index 262297dfe..000000000 --- a/packages/server/src/services/Warehouses/Activate/CreditNoteWarehousesActivate.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class CreditNotesActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all credit note transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateCreditsWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { CreditNote, ItemEntry } = this.tenancy.models(tenantId); - - // Updates the sale estimates with primary warehouse. - await CreditNote.query().update({ warehouseId: primaryWarehouse.id }); - - // Update the sale estimates entries with primary warehouse. - await ItemEntry.query().where('referenceType', 'CreditNote').update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/Activate/EstimateWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/EstimateWarehousesActivate.ts deleted file mode 100644 index e7fd2c5bf..000000000 --- a/packages/server/src/services/Warehouses/Activate/EstimateWarehousesActivate.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class EstimatesActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all inventory transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateEstimatesWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { SaleEstimate, ItemEntry } = this.tenancy.models(tenantId); - - // Updates the sale estimates with primary warehouse. - await SaleEstimate.query().update({ warehouseId: primaryWarehouse.id }); - - // Update the sale estimates entries with primary warehouse. - await ItemEntry.query().where('referenceType', 'SaleEstimate').update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts deleted file mode 100644 index 0bc0b8e4f..000000000 --- a/packages/server/src/services/Warehouses/Activate/InventoryTransactionsWarehousesActivate.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class InventoryActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all inventory transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateInventoryTransactionsWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { InventoryTransaction, InventoryCostLotTracker } = - this.tenancy.models(tenantId); - - // Updates the inventory transactions with primary warehouse. - await InventoryTransaction.query().update({ - warehouseId: primaryWarehouse.id, - }); - await InventoryCostLotTracker.query().update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/Activate/InvoiceWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/InvoiceWarehousesActivate.ts deleted file mode 100644 index 94244dfec..000000000 --- a/packages/server/src/services/Warehouses/Activate/InvoiceWarehousesActivate.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class InvoicesActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all inventory transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateInvoicesWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { SaleInvoice, ItemEntry } = this.tenancy.models(tenantId); - - // Updates the sale invoices with primary warehouse. - await SaleInvoice.query().update({ warehouseId: primaryWarehouse.id }); - - // Update the sale invoices entries with primary warehouse. - await ItemEntry.query().where('referenceType', 'SaleInvoice').update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/Activate/ReceiptWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/ReceiptWarehousesActivate.ts deleted file mode 100644 index 722e9a535..000000000 --- a/packages/server/src/services/Warehouses/Activate/ReceiptWarehousesActivate.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ReceiptActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all sale receipts transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateReceiptsWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { SaleReceipt, ItemEntry } = this.tenancy.models(tenantId); - - // Updates the vendor credits transactions with primary warehouse. - await SaleReceipt.query().update({ warehouseId: primaryWarehouse.id }); - - // Update the sale invoices entries with primary warehouse. - await ItemEntry.query().where('referenceType', 'SaleReceipt').update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/Activate/VendorCreditWarehousesActivate.ts b/packages/server/src/services/Warehouses/Activate/VendorCreditWarehousesActivate.ts deleted file mode 100644 index 4402c4076..000000000 --- a/packages/server/src/services/Warehouses/Activate/VendorCreditWarehousesActivate.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehouse } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class VendorCreditActivateWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all vendor credits transactions with the primary warehouse. - * @param {number} tenantId - * @param {number} primaryWarehouse - * @returns {Promise} - */ - public updateCreditsWithWarehouse = async ( - tenantId: number, - primaryWarehouse: IWarehouse - ): Promise => { - const { VendorCredit, ItemEntry } = this.tenancy.models(tenantId); - - // Updates the vendor credits transactions with primary warehouse. - await VendorCredit.query().update({ warehouseId: primaryWarehouse.id }); - - // Update the sale invoices entries with primary warehouse. - await ItemEntry.query().where('referenceType', 'VendorCredit').update({ - warehouseId: primaryWarehouse.id, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/ActivateWarehouses.ts b/packages/server/src/services/Warehouses/ActivateWarehouses.ts deleted file mode 100644 index 4636515b9..000000000 --- a/packages/server/src/services/Warehouses/ActivateWarehouses.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; - -import { ServiceError } from '@/exceptions'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import { CreateInitialWarehouse } from './CreateInitialWarehouse'; -import { WarehousesSettings } from './WarehousesSettings'; - -import events from '@/subscribers/events'; -import { ERRORS } from './contants'; - -@Service() -export class ActivateWarehouses { - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - createInitialWarehouse: CreateInitialWarehouse; - - @Inject() - settings: WarehousesSettings; - - /** - * Throws error if the multi-warehouses is already activated. - * @param {boolean} isActivated - */ - private throwIfWarehousesActivated = (isActivated: boolean) => { - if (isActivated) { - throw new ServiceError(ERRORS.MUTLI_WAREHOUSES_ALREADY_ACTIVATED); - } - }; - - /** - * Activates the multi-warehouses. - * - * - Creates a new warehouses and mark it as primary. - * - Seed warehouses items quantity. - * - Mutate inventory transactions with the primary warehouse. - * -------- - * @param {number} tenantId - * @returns {Promise} - */ - public activateWarehouses = (tenantId: number): Promise => { - // Retrieve whether the multi-warehouses is active. - const isActivated = this.settings.isMultiWarehousesActive(tenantId); - - // Throw error if the warehouses is already activated. - this.throwIfWarehousesActivated(isActivated); - - // Activates multi-warehouses on unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseActivate` event. - await this.eventPublisher.emitAsync(events.warehouse.onActivate, { - tenantId, - trx, - }); - // Creates a primary warehouse on the storage.. - const primaryWarehouse = - await this.createInitialWarehouse.createInitialWarehouse(tenantId); - - // Marks the multi-warehouses is activated. - this.settings.markMutliwarehoussAsActivated(tenantId); - - // Triggers `onWarehouseActivated` event. - await this.eventPublisher.emitAsync(events.warehouse.onActivated, { - tenantId, - primaryWarehouse, - trx, - }); - }); - }; -} diff --git a/packages/server/src/services/Warehouses/ActivateWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/ActivateWarehousesSubscriber.ts deleted file mode 100644 index 165be4cbc..000000000 --- a/packages/server/src/services/Warehouses/ActivateWarehousesSubscriber.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import { UpdateInventoryTransactionsWithWarehouse } from './UpdateInventoryTransactionsWithWarehouse'; -import { CreateInitialWarehousesItemsQuantity } from './CreateInitialWarehousesitemsQuantity'; - -@Service() -export class ActivateWarehousesSubscriber { - @Inject() - private updateInventoryTransactionsWithWarehouse: UpdateInventoryTransactionsWithWarehouse; - - @Inject() - private createInitialWarehousesItemsQuantity: CreateInitialWarehousesItemsQuantity; - - /** - * Attaches events with handlers. - */ - attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateInventoryTransactionsWithWarehouseOnActivating - ); - bus.subscribe( - events.warehouse.onActivated, - this.createInitialWarehousesItemsQuantityOnActivating - ); - return bus; - } - - /** - * Updates inventory transactiont to primary warehouse once - * multi-warehouses activated. - * @param {IWarehousesActivatedPayload} - */ - private updateInventoryTransactionsWithWarehouseOnActivating = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.updateInventoryTransactionsWithWarehouse.run( - tenantId, - primaryWarehouse.id - ); - }; - - /** - * Creates initial warehouses items quantity once the multi-warehouses activated. - * @param {IWarehousesActivatedPayload} - */ - private createInitialWarehousesItemsQuantityOnActivating = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.createInitialWarehousesItemsQuantity.run( - tenantId, - primaryWarehouse.id - ); - }; -} diff --git a/packages/server/src/services/Warehouses/CRUDWarehouse.ts b/packages/server/src/services/Warehouses/CRUDWarehouse.ts deleted file mode 100644 index 92eddba10..000000000 --- a/packages/server/src/services/Warehouses/CRUDWarehouse.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './contants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -export class CRUDWarehouse { - @Inject() - tenancy: HasTenancyService; - - getWarehouseOrThrowNotFound = async (tenantId: number, warehouseId: number) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const foundWarehouse = await Warehouse.query().findById(warehouseId); - - if (!foundWarehouse) { - throw new ServiceError(ERRORS.WAREHOUSE_NOT_FOUND); - } - return foundWarehouse; - }; - - throwIfWarehouseNotFound = (warehouse) => { - if (!warehouse) { - throw new ServiceError(ERRORS.WAREHOUSE_NOT_FOUND); - } - } -} diff --git a/packages/server/src/services/Warehouses/CreateInitialWarehouse.ts b/packages/server/src/services/Warehouses/CreateInitialWarehouse.ts deleted file mode 100644 index db25e1914..000000000 --- a/packages/server/src/services/Warehouses/CreateInitialWarehouse.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CreateWarehouse } from './CreateWarehouse'; - -@Service() -export class CreateInitialWarehouse { - @Inject() - private createWarehouse: CreateWarehouse; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Creates a initial warehouse. - * @param {number} tenantId - */ - public createInitialWarehouse = async (tenantId: number) => { - const { __ } = this.tenancy.i18n(tenantId); - - return this.createWarehouse.createWarehouse(tenantId, { - name: __('warehouses.primary_warehouse'), - code: '10001', - primary: true, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/CreateInitialWarehousesitemsQuantity.ts b/packages/server/src/services/Warehouses/CreateInitialWarehousesitemsQuantity.ts deleted file mode 100644 index 876408fcd..000000000 --- a/packages/server/src/services/Warehouses/CreateInitialWarehousesitemsQuantity.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { IItem, IItemWarehouseQuantityChange } from '@/interfaces'; -import { WarehousesItemsQuantitySync } from './Integrations/WarehousesItemsQuantitySync'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class CreateInitialWarehousesItemsQuantity { - @Inject() - private warehousesItemsQuantitySync: WarehousesItemsQuantitySync; - - @Inject() - private tenancy: HasTenancyService; - - /** - * Retrieves items warehouses quantity changes of the given inventory items. - * @param {IItem[]} items - * @param {IWarehouse} primaryWarehouse - * @returns {IItemWarehouseQuantityChange[]} - */ - private getWarehousesItemsChanges = ( - items: IItem[], - primaryWarehouseId: number - ): IItemWarehouseQuantityChange[] => { - return items - .filter((item: IItem) => item.quantityOnHand) - .map((item: IItem) => ({ - itemId: item.id, - warehouseId: primaryWarehouseId, - amount: item.quantityOnHand, - })); - }; - - /** - * Creates initial warehouses items quantity. - * @param {number} tenantId - */ - public run = async ( - tenantId: number, - primaryWarehouseId: number, - trx?: Knex.Transaction - ): Promise => { - const { Item } = this.tenancy.models(tenantId); - - const items = await Item.query(trx).where('type', 'Inventory'); - - const warehousesChanges = this.getWarehousesItemsChanges( - items, - primaryWarehouseId - ); - await this.warehousesItemsQuantitySync.mutateWarehousesItemsQuantity( - tenantId, - warehousesChanges, - trx - ); - }; -} diff --git a/packages/server/src/services/Warehouses/CreateWarehouse.ts b/packages/server/src/services/Warehouses/CreateWarehouse.ts deleted file mode 100644 index 866c8b443..000000000 --- a/packages/server/src/services/Warehouses/CreateWarehouse.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { - ICreateWarehouseDTO, - IWarehouse, - IWarehouseCreatedPayload, - IWarehouseCreatePayload, -} from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import events from '@/subscribers/events'; -import { WarehouseValidator } from './WarehouseValidator'; - -@Service() -export class CreateWarehouse { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private validator: WarehouseValidator; - - /** - * Authorize the warehouse before deleting. - * @param {number} tenantId - - * @param {ICreateWarehouseDTO} warehouseDTO - - */ - public authorize = async ( - tenantId: number, - warehouseDTO: ICreateWarehouseDTO - ) => { - if (warehouseDTO.code) { - await this.validator.validateWarehouseCodeUnique( - tenantId, - warehouseDTO.code - ); - } - }; - - /** - * Creates a new warehouse on the system. - * @param {number} tenantId - * @param {ICreateWarehouseDTO} warehouseDTO - */ - public createWarehouse = async ( - tenantId: number, - warehouseDTO: ICreateWarehouseDTO - ): Promise => { - const { Warehouse } = this.tenancy.models(tenantId); - - // Authorize warehouse before creating. - await this.authorize(tenantId, warehouseDTO); - - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseCreate` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdit, { - tenantId, - warehouseDTO, - trx, - } as IWarehouseCreatePayload); - - // Creates a new warehouse on the storage. - const warehouse = await Warehouse.query(trx).insertAndFetch({ - ...warehouseDTO, - }); - // Triggers `onWarehouseCreated` event. - await this.eventPublisher.emitAsync(events.warehouse.onCreated, { - tenantId, - warehouseDTO, - warehouse, - trx, - } as IWarehouseCreatedPayload); - - return warehouse; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/DeleteItemWarehousesQuantity.ts b/packages/server/src/services/Warehouses/DeleteItemWarehousesQuantity.ts deleted file mode 100644 index 1e92e2162..000000000 --- a/packages/server/src/services/Warehouses/DeleteItemWarehousesQuantity.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class DeleteItemWarehousesQuantity { - @Inject() - private tenancy: HasTenancyService; - - /** - * Deletes the given item warehouses quantities. - * @param {number} tenantId - * @param {number} itemId - * @param {Knex.Transaction} trx - - */ - public deleteItemWarehousesQuantity = async ( - tenantId: number, - itemId: number, - trx?: Knex.Transaction - ): Promise => { - const { ItemWarehouseQuantity } = this.tenancy.models(tenantId); - - await ItemWarehouseQuantity.query(trx).where('itemId', itemId).delete(); - }; -} diff --git a/packages/server/src/services/Warehouses/DeleteWarehouse.ts b/packages/server/src/services/Warehouses/DeleteWarehouse.ts deleted file mode 100644 index 392519cf3..000000000 --- a/packages/server/src/services/Warehouses/DeleteWarehouse.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { IWarehouseDeletedPayload, IWarehouseDeletePayload } from '@/interfaces'; -import { CRUDWarehouse } from './CRUDWarehouse'; -import { WarehouseValidator } from './WarehouseValidator'; -import { ERRORS } from './contants'; - -@Service() -export class DeleteWarehouse extends CRUDWarehouse { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - @Inject() - validator: WarehouseValidator; - - /** - * Validates the given warehouse before deleting. - * @param {number} tenantId - * @param {number} warehouseId - * @returns {Promise} - */ - public authorize = async (tenantId: number, warehouseId: number) => { - await this.validator.validateWarehouseNotOnlyWarehouse( - tenantId, - warehouseId - ); - }; - - /** - * Deletes specific warehouse. - * @param {number} tenantId - * @param {number} warehouseId - * @returns {Promise} - */ - public deleteWarehouse = async ( - tenantId: number, - warehouseId: number - ): Promise => { - const { Warehouse } = this.tenancy.models(tenantId); - - // Retrieves the old warehouse or throw not found service error. - const oldWarehouse = await Warehouse.query() - .findById(warehouseId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS, - }); - - // Validates the given warehouse before deleting. - await this.authorize(tenantId, warehouseId); - - // Creates a new warehouse under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - const eventPayload = { - tenantId, - warehouseId, - oldWarehouse, - trx, - } as IWarehouseDeletePayload | IWarehouseDeletedPayload; - - // Triggers `onWarehouseCreate`. - await this.eventPublisher.emitAsync( - events.warehouse.onDelete, - eventPayload - ); - // Delets the given warehouse from the storage. - await Warehouse.query().findById(warehouseId).delete(); - - // Triggers `onWarehouseCreated`. - await this.eventPublisher.emitAsync( - events.warehouse.onDeleted, - eventPayload as IWarehouseDeletedPayload - ); - }); - }; -} diff --git a/packages/server/src/services/Warehouses/EditWarehouse.ts b/packages/server/src/services/Warehouses/EditWarehouse.ts deleted file mode 100644 index 285e9406d..000000000 --- a/packages/server/src/services/Warehouses/EditWarehouse.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { Knex } from 'knex'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { IEditWarehouseDTO, IWarehouse } from '@/interfaces'; -import { WarehouseValidator } from './WarehouseValidator'; - -@Service() -export class EditWarehouse { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private validator: WarehouseValidator; - - /** - * Authorize the warehouse before deleting. - * @param {number} tenantId - - * @param {ICreateWarehouseDTO} warehouseDTO - - */ - public authorize = async ( - tenantId: number, - warehouseDTO: IEditWarehouseDTO, - warehouseId: number - ) => { - if (warehouseDTO.code) { - await this.validator.validateWarehouseCodeUnique( - tenantId, - warehouseDTO.code, - warehouseId - ); - } - }; - - /** - * Edits a new warehouse on the system. - * @param {number} tenantId - * @param {ICreateWarehouseDTO} warehouseDTO - * @returns {Promise} - */ - public editWarehouse = async ( - tenantId: number, - warehouseId: number, - warehouseDTO: IEditWarehouseDTO - ): Promise => { - const { Warehouse } = this.tenancy.models(tenantId); - - // Authorize the warehouse DTO before editing. - await this.authorize(tenantId, warehouseDTO, warehouseId); - - // Edits warehouse under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseEdit` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdit, { - tenantId, - warehouseId, - warehouseDTO, - trx, - }); - // Updates the given branch on the storage. - const warehouse = await Warehouse.query().patchAndFetchById(warehouseId, { - ...warehouseDTO, - }); - // Triggers `onWarehouseEdited` event. - await this.eventPublisher.emitAsync(events.warehouse.onEdited, { - tenantId, - warehouse, - warehouseDTO, - trx, - }); - return warehouse; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/EventsProvider.ts b/packages/server/src/services/Warehouses/EventsProvider.ts deleted file mode 100644 index bdf02774b..000000000 --- a/packages/server/src/services/Warehouses/EventsProvider.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - BillsActivateWarehousesSubscriber, - CreditsActivateWarehousesSubscriber, - InvoicesActivateWarehousesSubscriber, - ReceiptsActivateWarehousesSubscriber, - EstimatesActivateWarehousesSubscriber, - InventoryActivateWarehousesSubscriber, - VendorCreditsActivateWarehousesSubscriber, -} from './Subscribers/Activate'; -import { - BillWarehousesValidateSubscriber, - CreditNoteWarehousesValidateSubscriber, - SaleReceiptWarehousesValidateSubscriber, - SaleEstimateWarehousesValidateSubscriber, - SaleInvoicesWarehousesValidateSubscriber, - VendorCreditWarehousesValidateSubscriber, - InventoryAdjustmentWarehouseValidatorSubscriber, -} from './Subscribers/Validators'; -import { DeleteItemWarehousesQuantitySubscriber } from './Subscribers/DeleteItemWarehousesQuantitySubscriber'; - -export default () => [ - BillsActivateWarehousesSubscriber, - CreditsActivateWarehousesSubscriber, - InvoicesActivateWarehousesSubscriber, - ReceiptsActivateWarehousesSubscriber, - EstimatesActivateWarehousesSubscriber, - InventoryActivateWarehousesSubscriber, - VendorCreditsActivateWarehousesSubscriber, - - BillWarehousesValidateSubscriber, - CreditNoteWarehousesValidateSubscriber, - SaleReceiptWarehousesValidateSubscriber, - SaleEstimateWarehousesValidateSubscriber, - SaleInvoicesWarehousesValidateSubscriber, - VendorCreditWarehousesValidateSubscriber, - InventoryAdjustmentWarehouseValidatorSubscriber, - - DeleteItemWarehousesQuantitySubscriber, -]; diff --git a/packages/server/src/services/Warehouses/GetWarehouse.ts b/packages/server/src/services/Warehouses/GetWarehouse.ts deleted file mode 100644 index e403a1864..000000000 --- a/packages/server/src/services/Warehouses/GetWarehouse.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { CRUDWarehouse } from './CRUDWarehouse'; - -@Service() -export class GetWarehouse extends CRUDWarehouse { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieves warehouse details. - * @param {number} tenantId - * @returns - */ - public getWarehouse = async (tenantId: number, warehouseId: number) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouse = await Warehouse.query().findById(warehouseId); - - this.throwIfWarehouseNotFound(warehouse); - - return warehouse; - }; -} diff --git a/packages/server/src/services/Warehouses/GetWarehouses.ts b/packages/server/src/services/Warehouses/GetWarehouses.ts deleted file mode 100644 index 631dbc205..000000000 --- a/packages/server/src/services/Warehouses/GetWarehouses.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class GetWarehouses { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieves warehouses list. - * @param {number} tenantId - * @returns - */ - public getWarehouses = async (tenantId: number) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouses = await Warehouse.query().orderBy('name', 'DESC'); - - return warehouses; - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/ValidateWarehouseExistance.ts b/packages/server/src/services/Warehouses/Integrations/ValidateWarehouseExistance.ts deleted file mode 100644 index c8892670e..000000000 --- a/packages/server/src/services/Warehouses/Integrations/ValidateWarehouseExistance.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { chain, difference } from 'lodash'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class ValidateWarehouseExistance { - @Inject() - tenancy: HasTenancyService; - - /** - * Validate transaction warehouse id existance. - * @param transDTO - * @param entries - */ - public validateWarehouseIdExistance = ( - transDTO: { warehouseId?: number }, - entries: { warehouseId?: number }[] = [] - ) => { - const notAssignedWarehouseEntries = entries.filter((e) => !e.warehouseId); - - if (notAssignedWarehouseEntries.length > 0 && !transDTO.warehouseId) { - throw new ServiceError(ERRORS.WAREHOUSE_ID_NOT_FOUND); - } - if (entries.length === 0 && !transDTO.warehouseId) { - throw new ServiceError(ERRORS.WAREHOUSE_ID_NOT_FOUND); - } - }; - - /** - * Validate warehouse existance. - * @param {number} tenantId - * @param {number} warehouseId - */ - public validateWarehouseExistance = ( - tenantId: number, - warehouseId: number - ) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouse = Warehouse.query().findById(warehouseId); - - if (!warehouse) { - throw new ServiceError(ERRORS.WAREHOUSE_ID_NOT_FOUND); - } - }; - - /** - * - * @param {number} tenantId - * @param {{ warehouseId?: number }[]} entries - */ - public validateItemEntriesWarehousesExistance = async ( - tenantId: number, - entries: { warehouseId?: number }[] - ) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const entriesWarehousesIds = chain(entries) - .filter((e) => !!e.warehouseId) - .map((e) => e.warehouseId) - .uniq() - .value(); - - const warehouses = await Warehouse.query().whereIn( - 'id', - entriesWarehousesIds - ); - const warehousesIds = warehouses.map((e) => e.id); - const notFoundWarehousesIds = difference( - entriesWarehousesIds, - warehousesIds - ); - if (notFoundWarehousesIds.length > 0) { - throw new ServiceError(ERRORS.WAREHOUSE_ID_NOT_FOUND); - } - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts b/packages/server/src/services/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts deleted file mode 100644 index 297ae5aa6..000000000 --- a/packages/server/src/services/Warehouses/Integrations/WarehouseTransactionDTOTransform.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { omit } from 'lodash'; -import * as R from 'ramda'; -import { WarehousesSettings } from '../WarehousesSettings'; - -@Service() -export class WarehouseTransactionDTOTransform { - @Inject() - private warehousesSettings: WarehousesSettings; - - /** - * Excludes DTO warehouse id when mutli-warehouses feature is inactive. - * @param {number} tenantId - * @returns {Promise | T>} - */ - private excludeDTOWarehouseIdWhenInactive = < - T extends { warehouseId?: number } - >( - tenantId: number, - DTO: T - ): Omit | T => { - const isActive = this.warehousesSettings.isMultiWarehousesActive(tenantId); - - return !isActive ? omit(DTO, ['warehouseId']) : DTO; - }; - - /** - * - * @param {number} tenantId - * @param {T} DTO - - * @returns {Omit | T} - */ - public transformDTO = - (tenantId: number) => - (DTO: T): Omit | T => { - return this.excludeDTOWarehouseIdWhenInactive(tenantId, DTO); - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/WarehousesDTOValidators.ts b/packages/server/src/services/Warehouses/Integrations/WarehousesDTOValidators.ts deleted file mode 100644 index 6e2d71067..000000000 --- a/packages/server/src/services/Warehouses/Integrations/WarehousesDTOValidators.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { isEmpty } from 'lodash'; -import { ValidateWarehouseExistance } from './ValidateWarehouseExistance'; -import { WarehousesSettings } from '../WarehousesSettings'; - -interface IWarehouseTransactionDTO { - warehouseId?: number|null; - entries?: { warehouseId?: number|null }[]; -} - -@Service() -export class WarehousesDTOValidators { - @Inject() - private validateWarehouseExistanceService: ValidateWarehouseExistance; - - @Inject() - private warehousesSettings: WarehousesSettings; - - /** - * Validates the warehouse existance of sale invoice transaction. - * @param {number} tenantId - * @param {ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO} saleInvoiceDTO - */ - public validateDTOWarehouseExistance = async ( - tenantId: number, - DTO: IWarehouseTransactionDTO - ) => { - // Validates the sale invoice warehouse id existance. - this.validateWarehouseExistanceService.validateWarehouseIdExistance( - DTO, - DTO.entries - ); - // Validate the sale invoice warehouse existance on the storage. - if (DTO.warehouseId) { - this.validateWarehouseExistanceService.validateWarehouseExistance( - tenantId, - DTO.warehouseId - ); - } - // Validate the sale invoice entries warehouses existance on the storage. - if (!isEmpty(DTO.entries)) { - await this.validateWarehouseExistanceService.validateItemEntriesWarehousesExistance( - tenantId, - DTO.entries - ); - } - }; - - /** - * Validate the warehouse existance of - * @param {number} tenantId - * @param {IWarehouseTransactionDTO} saleInvoiceDTO - * @returns - */ - public validateDTOWarehouseWhenActive = async ( - tenantId: number, - DTO: IWarehouseTransactionDTO - ): Promise => { - const isActive = this.warehousesSettings.isMultiWarehousesActive(tenantId); - - // Can't continue if the multi-warehouses feature is inactive. - if (!isActive) return; - - return this.validateDTOWarehouseExistance(tenantId, DTO); - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantity.ts b/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantity.ts deleted file mode 100644 index cbf00c909..000000000 --- a/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantity.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { - IInventoryTransaction, - IItemWarehouseQuantityChange, -} from '@/interfaces'; -import { set, get, chain, toPairs } from 'lodash'; - -export class WarehousesItemsQuantity { - balanceMap: { [warehouseId: number]: { [itemId: number]: number } } = {}; - /** - * - * @param {number} warehouseId - * @param {number} itemId - * @returns {number} - */ - public get = (warehouseId: number, itemId: number): number => { - return get(this.balanceMap, `${warehouseId}.${itemId}`, 0); - }; - - /** - * - * @param {number} warehouseId - * @param {number} itemId - * @param {number} amount - * @returns {WarehousesItemsQuantity} - */ - public set = (warehouseId: number, itemId: number, amount: number) => { - if (!get(this.balanceMap, warehouseId)) { - set(this.balanceMap, warehouseId, {}); - } - set(this.balanceMap, `${warehouseId}.${itemId}`, amount); - - return this; - }; - - /** - * - * @param {number} warehouseId - * @param {number} itemId - * @param {number} amount - * @returns {WarehousesItemsQuantity} - */ - public increment = (warehouseId: number, itemId: number, amount: number) => { - const oldAmount = this.get(warehouseId, itemId); - - return this.set(warehouseId, itemId, oldAmount + amount); - }; - - /** - * - * @param {number} warehouseId - * @param {number} itemId - * @param {number} amount - * @returns {WarehousesItemsQuantity} - */ - public decrement = (warehouseId: number, itemId: number, amount: number) => { - const oldAmount = this.get(warehouseId, itemId); - - return this.set(warehouseId, itemId, oldAmount - amount); - }; - - /** - * - * @returns {WarehousesItemsQuantity} - */ - public reverse = () => { - const collection = this.toArray(); - - collection.forEach((change) => { - this.set(change.warehouseId, change.itemId, change.amount * -1); - }); - return this; - }; - - /** - * - * @returns {IItemWarehouseQuantityChange[]} - */ - public toArray = (): IItemWarehouseQuantityChange[] => { - return chain(this.balanceMap) - .toPairs() - .map(([warehouseId, item]) => { - const pairs = toPairs(item); - - return pairs.map(([itemId, amount]) => ({ - itemId: parseInt(itemId), - warehouseId: parseInt(warehouseId), - amount, - })); - }) - .flatten() - .value(); - }; - - /** - * - * @param {IInventoryTransaction[]} inventoryTransactions - * @returns {WarehousesItemsQuantity} - */ - static fromInventoryTransaction = ( - inventoryTransactions: IInventoryTransaction[] - ): WarehousesItemsQuantity => { - const warehouseTransactions = inventoryTransactions.filter( - (transaction) => transaction.warehouseId - ); - const warehouseItemsQuantity = new WarehousesItemsQuantity(); - - warehouseTransactions.forEach((transaction: IInventoryTransaction) => { - const change = - transaction.direction === 'IN' - ? warehouseItemsQuantity.increment - : warehouseItemsQuantity.decrement; - - change(transaction.warehouseId, transaction.itemId, transaction.quantity); - }); - return warehouseItemsQuantity; - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts b/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts deleted file mode 100644 index d1b8e3836..000000000 --- a/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySynSubscriber.ts +++ /dev/null @@ -1,74 +0,0 @@ -import events from '@/subscribers/events'; -import { Service, Inject } from 'typedi'; -import { WarehousesItemsQuantitySync } from './WarehousesItemsQuantitySync'; -import { - IInventoryTransactionsCreatedPayload, - IInventoryTransactionsDeletedPayload, -} from '@/interfaces'; -import { WarehousesSettings } from '../WarehousesSettings'; - -@Service() -export class WarehousesItemsQuantitySyncSubscriber { - @Inject() - private warehousesItemsQuantitySync: WarehousesItemsQuantitySync; - - @Inject() - private warehousesSettings: WarehousesSettings; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.inventory.onInventoryTransactionsCreated, - this.syncWarehousesItemsQuantityOnInventoryTransCreated - ); - bus.subscribe( - events.inventory.onInventoryTransactionsDeleted, - this.syncWarehousesItemsQuantityOnInventoryTransDeleted - ); - return bus; - } - - /** - * Syncs warehouses items quantity once inventory transactions created. - * @param {IInventoryTransactionsCreatedPayload} - */ - private syncWarehousesItemsQuantityOnInventoryTransCreated = async ({ - tenantId, - inventoryTransactions, - trx, - }: IInventoryTransactionsCreatedPayload) => { - const isActive = this.warehousesSettings.isMultiWarehousesActive(tenantId); - - // Can't continue if the warehouses features is not active. - if (!isActive) return; - - await this.warehousesItemsQuantitySync.mutateWarehousesItemsQuantityFromTransactions( - tenantId, - inventoryTransactions, - trx - ); - }; - - /** - * Syncs warehouses items quantity once inventory transactions deleted. - * @param {IInventoryTransactionsDeletedPayload} - */ - private syncWarehousesItemsQuantityOnInventoryTransDeleted = async ({ - tenantId, - oldInventoryTransactions, - trx, - }: IInventoryTransactionsDeletedPayload) => { - const isActive = this.warehousesSettings.isMultiWarehousesActive(tenantId); - - // Can't continue if the warehouses feature is not active yet. - if (!isActive) return; - - await this.warehousesItemsQuantitySync.reverseWarehousesItemsQuantityFromTransactions( - tenantId, - oldInventoryTransactions, - trx - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySync.ts b/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySync.ts deleted file mode 100644 index ed1166397..000000000 --- a/packages/server/src/services/Warehouses/Integrations/WarehousesItemsQuantitySync.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Knex } from 'knex'; -import { Service, Inject } from 'typedi'; -import { omit } from 'lodash'; -import { - IInventoryTransaction, - IItemWarehouseQuantityChange, -} from '@/interfaces'; -import { WarehousesItemsQuantity } from './WarehousesItemsQuantity'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class WarehousesItemsQuantitySync { - @Inject() - tenancy: HasTenancyService; - - /** - * Retrieves the reversed warehouses items quantity changes. - * @param {IInventoryTransaction[]} inventoryTransactions - * @returns {IItemWarehouseQuantityChange[]} - */ - public getReverseWarehousesItemsQuantityChanges = ( - inventoryTransactions: IInventoryTransaction[] - ): IItemWarehouseQuantityChange[] => { - const warehouseItemsQuantity = - WarehousesItemsQuantity.fromInventoryTransaction(inventoryTransactions); - - return warehouseItemsQuantity.reverse().toArray(); - }; - - /** - * Retrieves the warehouses items changes from the given inventory tranasctions. - * @param {IInventoryTransaction[]} inventoryTransactions - * @returns {IItemWarehouseQuantityChange[]} - */ - public getWarehousesItemsQuantityChange = ( - inventoryTransactions: IInventoryTransaction[] - ): IItemWarehouseQuantityChange[] => { - const warehouseItemsQuantity = - WarehousesItemsQuantity.fromInventoryTransaction(inventoryTransactions); - - return warehouseItemsQuantity.toArray(); - }; - - /** - * Mutates warehouses items quantity on hand on the storage. - * @param {number} tenantId - * @param {IItemWarehouseQuantityChange[]} warehousesItemsQuantity - * @param {Knex.Transaction} trx - */ - public mutateWarehousesItemsQuantity = async ( - tenantId: number, - warehousesItemsQuantity: IItemWarehouseQuantityChange[], - trx?: Knex.Transaction - ): Promise => { - const mutationsOpers = warehousesItemsQuantity.map( - (change: IItemWarehouseQuantityChange) => - this.mutateWarehouseItemQuantity(tenantId, change, trx) - ); - await Promise.all(mutationsOpers); - }; - - /** - * Mutates the warehouse item quantity. - * @param {number} tenantId - * @param {number} warehouseItemQuantity - * @param {Knex.Transaction} trx - */ - public mutateWarehouseItemQuantity = async ( - tenantId: number, - warehouseItemQuantity: IItemWarehouseQuantityChange, - trx: Knex.Transaction - ): Promise => { - const { ItemWarehouseQuantity } = this.tenancy.models(tenantId); - - const itemWarehouseQuantity = await ItemWarehouseQuantity.query(trx) - .where('itemId', warehouseItemQuantity.itemId) - .where('warehouseId', warehouseItemQuantity.warehouseId) - .first(); - - if (itemWarehouseQuantity) { - await ItemWarehouseQuantity.changeAmount( - { - itemId: warehouseItemQuantity.itemId, - warehouseId: warehouseItemQuantity.warehouseId, - }, - 'quantityOnHand', - warehouseItemQuantity.amount, - trx - ); - } else { - await ItemWarehouseQuantity.query(trx).insert({ - ...omit(warehouseItemQuantity, ['amount']), - quantityOnHand: warehouseItemQuantity.amount, - }); - } - }; - - /** - * Mutates warehouses items quantity from inventory transactions. - * @param {number} tenantId - - * @param {IInventoryTransaction[]} inventoryTransactions - - * @param {Knex.Transaction} - */ - public mutateWarehousesItemsQuantityFromTransactions = async ( - tenantId: number, - inventoryTransactions: IInventoryTransaction[], - trx?: Knex.Transaction - ) => { - const changes = this.getWarehousesItemsQuantityChange( - inventoryTransactions - ); - await this.mutateWarehousesItemsQuantity(tenantId, changes, trx); - }; - - /** - * Reverses warehouses items quantity from inventory transactions. - * @param {number} tenantId - * @param {IInventoryTransaction[]} inventoryTransactions - * @param {Knex.Transaction} trx - */ - public reverseWarehousesItemsQuantityFromTransactions = async ( - tenantId: number, - inventoryTransactions: IInventoryTransaction[], - trx?: Knex.Transaction - ) => { - const changes = this.getReverseWarehousesItemsQuantityChanges( - inventoryTransactions - ); - await this.mutateWarehousesItemsQuantity(tenantId, changes, trx); - }; -} diff --git a/packages/server/src/services/Warehouses/Integrations/constants.ts b/packages/server/src/services/Warehouses/Integrations/constants.ts deleted file mode 100644 index f1799f58d..000000000 --- a/packages/server/src/services/Warehouses/Integrations/constants.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const ERRORS = { - WAREHOUSE_ID_NOT_FOUND: 'WAREHOUSE_ID_NOT_FOUND', - ITEM_ENTRY_WAREHOUSE_ID_NOT_FOUND: 'ITEM_ENTRY_WAREHOUSE_ID_NOT_FOUND', -}; diff --git a/packages/server/src/services/Warehouses/Items/GetItemWarehouses.ts b/packages/server/src/services/Warehouses/Items/GetItemWarehouses.ts deleted file mode 100644 index 14ee97a2c..000000000 --- a/packages/server/src/services/Warehouses/Items/GetItemWarehouses.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { GetItemWarehouseTransformer } from './GettItemWarehouseTransformer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetItemWarehouses { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the item warehouses. - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public getItemWarehouses = async (tenantId: number, itemId: number) => { - const { ItemWarehouseQuantity, Item } = this.tenancy.models(tenantId); - - // Retrieves specific item or throw not found service error. - const item = await Item.query().findById(itemId).throwIfNotFound(); - - const itemWarehouses = await ItemWarehouseQuantity.query() - .where('itemId', itemId) - .withGraphFetched('warehouse'); - - // Retrieves the transformed items warehouses. - return this.transformer.transform( - tenantId, - itemWarehouses, - new GetItemWarehouseTransformer() - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Items/GettItemWarehouseTransformer.ts b/packages/server/src/services/Warehouses/Items/GettItemWarehouseTransformer.ts deleted file mode 100644 index 25ae36ca4..000000000 --- a/packages/server/src/services/Warehouses/Items/GettItemWarehouseTransformer.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { formatNumber } from 'utils'; - -export class GetItemWarehouseTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return [ - 'warehouseId', - 'warehouseName', - 'warehouseCode', - 'quantityOnHandFormatted', - ]; - }; - - public excludeAttributes = (): string[] => { - return ['warehouse']; - }; - - /** - * Formatted sell price. - * @param item - * @returns {string} - */ - public quantityOnHandFormatted(item): string { - return formatNumber(item.quantityOnHand, { money: false }); - } - - public warehouseCode(item): string { - return item.warehouse.code; - } - - public warehouseName(item): string { - return item.warehouse.name; - } - - public warehouseId(item): number { - return item.warehouse.id; - } -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/BillWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/BillWarehousesActivateSubscriber.ts deleted file mode 100644 index 3f7ae4ae1..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/BillWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { BillActivateWarehouses } from '../../Activate/BillWarehousesActivate'; - -@Service() -export class BillsActivateWarehousesSubscriber { - @Inject() - private billsActivateWarehouses: BillActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateBillsWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all inventory transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateBillsWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.billsActivateWarehouses.updateBillsWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts deleted file mode 100644 index 71619e603..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/CreditNoteWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { CreditNotesActivateWarehouses } from '../../Activate/CreditNoteWarehousesActivate'; - -@Service() -export class CreditsActivateWarehousesSubscriber { - @Inject() - private creditsActivateWarehouses: CreditNotesActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateInvoicesWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all inventory transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateInvoicesWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.creditsActivateWarehouses.updateCreditsWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/EstimateWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/EstimateWarehousesActivateSubscriber.ts deleted file mode 100644 index cb3ed9810..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/EstimateWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { EstimatesActivateWarehouses } from '../../Activate/EstimateWarehousesActivate'; - -@Service() -export class EstimatesActivateWarehousesSubscriber { - @Inject() - private estimatesActivateWarehouses: EstimatesActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateEstimatessWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all inventory transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateEstimatessWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.estimatesActivateWarehouses.updateEstimatesWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts deleted file mode 100644 index 12914fa38..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/InventoryTransactionsWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { InventoryActivateWarehouses } from '../../Activate/InventoryTransactionsWarehousesActivate'; - -@Service() -export class InventoryActivateWarehousesSubscriber { - @Inject() - private inventoryActivateWarehouses: InventoryActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateInventoryTransactionsWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all inventory transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateInventoryTransactionsWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.inventoryActivateWarehouses.updateInventoryTransactionsWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts deleted file mode 100644 index 8d2c82fc4..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/InvoiceWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { InvoicesActivateWarehouses } from '../../Activate/InvoiceWarehousesActivate'; - -@Service() -export class InvoicesActivateWarehousesSubscriber { - @Inject() - private invoicesActivateWarehouses: InvoicesActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateInvoicesWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all inventory transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateInvoicesWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.invoicesActivateWarehouses.updateInvoicesWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts deleted file mode 100644 index 3e9077a7c..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/ReceiptWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { ReceiptActivateWarehouses } from '../../Activate/ReceiptWarehousesActivate'; - -@Service() -export class ReceiptsActivateWarehousesSubscriber { - @Inject() - private receiptsActivateWarehouses: ReceiptActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateInventoryTransactionsWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all receipts transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateInventoryTransactionsWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.receiptsActivateWarehouses.updateReceiptsWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts deleted file mode 100644 index ace6d4e11..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/VendorCreditWarehousesActivateSubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { IWarehousesActivatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { VendorCreditActivateWarehouses } from '../../Activate/VendorCreditWarehousesActivate'; - -@Service() -export class VendorCreditsActivateWarehousesSubscriber { - @Inject() - private creditsActivateWarehouses: VendorCreditActivateWarehouses; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.warehouse.onActivated, - this.updateCreditsWithWarehouseOnActivated - ); - return bus; - } - - /** - * Updates all inventory transactions with the primary warehouse once - * multi-warehouses feature is activated. - * @param {IWarehousesActivatedPayload} - */ - private updateCreditsWithWarehouseOnActivated = async ({ - tenantId, - primaryWarehouse, - }: IWarehousesActivatedPayload) => { - await this.creditsActivateWarehouses.updateCreditsWithWarehouse( - tenantId, - primaryWarehouse - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Activate/index.ts b/packages/server/src/services/Warehouses/Subscribers/Activate/index.ts deleted file mode 100644 index 16febf17c..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Activate/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable import/extensions */ -export * from './BillWarehousesActivateSubscriber'; -export * from './CreditNoteWarehousesActivateSubscriber'; -export * from './EstimateWarehousesActivateSubscriber'; -export * from './InventoryTransactionsWarehousesActivateSubscriber'; -export * from './VendorCreditWarehousesActivateSubscriber'; -export * from './ReceiptWarehousesActivateSubscriber'; -export * from './InvoiceWarehousesActivateSubscriber'; diff --git a/packages/server/src/services/Warehouses/Subscribers/DeleteItemWarehousesQuantitySubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/DeleteItemWarehousesQuantitySubscriber.ts deleted file mode 100644 index 1f925c34f..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/DeleteItemWarehousesQuantitySubscriber.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { DeleteItemWarehousesQuantity } from '../DeleteItemWarehousesQuantity'; -import { IItemEventDeletingPayload } from '@/interfaces'; - -@Service() -export class DeleteItemWarehousesQuantitySubscriber { - @Inject() - private deleteItemWarehousesQuantity: DeleteItemWarehousesQuantity; - - /** - * Attaches events. - */ - public attach(bus) { - bus.subscribe( - events.item.onDeleting, - this.deleteItemWarehouseQuantitiesOnItemDelete - ); - } - - /** - * Deletes the given item warehouses quantities once the item deleting. - * @param {IItemEventDeletingPayload} payload - - */ - private deleteItemWarehouseQuantitiesOnItemDelete = async ({ - tenantId, - oldItem, - trx, - }: IItemEventDeletingPayload) => { - await this.deleteItemWarehousesQuantity.deleteItemWarehousesQuantity( - tenantId, - oldItem.id, - trx - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts deleted file mode 100644 index 527474c8d..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IInventoryAdjustmentCreatingPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class InventoryAdjustmentWarehouseValidatorSubscriber { - @Inject() - private warehouseDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.inventoryAdjustment.onQuickCreating, - this.validateAdjustmentWarehouseExistanceOnCreating - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {IBillCreatingPayload} - */ - private validateAdjustmentWarehouseExistanceOnCreating = async ({ - quickAdjustmentDTO, - tenantId, - }: IInventoryAdjustmentCreatingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - quickAdjustmentDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/BillWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/BillWarehousesSubscriber.ts deleted file mode 100644 index d071b3d53..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/BillWarehousesSubscriber.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { IBillCreatingPayload, IBillEditingPayload } from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class BillWarehousesValidateSubscriber { - @Inject() - private warehouseDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.bill.onCreating, - this.validateBillWarehouseExistanceOnCreating - ); - bus.subscribe( - events.bill.onEditing, - this.validateSaleEstimateWarehouseExistanceOnEditing - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {IBillCreatingPayload} - */ - private validateBillWarehouseExistanceOnCreating = async ({ - billDTO, - tenantId, - }: IBillCreatingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - billDTO - ); - }; - - /** - * Validate warehouse existance of sale invoice once editing. - * @param {IBillEditingPayload} - */ - private validateSaleEstimateWarehouseExistanceOnEditing = async ({ - tenantId, - billDTO, - }: IBillEditingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - billDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts deleted file mode 100644 index 425bcd89f..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/Purchases/VendorCreditWarehousesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IVendorCreditCreatingPayload, - IVendorCreditEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class VendorCreditWarehousesValidateSubscriber { - @Inject() - warehouseDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.vendorCredit.onCreating, - this.validateVendorCreditWarehouseExistanceOnCreating - ); - bus.subscribe( - events.vendorCredit.onEditing, - this.validateSaleEstimateWarehouseExistanceOnEditing - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {IVendorCreditCreatingPayload} - */ - private validateVendorCreditWarehouseExistanceOnCreating = async ({ - vendorCreditCreateDTO, - tenantId, - }: IVendorCreditCreatingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - vendorCreditCreateDTO - ); - }; - - /** - * Validate warehouse existance of sale invoice once editing. - * @param {IVendorCreditEditingPayload} - */ - private validateSaleEstimateWarehouseExistanceOnEditing = async ({ - tenantId, - vendorCreditDTO, - }: IVendorCreditEditingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - vendorCreditDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts deleted file mode 100644 index 4a6f65c1e..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/CreditNoteWarehousesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ICreditNoteCreatingPayload, - ICreditNoteEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class CreditNoteWarehousesValidateSubscriber { - @Inject() - warehouseDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.creditNote.onCreating, - this.validateCreditNoteWarehouseExistanceOnCreating - ); - bus.subscribe( - events.creditNote.onEditing, - this.validateCreditNoteWarehouseExistanceOnEditing - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {ICreditNoteCreatingPayload} - */ - private validateCreditNoteWarehouseExistanceOnCreating = async ({ - creditNoteDTO, - tenantId, - }: ICreditNoteCreatingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - creditNoteDTO - ); - }; - - /** - * Validate warehouse existance of sale invoice once editing. - * @param {ICreditNoteEditingPayload} - */ - private validateCreditNoteWarehouseExistanceOnEditing = async ({ - tenantId, - creditNoteEditDTO, - }: ICreditNoteEditingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - creditNoteEditDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts deleted file mode 100644 index 402ecb04a..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleEstimateWarehousesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleEstimateCreatingPayload, - ISaleEstimateEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class SaleEstimateWarehousesValidateSubscriber { - @Inject() - warehouseDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleEstimate.onCreating, - this.validateSaleEstimateWarehouseExistanceOnCreating - ); - bus.subscribe( - events.saleEstimate.onEditing, - this.validateSaleEstimateWarehouseExistanceOnEditing - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {ISaleEstimateCreatingPayload} - */ - private validateSaleEstimateWarehouseExistanceOnCreating = async ({ - estimateDTO, - tenantId, - }: ISaleEstimateCreatingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - estimateDTO - ); - }; - - /** - * Validate warehouse existance of sale invoice once editing. - * @param {ISaleEstimateEditingPayload} - */ - private validateSaleEstimateWarehouseExistanceOnEditing = async ({ - tenantId, - estimateDTO, - }: ISaleEstimateEditingPayload) => { - await this.warehouseDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - estimateDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts deleted file mode 100644 index bc04b7228..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleInvoicesWarehousesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleInvoiceCreatingPaylaod, - ISaleInvoiceEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class SaleInvoicesWarehousesValidateSubscriber { - @Inject() - warehousesDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreating, - this.validateSaleInvoiceWarehouseExistanceOnCreating - ); - bus.subscribe( - events.saleInvoice.onEditing, - this.validateSaleInvoiceWarehouseExistanceOnEditing - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private validateSaleInvoiceWarehouseExistanceOnCreating = async ({ - saleInvoiceDTO, - tenantId, - }: ISaleInvoiceCreatingPaylaod) => { - await this.warehousesDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - saleInvoiceDTO - ); - }; - - /** - * Validate warehouse existance of sale invoice once editing. - * @param {ISaleInvoiceEditingPayload} - */ - private validateSaleInvoiceWarehouseExistanceOnEditing = async ({ - tenantId, - saleInvoiceDTO, - }: ISaleInvoiceEditingPayload) => { - await this.warehousesDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - saleInvoiceDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts deleted file mode 100644 index a32620706..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/Sales/SaleReceiptWarehousesSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleReceiptCreatingPayload, - ISaleReceiptEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { WarehousesDTOValidators } from '../../../Integrations/WarehousesDTOValidators'; - -@Service() -export class SaleReceiptWarehousesValidateSubscriber { - @Inject() - private warehousesDTOValidator: WarehousesDTOValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreating, - this.validateSaleReceiptWarehouseExistanceOnCreating - ); - bus.subscribe( - events.saleReceipt.onEditing, - this.validateSaleReceiptWarehouseExistanceOnEditing - ); - return bus; - } - - /** - * Validate warehouse existance of sale invoice once creating. - * @param {ISaleReceiptCreatingPayload} - */ - private validateSaleReceiptWarehouseExistanceOnCreating = async ({ - saleReceiptDTO, - tenantId, - }: ISaleReceiptCreatingPayload) => { - await this.warehousesDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - saleReceiptDTO - ); - }; - - /** - * Validate warehouse existance of sale invoice once editing. - * @param {ISaleReceiptEditingPayload} - */ - private validateSaleReceiptWarehouseExistanceOnEditing = async ({ - tenantId, - saleReceiptDTO, - }: ISaleReceiptEditingPayload) => { - await this.warehousesDTOValidator.validateDTOWarehouseWhenActive( - tenantId, - saleReceiptDTO - ); - }; -} diff --git a/packages/server/src/services/Warehouses/Subscribers/Validators/index.ts b/packages/server/src/services/Warehouses/Subscribers/Validators/index.ts deleted file mode 100644 index f0d4daa1d..000000000 --- a/packages/server/src/services/Warehouses/Subscribers/Validators/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './Purchases/BillWarehousesSubscriber'; -export * from './Purchases/VendorCreditWarehousesSubscriber'; - -export * from './Sales/SaleEstimateWarehousesSubscriber'; -export * from './Sales/CreditNoteWarehousesSubscriber'; -export * from './Sales/SaleInvoicesWarehousesSubscriber'; -export * from './Sales/SaleReceiptWarehousesSubscriber'; - -export * from './InventoryAdjustment/InventoryAdjustmentWarehouseValidatorSubscriber'; \ No newline at end of file diff --git a/packages/server/src/services/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts b/packages/server/src/services/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts deleted file mode 100644 index 82d8e3a8a..000000000 --- a/packages/server/src/services/Warehouses/UpdateInventoryTransactionsWithWarehouse.ts +++ /dev/null @@ -1,21 +0,0 @@ -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { Service, Inject } from 'typedi'; - -@Service() -export class UpdateInventoryTransactionsWithWarehouse { - @Inject() - tenancy: HasTenancyService; - - /** - * Updates all inventory transactions with primary warehouse. - * @param {number} tenantId - - * @param {number} warehouseId - - */ - public run = async (tenantId: number, primaryWarehouseId: number) => { - const { InventoryTransaction } = this.tenancy.models(tenantId); - - await InventoryTransaction.query().update({ - warehouseId: primaryWarehouseId, - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehouseMarkPrimary.ts b/packages/server/src/services/Warehouses/WarehouseMarkPrimary.ts deleted file mode 100644 index 4b11e1b93..000000000 --- a/packages/server/src/services/Warehouses/WarehouseMarkPrimary.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { CRUDWarehouse } from './CRUDWarehouse'; -import { - IWarehouseMarkAsPrimaryPayload, - IWarehouseMarkedAsPrimaryPayload, -} from '@/interfaces'; - -@Service() -export class WarehouseMarkPrimary extends CRUDWarehouse { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Marks the given warehouse as primary. - * @param {number} tenantId - * @param {number} warehouseId - * @returns {Promise} - */ - public markAsPrimary = async (tenantId: number, warehouseId: number) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const oldWarehouse = await this.getWarehouseOrThrowNotFound( - tenantId, - warehouseId - ); - // Updates the branches under unit-of-work enivrement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseMarkPrimary` event. - await this.eventPublisher.emitAsync(events.warehouse.onMarkPrimary, { - tenantId, - oldWarehouse, - trx, - } as IWarehouseMarkAsPrimaryPayload); - // marks all warehouses as not primary. - await Warehouse.query(trx).update({ primary: false }); - - // Marks the particular branch as primary. - const markedWarehouse = await Warehouse.query(trx).patchAndFetchById( - warehouseId, - { primary: true } - ); - // Triggers `onWarehouseMarkedPrimary` event. - await this.eventPublisher.emitAsync(events.warehouse.onMarkedPrimary, { - tenantId, - oldWarehouse, - markedWarehouse, - trx, - } as IWarehouseMarkedAsPrimaryPayload); - - return markedWarehouse; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehouseValidator.ts b/packages/server/src/services/Warehouses/WarehouseValidator.ts deleted file mode 100644 index 3ce99283c..000000000 --- a/packages/server/src/services/Warehouses/WarehouseValidator.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Inject, Service } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError, ServiceErrors } from '@/exceptions'; -import { ERRORS } from './contants'; - -@Service() -export class WarehouseValidator { - @Inject() - tenancy: HasTenancyService; - - /** - * - * @param {number} tenantId - * @param {number} warehouseId - */ - public validateWarehouseNotOnlyWarehouse = async ( - tenantId: number, - warehouseId: number - ) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouses = await Warehouse.query().whereNot('id', warehouseId); - - if (warehouses.length === 0) { - throw new ServiceError(ERRORS.COULD_NOT_DELETE_ONLY_WAERHOUSE); - } - }; - - /** - * - * @param tenantId - * @param code - * @param exceptWarehouseId - */ - public validateWarehouseCodeUnique = async ( - tenantId: number, - code: string, - exceptWarehouseId?: number - ) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouse = await Warehouse.query() - .onBuild((query) => { - query.select(['id']); - query.where('code', code); - - if (exceptWarehouseId) { - query.whereNot('id', exceptWarehouseId); - } - }) - .first(); - - if (warehouse) { - throw new ServiceError(ERRORS.WAREHOUSE_CODE_NOT_UNIQUE); - } - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesApplication.ts b/packages/server/src/services/Warehouses/WarehousesApplication.ts deleted file mode 100644 index 0577fcbbb..000000000 --- a/packages/server/src/services/Warehouses/WarehousesApplication.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { ICreateWarehouseDTO, IEditWarehouseDTO, IWarehouse } from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import { ActivateWarehouses } from './ActivateWarehouses'; -import { CreateWarehouse } from './CreateWarehouse'; -import { DeleteWarehouse } from './DeleteWarehouse'; -import { EditWarehouse } from './EditWarehouse'; -import { GetWarehouse } from './GetWarehouse'; -import { GetWarehouses } from './GetWarehouses'; -import { GetItemWarehouses } from './Items/GetItemWarehouses'; -import { WarehouseMarkPrimary } from './WarehouseMarkPrimary'; - -@Service() -export class WarehousesApplication { - @Inject() - private createWarehouseService: CreateWarehouse; - - @Inject() - private editWarehouseService: EditWarehouse; - - @Inject() - private deleteWarehouseService: DeleteWarehouse; - - @Inject() - private getWarehouseService: GetWarehouse; - - @Inject() - private getWarehousesService: GetWarehouses; - - @Inject() - private activateWarehousesService: ActivateWarehouses; - - @Inject() - private markWarehousePrimaryService: WarehouseMarkPrimary; - - @Inject() - private getItemWarehousesService: GetItemWarehouses; - - /** - * Creates a new warehouse. - * @param {number} tenantId - * @param {ICreateWarehouseDTO} createWarehouseDTO - * @returns - */ - public createWarehouse = ( - tenantId: number, - createWarehouseDTO: ICreateWarehouseDTO - ) => { - return this.createWarehouseService.createWarehouse( - tenantId, - createWarehouseDTO - ); - }; - - /** - * Edits the given warehouse. - * @param {number} tenantId - * @param {number} warehouseId - * @param {IEditWarehouseDTO} editWarehouseDTO - * @returns {Promise} - */ - public editWarehouse = ( - tenantId: number, - warehouseId: number, - editWarehouseDTO: IEditWarehouseDTO - ) => { - return this.editWarehouseService.editWarehouse( - tenantId, - warehouseId, - editWarehouseDTO - ); - }; - - /** - * Deletes the given warehouse. - * @param {number} tenantId - * @param {number} warehouseId - */ - public deleteWarehouse = (tenantId: number, warehouseId: number) => { - return this.deleteWarehouseService.deleteWarehouse(tenantId, warehouseId); - }; - - /** - * Retrieves the specific warehouse. - * @param {number} tenantId - * @param {number} warehouseId - * @returns - */ - public getWarehouse = (tenantId: number, warehouseId: number) => { - return this.getWarehouseService.getWarehouse(tenantId, warehouseId); - }; - - /** - * - * @param {number} tenantId - * @returns - */ - public getWarehouses = (tenantId: number) => { - return this.getWarehousesService.getWarehouses(tenantId); - }; - - /** - * Activates the warehouses feature. - * @param {number} tenantId - * @returns {Promise} - */ - public activateWarehouses = (tenantId: number) => { - return this.activateWarehousesService.activateWarehouses(tenantId); - }; - - /** - * Mark the given warehouse as primary. - * @param {number} tenantId - - * @returns {Promise} - */ - public markWarehousePrimary = ( - tenantId: number, - warehouseId: number - ): Promise => { - return this.markWarehousePrimaryService.markAsPrimary( - tenantId, - warehouseId - ); - }; - - /** - * Retrieves the specific item warehouses quantity. - * @param {number} tenantId - * @param {number} itemId - * @returns - */ - public getItemWarehouses = ( - tenantId: number, - itemId: number - ): Promise => { - return this.getItemWarehousesService.getItemWarehouses(tenantId, itemId); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesService.ts b/packages/server/src/services/Warehouses/WarehousesService.ts deleted file mode 100644 index 67a7405d8..000000000 --- a/packages/server/src/services/Warehouses/WarehousesService.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Service } from 'typedi'; - -@Service() -export class WarehousesService { - /** - * - * @param {number} tenantId - * @param {number} warehouseId - */ - getWarehouse = (tenantId: number, warehouseId: number) => {}; - - /** - * - * @param {number} tenantId - */ - getWarehouses = (tenantId: number) => {}; - - /** - * - * @param {number} tenantId - * @param {number} warehouseId - */ - deleteWarehouse = (tenantId: number, warehouseId: number) => {}; - - /** - * - * @param {number} tenantId - * @param {number} warehouseId - * @param {IEditWarehouseDTO} warehouseDTO - */ - editWarehouse = ( - tenantId: number, - warehouseId: number, - warehouseDTO: IEditWarehouseDTO - ) => {}; -} diff --git a/packages/server/src/services/Warehouses/WarehousesSettings.ts b/packages/server/src/services/Warehouses/WarehousesSettings.ts deleted file mode 100644 index 512efce05..000000000 --- a/packages/server/src/services/Warehouses/WarehousesSettings.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Features } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class WarehousesSettings { - @Inject() - tenancy: HasTenancyService; - - /** - * Marks multi-warehouses as activated. - */ - public markMutliwarehoussAsActivated = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); - - settings.set({ group: 'features', key: Features.WAREHOUSES, value: 1 }); - }; - - /** - * Detarmines multi-warehouses is active. - * @param {number} tenantId - * @returns {boolean} - */ - public isMultiWarehousesActive = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); - - return settings.get({ group: 'features', key: Features.WAREHOUSES }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/CRUDWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/CRUDWarehouseTransfer.ts deleted file mode 100644 index 9a1800792..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/CRUDWarehouseTransfer.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -@Service() -export class CRUDWarehouseTransfer { - @Inject() - tenancy: HasTenancyService; - - - throwIfTransferNotFound = (warehouseTransfer) => { - if (!warehouseTransfer) { - throw new ServiceError(ERRORS.WAREHOUSE_TRANSFER_NOT_FOUND); - } - } - - public getWarehouseTransferOrThrowNotFound = async ( - tenantId: number, - branchId: number - ) => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - const foundTransfer = await WarehouseTransfer.query().findById(branchId); - - if (!foundTransfer) { - throw new ServiceError(ERRORS.WAREHOUSE_TRANSFER_NOT_FOUND); - } - return foundTransfer; - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/CommandWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/CommandWarehouseTransfer.ts deleted file mode 100644 index 0afe58ff9..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/CommandWarehouseTransfer.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Inject } from 'typedi'; -import { - ICreateWarehouseTransferDTO, - IEditWarehouseTransferDTO, - IItem, -} from '@/interfaces'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import { CRUDWarehouseTransfer } from './CRUDWarehouseTransfer'; - -export class CommandWarehouseTransfer extends CRUDWarehouseTransfer { - @Inject() - tenancy: HasTenancyService; - - @Inject() - itemsEntries: ItemsEntriesService; - - /** - * Validate the from/to warehouses should not be the same. - * @param {ICreateWarehouseTransferDTO|IEditWarehouseTransferDTO} warehouseTransferDTO - */ - protected validateWarehouseFromToNotSame = ( - warehouseTransferDTO: - | ICreateWarehouseTransferDTO - | IEditWarehouseTransferDTO - ) => { - if ( - warehouseTransferDTO.fromWarehouseId === - warehouseTransferDTO.toWarehouseId - ) { - throw new ServiceError(ERRORS.WAREHOUSES_TRANSFER_SHOULD_NOT_BE_SAME); - } - }; - - /** - * Validates entries items should be inventory. - * @param {IItem[]} items - * @returns {void} - */ - protected validateItemsShouldBeInventory = (items: IItem[]): void => { - const nonInventoryItems = items.filter((item) => item.type !== 'inventory'); - - if (nonInventoryItems.length > 0) { - throw new ServiceError( - ERRORS.WAREHOUSE_TRANSFER_ITEMS_SHOULD_BE_INVENTORY - ); - } - }; - - protected getToWarehouseOrThrow = async ( - tenantId: number, - fromWarehouseId: number - ) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouse = await Warehouse.query().findById(fromWarehouseId); - - if (!warehouse) { - throw new ServiceError(ERRORS.TO_WAREHOUSE_NOT_FOUND); - } - return warehouse; - }; - - protected getFromWarehouseOrThrow = async ( - tenantId: number, - fromWarehouseId: number - ) => { - const { Warehouse } = this.tenancy.models(tenantId); - - const warehouse = await Warehouse.query().findById(fromWarehouseId); - - if (!warehouse) { - throw new ServiceError(ERRORS.FROM_WAREHOUSE_NOT_FOUND); - } - return warehouse; - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/CreateWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/CreateWarehouseTransfer.ts deleted file mode 100644 index b9d7c0012..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/CreateWarehouseTransfer.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { Knex } from 'knex'; -import { omit, get, isNumber } from 'lodash'; -import * as R from 'ramda'; -import { - ICreateWarehouseTransferDTO, - IWarehouseTransfer, - IWarehouseTransferCreate, - IWarehouseTransferCreated, - IWarehouseTransferEntryDTO, - IInventoryItemCostMeta, -} from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import ItemsEntriesService from '@/services/Items/ItemsEntriesService'; -import { CommandWarehouseTransfer } from './CommandWarehouseTransfer'; -import { InventoryItemCostService } from '@/services/Inventory/InventoryCostsService'; -import { WarehouseTransferAutoIncrement } from './WarehouseTransferAutoIncrement'; - -@Service() -export class CreateWarehouseTransfer extends CommandWarehouseTransfer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - @Inject() - private itemsEntries: ItemsEntriesService; - - @Inject() - private inventoryItemCost: InventoryItemCostService; - - @Inject() - private autoIncrementOrders: WarehouseTransferAutoIncrement; - - /** - * Transformes the givne new warehouse transfer DTO to model. - * @param {ICreateWarehouseTransferDTO} warehouseTransferDTO - * @returns {IWarehouseTransfer} - */ - private transformDTOToModel = async ( - tenantId: number, - warehouseTransferDTO: ICreateWarehouseTransferDTO - ): Promise => { - const entries = await this.transformEntries( - tenantId, - warehouseTransferDTO, - warehouseTransferDTO.entries - ); - // Retrieves the auto-increment the warehouse transfer number. - const autoNextNumber = - this.autoIncrementOrders.getNextTransferNumber(tenantId); - - // Warehouse transfer order transaction number. - const transactionNumber = - warehouseTransferDTO.transactionNumber || autoNextNumber; - - return { - ...omit(warehouseTransferDTO, ['transferDelivered', 'transferInitiated']), - transactionNumber, - ...(warehouseTransferDTO.transferDelivered - ? { - transferDeliveredAt: new Date(), - } - : {}), - ...(warehouseTransferDTO.transferDelivered || - warehouseTransferDTO.transferInitiated - ? { - transferInitiatedAt: new Date(), - } - : {}), - entries, - }; - }; - - /** - * Assoc average cost to the entry that has no cost. - * @param {Promise} inventoryItemsCostMap - - * @param {IWarehouseTransferEntryDTO} entry - - */ - private transformEntryAssocAverageCost = R.curry( - ( - inventoryItemsCostMap: Map, - entry: IWarehouseTransferEntryDTO - ): IWarehouseTransferEntryDTO => { - const itemValuation = inventoryItemsCostMap.get(entry.itemId); - const itemCost = get(itemValuation, 'average', 0); - - return isNumber(entry.cost) ? entry : R.assoc('cost', itemCost, entry); - } - ); - - /** - * Transformes warehouse transfer entries. - * @param {number} tenantId - * @param {ICreateWarehouseTransferDTO} warehouseTransferDTO - * @param {IWarehouseTransferEntryDTO[]} entries - * @returns {Promise} - */ - public transformEntries = async ( - tenantId: number, - warehouseTransferDTO: ICreateWarehouseTransferDTO, - entries: IWarehouseTransferEntryDTO[] - ): Promise => { - const inventoryItemsIds = warehouseTransferDTO.entries.map((e) => e.itemId); - - // Retrieves the inventory items valuation map. - const inventoryItemsCostMap = - await this.inventoryItemCost.getItemsInventoryValuation( - tenantId, - inventoryItemsIds, - warehouseTransferDTO.date - ); - // Assoc average cost to the entry. - const assocAverageCost = this.transformEntryAssocAverageCost( - inventoryItemsCostMap - ); - return R.map(assocAverageCost)(entries); - }; - - /** - * Authorize warehouse transfer before creating. - * @param {number} tenantId - * @param {ICreateWarehouseTransferDTO} warehouseTransferDTO - */ - public authorize = async ( - tenantId: number, - warehouseTransferDTO: ICreateWarehouseTransferDTO - ) => { - // Validate warehouse from and to should not be the same. - this.validateWarehouseFromToNotSame(warehouseTransferDTO); - - // Retrieves the from warehouse or throw not found service error. - const fromWarehouse = await this.getFromWarehouseOrThrow( - tenantId, - warehouseTransferDTO.fromWarehouseId - ); - // Retrieves the to warehouse or throw not found service error. - const toWarehouse = await this.getToWarehouseOrThrow( - tenantId, - warehouseTransferDTO.toWarehouseId - ); - // Validates the not found entries items ids. - const items = await this.itemsEntries.validateItemsIdsExistance( - tenantId, - warehouseTransferDTO.entries - ); - // Validate the items entries should be inventory type. - this.validateItemsShouldBeInventory(items); - }; - - /** - * Creates a new warehouse transfer transaction. - * @param {number} tenantId - - * @param {ICreateWarehouseTransferDTO} warehouseDTO - - * @returns {Promise} - */ - public createWarehouseTransfer = async ( - tenantId: number, - warehouseTransferDTO: ICreateWarehouseTransferDTO - ): Promise => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - // Authorize warehouse transfer before creating. - await this.authorize(tenantId, warehouseTransferDTO); - - // Transformes the warehouse transfer DTO to model. - const warehouseTransferModel = await this.transformDTOToModel( - tenantId, - warehouseTransferDTO - ); - // Create warehouse transfer under unit-of-work. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseTransferCreate` event. - await this.eventPublisher.emitAsync(events.warehouseTransfer.onCreate, { - trx, - warehouseTransferDTO, - tenantId, - } as IWarehouseTransferCreate); - - // Stores the warehouse transfer transaction graph to the storage. - const warehouseTransfer = await WarehouseTransfer.query( - trx - ).upsertGraphAndFetch({ - ...warehouseTransferModel, - }); - // Triggers `onWarehouseTransferCreated` event. - await this.eventPublisher.emitAsync(events.warehouseTransfer.onCreated, { - trx, - warehouseTransfer, - warehouseTransferDTO, - tenantId, - } as IWarehouseTransferCreated); - - return warehouseTransfer; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/DeleteWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/DeleteWarehouseTransfer.ts deleted file mode 100644 index 3a40e5163..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/DeleteWarehouseTransfer.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { - IWarehouseTransferDeletedPayload, - IWarehouseTransferDeletePayload, -} from '@/interfaces'; -import { CRUDWarehouseTransfer } from './CRUDWarehouseTransfer'; - -@Service() -export class DeleteWarehouseTransfer extends CRUDWarehouseTransfer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Deletes warehouse transfer transaction. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public deleteWarehouseTransfer = async ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - const { WarehouseTransfer, WarehouseTransferEntry } = - this.tenancy.models(tenantId); - - // Retrieve the old warehouse transfer or throw not found service error. - const oldWarehouseTransfer = await WarehouseTransfer.query() - .findById(warehouseTransferId) - .throwIfNotFound(); - - // Deletes the warehouse transfer under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseTransferCreate` event. - await this.eventPublisher.emitAsync(events.warehouseTransfer.onDelete, { - tenantId, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferDeletePayload); - - // Delete warehouse transfer entries. - await WarehouseTransferEntry.query(trx) - .where('warehouseTransferId', warehouseTransferId) - .delete(); - - // Delete warehouse transfer. - await WarehouseTransfer.query(trx).findById(warehouseTransferId).delete(); - - // Triggers `onWarehouseTransferDeleted` event - await this.eventPublisher.emitAsync(events.warehouseTransfer.onDeleted, { - tenantId, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferDeletedPayload); - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/EditWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/EditWarehouseTransfer.ts deleted file mode 100644 index f12d62a31..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/EditWarehouseTransfer.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import { Knex } from 'knex'; -import events from '@/subscribers/events'; -import { - IEditWarehouseTransferDTO, - IWarehouseTransfer, - IWarehouseTransferEditPayload, - IWarehouseTransferEditedPayload, -} from '@/interfaces'; -import { CommandWarehouseTransfer } from './CommandWarehouseTransfer'; - -@Service() -export class EditWarehouseTransfer extends CommandWarehouseTransfer { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Edits warehouse transfer. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @param {IEditWarehouseTransferDTO} editWarehouseDTO - * @returns {Promise} - */ - public editWarehouseTransfer = async ( - tenantId: number, - warehouseTransferId: number, - editWarehouseDTO: IEditWarehouseTransferDTO - ): Promise => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - // Retrieves the old warehouse transfer transaction. - const oldWarehouseTransfer = await WarehouseTransfer.query() - .findById(warehouseTransferId) - .throwIfNotFound(); - - // Validate warehouse from and to should not be the same. - this.validateWarehouseFromToNotSame(editWarehouseDTO); - - // Retrieves the from warehouse or throw not found service error. - const fromWarehouse = await this.getFromWarehouseOrThrow( - tenantId, - editWarehouseDTO.fromWarehouseId - ); - // Retrieves the to warehouse or throw not found service error. - const toWarehouse = await this.getToWarehouseOrThrow( - tenantId, - editWarehouseDTO.toWarehouseId - ); - // Validates the not found entries items ids. - const items = await this.itemsEntries.validateItemsIdsExistance( - tenantId, - editWarehouseDTO.entries - ); - // Validate the items entries should be inventory type. - this.validateItemsShouldBeInventory(items); - - // Edits warehouse transfer transaction under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseTransferEdit` event. - await this.eventPublisher.emitAsync(events.warehouseTransfer.onEdit, { - tenantId, - editWarehouseDTO, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferEditPayload); - - // Updates warehouse transfer graph on the storage. - const warehouseTransfer = await WarehouseTransfer.query( - trx - ).upsertGraphAndFetch({ - id: warehouseTransferId, - ...editWarehouseDTO, - }); - // Triggers `onWarehouseTransferEdit` event - await this.eventPublisher.emitAsync(events.warehouseTransfer.onEdited, { - tenantId, - editWarehouseDTO, - warehouseTransfer, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferEditedPayload); - - return warehouseTransfer; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfer.ts deleted file mode 100644 index 80f350578..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Service, Inject } from 'typedi'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { IWarehouseTransfer } from '@/interfaces'; -import { CRUDWarehouseTransfer } from './CRUDWarehouseTransfer'; -import { WarehouseTransferTransformer } from './WarehouseTransferTransfomer'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetWarehouseTransfer extends CRUDWarehouseTransfer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Retrieves the specific warehouse transfer transaction. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @param {IEditWarehouseTransferDTO} editWarehouseDTO - * @returns {Promise} - */ - public getWarehouseTransfer = async ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - // Retrieves the old warehouse transfer transaction. - const warehouseTransfer = await WarehouseTransfer.query() - .findById(warehouseTransferId) - .withGraphFetched('entries.item') - .withGraphFetched('fromWarehouse') - .withGraphFetched('toWarehouse'); - - this.throwIfTransferNotFound(warehouseTransfer); - - // Retrieves the transfromed warehouse transfers. - return this.transformer.transform( - tenantId, - warehouseTransfer, - new WarehouseTransferTransformer() - ); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfers.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfers.ts deleted file mode 100644 index 43635a55a..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/GetWarehouseTransfers.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as R from 'ramda'; -import { Service, Inject } from 'typedi'; -import DynamicListingService from '@/services/DynamicListing/DynamicListService'; -import { IGetWarehousesTransfersFilterDTO } from '@/interfaces'; -import { WarehouseTransferTransformer } from './WarehouseTransferTransfomer'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; - -@Service() -export class GetWarehouseTransfers { - @Inject() - private dynamicListService: DynamicListingService; - - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private transformer: TransformerInjectable; - - /** - * Parses the sale invoice list filter DTO. - * @param filterDTO - * @returns - */ - private parseListFilterDTO(filterDTO) { - return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO); - } - - /** - * Retrieves warehouse transfers paginated list. - * @param {number} tenantId - * @param {IGetWarehousesTransfersFilterDTO} filterDTO - * @returns {} - */ - public getWarehouseTransfers = async ( - tenantId: number, - filterDTO: IGetWarehousesTransfersFilterDTO - ) => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - // Parses stringified filter roles. - const filter = this.parseListFilterDTO(filterDTO); - - // Dynamic list service. - const dynamicFilter = await this.dynamicListService.dynamicList( - tenantId, - WarehouseTransfer, - filter - ); - const { results, pagination } = await WarehouseTransfer.query() - .onBuild((query) => { - query.withGraphFetched('entries.item'); - query.withGraphFetched('fromWarehouse'); - query.withGraphFetched('toWarehouse'); - - dynamicFilter.buildQuery()(query); - }) - .pagination(filter.page - 1, filter.pageSize); - - // Retrieves the transformed warehouse transfers - const warehousesTransfers = await this.transformer.transform( - tenantId, - results, - new WarehouseTransferTransformer() - ); - return { - warehousesTransfers, - pagination, - filter, - }; - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/InitiateWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/InitiateWarehouseTransfer.ts deleted file mode 100644 index 4e40455bb..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/InitiateWarehouseTransfer.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { - IWarehouseTransfer, - IWarehouseTransferEditedPayload, - IWarehouseTransferInitiatePayload, -} from '@/interfaces'; -import { CommandWarehouseTransfer } from './CommandWarehouseTransfer'; -import { ServiceError } from '@/exceptions'; -import { ERRORS } from './constants'; - -@Service() -export class InitiateWarehouseTransfer extends CommandWarehouseTransfer { - @Inject() - private tenancy: HasTenancyService; - - @Inject() - private uow: UnitOfWork; - - @Inject() - private eventPublisher: EventPublisher; - - /** - * Validate the given warehouse transfer not already initiated. - * @param {IWarehouseTransfer} warehouseTransfer - */ - private validateWarehouseTransferNotAlreadyInitiated = ( - warehouseTransfer: IWarehouseTransfer - ) => { - if (warehouseTransfer.transferInitiatedAt) { - throw new ServiceError(ERRORS.WAREHOUSE_TRANSFER_ALREADY_INITIATED); - } - }; - - /** - * Initiate warehouse transfer. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public initiateWarehouseTransfer = async ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - // Retrieves the old warehouse transfer transaction. - const oldWarehouseTransfer = await WarehouseTransfer.query() - .findById(warehouseTransferId) - .throwIfNotFound(warehouseTransferId); - - // Validate the given warehouse transfer not already initiated. - this.validateWarehouseTransferNotAlreadyInitiated(oldWarehouseTransfer); - - // Edits warehouse transfer transaction under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseTransferInitiate` event. - await this.eventPublisher.emitAsync(events.warehouseTransfer.onInitiate, { - tenantId, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferInitiatePayload); - - // Updates warehouse transfer graph on the storage. - const warehouseTransferUpdated = await WarehouseTransfer.query(trx) - .findById(warehouseTransferId) - .patch({ - transferInitiatedAt: new Date(), - }); - // Fetches the warehouse transfer with entries. - const warehouseTransfer = await WarehouseTransfer.query(trx) - .findById(warehouseTransferId) - .withGraphFetched('entries'); - - // Triggers `onWarehouseTransferEdit` event - await this.eventPublisher.emitAsync( - events.warehouseTransfer.onInitiated, - { - tenantId, - warehouseTransfer, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferEditedPayload - ); - return warehouseTransfer; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/TransferredWarehouseTransfer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/TransferredWarehouseTransfer.ts deleted file mode 100644 index 9ce618990..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/TransferredWarehouseTransfer.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { Knex } from 'knex'; -import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; -import UnitOfWork from '@/services/UnitOfWork'; -import events from '@/subscribers/events'; -import { - IWarehouseTransfer, - IWarehouseTransferTransferingPayload, - IWarehouseTransferTransferredPayload, -} from '@/interfaces'; -import { CommandWarehouseTransfer } from './CommandWarehouseTransfer'; -import { ERRORS } from './constants'; -import { ServiceError } from '@/exceptions'; - -@Service() -export class TransferredWarehouseTransfer extends CommandWarehouseTransfer { - @Inject() - tenancy: HasTenancyService; - - @Inject() - uow: UnitOfWork; - - @Inject() - eventPublisher: EventPublisher; - - /** - * Validate the warehouse transfer not already transferred. - * @param {IWarehouseTransfer} warehouseTransfer - */ - private validateWarehouseTransferNotTransferred = ( - warehouseTransfer: IWarehouseTransfer - ) => { - if (warehouseTransfer.transferDeliveredAt) { - throw new ServiceError(ERRORS.WAREHOUSE_TRANSFER_ALREADY_TRANSFERRED); - } - }; - - /** - * Validate the warehouse transfer should be initiated. - * @param {IWarehouseTransfer} warehouseTransfer - */ - private validateWarehouseTranbsferShouldInitiated = ( - warehouseTransfer: IWarehouseTransfer - ) => { - if (!warehouseTransfer.transferInitiatedAt) { - throw new ServiceError(ERRORS.WAREHOUSE_TRANSFER_NOT_INITIATED); - } - }; - - /** - * Transferred warehouse transfer. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public transferredWarehouseTransfer = async ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - const { WarehouseTransfer } = this.tenancy.models(tenantId); - - // Retrieves the old warehouse transfer transaction. - const oldWarehouseTransfer = await WarehouseTransfer.query() - .findById(warehouseTransferId) - .throwIfNotFound(); - - // Validate the warehouse transfer not already transferred. - this.validateWarehouseTransferNotTransferred(oldWarehouseTransfer); - - // Validate the warehouse transfer should be initiated. - this.validateWarehouseTranbsferShouldInitiated(oldWarehouseTransfer); - - // Edits warehouse transfer transaction under unit-of-work envirement. - return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onWarehouseTransferInitiate` event. - await this.eventPublisher.emitAsync(events.warehouseTransfer.onTransfer, { - tenantId, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferTransferingPayload); - - // Updates warehouse transfer graph on the storage. - const warehouseTransferUpdated = await WarehouseTransfer.query(trx) - .findById(warehouseTransferId) - .patch({ - transferDeliveredAt: new Date(), - }); - // Fetches the warehouse transfer with entries. - const warehouseTransfer = await WarehouseTransfer.query(trx) - .findById(warehouseTransferId) - .withGraphFetched('entries'); - - // Triggers `onWarehouseTransferEdit` event - await this.eventPublisher.emitAsync( - events.warehouseTransfer.onTransferred, - { - tenantId, - warehouseTransfer, - oldWarehouseTransfer, - trx, - } as IWarehouseTransferTransferredPayload - ); - return warehouseTransfer; - }); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferApplication.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferApplication.ts deleted file mode 100644 index 4e27b5092..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferApplication.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - ICreateWarehouseTransferDTO, - IEditWarehouseTransferDTO, - IGetWarehousesTransfersFilterDTO, - IWarehouseTransfer, -} from '@/interfaces'; -import { Service, Inject } from 'typedi'; -import { CreateWarehouseTransfer } from './CreateWarehouseTransfer'; -import { DeleteWarehouseTransfer } from './DeleteWarehouseTransfer'; -import { EditWarehouseTransfer } from './EditWarehouseTransfer'; -import { GetWarehouseTransfer } from './GetWarehouseTransfer'; -import { GetWarehouseTransfers } from './GetWarehouseTransfers'; -import { InitiateWarehouseTransfer } from './InitiateWarehouseTransfer'; -import { TransferredWarehouseTransfer } from './TransferredWarehouseTransfer'; - -@Service() -export class WarehouseTransferApplication { - @Inject() - private createWarehouseTransferService: CreateWarehouseTransfer; - - @Inject() - private editWarehouseTransferService: EditWarehouseTransfer; - - @Inject() - private deleteWarehouseTransferService: DeleteWarehouseTransfer; - - @Inject() - private getWarehouseTransferService: GetWarehouseTransfer; - - @Inject() - private getWarehousesTransfersService: GetWarehouseTransfers; - - @Inject() - private initiateWarehouseTransferService: InitiateWarehouseTransfer; - - @Inject() - private transferredWarehouseTransferService: TransferredWarehouseTransfer; - - /** - * Creates a warehouse transfer transaction. - * @param {number} tenantId - * @param {ICreateWarehouseTransferDTO} createWarehouseTransferDTO - * @returns {} - */ - public createWarehouseTransfer = ( - tenantId: number, - createWarehouseTransferDTO: ICreateWarehouseTransferDTO - ): Promise => { - return this.createWarehouseTransferService.createWarehouseTransfer( - tenantId, - createWarehouseTransferDTO - ); - }; - - /** - * Edits warehouse transfer transaction. - * @param {number} tenantId - - * @param {number} warehouseTransferId - number - * @param {IEditWarehouseTransferDTO} editWarehouseTransferDTO - */ - public editWarehouseTransfer = ( - tenantId: number, - warehouseTransferId: number, - editWarehouseTransferDTO: IEditWarehouseTransferDTO - ): Promise => { - return this.editWarehouseTransferService.editWarehouseTransfer( - tenantId, - warehouseTransferId, - editWarehouseTransferDTO - ); - }; - - /** - * Deletes warehouse transfer transaction. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public deleteWarehouseTransfer = ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - return this.deleteWarehouseTransferService.deleteWarehouseTransfer( - tenantId, - warehouseTransferId - ); - }; - - /** - * Retrieves warehouse transfer transaction. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public getWarehouseTransfer = ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - return this.getWarehouseTransferService.getWarehouseTransfer( - tenantId, - warehouseTransferId - ); - }; - - /** - * Retrieves warehouses trans - * @param {number} tenantId - * @param {IGetWarehousesTransfersFilterDTO} filterDTO - * @returns {Promise} - */ - public getWarehousesTransfers = ( - tenantId: number, - filterDTO: IGetWarehousesTransfersFilterDTO - ) => { - return this.getWarehousesTransfersService.getWarehouseTransfers( - tenantId, - filterDTO - ); - }; - - /** - * Marks the warehouse transfer order as transfered. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public transferredWarehouseTransfer = ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - return this.transferredWarehouseTransferService.transferredWarehouseTransfer( - tenantId, - warehouseTransferId - ); - }; - - /** - * Marks the warehouse transfer order as initiated. - * @param {number} tenantId - * @param {number} warehouseTransferId - * @returns {Promise} - */ - public initiateWarehouseTransfer = ( - tenantId: number, - warehouseTransferId: number - ): Promise => { - return this.initiateWarehouseTransferService.initiateWarehouseTransfer( - tenantId, - warehouseTransferId - ); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrement.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrement.ts deleted file mode 100644 index 85daa5e7d..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrement.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import AutoIncrementOrdersService from '../../Sales/AutoIncrementOrdersService'; - -@Service() -export class WarehouseTransferAutoIncrement { - @Inject() - private autoIncrementOrdersService: AutoIncrementOrdersService; - - /** - * Retrieve the next unique invoice number. - * @param {number} tenantId - Tenant id. - * @return {string} - */ - public getNextTransferNumber(tenantId: number): string { - return this.autoIncrementOrdersService.getNextTransactionNumber( - tenantId, - 'warehouse_transfers' - ); - } - - /** - * Increment the invoice next number. - * @param {number} tenantId - - */ - public incrementNextTransferNumber(tenantId: number) { - return this.autoIncrementOrdersService.incrementSettingsNextNumber( - tenantId, - 'warehouse_transfers' - ); - } -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber.ts deleted file mode 100644 index 1bbbd9536..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { IWarehouseTransferCreated } from '@/interfaces'; -import { WarehouseTransferAutoIncrement } from './WarehouseTransferAutoIncrement'; - -@Service() -export class WarehouseTransferAutoIncrementSubscriber { - @Inject() - private warehouseTransferAutoIncrement: WarehouseTransferAutoIncrement; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.warehouseTransfer.onCreated, - this.incrementTransferAutoIncrementOnCreated - ); - return bus; - }; - - /** - * Writes inventory transactions once warehouse transfer created. - * @param {IInventoryTransactionsCreatedPayload} - - */ - private incrementTransferAutoIncrementOnCreated = async ({ - tenantId, - }: IWarehouseTransferCreated) => { - await this.warehouseTransferAutoIncrement.incrementNextTransferNumber( - tenantId - ); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferInventoryTransactionsSubscriber.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferInventoryTransactionsSubscriber.ts deleted file mode 100644 index 80f1ef29e..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferInventoryTransactionsSubscriber.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - IWarehouseTransferEditedPayload, - IWarehouseTransferDeletedPayload, - IWarehouseTransferCreated, - IWarehouseTransferInitiatedPayload, - IWarehouseTransferTransferredPayload, -} from '@/interfaces'; -import { WarehouseTransferInventoryTransactions } from './WriteInventoryTransactions'; - -@Service() -export class WarehouseTransferInventoryTransactionsSubscriber { - @Inject() - private warehouseTransferInventoryTransactions: WarehouseTransferInventoryTransactions; - - /** - * Attaches events with handlers. - */ - public attach = (bus) => { - bus.subscribe( - events.warehouseTransfer.onCreated, - this.writeInventoryTransactionsOnWarehouseTransferCreated - ); - bus.subscribe( - events.warehouseTransfer.onEdited, - this.rewriteInventoryTransactionsOnWarehouseTransferEdited - ); - bus.subscribe( - events.warehouseTransfer.onDeleted, - this.revertInventoryTransactionsOnWarehouseTransferDeleted - ); - bus.subscribe( - events.warehouseTransfer.onInitiated, - this.writeInventoryTransactionsOnTransferInitiated - ); - bus.subscribe( - events.warehouseTransfer.onTransferred, - this.writeInventoryTransactionsOnTransferred - ); - return bus; - }; - - /** - * Writes inventory transactions once warehouse transfer created. - * @param {IInventoryTransactionsCreatedPayload} - - */ - private writeInventoryTransactionsOnWarehouseTransferCreated = async ({ - warehouseTransfer, - tenantId, - trx, - }: IWarehouseTransferCreated) => { - // Can't continue if the warehouse transfer is not initiated yet. - if (!warehouseTransfer.isInitiated) return; - - // Write all inventory transaction if warehouse transfer initiated and transferred. - if (warehouseTransfer.isInitiated && warehouseTransfer.isTransferred) { - await this.warehouseTransferInventoryTransactions.writeAllInventoryTransactions( - tenantId, - warehouseTransfer, - false, - trx - ); - // Write initiate inventory transaction if warehouse transfer initited and transferred yet. - } else if (warehouseTransfer.isInitiated) { - await this.warehouseTransferInventoryTransactions.writeInitiateInventoryTransactions( - tenantId, - warehouseTransfer, - false, - trx - ); - } - }; - - /** - * Rewrite inventory transactions once warehouse transfer edited. - * @param {IWarehouseTransferEditedPayload} - - */ - private rewriteInventoryTransactionsOnWarehouseTransferEdited = async ({ - tenantId, - warehouseTransfer, - trx, - }: IWarehouseTransferEditedPayload) => { - // Can't continue if the warehouse transfer is not initiated yet. - if (!warehouseTransfer.isInitiated) return; - - // Write all inventory transaction if warehouse transfer initiated and transferred. - if (warehouseTransfer.isInitiated && warehouseTransfer.isTransferred) { - await this.warehouseTransferInventoryTransactions.writeAllInventoryTransactions( - tenantId, - warehouseTransfer, - true, - trx - ); - // Write initiate inventory transaction if warehouse transfer initited and transferred yet. - } else if (warehouseTransfer.isInitiated) { - await this.warehouseTransferInventoryTransactions.writeInitiateInventoryTransactions( - tenantId, - warehouseTransfer, - true, - trx - ); - } - }; - - /** - * Reverts inventory transactions once warehouse transfer deleted. - * @parma {IWarehouseTransferDeletedPayload} - - */ - private revertInventoryTransactionsOnWarehouseTransferDeleted = async ({ - tenantId, - oldWarehouseTransfer, - trx, - }: IWarehouseTransferDeletedPayload) => { - await this.warehouseTransferInventoryTransactions.revertInventoryTransactions( - tenantId, - oldWarehouseTransfer.id, - trx - ); - }; - - /** - * Write inventory transactions of warehouse transfer once the transfer initiated. - * @param {IWarehouseTransferInitiatedPayload} - */ - private writeInventoryTransactionsOnTransferInitiated = async ({ - trx, - warehouseTransfer, - tenantId, - }: IWarehouseTransferInitiatedPayload) => { - await this.warehouseTransferInventoryTransactions.writeInitiateInventoryTransactions( - tenantId, - warehouseTransfer, - false, - trx - ); - }; - - /** - * Write inventory transactions of warehouse transfer once the transfer completed. - * @param {IWarehouseTransferTransferredPayload} - */ - private writeInventoryTransactionsOnTransferred = async ({ - trx, - warehouseTransfer, - tenantId, - }: IWarehouseTransferTransferredPayload) => { - await this.warehouseTransferInventoryTransactions.writeTransferredInventoryTransactions( - tenantId, - warehouseTransfer, - false, - trx - ); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferItemTransformer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferItemTransformer.ts deleted file mode 100644 index 970cd9f64..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferItemTransformer.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; - -export class WarehouseTransferItemTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['formattedQuantity', 'formattedCost', 'formattedTotal']; - }; - - /** - * - * @param entry - * @returns - */ - public formattedTotal = (entry) => { - return this.formatMoney(entry.total); - }; - - /** - * - * @param entry - * @returns - */ - public formattedQuantity = (entry) => { - return this.formatNumber(entry.quantity); - }; - - /** - * - * @param entry - * @returns - */ - public formattedCost = (entry) => { - return this.formatMoney(entry.cost); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferTransfomer.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferTransfomer.ts deleted file mode 100644 index 605fe457e..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WarehouseTransferTransfomer.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; -import { WarehouseTransferItemTransformer } from './WarehouseTransferItemTransformer'; - -export class WarehouseTransferTransformer extends Transformer { - /** - * Include these attributes to sale invoice object. - * @returns {Array} - */ - public includeAttributes = (): string[] => { - return ['formattedDate', 'entries']; - }; - - /** - * - * @param transfer - * @returns - */ - protected formattedDate = (transfer) => { - return this.formatDate(transfer.date); - }; - - /** - * - */ - protected entries = (transfer) => { - return this.item(transfer.entries, new WarehouseTransferItemTransformer()); - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/WriteInventoryTransactions.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/WriteInventoryTransactions.ts deleted file mode 100644 index 5d8c1676f..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/WriteInventoryTransactions.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { Knex } from 'knex'; -import { - IWarehouseTransfer, - IInventoryTransaction, - IWarehouseTransferEntry, -} from '@/interfaces'; -import { Inject, Service } from 'typedi'; -import InventoryService from '@/services/Inventory/Inventory'; - -@Service() -export class WarehouseTransferInventoryTransactions { - @Inject() - private inventory: InventoryService; - - /** - * Writes all (initiate and transfer) inventory transactions. - * @param {number} tenantId - * @param {IWarehouseTransfer} warehouseTransfer - * @param {Boolean} override - * @param {Knex.Transaction} trx - Knex transcation. - * @returns {Promise} - */ - public writeAllInventoryTransactions = async ( - tenantId: number, - warehouseTransfer: IWarehouseTransfer, - override?: boolean, - trx?: Knex.Transaction - ): Promise => { - const inventoryTransactions = - this.getWarehouseTransferInventoryTransactions(warehouseTransfer); - - await this.inventory.recordInventoryTransactions( - tenantId, - inventoryTransactions, - override, - trx - ); - }; - - /** - * Writes initiate inventory transactions of warehouse transfer transaction. - * @param {number} tenantId - * @param {IWarehouseTransfer} warehouseTransfer - * @param {boolean} override - * @param {Knex.Transaction} trx - Knex transaction. - * @returns {Promise} - */ - public writeInitiateInventoryTransactions = async ( - tenantId: number, - warehouseTransfer: IWarehouseTransfer, - override?: boolean, - trx?: Knex.Transaction - ): Promise => { - const inventoryTransactions = - this.getWarehouseFromTransferInventoryTransactions(warehouseTransfer); - - await this.inventory.recordInventoryTransactions( - tenantId, - inventoryTransactions, - override, - trx - ); - }; - - /** - * Writes transferred inventory transaction of warehouse transfer transaction. - * @param {number} tenantId - * @param {IWarehouseTransfer} warehouseTransfer - * @param {boolean} override - * @param {Knex.Transaction} trx - Knex transaction. - * @returns {Promise} - */ - public writeTransferredInventoryTransactions = async ( - tenantId: number, - warehouseTransfer: IWarehouseTransfer, - override?: boolean, - trx?: Knex.Transaction - ): Promise => { - const inventoryTransactions = - this.getWarehouseToTransferInventoryTransactions(warehouseTransfer); - - await this.inventory.recordInventoryTransactions( - tenantId, - inventoryTransactions, - override, - trx - ); - }; - - /** - * Reverts warehouse transfer inventory transactions. - * @param {number} tenatnId - * @param {number} warehouseTransferId - * @param {Knex.Transaction} trx - * @returns {Promise} - */ - public revertInventoryTransactions = async ( - tenantId: number, - warehouseTransferId: number, - trx?: Knex.Transaction - ): Promise => { - await this.inventory.deleteInventoryTransactions( - tenantId, - warehouseTransferId, - 'WarehouseTransfer', - trx - ); - }; - - /** - * Retrieves the inventory transactions of the given warehouse transfer. - * @param {IWarehouseTransfer} warehouseTransfer - * @returns {IInventoryTransaction[]} - */ - private getWarehouseFromTransferInventoryTransactions = ( - warehouseTransfer: IWarehouseTransfer - ): IInventoryTransaction[] => { - const commonEntry = { - date: warehouseTransfer.date, - transactionType: 'WarehouseTransfer', - transactionId: warehouseTransfer.id, - }; - return warehouseTransfer.entries.map((entry: IWarehouseTransferEntry) => ({ - ...commonEntry, - entryId: entry.id, - itemId: entry.itemId, - quantity: entry.quantity, - rate: entry.cost, - direction: 'OUT', - warehouseId: warehouseTransfer.fromWarehouseId, - })); - }; - - /** - * - * @param {IWarehouseTransfer} warehouseTransfer - * @returns {IInventoryTransaction[]} - */ - private getWarehouseToTransferInventoryTransactions = ( - warehouseTransfer: IWarehouseTransfer - ): IInventoryTransaction[] => { - const commonEntry = { - date: warehouseTransfer.date, - transactionType: 'WarehouseTransfer', - transactionId: warehouseTransfer.id, - }; - return warehouseTransfer.entries.map((entry: IWarehouseTransferEntry) => ({ - ...commonEntry, - entryId: entry.id, - itemId: entry.itemId, - quantity: entry.quantity, - rate: entry.cost, - direction: 'IN', - warehouseId: warehouseTransfer.toWarehouseId, - })); - }; - - /** - * - * @param {IWarehouseTransfer} warehouseTransfer - * @returns {IInventoryTransaction[]} - */ - private getWarehouseTransferInventoryTransactions = ( - warehouseTransfer: IWarehouseTransfer - ): IInventoryTransaction[] => { - // Retrieve the to inventory transactions of warehouse transfer. - const toTransactions = - this.getWarehouseToTransferInventoryTransactions(warehouseTransfer); - - // Retrieve the from inventory transactions of warehouse transfer. - const fromTransactions = - this.getWarehouseFromTransferInventoryTransactions(warehouseTransfer); - - return [...toTransactions, ...fromTransactions]; - }; -} diff --git a/packages/server/src/services/Warehouses/WarehousesTransfers/constants.ts b/packages/server/src/services/Warehouses/WarehousesTransfers/constants.ts deleted file mode 100644 index 790061627..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfers/constants.ts +++ /dev/null @@ -1,57 +0,0 @@ -export const ERRORS = { - WAREHOUSE_TRANSFER_NOT_FOUND: 'WAREHOUSE_TRANSFER_NOT_FOUND', - WAREHOUSES_TRANSFER_SHOULD_NOT_BE_SAME: - 'WAREHOUSES_TRANSFER_SHOULD_NOT_BE_SAME', - - FROM_WAREHOUSE_NOT_FOUND: 'FROM_WAREHOUSE_NOT_FOUND', - TO_WAREHOUSE_NOT_FOUND: 'TO_WAREHOUSE_NOT_FOUND', - WAREHOUSE_TRANSFER_ITEMS_SHOULD_BE_INVENTORY: - 'WAREHOUSE_TRANSFER_ITEMS_SHOULD_BE_INVENTORY', - - WAREHOUSE_TRANSFER_ALREADY_TRANSFERRED: - 'WAREHOUSE_TRANSFER_ALREADY_TRANSFERRED', - - WAREHOUSE_TRANSFER_ALREADY_INITIATED: 'WAREHOUSE_TRANSFER_ALREADY_INITIATED', - WAREHOUSE_TRANSFER_NOT_INITIATED: 'WAREHOUSE_TRANSFER_NOT_INITIATED', -}; - -// Warehouse transfers default views. -export const DEFAULT_VIEWS = [ - { - name: 'warehouse_transfer.view.draft.name', - slug: 'draft', - rolesLogicExpression: '1', - roles: [ - { index: 1, fieldKey: 'status', comparator: 'equals', value: 'draft' }, - ], - columns: [], - }, - { - name: 'warehouse_transfer.view.in_transit.name', - slug: 'in-transit', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'in-transit', - }, - ], - columns: [], - }, - { - name: 'warehouse_transfer.view.transferred.name', - slug: 'transferred', - rolesLogicExpression: '1', - roles: [ - { - index: 1, - fieldKey: 'status', - comparator: 'equals', - value: 'tansferred', - }, - ], - columns: [], - }, -]; diff --git a/packages/server/src/services/Warehouses/WarehousesTransfersService.ts b/packages/server/src/services/Warehouses/WarehousesTransfersService.ts deleted file mode 100644 index d6d04f2ff..000000000 --- a/packages/server/src/services/Warehouses/WarehousesTransfersService.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Service, Inject } from 'typedi'; - - -export class WarehousesTransfersService { - createWarehouseTranser = ( - tenantId: number, - createWarehouseTransfer: ICreateWarehouseTransferDTO - ) => {}; - - editWarehouseTranser = ( - tenantId: number, - editWarehouseTransfer: IEditWarehouseTransferDTO - ) => {}; - - deleteWarehouseTranser = ( - tenantId: number, - warehouseTransferId: number - ) => {}; - - getWarehouseTransfer = (tenantId: number, warehouseTransferId: number) => {}; - - getWarehouseTransfers = (tenantId: number) => {}; -} diff --git a/packages/server/src/services/Warehouses/contants.ts b/packages/server/src/services/Warehouses/contants.ts deleted file mode 100644 index e41d9b3ff..000000000 --- a/packages/server/src/services/Warehouses/contants.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const ERRORS = { - WAREHOUSE_NOT_FOUND: 'WAREHOUSE_NOT_FOUND', - MUTLI_WAREHOUSES_ALREADY_ACTIVATED: 'MUTLI_WAREHOUSES_ALREADY_ACTIVATED', - COULD_NOT_DELETE_ONLY_WAERHOUSE: 'COULD_NOT_DELETE_ONLY_WAERHOUSE', - WAREHOUSE_CODE_NOT_UNIQUE: 'WAREHOUSE_CODE_NOT_UNIQUE', - WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS: 'WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS' -}; \ No newline at end of file diff --git a/packages/server/src/subscribers/Authentication/ResetLoginThrottle.ts b/packages/server/src/subscribers/Authentication/ResetLoginThrottle.ts deleted file mode 100644 index 2dcd7ed59..000000000 --- a/packages/server/src/subscribers/Authentication/ResetLoginThrottle.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Container, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { IAuthSignedInEventPayload } from '@/interfaces'; - -@Service() -export default class ResetLoginThrottleSubscriber { - /** - * Attaches events with handlers. - * @param bus - */ - public attach(bus) { - bus.subscribe(events.auth.signIn, this.resetLoginThrottleOnceSuccessLogin); - } - - /** - * Resets the login throttle once the login success. - * @param {IAuthSignedInEventPayload} payload - - */ - private async resetLoginThrottleOnceSuccessLogin( - payload: IAuthSignedInEventPayload - ) { - const { email, user } = payload; - const loginThrottler = Container.get('rateLimiter.login'); - - // Reset the login throttle by the given email and phone number. - await loginThrottler.reset(user.email); - await loginThrottler.reset(email); - } -} diff --git a/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts b/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts deleted file mode 100644 index 935caf8dd..000000000 --- a/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; - -@Service() -export default class AuthenticationSubscriber { - @Inject('agenda') - private agenda: any; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe(events.auth.sendResetPassword, this.sendPasswordMail); - } - - /** - * Sends reset password mail once the reset password success. - */ - public sendPasswordMail = (payload) => { - const { user, token } = payload; - - // Send reset password mail. - this.agenda.now('reset-password-mail', { user, token }); - }; -} diff --git a/packages/server/src/subscribers/Bills/WriteInventoryTransactions.ts b/packages/server/src/subscribers/Bills/WriteInventoryTransactions.ts deleted file mode 100644 index 6af4e8551..000000000 --- a/packages/server/src/subscribers/Bills/WriteInventoryTransactions.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - IBillCreatedPayload, - IBillEditedPayload, - IBIllEventDeletedPayload, - IBillOpenedPayload, -} from '@/interfaces'; -import { BillInventoryTransactions } from '@/services/Purchases/Bills/BillInventoryTransactions'; - -@Service() -export default class BillWriteInventoryTransactionsSubscriber { - @Inject() - private billsInventory: BillInventoryTransactions; - - /** - * Attaches events with handles. - */ - public attach(bus) { - bus.subscribe( - events.bill.onCreated, - this.handleWritingInventoryTransactions - ); - bus.subscribe( - events.bill.onOpened, - this.handleWritingInventoryTransactions - ); - bus.subscribe( - events.bill.onEdited, - this.handleOverwritingInventoryTransactions - ); - bus.subscribe( - events.bill.onDeleted, - this.handleRevertInventoryTransactions - ); - } - - /** - * Handles writing the inventory transactions once bill created. - * @param {IBillCreatedPayload | IBillOpenedPayload} payload - - */ - private handleWritingInventoryTransactions = async ({ - tenantId, - bill, - trx, - }: IBillCreatedPayload | IBillOpenedPayload) => { - // Can't continue if the bill is not opened yet. - if (!bill.openedAt) return null; - - await this.billsInventory.recordInventoryTransactions( - tenantId, - bill.id, - false, - trx - ); - }; - - /** - * Handles the overwriting the inventory transactions once bill edited. - * @param {IBillEditedPayload} payload - - */ - private handleOverwritingInventoryTransactions = async ({ - tenantId, - billId, - bill, - trx, - }: IBillEditedPayload) => { - // Can't continue if the bill is not opened yet. - if (!bill.openedAt) return null; - - await this.billsInventory.recordInventoryTransactions( - tenantId, - billId, - true, - trx - ); - }; - - /** - * Handles the reverting the inventory transactions once the bill deleted. - * @param {IBIllEventDeletedPayload} payload - - */ - private handleRevertInventoryTransactions = async ({ - tenantId, - billId, - trx, - }: IBIllEventDeletedPayload) => { - await this.billsInventory.revertInventoryTransactions( - tenantId, - billId, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/Bills/index.ts b/packages/server/src/subscribers/Bills/index.ts deleted file mode 100644 index 720561be2..000000000 --- a/packages/server/src/subscribers/Bills/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Container } from 'typedi'; -import { EventSubscriber, On } from 'event-dispatch'; - -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import BillsService from '@/services/Purchases/Bills'; - -@EventSubscriber() -export default class BillSubscriber { - tenancy: TenancyService; - billsService: BillsService; - logger: any; - - /** - * Constructor method. - */ - constructor() { - this.tenancy = Container.get(TenancyService); - this.billsService = Container.get(BillsService); - this.logger = Container.get('logger'); - } -} diff --git a/packages/server/src/subscribers/Inventory/Inventory.ts b/packages/server/src/subscribers/Inventory/Inventory.ts deleted file mode 100644 index 4229506b8..000000000 --- a/packages/server/src/subscribers/Inventory/Inventory.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { map, head } from 'lodash'; -import events from '@/subscribers/events'; -import InventoryItemsQuantitySync from '@/services/Inventory/InventoryItemsQuantitySync'; -import InventoryService from '@/services/Inventory/Inventory'; -import { - IComputeItemCostJobCompletedPayload, - IInventoryTransactionsCreatedPayload, - IInventoryTransactionsDeletedPayload, -} from '@/interfaces'; -import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks'; -import { SaleInvoicesCost } from '@/services/Sales/Invoices/SalesInvoicesCost'; -import { ImportAls } from '@/services/Import/ImportALS'; - -@Service() -export default class InventorySubscriber { - @Inject() - private saleInvoicesCost: SaleInvoicesCost; - - @Inject() - private itemsQuantitySync: InventoryItemsQuantitySync; - - @Inject() - private inventoryService: InventoryService; - - @Inject('agenda') - private agenda: any; - - @Inject() - private importAls: ImportAls; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.inventory.onInventoryTransactionsCreated, - this.handleScheduleItemsCostOnInventoryTransactionsCreated - ); - bus.subscribe( - events.inventory.onInventoryTransactionsCreated, - this.syncItemsQuantityOnceInventoryTransactionsCreated - ); - bus.subscribe( - events.inventory.onComputeItemCostJobScheduled, - this.markGlobalSettingsComputeItems - ); - bus.subscribe( - events.inventory.onInventoryCostEntriesWritten, - this.markGlobalSettingsComputeItemsCompeted - ); - bus.subscribe( - events.inventory.onComputeItemCostJobCompleted, - this.onComputeItemCostJobFinished - ); - bus.subscribe( - events.inventory.onInventoryTransactionsDeleted, - this.handleScheduleItemsCostOnInventoryTransactionsDeleted - ); - bus.subscribe( - events.inventory.onInventoryTransactionsDeleted, - this.syncItemsQuantityOnceInventoryTransactionsDeleted - ); - } - - /** - * Sync inventory items quantity once inventory transactions created. - * @param {IInventoryTransactionsCreatedPayload} payload - - */ - private syncItemsQuantityOnceInventoryTransactionsCreated = async ({ - tenantId, - inventoryTransactions, - trx, - }: IInventoryTransactionsCreatedPayload) => { - const itemsQuantityChanges = this.itemsQuantitySync.getItemsQuantityChanges( - inventoryTransactions - ); - - await this.itemsQuantitySync.changeItemsQuantity( - tenantId, - itemsQuantityChanges, - trx - ); - }; - - /** - * Handles schedule compute inventory items cost once inventory transactions created. - * @param {IInventoryTransactionsCreatedPayload} payload - - */ - private handleScheduleItemsCostOnInventoryTransactionsCreated = async ({ - tenantId, - inventoryTransactions, - trx, - }: IInventoryTransactionsCreatedPayload) => { - const inImportPreviewScope = this.importAls.isImportPreview; - - // Avoid running the cost items job if the async process is in import preview. - if (inImportPreviewScope) return; - - await this.saleInvoicesCost.computeItemsCostByInventoryTransactions( - tenantId, - inventoryTransactions - ); - }; - - /** - * Marks items cost compute running state. - */ - private markGlobalSettingsComputeItems = async ({ tenantId }) => { - await this.inventoryService.markItemsCostComputeRunning(tenantId, true); - }; - - /** - * Marks items cost compute as completed. - */ - private markGlobalSettingsComputeItemsCompeted = async ({ tenantId }) => { - await this.inventoryService.markItemsCostComputeRunning(tenantId, false); - }; - - /** - * Handle run writing the journal entries once the compute items jobs completed. - */ - private onComputeItemCostJobFinished = async ({ - itemId, - tenantId, - startingDate, - }: IComputeItemCostJobCompletedPayload) => { - const dependsComputeJobs = await this.agenda.jobs({ - name: 'compute-item-cost', - nextRunAt: { $ne: null }, - 'data.tenantId': tenantId, - }); - // There is no scheduled compute jobs waiting. - if (dependsComputeJobs.length === 0) { - await this.saleInvoicesCost.scheduleWriteJournalEntries( - tenantId, - startingDate - ); - } - }; - - /** - * Sync inventory items quantity once inventory transactions deleted. - */ - private syncItemsQuantityOnceInventoryTransactionsDeleted = async ({ - tenantId, - oldInventoryTransactions, - trx, - }: IInventoryTransactionsDeletedPayload) => { - const itemsQuantityChanges = - this.itemsQuantitySync.getReverseItemsQuantityChanges( - oldInventoryTransactions - ); - await this.itemsQuantitySync.changeItemsQuantity( - tenantId, - itemsQuantityChanges, - trx - ); - }; - - /** - * Schedules compute items cost once the inventory transactions deleted. - */ - private handleScheduleItemsCostOnInventoryTransactionsDeleted = async ({ - tenantId, - transactionType, - transactionId, - oldInventoryTransactions, - trx, - }: IInventoryTransactionsDeletedPayload) => { - // Ignore compute item cost with theses transaction types. - const ignoreWithTransactionTypes = ['OpeningItem']; - - if (ignoreWithTransactionTypes.indexOf(transactionType) !== -1) { - return; - } - const inventoryItemsIds = map(oldInventoryTransactions, 'itemId'); - const startingDates = map(oldInventoryTransactions, 'date'); - const startingDate: Date = head(startingDates); - - runAfterTransaction(trx, async () => { - try { - await this.saleInvoicesCost.scheduleComputeCostByItemsIds( - tenantId, - inventoryItemsIds, - startingDate - ); - } catch (error) { - console.error(error); - } - }); - }; -} diff --git a/packages/server/src/subscribers/Inventory/InventoryAdjustment.ts b/packages/server/src/subscribers/Inventory/InventoryAdjustment.ts deleted file mode 100644 index 7db1a0069..000000000 --- a/packages/server/src/subscribers/Inventory/InventoryAdjustment.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import InventoryAdjustmentService from '@/services/Inventory/InventoryAdjustmentService'; -import InventoryAdjustmentsGL from '@/services/Inventory/InventoryAdjustmentGL'; -import { - IInventoryAdjustmentEventCreatedPayload, - IInventoryAdjustmentEventDeletedPayload, - IInventoryAdjustmentEventPublishedPayload, -} from '@/interfaces'; - -@Service() -export default class InventoryAdjustmentsSubscriber { - @Inject() - private inventoryAdjustment: InventoryAdjustmentService; - - @Inject() - private inventoryAdjustmentGL: InventoryAdjustmentsGL; - - /** - * Attaches events with handles. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.inventoryAdjustment.onQuickCreated, - this.handleWriteInventoryTransactionsOncePublished - ); - bus.subscribe( - events.inventoryAdjustment.onQuickCreated, - this.handleGLEntriesOnceIncrementAdjustmentCreated - ); - bus.subscribe( - events.inventoryAdjustment.onPublished, - this.handleGLEntriesOnceIncrementAdjustmentCreated - ); - bus.subscribe( - events.inventoryAdjustment.onPublished, - this.handleWriteInventoryTransactionsOncePublished - ); - bus.subscribe( - events.inventoryAdjustment.onDeleted, - this.handleRevertInventoryTransactionsOnceDeleted - ); - bus.subscribe( - events.inventoryAdjustment.onDeleted, - this.revertAdjustmentGLEntriesOnceDeleted - ); - } - - /** - * Handles writing increment inventory adjustment GL entries. - */ - private handleGLEntriesOnceIncrementAdjustmentCreated = async ({ - tenantId, - inventoryAdjustmentId, - inventoryAdjustment, - trx, - }: IInventoryAdjustmentEventCreatedPayload) => { - // Can't continue if the inventory adjustment is not published. - if (!inventoryAdjustment.isPublished) { - return; - } - // Can't continue if the inventory adjustment direction is not `IN`. - if (inventoryAdjustment.type !== 'increment') { - return; - } - await this.inventoryAdjustmentGL.writeAdjustmentGLEntries( - tenantId, - inventoryAdjustmentId, - trx - ); - }; - - /** - * Handles writing inventory transactions once the quick adjustment created. - * @param {IInventoryAdjustmentEventPublishedPayload} payload - * @param {IInventoryAdjustmentEventCreatedPayload} payload - - */ - private handleWriteInventoryTransactionsOncePublished = async ({ - tenantId, - inventoryAdjustment, - trx, - }: - | IInventoryAdjustmentEventPublishedPayload - | IInventoryAdjustmentEventCreatedPayload) => { - await this.inventoryAdjustment.writeInventoryTransactions( - tenantId, - inventoryAdjustment, - false, - trx - ); - }; - - /** - * Handles reverting invetory transactions once the inventory adjustment deleted. - * @param {IInventoryAdjustmentEventDeletedPayload} payload - - */ - private handleRevertInventoryTransactionsOnceDeleted = async ({ - tenantId, - inventoryAdjustmentId, - oldInventoryAdjustment, - trx, - }: IInventoryAdjustmentEventDeletedPayload) => { - // Can't continue if the inventory adjustment is not published. - if (!oldInventoryAdjustment.isPublished) { - return; - } - // Reverts the inventory transactions of adjustment transaction. - await this.inventoryAdjustment.revertInventoryTransactions( - tenantId, - inventoryAdjustmentId, - trx - ); - }; - - /** - * Reverts the inventory adjustment GL entries once the transaction deleted. - * @param {IInventoryAdjustmentEventDeletedPayload} payload - - */ - private revertAdjustmentGLEntriesOnceDeleted = async ({ - tenantId, - inventoryAdjustmentId, - oldInventoryAdjustment, - }: IInventoryAdjustmentEventDeletedPayload) => { - // Can't continue if the inventory adjustment is not published. - if (!oldInventoryAdjustment.isPublished) { - return; - } - await this.inventoryAdjustmentGL.revertAdjustmentGLEntries( - tenantId, - inventoryAdjustmentId - ); - }; -} diff --git a/packages/server/src/subscribers/LandedCost/index.ts b/packages/server/src/subscribers/LandedCost/index.ts deleted file mode 100644 index b5642036e..000000000 --- a/packages/server/src/subscribers/LandedCost/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Container } from 'typedi'; -import { On, EventSubscriber } from 'event-dispatch'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import BillsService from '@/services/Purchases/Bills'; - -@EventSubscriber() -export default class BillLandedCostSubscriber { - logger: any; - tenancy: TenancyService; - billsService: BillsService; - - /** - * Constructor method. - */ - constructor() { - this.logger = Container.get('logger'); - this.tenancy = Container.get(TenancyService); - this.billsService = Container.get(BillsService); - } - - /** - * Marks the rewrite bill journal entries once the landed cost transaction - * be deleted or created. - */ - @On(events.billLandedCost.onCreated) - @On(events.billLandedCost.onDeleted) - public async handleRewriteBillJournalEntries({ - tenantId, - billId, - bilLandedCostId, - }) { - // Overwrite the journal entries for the given bill transaction. - this.logger.info('[bill] overwriting bill journal entries.', { tenantId }); - await this.billsService.recordJournalTransactions(tenantId, billId, true); - } -} diff --git a/packages/server/src/subscribers/Organization/BuildSmsNotification.ts b/packages/server/src/subscribers/Organization/BuildSmsNotification.ts deleted file mode 100644 index d516dd393..000000000 --- a/packages/server/src/subscribers/Organization/BuildSmsNotification.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { IOrganizationBuildEventPayload } from '@/interfaces'; - -@Service() -export default class OrgBuildSmsNotificationSubscriber { - @Inject('agenda') - agenda: any; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe(events.organization.build, this.sendWelcomeSmsNotification); - } - - /** - * Sends welcome SMS once the organization build completed. - */ - public sendWelcomeSmsNotification = async ({ - tenantId, - systemUser, - }: IOrganizationBuildEventPayload) => { - // await this.agenda.now('welcome-sms', { tenant, user }); - }; -} diff --git a/packages/server/src/subscribers/Organization/SyncTenantAdminUser.ts b/packages/server/src/subscribers/Organization/SyncTenantAdminUser.ts deleted file mode 100644 index f0d88fcf6..000000000 --- a/packages/server/src/subscribers/Organization/SyncTenantAdminUser.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import OrganizationService from '@/services/Organization/OrganizationService'; -import { IOrganizationBuildEventPayload } from '@/interfaces'; - -@Service() -export default class OrgSyncTenantAdminUserSubscriber { - @Inject() - organizationService: OrganizationService; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe(events.organization.build, this.assignSystemUserAsAdminRole); - } - - /** - * Assign the authorized system user as admin role. - */ - public assignSystemUserAsAdminRole = async ({ - tenantId, - systemUser, - }: IOrganizationBuildEventPayload) => { - await this.organizationService.syncSystemUserToTenant(tenantId, systemUser); - }; -} diff --git a/packages/server/src/subscribers/PaymentMades/PaymentSyncBillBalance.ts b/packages/server/src/subscribers/PaymentMades/PaymentSyncBillBalance.ts deleted file mode 100644 index 5a6ce8a72..000000000 --- a/packages/server/src/subscribers/PaymentMades/PaymentSyncBillBalance.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { BillPaymentBillSync } from '@/services/Purchases/BillPayments/BillPaymentBillSync'; -import { - IBillPaymentEventCreatedPayload, - IBillPaymentEventDeletedPayload, - IBillPaymentEventEditedPayload, -} from '@/interfaces'; - -@Service() -export default class PaymentSyncBillBalance { - @Inject() - private billPaymentsService: BillPaymentBillSync; - - /** - * - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.billPayment.onCreated, - this.handleBillsIncrementPaymentAmount - ); - bus.subscribe( - events.billPayment.onEdited, - this.handleBillsIncrementPaymentAmount - ); - bus.subscribe( - events.billPayment.onDeleted, - this.handleBillDecrementPaymentAmount - ); - } - - /** - * Handle bill payment amount increment/decrement once bill payment created or edited. - */ - private handleBillsIncrementPaymentAmount = async ({ - tenantId, - billPayment, - oldBillPayment, - billPaymentId, - trx, - }: IBillPaymentEventCreatedPayload | IBillPaymentEventEditedPayload) => { - this.billPaymentsService.saveChangeBillsPaymentAmount( - tenantId, - billPayment.entries, - oldBillPayment?.entries || null, - trx - ); - }; - - /** - * Handle revert bill payment amount once bill payment deleted. - */ - private handleBillDecrementPaymentAmount = async ({ - tenantId, - billPaymentId, - oldBillPayment, - trx, - }: IBillPaymentEventDeletedPayload) => { - this.billPaymentsService.saveChangeBillsPaymentAmount( - tenantId, - oldBillPayment.entries.map((entry) => ({ ...entry, paymentAmount: 0 })), - oldBillPayment.entries, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/PaymentReceive/AutoSerialIncrement.ts b/packages/server/src/subscribers/PaymentReceive/AutoSerialIncrement.ts deleted file mode 100644 index 89f60a9e6..000000000 --- a/packages/server/src/subscribers/PaymentReceive/AutoSerialIncrement.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { PaymentReceivedIncrement } from '@/services/Sales/PaymentReceived/PaymentReceivedIncrement'; -import { IPaymentReceivedCreatedPayload } from '@/interfaces'; - -@Service() -export default class PaymentReceiveAutoSerialSubscriber extends EventSubscriber { - @Inject() - private paymentIncrement: PaymentReceivedIncrement; - - /** - * Attaches the events with handles. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onCreated, - this.handlePaymentNextNumberIncrement - ); - } - - /** - * Handles increment next number of payment receive once be created. - * @param {IPaymentReceivedCreatedPayload} payload - - */ - private handlePaymentNextNumberIncrement = async ({ - tenantId, - paymentReceiveId, - trx, - }: IPaymentReceivedCreatedPayload) => { - await this.paymentIncrement.incrementNextPaymentReceiveNumber(tenantId); - }; -} diff --git a/packages/server/src/subscribers/PaymentReceive/PaymentReceiveSyncInvoices.ts b/packages/server/src/subscribers/PaymentReceive/PaymentReceiveSyncInvoices.ts deleted file mode 100644 index 643ca94d4..000000000 --- a/packages/server/src/subscribers/PaymentReceive/PaymentReceiveSyncInvoices.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { PaymentReceivedInvoiceSync } from '@/services/Sales/PaymentReceived/PaymentReceivedInvoiceSync'; -import { - IPaymentReceivedCreatedPayload, - IPaymentReceivedDeletedPayload, - IPaymentReceivedEditedPayload, -} from '@/interfaces'; - -@Service() -export default class PaymentReceiveSyncInvoicesSubscriber { - @Inject() - private paymentSyncInvoice: PaymentReceivedInvoiceSync; - - /** - * Attaches the events to handles. - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onCreated, - this.handleInvoiceIncrementPaymentOnceCreated - ); - bus.subscribe( - events.paymentReceive.onEdited, - this.handleInvoiceIncrementPaymentOnceEdited - ); - bus.subscribe( - events.paymentReceive.onDeleted, - this.handleInvoiceDecrementPaymentAmount - ); - } - - /** - * Handle sale invoice increment/decrement payment amount - * once created, edited or deleted. - */ - private handleInvoiceIncrementPaymentOnceCreated = async ({ - tenantId, - paymentReceive, - trx, - }: IPaymentReceivedCreatedPayload) => { - await this.paymentSyncInvoice.saveChangeInvoicePaymentAmount( - tenantId, - paymentReceive.entries, - null, - trx - ); - }; - - /** - * Handle sale invoice increment/decrement payment amount once edited. - */ - private handleInvoiceIncrementPaymentOnceEdited = async ({ - tenantId, - paymentReceiveId, - paymentReceive, - oldPaymentReceive, - trx, - }: IPaymentReceivedEditedPayload) => { - await this.paymentSyncInvoice.saveChangeInvoicePaymentAmount( - tenantId, - paymentReceive.entries, - oldPaymentReceive?.entries || null, - trx - ); - }; - - /** - * Handle revert invoices payment amount once payment receive deleted. - */ - private handleInvoiceDecrementPaymentAmount = async ({ - tenantId, - paymentReceiveId, - oldPaymentReceive, - trx, - }: IPaymentReceivedDeletedPayload) => { - await this.paymentSyncInvoice.saveChangeInvoicePaymentAmount( - tenantId, - oldPaymentReceive.entries.map((entry) => ({ - ...entry, - paymentAmount: 0, - })), - oldPaymentReceive.entries, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/PaymentReceive/SendSmsNotificationToCustomer.ts b/packages/server/src/subscribers/PaymentReceive/SendSmsNotificationToCustomer.ts deleted file mode 100644 index 840698831..000000000 --- a/packages/server/src/subscribers/PaymentReceive/SendSmsNotificationToCustomer.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { PaymentReceiveNotifyBySms } from '@/services/Sales/PaymentReceived/PaymentReceivedSmsNotify'; -import { IPaymentReceivedCreatedPayload } from '@/interfaces'; -import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks'; - -@Service() -export default class SendSmsNotificationPaymentReceive { - @Inject() - private paymentReceiveSmsNotify: PaymentReceiveNotifyBySms; - - /** - * Attach events. - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onCreated, - this.handleNotifyViaSmsOncePaymentPublish - ); - } - - /** - * Handles send SMS notification after payment transaction creation. - */ - private handleNotifyViaSmsOncePaymentPublish = ({ - tenantId, - paymentReceiveId, - trx, - }: IPaymentReceivedCreatedPayload) => { - // Notify via Sms after transactions complete running. - runAfterTransaction(trx, async () => { - try { - await this.paymentReceiveSmsNotify.notifyViaSmsNotificationAfterCreation( - tenantId, - paymentReceiveId - ); - } catch (error) { } - }); - }; -} diff --git a/packages/server/src/subscribers/PaymentReceive/WriteGLEntries.ts b/packages/server/src/subscribers/PaymentReceive/WriteGLEntries.ts deleted file mode 100644 index b1b197a96..000000000 --- a/packages/server/src/subscribers/PaymentReceive/WriteGLEntries.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - IPaymentReceivedCreatedPayload, - IPaymentReceivedDeletedPayload, - IPaymentReceivedEditedPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { PaymentReceivedGLEntries } from '@/services/Sales/PaymentReceived/PaymentReceivedGLEntries'; - -@Service() -export default class PaymentReceivesWriteGLEntriesSubscriber { - @Inject() - private paymentReceiveGLEntries: PaymentReceivedGLEntries; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.paymentReceive.onCreated, - this.handleWriteJournalEntriesOnceCreated - ); - bus.subscribe( - events.paymentReceive.onEdited, - this.handleOverwriteJournalEntriesOnceEdited - ); - bus.subscribe( - events.paymentReceive.onDeleted, - this.handleRevertJournalEntriesOnceDeleted - ); - } - - /** - * Handle journal entries writing once the payment receive created. - */ - private handleWriteJournalEntriesOnceCreated = async ({ - tenantId, - paymentReceiveId, - trx, - }: IPaymentReceivedCreatedPayload) => { - await this.paymentReceiveGLEntries.writePaymentGLEntries( - tenantId, - paymentReceiveId, - trx - ); - }; - - /** - * Handle journal entries writing once the payment receive edited. - */ - private handleOverwriteJournalEntriesOnceEdited = async ({ - tenantId, - paymentReceive, - trx, - }: IPaymentReceivedEditedPayload) => { - await this.paymentReceiveGLEntries.rewritePaymentGLEntries( - tenantId, - paymentReceive.id, - trx - ); - }; - - /** - * Handles revert journal entries once deleted. - */ - private handleRevertJournalEntriesOnceDeleted = async ({ - tenantId, - paymentReceiveId, - trx, - }: IPaymentReceivedDeletedPayload) => { - await this.paymentReceiveGLEntries.revertPaymentGLEntries( - tenantId, - paymentReceiveId, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/SaleEstimate/AutoIncrementSerial.ts b/packages/server/src/subscribers/SaleEstimate/AutoIncrementSerial.ts deleted file mode 100644 index 8cc9300fc..000000000 --- a/packages/server/src/subscribers/SaleEstimate/AutoIncrementSerial.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import SettingsService from '@/services/Settings/SettingsService'; -import { ISaleEstimateCreatedPayload } from '@/interfaces'; - -@Service() -export default class SaleEstimateAutoSerialSubscriber { - @Inject() - tenancy: TenancyService; - - @Inject() - settingsService: SettingsService; - - /** - * Attaches events to handles.events.saleEstimate.onCreated - */ - public attach(bus) { - bus.subscribe( - events.saleEstimate.onCreated, - this.handleEstimateNextNumberIncrement - ); - } - - /** - * Handle sale estimate increment next number once be created. - */ - private handleEstimateNextNumberIncrement = async ({ - tenantId, - saleEstimateId, - trx, - }: ISaleEstimateCreatedPayload) => { - await this.settingsService.incrementNextNumber(tenantId, { - key: 'next_number', - group: 'sales_estimates', - }); - }; -} diff --git a/packages/server/src/subscribers/SaleEstimate/SmsNotifications.ts b/packages/server/src/subscribers/SaleEstimate/SmsNotifications.ts deleted file mode 100644 index 1da8f501d..000000000 --- a/packages/server/src/subscribers/SaleEstimate/SmsNotifications.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleEstimateNotifyBySms } from '@/services/Sales/Estimates/SaleEstimateSmsNotify'; -import { ISaleEstimateCreatedPayload } from '@/interfaces'; -import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks'; - -@Service() -export default class SaleEstimateSmsNotificationSubscriber { - @Inject() - private saleEstimateNotifyBySms: SaleEstimateNotifyBySms; - - /** - * Attaches events to handles.events.saleEstimate.onCreated - */ - public attach(bus) { - bus.subscribe( - events.saleEstimate.onCreated, - this.handleNotifySmSNotificationAfterCreation - ); - } - - /** - * Notify via SMS notification after sale estimate creation. - */ - private handleNotifySmSNotificationAfterCreation = async ({ - tenantId, - saleEstimateId, - saleEstimate, - trx, - }: ISaleEstimateCreatedPayload) => { - // Can't continue if estimate is not delivered. - if (!saleEstimate.isDelivered) return; - - runAfterTransaction(trx, async () => { - try { - await this.saleEstimateNotifyBySms.notifyViaSmsNotificationAfterCreation( - tenantId, - saleEstimateId - ); - } catch (error) {} - }); - }; -} diff --git a/packages/server/src/subscribers/SaleInvoices/AutoIncrementSerial.ts b/packages/server/src/subscribers/SaleInvoices/AutoIncrementSerial.ts deleted file mode 100644 index 1c8764f6a..000000000 --- a/packages/server/src/subscribers/SaleInvoices/AutoIncrementSerial.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import events from '@/subscribers/events'; -import { SaleInvoiceIncrement } from '@/services/Sales/Invoices/SaleInvoiceIncrement'; -import { ISaleInvoiceCreatedPayload } from '@/interfaces'; - -@Service() -export default class SaleInvoiceAutoIncrementSubscriber extends EventSubscriber { - @Inject() - private saleInvoicesService: SaleInvoiceIncrement; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleInvoiceNextNumberIncrement - ); - } - - /** - * Handles sale invoice next number increment once invoice created. - * @param {ISaleInvoiceCreatedPayload} payload - - */ - private handleInvoiceNextNumberIncrement = async ({ - tenantId, - }: ISaleInvoiceCreatedPayload) => { - await this.saleInvoicesService.incrementNextInvoiceNumber(tenantId); - }; -} diff --git a/packages/server/src/subscribers/SaleInvoices/ConvertFromEstimate.ts b/packages/server/src/subscribers/SaleInvoices/ConvertFromEstimate.ts deleted file mode 100644 index e8cba71a2..000000000 --- a/packages/server/src/subscribers/SaleInvoices/ConvertFromEstimate.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -import { ConvertSaleEstimate } from '@/services/Sales/Estimates/ConvetSaleEstimate'; -import { ISaleInvoiceCreatedPayload } from '@/interfaces'; -import events from '@/subscribers/events'; - -@Service() -export default class SaleInvoiceConvertFromEstimateSubscriber extends EventSubscriber { - @Inject() - private convertEstimateToInvoiceService: ConvertSaleEstimate; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleMarkEstimateConvertOnceInvoiceCreated - ); - } - - /** - * Marks the sale estimate as converted from the sale invoice once created. - */ - private handleMarkEstimateConvertOnceInvoiceCreated = async ({ - tenantId, - saleInvoice, - saleInvoiceDTO, - saleInvoiceId, - trx, - }: ISaleInvoiceCreatedPayload) => { - if (saleInvoiceDTO.fromEstimateId) { - await this.convertEstimateToInvoiceService.convertEstimateToInvoice( - tenantId, - saleInvoiceDTO.fromEstimateId, - saleInvoiceId, - trx - ); - } - }; -} diff --git a/packages/server/src/subscribers/SaleInvoices/SendSmsNotificationToCustomer.ts b/packages/server/src/subscribers/SaleInvoices/SendSmsNotificationToCustomer.ts deleted file mode 100644 index 94907a99d..000000000 --- a/packages/server/src/subscribers/SaleInvoices/SendSmsNotificationToCustomer.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleInvoiceNotifyBySms } from '@/services/Sales/Invoices/SaleInvoiceNotifyBySms'; -import { ISaleInvoiceCreatedPayload } from '@/interfaces'; -import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks'; - -@Service() -export default class SendSmsNotificationToCustomer { - @Inject() - private saleInvoiceNotifyBySms: SaleInvoiceNotifyBySms; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.sendSmsNotificationAfterInvoiceCreation - ); - } - - /** - * Hnadle sending SMS notification after invoice transaction creation. - */ - private sendSmsNotificationAfterInvoiceCreation = async ({ - tenantId, - saleInvoiceId, - saleInvoice, - trx, - }: ISaleInvoiceCreatedPayload) => { - // Can't continue if the sale invoice is not marked as delivered. - if (!saleInvoice.deliveredAt) return; - - // Notify via sms after transactions complete running. - runAfterTransaction(trx, async () => { - try { - await this.saleInvoiceNotifyBySms.notifyDetailsBySmsAfterCreation( - tenantId, - saleInvoiceId - ); - } catch (error) {} - }); - }; -} diff --git a/packages/server/src/subscribers/SaleInvoices/WriteInventoryTransactions.ts b/packages/server/src/subscribers/SaleInvoices/WriteInventoryTransactions.ts deleted file mode 100644 index ec3d920a5..000000000 --- a/packages/server/src/subscribers/SaleInvoices/WriteInventoryTransactions.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletedPayload, - ISaleInvoiceEditedPayload, - ISaleInvoiceEventDeliveredPayload, -} from '@/interfaces'; -import { InvoiceInventoryTransactions } from '@/services/Sales/Invoices/InvoiceInventoryTransactions'; - -@Service() -export default class WriteInventoryTransactions { - @Inject() - private saleInvoiceInventory: InvoiceInventoryTransactions; - - /** - * Attaches events with handles - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleWritingInventoryTransactions - ); - bus.subscribe( - events.saleInvoice.onDelivered, - this.handleWritingInventoryTransactions - ); - bus.subscribe( - events.saleInvoice.onEdited, - this.handleRewritingInventoryTransactions - ); - bus.subscribe( - events.saleInvoice.onDeleted, - this.handleDeletingInventoryTransactions - ); - } - - /** - * Handles the writing inventory transactions once the invoice created. - * @param {ISaleInvoiceCreatedPayload} payload - */ - private handleWritingInventoryTransactions = async ({ - tenantId, - saleInvoice, - trx, - }: ISaleInvoiceCreatedPayload | ISaleInvoiceEventDeliveredPayload) => { - // Can't continue if the sale invoice is not delivered yet. - if (!saleInvoice.deliveredAt) return null; - - await this.saleInvoiceInventory.recordInventoryTranscactions( - tenantId, - saleInvoice, - false, - trx - ); - }; - - /** - * Rewriting the inventory transactions once the sale invoice be edited. - * @param {ISaleInvoiceEditPayload} payload - - */ - private handleRewritingInventoryTransactions = async ({ - tenantId, - saleInvoice, - trx, - }: ISaleInvoiceEditedPayload) => { - await this.saleInvoiceInventory.recordInventoryTranscactions( - tenantId, - saleInvoice, - true, - trx - ); - }; - - /** - * Handles deleting the inventory transactions once the invoice deleted. - * @param {ISaleInvoiceDeletedPayload} payload - - */ - private handleDeletingInventoryTransactions = async ({ - tenantId, - saleInvoiceId, - oldSaleInvoice, - trx, - }: ISaleInvoiceDeletedPayload) => { - await this.saleInvoiceInventory.revertInventoryTransactions( - tenantId, - saleInvoiceId, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/SaleInvoices/WriteJournalEntries.ts b/packages/server/src/subscribers/SaleInvoices/WriteJournalEntries.ts deleted file mode 100644 index 4b1eab698..000000000 --- a/packages/server/src/subscribers/SaleInvoices/WriteJournalEntries.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { - ISaleInvoiceCreatedPayload, - ISaleInvoiceDeletePayload, - ISaleInvoiceEditedPayload, -} from '@/interfaces'; -import { SaleInvoiceGLEntries } from '@/services/Sales/Invoices/InvoiceGLEntries'; - -@Service() -export default class SaleInvoiceWriteGLEntriesSubscriber { - @Inject() - private saleInvoiceGLEntries: SaleInvoiceGLEntries; - - /** - * Constructor method. - */ - public attach(bus) { - bus.subscribe( - events.saleInvoice.onCreated, - this.handleWriteJournalEntriesOnInvoiceCreated - ); - bus.subscribe( - events.saleInvoice.onDelivered, - this.handleWriteJournalEntriesOnInvoiceCreated - ); - bus.subscribe( - events.saleInvoice.onEdited, - this.handleRewriteJournalEntriesOnceInvoiceEdit - ); - bus.subscribe( - events.saleInvoice.onDeleted, - this.handleRevertingInvoiceJournalEntriesOnDelete - ); - } - - /** - * Records journal entries of the non-inventory invoice. - * @param {ISaleInvoiceCreatedPayload} payload - - * @returns {Promise} - */ - private handleWriteJournalEntriesOnInvoiceCreated = async ({ - tenantId, - saleInvoiceId, - saleInvoice, - trx, - }: ISaleInvoiceCreatedPayload) => { - // Can't continue if the sale invoice is not delivered yet. - if (!saleInvoice.deliveredAt) return null; - - await this.saleInvoiceGLEntries.writeInvoiceGLEntries( - tenantId, - saleInvoiceId, - trx - ); - }; - - /** - * Records journal entries of the non-inventory invoice. - * @param {ISaleInvoiceEditedPayload} payload - - * @returns {Promise} - */ - private handleRewriteJournalEntriesOnceInvoiceEdit = async ({ - tenantId, - saleInvoice, - trx, - }: ISaleInvoiceEditedPayload) => { - // Can't continue if the sale invoice is not delivered yet. - if (!saleInvoice.deliveredAt) return null; - - await this.saleInvoiceGLEntries.rewritesInvoiceGLEntries( - tenantId, - saleInvoice.id, - trx - ); - }; - - /** - * Handle reverting journal entries once sale invoice delete. - * @param {ISaleInvoiceDeletePayload} payload - - * @returns {Promise} - */ - private handleRevertingInvoiceJournalEntriesOnDelete = async ({ - tenantId, - saleInvoiceId, - trx, - }: ISaleInvoiceDeletePayload) => { - await this.saleInvoiceGLEntries.revertInvoiceGLEntries( - tenantId, - saleInvoiceId, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/SaleReceipt/AutoIncrementSerial.ts b/packages/server/src/subscribers/SaleReceipt/AutoIncrementSerial.ts deleted file mode 100644 index 934690fe9..000000000 --- a/packages/server/src/subscribers/SaleReceipt/AutoIncrementSerial.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleReceiptIncrement } from '@/services/Sales/Receipts/SaleReceiptIncrement'; -import { ISaleReceiptCreatedPayload } from '@/interfaces'; - -@Service() -export default class SaleReceiptAutoSerialSubscriber { - @Inject() - private saleReceiptsService: SaleReceiptIncrement; - - /** - * - * @param bus - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreated, - this.handleReceiptNextNumberIncrement - ); - } - - /** - * Handle sale receipt increment next number once be created. - */ - private handleReceiptNextNumberIncrement = async ({ - tenantId, - saleReceiptId, - }: ISaleReceiptCreatedPayload) => { - await this.saleReceiptsService.incrementNextReceiptNumber(tenantId); - }; -} diff --git a/packages/server/src/subscribers/SaleReceipt/SendSmsNotificationToCustomer.ts b/packages/server/src/subscribers/SaleReceipt/SendSmsNotificationToCustomer.ts deleted file mode 100644 index 41aa53c4d..000000000 --- a/packages/server/src/subscribers/SaleReceipt/SendSmsNotificationToCustomer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Inject, Service } from 'typedi'; -import events from '@/subscribers/events'; -import { SaleReceiptNotifyBySms } from '@/services/Sales/Receipts/SaleReceiptNotifyBySms'; -import { ISaleReceiptCreatedPayload } from '@/interfaces'; -import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks'; - -@Service() -export default class SendSmsNotificationSaleReceipt { - @Inject() - private saleReceiptNotifyBySms: SaleReceiptNotifyBySms; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreated, - this.handleNotifyViaSmsAfterReceiptCreation - ); - } - - /** - * Notify via SMS message after receipt transaction creation. - * @param {ISaleReceiptCreatedPayload} payload - - */ - private handleNotifyViaSmsAfterReceiptCreation = ({ - tenantId, - saleReceiptId, - saleReceipt, - trx, - }: ISaleReceiptCreatedPayload) => { - // Can't continue if the sale receipt is not closed. - if (!saleReceipt.isClosed) return; - - // Notify via sms after transaction complete running. - runAfterTransaction(trx, async () => { - try { - await this.saleReceiptNotifyBySms.notifyViaSmsAfterCreation( - tenantId, - saleReceiptId - ); - } catch (error) {} - }); - }; -} diff --git a/packages/server/src/subscribers/SaleReceipt/WriteInventoryTransactions.ts b/packages/server/src/subscribers/SaleReceipt/WriteInventoryTransactions.ts deleted file mode 100644 index bf4fd007a..000000000 --- a/packages/server/src/subscribers/SaleReceipt/WriteInventoryTransactions.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Inject } from 'typedi'; -import { EventSubscriber } from 'event-dispatch'; -import events from '@/subscribers/events'; -import { - ISaleReceiptCreatedPayload, - ISaleReceiptEditedPayload, - ISaleReceiptEventDeletedPayload, -} from '@/interfaces'; -import { SaleReceiptInventoryTransactions } from '@/services/Sales/Receipts/SaleReceiptInventoryTransactions'; - -@EventSubscriber() -export default class SaleReceiptInventoryTransactionsSubscriber { - @Inject() - private saleReceiptInventory: SaleReceiptInventoryTransactions; - - /** - * Subscribe events to handles. - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreated, - this.handleWritingInventoryTransactions - ); - bus.subscribe( - events.saleReceipt.onEdited, - this.handleRewritingInventoryTransactions - ); - bus.subscribe( - events.saleReceipt.onDeleted, - this.handleDeletingInventoryTransactions - ); - } - - /** - * Handles the writing inventory transactions once the receipt created. - * @param {ISaleReceiptCreatedPayload} payload - - */ - private handleWritingInventoryTransactions = async ({ - tenantId, - saleReceipt, - trx, - }: ISaleReceiptCreatedPayload) => { - // Can't continue if the sale receipt is not closed yet. - if (!saleReceipt.closedAt) return null; - - await this.saleReceiptInventory.recordInventoryTransactions( - tenantId, - saleReceipt, - false, - trx - ); - }; - - /** - * Rewriting the inventory transactions once the sale invoice be edited. - * @param {ISaleReceiptEditedPayload} payload - - */ - private handleRewritingInventoryTransactions = async ({ - tenantId, - saleReceipt, - trx, - }: ISaleReceiptEditedPayload) => { - // Can't continue if the sale receipt is not closed yet. - if (!saleReceipt.closedAt) return null; - - await this.saleReceiptInventory.recordInventoryTransactions( - tenantId, - saleReceipt, - true, - trx - ); - }; - - /** - * Handles deleting the inventory transactions once the receipt deleted. - * @param {ISaleReceiptEventDeletedPayload} payload - - */ - private handleDeletingInventoryTransactions = async ({ - tenantId, - saleReceiptId, - trx, - }: ISaleReceiptEventDeletedPayload) => { - await this.saleReceiptInventory.revertInventoryTransactions( - tenantId, - saleReceiptId, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/SaleReceipt/WriteJournalEntries.ts b/packages/server/src/subscribers/SaleReceipt/WriteJournalEntries.ts deleted file mode 100644 index 32c9c363b..000000000 --- a/packages/server/src/subscribers/SaleReceipt/WriteJournalEntries.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; -import TenancyService from '@/services/Tenancy/TenancyService'; -import { - ISaleReceiptCreatedPayload, - ISaleReceiptEditedPayload, - ISaleReceiptEventDeletedPayload, -} from '@/interfaces'; -import { SaleReceiptGLEntries } from '@/services/Sales/Receipts/SaleReceiptGLEntries'; - -@Service() -export default class SaleReceiptWriteGLEntriesSubscriber { - @Inject() - private saleReceiptGLEntries: SaleReceiptGLEntries; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreated, - this.handleWriteReceiptIncomeJournalEntrieOnCreate - ); - bus.subscribe( - events.saleReceipt.onClosed, - this.handleWriteReceiptIncomeJournalEntrieOnCreate - ); - bus.subscribe( - events.saleReceipt.onEdited, - this.handleWriteReceiptIncomeJournalEntrieOnEdited - ); - bus.subscribe( - events.saleReceipt.onDeleted, - this.handleRevertReceiptJournalEntriesOnDeleted - ); - } - - /** - * Handles writing sale receipt income journal entries once created. - * @param {ISaleReceiptCreatedPayload} payload - - */ - public handleWriteReceiptIncomeJournalEntrieOnCreate = async ({ - tenantId, - saleReceiptId, - saleReceipt, - trx, - }: ISaleReceiptCreatedPayload) => { - // Can't continue if the sale receipt is not closed yet. - if (!saleReceipt.closedAt) return null; - - // Writes the sale receipt income journal entries. - await this.saleReceiptGLEntries.writeIncomeGLEntries( - tenantId, - saleReceiptId, - trx - ); - }; - - /** - * Handles sale receipt revert jouranl entries once be deleted. - * @param {ISaleReceiptEventDeletedPayload} payload - - */ - public handleRevertReceiptJournalEntriesOnDeleted = async ({ - tenantId, - saleReceiptId, - trx, - }: ISaleReceiptEventDeletedPayload) => { - await this.saleReceiptGLEntries.revertReceiptGLEntries( - tenantId, - saleReceiptId, - trx - ); - }; - - /** - * Handles writing sale receipt income journal entries once be edited. - * @param {ISaleReceiptEditedPayload} payload - - */ - private handleWriteReceiptIncomeJournalEntrieOnEdited = async ({ - tenantId, - saleReceiptId, - saleReceipt, - trx, - }: ISaleReceiptEditedPayload) => { - // Can't continue if the sale receipt is not closed yet. - if (!saleReceipt.closedAt) return null; - - // Writes the sale receipt income journal entries. - await this.saleReceiptGLEntries.rewriteReceiptGLEntries( - tenantId, - saleReceiptId, - trx - ); - }; -} diff --git a/packages/server/src/subscribers/events.ts b/packages/server/src/subscribers/events.ts deleted file mode 100644 index d1ee2d6d1..000000000 --- a/packages/server/src/subscribers/events.ts +++ /dev/null @@ -1,775 +0,0 @@ -export default { - /** - * Authentication service. - */ - auth: { - signIn: 'onSignIn', - signingIn: 'onSigningIn', - - signUp: 'onSignUp', - signingUp: 'onSigningUp', - - signUpConfirming: 'signUpConfirming', - signUpConfirmed: 'signUpConfirmed', - - sendingResetPassword: 'onSendingResetPassword', - sendResetPassword: 'onSendResetPassword', - - resetPassword: 'onResetPassword', - resetingPassword: 'onResetingPassword', - }, - - /** - * Invite users service. - */ - inviteUser: { - acceptInvite: 'onUserAcceptInvite', - sendInvite: 'onUserSendInvite', - resendInvite: 'onUserInviteResend', - checkInvite: 'onUserCheckInvite', - sendInviteTenantSynced: 'onUserSendInviteTenantSynced', - }, - - /** - * Organization managment service. - */ - organization: { - build: 'onOrganizationBuild', - built: 'onOrganizationBuilt', - - seeded: 'onOrganizationSeeded', - - baseCurrencyUpdated: 'onOrganizationBaseCurrencyUpdated', - }, - - /** - * Organization subscription. - */ - subscription: { - onSubscriptionCancel: 'onSubscriptionCancel', - onSubscriptionCancelled: 'onSubscriptionCancelled', - - onSubscriptionResume: 'onSubscriptionResume', - onSubscriptionResumed: 'onSubscriptionResumed', - - onSubscriptionPlanChange: 'onSubscriptionPlanChange', - onSubscriptionPlanChanged: 'onSubscriptionPlanChanged', - - onSubscriptionSubscribed: 'onSubscriptionSubscribed', - - onSubscriptionPaymentSucceed: 'onSubscriptionPaymentSucceed', - onSubscriptionPaymentFailed: 'onSubscriptionPaymentFailed', - }, - - /** - * Tenants managment service. - */ - tenantManager: { - databaseCreated: 'onDatabaseCreated', - tenantMigrated: 'onTenantMigrated', - tenantSeeded: 'onTenantSeeded', - }, - - /** - * Accounts service. - */ - accounts: { - onViewed: 'onAccountViewed', - onListViewed: 'onAccountsListViewed', - - onCreating: 'onAccountCreating', - onCreated: 'onAccountCreated', - - onEditing: 'onAccountEditing', - onEdited: 'onAccountEdited', - - onDelete: 'onAccountDelete', - onDeleted: 'onAccountDeleted', - - onBulkDeleted: 'onBulkDeleted', - onBulkActivated: 'onAccountBulkActivated', - - onActivated: 'onAccountActivated', - }, - - /** - * Manual journals service. - */ - manualJournals: { - onCreating: 'onManualJournalCreating', - onCreated: 'onManualJournalCreated', - - onEditing: 'onManualJournalEditing', - onEdited: 'onManualJournalEdited', - - onDeleting: 'onManualJournalDeleting', - onDeleted: 'onManualJournalDeleted', - - onPublished: 'onManualJournalPublished', - onPublishing: 'onManualJournalPublishing', - }, - - /** - * Expenses service. - */ - expenses: { - onCreating: 'onExpenseCreating', - onCreated: 'onExpenseCreated', - - onEditing: 'onExpenseEditing', - onEdited: 'onExpenseEdited', - - onDeleting: 'onExpenseDeleting', - onDeleted: 'onExpenseDeleted', - - onPublishing: 'onExpensePublishing', - onPublished: 'onExpensePublished', - }, - - /** - * Sales invoices service. - */ - saleInvoice: { - onViewed: 'onSaleInvoiceItemViewed', - onListViewed: 'onSaleInvoiceListViewed', - - onPdfViewed: 'onSaleInvoicePdfViewed', - - onCreate: 'onSaleInvoiceCreate', - onCreating: 'onSaleInvoiceCreating', - onCreated: 'onSaleInvoiceCreated', - - onEdit: 'onSaleInvoiceEdit', - onEditing: 'onSaleInvoiceEditing', - onEdited: 'onSaleInvoiceEdited', - - onDelete: 'onSaleInvoiceDelete', - onDeleting: 'onSaleInvoiceDeleting', - onDeleted: 'onSaleInvoiceDeleted', - - onDelivering: 'onSaleInvoiceDelivering', - onDeliver: 'onSaleInvoiceDeliver', - onDelivered: 'onSaleInvoiceDelivered', - - onPublish: 'onSaleInvoicePublish', - onPublished: 'onSaleInvoicePublished', - - onWriteoff: 'onSaleInvoiceWriteoff', - onWrittenoff: 'onSaleInvoiceWrittenoff', - onWrittenoffCancel: 'onSaleInvoiceWrittenoffCancel', - onWrittenoffCanceled: 'onSaleInvoiceWrittenoffCanceled', - - onNotifySms: 'onSaleInvoiceNotifySms', - onNotifiedSms: 'onSaleInvoiceNotifiedSms', - - onNotifyMail: 'onSaleInvoiceNotifyMail', - onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail', - - onPreMailSend: 'onSaleInvoicePreMailSend', - onMailSend: 'onSaleInvoiceMailSend', - onMailSent: 'onSaleInvoiceMailSent', - - onMailReminderSend: 'onSaleInvoiceMailReminderSend', - onMailReminderSent: 'onSaleInvoiceMailReminderSent', - - onPublicLinkGenerating: 'onPublicSharableLinkGenerating', - onPublicLinkGenerated: 'onPublicSharableLinkGenerated', - }, - - /** - * Sales estimates service. - */ - saleEstimate: { - onViewed: 'onSaleEstimateViewed', - onPdfViewed: 'onSaleEstimatePdfViewed', - - onCreating: 'onSaleEstimateCreating', - onCreated: 'onSaleEstimateCreated', - - onEditing: 'onSaleEstimateEditing', - onEdited: 'onSaleEstimateEdited', - - onDeleting: 'onSaleEstimatedDeleting', - onDeleted: 'onSaleEstimatedDeleted', - - onPublishing: 'onSaleEstimatedPublishing', - onPublished: 'onSaleEstimatedPublished', - - onNotifySms: 'onSaleEstimateNotifySms', - onNotifiedSms: 'onSaleEstimateNotifiedSms', - - onDelivering: 'onSaleEstimateDelivering', - onDelivered: 'onSaleEstimateDelivered', - - onConvertedToInvoice: 'onSaleEstimateConvertedToInvoice', - - onApproving: 'onSaleEstimateApproving', - onApproved: 'onSaleEstimateApproved', - - onRejecting: 'onSaleEstimateRejecting', - onRejected: 'onSaleEstimateRejected', - - onNotifyMail: 'onSaleEstimateNotifyMail', - - onPreMailSend: 'onSaleEstimatePreMailSend', - onMailSend: 'onSaleEstimateMailSend', - onMailSent: 'onSaleEstimateMailSent', - }, - - /** - * Sales receipts service. - */ - saleReceipt: { - onPdfViewed: 'onSaleReceiptPdfViewed', - - onCreating: 'onSaleReceiptsCreating', - onCreated: 'onSaleReceiptsCreated', - - onEditing: 'onSaleReceiptsEditing', - onEdited: 'onSaleReceiptsEdited', - - onDeleting: 'onSaleReceiptsDeleting', - onDeleted: 'onSaleReceiptsDeleted', - - onPublishing: 'onSaleReceiptPublishing', - onPublished: 'onSaleReceiptPublished', - - onClosed: 'onSaleReceiptClosed', - onClosing: 'onSaleReceiptClosing', - - onNotifySms: 'onSaleReceiptNotifySms', - onNotifiedSms: 'onSaleReceiptNotifiedSms', - - onPreMailSend: 'onSaleReceiptPreMailSend', - onMailSend: 'onSaleReceiptMailSend', - onMailSent: 'onSaleReceiptMailSent', - }, - - /** - * Payment receipts service. - */ - paymentReceive: { - onPdfViewed: 'onPaymentReceivedPdfViewed', - - onCreated: 'onPaymentReceiveCreated', - onCreating: 'onPaymentReceiveCreating', - - onEditing: 'onPaymentReceiveEditing', - onEdited: 'onPaymentReceiveEdited', - - onDeleting: 'onPaymentReceiveDeleting', - onDeleted: 'onPaymentReceiveDeleted', - - onPublishing: 'onPaymentReceivePublishing', - onPublished: 'onPaymentReceivePublished', - - onNotifySms: 'onPaymentReceiveNotifySms', - onNotifiedSms: 'onPaymentReceiveNotifiedSms', - - onPreMailSend: 'onPaymentReceivePreMailSend', - onMailSend: 'onPaymentReceiveMailSend', - onMailSent: 'onPaymentReceiveMailSent', - }, - - /** - * Bills service. - */ - bill: { - onCreating: 'onBillCreating', - onCreated: 'onBillCreated', - - onEditing: 'onBillEditing', - onEdited: 'onBillEdited', - - onDeleting: 'onBillDeleting', - onDeleted: 'onBillDeleted', - - onPublishing: 'onBillPublishing', - onPublished: 'onBillPublished', - - onOpening: 'onBillOpening', - onOpened: 'onBillOpened', - }, - - /** - * Bill payments service. - */ - billPayment: { - onCreating: 'onBillPaymentCreating', - onCreated: 'onBillPaymentCreated', - - onEditing: 'onBillPaymentEditing', - onEdited: 'onBillPaymentEdited', - - onDeleted: 'onBillPaymentDeleted', - onDeleting: 'onBillPaymentDeleting', - - onPublishing: 'onBillPaymentPublishing', - onPublished: 'onBillPaymentPublished', - }, - - /** - * Customers services. - */ - customers: { - onCreating: 'onCustomerCreating', - onCreated: 'onCustomerCreated', - - onEdited: 'onCustomerEdited', - onEditing: 'onCustomerEditing', - - onDeleted: 'onCustomerDeleted', - onDeleting: 'onCustomerDeleting', - onBulkDeleted: 'onBulkDeleted', - - onOpeningBalanceChanging: 'onCustomerOpeningBalanceChanging', - onOpeningBalanceChanged: 'onCustomerOpeingBalanceChanged', - - onActivating: 'onCustomerActivating', - onActivated: 'onCustomerActivated', - }, - - /** - * Vendors services. - */ - vendors: { - onCreated: 'onVendorCreated', - onCreating: 'onVendorCreating', - - onEdited: 'onVendorEdited', - onEditing: 'onVendorEditing', - - onDeleted: 'onVendorDeleted', - onDeleting: 'onVendorDeleting', - - onOpeningBalanceChanging: 'onVendorOpeingBalanceChanging', - onOpeningBalanceChanged: 'onVendorOpeingBalanceChanged', - - onActivating: 'onVendorActivating', - onActivated: 'onVendorActivated', - }, - - /** - * Items service. - */ - item: { - onViewed: 'onItemViewed', - - onCreated: 'onItemCreated', - onCreating: 'onItemCreating', - - onEditing: 'onItemEditing', - onEdited: 'onItemEdited', - - onDeleted: 'onItemDeleted', - onDeleting: 'onItemDeleting', - - onActivating: 'onItemActivating', - onActivated: 'onItemActivated', - - onInactivating: 'onInactivating', - onInactivated: 'onItemInactivated', - }, - - /** - * Item category service. - */ - itemCategory: { - onCreated: 'onItemCategoryCreated', - onEdited: 'onItemCategoryEdited', - onDeleted: 'onItemCategoryDeleted', - onBulkDeleted: 'onItemCategoryBulkDeleted', - }, - - /** - * Inventory service. - */ - inventory: { - onInventoryTransactionsCreated: 'onInventoryTransactionsCreated', - onInventoryTransactionsDeleted: 'onInventoryTransactionsDeleted', - - onComputeItemCostJobScheduled: 'onComputeItemCostJobScheduled', - onComputeItemCostJobStarted: 'onComputeItemCostJobStarted', - onComputeItemCostJobCompleted: 'onComputeItemCostJobCompleted', - - onInventoryCostEntriesWritten: 'onInventoryCostEntriesWritten', - - onCostLotsGLEntriesBeforeWrite: 'onInventoryCostLotsGLEntriesBeforeWrite', - onCostLotsGLEntriesWrite: 'onInventoryCostLotsGLEntriesWrite', - }, - - /** - * Inventory adjustment service. - */ - inventoryAdjustment: { - onQuickCreating: 'onInventoryAdjustmentCreating', - onQuickCreated: 'onInventoryAdjustmentQuickCreated', - - onCreated: 'onInventoryAdjustmentCreated', - - onDeleting: 'onInventoryAdjustmentDeleting', - onDeleted: 'onInventoryAdjustmentDeleted', - - onPublishing: 'onInventoryAdjustmentPublishing', - onPublished: 'onInventoryAdjustmentPublished', - }, - - /** - * Bill landed cost. - */ - billLandedCost: { - onCreate: 'onBillLandedCostCreate', - onCreated: 'onBillLandedCostCreated', - onDelete: 'onBillLandedCostDelete', - onDeleted: 'onBillLandedCostDeleted', - }, - - cashflow: { - onOwnerContributionCreate: 'onCashflowOwnerContributionCreate', - onOwnerContributionCreated: 'onCashflowOwnerContributionCreated', - - onOtherIncomeCreate: 'onCashflowOtherIncomeCreate', - onOtherIncomeCreated: 'onCashflowOtherIncomeCreated', - - onTransactionCreating: 'onCashflowTransactionCreating', - onTransactionCreated: 'onCashflowTransactionCreated', - - onTransactionDeleting: 'onCashflowTransactionDeleting', - onTransactionDeleted: 'onCashflowTransactionDeleted', - - onTransactionCategorizing: 'onTransactionCategorizing', - onTransactionCategorized: 'onCashflowTransactionCategorized', - - onTransactionUncategorizedCreating: 'onTransactionUncategorizedCreating', - onTransactionUncategorizedCreated: 'onTransactionUncategorizedCreated', - - onTransactionUncategorizing: 'onTransactionUncategorizing', - onTransactionUncategorized: 'onTransactionUncategorized', - - onTransactionCategorizingAsExpense: 'onTransactionCategorizingAsExpense', - onTransactionCategorizedAsExpense: 'onTransactionCategorizedAsExpense', - }, - - /** - * Roles service events. - */ - roles: { - onCreate: 'onRoleCreate', - onCreated: 'onRoleCreated', - onEdit: 'onRoleEdit', - onEdited: 'onRoleEdited', - onDelete: 'onRoleDelete', - onDeleted: 'onRoleDeleted', - }, - - tenantUser: { - onEdited: 'onTenantUserEdited', - onDeleted: 'onTenantUserDeleted', - onActivated: 'onTenantUserActivated', - onInactivated: 'onTenantUserInactivated', - }, - - /** - * Credit note service. - */ - creditNote: { - onPdfViewed: 'onCreditNotePdfViewed', - - onCreate: 'onCreditNoteCreate', - onCreating: 'onCreditNoteCreating', - onCreated: 'onCreditNoteCreated', - - onEditing: 'onCreditNoteEditing', - onEdit: 'onCreditNoteEdit', - onEdited: 'onCreditNoteEdited', - - onDelete: 'onCreditNoteDelete', - onDeleting: 'onCreditNoteDeleting', - onDeleted: 'onCreditNoteDeleted', - - onOpen: 'onCreditNoteOpen', - onOpening: 'onCreditNoteOpening', - onOpened: 'onCreditNoteOpened', - - onRefundCreate: 'onCreditNoteRefundCreate', - onRefundCreating: 'onCreditNoteRefundCreating', - onRefundCreated: 'onCreditNoteRefundCreated', - - onRefundDelete: 'onCreditNoteRefundDelete', - onRefundDeleting: 'onCreditNoteRefundDeleting', - onRefundDeleted: 'onCreditNoteRefundDeleted', - - onApplyToInvoicesCreated: 'onCreditNoteApplyToInvoiceCreated', - onApplyToInvoicesCreate: 'onCreditNoteApplyToInvoiceCreate', - onApplyToInvoicesDeleted: 'onCreditNoteApplyToInvoiceDeleted', - }, - - /** - * Vendor credit service. - */ - vendorCredit: { - onCreate: 'onVendorCreditCreate', - onCreating: 'onVendorCreditCreating', - onCreated: 'onVendorCreditCreated', - - onEdit: 'onVendorCreditEdit', - onEditing: 'onVendorCreditEditing', - onEdited: 'onVendorCreditEdited', - - onDelete: 'onVendorCreditDelete', - onDeleting: 'onVendorCreditDeleting', - onDeleted: 'onVendorCreditDeleted', - - onOpen: 'onVendorCreditOpen', - onOpened: 'onVendorCreditOpened', - - onRefundCreating: 'onVendorCreditRefundCreating', - onRefundCreate: 'onVendorCreditRefundCreate', - onRefundCreated: 'onVendorCreditRefundCreated', - - onRefundDelete: 'onVendorCreditRefundDelete', - onRefundDeleting: 'onVendorCreditRefundDeleting', - onRefundDeleted: 'onVendorCreditRefundDeleted', - - onApplyToInvoicesCreated: 'onVendorCreditApplyToInvoiceCreated', - onApplyToInvoicesCreate: 'onVendorCreditApplyToInvoiceCreate', - onApplyToInvoicesDeleted: 'onVendorCreditApplyToInvoiceDeleted', - }, - - transactionsLocking: { - locked: 'onTransactionLockingLocked', - lockCanceled: 'onTransactionLockingLockCanceled', - partialUnlocked: 'onTransactionLockingPartialUnlocked', - partialUnlockCanceled: 'onTransactionLockingPartialUnlockCanceled', - }, - - warehouse: { - onCreate: 'onWarehouseCreate', - onCreated: 'onWarehouseCreated', - - onEdit: 'onWarehouseEdit', - onEdited: 'onWarehouseEdited', - - onDelete: 'onWarehouseDelete', - onDeleted: 'onWarehouseDeleted', - - onActivate: 'onWarehouseActivate', - onActivated: 'onWarehouseActivated', - - onMarkPrimary: 'onWarehouseMarkPrimary', - onMarkedPrimary: 'onWarehouseMarkedPrimary', - }, - - warehouseTransfer: { - onCreate: 'onWarehouseTransferCreate', - onCreated: 'onWarehouseTransferCreated', - - onEdit: 'onWarehouseTransferEdit', - onEdited: 'onWarehouseTransferEdited', - - onDelete: 'onWarehouseTransferDelete', - onDeleted: 'onWarehouseTransferDeleted', - - onInitiate: 'onWarehouseTransferInitiate', - onInitiated: 'onWarehouseTransferInitated', - - onTransfer: 'onWarehouseTransferInitiate', - onTransferred: 'onWarehouseTransferTransferred', - }, - - /** - * Branches. - */ - branch: { - onActivate: 'onBranchActivate', - onActivated: 'onBranchActivated', - - onMarkPrimary: 'onBranchMarkPrimary', - onMarkedPrimary: 'onBranchMarkedPrimary', - }, - - /** - * Projects. - */ - project: { - onCreate: 'onProjectCreate', - onCreating: 'onProjectCreating', - onCreated: 'onProjectCreated', - - onEdit: 'onEditProject', - onEditing: 'onEditingProject', - onEdited: 'onEditedProject', - - onEditStatus: 'onEditStatusProject', - onEditingStatus: 'onEditingStatusProject', - onEditedStatus: 'onEditedStatusProject', - - onDelete: 'onDeleteProject', - onDeleting: 'onDeletingProject', - onDeleted: 'onDeletedProject', - }, - - /** - * Project Tasks. - */ - projectTask: { - onCreate: 'onProjectTaskCreate', - onCreating: 'onProjectTaskCreating', - onCreated: 'onProjectTaskCreated', - - onEdit: 'onProjectTaskEdit', - onEditing: 'onProjectTaskEditing', - onEdited: 'onProjectTaskEdited', - - onDelete: 'onProjectTaskDelete', - onDeleting: 'onProjectTaskDeleting', - onDeleted: 'onProjectTaskDeleted', - }, - - /** - * Project Times. - */ - projectTime: { - onCreate: 'onProjectTimeCreate', - onCreating: 'onProjectTimeCreating', - onCreated: 'onProjectTimeCreated', - - onEdit: 'onProjectTimeEdit', - onEditing: 'onProjectTimeEditing', - onEdited: 'onProjectTimeEdited', - - onDelete: 'onProjectTimeDelete', - onDeleting: 'onProjectTimeDeleting', - onDeleted: 'onProjectTimeDeleted', - }, - - taxRates: { - onCreating: 'onTaxRateCreating', - onCreated: 'onTaxRateCreated', - - onEditing: 'onTaxRateEditing', - onEdited: 'onTaxRateEdited', - - onDeleting: 'onTaxRateDeleting', - onDeleted: 'onTaxRateDeleted', - - onActivating: 'onTaxRateActivating', - onActivated: 'onTaxRateActivated', - - onInactivating: 'onTaxRateInactivating', - onInactivated: 'onTaxRateInactivated', - }, - - plaid: { - onItemCreated: 'onPlaidItemCreated', - onTransactionsSynced: 'onPlaidTransactionsSynced', - }, - - // Bank rules. - bankRules: { - onCreating: 'onBankRuleCreating', - onCreated: 'onBankRuleCreated', - - onEditing: 'onBankRuleEditing', - onEdited: 'onBankRuleEdited', - - onDeleting: 'onBankRuleDeleting', - onDeleted: 'onBankRuleDeleted', - }, - - // Bank matching. - bankMatch: { - onMatching: 'onBankTransactionMatching', - onMatched: 'onBankTransactionMatched', - - onUnmatching: 'onBankTransactionUnmathcing', - onUnmatched: 'onBankTransactionUnmathced', - }, - - bankTransactions: { - onExcluding: 'onBankTransactionExclude', - onExcluded: 'onBankTransactionExcluded', - - onUnexcluding: 'onBankTransactionUnexcluding', - onUnexcluded: 'onBankTransactionUnexcluded', - - onPendingRemoving: 'onBankTransactionPendingRemoving', - onPendingRemoved: 'onBankTransactionPendingRemoved', - }, - - bankAccount: { - onDisconnecting: 'onBankAccountDisconnecting', - onDisconnected: 'onBankAccountDisconnected', - }, - - // Import files. - import: { - onImportCommitted: 'onImportFileCommitted', - }, - - // Branding templates - pdfTemplate: { - onCreating: 'onPdfTemplateCreating', - onCreated: 'onPdfTemplateCreated', - - onEditing: 'onPdfTemplateEditing', - onEdited: 'onPdfTemplatedEdited', - - onDeleting: 'onPdfTemplateDeleting', - onDeleted: 'onPdfTemplateDeleted', - - onAssignedDefault: 'onPdfTemplateAssignedDefault', - onAssigningDefault: 'onPdfTemplateAssigningDefault', - }, - - // Payment method. - paymentMethod: { - onEditing: 'onPaymentMethodEditing', - onEdited: 'onPaymentMethodEdited', - - onDeleted: 'onPaymentMethodDeleted', - }, - - // Payment methods integrations - paymentIntegrationLink: { - onPaymentIntegrationLink: 'onPaymentIntegrationLink', - onPaymentIntegrationDeleteLink: 'onPaymentIntegrationDeleteLink', - }, - - // Stripe Payment Integration - stripeIntegration: { - onAccountCreated: 'onStripeIntegrationAccountCreated', - onAccountDeleted: 'onStripeIntegrationAccountDeleted', - - onPaymentLinkCreated: 'onStripePaymentLinkCreated', - onPaymentLinkInactivated: 'onStripePaymentLinkInactivated', - - onOAuthCodeGranted: 'onStripeOAuthCodeGranted', - }, - - // Stripe Payment Webhooks - stripeWebhooks: { - onCheckoutSessionCompleted: 'onStripeCheckoutSessionCompleted', - onAccountUpdated: 'onStripeAccountUpdated', - }, - - // Reports - reports: { - onBalanceSheetViewed: 'onBalanceSheetViewed', - onTrialBalanceSheetView: 'onTrialBalanceSheetViewed', - onProfitLossSheetViewed: 'onProfitLossSheetViewed', - onCashflowStatementViewed: 'onCashflowStatementViewed', - onGeneralLedgerViewed: 'onGeneralLedgerViewed', - onJournalViewed: 'onJounralViewed', - onReceivableAgingViewed: 'onReceivableAgingViewed', - onPayableAgingViewed: 'onPayableAgingViewed', - onCustomerBalanceSummaryViewed: 'onInventoryValuationViewed', - onVendorBalanceSummaryViewed: 'onVendorBalanceSummaryViewed', - onInventoryValuationViewed: 'onCustomerBalanceSummaryViewed', - onCustomerTransactionsViewed: 'onCustomerTransactionsViewed', - onVendorTransactionsViewed: 'onVendorTransactionsViewed', - onSalesByItemViewed: 'onSalesByItemViewed', - onPurchasesByItemViewed: 'onPurchasesByItemViewed', - }, - -}; diff --git a/packages/server/src/system/migrations/20190104195900_create_password_resets_table.js b/packages/server/src/system/migrations/20190104195900_create_password_resets_table.js deleted file mode 100644 index 9337949c7..000000000 --- a/packages/server/src/system/migrations/20190104195900_create_password_resets_table.js +++ /dev/null @@ -1,9 +0,0 @@ - -exports.up = (knex) => knex.schema.createTable('password_resets', (table) => { - table.increments(); - table.string('email').index(); - table.string('token').index(); - table.timestamp('created_at'); -}); - -exports.down = (knex) => knex.schema.dropTableIfExists('password_resets'); \ No newline at end of file diff --git a/packages/server/src/system/migrations/20200420134631_create_tenants_table.js b/packages/server/src/system/migrations/20200420134631_create_tenants_table.js deleted file mode 100644 index 189afa328..000000000 --- a/packages/server/src/system/migrations/20200420134631_create_tenants_table.js +++ /dev/null @@ -1,22 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('tenants', (table) => { - table.bigIncrements(); - table.string('organization_id').index(); - - table.dateTime('under_maintenance_since').nullable(); - table.dateTime('initialized_at').nullable(); - table.dateTime('seeded_at').nullable(); - table.dateTime('built_at').nullable(); - table.string('build_job_id'); - - table.integer('database_batch'); - table.string('upgrade_job_id'); - - table.timestamps(); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('tenants'); -}; diff --git a/packages/server/src/system/migrations/20200420134633_create_users_table.js b/packages/server/src/system/migrations/20200420134633_create_users_table.js deleted file mode 100644 index 0366df1b1..000000000 --- a/packages/server/src/system/migrations/20200420134633_create_users_table.js +++ /dev/null @@ -1,26 +0,0 @@ -exports.up = (knex) => { - return knex.schema.createTable('users', (table) => { - table.increments(); - table.string('first_name'); - table.string('last_name'); - table.string('email').index(); - table.string('phone_number').index(); - table.string('password'); - table.boolean('active').index(); - table.string('language'); - table - .bigInteger('tenant_id') - .unsigned() - .index() - .references('id') - .inTable('tenants'); - table.dateTime('invite_accepted_at').index(); - table.dateTime('last_login_at').index(); - table.dateTime('deleted_at').index(); - table.timestamps(); - }); -}; - -exports.down = (knex) => { - return knex.schema.dropTableIfExists('users'); -}; diff --git a/packages/server/src/system/migrations/20200422225247_create_user_invites_table.js b/packages/server/src/system/migrations/20200422225247_create_user_invites_table.js deleted file mode 100644 index 42028ccc7..000000000 --- a/packages/server/src/system/migrations/20200422225247_create_user_invites_table.js +++ /dev/null @@ -1,15 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('user_invites', (table) => { - table.increments(); - table.string('email').index(); - table.string('token').unique().index(); - table.bigInteger('tenant_id').unsigned().index().references('id').inTable('tenants'); - table.integer('user_id').unsigned().index().references('id').inTable('users'); - table.datetime('created_at'); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('user_invites'); -}; diff --git a/packages/server/src/system/migrations/20200527091642_create_subscriptions_plans_table.js b/packages/server/src/system/migrations/20200527091642_create_subscriptions_plans_table.js deleted file mode 100644 index 09d890648..000000000 --- a/packages/server/src/system/migrations/20200527091642_create_subscriptions_plans_table.js +++ /dev/null @@ -1,22 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('subscriptions_plans', table => { - table.increments(); - - table.string('name'); - table.string('description'); - table.decimal('price'); - table.string('currency', 3); - - table.integer('trial_period'); - table.string('trial_interval'); - - table.integer('invoice_period'); - table.string('invoice_interval'); - table.timestamps(); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('subscriptions_plans') -}; diff --git a/packages/server/src/system/migrations/20200823234134_create_plans_table.js b/packages/server/src/system/migrations/20200823234134_create_plans_table.js deleted file mode 100644 index 2fc61a43a..000000000 --- a/packages/server/src/system/migrations/20200823234134_create_plans_table.js +++ /dev/null @@ -1,30 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('subscription_plans', table => { - table.increments(); - table.string('slug'); - table.string('name'); - table.string('desc'); - table.boolean('active'); - - table.decimal('price').unsigned(); - table.string('currency', 3); - - table.decimal('trial_period').nullable(); - table.string('trial_interval').nullable(); - - table.decimal('invoice_period').nullable(); - table.string('invoice_interval').nullable(); - - table.integer('index').unsigned(); - table.timestamps(); - }).then(() => { - return knex.seed.run({ - specific: 'seed_subscriptions_plans.js', - }); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('subscription_plans') -}; diff --git a/packages/server/src/system/migrations/20200823234636_create_subscription_plan_subscription.js b/packages/server/src/system/migrations/20200823234636_create_subscription_plan_subscription.js deleted file mode 100644 index 267be4614..000000000 --- a/packages/server/src/system/migrations/20200823234636_create_subscription_plan_subscription.js +++ /dev/null @@ -1,22 +0,0 @@ - -exports.up = function(knex) { - return knex.schema.createTable('subscription_plan_subscriptions', table => { - table.increments('id'); - table.string('slug'); - - table.integer('plan_id').unsigned().index().references('id').inTable('subscription_plans'); - table.bigInteger('tenant_id').unsigned().index().references('id').inTable('tenants'); - - table.dateTime('starts_at').nullable(); - table.dateTime('ends_at').nullable(); - - table.dateTime('cancels_at').nullable(); - table.dateTime('canceled_at').nullable(); - - table.timestamps(); - }); -}; - -exports.down = function(knex) { - return knex.schema.dropTableIfExists('subscription_plan_subscriptions'); -}; diff --git a/packages/server/src/system/migrations/20200823235340_create_tenants_metadata_table.js b/packages/server/src/system/migrations/20200823235340_create_tenants_metadata_table.js deleted file mode 100644 index c8f765b6a..000000000 --- a/packages/server/src/system/migrations/20200823235340_create_tenants_metadata_table.js +++ /dev/null @@ -1,22 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('tenants_metadata', (table) => { - table.bigIncrements(); - table.integer('tenant_id').unsigned(); - - table.string('name'); - table.string('industry'); - table.string('location'); - - table.string('base_currency'); - table.string('language'); - - table.string('timezone'); - table.string('date_format'); - - table.string('fiscal_year'); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('tenants_metadata'); -}; diff --git a/packages/server/src/system/migrations/20230405011450_drop_phone_number_column_from_users_table.js b/packages/server/src/system/migrations/20230405011450_drop_phone_number_column_from_users_table.js deleted file mode 100644 index 9ab142779..000000000 --- a/packages/server/src/system/migrations/20230405011450_drop_phone_number_column_from_users_table.js +++ /dev/null @@ -1,9 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('users', (table) => { - table.dropColumn('phone_number'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('users', (table) => {}); -}; diff --git a/packages/server/src/system/migrations/20231012112401_add_tax_number_column_to_tenants_metadata_table.js b/packages/server/src/system/migrations/20231012112401_add_tax_number_column_to_tenants_metadata_table.js deleted file mode 100644 index ce7de80f0..000000000 --- a/packages/server/src/system/migrations/20231012112401_add_tax_number_column_to_tenants_metadata_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('tenants_metadata', (table) => { - table.string('tax_number') - }); -}; - -exports.down = function (knex) { - return knex.schema.table('tenants_metadata', (table) => { - table.dropColumn('tax_number'); - }); -}; diff --git a/packages/server/src/system/migrations/20231209230719_create_imports_table.js b/packages/server/src/system/migrations/20231209230719_create_imports_table.js deleted file mode 100644 index ef3f73cd4..000000000 --- a/packages/server/src/system/migrations/20231209230719_create_imports_table.js +++ /dev/null @@ -1,22 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('imports', (table) => { - table.increments(); - table.string('filename'); - table.string('import_id'); - table.string('resource'); - table.json('columns'); - table.json('mapping'); - table.json('params'); - table - .bigInteger('tenant_id') - .unsigned() - .index() - .references('id') - .inTable('tenants'); - table.timestamps(); - }); -}; - -exports.down = function (knex) { - return knex.schema.dropTableIfExists('imports'); -}; diff --git a/packages/server/src/system/migrations/20240222134235_create_plaid_items_table.js b/packages/server/src/system/migrations/20240222134235_create_plaid_items_table.js deleted file mode 100644 index 4098bccca..000000000 --- a/packages/server/src/system/migrations/20240222134235_create_plaid_items_table.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = function (knex) { - return knex.schema.createTable('plaid_items', (table) => { - table.bigIncrements('id'); - table - .bigInteger('tenant_id') - .unsigned() - .index() - .references('id') - .inTable('tenants'); - table.string('plaid_item_id'); - table.timestamps(); - }); -}; - -exports.down = (knex) => {}; diff --git a/packages/server/src/system/migrations/20240222134235_seed_free_subscription_to_tenants.js b/packages/server/src/system/migrations/20240222134235_seed_free_subscription_to_tenants.js deleted file mode 100644 index 5368db3c0..000000000 --- a/packages/server/src/system/migrations/20240222134235_seed_free_subscription_to_tenants.js +++ /dev/null @@ -1,7 +0,0 @@ -exports.up = function (knex) { - return knex.seed.run({ - specific: 'seed_tenants_free_subscription.js', - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server/src/system/migrations/20240425100821_add_confirmation_columns_to_users.js b/packages/server/src/system/migrations/20240425100821_add_confirmation_columns_to_users.js deleted file mode 100644 index fada1380f..000000000 --- a/packages/server/src/system/migrations/20240425100821_add_confirmation_columns_to_users.js +++ /dev/null @@ -1,12 +0,0 @@ -exports.up = function (knex) { - return knex.schema - .table('users', (table) => { - table.string('verify_token'); - table.boolean('verified').defaultTo(false); - }) - .then(() => { - return knex('USERS').update({ verified: true }); - }); -}; - -exports.down = (knex) => {}; diff --git a/packages/server/src/system/migrations/20240714101006_add_lemon_variant_id_to_subscription_plans.js b/packages/server/src/system/migrations/20240714101006_add_lemon_variant_id_to_subscription_plans.js deleted file mode 100644 index eeee3581f..000000000 --- a/packages/server/src/system/migrations/20240714101006_add_lemon_variant_id_to_subscription_plans.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('subscription_plans', (table) => { - table.string('lemon_variant_id').nullable().index(); - }); -}; - -exports.down = (knex) => { - return knex.schema.table('subscription_plans', (table) => { - table.dropColumn('lemon_variant_id'); - }); -}; diff --git a/packages/server/src/system/migrations/20240714101229_seed_monthly_subscription_plans.js b/packages/server/src/system/migrations/20240714101229_seed_monthly_subscription_plans.js deleted file mode 100644 index 7f1e506ac..000000000 --- a/packages/server/src/system/migrations/20240714101229_seed_monthly_subscription_plans.js +++ /dev/null @@ -1,96 +0,0 @@ -exports.up = function (knex) { - return knex('subscription_plans').insert([ - // Capital Basic - { - name: 'Capital Basic (Monthly)', - slug: 'capital-basic-monthly', - price: 10, - active: true, - currency: 'USD', - invoice_period: 1, - invoice_interval: 'month', - lemon_variant_id: '446152', - // lemon_variant_id: '450016', - }, - { - name: 'Capital Basic (Annually)', - slug: 'capital-basic-annually', - price: 90, - active: true, - currency: 'USD', - invoice_period: 1, - invoice_interval: 'year', - lemon_variant_id: '446153', - // lemon_variant_id: '450018', - }, - - // # Capital Essential - { - name: 'Capital Essential (Monthly)', - slug: 'capital-essential-monthly', - price: 20, - active: true, - currency: 'USD', - invoice_period: 1, - invoice_interval: 'month', - lemon_variant_id: '446155', - // lemon_variant_id: '450028', - }, - { - name: 'Capital Essential (Annually)', - slug: 'capital-essential-annually', - price: 180, - active: true, - invoice_period: 1, - invoice_interval: 'year', - lemon_variant_id: '446156', - // lemon_variant_id: '450029', - }, - - // # Capital Plus - { - name: 'Capital Plus (Monthly)', - slug: 'capital-plus-monthly', - price: 25, - active: true, - invoice_period: 1, - invoice_interval: 'month', - lemon_variant_id: '446165', - // lemon_variant_id: '450031', - }, - { - name: 'Capital Plus (Annually)', - slug: 'capital-plus-annually', - price: 228, - active: true, - invoice_period: 1, - invoice_interval: 'year', - lemon_variant_id: '446164', - // lemon_variant_id: '450032', - }, - - // # Capital Big - { - name: 'Capital Big (Monthly)', - slug: 'capital-big-monthly', - price: 40, - active: true, - invoice_period: 1, - invoice_interval: 'month', - lemon_variant_id: '446167', - // lemon_variant_id: '450024', - }, - { - name: 'Capital Big (Annually)', - slug: 'capital-big-annually', - price: 360, - active: true, - invoice_period: 1, - invoice_interval: 'year', - lemon_variant_id: '446168', - // lemon_variant_id: '450025', - }, - ]); -}; - -exports.down = function (knex) {}; diff --git a/packages/server/src/system/migrations/20240727094214_add_lemon_subscription_id_to_subscriptions_table.js b/packages/server/src/system/migrations/20240727094214_add_lemon_subscription_id_to_subscriptions_table.js deleted file mode 100644 index 29907345a..000000000 --- a/packages/server/src/system/migrations/20240727094214_add_lemon_subscription_id_to_subscriptions_table.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('subscription_plan_subscriptions', (table) => { - table.string('lemon_subscription_id').nullable(); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('subscription_plan_subscriptions', (table) => { - table.dropColumn('lemon_subscription_id'); - }); -}; diff --git a/packages/server/src/system/migrations/20240728123419_add_trial_columns_to_subscription_table.js b/packages/server/src/system/migrations/20240728123419_add_trial_columns_to_subscription_table.js deleted file mode 100644 index b8addd516..000000000 --- a/packages/server/src/system/migrations/20240728123419_add_trial_columns_to_subscription_table.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.up = function (knex) { - return knex.schema.table('subscription_plan_subscriptions', (table) => { - table.dateTime('trial_ends_at').nullable(); - table.dropColumn('cancels_at'); - }); -}; - -exports.down = function (knex) { - return knex.schema.table('subscription_plan_subscriptions', (table) => { - table.dropColumn('trial_ends_at').nullable(); - table.dateTime('cancels_at').nullable(); - }); -}; diff --git a/packages/server/src/system/migrations/20240819164614_create_oneclick_demos_table.js b/packages/server/src/system/migrations/20240819164614_create_oneclick_demos_table.js deleted file mode 100644 index 0586350c2..000000000 --- a/packages/server/src/system/migrations/20240819164614_create_oneclick_demos_table.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.createTable('oneclick_demos', (table) => { - table.increments('id'); - table.string('key'); - table.integer('tenant_id').unsigned(); - table.integer('user_id').unsigned(); - table.timestamps(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.dropTableIfExists('oneclick_demos'); -}; diff --git a/packages/server/src/system/migrations/20240824151006_add_payment_status_to_subscriptions_table.js b/packages/server/src/system/migrations/20240824151006_add_payment_status_to_subscriptions_table.js deleted file mode 100644 index b1e70083f..000000000 --- a/packages/server/src/system/migrations/20240824151006_add_payment_status_to_subscriptions_table.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.table('subscription_plan_subscriptions', (table) => { - table.string('payment_status'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.table('subscription_plan_subscriptions', (table) => { - table.dropColumn('payment_status'); - }); -}; diff --git a/packages/server/src/system/migrations/20240909091320_create_stripe_connect_accounts_table.js b/packages/server/src/system/migrations/20240909091320_create_stripe_connect_accounts_table.js deleted file mode 100644 index 9aec8f70c..000000000 --- a/packages/server/src/system/migrations/20240909091320_create_stripe_connect_accounts_table.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.createTable('stripe_accounts', (table) => { - table.increments('id').primary(); - table.string('stripe_account_id').notNullable(); - table.string('tenant_id').notNullable(); - table.timestamps(true, true); // Adds created_at and updated_at columns - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.dropTableIfExists('stripe_accounts'); -}; diff --git a/packages/server/src/system/migrations/20240915070439_create_payment_links_table.js b/packages/server/src/system/migrations/20240915070439_create_payment_links_table.js deleted file mode 100644 index 1283052c6..000000000 --- a/packages/server/src/system/migrations/20240915070439_create_payment_links_table.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.createTable('payment_links', (table) => { - table.increments('id'); - table.integer('tenant_id'); - table.integer('resource_id'); - table.text('resource_type'); - table.string('linkId'); - table.string('publicity'); - table.datetime('expiry_at'); - table.timestamps(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.dropTableIfExists('payment_links'); -}; diff --git a/packages/server/src/system/migrations/20240928145627_add_logo_key_to_tenant_metadata.js b/packages/server/src/system/migrations/20240928145627_add_logo_key_to_tenant_metadata.js deleted file mode 100644 index c1197335b..000000000 --- a/packages/server/src/system/migrations/20240928145627_add_logo_key_to_tenant_metadata.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = function (knex) { - return knex.schema.table('tenants_metadata', (table) => { - table.string('primary_color'); - table.string('logo_key'); - table.json('address'); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = function (knex) { - return knex.schema.table('tenants_metadata', (table) => { - table.dropColumn('primary_color'); - table.dropColumn('logo_key'); - table.dropColumn('address'); - }); -}; diff --git a/packages/server/src/system/models/Import.ts b/packages/server/src/system/models/Import.ts deleted file mode 100644 index c7dfd2b90..000000000 --- a/packages/server/src/system/models/Import.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Model, ModelObject } from 'objection'; -import SystemModel from './SystemModel'; - -export class Import extends SystemModel { - resource: string; - tenantId: number; - mapping!: string; - columns!: string; - params!: string; - - /** - * Table name. - */ - static get tableName() { - return 'imports'; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['mappingParsed']; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Detarmines whether the import is mapped. - * @returns {boolean} - */ - public get isMapped() { - return Boolean(this.mapping); - } - - public get columnsParsed() { - try { - return JSON.parse(this.columns); - } catch { - return []; - } - } - - public get paramsParsed() { - try { - return JSON.parse(this.params); - } catch { - return []; - } - } - - public get mappingParsed() { - try { - return JSON.parse(this.mapping); - } catch { - return []; - } - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Tenant = require('system/models/Tenant'); - - return { - /** - * System user may belongs to tenant model. - */ - tenant: { - relation: Model.BelongsToOneRelation, - modelClass: Tenant.default, - join: { - from: 'imports.tenantId', - to: 'tenants.id', - }, - }, - }; - } -} - -export type ImportShape = ModelObject; diff --git a/packages/server/src/system/models/Invite.ts b/packages/server/src/system/models/Invite.ts deleted file mode 100644 index 5fa9e0948..000000000 --- a/packages/server/src/system/models/Invite.ts +++ /dev/null @@ -1,30 +0,0 @@ -import SystemModel from '@/system/models/SystemModel'; -import moment from 'moment'; - -export default class UserInvite extends SystemModel { - /** - * Table name. - */ - static get tableName() { - return 'user_invites'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt']; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - notExpired(query) { - const comp = moment().subtract(24, 'hours').toMySqlDateTime(); - query.where('created_at', '>=', comp); - } - } - } -} diff --git a/packages/server/src/system/models/OneclickDemo.ts b/packages/server/src/system/models/OneclickDemo.ts deleted file mode 100644 index 9900a0285..000000000 --- a/packages/server/src/system/models/OneclickDemo.ts +++ /dev/null @@ -1,17 +0,0 @@ -import SystemModel from '@/system/models/SystemModel'; - -export class OneClickDemo extends SystemModel { - /** - * Table name - */ - static get tableName() { - return 'oneclick_demos'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt']; - } -} diff --git a/packages/server/src/system/models/PasswordReset.ts b/packages/server/src/system/models/PasswordReset.ts deleted file mode 100644 index b72b0aeef..000000000 --- a/packages/server/src/system/models/PasswordReset.ts +++ /dev/null @@ -1,17 +0,0 @@ -import SystemModel from '@/system/models/SystemModel'; - -export default class PasswordResets extends SystemModel { - /** - * Table name - */ - static get tableName() { - return 'password_resets'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt']; - } -} diff --git a/packages/server/src/system/models/PaymentLink.ts b/packages/server/src/system/models/PaymentLink.ts deleted file mode 100644 index 00d83ea2d..000000000 --- a/packages/server/src/system/models/PaymentLink.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Model } from 'objection'; - -export class PaymentLink extends Model { - static get tableName() { - return 'payment_links'; - } - - /** - * Timestamps columns. - * @returns {string[]} - */ - static get timestamps() { - return ['createdAt', 'updatedAt']; - } - - public tenantId!: number; - public resourceId!: number; - public resourceType!: string; - public linkId!: string; - public publicity!: string; - public expiryAt!: Date; - - // Timestamps - public createdAt!: Date; - public updatedAt!: Date; -} diff --git a/packages/server/src/system/models/StripeAccount.ts b/packages/server/src/system/models/StripeAccount.ts deleted file mode 100644 index 2124d0c0e..000000000 --- a/packages/server/src/system/models/StripeAccount.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Model } from 'objection'; - -export class StripeAccount { - /** - * Table name - */ - static get tableName() { - return 'stripe_accounts'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return {}; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Tenant = require('./Tenant'); - - return { - tenant: { - relation: Model.BelongsToOneRelation, - modelClass: Tenant.default, - join: { - from: 'stripe_accounts.tenant_id', - to: 'tenants.id', - }, - }, - }; - } -} diff --git a/packages/server/src/system/models/Subscriptions/Plan.ts b/packages/server/src/system/models/Subscriptions/Plan.ts deleted file mode 100644 index dfbf45eff..000000000 --- a/packages/server/src/system/models/Subscriptions/Plan.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Model, mixin } from 'objection'; -import SystemModel from '@/system/models/SystemModel'; -import { PlanSubscription } from '..'; - -export default class Plan extends mixin(SystemModel) { - price: number; - invoiceInternal: number; - invoicePeriod: string; - - /** - * Table name. - */ - static get tableName() { - return 'subscription_plans'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Defined virtual attributes. - */ - static get virtualAttributes() { - return ['isFree', 'hasTrial']; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - getFeatureBySlug(builder, featureSlug) { - builder.where('slug', featureSlug); - }, - }; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const PlanSubscription = require('system/models/Subscriptions/PlanSubscription'); - - return { - /** - * The plan may have many subscriptions. - */ - subscriptions: { - relation: Model.HasManyRelation, - modelClass: PlanSubscription.default, - join: { - from: 'subscription_plans.id', - to: 'subscription_plan_subscriptions.planId', - }, - } - }; - } - - /** - * Check if plan is free. - * @return {boolean} - */ - isFree() { - return this.price <= 0; - } - - /** - * Check if plan is paid. - * @return {boolean} - */ - isPaid() { - return !this.isFree(); - } - - /** - * Check if plan has trial. - * @return {boolean} - */ - hasTrial() { - return this.trialPeriod && this.trialInterval; - } -} diff --git a/packages/server/src/system/models/Subscriptions/PlanSubscription.ts b/packages/server/src/system/models/Subscriptions/PlanSubscription.ts deleted file mode 100644 index 13c09bceb..000000000 --- a/packages/server/src/system/models/Subscriptions/PlanSubscription.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { Model, mixin } from 'objection'; -import SystemModel from '@/system/models/SystemModel'; -import moment from 'moment'; -import SubscriptionPeriod from '@/services/Subscription/SubscriptionPeriod'; -import { SubscriptionPaymentStatus } from '@/interfaces'; - -export default class PlanSubscription extends mixin(SystemModel) { - public lemonSubscriptionId: number; - - public endsAt: Date; - public startsAt: Date; - - public canceledAt: Date; - - public trialEndsAt: Date; - - public paymentStatus: SubscriptionPaymentStatus; - - /** - * Table name. - */ - static get tableName() { - return 'subscription_plan_subscriptions'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Defined virtual attributes. - */ - static get virtualAttributes() { - return [ - 'active', - 'inactive', - 'ended', - 'canceled', - 'onTrial', - 'status', - 'isPaymentFailed', - 'isPaymentSucceed', - ]; - } - - /** - * Modifiers queries. - */ - static get modifiers() { - return { - activeSubscriptions(builder) { - const dateFormat = 'YYYY-MM-DD HH:mm:ss'; - const now = moment().format(dateFormat); - - builder.where('ends_at', '>', now); - builder.where('trial_ends_at', '>', now); - }, - - inactiveSubscriptions(builder) { - builder.modify('endedTrial'); - builder.modify('endedPeriod'); - }, - - subscriptionBySlug(builder, subscriptionSlug) { - builder.where('slug', subscriptionSlug); - }, - - endedTrial(builder) { - const dateFormat = 'YYYY-MM-DD HH:mm:ss'; - const endDate = moment().format(dateFormat); - - builder.where('ends_at', '<=', endDate); - }, - - endedPeriod(builder) { - const dateFormat = 'YYYY-MM-DD HH:mm:ss'; - const endDate = moment().format(dateFormat); - - builder.where('trial_ends_at', '<=', endDate); - }, - - /** - * Filter the failed payment. - * @param builder - */ - failedPayment(builder) { - builder.where('payment_status', SubscriptionPaymentStatus.Failed); - }, - - /** - * Filter the succeed payment. - * @param builder - */ - succeedPayment(builder) { - builder.where('payment_status', SubscriptionPaymentStatus.Succeed); - }, - }; - } - - /** - * Relations mappings. - */ - static get relationMappings() { - const Tenant = require('system/models/Tenant'); - const Plan = require('system/models/Subscriptions/Plan'); - - return { - /** - * Plan subscription belongs to tenant. - */ - tenant: { - relation: Model.BelongsToOneRelation, - modelClass: Tenant.default, - join: { - from: 'subscription_plan_subscriptions.tenantId', - to: 'tenants.id', - }, - }, - - /** - * Plan description belongs to plan. - */ - plan: { - relation: Model.BelongsToOneRelation, - modelClass: Plan.default, - join: { - from: 'subscription_plan_subscriptions.planId', - to: 'subscription_plans.id', - }, - }, - }; - } - - /** - * Check if the subscription is active. - * Crtiria should be active: - * - During the trial period should NOT be canceled. - * - Out of trial period should NOT be ended. - * @return {Boolean} - */ - public active() { - return this.onTrial() ? !this.canceled() : !this.ended(); - } - - /** - * Check if the subscription is inactive. - * @return {Boolean} - */ - public inactive() { - return !this.active(); - } - - /** - * Check if paid subscription period has ended. - * @return {Boolean} - */ - public ended() { - return this.endsAt ? moment().isAfter(this.endsAt) : false; - } - - /** - * Check if the paid subscription has started. - * @returns {Boolean} - */ - public started() { - return this.startsAt ? moment().isAfter(this.startsAt) : false; - } - - /** - * Check if subscription is currently on trial. - * @return {Boolean} - */ - public onTrial() { - return this.trialEndsAt ? moment().isBefore(this.trialEndsAt) : false; - } - - /** - * Check if the subscription is canceled. - * @returns {boolean} - */ - public canceled() { - return !!this.canceledAt; - } - - /** - * Retrieves the subscription status. - * @returns {string} - */ - public status() { - return this.canceled() - ? 'canceled' - : this.onTrial() - ? 'on_trial' - : this.active() - ? 'active' - : 'inactive'; - } - - /** - * Set new period from the given details. - * @param {string} invoiceInterval - * @param {number} invoicePeriod - * @param {string} start - * - * @return {Object} - */ - static setNewPeriod(invoiceInterval, invoicePeriod, start) { - const period = new SubscriptionPeriod( - invoiceInterval, - invoicePeriod, - start - ); - - const startsAt = period.getStartDate(); - const endsAt = period.getEndDate(); - - return { startsAt, endsAt }; - } - - /** - * Renews subscription period. - * @Promise - */ - renew(invoiceInterval, invoicePeriod) { - const { startsAt, endsAt } = PlanSubscription.setNewPeriod( - invoiceInterval, - invoicePeriod - ); - return this.$query().update({ startsAt, endsAt }); - } - - /** - * Detarmines the subscription payment whether is failed. - * @returns {boolean} - */ - public isPaymentFailed() { - return this.paymentStatus === SubscriptionPaymentStatus.Failed; - } - - /** - * Detarmines the subscription payment whether is succeed. - * @returns {boolean} - */ - public isPaymentSucceed() { - return this.paymentStatus === SubscriptionPaymentStatus.Succeed; - } -} diff --git a/packages/server/src/system/models/SystemModel.ts b/packages/server/src/system/models/SystemModel.ts deleted file mode 100644 index cba8eea01..000000000 --- a/packages/server/src/system/models/SystemModel.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Container } from 'typedi'; -import BaseModel from 'models/Model'; - -export default class SystemModel extends BaseModel{ - /** - * Loging all system database queries. - * @param {...any} args - */ - static query(...args) { - const Logger = Container.get('logger'); - return super.query(...args).onBuildKnex(knexQueryBuilder => { - knexQueryBuilder.on('query', queryData => { - Logger.info(`[query][system] ${queryData.sql}`, { - bindings: queryData.bindings, - }); - }); - }); - } -} \ No newline at end of file diff --git a/packages/server/src/system/models/SystemPlaidItem.ts b/packages/server/src/system/models/SystemPlaidItem.ts deleted file mode 100644 index 43b8fb4af..000000000 --- a/packages/server/src/system/models/SystemPlaidItem.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Model } from 'objection'; -import SystemModel from '@/system/models/SystemModel'; - -export default class SystemPlaidItem extends SystemModel { - tenantId: number; - plaidItemId: string; - - /** - * Table name. - */ - static get tableName() { - return 'plaid_items'; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return []; - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Tenant = require('system/models/Tenant'); - - return { - /** - * System user may belongs to tenant model. - */ - tenant: { - relation: Model.BelongsToOneRelation, - modelClass: Tenant.default, - join: { - from: 'users.tenantId', - to: 'tenants.id', - }, - }, - }; - } -} diff --git a/packages/server/src/system/models/SystemUser.ts b/packages/server/src/system/models/SystemUser.ts deleted file mode 100644 index e1f77d566..000000000 --- a/packages/server/src/system/models/SystemUser.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Model } from 'objection'; -import bcrypt from 'bcryptjs'; -import SystemModel from '@/system/models/SystemModel'; -import SoftDeleteQueryBuilder from '@/collection/SoftDeleteQueryBuilder'; - -export default class SystemUser extends SystemModel { - firstName!: string; - lastName!: string; - verified!: boolean; - inviteAcceptedAt!: Date | null; - deletedAt!: Date | null; - - /** - * Table name. - */ - static get tableName() { - return 'users'; - } - - /** - * Soft delete query builder. - */ - static get QueryBuilder() { - return SoftDeleteQueryBuilder; - } - - /** - * Timestamps columns. - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['fullName', 'isDeleted', 'isInviteAccepted', 'isVerified']; - } - - /** - * Detarmines whether the user is deleted. - * @returns {boolean} - */ - get isDeleted() { - return !!this.deletedAt; - } - - /** - * Detarmines whether the sent invite is accepted. - * @returns {boolean} - */ - get isInviteAccepted() { - return !!this.inviteAcceptedAt; - } - - /** - * Detarmines whether the user's email is verified. - * @returns {boolean} - */ - get isVerified() { - return !!this.verified; - } - - /** - * Full name attribute. - */ - get fullName() { - return (this.firstName + ' ' + this.lastName).trim(); - } - - /** - * Relationship mapping. - */ - static get relationMappings() { - const Tenant = require('system/models/Tenant'); - - return { - /** - * System user may belongs to tenant model. - */ - tenant: { - relation: Model.BelongsToOneRelation, - modelClass: Tenant.default, - join: { - from: 'users.tenantId', - to: 'tenants.id', - }, - }, - }; - } - - /** - * Model modifiers. - */ - static get modifiers() { - return { - /** - * Filters the invite accepted users. - */ - inviteAccepted(query) { - query.whereNotNull('invite_accepted_at'); - }, - }; - } - - /** - * Verify the password of the user. - * @param {String} password - The given password. - * @return {Boolean} - */ - verifyPassword(password) { - return bcrypt.compareSync(password, this.password); - } -} diff --git a/packages/server/src/system/models/Tenant.ts b/packages/server/src/system/models/Tenant.ts deleted file mode 100644 index c91ca2081..000000000 --- a/packages/server/src/system/models/Tenant.ts +++ /dev/null @@ -1,236 +0,0 @@ -import moment from 'moment'; -import { Model } from 'objection'; -import uniqid from 'uniqid'; -import SubscriptionPeriod from '@/services/Subscription/SubscriptionPeriod'; -import BaseModel from 'models/Model'; -import TenantMetadata from './TenantMetadata'; -import PlanSubscription from './Subscriptions/PlanSubscription'; - -export default class Tenant extends BaseModel { - upgradeJobId: string; - buildJobId: string; - initializedAt!: Date | null; - seededAt!: Date | null; - - /** - * Table name. - */ - static get tableName() { - return 'tenants'; - } - - /** - * Timestamps columns. - * @returns {string[]} - */ - get timestamps() { - return ['createdAt', 'updatedAt']; - } - - /** - * Virtual attributes. - * @returns {string[]} - */ - static get virtualAttributes() { - return ['isReady', 'isBuildRunning', 'isUpgradeRunning']; - } - - /** - * Tenant is ready. - * @returns {boolean} - */ - get isReady() { - return !!(this.initializedAt && this.seededAt); - } - - /** - * Detarimes the tenant whether is build currently running. - * @returns {boolean} - */ - get isBuildRunning() { - return !!this.buildJobId; - } - - /** - * Detarmines the tenant whether is upgrade currently running. - * @returns {boolean} - */ - get isUpgradeRunning() { - return !!this.upgradeJobId; - } - - /** - * Query modifiers. - */ - static modifiers() { - return { - subscriptions(builder) { - builder.withGraphFetched('subscriptions'); - }, - }; - } - - /** - * Relations mappings. - */ - static get relationMappings() { - const PlanSubscription = require('./Subscriptions/PlanSubscription'); - const TenantMetadata = require('./TenantMetadata'); - - return { - subscriptions: { - relation: Model.HasManyRelation, - modelClass: PlanSubscription.default, - join: { - from: 'tenants.id', - to: 'subscription_plan_subscriptions.tenantId', - }, - }, - metadata: { - relation: Model.HasOneRelation, - modelClass: TenantMetadata.default, - join: { - from: 'tenants.id', - to: 'tenants_metadata.tenantId', - }, - }, - }; - } - - /** - * Creates a new tenant with random organization id. - */ - static createWithUniqueOrgId(uniqId) { - const organizationId = uniqid() || uniqId; - return this.query().insert({ organizationId }); - } - - /** - * Mark as seeded. - * @param {number} tenantId - */ - static markAsSeeded(tenantId) { - const seededAt = moment().toMySqlDateTime(); - return this.query().update({ seededAt }).where({ id: tenantId }); - } - - /** - * Mark the the given organization as initialized. - * @param {string} organizationId - */ - static markAsInitialized(tenantId) { - const initializedAt = moment().toMySqlDateTime(); - return this.query().update({ initializedAt }).where({ id: tenantId }); - } - - /** - * Marks the given tenant as built. - */ - static markAsBuilt(tenantId) { - const builtAt = moment().toMySqlDateTime(); - return this.query().update({ builtAt }).where({ id: tenantId }); - } - - /** - * Marks the given tenant as built. - */ - static markAsBuilding(tenantId, buildJobId) { - return this.query().update({ buildJobId }).where({ id: tenantId }); - } - - /** - * Marks the given tenant as built. - */ - static markAsBuildCompleted(tenantId) { - return this.query().update({ buildJobId: null }).where({ id: tenantId }); - } - - /** - * Marks the given tenant as upgrading. - * @param {number} tenantId - * @param {string} upgradeJobId - * @returns - */ - static markAsUpgrading(tenantId, upgradeJobId) { - return this.query().update({ upgradeJobId }).where({ id: tenantId }); - } - - /** - * Markes the given tenant as upgraded. - * @param {number} tenantId - * @returns - */ - static markAsUpgraded(tenantId) { - return this.query().update({ upgradeJobId: null }).where({ id: tenantId }); - } - - /** - * Saves the metadata of the given tenant. - */ - static async saveMetadata(tenantId, metadata) { - const foundMetadata = await TenantMetadata.query().findOne({ tenantId }); - const updateOrInsert = foundMetadata ? 'patch' : 'insert'; - - return TenantMetadata.query() - [updateOrInsert]({ - tenantId, - ...metadata, - }) - .where({ tenantId }); - } - - /** - * Saves the metadata of the tenant. - */ - saveMetadata(metadata) { - return Tenant.saveMetadata(this.id, metadata); - } - - /** - * - * @param {*} planId - * @param {*} invoiceInterval - * @param {*} invoicePeriod - * @param {*} subscriptionSlug - * @returns - */ - public newSubscription( - planId, - invoiceInterval, - invoicePeriod, - subscriptionSlug, - payload?, - ) { - return Tenant.newSubscription( - this.id, - planId, - invoiceInterval, - invoicePeriod, - subscriptionSlug, - payload - ); - } - - /** - * Records a new subscription for the associated tenant. - */ - static newSubscription( - tenantId: number, - planId: number, - invoiceInterval: 'month' | 'year', - invoicePeriod: number, - subscriptionSlug: string, - payload?: { lemonSqueezyId: string } - ) { - const period = new SubscriptionPeriod(invoiceInterval, invoicePeriod); - - return PlanSubscription.query().insert({ - tenantId, - slug: subscriptionSlug, - planId, - startsAt: period.getStartDate(), - endsAt: period.getEndDate(), - lemonSubscriptionId: payload?.lemonSqueezyId || null, - }); - } -} diff --git a/packages/server/src/system/models/TenantMetadata.ts b/packages/server/src/system/models/TenantMetadata.ts deleted file mode 100644 index 7356db3c6..000000000 --- a/packages/server/src/system/models/TenantMetadata.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { - defaultOrganizationAddressFormat, - organizationAddressTextFormat, -} from '@/utils/address-text-format'; -import BaseModel from 'models/Model'; -import { findByIsoCountryCode } from '@bigcapital/utils'; -import { getUploadedObjectUri } from '../../services/Attachments/utils'; - -export default class TenantMetadata extends BaseModel { - baseCurrency!: string; - name!: string; - tenantId!: number; - industry!: string; - location!: string; - language!: string; - timezone!: string; - dateFormat!: string; - fiscalYear!: string; - primaryColor!: string; - logoKey!: string; - address!: Record; - - /** - * Json schema. - */ - static get jsonSchema() { - return { - type: 'object', - required: ['tenantId', 'name', 'baseCurrency'], - properties: { - tenantId: { type: 'integer' }, - name: { type: 'string', maxLength: 255 }, - industry: { type: 'string', maxLength: 255 }, - location: { type: 'string', maxLength: 255 }, - baseCurrency: { type: 'string', maxLength: 3 }, - language: { type: 'string', maxLength: 255 }, - timezone: { type: 'string', maxLength: 255 }, - dateFormat: { type: 'string', maxLength: 255 }, - fiscalYear: { type: 'string', maxLength: 255 }, - primaryColor: { type: 'string', maxLength: 7 }, // Assuming hex color code - logoKey: { type: 'string', maxLength: 255 }, - address: { type: 'object' }, - }, - }; - } - - /** - * Table name. - */ - static get tableName() { - return 'tenants_metadata'; - } - - /** - * Virtual attributes. - */ - static get virtualAttributes() { - return ['logoUri']; - } - - /** - * Organization logo url. - * @returns {string | null} - */ - public get logoUri() { - return this.logoKey ? getUploadedObjectUri(this.logoKey) : null; - } - - /** - * Retrieves the organization address formatted text. - * @returns {string} - */ - public get addressTextFormatted() { - const addressCountry = findByIsoCountryCode(this.location); - - return organizationAddressTextFormat(defaultOrganizationAddressFormat, { - organizationName: this.name, - address1: this.address?.address1, - address2: this.address?.address2, - state: this.address?.stateProvince, - city: this.address?.city, - postalCode: this.address?.postalCode, - phone: this.address?.phone, - country: addressCountry?.name ?? '', - }); - } -} diff --git a/packages/server/src/system/models/index.ts b/packages/server/src/system/models/index.ts deleted file mode 100644 index 05dd23f87..000000000 --- a/packages/server/src/system/models/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import Plan from './Subscriptions/Plan'; -import PlanSubscription from './Subscriptions/PlanSubscription'; -import Tenant from './Tenant'; -import TenantMetadata from './TenantMetadata'; -import SystemUser from './SystemUser'; -import PasswordReset from './PasswordReset'; -import Invite from './Invite'; -import SystemPlaidItem from './SystemPlaidItem'; -import { Import } from './Import'; -import { StripeAccount } from './StripeAccount'; -import { PaymentLink } from './PaymentLink'; - -export { - Plan, - PlanSubscription, - Tenant, - TenantMetadata, - SystemUser, - PasswordReset, - Invite, - SystemPlaidItem, - Import, - StripeAccount, - PaymentLink, -}; diff --git a/packages/server/src/system/repositories/SubscriptionRepository.ts b/packages/server/src/system/repositories/SubscriptionRepository.ts deleted file mode 100644 index 004d501cb..000000000 --- a/packages/server/src/system/repositories/SubscriptionRepository.ts +++ /dev/null @@ -1,22 +0,0 @@ -import SystemRepository from '@/system/repositories/SystemRepository'; -import { PlanSubscription } from '@/system/models'; - -export default class SubscriptionRepository extends SystemRepository { - /** - * Gets the repository's model. - */ - get model() { - return PlanSubscription.bindKnex(this.knex); - } - - /** - * Retrieve subscription from a given slug in specific tenant. - * @param {string} slug - * @param {number} tenantId - */ - getBySlugInTenant(slug: string, tenantId: number) { - return PlanSubscription.query() - .findOne('slug', slug) - .where('tenant_id', tenantId); - } -} diff --git a/packages/server/src/system/repositories/SystemRepository.ts b/packages/server/src/system/repositories/SystemRepository.ts deleted file mode 100644 index e44377130..000000000 --- a/packages/server/src/system/repositories/SystemRepository.ts +++ /dev/null @@ -1,5 +0,0 @@ -import CachableRepository from "repositories/CachableRepository"; - -export default class SystemRepository extends CachableRepository { - -} \ No newline at end of file diff --git a/packages/server/src/system/repositories/SystemUserRepository.ts b/packages/server/src/system/repositories/SystemUserRepository.ts deleted file mode 100644 index 0e4b1ca75..000000000 --- a/packages/server/src/system/repositories/SystemUserRepository.ts +++ /dev/null @@ -1,101 +0,0 @@ -import moment from 'moment'; -import SystemRepository from '@/system/repositories/SystemRepository'; -import { SystemUser } from '@/system/models'; -import { ISystemUser } from '@/interfaces'; - -export default class SystemUserRepository extends SystemRepository { - /** - * Gets the repository's model. - */ - get model() { - return SystemUser.bindKnex(this.knex); - } - - /** - * Finds system user by crediential. - * @param {string} crediential - Phone number or email. - * @return {ISystemUser} - * @return {Promise} - */ - findByCrediential(crediential: string): Promise { - const cacheKey = this.getCacheKey('findByCrediential', crediential); - - return this.cache.get(cacheKey, () => { - return this.model.query() - .findOne('email', crediential) - .orWhere('phone_number', crediential); - }); - } - - /** - * Retrieve user by id and tenant id. - * @param {number} userId - User id. - * @param {number} tenantId - Tenant id. - * @return {Promise} - */ - findOneByIdAndTenant(userId: number, tenantId: number): Promise { - const cacheKey = this.getCacheKey('findOneByIdAndTenant', userId, tenantId); - - return this.cache.get(cacheKey, () => { - return this.model.query() - .findOne({ id: userId, tenant_id: tenantId }); - }); - } - - /** - * Retrieve system user details by the given email. - * @param {string} email - Email - * @return {Promise} - */ - findOneByEmail(email: string): Promise { - const cacheKey = this.getCacheKey('findOneByEmail', email); - - return this.cache.get(cacheKey, () => { - return this.model.query().findOne('email', email); - }); - } - - /** - * Retrieve user by phone number. - * @param {string} phoneNumber - Phone number - * @return {Promise} - */ - findOneByPhoneNumber(phoneNumber: string): Promise { - const cacheKey = this.getCacheKey('findOneByPhoneNumber', phoneNumber); - - return this.cache.get(cacheKey, () => { - return this.model.query() - .findOne('phoneNumber', phoneNumber); - }); - } - - /** - * Patches the last login date to the given system user. - * @param {number} userId - * @return {Promise} - */ - patchLastLoginAt(userId: number): Promise { - return super.update( - { last_login_at: moment().toMySqlDateTime() }, - { id: userId } - ); - } - - /** - * Activate user by the given id. - * @param {number} userId - User id. - * @return {Promise} - */ - activateById(userId: number): Promise { - return super.update({ active: 1 }, { id: userId }); - } - - /** - * Inactivate user by the given id. - * @param {number} userId - User id. - * @return {Promise} - */ - inactivateById(userId: number): Promise { - return super.update({ active: 0 }, { id: userId }); - } -} diff --git a/packages/server/src/system/repositories/TenantRepository.ts b/packages/server/src/system/repositories/TenantRepository.ts deleted file mode 100644 index b487a62ac..000000000 --- a/packages/server/src/system/repositories/TenantRepository.ts +++ /dev/null @@ -1,43 +0,0 @@ -import moment from "moment"; -import uniqid from 'uniqid'; -import SystemRepository from "./SystemRepository"; -import { Tenant } from "@/system/models"; -import { ITenant } from '@/interfaces'; - -export default class TenantRepository extends SystemRepository { - /** - * Gets the repository's model. - */ - get model() { - return Tenant.bindKnex(this.knex); - } - - /** - * Creates a new tenant with random organization id. - * @return {ITenant} - */ - createWithUniqueOrgId(uniqId?: string): Promise{ - const organizationId = uniqid() || uniqId; - return super.create({ organizationId }); - } - - /** - * Mark as seeded. - * @param {number} tenantId - */ - markAsSeeded(tenantId: number) { - return super.update({ - seededAt: moment().toMySqlDateTime(), - }, { id: tenantId }) - } - - /** - * Mark the the given organization as initialized. - * @param {string} organizationId - */ - markAsInitialized(tenantId: number) { - return super.update({ - initializedAt: moment().toMySqlDateTime(), - }, { id: tenantId }); - } -} \ No newline at end of file diff --git a/packages/server/src/system/repositories/index.ts b/packages/server/src/system/repositories/index.ts deleted file mode 100644 index 9fb001718..000000000 --- a/packages/server/src/system/repositories/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import SystemUserRepository from '@/system/repositories/SystemUserRepository'; -import SubscriptionRepository from '@/system/repositories/SubscriptionRepository'; -import TenantRepository from '@/system/repositories/TenantRepository'; - -export { - SystemUserRepository, - SubscriptionRepository, - TenantRepository, -}; \ No newline at end of file diff --git a/packages/server/src/system/seeds/seed_subscriptions_plans.js b/packages/server/src/system/seeds/seed_subscriptions_plans.js deleted file mode 100644 index b810510bc..000000000 --- a/packages/server/src/system/seeds/seed_subscriptions_plans.js +++ /dev/null @@ -1,26 +0,0 @@ -exports.seed = (knex) => { - // Deletes ALL existing entries - return knex('subscription_plans') - .del() - .then(() => { - // Inserts seed entries - return knex('subscription_plans').insert([ - { - name: 'Free', - slug: 'free', - price: 0, - active: true, - currency: 'USD', - }, - { - name: 'Early Adaptor', - slug: 'early-adaptor', - price: 29, - active: true, - currency: 'USD', - invoice_period: 12, - invoice_interval: 'month', - }, - ]); - }); -}; diff --git a/packages/server/src/system/seeds/seed_tenants_free_subscription.js b/packages/server/src/system/seeds/seed_tenants_free_subscription.js deleted file mode 100644 index 0c08a41b1..000000000 --- a/packages/server/src/system/seeds/seed_tenants_free_subscription.js +++ /dev/null @@ -1,26 +0,0 @@ -exports.seed = (knex) => { - // Deletes ALL existing entries - return knex('subscription_plan_subscriptions') - .then(async () => { - const tenants = await knex('tenants'); - - for (const tenant of tenants) { - const existingSubscription = await knex('subscription_plan_subscriptions') - .where('tenantId', tenant.id) - .first(); - - if (!existingSubscription) { - const freePlan = await knex('subscription_plans').where('slug', 'free').first(); - - await knex('subscription_plan_subscriptions').insert({ - tenantId: tenant.id, - planId: freePlan.id, - slug: 'main', - startsAt: knex.fn.now(), - endsAt: null, - createdAt: knex.fn.now(), - }); - } - } - }); -}; diff --git a/packages/server-nest/src/utils/accum-sum.ts b/packages/server/src/utils/accum-sum.ts similarity index 100% rename from packages/server-nest/src/utils/accum-sum.ts rename to packages/server/src/utils/accum-sum.ts diff --git a/packages/server/src/utils/address-text-format.ts b/packages/server/src/utils/address-text-format.ts index 30875ee9d..3813f7e04 100644 --- a/packages/server/src/utils/address-text-format.ts +++ b/packages/server/src/utils/address-text-format.ts @@ -1,4 +1,4 @@ -import { IContact } from '@/interfaces'; +import { Contact } from "@/modules/Contacts/models/Contact"; interface OrganizationAddressFormatArgs { organizationName?: string; @@ -83,7 +83,7 @@ export const defaultContactAddressFormat = `{CONTACT_NAME} `; export const contactAddressTextFormat = ( - contact: IContact, + contact: Contact, message: string = defaultContactAddressFormat ) => { const args = { diff --git a/packages/server-nest/src/utils/all-conditions-passed.ts b/packages/server/src/utils/all-conditions-passed.ts similarity index 100% rename from packages/server-nest/src/utils/all-conditions-passed.ts rename to packages/server/src/utils/all-conditions-passed.ts diff --git a/packages/server-nest/src/utils/assoc-depth-level-to-object-tree.ts b/packages/server/src/utils/assoc-depth-level-to-object-tree.ts similarity index 100% rename from packages/server-nest/src/utils/assoc-depth-level-to-object-tree.ts rename to packages/server/src/utils/assoc-depth-level-to-object-tree.ts diff --git a/packages/server-nest/src/utils/associate-item-entries-index.ts b/packages/server/src/utils/associate-item-entries-index.ts similarity index 100% rename from packages/server-nest/src/utils/associate-item-entries-index.ts rename to packages/server/src/utils/associate-item-entries-index.ts diff --git a/packages/server-nest/src/utils/cast-comma-list-envvar-Array.ts b/packages/server/src/utils/cast-comma-list-envvar-Array.ts similarity index 100% rename from packages/server-nest/src/utils/cast-comma-list-envvar-Array.ts rename to packages/server/src/utils/cast-comma-list-envvar-Array.ts diff --git a/packages/server-nest/src/utils/date-range-collection.ts b/packages/server/src/utils/date-range-collection.ts similarity index 100% rename from packages/server-nest/src/utils/date-range-collection.ts rename to packages/server/src/utils/date-range-collection.ts diff --git a/packages/server/src/utils/deepdash.ts b/packages/server/src/utils/deepdash.ts index c0535bc2b..7c44d298a 100644 --- a/packages/server/src/utils/deepdash.ts +++ b/packages/server/src/utils/deepdash.ts @@ -1,5 +1,6 @@ +// @ts-nocheck import * as _ from 'lodash'; -import * as deepdash from 'deepdash'; +import * as addDeepdash from 'deepdash'; const { condense, @@ -16,6 +17,7 @@ const { mapDeep, mapKeysDeep, mapValuesDeep, + mapValues, omitDeep, pathMatches, pathToString, @@ -24,7 +26,7 @@ const { reduceDeep, someDeep, iteratee, -} = deepdash.default(_); +} = addDeepdash(_); const mapValuesDeepReverse = (nodes, callback, config?) => { const clonedNodes = _.clone(nodes); @@ -115,6 +117,7 @@ export { mapDeep, mapKeysDeep, mapValuesDeep, + mapValues, omitDeep, pathMatches, pathToString, diff --git a/packages/server-nest/src/utils/entries-amount-diff.ts b/packages/server/src/utils/entries-amount-diff.ts similarity index 100% rename from packages/server-nest/src/utils/entries-amount-diff.ts rename to packages/server/src/utils/entries-amount-diff.ts diff --git a/packages/server-nest/src/utils/flat-to-nested-array.ts b/packages/server/src/utils/flat-to-nested-array.ts similarity index 100% rename from packages/server-nest/src/utils/flat-to-nested-array.ts rename to packages/server/src/utils/flat-to-nested-array.ts diff --git a/packages/server-nest/src/utils/format-date-fields.ts b/packages/server/src/utils/format-date-fields.ts similarity index 100% rename from packages/server-nest/src/utils/format-date-fields.ts rename to packages/server/src/utils/format-date-fields.ts diff --git a/packages/server-nest/src/utils/format-message.ts b/packages/server/src/utils/format-message.ts similarity index 100% rename from packages/server-nest/src/utils/format-message.ts rename to packages/server/src/utils/format-message.ts diff --git a/packages/server-nest/src/utils/format-number.ts b/packages/server/src/utils/format-number.ts similarity index 100% rename from packages/server-nest/src/utils/format-number.ts rename to packages/server/src/utils/format-number.ts diff --git a/packages/server/src/utils/formatMinutes.ts b/packages/server/src/utils/formatMinutes.ts deleted file mode 100644 index 9fecf3dbe..000000000 --- a/packages/server/src/utils/formatMinutes.ts +++ /dev/null @@ -1,11 +0,0 @@ - -export function formatMinutes(totalMinutes: number) { - const minutes = totalMinutes % 60; - const hours = Math.floor(totalMinutes / 60); - - return `${padTo2Digits(hours)}:${padTo2Digits(minutes)}`; -} - -export function padTo2Digits(num: number) { - return num.toString().padStart(2, '0'); -} diff --git a/packages/server-nest/src/utils/increment.ts b/packages/server/src/utils/increment.ts similarity index 100% rename from packages/server-nest/src/utils/increment.ts rename to packages/server/src/utils/increment.ts diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts deleted file mode 100644 index 1e9d48eac..000000000 --- a/packages/server/src/utils/index.ts +++ /dev/null @@ -1,522 +0,0 @@ -import bcrypt from 'bcryptjs'; -import moment from 'moment'; -import _, { isEmpty } from 'lodash'; -import path from 'path'; -import * as R from 'ramda'; - -import accounting from 'accounting'; -import pug from 'pug'; -import Currencies from 'js-money/lib/currency'; -import definedOptions from '@/data/options'; - -export * from './table'; - -const hashPassword = (password) => - new Promise((resolve) => { - bcrypt.genSalt(10, (error, salt) => { - bcrypt.hash(password, salt, (err, hash) => { - resolve(hash); - }); - }); - }); - -const origin = (request) => `${request.protocol}://${request.hostname}`; - -const dateRangeCollection = ( - fromDate, - toDate, - addType = 'day', - increment = 1 -) => { - const collection = []; - const momentFromDate = moment(fromDate); - let dateFormat = ''; - - switch (addType) { - case 'day': - default: - dateFormat = 'YYYY-MM-DD'; - break; - case 'month': - case 'quarter': - dateFormat = 'YYYY-MM'; - break; - case 'year': - dateFormat = 'YYYY'; - break; - } - for ( - let i = momentFromDate; - i.isBefore(toDate, addType) || i.isSame(toDate, addType); - i.add(increment, `${addType}s`) - ) { - collection.push(i.endOf(addType).format(dateFormat)); - } - return collection; -}; - -const dateRangeFromToCollection = ( - fromDate, - toDate, - addType = 'day', - increment = 1 -) => { - const collection = []; - const momentFromDate = moment(fromDate); - const dateFormat = 'YYYY-MM-DD'; - - for ( - let i = momentFromDate; - i.isBefore(toDate, addType) || i.isSame(toDate, addType); - i.add(increment, `${addType}s`) - ) { - collection.push({ - fromDate: i.startOf(addType).format(dateFormat), - toDate: i.endOf(addType).format(dateFormat), - }); - } - return collection; -}; - -const dateRangeFormat = (rangeType) => { - switch (rangeType) { - case 'year': - return 'YYYY'; - case 'month': - case 'quarter': - default: - return 'YYYY-MM'; - } -}; - -function mapKeysDeep(obj, cb, isRecursive) { - if (!obj && !isRecursive) { - return {}; - } - if (!isRecursive) { - if ( - typeof obj === 'string' || - typeof obj === 'number' || - typeof obj === 'boolean' - ) { - return {}; - } - } - if (Array.isArray(obj)) { - return obj.map((item) => mapKeysDeep(item, cb, true)); - } - if (!_.isPlainObject(obj)) { - return obj; - } - const result = _.mapKeys(obj, cb); - return _.mapValues(result, (value) => mapKeysDeep(value, cb, true)); -} - -const mapValuesDeep = (v, callback) => - _.isObject(v) - ? _.mapValues(v, (v) => mapValuesDeep(v, callback)) - : callback(v); - -const promiseSerial = (funcs) => { - return funcs.reduce( - (promise, func) => - promise.then((result) => - func().then(Array.prototype.concat.bind(result)) - ), - Promise.resolve([]) - ); -}; - -const flatToNestedArray = ( - data, - config = { id: 'id', parentId: 'parent_id' } -) => { - const map = {}; - const nestedArray = []; - - data.forEach((item) => { - map[item[config.id]] = item; - map[item[config.id]].children = []; - }); - - data.forEach((item) => { - const parentItemId = item[config.parentId]; - - if (!item[config.parentId]) { - nestedArray.push(item); - } - if (parentItemId) { - map[parentItemId].children.push(item); - } - }); - return nestedArray; -}; - -const itemsStartWith = (items, char) => { - return items.filter((item) => item.indexOf(char) === 0); -}; - -const getTotalDeep = (items, deepProp, totalProp) => - items.reduce((acc, item) => { - const total = Array.isArray(item[deepProp]) - ? getTotalDeep(item[deepProp], deepProp, totalProp) - : 0; - return _.sumBy(item, totalProp) + total + acc; - }, 0); - -function applyMixins(derivedCtor, baseCtors) { - baseCtors.forEach((baseCtor) => { - Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { - Object.defineProperty( - derivedCtor.prototype, - name, - Object.getOwnPropertyDescriptor(baseCtor.prototype, name) - ); - }); - }); -} - -const formatDateFields = (inputDTO, fields, format = 'YYYY-MM-DD') => { - const _inputDTO = { ...inputDTO }; - - fields.forEach((field) => { - if (_inputDTO[field]) { - _inputDTO[field] = moment(_inputDTO[field]).format(format); - } - }); - return _inputDTO; -}; - -const getDefinedOptions = () => { - const options = []; - - Object.keys(definedOptions).forEach((groupKey) => { - const groupOptions = definedOptions[groupKey]; - groupOptions.forEach((option) => { - options.push({ ...option, group: groupKey }); - }); - }); - return options; -}; - -const getDefinedOption = (key, group) => { - return definedOptions?.[group]?.find((option) => option.key == key); -}; - -const isDefinedOptionConfigurable = (key, group) => { - const definedOption = getDefinedOption(key, group); - return definedOption?.config || false; -}; - -const entriesAmountDiff = ( - newEntries, - oldEntries, - amountAttribute, - idAttribute -) => { - const oldEntriesTable = _.chain(oldEntries) - .groupBy(idAttribute) - .mapValues((group) => _.sumBy(group, amountAttribute) || 0) - .value(); - - const newEntriesTable = _.chain(newEntries) - .groupBy(idAttribute) - .mapValues((group) => _.sumBy(group, amountAttribute) || 0) - .mergeWith(oldEntriesTable, (objValue, srcValue) => { - return _.isNumber(objValue) ? objValue - srcValue : srcValue * -1; - }) - .value(); - - return _.chain(newEntriesTable) - .mapValues((value, key) => ({ - [idAttribute]: key, - [amountAttribute]: value, - })) - .filter((entry) => entry[amountAttribute] != 0) - .values() - .value(); -}; - -const convertEmptyStringToNull = (value) => { - return typeof value === 'string' - ? value.trim() === '' - ? null - : value - : value; -}; - -const getNegativeFormat = (formatName) => { - switch (formatName) { - case 'parentheses': - return '(%s%v)'; - case 'mines': - return '-%s%v'; - } -}; - -const getCurrencySign = (currencyCode) => { - return _.get(Currencies, `${currencyCode}.symbol`); -}; - -const formatNumber = ( - balance, - { - precision = 2, - divideOn1000 = false, - excerptZero = false, - negativeFormat = 'mines', - thousand = ',', - decimal = '.', - zeroSign = '', - money = true, - currencyCode, - symbol = '', - } -) => { - const formattedSymbol = getCurrencySign(currencyCode); - const negForamt = getNegativeFormat(negativeFormat); - const format = '%s%v'; - - let formattedBalance = parseFloat(balance); - - if (divideOn1000) { - formattedBalance /= 1000; - } - return accounting.formatMoney( - formattedBalance, - money ? formattedSymbol : symbol ? symbol : '', - precision, - thousand, - decimal, - { - pos: format, - neg: negForamt, - zero: excerptZero ? zeroSign : format, - } - ); -}; - -const isBlank = (value) => { - return (_.isEmpty(value) && !_.isNumber(value)) || _.isNaN(value); -}; - -function defaultToTransform(value, defaultOrTransformedValue, defaultValue) { - const _defaultValue = - typeof defaultValue === 'undefined' - ? defaultOrTransformedValue - : defaultValue; - - const _transfromedValue = - typeof defaultValue === 'undefined' ? value : defaultOrTransformedValue; - - return value == null || value !== value || value === '' - ? _defaultValue - : _transfromedValue; -} - -const transformToMap = (objects, key) => { - const map = new Map(); - - objects.forEach((object) => { - map.set(object[key], object); - }); - return map; -}; - -const transactionIncrement = (s) => s.replace(/([0-8]|\d?9+)?$/, (e) => ++e); - -const booleanValuesRepresentingTrue: string[] = ['true', '1']; -const booleanValuesRepresentingFalse: string[] = ['false', '0']; - -const normalizeValue = (value: any): string => - value?.toString().trim().toLowerCase(); - -const booleanValues: string[] = [ - ...booleanValuesRepresentingTrue, - ...booleanValuesRepresentingFalse, -].map((value) => normalizeValue(value)); - -export const parseBoolean = (value: any, defaultValue: T): T | boolean => { - if (typeof value === 'boolean') { - return value; // Retrun early we have nothing to parse. - } - const normalizedValue = normalizeValue(value); - if (isEmpty(value) || booleanValues.indexOf(normalizedValue) === -1) { - return defaultValue; - } - return booleanValuesRepresentingTrue.indexOf(normalizedValue) !== -1; -}; - -var increment = (n) => { - return () => { - n += 1; - return n; - }; -}; - -const transformToMapBy = (collection, key) => { - return new Map(Object.entries(_.groupBy(collection, key))); -}; - -const transformToMapKeyValue = (collection, key) => { - return new Map(collection.map((item) => [item[key], item])); -}; - -const accumSum = (data, callback) => { - return data.reduce((acc, _data) => { - const amount = callback(_data); - return acc + amount; - }, 0); -}; - -const mergeObjectsBykey = (object1, object2, key) => { - var merged = _.merge(_.keyBy(object1, key), _.keyBy(object2, key)); - return _.values(merged); -}; - -function templateRender(filePath, options) { - const basePath = path.join(global.__resources_dir, '/views'); - return pug.renderFile(`${basePath}/${filePath}.pug`, options); -} - -/** - * All passed conditions should pass. - * @param condsPairFilters - * @returns - */ -export const allPassedConditionsPass = (condsPairFilters): Function => { - const filterCallbacks = condsPairFilters - .filter((cond) => cond[0]) - .map((cond) => cond[1]); - - return R.allPass(filterCallbacks); -}; - -export const runningAmount = (amount: number) => { - let runningBalance = amount; - - return { - decrement: (decrement: number) => { - runningBalance -= decrement; - }, - increment: (increment: number) => { - runningBalance += increment; - }, - amount: () => runningBalance, - }; -}; - -export const formatSmsMessage = (message: string, args) => { - let formattedMessage = message; - - Object.keys(args).forEach((key) => { - const variable = `{${key}}`; - const value = _.defaultTo(args[key], ''); - - formattedMessage = formattedMessage.replace( - new RegExp(variable, 'g'), - value - ); - }); - return formattedMessage; -}; - -export const parseDate = (date: string) => { - return date ? moment(date).utcOffset(0).format('YYYY-MM-DD') : ''; -}; - -const nestedArrayToFlatten = ( - collection, - property = 'children', - parseItem = (a, level) => a, - level = 1 -) => { - const parseObject = (obj) => - parseItem( - { - ..._.omit(obj, [property]), - }, - level - ); - - return collection.reduce((items, currentValue, index) => { - let localItems = [...items]; - const parsedItem = parseObject(currentValue, level); - localItems.push(parsedItem); - - if (Array.isArray(currentValue[property])) { - const flattenArray = nestedArrayToFlatten( - currentValue[property], - property, - parseItem, - level + 1 - ); - localItems = _.concat(localItems, flattenArray); - } - return localItems; - }, []); -}; - -const assocDepthLevelToObjectTree = ( - objects, - level = 1, - propertyName = 'level' -) => { - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; - object[propertyName] = level; - - if (object.children) { - assocDepthLevelToObjectTree(object.children, level + 1, propertyName); - } - } - return objects; -}; - -const castCommaListEnvVarToArray = (envVar: string): Array => { - return envVar ? envVar?.split(',')?.map(_.trim) : []; -}; - -export const sortObjectKeysAlphabetically = (object) => { - return Object.keys(object) - .sort() - .reduce((objEntries, key) => { - objEntries[key] = object[key]; - return objEntries; - }, {}); -}; - -export { - templateRender, - accumSum, - increment, - hashPassword, - origin, - dateRangeCollection, - dateRangeFormat, - mapValuesDeep, - mapKeysDeep, - promiseSerial, - flatToNestedArray, - itemsStartWith, - getTotalDeep, - applyMixins, - formatDateFields, - isDefinedOptionConfigurable, - getDefinedOption, - getDefinedOptions, - entriesAmountDiff, - convertEmptyStringToNull, - formatNumber, - isBlank, - defaultToTransform, - transformToMap, - transactionIncrement, - transformToMapBy, - dateRangeFromToCollection, - transformToMapKeyValue, - mergeObjectsBykey, - nestedArrayToFlatten, - assocDepthLevelToObjectTree, - castCommaListEnvVarToArray, -}; diff --git a/packages/server-nest/src/utils/is-blank.ts b/packages/server/src/utils/is-blank.ts similarity index 100% rename from packages/server-nest/src/utils/is-blank.ts rename to packages/server/src/utils/is-blank.ts diff --git a/packages/server-nest/src/utils/items-start-with.ts b/packages/server/src/utils/items-start-with.ts similarity index 100% rename from packages/server-nest/src/utils/items-start-with.ts rename to packages/server/src/utils/items-start-with.ts diff --git a/packages/server-nest/src/utils/moment-mysql.ts b/packages/server/src/utils/moment-mysql.ts similarity index 100% rename from packages/server-nest/src/utils/moment-mysql.ts rename to packages/server/src/utils/moment-mysql.ts diff --git a/packages/server/src/utils/multi-number-parse.test.ts b/packages/server/src/utils/multi-number-parse.test.ts deleted file mode 100644 index a45ef384c..000000000 --- a/packages/server/src/utils/multi-number-parse.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { assert } from 'chai'; -import { multiNumberParse } from './multi-number-parse'; - -const correctNumbers = [ - { actual: '10.5', expected: 10.5 }, - { actual: '10,5', expected: 10.5 }, - { actual: '1.235,76', expected: 1235.76 }, - { actual: '2,543.56', expected: 2543.56 }, - { actual: '10 654.1234', expected: 10654.1234 }, - { actual: '2.654$10', expected: 2654.1 }, - { actual: '5.435.123,645', expected: 5435123.645 }, - { actual: '2,566,765.234', expected: 2566765.234 }, - { actual: '2,432,123$23', expected: 2432123.23 }, - { actual: '2,45EUR', expected: 2.45 }, - { actual: '4.78€', expected: 4.78 }, - { actual: '28', expected: 28 }, - { actual: '-48', expected: -48 }, - { actual: '39USD', expected: 39 }, - - // Some negative numbers - { actual: '-2,543.56', expected: -2543.56 }, - { actual: '-10 654.1234', expected: -10654.1234 }, - { actual: '-2.654$10', expected: -2654.1 }, -]; - -const incorrectNumbers = [ - '10 345,234.21', // too many different separators - '1.123.234,534,234', // impossible to detect where's the decimal separator - '10.4,2', // malformed digit groups - '1.123.2', // also malformed digit groups -]; - -describe('Test numbers', () => { - correctNumbers.forEach((item) => { - it(`"${item.actual}" should return ${item.expected}`, (done) => { - const parsed = multiNumberParse(item.actual); - assert.isNotNaN(parsed); - assert.equal(parsed, item.expected); - - done(); - }); - }); - - incorrectNumbers.forEach((item) => { - it(`"${item}" should return NaN`, (done) => { - assert.isNaN(numberParse(item)); - - done(); - }); - }); -}); diff --git a/packages/server/src/utils/multi-number-parse.ts b/packages/server/src/utils/multi-number-parse.ts deleted file mode 100644 index 261e66335..000000000 --- a/packages/server/src/utils/multi-number-parse.ts +++ /dev/null @@ -1,130 +0,0 @@ -const validGrouping = (integerPart, sep) => - integerPart.split(sep).reduce((acc, group, idx) => { - if (idx > 0) { - return acc && group.length === 3; - } - - return acc && group.length; - }, true); - -export const multiNumberParse = (number: number | string, standardDecSep = '.') => { - // if it's a number already, this is going to be easy... - if (typeof number === 'number') { - return number; - } - - // check validity of parameters - if (!number || typeof number !== 'string') { - throw new TypeError('number must be a string'); - } - - if (typeof standardDecSep !== 'string' || standardDecSep.length !== 1) { - throw new TypeError('standardDecSep must be a single character string'); - } - - // check if negative - const negative = number[0] === '-'; - - // strip unnecessary chars - const stripped = number - // get rid of trailing non-numbers - .replace(/[^\d]+$/, '') - // get rid of the signal - .slice(negative ? 1 : 0); - - // analyze separators - const separators = (stripped.match(/[^\d]/g) || []).reduce( - (acc, sep, idx) => { - const sepChr = `str_${sep.codePointAt(0)}`; - const cnt = ((acc[sepChr] || {}).cnt || 0) + 1; - - return { - ...acc, - [sepChr]: { - sep, - cnt, - lastIdx: idx, - }, - }; - }, - {} - ); - - // check correctness of separators - const sepKeys = Object.keys(separators); - - if (!sepKeys.length) { - // no separator, that's easy-peasy - return parseInt(stripped, 10) * (negative ? -1 : 1); - } - - if (sepKeys.length > 2) { - // there's more than 2 separators, that's wrong - return Number.NaN; - } - - if (sepKeys.length > 1) { - // there's two separators, that's ok by now - let sep1 = separators[sepKeys[0]]; - let sep2 = separators[sepKeys[1]]; - - if (sep1.lastIdx > sep2.lastIdx) { - // swap - [sep1, sep2] = [sep2, sep1]; - } - - // if more than one separator appears more than once, that's wrong - if (sep1.cnt > 1 && sep2.cnt > 1) { - return Number.NaN; - } - - // check if the last separator is the single one - if (sep2.cnt > 1) { - return Number.NaN; - } - - // check the groupings - const [integerPart] = stripped.split(sep2.sep); - - if (!validGrouping(integerPart, sep1.sep)) { - return Number.NaN; - } - - // ok, we got here! let's handle it - return ( - parseFloat(stripped.split(sep1.sep).join('').replace(sep2.sep, '.')) * - (negative ? -1 : 1) - ); - } - - // ok, only one separator, which is nice - const sep = separators[sepKeys[0]]; - - if (sep.cnt > 1) { - // there's more than one separator, which means it's integer - // let's check the groupings - if (!validGrouping(stripped, sep.sep)) { - return Number.NaN; - } - - // it's valid, let's return an integer - return parseInt(stripped.split(sep.sep).join(''), 10) * (negative ? -1 : 1); - } - - // just one separator, let's check last group - const groups = stripped.split(sep.sep); - - if (groups[groups.length - 1].length === 3) { - // ok, we're in ambiguous territory here - - if (sep.sep !== standardDecSep) { - // it's an integer - return ( - parseInt(stripped.split(sep.sep).join(''), 10) * (negative ? -1 : 1) - ); - } - } - - // well, it looks like it's a simple float - return parseFloat(stripped.replace(sep.sep, '.')) * (negative ? -1 : 1); -}; diff --git a/packages/server-nest/src/utils/nested-array-to-flatten.ts b/packages/server/src/utils/nested-array-to-flatten.ts similarity index 100% rename from packages/server-nest/src/utils/nested-array-to-flatten.ts rename to packages/server/src/utils/nested-array-to-flatten.ts diff --git a/packages/server-nest/src/utils/parse-boolean.ts b/packages/server/src/utils/parse-boolean.ts similarity index 100% rename from packages/server-nest/src/utils/parse-boolean.ts rename to packages/server/src/utils/parse-boolean.ts diff --git a/packages/server/src/utils/parse-json-safe.ts b/packages/server/src/utils/parse-json-safe.ts deleted file mode 100644 index f8a12e2e7..000000000 --- a/packages/server/src/utils/parse-json-safe.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const parseJsonSafe = (value: string) => { - try { - return JSON.parse(value); - } catch { - return null; - } -}; diff --git a/packages/server-nest/src/utils/sanitize-database-name.ts b/packages/server/src/utils/sanitize-database-name.ts similarity index 100% rename from packages/server-nest/src/utils/sanitize-database-name.ts rename to packages/server/src/utils/sanitize-database-name.ts diff --git a/packages/server/src/utils/sanitizers.ts b/packages/server/src/utils/sanitizers.ts deleted file mode 100644 index 4ca07a5d8..000000000 --- a/packages/server/src/utils/sanitizers.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function sanitizeDatabaseName(dbName: string) { - // Replace any character that is not alphanumeric or an underscore with an underscore - return dbName.replace(/[^a-zA-Z0-9_]/g, ''); -} diff --git a/packages/server/src/utils/table.ts b/packages/server/src/utils/table.ts deleted file mode 100644 index 74f5c3170..000000000 --- a/packages/server/src/utils/table.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { get } from 'lodash'; -import { IColumnMapperMeta, ITableRow } from '@/interfaces'; - -export function tableMapper( - data: Object[], - columns: IColumnMapperMeta[], - rowsMeta -): ITableRow[] { - return data.map((object) => tableRowMapper(object, columns, rowsMeta)); -} - -function getAccessor(object, accessor) { - return typeof accessor === 'function' - ? accessor(object) - : get(object, accessor); -} - -export function tableRowMapper( - object: Object, - columns: IColumnMapperMeta[], - rowMeta -): ITableRow { - const cells = columns.map((column) => ({ - key: column.key, - value: column.value - ? column.value - : getAccessor(object, column.accessor) || '', - })); - - return { - cells, - ...rowMeta, - }; -} diff --git a/packages/server/src/utils/taxRate.ts b/packages/server/src/utils/taxRate.ts deleted file mode 100644 index 15d9e9d36..000000000 --- a/packages/server/src/utils/taxRate.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Get inclusive tax amount. - * @param {number} amount - * @param {number} taxRate - * @returns {number} - */ -export const getInclusiveTaxAmount = (amount: number, taxRate: number) => { - return (amount * taxRate) / (100 + taxRate); -}; - -/** - * Get exclusive tax amount. - * @param {number} amount - * @param {number} taxRate - * @returns {number} - */ -export const getExlusiveTaxAmount = (amount: number, taxRate: number) => { - return (amount * taxRate) / 100; -}; diff --git a/packages/server-nest/src/utils/template-render.ts b/packages/server/src/utils/template-render.ts similarity index 100% rename from packages/server-nest/src/utils/template-render.ts rename to packages/server/src/utils/template-render.ts diff --git a/packages/server-nest/src/utils/transaction-increment.ts b/packages/server/src/utils/transaction-increment.ts similarity index 100% rename from packages/server-nest/src/utils/transaction-increment.ts rename to packages/server/src/utils/transaction-increment.ts diff --git a/packages/server/src/utils/transactions-types.ts b/packages/server/src/utils/transactions-types.ts deleted file mode 100644 index bda6a2159..000000000 --- a/packages/server/src/utils/transactions-types.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { isObject, upperFirst, camelCase } from 'lodash'; -import { - TransactionTypes, - CashflowTransactionTypes, -} from '@/data/TransactionTypes'; - -/** - * Retrieves the formatted type of account transaction. - * @param {string} referenceType - * @param {string} transactionType - * @returns {string} - */ -export const getTransactionTypeLabel = ( - referenceType: string, - transactionType?: string -) => { - const _referenceType = upperFirst(camelCase(referenceType)); - const _transactionType = upperFirst(camelCase(transactionType)); - - return isObject(TransactionTypes[_referenceType]) - ? TransactionTypes[_referenceType][_transactionType] - : TransactionTypes[_referenceType] || null; -}; - -/** - * Retrieves the formatted type of cashflow transaction. - * @param {string} transactionType - * @returns {string¿} - */ -export const getCashflowTransactionFormattedType = ( - transactionType: string -) => { - const _transactionType = upperFirst(camelCase(transactionType)); - - return CashflowTransactionTypes[_transactionType] || null; -}; diff --git a/packages/server-nest/src/utils/transform-to-key.ts b/packages/server/src/utils/transform-to-key.ts similarity index 100% rename from packages/server-nest/src/utils/transform-to-key.ts rename to packages/server/src/utils/transform-to-key.ts diff --git a/packages/server-nest/src/utils/transform-to-map-by.ts b/packages/server/src/utils/transform-to-map-by.ts similarity index 100% rename from packages/server-nest/src/utils/transform-to-map-by.ts rename to packages/server/src/utils/transform-to-map-by.ts diff --git a/packages/server-nest/src/utils/transform-to-map-key-value.ts b/packages/server/src/utils/transform-to-map-key-value.ts similarity index 100% rename from packages/server-nest/src/utils/transform-to-map-key-value.ts rename to packages/server/src/utils/transform-to-map-key-value.ts diff --git a/packages/server-nest/static/demo-sheets/Expenses.csv b/packages/server/static/demo-sheets/Expenses.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/Expenses.csv rename to packages/server/static/demo-sheets/Expenses.csv diff --git a/packages/server-nest/static/demo-sheets/bank-transactions.csv b/packages/server/static/demo-sheets/bank-transactions.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/bank-transactions.csv rename to packages/server/static/demo-sheets/bank-transactions.csv diff --git a/packages/server-nest/static/demo-sheets/customers.csv b/packages/server/static/demo-sheets/customers.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/customers.csv rename to packages/server/static/demo-sheets/customers.csv diff --git a/packages/server-nest/static/demo-sheets/items.csv b/packages/server/static/demo-sheets/items.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/items.csv rename to packages/server/static/demo-sheets/items.csv diff --git a/packages/server-nest/static/demo-sheets/manual-journals.csv b/packages/server/static/demo-sheets/manual-journals.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/manual-journals.csv rename to packages/server/static/demo-sheets/manual-journals.csv diff --git a/packages/server-nest/static/demo-sheets/sale-invoices.csv b/packages/server/static/demo-sheets/sale-invoices.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/sale-invoices.csv rename to packages/server/static/demo-sheets/sale-invoices.csv diff --git a/packages/server-nest/static/demo-sheets/vendors.csv b/packages/server/static/demo-sheets/vendors.csv similarity index 100% rename from packages/server-nest/static/demo-sheets/vendors.csv rename to packages/server/static/demo-sheets/vendors.csv diff --git a/packages/server-nest/static/images/bigcapital.png b/packages/server/static/images/bigcapital.png similarity index 100% rename from packages/server-nest/static/images/bigcapital.png rename to packages/server/static/images/bigcapital.png diff --git a/packages/server-nest/static/mail/ResetPassword.html b/packages/server/static/mail/ResetPassword.html similarity index 100% rename from packages/server-nest/static/mail/ResetPassword.html rename to packages/server/static/mail/ResetPassword.html diff --git a/packages/server-nest/static/mail/SignupVerifyEmail.html b/packages/server/static/mail/SignupVerifyEmail.html similarity index 100% rename from packages/server-nest/static/mail/SignupVerifyEmail.html rename to packages/server/static/mail/SignupVerifyEmail.html diff --git a/packages/server-nest/static/mail/UserInvite.html b/packages/server/static/mail/UserInvite.html similarity index 100% rename from packages/server-nest/static/mail/UserInvite.html rename to packages/server/static/mail/UserInvite.html diff --git a/packages/server/storage/.gitignore b/packages/server/storage/.gitignore deleted file mode 100644 index 09c3737b9..000000000 --- a/packages/server/storage/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!pdf/ -!imports/ -!.gitignore \ No newline at end of file diff --git a/packages/server/storage/imports/.gitignore b/packages/server/storage/imports/.gitignore deleted file mode 100644 index c96a04f00..000000000 --- a/packages/server/storage/imports/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/packages/server/storage/pdf/.gitignore b/packages/server/storage/pdf/.gitignore deleted file mode 100644 index c96a04f00..000000000 --- a/packages/server/storage/pdf/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/packages/server-nest/test/auth.e2e-spec.ts b/packages/server/test/auth.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/auth.e2e-spec.ts rename to packages/server/test/auth.e2e-spec.ts diff --git a/packages/server-nest/test/bank-rules.e2e-spec.ts b/packages/server/test/bank-rules.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/bank-rules.e2e-spec.ts rename to packages/server/test/bank-rules.e2e-spec.ts diff --git a/packages/server-nest/test/banking-transactions.e2e-spec.ts b/packages/server/test/banking-transactions.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/banking-transactions.e2e-spec.ts rename to packages/server/test/banking-transactions.e2e-spec.ts diff --git a/packages/server-nest/test/branches.e2e-spec.ts b/packages/server/test/branches.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/branches.e2e-spec.ts rename to packages/server/test/branches.e2e-spec.ts diff --git a/packages/server-nest/test/credit-notes.e2e-spec.ts b/packages/server/test/credit-notes.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/credit-notes.e2e-spec.ts rename to packages/server/test/credit-notes.e2e-spec.ts diff --git a/packages/server-nest/test/customers.e2e-spec.ts b/packages/server/test/customers.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/customers.e2e-spec.ts rename to packages/server/test/customers.e2e-spec.ts diff --git a/packages/server-nest/test/expenses.e2e-spec.ts b/packages/server/test/expenses.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/expenses.e2e-spec.ts rename to packages/server/test/expenses.e2e-spec.ts diff --git a/packages/server-nest/test/init-app-test.ts b/packages/server/test/init-app-test.ts similarity index 100% rename from packages/server-nest/test/init-app-test.ts rename to packages/server/test/init-app-test.ts diff --git a/packages/server-nest/test/inventory-adjustment.e2e-spec.ts b/packages/server/test/inventory-adjustment.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/inventory-adjustment.e2e-spec.ts rename to packages/server/test/inventory-adjustment.e2e-spec.ts diff --git a/packages/server-nest/test/item-categories.e2e-spec.ts b/packages/server/test/item-categories.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/item-categories.e2e-spec.ts rename to packages/server/test/item-categories.e2e-spec.ts diff --git a/packages/server-nest/test/items.e2e-spec.ts b/packages/server/test/items.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/items.e2e-spec.ts rename to packages/server/test/items.e2e-spec.ts diff --git a/packages/server-nest/test/jest-e2e.json b/packages/server/test/jest-e2e.json similarity index 100% rename from packages/server-nest/test/jest-e2e.json rename to packages/server/test/jest-e2e.json diff --git a/packages/server-nest/test/manual-journal.e2e-spec.ts b/packages/server/test/manual-journal.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/manual-journal.e2e-spec.ts rename to packages/server/test/manual-journal.e2e-spec.ts diff --git a/packages/server-nest/test/organization.e2e-spec.ts b/packages/server/test/organization.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/organization.e2e-spec.ts rename to packages/server/test/organization.e2e-spec.ts diff --git a/packages/server-nest/test/payment-received.e2e-spec.ts b/packages/server/test/payment-received.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/payment-received.e2e-spec.ts rename to packages/server/test/payment-received.e2e-spec.ts diff --git a/packages/server-nest/test/pdf-templates.e2e-spec.ts b/packages/server/test/pdf-templates.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/pdf-templates.e2e-spec.ts rename to packages/server/test/pdf-templates.e2e-spec.ts diff --git a/packages/server-nest/test/sale-estimates.e2e-spec.ts b/packages/server/test/sale-estimates.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/sale-estimates.e2e-spec.ts rename to packages/server/test/sale-estimates.e2e-spec.ts diff --git a/packages/server-nest/test/sale-invoices.e2e-spec.ts b/packages/server/test/sale-invoices.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/sale-invoices.e2e-spec.ts rename to packages/server/test/sale-invoices.e2e-spec.ts diff --git a/packages/server-nest/test/sale-receipts.e2e-spec.ts b/packages/server/test/sale-receipts.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/sale-receipts.e2e-spec.ts rename to packages/server/test/sale-receipts.e2e-spec.ts diff --git a/packages/server-nest/test/settings.e2e-spec.ts b/packages/server/test/settings.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/settings.e2e-spec.ts rename to packages/server/test/settings.e2e-spec.ts diff --git a/packages/server-nest/test/tax-rates.e2e-spec.ts b/packages/server/test/tax-rates.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/tax-rates.e2e-spec.ts rename to packages/server/test/tax-rates.e2e-spec.ts diff --git a/packages/server-nest/test/transactions-locking.e2e-spec.ts b/packages/server/test/transactions-locking.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/transactions-locking.e2e-spec.ts rename to packages/server/test/transactions-locking.e2e-spec.ts diff --git a/packages/server-nest/test/vendor-credits.e2e-spec.ts b/packages/server/test/vendor-credits.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/vendor-credits.e2e-spec.ts rename to packages/server/test/vendor-credits.e2e-spec.ts diff --git a/packages/server-nest/test/vendors.e2e-spec.ts b/packages/server/test/vendors.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/vendors.e2e-spec.ts rename to packages/server/test/vendors.e2e-spec.ts diff --git a/packages/server-nest/test/warehouses.e2e-spec.ts b/packages/server/test/warehouses.e2e-spec.ts similarity index 100% rename from packages/server-nest/test/warehouses.e2e-spec.ts rename to packages/server/test/warehouses.e2e-spec.ts diff --git a/packages/server/tests/collection/NestedSet.test.js b/packages/server/tests/collection/NestedSet.test.js deleted file mode 100644 index 7246259f8..000000000 --- a/packages/server/tests/collection/NestedSet.test.js +++ /dev/null @@ -1,130 +0,0 @@ -import { expect } from '~/testInit'; -import NestedSet from '@/collection/NestedSet'; - -describe('NestedSet', () => { - describe('linkChildren()', () => { - it('Should link parent and children nodes.', () => { - const flattenArray = [ - { id: 10 }, - { id: 1 }, - { - id: 3, - parent_id: 1, - }, - { - id: 2, - parent_id: 1, - }, - { - id: 4, - parent_id: 3, - }, - ]; - const nestSet = new NestedSet(flattenArray); - const treeGroups = nestSet.linkChildren(); - - expect(treeGroups['1']).deep.equals({ - id: 1, - children: { - '2': { id: 2, parent_id: 1, children: {} }, - '3': { - id: 3, parent_id: 1, children: { - '4': { id: 4, parent_id: 3, children: {} } - } - } - } - }); - expect(treeGroups['2']).deep.equals({ - id: 2, parent_id: 1, children: {}, - }); - expect(treeGroups['3']).deep.equals({ - id: 3, - parent_id: 1, - children: { '4': { id: 4, parent_id: 3, children: {} } } - }); - expect(treeGroups['4']).deep.equals({ - id: 4, parent_id: 3, children: {}, - }); - }); - }); - - describe('toArray()', () => { - it('Should retrieve nested sets as array.', () => { - const flattenArray = [ - { id: 10 }, - { id: 1 }, - { - id: 3, - parent_id: 1, - }, - { - id: 2, - parent_id: 1, - }, - { - id: 4, - parent_id: 3, - }, - ]; - const nestSet = new NestedSet(flattenArray); - const treeArray = nestSet.toArray(); - - expect(treeArray[0]).deep.equals({ - id: 10, children: [], - }); - expect(treeArray[1]).deep.equals({ - id: 1, - children: [ - { id: 2, parent_id: 1, children: [] }, - { id: 3, parent_id: 1, children: [{ - id: 4, parent_id: 3, children: [] - }] } - ] - }); - }); - }); - - describe('getParents(id)', () => { - it('Should retrieve parent nodes of the given node id.', () => { - const flattenArray = [ - { id: 10 }, - { id: 1 }, - { - id: 3, - parent_id: 1, - }, - { - id: 2, - parent_id: 1, - }, - { - id: 4, - parent_id: 3, - }, - ]; - const nestSet = new NestedSet(flattenArray); - const parentNodes = nestSet.getParents(4); - - expect(parentNodes).deep.equals([ - { id: 4, parent_id: 3, children: {} }, - { - id: 3, - parent_id: 1, - children: { '4': { id: 4, parent_id: 3, children: {} } } - }, - { - id: 1, - children: { - '2': { id: 2, parent_id: 1, children: {} }, - '3': { - id: 3, parent_id: 1, children: { - '4': { id: 4, parent_id: 3, children: {} } - } - } - } - } - ]); - }); - }) - -}); diff --git a/packages/server/tests/dbInit.js b/packages/server/tests/dbInit.js deleted file mode 100644 index 8da9bb9c9..000000000 --- a/packages/server/tests/dbInit.js +++ /dev/null @@ -1,40 +0,0 @@ -import { - request, - expect, - createTenantFactory, - createTenant, - bindTenantModel, - login, - systemFactory, - dropTenant, -} from '~/testInit'; -import CacheService from '@/services/Cache'; - -let tenantWebsite; -let tenantFactory; -let loginRes; - -beforeEach(async () => { - tenantWebsite = await createTenant(); - tenantFactory = createTenantFactory(tenantWebsite.tenantDb); - - bindTenantModel(tenantWebsite.tenantDb); - loginRes = await login(tenantWebsite); - - CacheService.flush(); -}); - -afterEach(async () => { - await dropTenant(tenantWebsite); - - loginRes = null; - tenantFactory = null; - tenantWebsite = null; -}); - -export { - tenantWebsite, - tenantFactory, - systemFactory, - loginRes, -}; \ No newline at end of file diff --git a/packages/server/tests/docker-compose.yml b/packages/server/tests/docker-compose.yml deleted file mode 100644 index 52c7a1c24..000000000 --- a/packages/server/tests/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ - -services: - mysql: - image: mysql/mysql-server:5.7 - ports: - - "3306:3306" - environment: - - MYSQL_ROOT_PASSWORD=root - - MYSQL_DATABASE=moosher_test - - MYSQL_USER=moosher - - MYSQL_PASSWORD=moosher - tmpfs: - - /var/lib/mysql/:rw,noexec,nosuid,size=600m - - /tmp/:rw,noexec,nosuid,size=50m diff --git a/packages/server/tests/lib/CachableModel.test.js b/packages/server/tests/lib/CachableModel.test.js deleted file mode 100644 index d81541cf1..000000000 --- a/packages/server/tests/lib/CachableModel.test.js +++ /dev/null @@ -1,32 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Account from 'models/Account'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import { times } from 'lodash'; - -describe('CachableModel', () => { - describe('remember()', () => { - it('Should retrieve the data from the storage.', async () => { - - for (let i = 0; i < 1; i++) { - const account = await Account.tenant().query() - .remember() - .where('id', 1); - - const account2 = await Account.tenant().query() - .remember() - .withGraphFetched('balance'); - - console.log(account2); - // \\\ - } - // Account.flushCache(); - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/lib/MetableStore.test.ts b/packages/server/tests/lib/MetableStore.test.ts deleted file mode 100644 index a2be0bdca..000000000 --- a/packages/server/tests/lib/MetableStore.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { expect } from '~/testInit'; -import MetableStore from '@/lib/MetableStore'; - -describe('MetableStore()', () => { - - describe('find', () => { - it('Find metadata by the given key.', () => { - const store = new MetableStore(); - store.metadata = [{ key: 'first-key', value: 'first-value' }]; - - const meta = store.find('first-key'); - - expect(meta.value).equals('first-value'); - expect(meta.key).equals('first-key'); - }); - - it('Find metadata by the key as payload.', () => { - - }); - - it('Find metadata by the given key and extra columns.', () => { - - }); - }); - - describe('all()', () => { - it('Should retrieve all metadata in the store.', () => { - - }); - }); - - describe('get()', () => { - it('Should retrieve data of the given metadata query.', () => { - - }); - }); - - describe('removeMeta') -}); \ No newline at end of file diff --git a/packages/server/tests/models/Account.test.js b/packages/server/tests/models/Account.test.js deleted file mode 100644 index c933ffcf3..000000000 --- a/packages/server/tests/models/Account.test.js +++ /dev/null @@ -1,50 +0,0 @@ -import { - expect, -} from '~/testInit'; -import Account from 'models/Account'; -import AccountType from 'models/AccountType'; -import { - tenantFactory, - tenantWebsite -} from '~/dbInit'; -import DependencyGraph from '@/lib/DependencyGraph'; - -describe('Model: Account', () => { - it('Should account model belongs to the associated account type model.', async () => { - const accountType = await tenantFactory.create('account_type'); - const account = await tenantFactory.create('account', { account_type_id: accountType.id }); - - const accountModel = await Account.tenant().query() - .where('id', account.id) - .withGraphFetched('type') - .first(); - - expect(accountModel.type.id).equals(accountType.id); - }); - - it('Should account model has one balance model that associated to the account model.', async () => { - const accountBalance = await tenantFactory.create('account_balance'); - - const accountModel = await Account.tenant().query() - .where('id', accountBalance.accountId) - .withGraphFetched('balance') - .first(); - - expect(accountModel.balance.amount).equals(accountBalance.amount); - }); - - it('Should account model has many transactions models that associated to the account model.', async () => { - const account = await tenantFactory.create('account'); - const accountTransaction = await tenantFactory.create('account_transaction', { account_id: account.id }); - - const accountModel = await Account.tenant().query().where('id', account.id).first(); - const transactionsModels = await accountModel.$relatedQuery('transactions'); - - expect(transactionsModels.length).equals(1); - }); - - it('Should retrieve dependency graph.', async () => { - const accountsDepGraph = await Account.tenant().depGraph().query(); - expect(accountsDepGraph).to.be.an.instanceOf(DependencyGraph); - }); -}); diff --git a/packages/server/tests/models/AccountType.test.js b/packages/server/tests/models/AccountType.test.js deleted file mode 100644 index 51bd5f5d7..000000000 --- a/packages/server/tests/models/AccountType.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import { create, expect } from '~/testInit'; -import 'models/Account'; -import AccountType from 'models/AccountType'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('Model: AccountType', () => { - it('Shoud account type model has many associated accounts.', async () => { - const accountType = await tenantFactory.create('account_type'); - await tenantFactory.create('account', { account_type_id: accountType.id }); - await tenantFactory.create('account', { account_type_id: accountType.id }); - - const accountTypeModel = await AccountType.tenant().query().where('id', accountType.id).first(); - const typeAccounts = await accountTypeModel.$relatedQuery('accounts'); - - expect(typeAccounts.length).equals(2); - }); -}); diff --git a/packages/server/tests/models/Expense.test.js b/packages/server/tests/models/Expense.test.js deleted file mode 100644 index ed5348a46..000000000 --- a/packages/server/tests/models/Expense.test.js +++ /dev/null @@ -1,39 +0,0 @@ -import { create, expect } from '~/testInit'; -import Expense from 'models/Expense'; -import ExpenseCategory from 'models/ExpenseCategory'; -import { - tenantFactory, - tenantWebsite -} from '~/dbInit'; - -describe('Model: Expense', () => { - describe('relations', () => { - it('Expense model may belongs to associated payment account.', async () => { - const expense = await tenantFactory.create('expense'); - - const expenseModel = await Expense.tenant().query().findById(expense.id); - const paymentAccountModel = await expenseModel.$relatedQuery('paymentAccount'); - - expect(paymentAccountModel.id).equals(expense.paymentAccountId); - }); - - it('Expense model may has many associated expense categories.', async () => { - const expenseCategory = await tenantFactory.create('expense_category'); - - const expenseModel = await Expense.tenant().query().findById(expenseCategory.expenseId); - const expenseCategories = await expenseModel.$relatedQuery('categories'); - - expect(expenseCategories.length).equals(1); - expect(expenseCategories[0].expenseId).equals(expenseModel.id); - }); - - it('Expense model may belongs to associated user model.', async () => { - const expense = await tenantFactory.create('expense'); - - const expenseModel = await Expense.tenant().query().findById(expense.id); - const expenseUserModel = await expenseModel.$relatedQuery('user'); - - expect(expenseUserModel.id).equals(expense.userId); - }); - }); -}); diff --git a/packages/server/tests/models/ExpenseCategory.test.js b/packages/server/tests/models/ExpenseCategory.test.js deleted file mode 100644 index 1eca93c07..000000000 --- a/packages/server/tests/models/ExpenseCategory.test.js +++ /dev/null @@ -1,5 +0,0 @@ - - -describe('ExpenseCategory', () => { - -}); \ No newline at end of file diff --git a/packages/server/tests/models/Item.test.js b/packages/server/tests/models/Item.test.js deleted file mode 100644 index 8ce26771c..000000000 --- a/packages/server/tests/models/Item.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import { create, expect } from '~/testInit'; -import Item from 'models/Item'; -// eslint-disable-next-line no-unused-vars -import itemCategory from 'models/ItemCategory'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('Model: Item', () => { - it('Should item model belongs to the associated category model.', async () => { - const category = await tenantFactory.create('item_category'); - const item = await tenantFactory.create('item', { category_id: category.id }); - - const itemModel = await Item.tenant().query().where('id', item.id).first(); - const itemCategoryModel = await itemModel.$relatedQuery('category'); - - expect(itemCategoryModel.id).equals(category.id); - }); -}); diff --git a/packages/server/tests/models/ItemCategories.test.js b/packages/server/tests/models/ItemCategories.test.js deleted file mode 100644 index cd339d70c..000000000 --- a/packages/server/tests/models/ItemCategories.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import { create, expect } from '~/testInit'; -import 'models/Item'; -import ItemCategory from 'models/ItemCategory'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('Model: ItemCategories', () => { - it('Shoud item category model has many associated items.', async () => { - const category = await tenantFactory.create('item_category'); - await tenantFactory.create('item', { category_id: category.id }); - await tenantFactory.create('item', { category_id: category.id }); - - const categoryModel = await ItemCategory.tenant().query() - .where('id', category.id).first(); - - const categoryItems = await categoryModel.$relatedQuery('items'); - - expect(categoryItems.length).equals(2); - }); -}); diff --git a/packages/server/tests/models/Resource.test.js b/packages/server/tests/models/Resource.test.js deleted file mode 100644 index 8a2a1eb11..000000000 --- a/packages/server/tests/models/Resource.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { create, expect } from '~/testInit'; -import Resource from 'models/Resource'; -import 'models/View'; -import 'models/ResourceField'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('Model: Resource', () => { - it('Resource model may has many associated views.', async () => { - const view = await tenantFactory.create('view'); - await tenantFactory.create('view', { resource_id: view.resourceId }); - - const resourceModel = await Resource.tenant().query().findById(view.resourceId); - const resourceViews = await resourceModel.$relatedQuery('views'); - - expect(resourceViews).to.have.lengthOf(2); - }); - - it('Resource model may has many fields.', async () => { - const resourceField = await tenantFactory.create('resource_field'); - - const resourceModel = await Resource.tenant().query().findById(resourceField.resourceId); - const resourceFields = await resourceModel.$relatedQuery('fields'); - - expect(resourceFields).to.have.lengthOf(1); - }); -}); diff --git a/packages/server/tests/models/User.test.js b/packages/server/tests/models/User.test.js deleted file mode 100644 index b29332288..000000000 --- a/packages/server/tests/models/User.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { create, expect } from '~/testInit'; -import User from 'models/TenantUser'; -import 'models/Role'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('Model: User', () => { - describe('relations', () => { - it('User model may has many associated roles.', async () => { - const userHasRole = await tenantFactory.create('user_has_role'); - await tenantFactory.create('user_has_role', { user_id: userHasRole.user_id }); - - const userModel = await User.tenant().query().where('id', userHasRole.userId).first(); - const userRoles = await userModel.$relatedQuery('roles'); - - expect(userRoles).to.have.lengthOf(1); - }); - }); -}); diff --git a/packages/server/tests/models/View.test.js b/packages/server/tests/models/View.test.js deleted file mode 100644 index 208302afa..000000000 --- a/packages/server/tests/models/View.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import { create, expect } from '~/testInit'; -import View from 'models/View'; -import Resource from 'models/Resource'; -import ResourceField from 'models/ResourceField'; -import ViewRole from 'models/ViewRole'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('Model: View', () => { - it('View model may has many associated resource.', async () => { - const view = await tenantFactory.create('view'); - - const viewModel = await View.tenant().query().findById(view.id); - const viewResource = await viewModel.$relatedQuery('resource'); - - const foundResource = await Resource.tenant().query().findById(view.resourceId); - - expect(viewResource.id).equals(foundResource.id); - expect(viewResource.name).equals(foundResource.name); - }); - - it('View model may has many associated view roles.', async () => { - const view = await tenantFactory.create('view'); - await tenantFactory.create('view_role', { view_id: view.id }); - await tenantFactory.create('view_role', { view_id: view.id }); - - const viewModel = await View.tenant().query().findById(view.id); - const viewRoles = await viewModel.$relatedQuery('roles'); - - expect(viewRoles).to.have.lengthOf(2); - }); - - it('View model may has many associated view columns', async () => { - const view = await tenantFactory.create('view'); - await tenantFactory.create('view_column', { view_id: view.id }); - await tenantFactory.create('view_column', { view_id: view.id }); - - const viewModel = await View.tenant().query().findById(view.id); - const viewColumns = await viewModel.$relatedQuery('columns'); - - expect(viewColumns).to.have.lengthOf(2); - }); -}); diff --git a/packages/server/tests/mysql-tmpfs.sh b/packages/server/tests/mysql-tmpfs.sh deleted file mode 100644 index 7ee993230..000000000 --- a/packages/server/tests/mysql-tmpfs.sh +++ /dev/null @@ -1,31 +0,0 @@ -MYSQL_USER="database_test" -MYSQL_DATABASE="database_test" -MYSQL_CONTAINER_NAME="database_test" - -MYSQL_ROOT_PASSWORD="root" -MYSQL_PASSWORD="root" - -echo "Start the testing MySql database..." - -docker \ - run \ - --detach \ - --env MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \ - --env MYSQL_USER=${MYSQL_USER} \ - --env MYSQL_PASSWORD=${MYSQL_PASSWORD} \ - --env MYSQL_DATABASE=${MYSQL_DATABASE} \ - --name ${MYSQL_CONTAINER_NAME} \ - --publish 3306:3306 \ - --tmpfs /var/lib/mysql:rw,noexec,nosuid,size=600m \ - mysql:5.7; - -echo "Sleeping for 10 seconds to allow time for the DB to be provisioned:" -for i in `seq 1 10`; -do - echo "." - sleep 1 -done - -echo "Database '${MYSQL_DATABASE}' running." -echo " Username: ${MYSQL_USER}" -echo " Password: ${MYSQL_PASSWORD}" diff --git a/packages/server/tests/routes/accounting.test.js b/packages/server/tests/routes/accounting.test.js deleted file mode 100644 index 1b2d1b2c5..000000000 --- a/packages/server/tests/routes/accounting.test.js +++ /dev/null @@ -1,887 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import moment from 'moment'; -import ManualJournal from 'models/ManualJournal'; -import AccountTransaction from 'models/AccountTransaction'; -import AccountBalance from 'models/AccountBalance'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: `/accounting`', () => { - describe('route: `/accounting/make-journal-entries`', async () => { - it('Should sumation of credit or debit does not equal zero.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '123', - reference: 'ASC', - entries: [ - { - index: 1, - credit: 0, - debit: 0, - account_id: account.id, - }, - { - index: 2, - credit: 0, - debit: 0, - account_id: account.id, - }, - ], - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', - code: 400, - }); - }); - - it('Should all credit entries equal debit.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '123', - entries: [ - { - index: 1, - credit: 1000, - debit: 0, - account_id: account.id, - }, - { - index: 2, - credit: 0, - debit: 500, - account_id: account.id, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'CREDIT.DEBIT.NOT.EQUALS', - code: 100, - }); - }); - - it('Should journal reference be not exists.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const account = await tenantFactory.create('account'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: manualJournal.journalNumber, - entries: [ - { - index: 1, - credit: 1000, - debit: 0, - account_id: account.id, - }, - { - index: 2, - credit: 0, - debit: 1000, - account_id: account.id, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'JOURNAL.NUMBER.ALREADY.EXISTS', - code: 300, - }); - }); - - it('Should response error in case account id not exists in one of the given entries.', async () => { - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '123', - entries: [ - { - index: 1, - credit: 1000, - debit: 0, - account_id: 12, - }, - { - index: 2, - credit: 0, - debit: 1000, - account_id: 12, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'ACCOUNTS.IDS.NOT.FOUND', - code: 200, - }); - }); - - it('Should discard journal entries that has null credit and debit amount.', async () => { - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '1000', - entries: [ - { - index: 1, - credit: null, - debit: 0, - account_id: account1.id, - }, - { - index: 2, - credit: null, - debit: 0, - account_id: account2.id, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', - - code: 400, - }); - }); - - it('Should validate the customers and vendors contact if were not found on the storage.', async () => { - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '1000', - entries: [ - { - index: 1, - credit: null, - debit: 1000, - account_id: account1.id, - contact_type: 'customer', - contact_id: 100, - }, - { - index: 2, - credit: 1000, - debit: 0, - account_id: account1.id, - contact_type: 'vendor', - contact_id: 300, - }, - ], - }); - - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMERS.CONTACTS.NOT.FOUND', code: 500, ids: [100], - }); - expect(res.body.errors).include.something.deep.equals({ - type: 'VENDORS.CONTACTS.NOT.FOUND', code: 600, ids: [300], - }) - }); - - it('Should customer contact_type with receivable accounts type.', async () => { - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - const customer = await tenantFactory.create('customer'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '1000', - entries: [ - { - index: 1, - credit: null, - debit: 1000, - account_id: account1.id, - contact_type: 'customer', - contact_id: 100, - }, - { - index: 2, - credit: 1000, - debit: 0, - account_id: account1.id, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMERS.NOT.WITH.RECEIVABLE.ACCOUNT', - code: 700, - indexes: [1] - }); - }); - - it('Should account receivable entries has contact_id and contact_type customer.', async () => { - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '1000', - entries: [ - { - index: 1, - credit: null, - debit: 1000, - account_id: 10, - }, - { - index: 2, - credit: 1000, - debit: 0, - account_id: 1, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'RECEIVABLE.ENTRIES.HAS.NO.CUSTOMERS', code: 900, indexes: [1], - }); - }); - - it('Should account payable entries has contact_id and contact_type vendor.', async () => { - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '1000', - entries: [ - { - index: 1, - credit: null, - debit: 1000, - account_id: 10, - }, - { - index: 2, - credit: 1000, - debit: 0, - account_id: 11, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'PAYABLE.ENTRIES.HAS.NO.VENDORS', code: 1000, indexes: [2] - }); - }); - - it('Should retrieve account_id is not receivable in case contact_type equals customer.', async () => { - const customer = await tenantFactory.create('customer'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '1000', - entries: [ - { - index: 1, - credit: null, - debit: 1000, - account_id: 2, - contact_id: customer.id, - contact_type: 'customer', - }, - { - index: 2, - credit: 1000, - debit: 0, - account_id: 11, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMERS.NOT.WITH.RECEIVABLE.ACCOUNT', code: 700, indexes: [1], - }); - }); - - it('Should store manual journal transaction to the storage.', async () => { - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date('2020-2-2').toISOString(), - journal_number: '1000', - reference: '2000', - description: 'Description here.', - entries: [ - { - index: 1, - credit: 1000, - account_id: account1.id, - }, - { - index: 2, - debit: 1000, - account_id: account2.id, - }, - ], - }); - - const foundManualJournal = await ManualJournal.tenant().query(); - expect(foundManualJournal.length).equals(1); - - expect(foundManualJournal[0].reference).equals('2000'); - expect(foundManualJournal[0].journalNumber).equals('1000'); - expect(foundManualJournal[0].transactionType).equals('Journal'); - expect(foundManualJournal[0].amount).equals(1000); - expect(moment(foundManualJournal[0].date).format('YYYY-MM-DD')).equals('2020-02-02'); - expect(foundManualJournal[0].description).equals('Description here.'); - expect(foundManualJournal[0].userId).to.be.a('number'); - }); - - it('Should store journal transactions to the storage.', async () => { - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - - const res = await request() - .post('/api/accounting/make-journal-entries') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - journal_number: '1', - date: new Date('2020-1-1').toISOString(), - reference: '1000', - memo: 'Description here.', - entries: [ - { - index: 1, - credit: 1000, - account_id: account1.id, - note: 'First note', - }, - { - index: 2, - debit: 1000, - account_id: account2.id, - note: 'Second note', - }, - ], - }); - - const foundAccountsTransactions = await AccountTransaction.tenant().query(); - - expect(foundAccountsTransactions.length).equals(2); - - expect(foundAccountsTransactions[0].credit).equals(1000); - expect(foundAccountsTransactions[0].debit).equals(null); - expect(foundAccountsTransactions[0].accountId).equals(account1.id); - expect(foundAccountsTransactions[0].note).equals('First note'); - expect(foundAccountsTransactions[0].referenceType).equals('Journal'); - expect(foundAccountsTransactions[0].userId).equals(1); - - expect(foundAccountsTransactions[1].credit).equals(null); - expect(foundAccountsTransactions[1].debit).equals(1000); - expect(foundAccountsTransactions[1].accountId).equals(account2.id); - expect(foundAccountsTransactions[1].note).equals('Second note'); - expect(foundAccountsTransactions[1].referenceType).equals('Journal'); - expect(foundAccountsTransactions[1].userId).equals(1); - }); - }); - - describe('route: POST: `/accounting/manual-journal/:id`', () => { - it('Should response not found in case manual journal transaction was not exists.', async () => { - const res = await request() - .post('/api/manual-journal/1000') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - }); - - it('Should sumation of credit or debit be equal zero.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '123', - reference: 'ASC', - entries: [ - { - credit: 0, - debit: 0, - account_id: 2000, - }, - { - credit: 0, - debit: 0, - account_id: 2000, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', - code: 400, - }); - }); - - it('Should all credit and debit sumation be equal.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: new Date().toISOString(), - journal_number: '123', - reference: 'ASC', - entries: [ - { - credit: 0, - debit: 2000, - account_id: 2000, - }, - { - credit: 1000, - debit: 0, - account_id: 2000, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'CREDIT.DEBIT.NOT.EQUALS', code: 100, - }); - }); - - it('Should response journal number already exists in case another one on the storage.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const manualJournal2 = await tenantFactory.create('manual_journal'); - - const jsonBody = { - date: new Date().toISOString(), - reference: 'ASC', - entries: [ - { - credit: 0, - debit: 2000, - account_id: 2000, - }, - { - credit: 1000, - debit: 0, - account_id: 2000, - }, - ], - }; - - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - ...jsonBody, - journal_number: manualJournal2.journalNumber, - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'JOURNAL.NUMBER.ALREADY.EXISTS', code: 300, - }); - }); - - it('Should not response journal number exists in case was unique number.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const manualJournal2 = await tenantFactory.create('manual_journal'); - - const jsonBody = { - date: new Date().toISOString(), - reference: 'ASC', - entries: [ - { - credit: 0, - debit: 2000, - account_id: 2000, - }, - { - credit: 1000, - debit: 0, - account_id: 2000, - }, - ], - }; - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - ...jsonBody, - journal_number: manualJournal.journalNumber, - }); - - expect(res.status).equals(400); - expect(res.body.errors).not.include.something.that.deep.equal({ - type: 'JOURNAL.NUMBER.ALREADY.EXISTS', code: 300, - }); - }) - - it('Should response error in case account id not exists in one of the given entries.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const manualJournal2 = await tenantFactory.create('manual_journal'); - - const jsonBody = { - date: new Date().toISOString(), - reference: 'ASC', - entries: [ - { - credit: 0, - debit: 1000, - account_id: 2000, - }, - { - credit: 1000, - debit: 0, - account_id: 2000, - }, - ], - }; - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - ...jsonBody, - journal_number: manualJournal.journalNumber, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'ACCOUNTS.IDS.NOT.FOUND', code: 200, - }); - }); - - it('Should update the given manual journal transaction in the storage.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - journal_number: '123', - date: new Date().toISOString(), - reference: 'ABC', - description: 'hello world', - entries: [ - { - credit: 0, - debit: 1000, - account_id: account1.id, - }, - { - credit: 1000, - debit: 0, - account_id: account2.id, - }, - ], - }); - - const foundManualJournal = await ManualJournal.tenant().query() - .where('id', manualJournal.id); - - expect(foundManualJournal.length).equals(1); - expect(foundManualJournal[0].journalNumber).equals('123'); - expect(foundManualJournal[0].reference).equals('ABC'); - expect(foundManualJournal[0].description).equals('hello world'); - }); - - it('Should update account transactions that associated to the manual journal transaction.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - const transaction = await tenantFactory.create('account_transaction', { - reference_type: 'Journal', - reference_id: manualJournal.id, - }); - const transaction2 = await tenantFactory.create('account_transaction', { - reference_type: 'Journal', - reference_id: manualJournal.id, - }); - - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - journal_number: '123', - date: new Date().toISOString(), - reference: 'ABC', - description: 'hello world', - entries: [ - { - credit: 0, - debit: 1000, - account_id: account1.id, - note: 'hello 1', - }, - { - credit: 1000, - debit: 0, - account_id: account2.id, - note: 'hello 2', - }, - ], - }); - - const foundTransactions = await AccountTransaction.tenant().query(); - - expect(foundTransactions.length).equals(2); - expect(foundTransactions[0].credit).equals(0); - expect(foundTransactions[0].debit).equals(1000); - expect(foundTransactions[0].accountId).equals(account1.id); - expect(foundTransactions[0].note).equals('hello 1'); - - expect(foundTransactions[1].credit).equals(1000); - expect(foundTransactions[1].debit).equals(0); - expect(foundTransactions[1].accountId).equals(account2.id); - expect(foundTransactions[1].note).equals('hello 2'); - }); - }); - - describe('route: DELETE `accounting/manual-journals/:id`', () => { - it('Should response not found in case the manual journal transaction was not found.', async() => { - const res = await request() - .delete('/api/accounting/manual-journals/1000') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equal({ - type: 'MANUAL.JOURNAL.NOT.FOUND', code: 100, - }); - }); - - it('Should delete manual journal transactions from storage.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - - const res = await request() - .delete(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundManualTransaction = await ManualJournal.tenant().query() - .where('id', manualJournal.id).first(); - - expect(foundManualTransaction).equals(undefined); - }); - - it('Should delete associated transactions of journal transaction.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - const transaction1 = await tenantFactory.create('account_transaction', { - reference_type: 'Journal', reference_id: manualJournal.id, - }); - const transaction2 = await tenantFactory.create('account_transaction', { - reference_type: 'Journal', reference_id: manualJournal.id, - }); - - const res = await request() - .delete(`/api/accounting/manual-journals/${manualJournal.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundTransactions = await AccountTransaction.tenant().query(); - expect(foundTransactions.length).equals(0); - }); - - it('Should revert accounts balance after delete account transactions.', () => { - - }); - }); - - describe('route: GET `accounting/manual-journals/:id`', () => { - it('Should response not found in case manual transaction id was not exists.', async () => { - const res = await request() - .delete('/api/accounting/manual-journals/100') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'MANUAL.JOURNAL.NOT.FOUND', code: 100, - }); - }); - - it('Should response manual transaction and transactions metadata.', async () => { - - }); - - }); - - describe('route: `accounting/manual-journals`', async () => { - - it('Should retrieve all manual journals with pagination meta.', async () => { - const manualJournal1 = await tenantFactory.create('manual_journal'); - const manualJournal2 = await tenantFactory.create('manual_journal'); - - const res = await request() - .get('/api/accounting/manual-journals') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - expect(res.body.manualJournals.results).to.be.a('array'); - expect(res.body.manualJournals.results.length).equals(2); - }); - }); - - describe('route: POST `accounting/manual-journals/:id/publish`', () => { - - it('Should response not found in case the manual journal id was not exists.', async () => { - const manualJournal = await tenantFactory.create('manual_journal'); - - const res = await request() - .post('/api/accounting/manual-journals/123/publish') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'MANUAL.JOURNAL.NOT.FOUND', code: 100, - }); - }); - - it('Should response published ready.', async () => { - const manualJournal = await tenantFactory.create('manual_journal', { status: 1 }); - - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}/publish`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'MANUAL.JOURNAL.PUBLISHED.ALREADY', code: 200, - }); - }); - - it('Should update all accounts transactions to not draft.', async () => { - const manualJournal = await tenantFactory.create('manual_journal', { status: 0 }); - const transaction = await tenantFactory.create('account_transaction', { - reference_type: 'Journal', - reference_id: manualJournal.id, - draft: 1, - }); - const transaction2 = await tenantFactory.create('account_transaction', { - reference_type: 'Journal', - reference_id: manualJournal.id, - draft: 1, - }); - const res = await request() - .post(`/api/accounting/manual-journals/${manualJournal.id}/publish`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundTransactions = await AccountTransaction.tenant().query() - .whereIn('id', [transaction.id, transaction2.id]); - - expect(foundTransactions[0].draft).equals(0); - expect(foundTransactions[1].draft).equals(0); - }); - - it('Should increment/decrement accounts balance.', () => { - - }); - }); - - describe('route: `/accounting/quick-journal-entries`', async () => { - it('Shoud `credit_account_id` be required', () => { - - }); - it('Should `debit_account_id` be required.', () => { - - }); - - it('Should `amount` be required.', () => { - - }); - - it('Should credit account id be exists.', () => { - - }); - - it('Should debit account id be exists.', () => { - - }); - - it('Should store the quick journal entry to the storage.', () => { - - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/accounts.test.js b/packages/server/tests/routes/accounts.test.js deleted file mode 100644 index 1a6fb1d31..000000000 --- a/packages/server/tests/routes/accounts.test.js +++ /dev/null @@ -1,758 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Account from 'models/Account'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: /accounts/', () => { - describe('POST `/accounts`', () => { - it('Should `name` be required.', async () => { - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should `account_type_id` be required.', async () => { - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should max length of `code` be limited.', async () => { - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should response type not found in case `account_type_id` was not exist.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Account Name', - description: account.description, - account_type_id: 22, // not found. - code: 123, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'NOT_EXIST_ACCOUNT_TYPE', code: 200, - }); - }); - - it('Should account code be unique in the storage.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: account.name, - description: account.description, - account_type_id: account.accountTypeId, - code: account.code, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'NOT_UNIQUE_CODE', code: 100, - }); - }); - - it('Should response success with correct data form.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Name', - description: 'description here', - code: 100, - account_type_id: account.accountTypeId, - parent_account_id: account.id, - }); - - expect(res.status).equals(200); - }); - - it('Should store account data in the storage.', async () => { - const account = await tenantFactory.create('account'); - - const res = await request().post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Account Name', - description: 'desc here', - account_type_id: account.accountTypeId, - parent_account_id: account.id, - }); - - const accountModel = await Account.tenant().query() - .where('name', 'Account Name') - .first(); - - expect(accountModel).a.an('object'); - expect(accountModel.description).equals('desc here'); - expect(accountModel.accountTypeId).equals(account.accountTypeId); - expect(accountModel.parentAccountId).equals(account.id); - }); - }); - - describe('POST `/accounts/:id`', () => { - it('Should `name` be required.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post(`/api/accounts/${account.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should `account_type_id` be required.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post(`/api/accounts/${account.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should max length of `code` be limited.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post(`/api/accounts/${account.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should response type not found in case `account_type_id` was not exist.', async () => { - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - }); - - it('Should account code be unique in the storage.', async () => { - await tenantFactory.create('account', { code: 'ABCD' }); - const account = await tenantFactory.create('account'); - const res = await request() - .post(`/api/accounts/${account.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'name', - code: 'ABCD', - account_type_id: account.accountTypeId, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'NOT_UNIQUE_CODE', code: 100, - }); - }); - - it('Should response success with correct data form.', async () => { - const account = await tenantFactory.create('account'); - const res = await request() - .post('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Name', - description: 'description here', - account_type_id: account.accountTypeId, - parent_account_id: account.id, - code: '123', - }); - - expect(res.status).equals(200); - }); - }); - - describe('GET: `/accounts`', () => { - it('Should retrieve chart of accounts', async () => { - await tenantFactory.create('resource', { name: 'accounts' }); - const account = await tenantFactory.create('account'); - await tenantFactory.create('account', { parent_account_id: account.id }); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - expect(res.body.accounts.length).above(0); - }); - - it('Should retrieve accounts based on view roles conditionals of the custom view.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - - const accountTypeField = await tenantFactory.create('resource_field', { - label_name: 'Account type', - key: 'type', - resource_id: resource.id, - active: true, - predefined: true, - }); - - const accountNameField = await tenantFactory.create('resource_field', { - label_name: 'Account Name', - key: 'name', - resource_id: resource.id, - active: true, - predefined: true, - }); - const accountsView = await tenantFactory.create('view', { - name: 'Accounts View', - resource_id: resource.id, - roles_logic_expression: '1 AND 2', - }); - const accountType = await tenantFactory.create('account_type'); - - await tenantFactory.create('view_role', { - view_id: accountsView.id, - index: 1, - field_id: accountTypeField.id, - value: accountType.name, - comparator: 'equals', - }); - await tenantFactory.create('view_role', { - view_id: accountsView.id, - index: 2, - field_id: accountNameField.id, - value: 'account', - comparator: 'contains', - }); - - await tenantFactory.create('account', { name: 'account-1', account_type_id: accountType.id }); - await tenantFactory.create('account', { name: 'account-2', account_type_id: accountType.id }); - await tenantFactory.create('account', { name: 'account-3' }); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - custom_view_id: accountsView.id - }) - .send(); - - expect(res.body.accounts.length).equals(2); - expect(res.body.accounts[0].name).equals('account-1'); - expect(res.body.accounts[1].name).equals('account-2'); - expect(res.body.accounts[0].account_type_id).equals(accountType.id); - expect(res.body.accounts[1].account_type_id).equals(accountType.id); - }); - - it('Should retrieve accounts based on view roles conditionals with relation join column.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - - const accountTypeField = await tenantFactory.create('resource_field', { - label_name: 'Account type', - key: 'type', - resource_id: resource.id, - active: true, - predefined: true, - }); - const accountsView = await tenantFactory.create('view', { - name: 'Accounts View', - resource_id: resource.id, - roles_logic_expression: '1', - }); - - const accountType = await tenantFactory.create('account_type'); - const accountsViewRole = await tenantFactory.create('view_role', { - view_id: accountsView.id, - index: 1, - field_id: accountTypeField.id, - value: accountType.name, - comparator: 'equals', - }); - - await tenantFactory.create('account', { account_type_id: accountType.id }); - await tenantFactory.create('account'); - await tenantFactory.create('account'); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - custom_view_id: accountsView.id - }) - .send(); - - expect(res.body.accounts.length).equals(1); - expect(res.body.accounts[0].account_type_id).equals(accountType.id); - }); - - it('Should retrieve accounts and child accounts in nested set graph.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account', { parent_account_id: account1.id }); - const account3 = await tenantFactory.create('account', { parent_account_id: account2.id }); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - - const foundAccount = res.body.accounts.find(a => a.id === account1.id); - - expect(foundAccount.id).equals(account1.id); - expect(foundAccount.children[0].id).equals(account2.id); - expect(foundAccount.children[0].children[0].id).equals(account3.id); - }); - - it('Should retrieve bad request when `filter_roles.*.comparator` not associated to `field_key`.', () => { - - }); - - it('Should retrieve bad request when `filter_roles.*.field_key` not found in accounts resource.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - - const account1 = await tenantFactory.create('account', { name: 'ahmed' }); - const account2 = await tenantFactory.create('account'); - const account3 = await tenantFactory.create('account'); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - stringified_filter_roles: JSON.stringify([{ - condition: 'AND', - field_key: 'not_found', - comparator: 'equals', - value: 'ahmed', - }, { - condition: 'AND', - field_key: 'mybe_found', - comparator: 'equals', - value: 'ahmed', - }]), - }); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ACCOUNTS.RESOURCE.HAS.NO.GIVEN.FIELDS', code: 500, - }); - }); - - it('Should retrieve bad request when `filter_roles.*.condition` is invalid.', async () => { - - }); - - it('Should retrieve filtered accounts according to the given account type filter condition.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const keyField = await tenantFactory.create('resource_field', { - key: 'type', - resource_id: resource.id, - }); - const nameFiled = await tenantFactory.create('resource_field', { - key: 'name', - resource_id: resource.id, - }); - const accountType = await tenantFactory.create('account_type'); - - const account1 = await tenantFactory.create('account', { - name: 'ahmed', - account_type_id: accountType.id - }); - const account2 = await tenantFactory.create('account'); - const account3 = await tenantFactory.create('account'); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - stringified_filter_roles: JSON.stringify([{ - condition: '&&', - field_key: 'type', - comparator: 'equals', - value: accountType.name, - }, { - condition: '&&', - field_key: 'name', - comparator: 'equals', - value: 'ahmed', - }]), - }); - - expect(res.body.accounts.length).equals(1); - }); - - it('Shoud retrieve filtered accounts according to the given account description filter condition.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const resourceField = await tenantFactory.create('resource_field', { - key: 'description', - resource_id: resource.id, - }); - - const account1 = await tenantFactory.create('account', { name: 'ahmed', description: 'here' }); - const account2 = await tenantFactory.create('account'); - const account3 = await tenantFactory.create('account'); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - stringified_filter_roles: JSON.stringify([{ - condition: 'AND', - field_key: resourceField.key, - comparator: 'contain', - value: 'here', - }]), - }); - - expect(res.body.accounts.length).equals(1); - expect(res.body.accounts[0].description).equals('here'); - }); - - it('Should retrieve filtered accounts based on given filter roles between OR conditions.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const resourceField = await tenantFactory.create('resource_field', { - key: 'description', - resource_id: resource.id, - }); - - const resourceCodeField = await tenantFactory.create('resource_field', { - key: 'code', - resource_id: resource.id, - }); - - const account1 = await tenantFactory.create('account', { name: 'ahmed', description: 'target' }); - const account2 = await tenantFactory.create('account', { description: 'target' }); - const account3 = await tenantFactory.create('account'); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - stringified_filter_roles: JSON.stringify([{ - condition: '&&', - field_key: resourceField.key, - comparator: 'contain', - value: 'target', - }, { - condition: '||', - field_key: resourceCodeField.key, - comparator: 'equals', - value: 'ahmed', - }]), - }); - - expect(res.body.accounts.length).equals(2); - expect(res.body.accounts[0].description).equals('target'); - expect(res.body.accounts[1].description).equals('target'); - expect(res.body.accounts[0].name).equals('ahmed'); - }); - - it('Should retrieve filtered accounts from custom view and filter roles.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const accountTypeField = await tenantFactory.create('resource_field', { - key: 'type', resource_id: resource.id, - }); - const accountDescriptionField = await tenantFactory.create('resource_field', { - key: 'description', resource_id: resource.id, - }); - - const accountType = await tenantFactory.create('account_type', { name: 'type-name' }); - - const account1 = await tenantFactory.create('account', { name: 'ahmed-1' }); - const account2 = await tenantFactory.create('account', { name: 'ahmed-2', account_type_id: accountType.id, description: 'target' }); - const account3 = await tenantFactory.create('account', { name: 'ahmed-3' }); - - const accountsView = await tenantFactory.create('view', { - name: 'Accounts View', - resource_id: resource.id, - roles_logic_expression: '1', - }); - const accountsViewRole = await tenantFactory.create('view_role', { - view_id: accountsView.id, - field_id: accountTypeField.id, - index: 1, - value: 'type-name', - comparator: 'equals', - }); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - custom_view_id: accountsView.id, - stringified_filter_roles: JSON.stringify([{ - condition: 'AND', - field_key: 'description', - comparator: 'contain', - value: 'target', - }]), - }); - - expect(res.body.accounts.length).equals(1); - expect(res.body.accounts[0].name).equals('ahmed-2'); - expect(res.body.accounts[0].description).equals('target'); - }); - - it('Should validate the given `column_sort_order` column on the accounts resource.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - column_sort_by: 'not_found', - sort_order: 'desc', - }); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'COLUMN.SORT.ORDER.NOT.FOUND', code: 300, - }); - }); - - it('Should sorting the given `column_sort_order` column on asc direction,', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const resourceField = await tenantFactory.create('resource_field', { - key: 'name', resource_id: resource.id, - }); - const accounts1 = await tenantFactory.create('account', { name: 'A' }); - const accounts2 = await tenantFactory.create('account', { name: 'B' }); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - column_sort_by: 'name', - sort_order: 'asc', - }); - - const AAccountIndex = res.body.accounts.findIndex(a => a.name === 'B'); - const BAccountIndex = res.body.accounts.findIndex(a => a.name === 'A'); - - expect(AAccountIndex).above(BAccountIndex); - }); - - it('Should sorting the given `column_sort_order` columnw with relation on another table on asc direction.', async () => { - const resource = await tenantFactory.create('resource', { name: 'accounts' }); - const resourceField = await tenantFactory.create('resource_field', { - key: 'type', resource_id: resource.id, - }); - const accounts1 = await tenantFactory.create('account', { name: 'A' }); - const accounts2 = await tenantFactory.create('account', { name: 'B' }); - - const res = await request() - .get('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - column_sort_by: 'name', - sort_order: 'asc', - }); - - expect(res.body.accounts[0].name).equals('A'); - expect(res.body.accounts[1].name).equals('B'); - }); - }); - - describe('DELETE: `/accounts`', () => { - it('Should response not found in case account was not exist.', async () => { - const res = await request() - .delete('/api/accounts/10') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - }); - - it('Should delete the give account from the storage.', async () => { - const account = await tenantFactory.create('account'); - await request() - .delete(`/api/accounts/${account.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundAccounts = await Account.tenant().query().where('id', account.id); - expect(foundAccounts).to.have.lengthOf(0); - }); - - it('Should not delete the given account in case account has associated transactions.', async () => { - const accountTransaction = await tenantFactory.create('account_transaction'); - - const res = await request() - .delete(`/api/accounts/${accountTransaction.accountId}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS', code: 100, - }); - }); - }); - - describe('DELETE: `/accounts?ids=`', () => { - it('Should response in case on of accounts ids was not exists.', async () => { - const res = await request() - .delete('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [100, 200], - }) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ACCOUNTS.IDS.NOT.FOUND', code: 200, ids: [100, 200], - }); - }); - - it('Should response bad request in case one of accounts has transactions.', async () => { - const accountTransaction = await tenantFactory.create('account_transaction'); - const accountTransaction2 = await tenantFactory.create('account_transaction'); - - const res = await request() - .delete('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [accountTransaction.accountId, accountTransaction2.accountId], - }) - .send(); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS', - code: 300, - ids: [accountTransaction.accountId, accountTransaction2.accountId], - }); - }); - - it('Should delete the given accounts from the storage.', async () => { - const account1 = await tenantFactory.create('account'); - const account2 = await tenantFactory.create('account'); - - const res = await request() - .delete('/api/accounts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [account1.id, account2.id], - }) - .send(); - - expect(res.status).equals(200); - - const foundAccounts = await Account.tenant().query() - .whereIn('id', [account1.id, account2.id]); - - expect(foundAccounts.length).equals(0); - }); - }); - - describe('POST: `/api/accounts/bulk/activate|inactivate', () => { - it('Should response if there one of accounts ids were not found.', async () => { - const res = await request() - .post('/api/accounts/bulk/activate') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [123123, 321321], - }) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ACCOUNTS.NOT.FOUND', code: 200, - }); - }); - - it('Should activate all the given accounts.', async () => { - const accountA = await tenantFactory.create('account', { active: 1 }); - const accountB = await tenantFactory.create('account', { active: 1 }); - - const res = await request() - .post('/api/accounts/bulk/inactivate') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [accountA.id, accountB.id], - }) - .send(); - - const updatedAccounts = await Account.tenant().query().whereIn('id', [accountA.id, accountB.id]); - - expect(updatedAccounts[0].active).equals(0); - expect(updatedAccounts[1].active).equals(0); - }); - - it('Should inactivate all the given accounts.', async () => { - const accountA = await tenantFactory.create('account', { active: 0 }); - const accountB = await tenantFactory.create('account', { active: 0 }); - - const res = await request() - .post('/api/accounts/bulk/activate') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [accountA.id, accountB.id], - }) - .send(); - - const updatedAccounts = await Account.tenant().query().whereIn('id', [accountA.id, accountB.id]); - - expect(updatedAccounts[0].active).equals(1); - expect(updatedAccounts[1].active).equals(1); - }); - }); -}); diff --git a/packages/server/tests/routes/auth.test.js b/packages/server/tests/routes/auth.test.js deleted file mode 100644 index 0f9da2b34..000000000 --- a/packages/server/tests/routes/auth.test.js +++ /dev/null @@ -1,288 +0,0 @@ -import { request, expect, createUser } from '~/testInit'; -import { hashPassword } from 'utils'; -import knex from '@/database/knex'; -import { - tenantWebsite, - tenantFactory, - systemFactory, - loginRes -} from '~/dbInit'; -import TenantUser from 'models/TenantUser'; -import PasswordReset from '@/system/models/PasswordReset'; -import SystemUser from '@/system/models/SystemUser'; - - -describe('routes: /auth/', () => { - describe('POST `/api/auth/login`', () => { - it('Should `crediential` be required.', async () => { - const res = await request().post('/api/auth/login').send({}); - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('crediential'); - }); - - it('Should `password` be required.', async () => { - const res = await request().post('/api/auth/login').send(); - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('password'); - }); - - it('Should the min length of the `password` be 5 ch.', async () => { - const res = await request().post('/api/auth/login').send({ - crediential: 'admin@admin.com', - password: 'test', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('password'); - }); - - it('Should be a valid email format in crediential attribute.', async () => { - const res = await request().post('/api/auth/login').send({ - crediential: 'admin', - password: 'test', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('password'); - }); - - it('Should not authenticate with wrong user email and password.', async () => { - const res = await request().post('/api/auth/login').send({ - crediential: 'admin@admin.com', - password: 'admin', - }); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'INVALID_DETAILS', code: 100, - }); - }); - - it('Should not authenticate in case user was not active.', async () => { - const user = await createUser(tenantWebsite, { - active: false, - email: 'admin@admin.com', - }); - - const res = await request().post('/api/auth/login').send({ - crediential: 'admin@admin.com', - password: 'admin', - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'USER_INACTIVE', code: 110, - }); - }); - - it('Should authenticate with correct email and password and active user.', async () => { - const user = await createUser(tenantWebsite, { - email: 'admin@admin.com', - }); - const res = await request().post('/api/auth/login').send({ - crediential: user.email, - password: 'admin', - }); - expect(res.status).equals(200); - }); - - it('Should authenticate success with correct phone number and password.', async () => { - const password = await hashPassword('admin'); - const user = await createUser(tenantWebsite, { - phone_number: '0920000000', - password, - }); - const res = await request().post('/api/auth/login').send({ - crediential: user.email, - password: 'admin', - }); - - expect(res.status).equals(200); - }); - - it('Should last login date be saved after success login.', async () => { - const user = await createUser(tenantWebsite, { - email: 'admin@admin.com', - }); - const res = await request().post('/api/auth/login').send({ - crediential: user.email, - password: 'admin', - }); - const foundUserAfterUpdate = await TenantUser.tenant().query() - .where('email', user.email) - .where('first_name', user.first_name) - .first(); - - expect(res.status).equals(200); - expect(foundUserAfterUpdate.lastLoginAt).to.not.be.null; - }); - }); - - describe('POST: `/auth/send_reset_password`', () => { - it('Should `email` be required.', async () => { - const res = await request().post('/api/auth/send_reset_password').send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should response unproccessable if the email address was invalid.', async () => { - const res = await request().post('/api/auth/send_reset_password').send({ - email: 'invalid_email', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should response unproccessable if the email address was not exist.', async () => { - const res = await request().post('/api/auth/send_reset_password').send({ - email: 'admin@admin.com', - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'EMAIL.NOT.REGISTERED', code: 200, - }); - }); - - it('Should delete all already tokens that associate to the given email.', async () => { - const user = await createUser(tenantWebsite); - const token = '123123'; - - await knex('password_resets').insert({ email: user.email, token }); - - await request().post('/api/auth/send_reset_password').send({ - email: user.email, - }); - - const oldPasswordToken = await knex('password_resets').where('token', token); - - expect(oldPasswordToken).to.have.lengthOf(0); - }); - - it('Should store new token associate with the given email.', async () => { - const user = await createUser(tenantWebsite); - await request().post('/api/auth/send_reset_password').send({ - email: user.email, - }); - - const token = await knex('password_resets').where('email', user.email); - - expect(token).to.have.lengthOf(1); - }); - - it('Should response success if the email was exist.', async () => { - const user = await createUser(tenantWebsite); - const res = await request().post('/api/auth/send_reset_password').send({ - email: user.email, - }); - - expect(res.status).equals(200); - }); - }); - - describe('POST: `/auth/reset/:token`', () => { - // it('Should response forbidden if the token was invalid.', () => { - - // }); - - it('Should response forbidden if the token was expired.', () => { - - }); - - it('Should `password` be required.', async () => { - const user = await createUser(tenantWebsite); - const passwordReset = await systemFactory.create('password_reset', { - email: user.email, - }); - - const res = await request() - .post(`/api/auth/reset/${passwordReset.token}`) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('password'); - }); - - it('Should password and confirm_password be equal.', async () => { - const user = await createUser(tenantWebsite); - const passwordReset = await systemFactory.create('password_reset', { - email: user.email, - }); - - const res = await request() - .post(`/api/auth/reset/${passwordReset.token}`) - .send({ - password: '123123', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('password'); - }); - - it('Should response success with correct data form.', async () => { - const user = await createUser(tenantWebsite); - const passwordReset = await systemFactory.create('password_reset', { - email: user.email, - }); - - const res = await request() - .post(`/api/auth/reset/${passwordReset.token}`) - .send({ - password: '123123', - confirm_password: '123123', - }); - expect(res.status).equals(200); - }); - - it('Should token be deleted after success response.', async () => { - const user = await createUser(tenantWebsite); - const passwordReset = await systemFactory.create('password_reset', { - email: user.email, - }); - await request() - .post(`/api/auth/reset/${passwordReset.token}`) - .send({ - password: '123123', - confirm_password: '123123', - }); - - const foundTokens = await PasswordReset.query().where('email', passwordReset.email); - - expect(foundTokens).to.have.lengthOf(0); - }); - - it('Should password be updated after success response.', async () => { - const user = await createUser(tenantWebsite); - const passwordReset = await systemFactory.create('password_reset', { - email: user.email, - }); - - const res = await request().post(`/api/auth/reset/${passwordReset.token}`).send({ - password: '123123', - confirm_password: '123123', - }); - const systemUserPasswordUpdated = await SystemUser.query() - .where('id', user.id).first(); - - expect(systemUserPasswordUpdated.id).equals(user.id); - expect(systemUserPasswordUpdated.password).not.equals(user.password); - }); - }); -}); diff --git a/packages/server/tests/routes/balance_sheet.test.js b/packages/server/tests/routes/balance_sheet.test.js deleted file mode 100644 index d3260e09d..000000000 --- a/packages/server/tests/routes/balance_sheet.test.js +++ /dev/null @@ -1,541 +0,0 @@ -import moment from 'moment'; -import { - request, - expect, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import { iteratee } from 'lodash'; - -let creditAccount; -let debitAccount; -let incomeAccount; -let incomeType; - -describe('routes: `/financial_statements`', () => { - beforeEach(async () => { - const accountTransactionMixied = { date: '2020-1-10' }; - - // Expense -- - // 1000 Credit - Cash account - // 1000 Debit - Bank account. - await tenantFactory.create('account_transaction', { - credit: 1000, debit: 0, account_id: 2, referenceType: 'Expense', - referenceId: 1, ...accountTransactionMixied, - }); - await tenantFactory.create('account_transaction', { - credit: 0, debit: 1000, account_id: 7, referenceType: 'Expense', - referenceId: 1, ...accountTransactionMixied, - }); - - // Jounral - // 4000 Credit - Opening balance account. - // 2000 Debit - Bank account - // 2000 Debit - Bank account - await tenantFactory.create('account_transaction', { - credit: 4000, debit: 0, account_id: 5, ...accountTransactionMixied, - }); - await tenantFactory.create('account_transaction', { - debit: 2000, credit: 0, account_id: 2, ...accountTransactionMixied, - }); - await tenantFactory.create('account_transaction', { - debit: 2000, credit: 0, account_id: 2, ...accountTransactionMixied, - }); - - // Income Journal. - // 2000 Credit - Income account. - // 2000 Debit - Bank account. - await tenantFactory.create('account_transaction', { - credit: 2000, account_id: 4, ...accountTransactionMixied - }); - await tenantFactory.create('account_transaction', { - debit: 2000, credit: 0, account_id: 2, ...accountTransactionMixied, - }); - - // ----------------------------------------- - // Bank account balance = 5000 | Opening balance account balance = 4000 - // Expense account balance = 1000 | Income account balance = 2000 - }); - - describe('routes: `financial_statements/balance_sheet`', () => { - it('Should response unauthorzied in case the user was not authorized.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .send(); - - expect(res.status).equals(401); - }); - - it('Should retrieve query of the balance sheet with default values.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'year', - from_date: '2020-01-01', - to_date: '2020-02-01', - }) - .send(); - - expect(res.body.query.display_columns_by).equals('year'); - expect(res.body.query.from_date).equals('2020-01-01'); - expect(res.body.query.to_date).equals('2020-02-01'); - - expect(res.body.query.number_format.no_cents).equals(false); - expect(res.body.query.number_format.divide_1000).equals(false); - - expect(res.body.query.none_zero).equals(false); - }); - - it('Should retrieve assets and liabilities/equity section.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'year', - }) - .send(); - - expect(res.body.balance_sheet[0].name).equals('Assets'); - expect(res.body.balance_sheet[1].name).equals('Liabilities and Equity'); - - expect(res.body.balance_sheet[0].section_type).equals('assets'); - expect(res.body.balance_sheet[1].section_type).equals('liabilities_equity'); - - expect(res.body.balance_sheet[0].type).equals('section'); - expect(res.body.balance_sheet[1].type).equals('section'); - }); - - it('Should retrieve assets and liabilities/equity total of each section.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - to_date: '2020-12-10', - }) - .send(); - - expect(res.body.balance_sheet[0].total.amount).equals(5000); - expect(res.body.balance_sheet[1].total.amount).equals(4000); - }); - - it('Should retrieve the asset and liabilities/equity accounts.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_type: 'total', - from_date: '2012-01-01', - to_date: '2032-02-02', - }) - .send(); - - expect(res.body.balance_sheet[0].children).to.be.a('array'); - expect(res.body.balance_sheet[0].children).to.be.a('array'); - - expect(res.body.balance_sheet[0].children.length).is.not.equals(0); - expect(res.body.balance_sheet[1].children.length).is.not.equals(0); - - expect(res.body.balance_sheet[1].children[0].children.length).is.not.equals(0); - expect(res.body.balance_sheet[1].children[1].children.length).is.not.equals(0); - }); - - it('Should retrieve assets/liabilities total balance between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_type: 'total', - from_date: '2012-01-01', - to_date: '2032-02-02', - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: 1001, - index: null, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - children: [], - total: { formatted_amount: 5000, amount: 5000, date: '2032-02-02' } - }); - - expect(res.body.accounts[1].children).include.something.deep.equals({ - id: 1000, - index: null, - name: creditAccount.name, - code: creditAccount.code, - parentAccountId: null, - children: [], - total: { formatted_amount: 4000, amount: 4000, date: '2032-02-02' } - }); - }); - - it('Should retrieve asset/liabilities balance sheet with display columns by `year`.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'year', - display_columns_type: 'date_periods', - from_date: '2012-01-01', - to_date: '2018-02-02', - }) - .send(); - - expect(res.body.accounts[0].children[0].total_periods.length).equals(7); - expect(res.body.accounts[1].children[0].total_periods.length).equals(7); - - expect(res.body.accounts[0].children[0].total_periods).deep.equals([ - { - amount: 0, - formatted_amount: 0, - date: '2012', - }, - { - amount: 0, - formatted_amount: 0, - date: '2013', - }, - { - amount: 0, - formatted_amount: 0, - date: '2014', - }, - { - amount: 0, - formatted_amount: 0, - date: '2015', - }, - { - amount: 0, - formatted_amount: 0, - date: '2016', - }, - { - amount: 0, - formatted_amount: 0, - date: '2017', - }, - { - amount: 0, - formatted_amount: 0, - date: '2018', - }, - ]); - }); - - it('Should retrieve balance sheet with display columns by `day`.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'day', - display_columns_type: 'date_periods', - from_date: '2020-01-08', - to_date: '2020-01-12', - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: debitAccount.id, - index: debitAccount.index, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - children: [], - total_periods: [ - { date: '2020-01-08', formatted_amount: 0, amount: 0 }, - { date: '2020-01-09', formatted_amount: 0, amount: 0 }, - { date: '2020-01-10', formatted_amount: 5000, amount: 5000 }, - { date: '2020-01-11', formatted_amount: 5000, amount: 5000 }, - { date: '2020-01-12', formatted_amount: 5000, amount: 5000 }, - ], - total: { formatted_amount: 5000, amount: 5000, date: '2020-01-12' } - }); - expect(res.body.accounts[1].children).include.something.deep.equals({ - id: creditAccount.id, - index: creditAccount.index, - name: creditAccount.name, - code: creditAccount.code, - parentAccountId: null, - children: [], - total_periods: [ - { date: '2020-01-08', formatted_amount: 0, amount: 0 }, - { date: '2020-01-09', formatted_amount: 0, amount: 0 }, - { date: '2020-01-10', formatted_amount: 4000, amount: 4000 }, - { date: '2020-01-11', formatted_amount: 4000, amount: 4000 }, - { date: '2020-01-12', formatted_amount: 4000, amount: 4000 } - ], - total: { formatted_amount: 4000, amount: 4000, date: '2020-01-12' } - }); - }); - - it('Should retrieve the balance sheet with display columns by `month`.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'month', - display_columns_type: 'date_periods', - from_date: '2019-07-01', - to_date: '2020-06-30', - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: debitAccount.id, - index: debitAccount.index, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - children: [], - total_periods: [ - { date: '2019-07', formatted_amount: 0, amount: 0 }, - { date: '2019-08', formatted_amount: 0, amount: 0 }, - { date: '2019-09', formatted_amount: 0, amount: 0 }, - { date: '2019-10', formatted_amount: 0, amount: 0 }, - { date: '2019-11', formatted_amount: 0, amount: 0 }, - { date: '2019-12', formatted_amount: 0, amount: 0 }, - { date: '2020-01', formatted_amount: 5000, amount: 5000 }, - { date: '2020-02', formatted_amount: 5000, amount: 5000 }, - { date: '2020-03', formatted_amount: 5000, amount: 5000 }, - { date: '2020-04', formatted_amount: 5000, amount: 5000 }, - { date: '2020-05', formatted_amount: 5000, amount: 5000 }, - { date: '2020-06', formatted_amount: 5000, amount: 5000 }, - ], - total: { formatted_amount: 5000, amount: 5000, date: '2020-06-30' } - }); - }); - - it('Should retrieve the balance sheet with display columns `quarter`.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'quarter', - display_columns_type: 'date_periods', - from_date: '2020-01-01', - to_date: '2020-12-31', - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: debitAccount.id, - index: debitAccount.index, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - children: [], - total_periods: [ - { date: '2020-03', formatted_amount: 5000, amount: 5000 }, - { date: '2020-06', formatted_amount: 5000, amount: 5000 }, - { date: '2020-09', formatted_amount: 5000, amount: 5000 }, - { date: '2020-12', formatted_amount: 5000, amount: 5000 }, - ], - total: { formatted_amount: 5000, amount: 5000, date: '2020-12-31' }, - }); - }); - - it('Should retrieve the balance sheet amounts without cents.', async () => { - await tenantFactory.create('account_transaction', { - debit: 0.25, credit: 0, account_id: debitAccount.id, date: '2020-1-10', - }); - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'quarter', - display_columns_type: 'date_periods', - from_date: '2020-01-01', - to_date: '2020-12-31', - number_format: { - no_cents: true, - }, - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: debitAccount.id, - index: debitAccount.index, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - children: [], - total_periods: [ - { date: '2020-03', formatted_amount: 5000, amount: 5000.25 }, - { date: '2020-06', formatted_amount: 5000, amount: 5000.25 }, - { date: '2020-09', formatted_amount: 5000, amount: 5000.25 }, - { date: '2020-12', formatted_amount: 5000, amount: 5000.25 }, - ], - total: { formatted_amount: 5000, amount: 5000.25, date: '2020-12-31' }, - }); - }); - - it('Should retrieve the balance sheet amounts divided on 1000.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'quarter', - display_columns_type: 'date_periods', - from_date: '2020', - to_date: '2021', - number_format: { - divide_1000: true, - }, - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: debitAccount.id, - index: debitAccount.index, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - children: [], - total_periods: [ - { date: '2020-03', formatted_amount: 5, amount: 5000 }, - { date: '2020-06', formatted_amount: 5, amount: 5000 }, - { date: '2020-09', formatted_amount: 5, amount: 5000 }, - { date: '2020-12', formatted_amount: 5, amount: 5000 }, - { date: '2021-03', formatted_amount: 5, amount: 5000 }, - ], - total: { formatted_amount: 5, amount: 5000, date: '2021' }, - }); - }); - - it('Should not retrieve accounts has no transactions between the given date range in case query none_zero is true.', async () => { - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - display_columns_by: 'quarter', - from_date: '2002', - to_date: '2003', - number_format: { - divide_1000: true, - }, - none_zero: true, - }) - .send(); - - expect(res.body.accounts[0].children.length).equals(0); - expect(res.body.accounts[1].children.length).equals(0); - }); - - it('Should retrieve accounts in nested structure parent and children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: debitAccount.id, - account_type_id: 1 - }); - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - none_zero: false, - account_ids: [childAccount.id, debitAccount.id] - }) - .send(); - - expect(res.body.accounts[0].children).include.something.deep.equals({ - id: debitAccount.id, - index: null, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - total: { formatted_amount: 5000, amount: 5000, date: '2020-12-31' }, - children: [ - { - id: childAccount.id, - index: null, - name: childAccount.name, - code: childAccount.code, - parentAccountId: debitAccount.id, - total: { formatted_amount: 0, amount: 0, date: '2020-12-31' }, - children: [], - } - ] - }); - }); - - it('Should parent account balance sumation of total balane all children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: debitAccount.id, - account_type_id: 1 - }); - await tenantFactory.create('account_transaction', { - credit: 0, debit: 1000, account_id: childAccount.id, date: '2020-1-10' - }); - - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - none_zero: false, - account_ids: [childAccount.id, debitAccount.id] - }) - .send(); - - expect(res.body.accounts[0].children[0].total.amount).equals(6000); - expect(res.body.accounts[0].children[0].total.formatted_amount).equals(6000); - }); - - it('Should parent account balance sumation of total periods amounts all children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: debitAccount.id, - account_type_id: 1 - }); - await tenantFactory.create('account_transaction', { - credit: 0, debit: 1000, account_id: childAccount.id, date: '2020-2-10' - }); - - const res = await request() - .get('/api/financial_statements/balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - none_zero: false, - account_ids: [childAccount.id, debitAccount.id], - display_columns_type: 'date_periods', - display_columns_by: 'month', - from_date: '2020-01-01', - to_date: '2020-12-12', - }) - .send(); - - expect(res.body.accounts[0].children[0].total_periods).deep.equals([ - { amount: 5000, formatted_amount: 5000, date: '2020-01' }, - { amount: 6000, formatted_amount: 6000, date: '2020-02' }, - { amount: 6000, formatted_amount: 6000, date: '2020-03' }, - { amount: 6000, formatted_amount: 6000, date: '2020-04' }, - { amount: 6000, formatted_amount: 6000, date: '2020-05' }, - { amount: 6000, formatted_amount: 6000, date: '2020-06' }, - { amount: 6000, formatted_amount: 6000, date: '2020-07' }, - { amount: 6000, formatted_amount: 6000, date: '2020-08' }, - { amount: 6000, formatted_amount: 6000, date: '2020-09' }, - { amount: 6000, formatted_amount: 6000, date: '2020-10' }, - { amount: 6000, formatted_amount: 6000, date: '2020-11' }, - { amount: 6000, formatted_amount: 6000, date: '2020-12' } - ]) - }); - }); -}); diff --git a/packages/server/tests/routes/bill_payments.test.js b/packages/server/tests/routes/bill_payments.test.js deleted file mode 100644 index 5c7440125..000000000 --- a/packages/server/tests/routes/bill_payments.test.js +++ /dev/null @@ -1,113 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - -describe('route: `/api/purchases/bill_payments`', () => { - describe('POST: `/api/purchases/bill_payments`', () => { - it('Should `payment_date` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'payment_date', - location: 'body', - }); - }); - - it('Should `payment_account_id` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'payment_account_id', - location: 'body', - }); - }); - - it('Should `payment_number` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'payment_number', - location: 'body', - }); - }); - - it('Should `entries.*.item_id` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].item_id', - location: 'body', - }); - }); - - it('Should `payment_number` be unique on the storage.', () => { - - }); - - it('Should `payment_account_id` be exists on the storage.', () => { - - }); - - it('Should `entries.*.item_id` be exists on the storage.', () => { - - }); - - it('Should store the given bill payment to the storage.', () => { - - }); - }); - - describe('POST: `/api/purchases/bill_payments/:id`', () => { - it('Should bill payment be exists on the storage.', () => { - - }); - }); - - describe('DELETE: `/api/purchases/bill_payments/:id`', () => { - it('Should bill payment be exists on the storage.', () => { - - }); - - it('Should delete the given bill payment from the storage.', () => { - - }); - }); - - describe('GET: `/api/purchases/bill_payments/:id`', () => { - it('Should bill payment be exists on the storage.', () => { - - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/bills.test.js b/packages/server/tests/routes/bills.test.js deleted file mode 100644 index 5ace5cec2..000000000 --- a/packages/server/tests/routes/bills.test.js +++ /dev/null @@ -1,217 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - -describe('route: `/api/purchases/bills`', () => { - describe('POST: `/api/purchases/bills`', () => { - it('Should `bill_number` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'bill_number', - location: 'body', - }); - }); - - it('Should `vendor_id` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'vendor_id', - location: 'body', - }); - }); - - it('Should `bill_date` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'bill_date', - location: 'body', - }); - }); - - it('Should `entries` be minimum one', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries', - location: 'body', - }); - }); - - it('Should `entries.*.item_id be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{ - - }] - }); - expect(res.status).equals(422); - expecvt(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].item_id', - location: 'body' - }); - }); - - it('Should `entries.*.rate` be required.', async () => { - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{ - - }] - }); - expect(res.status).equals(422); - expecvt(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].rate', - location: 'body' - }); - }); - - it('Should `entries.*.discount` be required.', () => { - - }); - - it('Should entries.*.quantity be required.', () => { - - }); - - - it('Should vendor_id be exists on the storage.', async () => { - const vendor = await tenantFactory.create('vendor'); - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - vendor_id: vendor.id, - bill_number: '123', - bill_date: '2020-02-02', - entries: [{ - item_id: 1, - rate: 1, - quantity: 1, - }] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'VENDOR.ID.NOT.FOUND', code: 300, - }) - }); - - it('Should entries.*.item_id be exists on the storage.', async () => { - const item = await tenantFactory.create('item'); - const vendor = await tenantFactory.create('vendor'); - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - vendor_id: vendor.id, - bill_number: '123', - bill_date: '2020-02-02', - entries: [{ - item_id: 123123, - rate: 1, - quantity: 1, - }] - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEMS.IDS.NOT.FOUND', code: 400, - }); - }); - - it('Should validate the bill number is not exists on the storage.', async () => { - const item = await tenantFactory.create('item'); - const vendor = await tenantFactory.create('vendor'); - const bill = await tenantFactory.create('bill', { bill_number: '123' }); - - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - vendor_id: vendor.id, - bill_number: '123', - bill_date: '2020-02-02', - entries: [{ - item_id: item.id, - rate: 1, - quantity: 1, - }] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'BILL.NUMBER.EXISTS', code: 500, - }) - }) - - it('Should store the given bill details with associated entries to the storage.', async () => { - const item = await tenantFactory.create('item'); - const vendor = await tenantFactory.create('vendor'); - const res = await request() - .post('/api/purchases/bills') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - vendor_id: vendor.id, - bill_number: '123', - bill_date: '2020-02-02', - entries: [{ - item_id: item.id, - rate: 1, - quantity: 1, - }] - }); - - expect(res.status).equals(200); - }); - - - }); - - describe('DELETE: `/api/purchases/bills/:id`', () => { - - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/currencies.test.js b/packages/server/tests/routes/currencies.test.js deleted file mode 100644 index a6583c0cd..000000000 --- a/packages/server/tests/routes/currencies.test.js +++ /dev/null @@ -1,191 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Currency from 'models/Currency'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('route: /currencies/', () => { - describe('POST: `/api/currencies`', () => { - it('Should response unauthorized in case user was not logged in.', async () => { - const res = await request() - .post('/api/currencies') - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `currency_name` be required.', async () => { - const res = await request() - .post('/api/currencies') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'currency_name', location: 'body', - }); - }); - - it('Should `currency_code` be required.', async () => { - const res = await request() - .post('/api/currencies') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'currency_code', location: 'body', - }); - }); - - it('Should response currency code is duplicated.', async () => { - tenantFactory.create('currency', { currency_code: 'USD' }); - - const res = await request() - .post('/api/currencies') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - currency_code: 'USD', - currency_name: 'Dollar', - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CURRENCY.CODE.ALREADY.EXISTS', code: 100, - }); - }); - - it('Should insert currency details to the storage.', async () => { - const res = await request() - .post('/api/currencies') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - currency_code: 'USD', - currency_name: 'Dollar', - }); - - const foundCurrency = await Currency.tenant().query().where('currency_code', 'USD'); - - expect(foundCurrency.length).equals(1); - expect(foundCurrency[0].currencyCode).equals('USD'); - expect(foundCurrency[0].currencyName).equals('Dollar'); - }); - - it('Should response success with correct data.', async () => { - const res = await request() - .post('/api/currencies') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - currency_code: 'USD', - currency_name: 'Dollar', - }); - - expect(res.status).equals(200); - }); - }); - - describe('DELETE: `/api/currencies/:currency_code`', () => { - it('Should delete the given currency code from the storage.', async () => { - const currency = await tenantFactory.create('currency'); - const res = await request() - .delete(`/api/currencies/${currency.currencyCode}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - - const foundCurrency = await Currency.tenant().query().where('currency_code', 'USD'); - expect(foundCurrency.length).equals(0); - }); - }); - - describe('POST: `/api/currencies/:id`', () => { - it('Should `currency_name` be required.', async () => { - const currency = await tenantFactory.create('currency'); - const res = await request() - .post(`/api/currencies/${currency.code}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'currency_name', location: 'body', - }); - }); - - it('Should `currency_code` be required.', async () => { - const currency = await tenantFactory.create('currency'); - const res = await request() - .post(`/api/currencies/${currency.code}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'currency_code', location: 'body', - }); - }); - - it('Should response currency code is duplicated.', async () => { - const currency1 = await tenantFactory.create('currency'); - const currency2 = await tenantFactory.create('currency'); - - const res = await request() - .post(`/api/currencies/${currency2.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - currency_code: currency1.currencyCode, - currency_name: 'Dollar', - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CURRENCY.CODE.ALREADY.EXISTS', code: 100, - }); - }); - - it('Should update currency details of the given currency on the storage.', async () => { - const currency1 = await tenantFactory.create('currency'); - const currency2 = await tenantFactory.create('currency'); - - const res = await request() - .post(`/api/currencies/${currency2.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - currency_code: 'ABC', - currency_name: 'Name', - }); - - const foundCurrency = await Currency.tenant().query().where('currency_code', 'ABC'); - - expect(foundCurrency.length).equals(1); - expect(foundCurrency[0].currencyCode).equals('ABC'); - expect(foundCurrency[0].currencyName).equals('Name'); - }); - - it('Should response success with correct data.', () => { - - }); - }) -}); diff --git a/packages/server/tests/routes/customers.test.js b/packages/server/tests/routes/customers.test.js deleted file mode 100644 index 2a3eb327d..000000000 --- a/packages/server/tests/routes/customers.test.js +++ /dev/null @@ -1,250 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Currency from 'models/Currency'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import Customer from '../../src/models/Customer'; - -describe('route: `/customers`', () => { - describe('POST: `/customers`', () => { - it('Should response unauthorized in case the user was not logged in.', async () => { - const res = await request() - .post('/api/customers') - .send({}); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `display_name` be required field.', async () => { - const res = await request() - .post('/api/customers') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'display_name', location: 'body', - }) - }); - - it('Should `customer_type` be required field', async () => { - const res = await request() - .post('/api/customers') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'customer_type', location: 'body', - }); - }); - - it('Should store the customer data to the storage.', async () => { - const res = await request() - .post('/api/customers') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_type: 'business', - - first_name: 'Ahmed', - last_name: 'Bouhuolia', - - company_name: 'Bigcapital', - - display_name: 'Ahmed Bouhuolia, Bigcapital', - - email: 'a.bouhuolia@live.com', - work_phone: '0927918381', - personal_phone: '0925173379', - - billing_address_city: 'Tripoli', - billing_address_country: 'Libya', - billing_address_email: 'a.bouhuolia@live.com', - billing_address_state: 'State Tripoli', - billing_address_zipcode: '21892', - - shipping_address_city: 'Tripoli', - shipping_address_country: 'Libya', - shipping_address_email: 'a.bouhuolia@live.com', - shipping_address_state: 'State Tripoli', - shipping_address_zipcode: '21892', - - note: '__desc__', - - active: true, - }); - - expect(res.status).equals(200); - - const foundCustomer = await Customer.tenant().query().where('id', res.body.id); - - expect(foundCustomer[0].customerType).equals('business'); - expect(foundCustomer[0].firstName).equals('Ahmed'); - expect(foundCustomer[0].lastName).equals('Bouhuolia'); - expect(foundCustomer[0].companyName).equals('Bigcapital'); - expect(foundCustomer[0].displayName).equals('Ahmed Bouhuolia, Bigcapital'); - - expect(foundCustomer[0].email).equals('a.bouhuolia@live.com'); - - expect(foundCustomer[0].workPhone).equals('0927918381'); - expect(foundCustomer[0].personalPhone).equals('0925173379'); - - expect(foundCustomer[0].billingAddressCity).equals('Tripoli'); - expect(foundCustomer[0].billingAddressCountry).equals('Libya'); - expect(foundCustomer[0].billingAddressEmail).equals('a.bouhuolia@live.com'); - expect(foundCustomer[0].billingAddressState).equals('State Tripoli'); - expect(foundCustomer[0].billingAddressZipcode).equals('21892'); - - expect(foundCustomer[0].shippingAddressCity).equals('Tripoli'); - expect(foundCustomer[0].shippingAddressCountry).equals('Libya'); - expect(foundCustomer[0].shippingAddressEmail).equals('a.bouhuolia@live.com'); - expect(foundCustomer[0].shippingAddressState).equals('State Tripoli'); - expect(foundCustomer[0].shippingAddressZipcode).equals('21892'); - }); - }); - - describe('GET: `/customers/:id`', () => { - it('Should response not found in case the given customer id was not exists on the storage.', async () => { - const res = await request() - .get('/api/customers/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.NOT.FOUND', code: 200, - }); - }); - }); - - describe('GET: `customers`', () => { - it('Should response customers items', async () => { - await tenantFactory.create('customer'); - await tenantFactory.create('customer'); - - const res = await request() - .get('/api/customers') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.customers.results.length).equals(2); - }); - }); - - describe('DELETE: `/customers/:id`', () => { - it('Should response not found in case the given customer id was not exists on the storage.', async () => { - const res = await request() - .delete('/api/customers/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given customer from the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const res = await request() - .delete(`/api/customers/${customer.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - - const foundCustomer = await Customer.tenant().query().where('id', customer.id); - expect(foundCustomer.length).equals(0); - }) - }); - - describe('POST: `/customers/:id`', () => { - it('Should response customer not found', async () => { - const res = await request() - .post('/api/customers/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_type: 'business', - display_name: 'Ahmed Bouhuolia, Bigcapital', - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.NOT.FOUND', code: 200, - }); - }); - - it('Should update details of the given customer.', async () => { - const customer = await tenantFactory.create('customer'); - const res = await request() - .post(`/api/customers/${customer.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_type: 'business', - display_name: 'Ahmed Bouhuolia, Bigcapital', - }); - - expect(res.status).equals(200); - const foundCustomer = await Customer.tenant().query().where('id', res.body.id); - - expect(foundCustomer.length).equals(1); - expect(foundCustomer[0].customerType).equals('business'); - expect(foundCustomer[0].displayName).equals('Ahmed Bouhuolia, Bigcapital'); - }) - }); - - describe('DELETE: `customers`', () => { - it('Should response customers ids not found.', async () => { - const res = await request() - .delete('/api/customers') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [100, 200], - }) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMERS.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given customers.', async () => { - const customer1 = await tenantFactory.create('customer'); - const customer2 = await tenantFactory.create('customer'); - - const res = await request() - .delete('/api/customers') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [customer1.id, customer2.id], - }) - .send(); - - const foundCustomers = await Customer.tenant().query() - .whereIn('id', [customer1.id, customer2.id]); - - expect(res.status).equals(200); - expect(foundCustomers.length).equals(0); - }); - }) -}); diff --git a/packages/server/tests/routes/exchange_rates.test.js b/packages/server/tests/routes/exchange_rates.test.js deleted file mode 100644 index c655ab316..000000000 --- a/packages/server/tests/routes/exchange_rates.test.js +++ /dev/null @@ -1,230 +0,0 @@ -import moment from 'moment'; -import { - request, - expect, -} from '~/testInit'; -import ExchangeRate from '../../src/models/ExchangeRate'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('route: /exchange_rates/', () => { - describe('POST: `/api/exchange_rates`', () => { - it('Should response unauthorized in case the user was not logged in.', async () => { - const res = await request() - .post('/api/exchange_rates') - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `currency_code` be required.', async () => { - const res = await request() - .post('/api/exchange_rates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'currency_code', location: 'body', - }); - }); - - it('Should `exchange_rate` be required.', async () => { - const res = await request() - .post('/api/exchange_rates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'exchange_rate', location: 'body', - }); - }); - - it('Should date be required', async () => { - const res = await request() - .post('/api/exchange_rates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'date', location: 'body', - }); - }); - - it('Should response date and currency code is already exists.', async () => { - await tenantFactory.create('exchange_rate', { - date: '2020-02-02', - currency_code: 'USD', - exchange_rate: 4.4, - }); - const res = await request() - .post('/api/exchange_rates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: '2020-02-02', - currency_code: 'USD', - exchange_rate: 4.4, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXCHANGE.RATE.DATE.PERIOD.DEFINED', code: 200, - }); - }); - - it('Should save the given exchange rate to the storage.', async () => { - const res = await request() - .post('/api/exchange_rates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: '2020-02-02', - currency_code: 'USD', - exchange_rate: 4.4, - }); - expect(res.status).equals(200); - - const foundExchangeRate = await ExchangeRate.tenant().query() - .where('currency_code', 'USD'); - - expect(foundExchangeRate.length).equals(1); - expect( - moment(foundExchangeRate[0].date).format('YYYY-MM-DD'), - ).equals('2020-02-02'); - expect(foundExchangeRate[0].currencyCode).equals('USD'); - expect(foundExchangeRate[0].exchangeRate).equals(4.4); - }); - }); - - describe('GET: `/api/exchange_rates', () => { - it('Should retrieve all exchange rates with pagination meta.', async () => { - await tenantFactory.create('exchange_rate'); - await tenantFactory.create('exchange_rate'); - await tenantFactory.create('exchange_rate'); - - const res = await request() - .get('/api/exchange_rates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - expect(res.body.exchange_rates.results.length).equals(3); - }); - }); - - describe('POST: `/api/exchange_rates/:id`', () => { - it('Should response the given exchange rate not found.', async () => { - const res = await request() - .post('/api/exchange_rates/100') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - date: '2020-02-02', - currency_code: 'USD', - exchange_rate: 4.4, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXCHANGE.RATE.NOT.FOUND', code: 200, - }); - }); - - it('Should update exchange rate of the given id on the storage.', async () => { - const exRate = await tenantFactory.create('exchange_rate'); - const res = await request() - .post(`/api/exchange_rates/${exRate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - exchange_rate: 4.4, - }); - expect(res.status).equals(200); - - const foundExchangeRate = await ExchangeRate.tenant().query() - .where('id', exRate.id); - - expect(foundExchangeRate.length).equals(1); - expect(foundExchangeRate[0].exchangeRate).equals(4.4); - }); - }); - - describe('DELETE: `/api/exchange_rates/:id`', () => { - it('Should response the given exchange rate id not found.', async () => { - const res = await request() - .delete('/api/exchange_rates/100') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXCHANGE.RATE.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given exchange rate id from the storage.', async () => { - const exRate = await tenantFactory.create('exchange_rate'); - const res = await request() - .delete(`/api/exchange_rates/${exRate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundRates = await ExchangeRate.tenant().query(); - expect(foundRates.length).equals(0); - }); - }); - - describe('DELETE: `/api/exchange_rates/bulk`', () => { - it('Should response the given exchange rates ids where not found.', async () => { - const res = await request() - .delete('/api/exchange_rates/bulk') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [12332, 32432], - }) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXCHANGE.RATES.IS.NOT.FOUND', code: 200, ids: [12332, 32432], - }) - }); - - it('Should delete the given excahnge rates ids.', async () => { - const exRate = await tenantFactory.create('exchange_rate'); - const exRate2 = await tenantFactory.create('exchange_rate'); - - const res = await request() - .delete('/api/exchange_rates/bulk') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [exRate.id, exRate2.id], - }) - .send(); - - const foundExchangeRate = await ExchangeRate.tenant().query() - .whereIn('id', [exRate.id, exRate2.id]); - - expect(foundExchangeRate.length).equals(0); - }) - }); -}); diff --git a/packages/server/tests/routes/expenses.test.js b/packages/server/tests/routes/expenses.test.js deleted file mode 100644 index 17a4c4ac9..000000000 --- a/packages/server/tests/routes/expenses.test.js +++ /dev/null @@ -1,739 +0,0 @@ -import moment from 'moment'; -import { pick } from 'lodash'; -import { - request, - expect, -} from '~/testInit'; -import Expense from 'models/Expense'; -import ExpenseCategory from 'models/ExpenseCategory'; -import AccountTransaction from 'models/AccountTransaction'; -import { - tenantWebsite, - tenantFactory, - loginRes, -} from '~/dbInit'; - -describe('routes: /expenses/', () => { - describe('POST `/expenses`', () => { - it('Should retrieve unauthorized access if the user was not authorized.', async () => { - const res = await request() - .post('/api/expenses') - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should categories total not be equals zero.', async () => { - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - payment_date: moment().format('YYYY-MM-DD'), - reference_no: '', - payment_account_id: 0, - description: '', - publish: 1, - categories: [ - { - index: 1, - expense_account_id: 33, - amount: 1000, - description: '', - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXPENSE.ACCOUNTS.IDS.NOT.STORED', code: 400, ids: [33] - }); - }); - - it('Should expense accounts ids be stored in the storage.', async () => { - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - payment_date: moment().format('YYYY-MM-DD'), - reference_no: '', - payment_account_id: 0, - description: '', - publish: 1, - categories: [ - { - index: 1, - expense_account_id: 22, - amount: 1000, - description: '', - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXPENSE.ACCOUNTS.IDS.NOT.STORED', code: 400, ids: [22], - }); - }); - - it('Should `payment_account_id` be in the storage.', async () => { - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - payment_date: moment().format('YYYY-MM-DD'), - reference_no: '', - payment_account_id: 22, - description: '', - publish: 1, - categories: [ - { - index: 1, - expense_account_id: 22, - amount: 1000, - description: '', - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'PAYMENT.ACCOUNT.NOT.FOUND', code: 500, - }); - }); - - it('Should payment_account be required.', async () => { - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - }); - - it('Should `categories.*.expense_account_id` be required.', async () => { - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - - }); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'payment_account_id', location: 'body' - }); - }); - - it('Should expense transactions be stored on the storage.', async () => { - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - payment_date: moment().format('YYYY-MM-DD'), - reference_no: 'ABC', - payment_account_id: paymentAccount.id, - description: 'desc', - publish: 1, - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 1000, - description: '', - }, - ], - }); - - const foundExpense = await Expense.tenant().query().where('id', res.body.id); - - expect(foundExpense.length).equals(1); - expect(foundExpense[0].referenceNo).equals('ABC'); - expect(foundExpense[0].paymentAccountId).equals(paymentAccount.id); - expect(foundExpense[0].description).equals('desc'); - expect(foundExpense[0].totalAmount).equals(1000); - }); - - it('Should expense categories transactions be stored on the storage.', async () => { - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - payment_date: moment().format('YYYY-MM-DD'), - reference_no: 'ABC', - payment_account_id: paymentAccount.id, - description: 'desc', - publish: 1, - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 1000, - description: 'category desc', - }, - ], - }); - - const foundCategories = await ExpenseCategory.tenant().query().where('id', res.body.id); - - expect(foundCategories.length).equals(1); - expect(foundCategories[0].index).equals(1); - expect(foundCategories[0].expenseAccountId).equals(expenseAccount.id); - expect(foundCategories[0].amount).equals(1000); - expect(foundCategories[0].description).equals('category desc'); - }); - - it('Should save journal entries that associate to the expense transaction.', async () => { - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - payment_date: moment().format('YYYY-MM-DD'), - reference_no: 'ABC', - payment_account_id: paymentAccount.id, - description: 'desc', - publish: 1, - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 1000, - description: 'category desc', - }, - ], - }); - - const transactions = await AccountTransaction.tenant().query() - .where('reference_id', res.body.id) - .where('reference_type', 'Expense'); - - const mappedTransactions = transactions.map(tr => ({ - ...pick(tr, ['credit', 'debit', 'referenceId', 'referenceType']), - })); - - expect(mappedTransactions[0]).deep.equals({ - credit: 1000, - debit: 0, - referenceType: 'Expense', - referenceId: res.body.id, - }); - expect(mappedTransactions[1]).deep.equals({ - credit: 0, - debit: 1000, - referenceType: 'Expense', - referenceId: res.body.id, - }); - expect(transactions.length).equals(2); - }) - }); - - describe('GET: `/expenses`', () => { - it('Should response unauthorized if the user was not logged in.', async () => { - const res = await request() - .post('/api/expenses') - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should retrieve expenses with pagination meta.', async () => { - await tenantFactory.create('expense'); - await tenantFactory.create('expense'); - - const res = await request() - .get('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.expenses).that.is.an('object'); - expect(res.body.expenses.results).that.is.an('array'); - }); - - it('Should retrieve expenses based on view roles conditions of the custom view.', () => { - - }); - - it('Should sort expenses based on the given `column_sort_order` column on ASC direction.', () => { - - }); - }); - - describe('DELETE: `/expenses/:id`', () => { - it('Should response unauthorized if the user was not logged in.', async () => { - const res = await request() - .delete('/api/expenses') - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response not found in case expense id was not exists on the storage.', async () => { - const res = await request() - .delete('/api/expenses/123321') - .set('organization-id', tenantWebsite.organizationId) - .set('x-access-token', loginRes.body.token) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXPENSE.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given expense transactions with associated categories.', async () => { - const expense = await tenantFactory.create('expense'); - - const res = await request() - .delete(`/api/expenses/${expense.id}`) - .set('organization-id', tenantWebsite.organizationId) - .set('x-access-token', loginRes.body.token) - .send(); - - expect(res.status).equals(200); - - const storedExpense = await Expense.tenant().query().where('id', expense.id); - const storedExpenseCategories = await ExpenseCategory.tenant().query().where('expense_id', expense.id); - - expect(storedExpense.length).equals(0); - expect(storedExpenseCategories.length).equals(0); - }); - - it('Should delete all journal entries that associated to the given expense.', async () => { - const expense = await tenantFactory.create('expense'); - - const trans = { reference_id: expense.id, reference_type: 'Expense' }; - await tenantFactory.create('account_transaction', trans); - await tenantFactory.create('account_transaction', trans); - - const res = await request() - .delete(`/api/expenses/${expense.id}`) - .set('organization-id', tenantWebsite.organizationId) - .set('x-access-token', loginRes.body.token) - .send(); - - const foundTransactions = await AccountTransaction.tenant().query() - .where('reference_type', 'Expense') - .where('reference_id', expense.id); - - expect(foundTransactions.length).equals(0); - }); - }); - - describe('GET: `/expenses/:id`', () => { - it('Should response unauthorized if the user was not logged in.', async () => { - const res = await request() - .get('/api/expenses/123') - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response not found in case the given expense id was not exists in the storage.', async () => { - const res = await request() - .get(`/api/expenses/321`) - .set('organization-id', tenantWebsite.organizationId) - .set('x-access-token', loginRes.body.token) - .send(); - - expect(res.status).equals(404); - }); - - it('Should retrieve expense metadata and associated expense categories.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseCategory = await tenantFactory.create('expense_category', { - expense_id: expense.id, - }) - const res = await request() - .get(`/api/expenses/${expense.id}`) - .set('organization-id', tenantWebsite.organizationId) - .set('x-access-token', loginRes.body.token) - .send(); - - expect(res.status).equals(200); - - expect(res.body.expense.id).is.a('number'); - expect(res.body.expense.paymentAccountId).is.a('number'); - expect(res.body.expense.totalAmount).is.a('number'); - expect(res.body.expense.userId).is.a('number'); - expect(res.body.expense.referenceNo).is.a('string'); - expect(res.body.expense.description).is.a('string'); - expect(res.body.expense.categories).is.a('array'); - - expect(res.body.expense.categories[0].id).is.a('number'); - expect(res.body.expense.categories[0].description).is.a('string'); - expect(res.body.expense.categories[0].expenseAccountId).is.a('number'); - }); - - it('Should retrieve journal entries with expense metadata.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseCategory = await tenantFactory.create('expense_category', { - expense_id: expense.id, - }); - const trans = { reference_id: expense.id, reference_type: 'Expense' }; - await tenantFactory.create('account_transaction', trans); - await tenantFactory.create('account_transaction', trans); - - const res = await request() - .get(`/api/expenses/${expense.id}`) - .set('organization-id', tenantWebsite.organizationId) - .set('x-access-token', loginRes.body.token) - .send(); - - expect(res.body.expense.journalEntries).is.an('array'); - expect(res.body.expense.journalEntries.length).equals(2); - }); - }); - - describe('POST: `expenses/:id`', () => { - it('Should response unauthorized in case the user was not logged in.', async () => { - const expense = await tenantFactory.create('expense'); - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response the given expense id not exists on the storage.', async () => { - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post('/api/expenses/1233') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment().format('YYYY-MM-DD'), - payment_account_id: 321, - publish: true, - categories: [ - { - expense_account_id: expenseAccount.id, - index: 1, - amount: 1000, - description: '', - }, - ], - }); - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXPENSE.NOT.FOUND', code: 200, - }); - }); - - it('Should response the given `payment_account_id` not exists.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment().format('YYYY-MM-DD'), - payment_account_id: 321, - publish: true, - categories: [ - { - expense_account_id: expenseAccount.id, - index: 1, - amount: 1000, - description: '', - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'PAYMENT.ACCOUNT.NOT.FOUND', code: 400, - }); - }); - - it('Should response the given `categories.*.expense_account_id` not exists.', async () => { - const paymentAccount = await tenantFactory.create('account'); - const expense = await tenantFactory.create('expense'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment().format('YYYY-MM-DD'), - payment_account_id: paymentAccount.id, - publish: true, - categories: [ - { - index: 1, - expense_account_id: 100, - amount: 1000, - description: '', - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXPENSE.ACCOUNTS.IDS.NOT.FOUND', code: 600, ids: [100], - }); - }); - - it('Should response the total amount equals zero.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseAccount = await tenantFactory.create('account'); - const paymentAccount = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment().format('YYYY-MM-DD'), - payment_account_id: paymentAccount.id, - publish: true, - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 0, - description: '', - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'TOTAL.AMOUNT.EQUALS.ZERO', code: 500, - }); - }); - - it('Should update the expense transaction.', async () => { - const expense = await tenantFactory.create('expense'); - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment('2009-01-02').format('YYYY-MM-DD'), - payment_account_id: paymentAccount.id, - publish: true, - description: 'Updated description', - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 3000, - description: '', - }, - ], - }); - expect(res.status).equals(200); - - const updatedExpense = await Expense.tenant().query() - .where('id', expense.id).first(); - - expect(updatedExpense.id).equals(expense.id); - expect(updatedExpense.referenceNo).equals('123'); - expect(updatedExpense.description).equals('Updated description'); - expect(updatedExpense.totalAmount).equals(3000); - expect(updatedExpense.paymentAccountId).equals(paymentAccount.id); - }); - - it('Should delete the expense categories that associated to the expense transaction.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseCategory = await tenantFactory.create('expense_category', { - expense_id: expense.id, - }); - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment('2009-01-02').format('YYYY-MM-DD'), - payment_account_id: paymentAccount.id, - publish: true, - description: 'Updated description', - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 3000, - description: '', - }, - ], - }); - - const foundExpenseCategories = await ExpenseCategory.tenant() - .query().where('id', expenseCategory.id) - - expect(foundExpenseCategories.length).equals(0); - }); - - it('Should insert the expense categories to associated to the expense transaction.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseCategory = await tenantFactory.create('expense_category', { - expense_id: expense.id, - }); - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment('2009-01-02').format('YYYY-MM-DD'), - payment_account_id: paymentAccount.id, - publish: true, - description: 'Updated description', - categories: [ - { - index: 1, - expense_account_id: expenseAccount.id, - amount: 3000, - description: '__desc__', - }, - ], - }); - - const foundExpenseCategories = await ExpenseCategory.tenant() - .query() - .where('expense_id', expense.id) - - expect(foundExpenseCategories.length).equals(1); - expect(foundExpenseCategories[0].id).not.equals(expenseCategory.id); - }); - - it('Should update the expense categories that associated to the expense transactions.', async () => { - const expense = await tenantFactory.create('expense'); - const expenseCategory = await tenantFactory.create('expense_category', { - expense_id: expense.id, - }); - const paymentAccount = await tenantFactory.create('account'); - const expenseAccount = await tenantFactory.create('account'); - - const res = await request() - .post(`/api/expenses/${expense.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - reference_no: '123', - payment_date: moment('2009-01-02').format('YYYY-MM-DD'), - payment_account_id: paymentAccount.id, - publish: true, - description: 'Updated description', - categories: [ - { - id: expenseCategory.id, - index: 1, - expense_account_id: expenseAccount.id, - amount: 3000, - description: '__desc__', - }, - ], - }); - - const foundExpenseCategory = await ExpenseCategory.tenant().query() - .where('id', expenseCategory.id); - - expect(foundExpenseCategory.length).equals(1); - expect(foundExpenseCategory[0].expenseAccountId).equals(expenseAccount.id); - expect(foundExpenseCategory[0].description).equals('__desc__'); - expect(foundExpenseCategory[0].amount).equals(3000); - }); - }); - - describe('DELETE: `/api/expenses`', () => { - it('Should response not found expenses ids.', async () => { - const res = await request() - .delete('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [100, 200], - }) - .send({}); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'EXPENSES.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given expenses ids.', async () => { - const expense1 = await tenantFactory.create('expense'); - const expense2 = await tenantFactory.create('expense'); - - const res = await request() - .delete('/api/expenses') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [expense1.id, expense2.id], - }) - .send({}); - - const foundExpenses = await Expense.tenant().query() - .whereIn('id', [expense1.id, expense2.id]); - - expect(res.status).equals(200); - expect(foundExpenses.length).equals(0); - }) - }); - - describe('POST: `/api/expenses/:id/publish`', () => { - it('Should publish the given expense.', async () => { - const expense = await tenantFactory.create('expense', { - published: 0, - }); - - const res = await request() - .post(`/api/expenses/${expense.id}/publish`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundExpense = await Expense.tenant().query() - .where('id', expense.id).first(); - - expect(res.status).equals(200); - expect(foundExpense.published).equals(1); - }); - }); -}); diff --git a/packages/server/tests/routes/financial_statements.test.js b/packages/server/tests/routes/financial_statements.test.js deleted file mode 100644 index e7a0893e1..000000000 --- a/packages/server/tests/routes/financial_statements.test.js +++ /dev/null @@ -1,956 +0,0 @@ -import moment from 'moment'; -import { - request, - expect, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import { iteratee } from 'lodash'; - -let creditAccount; -let debitAccount; -let incomeAccount; -let incomeType; - -describe('routes: `/financial_statements`', () => { - beforeEach(async () => { - // Balance sheet types. - const assetType = await tenantFactory.create('account_type', { normal: 'debit', balance_sheet: true }); - const liabilityType = await tenantFactory.create('account_type', { normal: 'credit', balance_sheet: true }); - - // Income statement types. - incomeType = await tenantFactory.create('account_type', { normal: 'credit', income_sheet: true }); - const expenseType = await tenantFactory.create('account_type', { normal: 'debit', income_sheet: true }); - - // Assets & liabilites accounts. - creditAccount = await tenantFactory.create('account', { account_type_id: liabilityType.id }); - debitAccount = await tenantFactory.create('account', { account_type_id: assetType.id }); - - // Income && expenses accounts. - incomeAccount = await tenantFactory.create('account', { account_type_id: incomeType.id }); - const expenseAccount = await tenantFactory.create('account', { account_type_id: expenseType.id }); - // const income2Account = await tenantFactory.create('account', { account_type_id: incomeType.id }); - - const accountTransactionMixied = { date: '2020-1-10' }; - - // Expense -- - // 1000 Credit - Credit account - // 1000 Debit - expense account. - await tenantFactory.create('account_transaction', { - credit: 1000, debit: 0, account_id: debitAccount.id, referenceType: 'Expense', - referenceId: 1, ...accountTransactionMixied, - }); - await tenantFactory.create('account_transaction', { - credit: 0, debit: 1000, account_id: expenseAccount.id, referenceType: 'Expense', - referenceId: 1, ...accountTransactionMixied, - }); - - // Jounral - // 4000 Credit - liability account. - // 2000 Debit - Asset account - // 2000 Debit - Asset account - await tenantFactory.create('account_transaction', { - credit: 4000, debit: 0, account_id: creditAccount.id, ...accountTransactionMixied, - }); - await tenantFactory.create('account_transaction', { - debit: 2000, credit: 0, account_id: debitAccount.id, ...accountTransactionMixied, - }); - await tenantFactory.create('account_transaction', { - debit: 2000, credit: 0, account_id: debitAccount.id, ...accountTransactionMixied, - }); - - // Income Journal. - // 2000 Credit - Income account. - // 2000 Debit - Asset account. - await tenantFactory.create('account_transaction', { - credit: 2000, account_id: incomeAccount.id, ...accountTransactionMixied - }); - await tenantFactory.create('account_transaction', { - debit: 2000, credit: 0, account_id: debitAccount.id, ...accountTransactionMixied, - }); - - // ----------------------------------------- - // Assets account balance = 5000 | Libility account balance = 4000 - // Expense account balance = 1000 | Income account balance = 2000 - }); - - - describe('routes: `/financial_statements/journal`', () => { - it('Should response unauthorized in case the user was not authorized.', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .send(); - - expect(res.status).equals(401); - }); - - it('Should retrieve ledger sheet transactions grouped by reference type and id.', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - expect(res.body.journal.length).to.be.at.least(1); - - expect(res.body.journal[0].credit).to.be.a('number'); - expect(res.body.journal[0].debit).to.be.a('number'); - expect(res.body.journal[0].entries).to.be.a('array'); - expect(res.body.journal[0].id).to.be.a('string'); - - expect(res.body.journal[0].entries[0].credit).to.be.a('number'); - expect(res.body.journal[0].entries[0].debit).to.be.a('number'); - }); - - it('Should retrieve transactions between date range.', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2018-01-01', - to_date: '2019-01-01', - }) - .send(); - - expect(res.body.journal.length).equals(0); - }); - - it('Should retrieve transactions that associated to the queried accounts.', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - account_ids: [creditAccount.id], - }) - .send(); - - expect(res.body.journal[0].entries.length).equals(1); - expect(res.body.journal[0].entries[0].account_id).equals(creditAccount.id); - - expect(res.body.journal.length).equals(1); - }); - - it('Should retrieve tranasactions with the given types.', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - transaction_types: ['Expense'], - }); - - expect(res.body.journal.length).equals(1); - }); - - it('Should retrieve transactions with range amount.', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_range: 2000, - to_range: 2000, - }) - .send(); - - expect(res.body.journal[0].credit).satisfy((credit) => { - return credit === 0 || credit >= 2000; - }); - expect(res.body.journal[0].debit).satisfy((debit) => { - return debit === 0 || debit >= 2000; - }); - }); - - it('Should format credit and debit to no cents of retrieved transactions.', async () => { - - }); - - it('Should divide credit/debit amount on 1000', async () => { - const res = await request() - .get('/api/financial_statements/journal') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - number_format: { - divide_1000: true, - }, - }) - .send(); - - const journal = res.body.journal.find((j) => j.id === '1-Expense'); - - expect(journal.formatted_credit).equals(1); - expect(journal.formatted_debit).equals(1); - }); - }); - - describe('routes: `/financial_statements/general_ledger`', () => { - it('Should response unauthorized in case the user was not authorized.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .send(); - - expect(res.status).equals(401); - }); - - it('Should retrieve request query meta on response schema.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.query.from_date).equals(moment().startOf('year').format('YYYY-MM-DD')); - expect(res.body.query.to_date).equals(moment().endOf('year').format('YYYY-MM-DD')); - expect(res.body.query.basis).equals('cash'); - expect(res.body.query.number_format.no_cents).equals(false); - expect(res.body.query.number_format.divide_1000).equals(false); - expect(res.body.query.none_zero).equals(false); - expect(res.body.query.accounts_ids).to.be.an('array'); - }); - - it('Should retrieve the general ledger accounts with associated transactions and opening/closing balance.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.accounts).is.an('array'); - expect(res.body.accounts[0].id).to.be.an('number'); - expect(res.body.accounts[0].name).to.be.a('string'); - expect(res.body.accounts[0].code).to.be.a('string'); - expect(res.body.accounts[0].transactions).to.be.a('array'); - expect(res.body.accounts[0].opening).to.be.a('object'); - expect(res.body.accounts[0].opening.amount).to.be.a('number'); - expect(res.body.accounts[0].opening.date).to.be.a('string'); - expect(res.body.accounts[0].closing).to.be.a('object'); - expect(res.body.accounts[0].closing.amount).to.be.a('number'); - expect(res.body.accounts[0].closing.date).to.be.a('string'); - }); - - it('Should retrieve opening and closing balance.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const targetAccount = res.body.accounts.find((a) => a.id === creditAccount.id); - - expect(targetAccount).to.be.an('object'); - expect(targetAccount.opening).to.deep.equal({ - amount: 0, formatted_amount: 0, date: '2020-01-01', - }); - expect(targetAccount.closing).to.deep.equal({ - amount: 4000, formatted_amount: 4000, date: '2020-12-31', - }); - }); - - it('Should retrieve opening and closing balance between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2018-01-01', - to_date: '2020-03-30', - // none_zero: true, - }) - .send(); - - const targetAccount = res.body.accounts.find((a) => a.id === creditAccount.id); - - expect(targetAccount).to.be.an('object'); - expect(targetAccount.opening).to.deep.equal({ - amount: 0, formatted_amount: 0, date: '2018-01-01', - }); - expect(targetAccount.closing).to.deep.equal({ - amount: 4000, formatted_amount: 4000, date: '2020-03-30', - }); - }); - - it('Should retrieve accounts with associated transactions.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - none_zero: true, - }) - .send(); - - }) - - it('Should retrieve accounts transactions only that between date range.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2020-03-30', - none_zero: true, - }) - .send(); - - - // console.log(res.body.accounts); - }); - - it('Should retrieve no accounts with given date period has not transactions.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-20', - to_date: '2020-03-30', - none_zero: true, - }) - .send(); - - expect(res.body.accounts.length).equals(0); - }); - - it('Should retrieve all accounts even it have no transactions in the given date range when `none_zero` is `true`', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2020-03-30', - none_zero: true, - }) - .send(); - - const accountsNoTransactions = res.body.accounts.filter(a => a.transactions.length === 0); - const accountsWithTransactions = res.body.accounts.filter(a => a.transactions.length > 0); - - expect(accountsNoTransactions.length).equals(0); - expect(accountsWithTransactions.length).not.equals(0); - }); - - it('Should amount transactions divided on `1000` when `number_format.none_zero` is `true`.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2020-03-30', - accounts_ids: [creditAccount.id], - number_format: { - divide_1000: true, - }, - }) - .send(); - - expect(res.body.accounts).include.something.deep.equals({ - id: creditAccount.id, - name: creditAccount.name, - code: creditAccount.code, - index: null, - parentAccountId: null, - children: [], - transactions: [ - { - id: 1002, - note: null, - transactionType: null, - referenceType: null, - referenceId: null, - date: '2020-01-09T22:00:00.000Z', - createdAt: null, - formatted_amount: 4, - amount: 4000, - } - ], - opening: { date: '2020-01-01', formatted_amount: 0, amount: 0 }, - closing: { date: '2020-03-30', formatted_amount: 4, amount: 4000 } - }); - }); - - it('Should amount transactions rounded with no decimals when `number_format.no_cents` is `true`.', async () => { - await tenantFactory.create('account_transaction', { - debit: 0.25, credit: 0, account_id: debitAccount.id, date: '2020-1-10', - }); - - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2020-03-30', - number_format: { - divide_1000: true, - no_cents: true, - }, - accounts_ids: [debitAccount.id] - }) - .send(); - - expect(res.body.accounts[0].transactions[2].formatted_amount).equal(2); - }); - - it('Should retrieve only accounts that given in the query.', async () => { - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2020-03-30', - none_zero: true, - accounts_ids: [creditAccount.id], - }) - .send(); - - expect(res.body.accounts.length).equals(1); - }); - - it('Should retrieve accounts in nested array structure as parent/children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: debitAccount.id, - account_type_id: 1 - }); - - const res = await request() - .get('/api/financial_statements/general_ledger') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - accounts_ids: [childAccount.id, debitAccount.id], - }) - .send(); - - expect(res.body.accounts[0].children.length).equals(1); - expect(res.body.accounts[0].children[0].id).equals(childAccount.id); - }); - }); - - describe('routes: `/financial_statements/trial_balance`', () => { - it('Should response unauthorized in case the user was not authorized.', async () => { - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .send(); - - expect(res.status).equals(401); - }); - - it('Should retrieve the trial balance of accounts.', async () => { - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.accounts).include.something.deep.equals({ - id: debitAccount.id, - name: debitAccount.name, - code: debitAccount.code, - parentAccountId: null, - accountNormal: 'debit', - credit: 1000, - debit: 6000, - balance: 5000, - - formatted_credit: 1000, - formatted_debit: 6000, - formatted_balance: 5000, - - children: [], - }); - expect(res.body.accounts).include.something.deep.equals({ - id: creditAccount.id, - name: creditAccount.name, - code: creditAccount.code, - accountNormal: 'credit', - parentAccountId: null, - - credit: 4000, - debit: 0, - balance: 4000, - - formatted_credit: 4000, - formatted_debit: 0, - formatted_balance: 4000, - - children: [], - }); - }); - - it('Should not retrieve accounts has no transactions between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - // There is no transactions between these dates. - from_date: '2002-01-01', - to_date: '2003-01-01', - none_zero: true, - }) - .send(); - - expect(res.body.accounts.length).equals(0); - }); - - it('Should retrieve trial balance of accounts between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - // There is no transactions between these dates. - from_date: '2020-01-05', - to_date: '2020-01-10', - none_zero: true, - }) - .send(); - - expect(res.body.accounts).include.something.deep.equals({ - id: creditAccount.id, - name: creditAccount.name, - code: creditAccount.code, - accountNormal: 'credit', - parentAccountId: null, - credit: 4000, - debit: 0, - balance: 4000, - - formatted_credit: 4000, - formatted_debit: 0, - formatted_balance: 4000, - - children: [] - }); - }); - - it('Should credit, debit and balance amount be divided on 1000.', async () => { - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - // There is no transactions between these dates. - from_date: '2020-01-05', - to_date: '2020-01-10', - number_format: { - divide_1000: true, - }, - }) - .send(); - - expect(res.body.accounts).include.something.deep.equals({ - id: creditAccount.id, - name: creditAccount.name, - code: creditAccount.code, - accountNormal: 'credit', - parentAccountId: null, - - credit: 4000, - debit: 0, - balance: 4000, - - formatted_credit: 4, - formatted_debit: 0, - formatted_balance: 4, - - children: [], - }); - }); - - it('Should credit, debit and balance amount rounded without cents.', async () => { - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - // There is no transactions between these dates. - from_date: '2020-01-05', - to_date: '2020-01-10', - number_format: { - no_cents: true, - }, - }) - .send(); - }); - - it('Should retrieve associated account details in accounts list.', async () => { - - }); - - it('Should retrieve account with nested array structure as parent/children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: debitAccount.id, - account_type_id: 1 - }); - - const res = await request() - .get('/api/financial_statements/trial_balance_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - account_ids: [debitAccount.id, childAccount.id], - }) - .send(); - - expect(res.body.accounts[0].children.length).equals(1); - expect(res.body.accounts[0].children[0].id).equals(childAccount.id); - }); - }); - - describe('routes: `/api/financial_statements/profit_loss_sheet`', () => { - it('Should response unauthorized in case the user was not authorized.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loos_sheet') - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should retrieve columns when display type `date_periods` and columns by `month` between date range.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2020-12-12', - display_columns_type: 'date_periods', - display_columns_by: 'month', - }) - .send(); - - expect(res.body.columns.length).equals(12); - expect(res.body.columns).deep.equals([ - '2020-01', '2020-02', - '2020-03', '2020-04', - '2020-05', '2020-06', - '2020-07', '2020-08', - '2020-09', '2020-10', - '2020-11', '2020-12', - ]); - }); - - it('Should retrieve columns when display type `date_periods` and columns by `quarter`.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: moment().startOf('year').format('YYYY-MM-DD'), - to_date: moment().endOf('year').format('YYYY-MM-DD'), - display_columns_type: 'date_periods', - display_columns_by: 'quarter', - }) - .send(); - - expect(res.body.columns.length).equals(4); - expect(res.body.columns).deep.equals([ - '2020-03', '2020-06', '2020-09', '2020-12', - ]); - }); - - it('Should retrieve columns when display type `date_periods` and columns by `day` between date range.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: moment('2020-01-01').startOf('month').format('YYYY-MM-DD'), - to_date: moment('2020-01-01').endOf('month').format('YYYY-MM-DD'), - display_columns_type: 'date_periods', - display_columns_by: 'day', - }) - .send(); - - expect(res.body.columns.length).equals(31); - expect(res.body.columns).deep.equals([ - '2020-01-01', '2020-01-02', '2020-01-03', - '2020-01-04', '2020-01-05', '2020-01-06', - '2020-01-07', '2020-01-08', '2020-01-09', - '2020-01-10', '2020-01-11', '2020-01-12', - '2020-01-13', '2020-01-14', '2020-01-15', - '2020-01-16', '2020-01-17', '2020-01-18', - '2020-01-19', '2020-01-20', '2020-01-21', - '2020-01-22', '2020-01-23', '2020-01-24', - '2020-01-25', '2020-01-26', '2020-01-27', - '2020-01-28', '2020-01-29', '2020-01-30', - '2020-01-31', - ]); - }); - - it('Should retrieve all income accounts even it has no transactions.', async () => { - const zeroAccount = await tenantFactory.create('account', { account_type_id: incomeType.id }); - - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: moment('2020-01-01').startOf('month').format('YYYY-MM-DD'), - to_date: moment('2020-01-31').endOf('month').format('YYYY-MM-DD'), - display_columns_type: 'total', - display_columns_by: 'month', - none_zero: false, - }) - .send(); - - expect(res.body.profitLoss.income.accounts).include.something.deep.equals({ - id: zeroAccount.id, - index: zeroAccount.index, - name: zeroAccount.name, - code: zeroAccount.code, - parentAccountId: null, - children: [], - total: { amount: 0, date: '2020-01-31', formatted_amount: 0 }, - }); - }); - - it('Should retrieve total of each income account when display columns by `total`.', async () => { - const toDate = moment('2020-01-01').endOf('month').format('YYYY-MM-DD'); - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: moment('2020-01-01').startOf('month').format('YYYY-MM-DD'), - to_date: toDate, - }) - .send(); - - expect(res.body.profitLoss.income.accounts).to.be.an('array'); - expect(res.body.profitLoss.income.accounts.length).not.equals(0); - expect(res.body.profitLoss.income.accounts[0].id).to.be.an('number'); - expect(res.body.profitLoss.income.accounts[0].name).to.be.an('string'); - expect(res.body.profitLoss.income.accounts[0].total).to.be.an('object'); - expect(res.body.profitLoss.income.accounts[0].total.amount).to.be.an('number'); - expect(res.body.profitLoss.income.accounts[0].total.formatted_amount).to.be.an('number'); - expect(res.body.profitLoss.income.accounts[0].total.date).equals(toDate); - }); - - it('Should retrieve credit sumation of income accounts.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2021-01-01', - }) - .send(); - - expect(res.body.profitLoss.income.total).to.be.an('object'); - expect(res.body.profitLoss.income.total.amount).equals(2000); - expect(res.body.profitLoss.income.total.formatted_amount).equals(2000); - expect(res.body.profitLoss.income.total.date).equals('2021-01-01'); - }); - - it('Should retrieve debit sumation of expenses accounts.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2021-01-01', - }) - .send(); - - expect(res.body.profitLoss.expenses.total).to.be.an('object'); - expect(res.body.profitLoss.expenses.total.amount).equals(1000); - expect(res.body.profitLoss.expenses.total.formatted_amount).equals(1000); - expect(res.body.profitLoss.expenses.total.date).equals('2021-01-01'); - }); - - it('Should retrieve credit total of income accounts with `date_periods` columns between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2019-12-01', - to_date: '2020-12-01', - display_columns_type: 'date_periods', - display_columns_by: 'month', - }) - .send(); - - expect(res.body.profitLoss.income.total_periods[0].amount).equals(0); - expect(res.body.profitLoss.income.total_periods[1].amount).equals(2000); - expect(res.body.profitLoss.income.total_periods[2].amount).equals(2000); - }); - - it('Should retrieve debit total of expenses accounts with `date_periods` columns between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2019-12-01', - to_date: '2020-12-01', - display_columns_type: 'date_periods', - display_columns_by: 'month', - }) - .send(); - - expect(res.body.profitLoss.expenses.total_periods[0].amount).equals(0); - expect(res.body.profitLoss.expenses.total_periods[1].amount).equals(1000); - expect(res.body.profitLoss.expenses.total_periods[2].amount).equals(1000); - }); - - it('Should retrieve total net income with `total column display between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2019-12-01', - to_date: '2020-12-01', - display_columns_type: 'total', - }) - .send(); - - expect(res.body.profitLoss.net_income.total.amount).equals(1000); - expect(res.body.profitLoss.net_income.total.formatted_amount).equals(1000); - expect(res.body.profitLoss.net_income.total.date).equals('2020-12-01'); - }); - - it('Should retrieve total net income with `date_periods` columns between the given date range.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2019-12-01', - to_date: '2020-12-01', - display_columns_type: 'date_periods', - display_columns_by: 'quarter', - }) - .send(); - - expect(res.body.profitLoss.net_income).deep.equals({ - total_periods: [ - { date: '2019-12', amount: 0, formatted_amount: 0 }, - { date: '2020-03', amount: 1000, formatted_amount: 1000 }, - { date: '2020-06', amount: 1000, formatted_amount: 1000 }, - { date: '2020-09', amount: 1000, formatted_amount: 1000 }, - { date: '2020-12', amount: 1000, formatted_amount: 1000 } - ], - }); - }); - - it('Should not retrieve income or expenses accounts that has no transactions between the given date range in case none_zero equals true.', async () => { - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - from_date: '2020-01-01', - to_date: '2021-01-01', - display_columns_by: 'month', - display_columns_type: 'date_periods', - none_zero: true, - }) - .send(); - - expect(res.body.profitLoss.income.accounts.length).equals(1); - }); - - it('Should retrieve accounts in nested array structure as parent/children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: incomeAccount.id, - account_type_id: 7 - }); - - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - account_ids: [childAccount.id, incomeAccount.id], - }) - .send(); - - expect(res.body.profitLoss.income.accounts.length).equals(1); - expect(res.body.profitLoss.income.accounts[0].children.length).equals(1); - expect(res.body.profitLoss.income.accounts[0].children[0].id).equals(childAccount.id); - }); - - it('Should parent account credit/debit sumation of total periods amounts all children accounts.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: incomeAccount.id, - account_type_id: 7, - }); - await tenantFactory.create('account_transaction', { - credit: 1000, debit: 0, account_id: childAccount.id, date: '2020-2-10' - }); - - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - account_ids: [childAccount.id, incomeAccount.id], - from_date: '2020-01-01', - to_date: '2020-12-12', - }) - .send(); - - expect(res.body.profitLoss.income.accounts[0].total).deep.equals({ - amount: 3000, date: '2020-12-12', formatted_amount: 3000 - }); - }); - - it('Should parent account credit/debit sumation of total date periods.', async () => { - const childAccount = await tenantFactory.create('account', { - parent_account_id: incomeAccount.id, - account_type_id: 7, - }); - await tenantFactory.create('account_transaction', { - credit: 1000, debit: 0, account_id: childAccount.id, date: '2020-2-10' - }); - - const res = await request() - .get('/api/financial_statements/profit_loss_sheet') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - account_ids: [childAccount.id, incomeAccount.id], - display_columns_type: 'date_periods', - display_columns_by: 'month', - from_date: '2020-01-01', - to_date: '2020-12-12', - }) - .send(); - - const periods = [ - { date: '2020-01', amount: 2000, formatted_amount: 2000 }, - { date: '2020-02', amount: 3000, formatted_amount: 3000 }, - { date: '2020-03', amount: 3000, formatted_amount: 3000 }, - { date: '2020-04', amount: 3000, formatted_amount: 3000 }, - { date: '2020-05', amount: 3000, formatted_amount: 3000 }, - { date: '2020-06', amount: 3000, formatted_amount: 3000 }, - { date: '2020-07', amount: 3000, formatted_amount: 3000 }, - { date: '2020-08', amount: 3000, formatted_amount: 3000 }, - { date: '2020-09', amount: 3000, formatted_amount: 3000 }, - { date: '2020-10', amount: 3000, formatted_amount: 3000 }, - { date: '2020-11', amount: 3000, formatted_amount: 3000 }, - { date: '2020-12', amount: 3000, formatted_amount: 3000 } - ]; - expect(res.body.profitLoss.income.accounts[0].periods).deep.equals(periods); - expect(res.body.profitLoss.income.total_periods).deep.equals(periods); - }); - }); -}); diff --git a/packages/server/tests/routes/inviteUsers.test.js b/packages/server/tests/routes/inviteUsers.test.js deleted file mode 100644 index b586f0dda..000000000 --- a/packages/server/tests/routes/inviteUsers.test.js +++ /dev/null @@ -1,259 +0,0 @@ -import knex from '@/database/knex'; -import { - request, - expect, - createUser, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import Invite from '@/system/models/Invite' -import TenantUser from 'models/TenantUser'; -import SystemUser from '@/system/models/SystemUser'; - -describe('routes: `/api/invite_users`', () => { - describe('POST: `/api/invite_users/send`', () => { - it('Should response unauthorized if the user was not authorized.', async () => { - const res = await request().get('/api/invite_users/send'); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should email be required.', async () => { - const res = await request() - .post('/api/invite/send') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'email', location: 'body', - }); - }); - - it('Should email not be already registered in the system database.', async () => { - const user = await createUser(tenantWebsite, { - active: false, - email: 'admin@admin.com', - }); - - const res = await request() - .post('/api/invite/send') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - email: 'admin@admin.com', - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'USER.EMAIL.ALREADY.REGISTERED', code: 100, - }); - }); - - it('Should invite token be inserted to the master database.', async () => { - const res = await request() - .post('/api/invite/send') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - email: 'admin@admin.com' - }); - - const foundInviteToken = await Invite.query() - .where('email', 'admin@admin.com').first(); - - expect(foundInviteToken).is.not.null; - expect(foundInviteToken.token).is.not.null; - }); - - it('Should invite email be insereted to users tenant database.', async () => { - const res = await request() - .post('/api/invite/send') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - email: 'admin@admin.com' - }); - - const foundTenantUser = await TenantUser.tenant().query() - .where('email', 'admin@admin.com').first(); - - expect(foundTenantUser).is.not.null; - expect(foundTenantUser.email).equals('admin@admin.com'); - expect(foundTenantUser.firstName).equals('admin@admin.com'); - expect(foundTenantUser.createdAt).is.not.null; - }); - }); - - describe('POST: `/api/invite/accept/:token`', () => { - let sendInviteRes; - let inviteUser; - - beforeEach(async () => { - sendInviteRes = await request() - .post('/api/invite/send') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - email: 'admin@admin.com' - }); - - inviteUser = await Invite.query() - .where('email', 'admin@admin.com') - .first(); - }); - - it('Should the given token be valid.', async () => { - const res = await request() - .post('/api/invite/accept/invalid_token') - .send({ - first_name: 'Ahmed', - last_name: 'Bouhuolia', - password: 'hard-password', - phone_number: '0927918381', - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'INVITE.TOKEN.NOT.FOUND', code: 300, - }); - }); - - it('Should first_name be required.', async () => { - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'first_name', location: 'body' - }); - }); - - it('Should last_name be required.', async () => { - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'last_name', location: 'body' - }); - }); - - it('Should phone_number be required.', async () => { - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'phone_number', location: 'body' - }); - }); - - it('Should password be required.', async () => { - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'password', location: 'body' - }); - }); - - it('Should phone number not be already registered.', async () => { - const user = await createUser(tenantWebsite); - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send({ - first_name: 'Ahmed', - last_name: 'Bouhuolia', - password: 'hard-password', - phone_number: user.phone_number, - }) - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'PHONE_MUMNER.ALREADY.EXISTS', code: 400, - }); - }); - - it('Should tenant user details updated after invite accept.', async () => { - const user = await createUser(tenantWebsite); - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send({ - first_name: 'Ahmed', - last_name: 'Bouhuolia', - password: 'hard-password', - phone_number: '0927918381', - }); - - const foundTenantUser = await TenantUser.tenant().query() - .where('email', 'admin@admin.com').first(); - - expect(foundTenantUser).is.not.null; - expect(foundTenantUser.id).is.not.null; - expect(foundTenantUser.email).equals('admin@admin.com'); - expect(foundTenantUser.firstName).equals('Ahmed'); - expect(foundTenantUser.lastName).equals('Bouhuolia'); - expect(foundTenantUser.active).equals(1); - expect(foundTenantUser.inviteAcceptedAt).is.not.null; - expect(foundTenantUser.createdAt).is.not.null; - expect(foundTenantUser.updatedAt).is.not.null; - }); - - it('Should user details be insereted to the system database', async () => { - const user = await createUser(tenantWebsite); - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send({ - first_name: 'Ahmed', - last_name: 'Bouhuolia', - password: 'hard-password', - phone_number: '0927918381', - }); - - const foundSystemUser = await SystemUser.query() - .where('email', 'admin@admin.com').first(); - - expect(foundSystemUser).is.not.null; - expect(foundSystemUser.id).is.not.null; - expect(foundSystemUser.tenantId).equals(inviteUser.tenantId); - expect(foundSystemUser.email).equals('admin@admin.com'); - expect(foundSystemUser.firstName).equals('Ahmed'); - expect(foundSystemUser.lastName).equals('Bouhuolia'); - expect(foundSystemUser.active).equals(1); - expect(foundSystemUser.lastLoginAt).is.null; - expect(foundSystemUser.createdAt).is.not.null; - expect(foundSystemUser.updatedAt).is.null; - }); - - it('Should invite token be deleted after invite accept.', async () => { - const res = await request() - .post(`/api/invite/accept/${inviteUser.token}`) - .send({ - first_name: 'Ahmed', - last_name: 'Bouhuolia', - password: 'hard-password', - phone_number: '0927918381', - }); - - const foundInviteToken = await Invite.query().where('token', inviteUser.token); - expect(foundInviteToken.length).equals(0); - }); - }); - - describe('GET: `/api/invite_users/:token`', () => { - it('Should response token invalid.', () => { - - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/items.test.js b/packages/server/tests/routes/items.test.js deleted file mode 100644 index 4e2858668..000000000 --- a/packages/server/tests/routes/items.test.js +++ /dev/null @@ -1,729 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Item from 'models/Item'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: `/items`', () => { - describe('POST: `/items`', () => { - it('Should not create a new item if the user was not authorized.', async () => { - const res = await request() - .post('/api/items') - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `name` be required.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'name', location: 'body', - }); - }); - - it('Should `type` be required.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'type', location: 'body', - }); - }); - - it('Should `type` be one of defined words.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - type: 'not-defined', - }); - - expect(res.body.errors).include.something.deep.equals({ - value: 'not-defined', - msg: 'Invalid value', - param: 'type', - location: 'body', - }); - }); - - it('Should `buy_price` be numeric.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - cost_price: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'cost_price', - location: 'body', - }); - }); - - it('Should `sell_price` be numeric.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - sell_price: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'sell_price', - location: 'body', - }); - }); - - it('Should `sell_account_id` be integer.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - cost_account_id: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'cost_account_id', - location: 'body', - }); - }); - - it('Should `cost_account_id` be integer.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - sell_account_id: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'sell_account_id', - location: 'body', - }); - }); - - it('Should `cost_account_id` be required if `cost_price` was presented.', async () => { - - }); - - it('Should `buy_account_id` be required if `buy_price` was presented.', async () => { - - }); - - it('Should `inventory_account_id` be required if type was `inventory` item.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'inventory', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 10, - cost_account_id: 20, - }); - - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'inventory_account_id', - location: 'body', - }); - }); - - it('Should `inventory_account_id` be not required if type was not `inventory`.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 10, - cost_account_id: 20, - }); - - expect(res.body.errors).include.something.deep.not.equals({ - msg: 'Invalid value', - param: 'inventory_account_id', - location: 'body', - }); - }); - - it('Should response bad request in case `cost account` was not exist.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 10, - cost_account_id: 20, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'COST_ACCOUNT_NOT_FOUND', code: 100, - }); - }); - - it('Should response bad request in case sell account was not exist.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 10, - cost_account_id: 20, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'SELL_ACCOUNT_NOT_FOUND', code: 120, - }); - }); - - it('Should response not category found in case item category was not exist.', async () => { - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 10, - cost_account_id: 20, - category_id: 20, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ITEM_CATEGORY_NOT_FOUND', code: 140, - }); - }); - - it('Should response success with correct data format.', async () => { - const account = await tenantFactory.create('account'); - const anotherAccount = await tenantFactory.create('account'); - const itemCategory = await tenantFactory.create('item_category'); - - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: account.id, - cost_account_id: anotherAccount.id, - category_id: itemCategory.id, - }); - - expect(res.status).equals(200); - }); - - it('Should store the given item details to the storage.', async () => { - const account = await tenantFactory.create('account'); - const anotherAccount = await tenantFactory.create('account'); - const itemCategory = await tenantFactory.create('item_category'); - - const res = await request() - .post('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sku: 'SKU CODE', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: account.id, - cost_account_id: anotherAccount.id, - category_id: itemCategory.id, - note: 'note about item' - }); - - const storedItem = await Item.tenant().query().where('id', res.body.id).first(); - - expect(storedItem.name).equals('Item Name'); - expect(storedItem.type).equals('service'); - - expect(storedItem.sellPrice).equals(10.2); - expect(storedItem.costPrice).equals(20.2); - expect(storedItem.sellAccountId).equals(account.id); - expect(storedItem.costAccountId).equals(anotherAccount.id); - expect(storedItem.categoryId).equals(itemCategory.id); - expect(storedItem.sku).equals('SKU CODE'); - expect(storedItem.note).equals('note about item'); - expect(storedItem.userId).is.not.null; - }); - }); - - describe('POST: `items/:id`', () => { - it('Should response item not found in case item id was not exist.', async () => { - const res = await request() - .post('/api/items/100') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'product', - cost_price: 100, - sell_price: 200, - sell_account_id: 1, - cost_account_id: 2, - category_id: 2, - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEM.NOT.FOUND', code: 100, - }); - }); - - it('Should `name` be required.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'name', location: 'body', - }); - }); - - it('Should `type` be required.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'type', location: 'body', - }); - }); - - it('Should `sell_price` be numeric.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - sell_price: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'sell_price', - location: 'body', - }); - }); - - it('Should `cost_price` be numeric.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - cost_price: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'cost_price', - location: 'body', - }); - }); - - it('Should `sell_account_id` be integer.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - sell_account_id: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'sell_account_id', - location: 'body', - }); - }); - - it('Should `cost_account_id` be integer.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - cost_account_id: 'not_numeric', - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'cost_account_id', - location: 'body', - }); - }); - - it ('Should response bad request in case cost account was not exist.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 10, - cost_account_id: 20, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'COST_ACCOUNT_NOT_FOUND', code: 100, - }); - }); - - it('Should response bad request in case sell account was not exist.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Item Name', - type: 'product', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: 1000000, - cost_account_id: 1000000, - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'SELL_ACCOUNT_NOT_FOUND', code: 120, - }); - }); - - it('Should update details of the given item.', async () => { - const account = await tenantFactory.create('account'); - const anotherAccount = await tenantFactory.create('account'); - const itemCategory = await tenantFactory.create('item_category'); - - const item = await tenantFactory.create('item'); - const res = await request() - .post(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'New Item Name', - type: 'service', - sell_price: 10.2, - cost_price: 20.2, - sell_account_id: account.id, - cost_account_id: anotherAccount.id, - category_id: itemCategory.id, - }); - - const updatedItem = await Item.tenant().query().findById(item.id); - - expect(updatedItem.name).equals('New Item Name'); - expect(updatedItem.type).equals('service'); - expect(updatedItem.sellPrice).equals(10.2); - expect(updatedItem.costPrice).equals(20.2); - expect(updatedItem.sellAccountId).equals(account.id); - expect(updatedItem.costAccountId).equals(anotherAccount.id); - expect(updatedItem.categoryId).equals(itemCategory.id); - }); - }); - - describe('DELETE: `items/:id`', () => { - it('Should response not found in case the item was not exist.', async () => { - const res = await request() - .delete('/api/items/10') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - }); - - it('Should response success in case was exist.', async () => { - const item = await tenantFactory.create('item'); - const res = await request() - .delete(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - }); - - it('Should delete the given item from the storage.', async () => { - const item = await tenantFactory.create('item'); - await request() - .delete(`/api/items/${item.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const storedItems = await Item.tenant().query().where('id', item.id); - expect(storedItems).to.have.lengthOf(0); - }); - }); - - describe('DELETE: `items?ids=`', () => { - it('Should response in case one of items ids where not exists.', async () => { - const res = await request() - .delete('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [100, 200], - }) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'ITEMS.NOT.FOUND', code: 200, ids: [100, 200], - }); - }); - - it('Should delete the given items from the storage.', async () => { - const item1 = await tenantFactory.create('item'); - const item2 = await tenantFactory.create('item'); - - const res = await request() - .delete('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [item1.id, item2.id], - }) - .send(); - - const foundItems = await Item.tenant().query(); - - expect(res.status).equals(200); - expect(foundItems.length).equals(0) - }); - }); - - describe('GET: `items`', () => { - it('Should response unauthorized access in case the user not authenticated.', async () => { - const res = await request() - .get('/api/items') - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should retrieve items list with associated accounts.', async () => { - await tenantFactory.create('resource', { name: 'items' }); - await tenantFactory.create('item'); - - const res = await request() - .get('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - - expect(res.body.items).to.be.a('object'); - expect(res.body.items.results).to.be.a('array'); - expect(res.body.items.results.length).equals(1); - - expect(res.body.items.results[0].cost_account).to.be.an('object'); - expect(res.body.items.results[0].sell_account).to.be.an('object'); - expect(res.body.items.results[0].inventory_account).to.be.an('object'); - expect(res.body.items.results[0].category).to.be.an('object'); - }); - - it('Should retrieve ordered items based on the given `column_sort_order` and `sort_order` query.', async () => { - await tenantFactory.create('item', { name: 'ahmed' }); - await tenantFactory.create('item', { name: 'mohamed' }); - - const res = await request() - .get('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - column_sort_order: 'name', - sort_order: 'desc', - }) - .send(); - - expect(res.body.items.results.length).equals(2); - expect(res.body.items.results[0].name).equals('mohamed'); - expect(res.body.items.results[1].name).equals('ahmed'); - }); - - it('Should retrieve pagination meta of items list.', async () => { - await tenantFactory.create('resource', { name: 'items' }); - - const res = await request() - .get('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.items.results).to.be.a('array'); - expect(res.body.items.results.length).equals(0); - expect(res.body.items.pagination).to.be.a('object'); - expect(res.body.items.pagination.total).to.be.a('number'); - expect(res.body.items.pagination.total).equals(0) - }); - - it('Should retrieve filtered items based on custom view conditions.', async () => { - const item1 = await tenantFactory.create('item', { type: 'service' }); - const item2 = await tenantFactory.create('item', { type: 'service' }); - const item3 = await tenantFactory.create('item', { type: 'inventory' }); - const item4 = await tenantFactory.create('item', { type: 'inventory' }); - - const view = await tenantFactory.create('view', { - name: 'Items Inventory', - resource_id: 2, - roles_logic_expression: '1', - }); - const viewCondition = await tenantFactory.create('view_role', { - view_id: view.id, - index: 1, - field_id: 12, - value: 'inventory', - comparator: 'equals', - }); - const res = await request() - .get('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - custom_view_id: view.id, - }) - .send(); - - expect(res.body.customViewId).equals(view.id); - expect(res.body.viewColumns).to.be.a('array'); - expect(res.body.viewConditions).to.be.a('array'); - expect(res.body.items.results.length).equals(2); - expect(res.body.items.results[0].type).equals('inventory'); - expect(res.body.items.results[1].type).equals('inventory'); - }); - - it('Should retrieve filtered items based on filtering conditions.', async () => { - const item1 = await tenantFactory.create('item', { type: 'service' }); - const item2 = await tenantFactory.create('item', { type: 'service', name: 'target' }); - const item3 = await tenantFactory.create('item', { type: 'inventory' }); - const item4 = await tenantFactory.create('item', { type: 'inventory' }); - - const res = await request() - .get('/api/items') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - stringified_filter_roles: JSON.stringify([ - { - condition: 'AND', - field_key: 'type', - comparator: 'equals', - value: 'inventory', - }, - { - condition: 'OR', - field_key: 'name', - comparator: 'equals', - value: 'target', - }, - ]), - }) - .send(); - - expect(res.body.items.results.length).equals(3); - expect(res.body.items.results[0].name).equals('target'); - expect(res.body.items.results[1].type).equals('inventory'); - expect(res.body.items.results[2].type).equals('inventory'); - }); - }); -}); diff --git a/packages/server/tests/routes/itemsCategories.test.js b/packages/server/tests/routes/itemsCategories.test.js deleted file mode 100644 index 63e1ee1a2..000000000 --- a/packages/server/tests/routes/itemsCategories.test.js +++ /dev/null @@ -1,311 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import ItemCategory from 'models/ItemCategory'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - -describe('routes: /item_categories/', () => { - describe('POST `/items_categories``', async () => { - it('Should not create a item category if the user was not authorized.', async () => { - const res = await request().post('/api/item_categories').send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `name` be required.', async () => { - const res = await request() - .post('/api/item_categories') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should `parent_category_id` be exist in the storage.', async () => { - const res = await request() - .post('/api/item_categories') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Clothes', - parent_category_id: 10, - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'PARENT_CATEGORY_NOT_FOUND', code: 100, - }); - }); - - it('Should response success with correct form data.', async () => { - const res = await request() - .post('/api/item_categories') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Clothes', - description: 'Here is description', - }); - - expect(res.status).equals(200); - expect(res.body.category).to.be.a('object'); - expect(res.body.category.id).to.be.a('number'); - expect(res.body.category.name).to.be.a('string'); - expect(res.body.category.description).to.be.a('string'); - }); - - it('Should item category data be saved to the storage.', async () => { - const category = await tenantFactory.create('item_category'); - const res = await request() - .post('/api/item_categories') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Clothes', - description: 'Here is description', - parent_category_id: category.id, - }); - - expect(res.status).equals(200); - - const storedCategory = await ItemCategory.tenant().query() - .where('id', res.body.category.id) - .first(); - - expect(storedCategory.name).equals('Clothes'); - expect(storedCategory.description).equals('Here is description'); - expect(storedCategory.parentCategoryId).equals(category.id); - expect(storedCategory.userId).to.be.a('number'); - }); - }); - - describe('POST `/items_category/{id}`', () => { - it('Should not update a item category if the user was not authorized.', async () => { - const category = await tenantFactory.create('item_category'); - const res = await request() - .post(`/api/item_categories/${category.id}`) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `name` be required.', async () => { - const category = await tenantFactory.create('item_category'); - const res = await request() - .post(`/api/item_categories/${category.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - }); - - it('Should `parent_category_id` be exist in the storage.', async () => { - const category = await tenantFactory.create('item_category'); - const res = await request() - .post(`/api/item_categories/${category.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Name', - parent_category_id: 10, - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'PARENT_CATEGORY_NOT_FOUND', code: 100, - }); - }); - - it('Should response success with correct data format.', async () => { - const category = await tenantFactory.create('item_category'); - const anotherCategory = await tenantFactory.create('item_category'); - - const res = await request() - .post(`/api/item_categories/${category.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Name', - parent_category_id: anotherCategory.id, - description: 'updated description', - }); - - expect(res.status).equals(200); - }); - - it('Should item category data be update in the storage.', async () => { - const category = await tenantFactory.create('item_category'); - const anotherCategory = await tenantFactory.create('item_category'); - - const res = await request() - .post(`/api/item_categories/${category.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'Name', - parent_category_id: anotherCategory.id, - description: 'updated description', - }); - - const storedCategory = await ItemCategory.tenant().query() - .where('id', res.body.id) - .first(); - - expect(storedCategory.name).equals('Name'); - expect(storedCategory.description).equals('updated description'); - expect(storedCategory.parentCategoryId).equals(anotherCategory.id); - }); - }); - - describe('DELETE: `/items_categories`', async () => { - it('Should not delete the give item category if the user was not authorized.', async () => { - const category = await tenantFactory.create('item_category'); - - const res = await request() - .delete(`/api/item_categories/${category.id}`) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should not delete if the item category was not found.', async () => { - const res = await request() - .delete('/api/item_categories/10') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - }); - - it('Should response success after delete the given item category.', async () => { - const category = await tenantFactory.create('item_category'); - const res = await request() - .delete(`/api/item_categories/${category.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - }); - - it('Should delete the give item category from the storage.', async () => { - const category = await tenantFactory.create('item_category'); - const res = await request() - .delete(`/api/item_categories/${category.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const categories = await ItemCategory.tenant().query() - .where('id', category.id); - - expect(categories).to.have.lengthOf(0); - }); - }); - - describe('GET: `/item_categories`', () => { - - it('Should retrieve list of item categories.', async () => { - const category1 = await tenantFactory.create('item_category'); - const category2 = await tenantFactory.create('item_category', { parent_category_id: category1.id }); - - const res = await request() - .get('/api/item_categories') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.categories).to.be.a('array'); - expect(res.body.categories.length).equals(2); - - expect(res.body.categories[0].id).to.be.a('number'); - expect(res.body.categories[0].name).to.be.a('string'); - expect(res.body.categories[0].parent_category_id).to.be.a('null'); - expect(res.body.categories[0].description).to.be.a('string'); - - expect(res.body.categories[1].parent_category_id).to.be.a('number'); - }); - - - it('Should retrieve of related items.', async () => { - const category1 = await tenantFactory.create('item_category'); - const category2 = await tenantFactory.create('item_category', { parent_category_id: category1.id }); - - await tenantFactory.create('item', { category_id: category1.id }); - - const res = await request() - .get('/api/item_categories') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.categories[0].count).to.be.a('number'); - expect(res.body.categories[0].count).equals(1); - }); - }); - - describe('GET `/items_category/{id}', () => { - it('Should response not found with incorrect item category ID.', () => { - - }); - - it('Should response success with exist item category.', () => { - - }); - - it('Should response data of item category.', () => { - - }); - }); - - describe('DELETE: `/items_cateogires`', () => { - it('Should response bad request in case one of item categories id not exists in the storage.', async () => { - const res = await request() - .delete('/api/item_categories/bulk') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [1020, 2020], - }) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEM.CATEGORIES.IDS.NOT.FOUND', code: 200 - }); - }); - - it('Should delete the given item categories.', async () => { - const itemCategory = await tenantFactory.create('item_category'); - const itemCategory2 = await tenantFactory.create('item_category'); - - const res = await request() - .delete('/api/item_categories/bulk') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - ids: [itemCategory.id, itemCategory2.id], - }) - .send(); - - const deleteItemCategories = await ItemCategory.tenant().query() - .whereIn('id', [itemCategory.id, itemCategory2.id]); - - expect(deleteItemCategories.length).equals(0); - }); - }); -}); diff --git a/packages/server/tests/routes/options.test.js b/packages/server/tests/routes/options.test.js deleted file mode 100644 index cc7445e30..000000000 --- a/packages/server/tests/routes/options.test.js +++ /dev/null @@ -1,120 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Option from 'models/Option'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: `/options`', () => { - describe('POST: `/options/`', () => { - it('Should response unauthorized if the user was not logged in.', async () => { - const res = await request() - .post('/api/options') - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response the options key and group is not defined.', async () => { - const res = await request() - .post('/api/options') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - options: [ - { - key: 'key', - value: 'hello world', - group: 'group', - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'OPTIONS.KEY.NOT.DEFINED', - code: 200, - keys: [ - { key: 'key', group: 'group' }, - ], - }); - }); - - it('Should save options to the storage.', async () => { - const res = await request() - .post('/api/options') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - options: [{ - key: 'name', - group: 'organization', - value: 'hello world', - }], - }); - expect(res.status).equals(200); - - const storedOptions = await Option.tenant().query() - .where('group', 'organization') - .where('key', 'name'); - - expect(storedOptions.metadata.length).equals(1); - }); - }); - - describe('GET: `/options`', () => { - it('Should response unauthorized if the user was not unauthorized.', async () => { - const res = await request() - .get('/api/options') - .query({ - group: 'organization', - }) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should retrieve options the associated to the given group.', async () => { - await tenantFactory.create('option', { group: 'organization', key: 'name' }); - await tenantFactory.create('option', { group: 'organization', key: 'base_currency' }); - - const res = await request() - .get('/api/options') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - group: 'organization', - }) - .send(); - - expect(res.status).equals(200); - expect(res.body.options).is.an('array'); - expect(res.body.options.length).equals(2); - }); - - it('Should retrieve options that associated to the given key.', async () => { - await tenantFactory.create('option', { group: 'organization', key: 'base_currency' }); - await tenantFactory.create('option', { group: 'organization', key: 'name' }); - - const res = await request() - .get('/api/options') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - key: 'name', - }) - .send(); - - expect(res.status).equals(200); - expect(res.body.options).is.an('array'); - expect(res.body.options.length).equals(1); - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/payable_aging.test.js b/packages/server/tests/routes/payable_aging.test.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/tests/routes/payment_receives.test.js b/packages/server/tests/routes/payment_receives.test.js deleted file mode 100644 index c89af23fb..000000000 --- a/packages/server/tests/routes/payment_receives.test.js +++ /dev/null @@ -1,274 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import { - PaymentReceive, - PaymentReceiveEntry, -} from 'models'; - -describe('route: `/sales/payment_receives`', () => { - describe('POST: `/sales/payment_receives`', () => { - it('Should `customer_id` be required.', async () => { - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'customer_id', - location: 'body', - }); - }); - - it('Should `payment_date` be required.', async () => { - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'payment_date', - location: 'body', - }); - }); - - it('Should `deposit_account_id` be required.', async () => { - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'deposit_account_id', - location: 'body', - }); - }); - - it('Should `payment_receive_no` be required.', async () => { - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'payment_receive_no', - location: 'body', - }); - }); - - it('Should invoices IDs be required.', async () => { - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'payment_receive_no', - location: 'body', - }); - }); - - it('Should `customer_id` be exists on the storage.', async () => { - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 123, - payment_date: '2020-02-02', - reference_no: '123', - deposit_account_id: 100, - payment_receive_no: '123', - entries: [ - { - invoice_id: 1, - payment_amount: 1000, - } - ], - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.ID.NOT.EXISTS', code: 200, - }); - }); - - it('Should `deposit_account_id` be exists on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - payment_date: '2020-02-02', - reference_no: '123', - deposit_account_id: 10000, - payment_receive_no: '123', - entries: [ - { - invoice_id: 1, - payment_amount: 1000, - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'DEPOSIT.ACCOUNT.NOT.EXISTS', code: 300, - }); - }); - - it('Should invoices IDs be exist on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const account = await tenantFactory.create('account'); - - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - payment_date: '2020-02-02', - reference_no: '123', - deposit_account_id: account.id, - payment_receive_no: '123', - entries: [ - { - invoice_id: 1, - payment_amount: 1000, - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'DEPOSIT.ACCOUNT.NOT.EXISTS', code: 300, - }); - }); - - it('Should payment receive number be unique on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const account = await tenantFactory.create('account'); - const paymentReceive = await tenantFactory.create('payment_receive', { - payment_receive_no: '123', - }); - - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - payment_date: '2020-02-02', - reference_no: '123', - deposit_account_id: account.id, - payment_receive_no: '123', - entries: [ - { - invoice_id: 1, - payment_amount: 1000, - } - ], - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'PAYMENT.RECEIVE.NUMBER.EXISTS', code: 400, - }); - }); - - it('Should store the payment receive details with associated entries.', async () => { - const customer = await tenantFactory.create('customer'); - const account = await tenantFactory.create('account'); - const invoice = await tenantFactory.create('sale_invoice'); - - const res = await request() - .post('/api/sales/payment_receives') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - payment_date: '2020-02-02', - reference_no: '123', - deposit_account_id: account.id, - payment_receive_no: '123', - entries: [ - { - invoice_id: invoice.id, - payment_amount: 1000, - } - ], - }); - - const storedPaymentReceived = await PaymentReceive.tenant().query().where('id', res.body.id).first(); - - expect(res.status).equals(200); - expect(storedPaymentReceived.customerId).equals(customer.id) - expect(storedPaymentReceived.referenceNo).equals('123'); - expect(storedPaymentReceived.paymentReceiveNo).equals('123'); - }); - }); - - describe('POST: `/sales/payment_receives/:id`', () => { - it('Should update the payment receive details with associated entries.', async () => { - const paymentReceive = await tenantFactory.create('payment_receive'); - const customer = await tenantFactory.create('customer'); - const account = await tenantFactory.create('account'); - const invoice = await tenantFactory.create('sale_invoice'); - - const res = await request() - .post(`/api/sales/payment_receives/${paymentReceive.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - payment_date: '2020-02-02', - reference_no: '123', - deposit_account_id: account.id, - payment_receive_no: '123', - entries: [ - { - invoice_id: invoice.id, - payment_amount: 1000, - } - ], - }); - expect(res.status).equals(200); - }); - }); - - describe('DELETE: `/sales/payment_receives/:id`', () => { - it('Should response the given payment receive is not exists on the storage.', async () => { - const res = await request() - .delete(`/api/sales/payment_receives/123`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'PAYMENT.RECEIVE.NO.EXISTS', code: 600, - }); - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/receivable_aging.test.js b/packages/server/tests/routes/receivable_aging.test.js deleted file mode 100644 index a08c05fb1..000000000 --- a/packages/server/tests/routes/receivable_aging.test.js +++ /dev/null @@ -1,234 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Item from 'models/Item'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: `/financial_statements/receivable_aging_summary`', () => { - - it('Should retrieve customers list.', async () => { - const customer1 = await tenantFactory.create('customer', { display_name: 'Ahmed' }); - const customer2 = await tenantFactory.create('customer', { display_name: 'Mohamed' }); - - const res = await request() - .get('/api/financial_statements/receivable_aging_summary') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - - expect(res.body.aging.customers).is.an('array'); - expect(res.body.aging.customers.length).equals(2); - - expect(res.body.aging.customers[0].customer_name).equals('Ahmed'); - expect(res.body.aging.customers[1].customer_name).equals('Mohamed'); - }); - - it('Should respon se the customers ids not found.', async () => { - const res = await request() - .get('/api/financial_statements/receivable_aging_summary') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - customer_ids: [3213, 3322], - }) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMERS.IDS.NOT.FOUND', code: 300, ids: [3213, 3322] - }) - }); - - it('Should retrieve aging report columns.', async () => { - const customer1 = await tenantFactory.create('customer', { display_name: 'Ahmed' }); - const customer2 = await tenantFactory.create('customer', { display_name: 'Mohamed' }); - - const res = await request() - .get('/api/financial_statements/receivable_aging_summary') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - as_date: '2020-06-01', - aging_days_before: 30, - aging_periods: 6, - }) - .send(); - - expect(res.body.columns).length(6); - expect(res.body.columns[0].before_days).equals(0); - expect(res.body.columns[0].to_days).equals(30); - - expect(res.body.columns[1].before_days).equals(31); - expect(res.body.columns[1].to_days).equals(60); - - expect(res.body.columns[2].before_days).equals(61); - expect(res.body.columns[2].to_days).equals(90); - - expect(res.body.columns[3].before_days).equals(91); - expect(res.body.columns[3].to_days).equals(120); - - expect(res.body.columns[4].before_days).equals(121); - expect(res.body.columns[4].to_days).equals(150); - - expect(res.body.columns[5].before_days).equals(151); - expect(res.body.columns[5].to_days).equals(null); - }); - - it('Should retrieve receivable total of the customers.', async () => { - const customer1 = await tenantFactory.create('customer', { display_name: 'Ahmed' }); - const customer2 = await tenantFactory.create('customer', { display_name: 'Mohamed' }); - - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 10000, - credit: 0, - account_id: 10, - date: '2020-01-01', - }); - - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 1000, - credit: 0, - account_id: 10, - date: '2020-03-15', - }); - - // Receive - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 0, - credit: 8000, - account_id: 10, - date: '2020-06-01', - }); - - const res = await request() - .get('/api/financial_statements/receivable_aging_summary') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - as_date: '2020-06-01', - aging_days_before: 30, - aging_periods: 6, - }) - .send(); - - expect(res.body.aging.total[0].total).equals(0); - expect(res.body.aging.total[1].total).equals(0); - expect(res.body.aging.total[2].total).equals(1000); - expect(res.body.aging.total[3].total).equals(0); - expect(res.body.aging.total[4].total).equals(0); - expect(res.body.aging.total[5].total).equals(2000); - }); - - - it('Should retrieve customer aging.', async () => { - const customer1 = await tenantFactory.create('customer', { display_name: 'Ahmed' }); - const customer2 = await tenantFactory.create('customer', { display_name: 'Mohamed' }); - - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 10000, - credit: 0, - account_id: 10, - date: '2020-01-14', - }); - - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 1000, - credit: 0, - account_id: 10, - date: '2020-03-15', - }); - - // Receive - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 0, - credit: 8000, - account_id: 10, - date: '2020-06-01', - }); - - const res = await request() - .get('/api/financial_statements/receivable_aging_summary') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - as_date: '2020-06-01', - aging_days_before: 30, - aging_periods: 6, - }) - .send(); - - expect(res.body.aging.customers[0].aging[0].total).equals(0); - expect(res.body.aging.customers[0].aging[1].total).equals(0); - expect(res.body.aging.customers[0].aging[2].total).equals(1000); - expect(res.body.aging.customers[0].aging[3].total).equals(0); - expect(res.body.aging.customers[0].aging[4].total).equals(2000); - expect(res.body.aging.customers[0].aging[5].total).equals(0); - }); - - it('Should retrieve the queried customers ids only.', async () => { - const customer1 = await tenantFactory.create('customer', { display_name: 'Ahmed' }); - const customer2 = await tenantFactory.create('customer', { display_name: 'Mohamed' }); - - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 10000, - credit: 0, - account_id: 10, - date: '2020-01-14', - }); - - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 1000, - credit: 0, - account_id: 10, - date: '2020-03-15', - }); - - // Receive - await tenantFactory.create('account_transaction', { - contact_id: customer1.id, - contact_type: 'customer', - debit: 0, - credit: 8000, - account_id: 10, - date: '2020-06-01', - }); - - const res = await request() - .get('/api/financial_statements/receivable_aging_summary') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ - as_date: '2020-06-01', - aging_days_before: 30, - aging_periods: 6, - customer_ids: [customer1.id], - }) - .send(); - - expect(res.body.aging.customers.length).equals(1); - }) -}); diff --git a/packages/server/tests/routes/sales_estimates.test.js b/packages/server/tests/routes/sales_estimates.test.js deleted file mode 100644 index 54e20241a..000000000 --- a/packages/server/tests/routes/sales_estimates.test.js +++ /dev/null @@ -1,439 +0,0 @@ -const { iteratee } = require('lodash'); -import { tenantWebsite, tenantFactory, loginRes } from '~/dbInit'; -import { request, expect } from '~/testInit'; -import { SaleEstimate, SaleEstimateEntry } from '../../src/models'; - -describe('route: `/sales/estimates`', () => { - describe('POST: `/sales/estimates`', () => { - it('Should `customer_id` be required.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'customer_id', - location: 'body', - }); - }); - - it('Should `estimate_date` be required.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'estimate_date', - location: 'body', - }); - }); - - it('Should `estimate_number` be required.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'estimate_number', - location: 'body', - }); - }); - - it('Should `entries` be atleast one entry.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - value: [], - msg: 'Invalid value', - param: 'entries', - location: 'body', - }); - }); - - it('Should `entries.*.item_id` be required.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].item_id', - location: 'body', - }); - }); - - it('Should `entries.*.quantity` be required.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].quantity', - location: 'body', - }); - }); - - it('Should be `entries.*.rate` be required.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].rate', - location: 'body', - }); - }); - - it('Should `customer_id` be exists on the storage.', async () => { - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 10, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: '1', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 2, - } - ], - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.ID.NOT.FOUND', code: 200, - }); - }); - - it('Should `estimate_number` be unique on the storage.', async () => { - const saleEstimate = await tenantFactory.create('sale_estimate'); - - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: saleEstimate.customerId, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: saleEstimate.estimateNumber, - entries: [ - { - item_id: 1, - rate: 1, - quantity: 2, - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ESTIMATE.NUMBER.IS.NOT.UNQIUE', code: 300, - }); - }); - - it('Should `entries.*.item_id` be exists on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: '12', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 2, - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEMS.IDS.NOT.EXISTS', code: 400, - }); - }); - - it('Should store the given details on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const item = await tenantFactory.create('item'); - - const res = await request() - .post('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: '12', - reference: 'reference', - note: 'note here', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: item.id, - rate: 1, - quantity: 2, - description: 'desc..' - } - ], - }); - - expect(res.status).equals(200); - - const storedEstimate = await SaleEstimate.tenant().query().where('id', res.body.id).first(); - const storedEstimateEntry = await SaleEstimateEntry.tenant().query().where('estimate_id', res.body.id).first(); - - expect(storedEstimate.id).equals(res.body.id); - expect(storedEstimate.customerId).equals(customer.id); - expect(storedEstimate.reference).equals('reference') - expect(storedEstimate.note).equals('note here'); - expect(storedEstimate.termsConditions).equals('terms and conditions'); - expect(storedEstimate.estimateNumber).equals('12'); - - expect(storedEstimateEntry.itemId).equals(item.id); - expect(storedEstimateEntry.rate).equals(1); - expect(storedEstimateEntry.quantity).equals(2); - expect(storedEstimateEntry.description).equals('desc..'); - }); - }); - - describe('DELETE: `/sales/estimates/:id`', () => { - it('Should estimate id be exists on the storage.', async () => { - const estimate = await tenantFactory.create('sale_estimate'); - const res = await request() - .delete(`/api/sales/estimates/123`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.ESTIMATE.ID.NOT.FOUND', code: 200 - }); - }); - - it('Should delete the given estimate with associated entries from the storage.', async () => { - const estimate = await tenantFactory.create('sale_estimate'); - const estimateEntry = await tenantFactory.create('sale_estimate_entry', { estimate_id: estimate.id }); - - const res = await request() - .delete(`/api/sales/estimates/${estimate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const foundEstimate = await SaleEstimate.tenant().query().where('id', estimate.id); - const foundEstimateEntry = await SaleEstimateEntry.tenant().query().where('estimate_id', estimate.id); - - expect(res.status).equals(200); - expect(foundEstimate.length).equals(0); - expect(foundEstimateEntry.length).equals(0); - }); - }); - - describe('POST: `/sales/estimates/:id`', () => { - it('Should estimate id be exists on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const item = await tenantFactory.create('item'); - - const res = await request() - .post(`/api/sales/estimates/123`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: '12', - reference: 'reference', - note: 'note here', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: item.id, - rate: 1, - quantity: 2, - description: 'desc..' - } - ], - }) - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.ESTIMATE.ID.NOT.FOUND', code: 200 - }); - }); - - it('Should `entries.*.item_id` be exists on the storage.', async () => { - const saleEstimate = await tenantFactory.create('sale_estimate'); - const customer = await tenantFactory.create('customer'); - - const res = await request() - .post(`/api/sales/estimates/${saleEstimate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: '12', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 2, - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEMS.IDS.NOT.EXISTS', code: 400 - }); - }); - - it('Should sale estimate number unique on the storage.', async () => { - const saleEstimate = await tenantFactory.create('sale_estimate'); - const saleEstimate2 = await tenantFactory.create('sale_estimate'); - - const res = await request() - .post(`/api/sales/estimates/${saleEstimate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: saleEstimate.customerId, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: saleEstimate2.estimateNumber, - entries: [ - { - item_id: 1, - rate: 1, - quantity: 2, - } - ], - }); - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ESTIMATE.NUMBER.IS.NOT.UNQIUE', code: 300, - }); - }); - - it('Should sale estimate entries IDs be exists on the storage and associated to the sale estimate.', async () => { - const item = await tenantFactory.create('item'); - const saleEstimate = await tenantFactory.create('sale_estimate'); - const saleEstimate2 = await tenantFactory.create('sale_estimate'); - - const res = await request() - .post(`/api/sales/estimates/${saleEstimate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: saleEstimate.customerId, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: saleEstimate.estimateNumber, - entries: [ - { - id: 100, - item_id: item.id, - rate: 1, - quantity: 2, - } - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ESTIMATE.NOT.FOUND.ENTRIES.IDS', code: 500, - }); - }); - - it('Should update the given sale estimates with associated entries.', async () => { - const customer = await tenantFactory.create('customer'); - const item = await tenantFactory.create('item'); - const saleEstimate = await tenantFactory.create('sale_estimate'); - const saleEstimateEntry = await tenantFactory.create('sale_estimate_entry', { - estimate_id: saleEstimate.id, - }); - - const res = await request() - .post(`/api/sales/estimates/${saleEstimate.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - estimate_date: '2020-02-02', - expiration_date: '2020-03-03', - estimate_number: '123', - entries: [ - { - id: saleEstimateEntry.id, - item_id: item.id, - rate: 100, - quantity: 200, - } - ], - }); - expect(res.status).equals(200); - }); - }); - - - describe('GET: `/sales/estimates`', () => { - it('Should retrieve sales estimates.', async () => { - const res = await request() - .get('/api/sales/estimates') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - console.log(res.status, res.body); - }); - }); -}); diff --git a/packages/server/tests/routes/sales_invoices.test.js b/packages/server/tests/routes/sales_invoices.test.js deleted file mode 100644 index f0441dd5a..000000000 --- a/packages/server/tests/routes/sales_invoices.test.js +++ /dev/null @@ -1,494 +0,0 @@ -import { tenantWebsite, tenantFactory, loginRes } from '~/dbInit'; -import { request, expect } from '~/testInit'; -import { SaleInvoice } from 'models'; -import { SaleInvoiceEntry } from '../../src/models'; - -describe('route: `/sales/invoices`', () => { - describe('POST: `/sales/invoices`', () => { - it('Should `customer_id` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'customer_id', - location: 'body', - }); - }); - - it('Should `invoice_date` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'invoice_date', - location: 'body', - }); - }); - - it('Should `due_date` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'due_date', - location: 'body', - }); - }); - - it('Should `invoice_no` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'invoice_no', - location: 'body', - }); - }); - - it('Should `status` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'status', - location: 'body', - }); - }); - - it('Should `entries.*.item_id` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].item_id', - location: 'body', - }); - }); - - it('Should `entries.*.quantity` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].quantity', - location: 'body', - }); - }); - - it('Should `entries.*.rate` be required.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].rate', - location: 'body', - }); - }); - - it('Should `customer_id` be exists on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 123, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '123', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.ID.NOT.EXISTS', code: 200, - }); - }); - - it('Should `invoice_date` be bigger than `due_date`.', async () => { - - }); - - it('Should `invoice_no` be unique on the storage.', async () => { - const saleInvoice = await tenantFactory.create('sale_invoice', { - invoice_no: '123', - }); - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 123, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '123', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.INVOICE.NUMBER.IS.EXISTS', code: 200 - }); - }); - - it('Should `entries.*.item_id` be exists on the storage.', async () => { - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 123, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '123', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEMS.IDS.NOT.EXISTS', code: 300, - }); - }); - - it('Should save the given sale invoice details with associated entries.', async () => { - const customer = await tenantFactory.create('customer'); - const item = await tenantFactory.create('item'); - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '123', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: item.id, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - expect(res.status).equals(200); - }); - }); - - describe('POST: `/api/sales/invoices/:id`', () => { - it('Should `customer_id` be required.', async () => { - const res = await request() - .post('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'customer_id', - location: 'body', - }); - }); - - it('Should `invoice_date` be required.', async () => { - const res = await request() - .post('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'invoice_date', - location: 'body', - }); - }); - - - it('Should `status` be required.', async () => { - const res = await request() - .post('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'status', - location: 'body', - }); - }); - - it('Should `entries.*.item_id` be required.', async () => { - const res = await request() - .post('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].item_id', - location: 'body', - }); - }); - - it('Should `entries.*.quantity` be required.', async () => { - const res = await request() - .post('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].quantity', - location: 'body', - }); - }); - - it('Should `entries.*.rate` be required.', async () => { - const res = await request() - .post('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - entries: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'entries[0].rate', - location: 'body', - }); - }); - - it('Should `customer_id` be exists on the storage.', async () => { - const customer = await tenantFactory.create('customer'); - const saleInvoice = await tenantFactory.create('sale_invoice'); - - const res = await request() - .post(`/api/sales/invoices/${saleInvoice.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 123, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '123', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.ID.NOT.EXISTS', code: 200, - }); - }); - - it('Should `invoice_date` be bigger than `due_date`.', async () => { - - }); - - it('Should `invoice_no` be unique on the storage.', async () => { - const saleInvoice = await tenantFactory.create('sale_invoice', { - invoice_no: '123', - }); - const res = await request() - .post('/api/sales/invoices') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: 123, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '123', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: 1, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.INVOICE.NUMBER.IS.EXISTS', code: 200 - }); - }); - - it('Should update the sale invoice details with associated entries.', async () => { - const saleInvoice = await tenantFactory.create('sale_invoice'); - const customer = await tenantFactory.create('customer'); - const item = await tenantFactory.create('item'); - - const res = await request() - .post(`/api/sales/invoices/${saleInvoice.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - customer_id: customer.id, - invoice_date: '2020-02-02', - due_date: '2020-03-03', - invoice_no: '1', - reference_no: '123', - status: 'published', - invoice_message: 'Invoice message...', - terms_conditions: 'terms and conditions', - entries: [ - { - item_id: item.id, - rate: 1, - quantity: 1, - discount: 1, - } - ] - }); - expect(res.status).equals(200); - }); - }); - - describe('DELETE: `/sales/invoices/:id`', () => { - it('Should retrieve sale invoice not found.', async () => { - const res = await request() - .delete('/api/sales/invoices/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.INVOICE.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given sale invoice with associated entries.', async () => { - const saleInvoice = await tenantFactory.create('sale_invoice'); - const saleInvoiceEntey = await tenantFactory.create('sale_invoice_entry', { - sale_invoice_id: saleInvoice.id, - }); - - const res = await request() - .delete(`/api/sales/invoices/${saleInvoice.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const storedSaleInvoice = await SaleInvoice.tenant().query().where('id', saleInvoice.id); - const storedSaleInvoiceEntry = await SaleInvoiceEntry.tenant().query().where('id', saleInvoiceEntey.id); - - expect(res.status).equals(200); - expect(storedSaleInvoice.length).equals(0); - expect(storedSaleInvoiceEntry.length).equals(0); - }); - }); -}); \ No newline at end of file diff --git a/packages/server/tests/routes/sales_receipts.test.js b/packages/server/tests/routes/sales_receipts.test.js deleted file mode 100644 index 5d112acb1..000000000 --- a/packages/server/tests/routes/sales_receipts.test.js +++ /dev/null @@ -1,294 +0,0 @@ -import { tenantWebsite, tenantFactory, loginRes } from '~/dbInit'; -import { request, expect } from '~/testInit'; -import { SaleReceipt } from 'models'; - -describe('route: `/sales/receipts`', () => { - describe('POST: `/sales/receipts`', () => { - it('Should `deposit_account_id` be required.', async () => { - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'deposit_account_id', - location: 'body', - }); - }); - - it('Should `customer_id` be required.', async () => { - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'customer_id', - location: 'body', - }); - }); - - it('should `receipt_date` be required.', async () => { - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'receipt_date', - location: 'body', - }); - }); - - it('Should `entries.*.item_id` be required.', async () => {}); - - it('Should `deposit_account_id` be exists.', async () => { - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - deposit_account_id: 12220, - customer_id: 1, - receipt_date: '2020-02-02', - reference_no: '123', - entries: [ - { - item_id: 1, - quantity: 1, - rate: 2, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'DEPOSIT.ACCOUNT.NOT.EXISTS', - code: 300, - }); - }); - - it('Should `customer_id` be exists.', async () => { - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - deposit_account_id: 12220, - customer_id: 1001, - receipt_date: '2020-02-02', - reference_no: '123', - entries: [ - { - item_id: 1, - quantity: 1, - rate: 2, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'CUSTOMER.ID.NOT.EXISTS', - code: 200, - }); - }); - - it('Should all `entries.*.item_id` be exists on the storage.', async () => { - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - deposit_account_id: 12220, - customer_id: 1001, - receipt_date: '2020-02-02', - reference_no: '123', - entries: [ - { - item_id: 1000, - quantity: 1, - rate: 2, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ITEMS.IDS.NOT.EXISTS', - code: 400, - }); - }); - - it('Should store the sale receipt details with entries to the storage.', async () => { - const item = await tenantFactory.create('item'); - const customer = await tenantFactory.create('customer'); - const account = await tenantFactory.create('account'); - - const res = await request() - .post('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - deposit_account_id: account.id, - customer_id: customer.id, - receipt_date: '2020-02-02', - reference_no: '123', - receipt_message: 'Receipt message...', - statement: 'Receipt statement...', - entries: [ - { - item_id: item.id, - quantity: 1, - rate: 2, - }, - ], - }); - - const storedSaleReceipt = await SaleReceipt.tenant() - .query() - .where('id', res.body.id) - .first(); - - expect(res.status).equals(200); - expect(storedSaleReceipt.depositAccountId).equals(account.id); - expect(storedSaleReceipt.referenceNo).equals('123'); - expect(storedSaleReceipt.customerId).equals(customer.id); - - expect(storedSaleReceipt.receiptMessage).equals('Receipt message...'); - expect(storedSaleReceipt.statement).equals('Receipt statement...'); - }); - }); - - describe('DELETE: `/sales/receipts/:id`', () => { - it('Should the given sale receipt id be exists on the storage.', async () => { - const res = await request() - .delete('/api/sales/receipts/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.RECEIPT.NOT.FOUND', - code: 200, - }); - }); - - it('Should delete the sale receipt with associated entries and journal transactions.', async () => { - const saleReceipt = await tenantFactory.create('sale_receipt'); - const saleReceiptEntry = await tenantFactory.create( - 'sale_receipt_entry', - { - sale_receipt_id: saleReceipt.id, - } - ); - const res = await request() - .delete(`/api/sales/receipts/${saleReceipt.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const storedSaleReceipt = await SaleReceipt.tenant() - .query() - .where('id', saleReceipt.id); - const storedSaleReceiptEntries = await SaleReceipt.tenant() - .query() - .where('id', saleReceiptEntry.id); - - expect(res.status).equals(200); - expect(storedSaleReceipt.length).equals(0); - expect(storedSaleReceiptEntries.length).equals(0); - }); - }); - - describe('POST: `/sales/receipts/:id`', () => { - it('Should the given sale receipt id be exists on the storage.', async () => { - const res = await request() - .post('/api/sales/receipts/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - deposit_account_id: 123, - customer_id: 123, - receipt_date: '2020-02-02', - reference_no: '123', - receipt_message: 'Receipt message...', - statement: 'Receipt statement...', - entries: [ - { - item_id: 123, - quantity: 1, - rate: 2, - }, - ], - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'SALE.RECEIPT.NOT.FOUND', - code: 200, - }); - }); - - it('Should update the sale receipt details with associated entries.', async () => { - const saleReceipt = await tenantFactory.create('sale_receipt'); - const depositAccount = await tenantFactory.create('account'); - const customer = await tenantFactory.create('customer'); - const item = await tenantFactory.create('item'); - - const res = await request() - .post(`/api/sales/receipts/${saleReceipt.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - deposit_account_id: depositAccount.id, - customer_id: customer.id, - receipt_date: '2020-02-02', - reference_no: '123', - receipt_message: 'Receipt message...', - statement: 'Receipt statement...', - entries: [ - { - id: 100, - item_id: item.id, - quantity: 1, - rate: 2, - }, - ], - }); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.deep.equals({ - type: 'ENTRIES.IDS.NOT.FOUND', code: 500, - }); - }); - }); - - describe('GET: `/sales/receipts`', () => { - it('Should response the custom view id not exists on the storage.', async () => { - const res = await request() - .get('/api/sales/receipts') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - - }); - - console.log(res.status, res.body); - }); - - it('Should retrieve all sales receipts on the storage with pagination meta.', () => { - - }); - }); -}); diff --git a/packages/server/tests/routes/users.test.js b/packages/server/tests/routes/users.test.js deleted file mode 100644 index 9c42d4c69..000000000 --- a/packages/server/tests/routes/users.test.js +++ /dev/null @@ -1,203 +0,0 @@ -import knex from '@/database/knex'; -import { - request, - expect, -} from '~/testInit'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: `/routes`', () => { - describe('GET: `/users`', () => { - it('Should response unauthorized if the user was not authorized.', async () => { - const res = await request().get('/api/users'); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should retrieve the stored users with pagination meta.', async () => { - await tenantFactory.create('user'); - - const res = await request() - .get('/api/users') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.users.results.length).equals(2); - expect(res.body.users.total).equals(2); - }); - }); - - describe('POST: `/users/:id`', () => { - it('Should create a new user if the user was not authorized.', async () => { - const user = await tenantFactory.create('user'); - const res = await request() - .post(`/api/users/${user.id}`); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `first_name` be required.', async () => { - const user = await  tenantFactory.create('user'); - const res = await request() - .post(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - - const foundFirstNameParam = res.body.errors.find((error) => error.param === 'first_name'); - expect(!!foundFirstNameParam).equals(true); - }); - - it('Should `last_name` be required.', async () => { - const user = await tenantFactory.create('user'); - const res = await request() - .post(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - - const foundFirstNameParam = res.body.errors.find((error) => error.param === 'last_name'); - expect(!!foundFirstNameParam).equals(true); - }); - - it('Should `email` be required.', async () => { - const user = await tenantFactory.create('user'); - const res = await request() - .post(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - - const foundEmailParam = res.body.errors.find((error) => error.param === 'email'); - expect(!!foundEmailParam).equals(true); - }); - - it('Should be `email` be valid format.', async () => { - const user = await tenantFactory.create('user'); - const res = await request() - .post(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - first_name: user.first_name, - last_name: user.last_name, - email: 'email', - phone_number: user.phone_number, - status: 1, - }); - - expect(res.status).equals(422); - - const foundEmailParam = res.body.errors.find((error) => error.param === 'email'); - expect(!!foundEmailParam).equals(true); - }); - - it('Should `phone_number` be valid format.', async () => { - const user = tenantFactory.create('user'); - const res = await request() - .post(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - first_name: user.first_name, - last_name: user.last_name, - email: user.email, - phone_number: 'phone_number', - status: 1, - }); - - expect(res.status).equals(422); - - const phoneNumberParam = res.body.errors.find((error) => error.param === 'phone_number'); - expect(!!phoneNumberParam).equals(true); - }); - }); - - describe('GET: `/users/:id`', () => { - it('Should not success if the user was not authorized.', async () => { - const res = await request().get('/api/users/1'); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response not found if the user was not exist.', async () => { - const res = await request() - .get('/api/users/10') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - }); - - it('Should response success if the user was exist.', async () => { - const user = await tenantFactory.create('user'); - const res = await request() - .get(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - }); - }); - - describe('DELETE: `/users/:id`', () => { - it('Should not success if the user was not authorized.', async () => { - const res = await request().delete('/api/users/1'); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response not found if the user was not exist.', async () => { - const res = await request() - .delete('/api/users/10') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'USER_NOT_FOUND', code: 100, - }); - }); - - it('Should response success if the user was exist.', async () => { - const user = await tenantFactory.create('user'); - const res = await request() - .delete(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - }); - - it('Should delete the give user from the storage.', async () => { - const user = await tenantFactory.create('user'); - await request() - .delete(`/api/users/${user.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - const storedUsers = await knex('users').where('id', user.id); - expect(storedUsers).to.have.lengthOf(0); - }); - }); -}); diff --git a/packages/server/tests/routes/vendors.test.js b/packages/server/tests/routes/vendors.test.js deleted file mode 100644 index 0fb1661c2..000000000 --- a/packages/server/tests/routes/vendors.test.js +++ /dev/null @@ -1,193 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import Currency from 'models/Currency'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import Vendor from 'models/Vendor'; - -describe('route: `/vendors`', () => { - describe('POST: `/vendors`', () => { - it('Should response unauthorized in case the user was not logged in.', async () => { - const res = await request() - .post('/api/vendors') - .send({}); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `display_name` be required field.', async () => { - const res = await request() - .post('/api/vendors') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - - }); - - expect(res.status).equals(422); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'display_name', location: 'body', - }) - }); - - it('Should store the vendor data to the storage.', async () => { - const res = await request() - .post('/api/vendors') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - first_name: 'Ahmed', - last_name: 'Bouhuolia', - - company_name: 'Bigcapital', - - display_name: 'Ahmed Bouhuolia, Bigcapital', - - email: 'a.bouhuolia@live.com', - work_phone: '0927918381', - personal_phone: '0925173379', - - billing_address_city: 'Tripoli', - billing_address_country: 'Libya', - billing_address_email: 'a.bouhuolia@live.com', - billing_address_state: 'State Tripoli', - billing_address_zipcode: '21892', - - shipping_address_city: 'Tripoli', - shipping_address_country: 'Libya', - shipping_address_email: 'a.bouhuolia@live.com', - shipping_address_state: 'State Tripoli', - shipping_address_zipcode: '21892', - - note: '__desc__', - - active: true, - }); - - expect(res.status).equals(200); - - const foundVendor = await Vendor.tenant().query().where('id', res.body.id); - - expect(foundVendor[0].firstName).equals('Ahmed'); - expect(foundVendor[0].lastName).equals('Bouhuolia'); - expect(foundVendor[0].companyName).equals('Bigcapital'); - expect(foundVendor[0].displayName).equals('Ahmed Bouhuolia, Bigcapital'); - - expect(foundVendor[0].email).equals('a.bouhuolia@live.com'); - - expect(foundVendor[0].workPhone).equals('0927918381'); - expect(foundVendor[0].personalPhone).equals('0925173379'); - - expect(foundVendor[0].billingAddressCity).equals('Tripoli'); - expect(foundVendor[0].billingAddressCountry).equals('Libya'); - expect(foundVendor[0].billingAddressEmail).equals('a.bouhuolia@live.com'); - expect(foundVendor[0].billingAddressState).equals('State Tripoli'); - expect(foundVendor[0].billingAddressZipcode).equals('21892'); - - expect(foundVendor[0].shippingAddressCity).equals('Tripoli'); - expect(foundVendor[0].shippingAddressCountry).equals('Libya'); - expect(foundVendor[0].shippingAddressEmail).equals('a.bouhuolia@live.com'); - expect(foundVendor[0].shippingAddressState).equals('State Tripoli'); - expect(foundVendor[0].shippingAddressZipcode).equals('21892'); - }); - }); - - describe('GET: `/vendors/:id`', () => { - it('Should response not found in case the given vendor id was not exists on the storage.', async () => { - const res = await request() - .get('/api/vendors/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'VENDOR.NOT.FOUND', code: 200, - }); - }); - }); - - describe('GET: `vendors`', () => { - it('Should response vendors items', async () => { - await tenantFactory.create('vendor'); - await tenantFactory.create('vendor'); - - const res = await request() - .get('/api/vendors') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.vendors.results.length).equals(2); - }); - }); - - describe('DELETE: `/vendors/:id`', () => { - it('Should response not found in case the given vendor id was not exists on the storage.', async () => { - const res = await request() - .delete('/api/vendors/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'VENDOR.NOT.FOUND', code: 200, - }); - }); - - it('Should delete the given vendor from the storage.', async () => { - const vendor = await tenantFactory.create('vendor'); - const res = await request() - .delete(`/api/vendors/${vendor.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - - const foundVendor = await Vendor.tenant().query().where('id', vendor.id); - expect(foundVendor.length).equals(0); - }) - }); - - describe('POST: `/vendors/:id`', () => { - it('Should response vendor not found', async () => { - const res = await request() - .post('/api/vendors/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - display_name: 'Ahmed Bouhuolia, Bigcapital', - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.deep.equals({ - type: 'VENDOR.NOT.FOUND', code: 200, - }); - }); - - it('Should update details of the given vendor.', async () => { - const vendor = await tenantFactory.create('vendor'); - const res = await request() - .post(`/api/vendors/${vendor.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - display_name: 'Ahmed Bouhuolia, Bigcapital', - }); - - expect(res.status).equals(200); - const foundVendor = await Vendor.tenant().query().where('id', res.body.id); - - expect(foundVendor.length).equals(1); - expect(foundVendor[0].displayName).equals('Ahmed Bouhuolia, Bigcapital'); - }) - }); -}); diff --git a/packages/server/tests/routes/views.test.js b/packages/server/tests/routes/views.test.js deleted file mode 100644 index 0dedf29f6..000000000 --- a/packages/server/tests/routes/views.test.js +++ /dev/null @@ -1,936 +0,0 @@ -import { - request, - expect, -} from '~/testInit'; -import View from 'models/View'; -import ViewRole from 'models/ViewRole'; -import 'models/ResourceField'; -import ViewColumn from '../../src/models/ViewColumn'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; - - -describe('routes: `/views`', () => { - describe('GET: `/views`', () => { - it('Should response unauthorized in case the user was not authorized.', async () => { - const res = await request().get('/api/views'); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should retrieve all views of the given resource name.', async () => { - const resource = await tenantFactory.create('resource', { name: 'resource_name' }); - const resourceFields = await tenantFactory.create('view', { - name: 'Resource View', - resource_id: resource.id, - roles_logic_expression: '', - }); - - const res = await request() - .get('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .query({ resource_name: 'resource_name' }) - .send(); - - expect(res.status).equals(200); - expect(res.body.views.length).equals(1); - }); - }); - - describe('GET `/views/:id`', () => { - it('Should response unauthorized in case the user was not authorized.', async () => { - const resource = await tenantFactory.create('resource', { name: 'resource_name' }); - const resourceView = await tenantFactory.create('view', { - name: 'Resource View', - resource_id: resource.id, - roles_logic_expression: '', - }); - - const res = await request() - .get(`/api/views/${resourceView.id}`) - .query({ resource_name: 'resource_name' }) - .send(); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should response not found in case the given view was not found.', async () => { - const resource = await tenantFactory.create('resource', { name: 'resource_name' }); - const resourceView = await tenantFactory.create('view', { - name: 'Resource View', - resource_id: resource.id, - roles_logic_expression: '', - }); - - const res = await request() - .get('/api/views/123') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors[0]).deep.equals({ - type: 'VIEW_NOT_FOUND', code: 100, - }); - }); - - it('Should retrieve details of the given view with associated graphs.', async () => { - const resource = await tenantFactory.create('resource', { name: 'resource_name' }); - const resourceView = await tenantFactory.create('view', { - name: 'Resource View', - resource_id: resource.id, - roles_logic_expression: '1 AND 2', - }); - const resourceField = await tenantFactory.create('resource_field', { - label_name: 'Expense Account', - key: 'expense_account', - data_type: 'integer', - resource_id: resource.id, - active: true, - predefined: true, - builtin: true, - }); - const viewRole = await tenantFactory.create('view_role', { - view_id: resourceView.id, - index: 1, - field_id: resourceField.id, - value: '12', - comparator: 'equals', - }); - - const res = await request() - .get(`/api/views/${resourceView.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(200); - expect(res.body.view.name).equals(resourceView.name); - expect(res.body.view.resource_id).equals(resourceView.resourceId); - expect(res.body.view.roles_logic_expression).equals(resourceView.rolesLogicExpression); - - expect(res.body.view.roles.length).equals(1); - expect(res.body.view.roles[0].view_id).equals(viewRole.viewId); - }); - }); - - describe('POST: `/views`', () => { - it('Should response unauthorzied in case the user was not authorized.', async () => { - const res = await request().post('/api/views'); - - expect(res.status).equals(401); - expect(res.body.message).equals('Unauthorized'); - }); - - it('Should `name` be required.', async () => { - await tenantFactory.create('resource'); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'name', location: 'body', - }); - }); - - it('Should `resource_name` be required.', async () => { - await tenantFactory.create('resource'); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'resource_name', location: 'body', - }); - }); - - it('Should `columns` be minimum limited', async () => { - await tenantFactory.create('resource'); - const res = await request() - .post('/api/views', { - label: 'View Label', - columns: [], - }) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'columns', location: 'body', - }); - }); - - it('Should `columns` be array.', async () => { - await tenantFactory.create('resource'); - const res = await request() - .post('/api/views', { - label: 'View Label', - columns: 'not_array', - }) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'columns', location: 'body', - }); - }); - - it('Should `roles.*.field_key` be required.', async () => { - const resource = await tenantFactory.create('resource'); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - label: 'View Label', - roles: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'roles[0].field_key', location: 'body', - }); - }); - - it('Should `roles.*.comparator` be valid.', async () => { - const resource = await tenantFactory.create('resource'); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - label: 'View Label', - roles: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - - const paramsErrors = res.body.errors.map((error) => error.param); - expect(paramsErrors).to.include('roles[0].comparator'); - }); - - it('Should `roles.*.index` be number as integer.', async () => { - const resource = await tenantFactory.create('resource'); - const res = await request() - .post('/api/views') - .send({ - resource_name: resource.name, - label: 'View Label', - roles: [ - { index: 'not_numeric' }, - ], - }) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - value: 'not_numeric', - msg: 'Invalid value', - param: 'roles[0].index', - location: 'body', - }); - }); - - it('Should response not found in case resource was not exist.', async () => { - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: 'not_found', - name: 'View Label', - columns: [ - { key: 'amount', index: 1 }, - { key: 'thumbnail', index: 1 }, - { key: 'status', index: 1 }, - ], - roles: [{ - index: 1, - field_key: 'amount', - comparator: 'equals', - value: '100', - }], - logic_expression: '1', - }); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'RESOURCE_NOT_FOUND', code: 100, - }); - }); - - it('Should response invalid logic expression.', async () =>{ - const resource = await tenantFactory.create('resource'); - await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - logic_expression: '100 && 100', - name: 'View Label', - columns: [ - { key: 'amount', index: 1 }, - ], - roles: [{ - index: 1, - field_key: 'amount', - comparator: 'equals', - value: '100', - }], - }); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'VIEW.ROLES.LOGIC.EXPRESSION.INVALID', code: 400, - }); - }); - - it('Should response the roles fields not exist in case role field was not exist.', async () => { - const resource = await tenantFactory.create('resource'); - await tenantFactory.create('resource_field', { resource_id: resource.id, label_name: 'Amount' }); - - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - name: 'View Label', - logic_expression: '1', - columns: [ - { key: 'amount', index: 1 }, - { key: 'thumbnail', index: 1 }, - { key: 'status', index: 1 }, - ], - roles: [{ - index: 1, - field_key: 'price', - comparator: 'equals', - value: '100', - }], - }); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'RESOURCE_FIELDS_NOT_EXIST', code: 100, fields: ['price'], - }); - }); - - it('Should response the columns that not exists in case column was not exist.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - name: 'View Label', - logic_expression: '1', - columns: [ - { key: 'amount', index: 1 }, - { key: 'thumbnail', index: 2 }, - { key: 'status', index: 3 }, - ], - roles: [{ - index: 1, - field_key: 'price', - comparator: 'equals', - value: '100', - }], - }); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'COLUMNS_NOT_EXIST', code: 200, columns: ['thumbnail', 'status'], - }); - }); - - it('Should save the given details of the view.', async () => { - const resource = await tenantFactory.create('resource'); - await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - name: 'View Label', - logic_expression: '1', - columns: [ - { key: 'amount', index: 1 }, - ], - roles: [{ - index: 1, - field_key: 'amount', - comparator: 'equals', - value: '100', - }], - }); - - const storedView = await View.tenant().query().where('name', 'View Label').first(); - - expect(storedView.name).equals('View Label'); - expect(storedView.predefined).equals(0); - expect(storedView.resourceId).equals(resource.id); - }); - - it('Should save the given details of view fields that associated to the given view id.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - name: 'View Label', - columns: [{ key: 'amount', index: 1 }], - logic_expression: '1', - roles: [{ - index: 1, - field_key: 'amount', - comparator: 'equals', - value: '100', - }], - }); - - const viewRoles = await ViewRole.tenant().query().where('view_id', res.body.id); - - expect(viewRoles.length).equals(1); - expect(viewRoles[0].index).equals(1); - expect(viewRoles[0].fieldId).equals(resourceField.id); - expect(viewRoles[0].value).equals('100'); - expect(viewRoles[0].comparator).equals('equals'); - }); - - it('Should save columns that associated to the given view.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - - const res = await request() - .post('/api/views') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - resource_name: resource.name, - name: 'View Label', - logic_expression: '1', - columns: [ - { key: 'amount', index: 1 }, - ], - roles: [{ - index: 1, - field_key: 'amount', - comparator: 'equals', - value: '100', - }], - }); - - const viewColumns = await ViewColumn.tenant().query().where('view_id', res.body.id); - expect(viewColumns.length).equals(1); - }); - - - }); - - describe('POST: `/views/:view_id`', () => { - it('Should `name` be required.', async () => { - const view = await tenantFactory.create('view'); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'name', location: 'body', - }); - }); - - it('Should columns be minimum limited', async () => { - const view = await tenantFactory.create('view'); - const res = await request() - .post(`/api/views/${view.id}`, { - label: 'View Label', - columns: [], - }) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'columns', location: 'body', - }); - }); - - it('Should columns be array.', async () => { - const view = await tenantFactory.create('view'); - const res = await request() - .post(`/api/views/${view.id}`, { - label: 'View Label', - columns: 'not_array', - }) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - columns: 'columns' - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'columns', location: 'body', value: 'columns', - }); - }); - - it('Should `roles.*.field_key` be required.', async () => { - const view = await tenantFactory.create('view'); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - label: 'View Label', - roles: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'roles[0].field_key', location: 'body', - }); - }); - - it('Should `roles.*.comparator` be required.', async () => { - const view = await tenantFactory.create('view'); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - label: 'View Label', - roles: [{}], - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', param: 'roles[0].comparator', location: 'body', - }); - }); - - it('Should `roles.*.index` be number as integer.', async () => { - const view = await tenantFactory.create('view'); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - label: 'View Label', - roles: [{ index: 'not_numeric' }], - }); - - expect(res.status).equals(422); - expect(res.body.code).equals('validation_error'); - expect(res.body.errors).include.something.deep.equals({ - msg: 'Invalid value', - param: 'roles[0].index', - location: 'body', - value: 'not_numeric', - }); - }); - - it('Should response the roles fields not exist in case role field was not exist.', async () => { - const view = await tenantFactory.create('view'); - await tenantFactory.create('resource_field', { - resource_id: view.resource_id, - label_name: 'Amount', - }); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: 'amount', - index: 1, - }, { - key: 'thumbnail', - index: 2, - }, { - key: 'status', - index: 3, - }], - roles: [{ - index: 1, - field_key: 'price', - comparator: 'equals', - value: '100', - }], - }); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'RESOURCE_FIELDS_NOT_EXIST', code: 100, fields: ['price'], - }); - }); - - it('Should response the resource columns not exists in case the column keys was not exist.', async () => { - const view = await tenantFactory.create('view'); - await tenantFactory.create('resource_field', { - resource_id: view.resource_id, - label_name: 'Amount', - }); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: 'amount', - index: 1, - }, { - key: 'thumbnail', - index: 2, - }, { - key: 'status', - index: 3, - }], - roles: [{ - index: 1, - field_key: 'price', - comparator: 'equals', - value: '100', - }], - }); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'RESOURCE_COLUMNS_NOT_EXIST', - code: 200, - columns: ['amount', 'thumbnail', 'status'], - }); - }); - - it('Should validate the logic expressions with the given conditions.', () => { - - }); - - it('Should delete the view roles that not presented the post data.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - - const view = await tenantFactory.create('view', { resource_id: resource.id }); - const viewRole = await tenantFactory.create('view_role', { - view_id: view.id, - field_id: resourceField.id, - }); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: resourceField.key, - index: 1, - }], - roles: [{ - index: 1, - field_key: resourceField.key, - comparator: 'equals', - value: '100', - }], - }); - - const foundViewRole = await ViewRole.tenant().query().where('id', viewRole.id); - expect(foundViewRole.length).equals(0); - }); - - it('Should update the view roles that presented in the given data.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - - const view = await tenantFactory.create('view', { resource_id: resource.id }); - const viewRole = await tenantFactory.create('view_role', { - view_id: view.id, - field_id: resourceField.id, - }); - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: resourceField.key, - index: 1, - }], - roles: [{ - id: viewRole.id, - index: 1, - field_key: resourceField.key, - comparator: 'equals', - value: '100', - }], - }); - - const foundViewRole = await ViewRole.tenant().query().where('id', viewRole.id); - - expect(foundViewRole.length).equals(1); - expect(foundViewRole[0].id).equals(viewRole.id); - expect(foundViewRole[0].index).equals(1); - expect(foundViewRole[0].value).equals('100'); - expect(foundViewRole[0].comparator).equals('equals'); - }); - - it('Should response not found roles ids in case not exists in the storage.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const view = await tenantFactory.create('view', { resource_id: resource.id }); - - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: resourceField.key, - index: 1, - }], - roles: [{ - id: 1, - index: 1, - field_key: resourceField.key, - comparator: 'equals', - value: '100', - }], - }); - - expect(res.body.errors).include.something.that.deep.equals({ - type: 'VIEW.ROLES.IDS.NOT.FOUND', code: 500, ids: [1], - }); - }); - - it('Should delete columns from storage in case view columns ids not presented.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const view = await tenantFactory.create('view', { resource_id: resource.id }); - const viewColumn = await tenantFactory.create('view_column', { view_id: view.id }); - - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: resourceField.key, - index: 1, - }], - roles: [{ - index: 1, - field_key: resourceField.key, - comparator: 'equals', - value: '100', - }], - }); - const foundViewColumns = await ViewColumn.tenant().query().where('id', viewColumn.id); - expect(foundViewColumns.length).equals(0); - }); - - it('Should insert columns to the storage if where new columns', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const view = await tenantFactory.create('view', { resource_id: resource.id }); - - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - key: resourceField.key, - index: 1, - }], - roles: [{ - index: 1, - field_key: resourceField.key, - comparator: 'equals', - value: '100', - }], - }); - - const foundViewColumns = await ViewColumn.tenant().query().where('view_id', view.id); - - expect(foundViewColumns.length).equals(1); - expect(foundViewColumns[0].viewId).equals(view.id); - expect(foundViewColumns[0].index).equals(1); - expect(foundViewColumns[0].fieldId).equals(resourceField.id); - }); - - - it('Should update columns on the storage.', async () => { - const resource = await tenantFactory.create('resource'); - const resourceField = await tenantFactory.create('resource_field', { - resource_id: resource.id, - label_name: 'Amount', - key: 'amount', - }); - const view = await tenantFactory.create('view', { resource_id: resource.id }); - const viewColumn = await tenantFactory.create('view_column', { view_id: view.id }); - - const res = await request() - .post(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send({ - name: 'View Label', - logic_expression: '1', - columns: [{ - id: viewColumn.id, - key: resourceField.key, - index: 10, - }], - roles: [{ - index: 1, - field_key: resourceField.key, - comparator: 'equals', - value: '100', - }], - }); - - console.log(res.body) - - const foundViewColumns = await ViewColumn.tenant().query().where('id', viewColumn.id); - - expect(foundViewColumns.length).equals(1); - expect(foundViewColumns[0].id).equals(viewColumn.id); - expect(foundViewColumns[0].viewId).equals(view.id); - expect(foundViewColumns[0].index).equals(10); - // expect(foundViewColumns[0].fieldId).equals(); - }) - }); - - describe('DELETE: `/views/:resource_id`', () => { - it('Should not delete predefined view.', async () => { - const view = await tenantFactory.create('view', { predefined: true }); - const res = await request() - .delete(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(400); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'PREDEFINED_VIEW', code: 200, - }); - }); - - it('Should response not found in case view was not exist.', async () => { - const res = await request() - .delete('/api/views/100') - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.status).equals(404); - expect(res.body.errors).include.something.that.deep.equals({ - type: 'VIEW_NOT_FOUND', code: 100, - }); - }); - - it('Should delete the given view and associated view columns and roles.', async () => { - const view = await tenantFactory.create('view', { predefined: false }); - await tenantFactory.create('view_role', { view_id: view.id }); - await tenantFactory.create('view_column', { view_id: view.id }); - - const res = await request() - .delete(`/api/views/${view.id}`) - .set('x-access-token', loginRes.body.token) - .set('organization-id', tenantWebsite.organizationId) - .send(); - - expect(res.body.id).equals(view.id); - - const foundViews = await View.tenant().query().where('id', view.id); - const foundViewRoles = await ViewRole.tenant().query().where('view_id', view.id); - - expect(foundViews).to.have.lengthOf(0); - expect(foundViewRoles).to.have.lengthOf(0); - }); - }); -}); diff --git a/packages/server/tests/services/JournalPoster.test.js b/packages/server/tests/services/JournalPoster.test.js deleted file mode 100644 index 171dc8cf7..000000000 --- a/packages/server/tests/services/JournalPoster.test.js +++ /dev/null @@ -1,406 +0,0 @@ -import { expect } from '~/testInit'; -import JournalPoster from '@/services/Accounting/JournalPoster'; -import JournalEntry from '@/services/Accounting/JournalEntry'; -import AccountBalance from 'models/AccountBalance'; -import AccountTransaction from 'models/AccountTransaction'; -import Account from 'models/Account'; -import { - tenantWebsite, - tenantFactory, - loginRes -} from '~/dbInit'; -import { omit } from 'lodash'; -import DependencyGraph from '@/lib/DependencyGraph'; - -let accountsDepGraph; - -describe('JournalPoster', () => { - beforeEach(async () => { - accountsDepGraph = await Account.tenant().depGraph().query().remember(); - }); - describe('credit()', () => { - it('Should write credit entry to journal entries stack.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - credit: 100, - account: 1, - }); - journalEntries.credit(journalEntry); - expect(journalEntries.entries.length).equals(1); - }); - }); - - describe('debit()', () => { - it('Should write debit entry to journal entries stack.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 100, - account: 1, - }); - - journalEntries.debit(journalEntry); - expect(journalEntries.entries.length).equals(1); - }); - }); - - describe('setBalanceChange()', () => { - it('Should increment balance amount after credit entry with credit normal account.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - credit: 100, - debit: 0, - account: 1, - accountNormal: 'debit', - }); - journalEntries.credit(journalEntry); - expect(journalEntries.balancesChange).to.have.property(1, -100); - }); - - it('Should decrement balance amount after debit entry wiht debit normal account.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 100, - account: 1, - accountNormal: 'debit', - }); - journalEntries.debit(journalEntry); - expect(journalEntries.balancesChange).to.have.property(1, 100); - }); - }); - - describe('setContactAccountBalance', () => { - it('Should increment balance amount after credit/debit entry.', () => { - - }); - - it('Should decrement balance amount after credit/debit customer/vendor entry.', () => { - - }); - }); - - describe('saveEntries()', () => { - it('Should save all stacked entries to the storage.', async () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 100, - account: 1, - accountNormal: 'debit', - }); - - journalEntries.debit(journalEntry); - await journalEntries.saveEntries(); - - const storedJournalEntries = await AccountTransaction.tenant().query(); - - expect(storedJournalEntries.length).equals(1); - expect(storedJournalEntries[0]).to.deep.include({ - referenceType: 'Expense', - referenceId: 1, - debit: 100, - credit: 0, - accountId: 1, - }); - }); - }); - - describe('saveBalance()', () => { - it('Should save account balance increment.', async () => { - const account = await tenantFactory.create('account'); - const depGraph = await Account.tenant().depGraph().query(); - - const journalEntries = new JournalPoster(depGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 100, - account: account.id, - accountNormal: 'debit', - }); - journalEntries.debit(journalEntry); - - await journalEntries.saveBalance(); - - const storedAccountBalance = await AccountBalance.tenant().query(); - - expect(storedAccountBalance.length).equals(1); - expect(storedAccountBalance[0].amount).equals(100); - }); - - it('Should save account balance decrement.', async () => { - const account = await tenantFactory.create('account'); - const depGraph = await Account.tenant().depGraph().query(); - - const journalEntries = new JournalPoster(depGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - credit: 100, - account: account.id, - accountNormal: 'debit', - }); - journalEntries.credit(journalEntry); - - await journalEntries.saveBalance(); - - const storedAccountBalance = await AccountBalance.tenant().query(); - - expect(storedAccountBalance.length).equals(1); - expect(storedAccountBalance[0].amount).equals(-100); - }); - }); - - describe('getClosingBalance', () => { - it('Should retrieve closing balance the given account id.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 100, - account: 1, - accountNormal: 'debit', - date: '2020-1-10', - }); - const journalEntry2 = new JournalEntry({ - referenceId: 1, - referenceType: 'Income', - credit: 100, - account: 2, - accountNormal: 'credit', - date: '2020-1-12', - }); - journalEntries.credit(journalEntry); - journalEntries.credit(journalEntry2); - - const closingBalance = journalEntries.getClosingBalance(1, '2020-1-30'); - expect(closingBalance).equals(100); - }); - - it('Should retrieve closing balance the given closing date period.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 100, - account: 1, - accountNormal: 'debit', - date: '2020-1-10', - }); - const journalEntry2 = new JournalEntry({ - referenceId: 1, - referenceType: 'Income', - credit: 100, - account: 2, - accountNormal: 'credit', - date: '2020-1-12', - }); - journalEntries.credit(journalEntry); - journalEntries.credit(journalEntry2); - - const closingBalance = journalEntries.getClosingBalance(1, '2020-1-2'); - expect(closingBalance).equals(0); - }); - }); - - describe('getTrialBalance(account, closeDate, dateType)', () => { - it('Should retrieve the trial balance of the given account id.', () => { - const journalEntries = new JournalPoster(accountsDepGraph); - const journalEntry = new JournalEntry({ - referenceId: 1, - referenceType: 'Expense', - debit: 200, - account: 1, - accountNormal: 'debit', - date: '2020-1-10', - }); - const journalEntry2 = new JournalEntry({ - referenceId: 1, - referenceType: 'Income', - credit: 100, - account: 1, - accountNormal: 'credit', - date: '2020-1-12', - }); - - journalEntries.debit(journalEntry); - journalEntries.credit(journalEntry2); - - const trialBalance = journalEntries.getTrialBalance(1); - - expect(trialBalance.credit).equals(100); - expect(trialBalance.debit).equals(200); - }); - }); - - describe('groupingEntriesByDate(accountId, dateGroupType)', () => { - - }); - - describe('removeEntries', () => { - it('Should remove all entries in the collection.', () => { - const journalPoster = new JournalPoster(accountsDepGraph); - const journalEntry1 = new JournalEntry({ - id: 1, - credit: 1000, - account: 1, - accountNormal: 'credit', - }); - const journalEntry2 = new JournalEntry({ - id: 2, - debit: 1000, - account: 2, - accountNormal: 'debit', - }); - journalPoster.credit(journalEntry1); - journalPoster.debit(journalEntry2); - - journalPoster.removeEntries(); - - expect(journalPoster.entries.length).equals(0); - }); - - it('Should remove the given entries ids from the collection.', () => { - const journalPoster = new JournalPoster(accountsDepGraph); - const journalEntry1 = new JournalEntry({ - id: 1, - credit: 1000, - account: 1, - accountNormal: 'credit', - }); - const journalEntry2 = new JournalEntry({ - id: 2, - debit: 1000, - account: 2, - accountNormal: 'debit', - }); - journalPoster.credit(journalEntry1); - journalPoster.debit(journalEntry2); - - journalPoster.removeEntries([1]); - expect(journalPoster.entries.length).equals(1); - }); - - it('Should the removed entries ids be stacked to deleted entries ids.', () => { - const journalPoster = new JournalPoster(accountsDepGraph); - const journalEntry1 = new JournalEntry({ - id: 1, - credit: 1000, - account: 1, - accountNormal: 'credit', - }); - const journalEntry2 = new JournalEntry({ - id: 2, - debit: 1000, - account: 2, - accountNormal: 'debit', - }); - journalPoster.credit(journalEntry1); - journalPoster.debit(journalEntry2); - - journalPoster.removeEntries(); - - expect(journalPoster.deletedEntriesIds.length).equals(2); - expect(journalPoster.deletedEntriesIds[0]).equals(1); - expect(journalPoster.deletedEntriesIds[1]).equals(2); - }); - - it('Should revert the account balance after remove the entries.', () => { - const journalPoster = new JournalPoster(accountsDepGraph); - const journalEntry1 = new JournalEntry({ - id: 1, - credit: 1000, - account: 1, - accountNormal: 'credit', - }); - const journalEntry2 = new JournalEntry({ - id: 2, - debit: 1000, - account: 2, - accountNormal: 'debit', - }); - journalPoster.credit(journalEntry1); - journalPoster.debit(journalEntry2); - - journalPoster.removeEntries([1]); - - expect(journalPoster.balancesChange['1']).equals(0); - expect(journalPoster.balancesChange['2']).equals(1000); - }) - }); - - describe('deleteEntries', () => { - it('Should delete all entries from the storage based on the stacked deleted entries ids.', () => { - - }); - }); - - describe('effectParentAccountsBalance()', () => { - it('Should all parent accounts increment after one of child accounts balance increment.', async () => { - const debitType = await tenantFactory.create('account_type', { normal: 'debit', balance_sheet: true }); - const mixin = { account_type_id: debitType.id }; - - const accountA = await tenantFactory.create('account', { ...mixin }); - const accountB = await tenantFactory.create('account', { ...mixin }); - - const accountAC = await tenantFactory.create('account', { parent_account_id: accountA.id, ...mixin }); - const accountBD = await tenantFactory.create('account', { ...mixin }); - - const depGraph = await Account.tenant().depGraph().query(); - const journalPoster = new JournalPoster(depGraph); - const journalEntryA = new JournalEntry({ - id: 1, - debit: 1000, - account: accountAC.id, - accountNormal: 'debit', - }); - const journalEntryB = new JournalEntry({ - id: 1, - debit: 1000, - account: accountBD.id, - accountNormal: 'debit', - }); - - journalPoster.debit(journalEntryA); - journalPoster.debit(journalEntryB); - - await journalPoster.saveBalance(); - - const accountBalances = await AccountBalance.tenant().query(); - const simplifiedArray = accountBalances.map(x => ({ ...omit(x, ['id']) })); - - expect(simplifiedArray.length).equals(3); - expect(simplifiedArray).to.include.something.deep.equals({ - accountId: accountA.id, - amount: 1000, - currencyCode: 'USD' - }); - expect(simplifiedArray).to.include.something.deep.equals({ - accountId: accountAC.id, - amount: 1000, - currencyCode: 'USD' - }); - expect(simplifiedArray).to.include.something.deep.equals({ - accountId: accountBD.id, - amount: 1000, - currencyCode: 'USD' - }); - }); - }); - - describe('reverseEntries()', () => { - - }); - - describe('loadFromCollection', () => { - - }); -}); diff --git a/packages/server/tests/testInit.js b/packages/server/tests/testInit.js deleted file mode 100644 index 23750a6eb..000000000 --- a/packages/server/tests/testInit.js +++ /dev/null @@ -1,88 +0,0 @@ -import chai from 'chai'; -import chaiHttp from 'chai-http'; -import chaiThings from 'chai-things'; -import systemDb from '@/database/knex'; -import app from 'app'; -import createTenantFactory from '@/database/factories'; -import TenantsManager from '@/system/TenantsManager'; -import faker from 'faker'; -import { hashPassword } from 'utils'; -import TenantModel from 'models/TenantModel'; -import createSystemFactory from '@/database/factories/system'; - - -const { expect } = chai; -const request = () => chai.request(app); - -beforeEach(async () => { - // Rollback/migrate the system database. - await systemDb.migrate.rollback(); - await systemDb.migrate.latest(); -}); - -afterEach(async () => { -}); - -chai.use(chaiHttp); -chai.use(chaiThings); - -// Create tenant database. -const createTenant = () => { - return TenantsManager.createTenant(); -}; - -// Drops tenant database. -const dropTenant = async (tenantWebsite) => { - return TenantsManager.dropTenant(tenantWebsite); -}; - -// Create a new user that associate to the given tenant Db. -const createUser = async (tenantWebsite, givenUser) => { - const userPassword = (givenUser && givenUser.password) ? givenUser.password : 'admin' - const hashedPassword = await hashPassword(userPassword); - - const userInfo = { - first_name: faker.lorem.word(), - last_name: faker.lorem.word(), - email: faker.internet.email(), - active: 1, - phone_number: faker.phone.phoneNumberFormat().replace('-', ''), - password: hashedPassword, - ...givenUser, - }; - const user = await TenantsManager.createTenantUser(tenantWebsite, userInfo); - return user; -}; - -const login = async (tenantWebsite, givenUser) => { - let user = givenUser; - - if (!givenUser && tenantWebsite) { - const createdUser = await createUser(tenantWebsite, givenUser); - user = createdUser; - } - return request() - .post('/api/auth/login') - .send({ - crediential: user.email, - password: 'admin', - }); -}; - -const bindTenantModel = (tenantDb) => { - TenantModel.knexBinded = tenantDb; -}; - -const systemFactory = createSystemFactory(); - -export { - login, - systemFactory, - createTenantFactory, - createTenant, - createUser, - dropTenant, - expect, - request, - bindTenantModel, -}; diff --git a/packages/server/tests/utils/utils.test.js b/packages/server/tests/utils/utils.test.js deleted file mode 100644 index 4dc6ae640..000000000 --- a/packages/server/tests/utils/utils.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { dateRangeCollection } from 'utils'; -import { expect } from '../testInit'; - -describe('utils', () => { - - describe('dateRangeCollection()', () => { - it('Should retrieve all range dates.', () => { - const fromDate = new Date('2020-1-1'); - const toDate = new Date('2020-1-25'); - - const range = dateRangeCollection(fromDate, toDate); - - expect(range.length).equals(25); - }); - }); -}); diff --git a/packages/server-nest/tsconfig.build.json b/packages/server/tsconfig.build.json similarity index 100% rename from packages/server-nest/tsconfig.build.json rename to packages/server/tsconfig.build.json diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 8312fd145..5f0ef4040 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -1,36 +1,25 @@ { "compilerOptions": { - "target": "es2017", - "lib": [ - "es2017", - "esnext.asynciterable" - ], - "typeRoots": [ - "./node_modules/@types", - "./src/types" - ], - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", "module": "commonjs", - "pretty": true, + "declaration": false, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2021", "sourceMap": true, - "outDir": "./build", - "allowJs": true, - "noEmit": false, - "esModuleInterop": true, - "baseUrl": "./src", + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": false, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": false, + "noFallthroughCasesInSwitch": false, "paths": { - "@/*": ["./*"] - }, - }, - "include": [ - "./src/**/*" - ], - "exclude": [ - "./node_modules", - "tests" - ] -} \ No newline at end of file + "@/*": ["./src/*"], + "@bigcapital/server/*": ["../server/*"] + } + } +} diff --git a/packages/server/views/.DS_Store b/packages/server/views/.DS_Store deleted file mode 100644 index 68b620314e225fdd5ffdfcff627bfbe7216423f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKJ8r^25S>XVkZ33=_W~5T!O9{h-~tpzP!N#fB(vUr~nn90#x8Z1+4eN=8Hf^DnJFOz@Gy4eJF6ln%D>Wrvt%9 z0N@O1H>`b@02WICYhoXW3`~Ox465dcp+QH!WL-_{1A{J_!-wXRH76AHr{nzM<)Sr^ zkqS_Op#rb5U0VNthu@k1ha~Q(02TOG3g~RJ-86Wm?5(4hvtC=^JGj+c;bvGn1;N`f j(AzOK){a+R6m`YcxL*_dK&K<`bRd5QOcxpzc(wvJKgAW7 diff --git a/packages/server/views/demo-sheets/Expenses.csv b/packages/server/views/demo-sheets/Expenses.csv deleted file mode 100644 index 137194144..000000000 --- a/packages/server/views/demo-sheets/Expenses.csv +++ /dev/null @@ -1,23 +0,0 @@ -Payment Date,Reference No.,Payment Account,Description,Currency Code,Exchange Rate,Expense Account,Amount,Line Description,Publish -2024-03-01,REF-1,Petty Cash,Vel et dolorem architecto veniam.,,,Office expenses,9000,Voluptates voluptas corporis vel.,T -2024-03-02,REF-2,Petty Cash,Id est molestias.,,,Office expenses,9000,Eos voluptatem cumque et voluptate reiciendis.,T -2024-03-03,REF-3,Petty Cash,Quam cupiditate at nihil dicta dignissimos non fugit illo.,,,Office expenses,9000,Hic alias rerum sed commodi dolores sint animi perferendis.,T -2024-03-04,REF-4,Petty Cash,Et voluptatem consequatur corrupti beatae sit.,,,Office expenses,9000,Exercitationem impedit praesentium et eaque.,T -2024-03-05,REF-5,Petty Cash,Illo aut ad id et non error et reiciendis optio.,,,Office expenses,9000,Accusantium modi consequuntur eaque consequatur deleniti consequuntur et qui.,T -2024-03-06,REF-6,Petty Cash,Ea consequatur placeat aut et enim.,,,Office expenses,9000,Itaque odio fugiat recusandae.,T -2024-03-07,REF-7,Petty Cash,A expedita consequatur sequi eveniet quos rerum.,,,Office expenses,9000,Quidem doloremque dignissimos totam dolor iure sed necessitatibus optio.,T -2024-03-08,REF-8,Petty Cash,Est libero deleniti animi delectus eligendi necessitatibus expedita fugit.,,,Office expenses,9000,Velit rerum aperiam mollitia ut eius error est quo aut.,T -2024-03-09,REF-9,Petty Cash,Ut dolor tempora quam consequuntur mollitia aut quos consectetur commodi.,,,Office expenses,9000,Culpa architecto ea vero nisi quis voluptas animi.,T -2024-03-10,REF-10,Petty Cash,Nihil hic soluta.,,,Office expenses,9000,Omnis recusandae ducimus vel.,T -2024-03-11,REF-11,Petty Cash,Aspernatur placeat odit asperiores et tempora quam.,,,Office expenses,9000,Sit tempora optio ullam velit beatae architecto et.,T -2024-03-12,REF-12,Petty Cash,Harum soluta sed.,,,Office expenses,9000,Nobis est earum saepe.,T -2024-03-13,REF-13,Petty Cash,Ea quod mollitia non illo dolores voluptatem distinctio.,,,Office expenses,9000,Sit eos dolores autem rerum voluptate quia ipsam.,T -2024-03-14,REF-14,Petty Cash,Et quod distinctio atque.,,,Office expenses,9000,Facilis sed expedita reiciendis.,T -2024-03-15,REF-15,Petty Cash,Omnis delectus tempore.,,,Office expenses,9000,Autem non reprehenderit placeat aut et quo.,T -2024-03-16,REF-16,Petty Cash,Dolores optio qui dolore quia aut explicabo eaque.,,,Office expenses,9000,Odit dolores ut.,T -2024-03-17,REF-17,Petty Cash,Odit quibusdam sunt in a quod error.,,,Office expenses,9000,Quo explicabo quae dolor enim nisi voluptas id et temporibus.,T -2024-03-18,REF-18,Petty Cash,Hic quibusdam officiis voluptatem facilis repellat molestiae non.,,,Office expenses,9000,Quo sit ea et itaque error.,T -2024-03-19,REF-19,Petty Cash,Dolor doloremque quia qui.,,,Office expenses,9000,Ut deleniti laboriosam et.,T -2024-03-20,REF-20,Petty Cash,Ad enim repellat sed et vero aliquid.,,,Office expenses,9000,Error in voluptas non quae quibusdam id excepturi illo neque.,T -2024-03-21,REF-21,Petty Cash,Doloribus ut excepturi.,,,Office expenses,9000,Sint magni et reiciendis harum praesentium vero sit blanditiis.,T -2024-03-22,REF-22,Petty Cash,Id rerum sunt et.,,,Office expenses,9000,Autem magnam eum error ex sunt temporibus exercitationem ullam est.,T \ No newline at end of file diff --git a/packages/server/views/demo-sheets/bank-transactions.csv b/packages/server/views/demo-sheets/bank-transactions.csv deleted file mode 100644 index f1bba69ac..000000000 --- a/packages/server/views/demo-sheets/bank-transactions.csv +++ /dev/null @@ -1,123 +0,0 @@ -Date,Amount,Description,Payee -2024-07-23,-48.25,CREDIT CARD PURCHASE SMART AND FINAL #1 ANAHEIM CA DATE 12/14 15277301931256 9 CARD 5, -2024-08-21,-21.77,PURCHASE AUTHORIZED ON 05/27 ROYAL FARMS 100 MONUMENT AVE A P NATIONAL HARBOR MD 0846248421604 CARD 44, -2024-08-21,-58,72116609 POS PURCHASE EARNIN RE SC 6 721582259, -2024-08-21,-70.61,Dunkin' Donuts, -2024-08-20,-52.34,Uber Eats, -2024-08-19,-15.47,Panera Bread, -2024-08-19,-4.79,5 PURCHASE-SIG DENNY'S 366992 EUGENE OR 6 039488, -2024-08-18,-186,American Airlines, -2024-08-18,-3,3947558 VISA PURCHASE PLAYSTUD 07057808 TAYLOR MI 8840321 748, -2024-08-18,-9.95,Bojangles, -2024-08-15,-134,GrubHub, -2024-08-15,-91.53,671 POS PURCHASE EARNIN RE SC 9671543 349619, -2024-08-15,-4.78,Popeyes, -2024-08-14,496,CASH DEPOSIT, -2024-08-14,-97.67,APPLE 857979823 NEWKIRK #4, -2024-08-07,-2.81,POS PUR 449399193 04/07 TIMESTAMP THE PIZZA PLACE 4205 NEW YORK NY 634330, -2024-08-06,-4.27,QUEENS BAR 35 E GRAND RIVER AVE #9 DETROIT MI CARD 29602991, -2024-08-06,-6.28,Walmart, -2024-08-06,-20.52,60904 PURCHASE-SIG 09/21 TIMESTAMP UPLIFT RE 9123348 562542 SC 63432961 3968766, -2024-08-06,-12.2,UBER 588639690 RIDE 05/12 CA 12095 DEBIT CARD PURCHASE 04/04 TIMESTAMP 8102241, -2024-08-05,-5.58,WITHDRAWAL 02178293119 POS POUR CHOICES, -2024-08-05,-25.98,Planet Fitness, -2024-08-05,-20,CASH APP TRANSFER, -2024-08-04,-38,WITHDRAWAL DEBIT CARD CONSUMER DEBIT PULSZ 252-291-2362 VA DATE 04/12 23978676735612 63546108 CARD 94353, -2024-08-04,-19,CASH APP TRANSFER, -2024-08-04,-3.25,MICROSOFT 979333884, -2024-08-03,-16,TOPGOLF 1010 GREENWOOD BLVD, -2024-08-03,-59.52,EFT DEBIT MICROSOFT XBOX CA 830 08/03 TIMESTAMP, -2024-08-03,-145.09,Venmo, -2024-08-03,-76.02,Albertsons, -2024-08-03,-9.79,STOP & SHOP #25402 WEST CALDWELL MODATE 01/24 31772803806094 17096869 CARD 34321 WITHDRAWAL DEBIT CARD, -2024-08-02,-103.44,Dunkin' Donuts, -2024-08-02,-72,Uber Eats, -2024-08-02,-143.93,Food Lion, -2024-08-02,-128.12,McDonald's, -2024-07-31,-37.47,CHECKCARD 538036 CLEO AI IN MOUNTAIN VIEWCA 172788892 RECURRING, -2024-07-30,-162.69,McDonald's, -2024-07-29,95,Brigit XX/XX #406735377 PMNT RCVD Brigit, -2024-07-29,-45.47,Starbucks, -2024-07-29,-595.11,INTERAC PURCHASE - 67200 TARGET #052, -2024-07-28,-89,TRANSFER PAYPAL ADD TO BALANCE INTERNET PAYMENT, -2024-07-27,-6.04,Krispy Kreme, -2024-07-27,-66.63,McDonald's, -2024-07-26,-133.56,CARD PURCHASE PAYBYPHONE 804665947 11/19, -2024-07-26,-10.02,70252237 AMAZON - LEN N, -2024-07-26,-5,BLAZE PIZZA #31 SIG PUR 9906, -2024-07-25,-30.9,CITGO, -2024-07-25,-69,Tropical Smoothie Cafe, -2024-07-24,-744,Internal Revenue Service, -2024-07-24,-15.61,Walmart, -2024-08-04,-38,WITHDRAWAL DEBIT CARD CONSUMER DEBIT, -2024-08-05,-5.58,WITHDRAWAL POS POUR, -2024-08-06,-6.28,Walmart, -2024-07-24,-15.61,Walmart, -2024-08-03,-145.09,Venmo, -2024-08-20,-52.34,Uber Eats, -2024-08-02,-72,Uber Eats, -2024-07-25,-69,Tropical Smoothie Cafe, -2024-07-28,-89,TRANSFER ADD TO BALANCE INTERNET PAYMENT, -2024-08-03,-76.02,Albertsons, -2024-08-18,-186,American Airlines, -2024-08-15,-91.53,POS PURCHASE EARNIN RE SC 9671543 349619, -2024-07-29,-95,PMNT RCVD Brigit, -2024-08-04,-19,CASH APP TRANSFER, -2024-08-05,-20,CASH APP TRANSFER, -2024-08-14,496,CASH DEPOSIT, -2024-07-31,-37.47,CHECKCARD 538036 CLEO AI IN MOUNTAIN VIEWCA, -2024-07-25,-30.9,Citgo, -2024-08-18,-9.95,Bojangles, -2024-07-24,-744,Internal Revenue Service, -2024-07-27,-6.04,Krispy Kreme, -2024-07-27,-66.63,McDonald's, -2024-07-30,-162.69,McDonald's, -2024-08-02,-128.12,McDonald's, -2024-08-04,-3.25,MICROSOFT, -2024-08-19,-15.47,Panera Bread, -2024-08-05,-25.98,Planet Fitness, -2024-08-15,-4.78,Popeyes, -2024-08-07,-2.81,POS PUR, -2024-08-21,-21.77,PURCHASE AUTHORIZED ON 05/27, -2024-07-29,-45.47,Starbucks, -2024-08-03,-9.79,WITHDRAWAL DEBIT CARD, -2024-08-03,-16,TOPGOLF 1010 GREENWOOD BLVD, -2024-08-04,-38,WITHDRAWAL DEBIT CARD CONSUMER DEBIT, -2024-08-05,-5.58,WITHDRAWAL POS POUR, -2024-08-06,-6.28,Walmart, -2024-07-24,-15.61,Walmart, -2024-08-03,-145.09,Venmo, -2024-08-20,-52.34,Uber Eats, -2024-08-02,-72,Uber Eats, -2024-07-25,-69,Tropical Smoothie Cafe, -2024-07-28,-89,TRANSFER ADD TO BALANCE INTERNET PAYMENT, -2024-08-03,-76.02,Albertsons, -2024-08-18,-186,American Airlines, -2024-08-15,-91.53,POS PURCHASE EARNIN RE SC 9671543 349619, -2024-07-29,-95,PMNT RCVD Brigit, -2024-08-04,-19,CASH APP TRANSFER, -2024-08-05,-20,CASH APP TRANSFER, -2024-08-14,496,CASH DEPOSIT, -2024-07-31,-37.47,CHECKCARD 538036 CLEO AI IN MOUNTAIN VIEWCA, -2024-07-25,-30.9,Citgo, -2024-08-18,-9.95,Bojangles, -2024-07-24,-744,Internal Revenue Service, -2024-07-27,-6.04,Krispy Kreme, -2024-07-27,-66.63,McDonald's, -2024-07-30,-162.69,McDonald's, -2024-08-02,-128.12,McDonald's, -2024-08-04,-3.25,MICROSOFT, -2024-08-19,-15.47,Panera Bread, -2024-08-05,-25.98,Planet Fitness, -2024-08-15,-4.78,Popeyes, -2024-08-07,-2.81,POS PUR, -2024-08-21,-21.77,PURCHASE AUTHORIZED ON 05/27, -2024-07-29,-45.47,Starbucks, -2024-08-03,-9.79,WITHDRAWAL DEBIT CARD, -2024-08-03,-16,TOPGOLF 1010 GREENWOOD BLVD, -2024-08-04,-38,WITHDRAWAL DEBIT CARD CONSUMER DEBIT, -2024-08-05,-5.58,WITHDRAWAL POS POUR, -2024-08-04,-3.25,MICROSOFT, -2024-08-07,-2.81,POS PUR, -2024-08-21,-21.77,PURCHASE AUTHORIZED ON 05/27, -2024-08-03,-9.79,WITHDRAWAL DEBIT CARD, \ No newline at end of file diff --git a/packages/server/views/demo-sheets/customers.csv b/packages/server/views/demo-sheets/customers.csv deleted file mode 100644 index 62e60eaab..000000000 --- a/packages/server/views/demo-sheets/customers.csv +++ /dev/null @@ -1,6 +0,0 @@ -Customer Type,First Name,Last Name,Company Name,Display Name,Email,Personal Phone Number,Work Phone Number,Website,Opening Balance,Opening Balance At,Opening Balance Ex. Rate,Currency,Active,Note,Billing Address 1,Billing Address 2,Billing Address City,Billing Address Country,Billing Address Phone,Billing Address Postcode,Billing Address State,Shipping Address 1,Shipping Address 2,Shipping Address City,Shipping Address Country,Shipping Address Phone,Shipping Address Postcode,Shipping Address State -Business,Nicolette,Schamberger,Homenick - Hane,Rowland Rowe,cicero86@yahoo.com,811-603-2235,906-993-5190,http://google.com,54302.23,2022-02-02,2,LYD,F,Doloribus autem optio temporibus dolores mollitia sit.,862 Jessika Well,1091 Dorthy Mount,Deckowfort,Ghana,825-011-5207,38228,Oregon,37626 Thiel Villages,132 Batz Avenue,Pagacburgh,Albania,171-546-3701,13709,Georgia -Business,Hermann,Crooks,Veum - Schaefer,Harley Veum,immanuel56@hotmail.com,449-780-9999,970-473-5785,http://google.com,54302.23,2022-02-02,2,LYD,T,Doloribus dolore dolor dicta vitae in fugit nisi quibusdam.,532 Simonis Spring,3122 Nicolas Inlet,East Matteofort,Holy See (Vatican City State),366-084-8629,41607,Montana,2889 Tremblay Plaza,71355 Kutch Isle,D'Amorehaven,Monaco,614-189-3328,09634-0435,Nevada -Business,Nellie,Gulgowski,"Boyle, Heller and Jones",Randall Kohler,anibal_frami@yahoo.com,498-578-0740,394-550-6827,http://google.com,54302.23,2022-02-02,2,LYD,T,Vero quibusdam rem fugit aperiam est modi.,214 Sauer Villages,30687 Kacey Square,Jayceborough,Benin,332-820-1127,16425-3887,Mississippi,562 Diamond Loaf,9595 Satterfield Trafficway,Alexandrinefort,Puerto Rico,776-500-8456,30258,South Dakota -Business,Stone,Jerde,"Cassin, Casper and Maggio",Clint McLaughlin,nathanael22@yahoo.com,562-790-6059,686-838-0027,http://google.com,54302.23,2022-02-02,2,LYD,F,Quis cumque molestias rerum.,22590 Cathy Harbor,24493 Brycen Brooks,Elnorashire,Andorra,701-852-8005,5680,Nevada,5355 Erdman Bridge,421 Jeanette Camp,East Philip,Venezuela,426-119-0858,34929-0501,Tennessee -Individual,Lempi,Kling,"Schamberger, O'Connell and Bechtelar",Alexie Barton,eulah.kreiger@hotmail.com,745-756-1063,965-150-1945,http://google.com,54302.23,2022-02-02,2,LYD,F,Maxime laboriosam hic voluptate maiores est officia.,0851 Jones Flat,845 Bailee Drives,Kamrenport,Niger,220-125-0608,30311,Delaware,929 Ferry Row,020 Adam Plaza,West Carmellaside,Ghana,053-333-6679,79221-4681,Illinois \ No newline at end of file diff --git a/packages/server/views/demo-sheets/items.csv b/packages/server/views/demo-sheets/items.csv deleted file mode 100644 index 8c0482a1f..000000000 --- a/packages/server/views/demo-sheets/items.csv +++ /dev/null @@ -1,61 +0,0 @@ -Item Type,Item Name,Item Code,Sellable,Purchasable,Cost Price,Sell Price,Cost Account,Sell Account,Inventory Account,Sell Description,Purchase Description,Category,Note,Active -Inventory,Amoxicillin and Clavulanatea,1000,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,At dolor est non tempore et quisquam.,TRUE -Inventory,Azithromycin,1001,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Id perspiciatis at adipisci minus accusamus dolor iure dolore.,TRUE -Inventory,Marks - Carroll,1002,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Odio odio minus similique.,TRUE -Inventory,"VonRueden, Ruecker and Hettinger",1003,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quibusdam dolores illo.,TRUE -Inventory,Aimovig SureClick Autoinjector,1004,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Labore atque quo nam natus ducimus.,TRUE -Inventory,Romaguera Group,1005,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Sit et aut rem necessitatibus.,TRUE -Inventory,Thompson - Reichert,1006,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Non non fuga esse fugit dolor soluta vel a.,TRUE -Inventory,AirDuo Digihaler with eModule,1007,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Error ut est soluta quos et qui.,TRUE -Inventory,"Reichert, Sanford and Shanahan",1008,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Nesciunt laboriosam nobis porro numquam hic expedita vel quod praesentium.,TRUE -Inventory,Crooks - Fay,1009,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Amet magni architecto voluptas itaque.,TRUE -Inventory,Becker - Kozey,1010,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Provident consequatur quos qui explicabo dicta nam.,TRUE -Inventory,Robel - Weber,1011,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quia cum eos rerum odio omnis quasi.,TRUE -Inventory,"Runte, Johns and Konopelski",1012,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Soluta et et accusantium corrupti autem repellendus assumenda fugit.,TRUE -Inventory,McCullough - Beer,1013,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quo quod sunt distinctio aliquid accusantium.,TRUE -Inventory,"Hintz, Wisozk and Mills",1014,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Asperiores esse at quos veritatis voluptas officiis.,TRUE -Inventory,"Zieme, Crist and Abbott",1015,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Ea ut qui architecto voluptates error.,TRUE -Inventory,Kiehn - Cormier,1016,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Libero sit impedit sint qui voluptatum id qui sed.,TRUE -Inventory,"Jast, Carter and Reynolds",1017,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Sint sunt quaerat nisi voluptate praesentium vero labore veniam quia.,TRUE -Inventory,Stehr Inc,1018,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Voluptas aut ipsum et iste.,TRUE -Inventory,"Friesen, Hamill and Hessel",1019,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Neque tenetur minima amet aut optio et recusandae vel ad.,TRUE -Inventory,Lemke - Hayes,1020,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Deleniti enim autem corrupti fuga quibusdam non.,TRUE -Inventory,Mirtazapine,1021,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Molestiae quia asperiores praesentium et voluptas iste sit et accusantium.,TRUE -Inventory,Medroxyprogesterone,1022,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Est quia omnis at.,TRUE -Inventory,Purdy and Sons,1023,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Veniam eos quibusdam neque consectetur eius aliquam.,TRUE -Inventory,"Zemlak, Kassulke and Veum",1024,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Vitae optio odit.,TRUE -Inventory,Kris LLC,1025,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Libero voluptatibus voluptatem quo.,TRUE -Inventory,"Jaskolski, Parker and Blanda",1026,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Laborum optio est voluptas dolores sunt voluptates.,TRUE -Inventory,Roberts Kilback,1027,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Ut illo molestiae dolore recusandae aut sequi molestiae fugit eum.,TRUE -Inventory,Olson Daugherty,1028,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Non est aut sit nulla nisi labore commodi delectus.,TRUE -Inventory,Hermann Inc,1029,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Commodi maxime minus dicta quia.,TRUE -Inventory,"Rowe, Nolan and Schaefer",1030,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quos et est eum odit quam omnis velit impedit tempora.,TRUE -Inventory,Cole - Lesch,1031,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Aut accusantium non.,TRUE -Inventory,"Emmerich, Prohaska and Schimmel",1032,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Doloribus aut qui sequi.,TRUE -Inventory,"Stracke, Champlin and Bayer",1033,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quisquam odio et et quod eum necessitatibus quaerat.,TRUE -Inventory,Spinka Okuneva,1034,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Rerum unde neque sit ut aut voluptas eum.,TRUE -Inventory,Swaniawski Muller,1035,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quia dolore minus voluptatibus modi.,TRUE -Inventory,Emard Satterfield,1036,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Nobis et nulla alias.,TRUE -Inventory,"Treutel, Muller and Sipes",1037,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Sit perspiciatis voluptate qui eos.,TRUE -Inventory,Cole and Sons,1038,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Qui sint ab iusto.,TRUE -Inventory,"Ullrich, Murazik and Roob",1039,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Explicabo sed maiores.,TRUE -Inventory,Dare and Sons,1040,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Aut eveniet omnis dolores labore qui delectus repellat.,TRUE -Inventory,Trantow and Sons,1041,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Animi rerum quaerat qui voluptas.,TRUE -Inventory,Dooley Price,1042,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Reiciendis beatae delectus qui corporis beatae autem modi laudantium.,TRUE -Inventory,"Shanahan, Considine and Towne",1043,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Molestiae nihil delectus eos.,TRUE -Inventory,"Moen, Mohr and Reilly",1044,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Dolor odio soluta eaque consequatur rerum iste vel.,TRUE -Inventory,Price Bradtke,1045,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Beatae autem illo ea alias ipsum nobis.,TRUE -Inventory,Fadel Toy,1046,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Et molestiae eum ut dolores.,TRUE -Inventory,Homenick Inc,1047,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Officia repellendus laboriosam iste quidem explicabo nemo quasi aliquam distinctio.,TRUE -Inventory,Witting Lemke,1048,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Nihil qui voluptatem unde.,TRUE -Inventory,Gerlach Thompson,1049,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quo quas debitis vel.,TRUE -Inventory,Schaefer Thompson,1050,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Minima nobis voluptas autem aut adipisci tenetur.,TRUE -Inventory,"Kovacek, Schuster and Kemmer",1051,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Aspernatur earum praesentium laudantium velit.,TRUE -Inventory,Treutel Stanton,1052,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Laboriosam repellendus quisquam labore ipsum et.,TRUE -Inventory,Bartell and Sons,1053,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Sed voluptatem consequatur reprehenderit ab aut molestiae.,TRUE -Inventory,"Bergnaum, Murray and McGlynn",1054,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Ullam in ut molestiae non eveniet et totam dolor.,TRUE -Inventory,"Wilkinson, Schowalter and Lindgren",1055,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Distinctio rerum iusto explicabo fugiat doloremque aut omnis at est.,TRUE -Inventory,"Glover, Zemlak and Kerluke",1056,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Eum at laboriosam aut.,TRUE -Inventory,Durgan Kirlin,1057,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Reprehenderit sunt expedita voluptatum nobis deleniti aliquam numquam quas.,TRUE -Inventory,Towne Crooks,1058,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Aliquam animi libero modi quisquam voluptas fugiat.,TRUE -Inventory,Wuckert McGlynn,1059,T,T,10000,1000,Cost of Goods Sold,Other Income,Inventory Asset,Description ....,Description ....,sdafasdfsadf,Quidem ut et ut reprehenderit.,TRUE \ No newline at end of file diff --git a/packages/server/views/demo-sheets/manual-journals.csv b/packages/server/views/demo-sheets/manual-journals.csv deleted file mode 100644 index f0483c440..000000000 --- a/packages/server/views/demo-sheets/manual-journals.csv +++ /dev/null @@ -1,11 +0,0 @@ -Date,Journal No,Reference No.,Currency Code,Exchange Rate,Journal Type,Description,Credit,Debit,Note,Account,Contact,Publish -2024-02-02,J-100022,REF-10000,,,,Animi quasi qui itaque aut possimus illum est magnam enim.,1000,0,Qui reprehenderit voluptate.,Bank Account,,T -2024-02-02,J-100022,REF-10000,,,,In assumenda dicta autem non est corrupti non et.,0,1000,Omnis tempora qui fugiat neque dolor voluptatem aut repudiandae nihil.,Bank Account,,T -2024-02-01,J-100023,REF-10000,,,,Animi quasi qui itaque aut possimus illum est magnam enim.,1400,0,Qui reprehenderit voluptate.,Bank Account,,T -2024-02-01,J-100023,REF-10000,,,,In assumenda dicta autem non est corrupti non et.,0,1400,Omnis tempora qui fugiat neque dolor voluptatem aut repudiandae nihil.,Bank Account,,T -2024-02-15,J-100024,REF-10000,,,,Animi quasi qui itaque aut possimus illum est magnam enim.,1900,0,Qui reprehenderit voluptate.,Bank Account,,T -2024-02-15,J-100024,REF-10000,,,,In assumenda dicta autem non est corrupti non et.,0,1900,Omnis tempora qui fugiat neque dolor voluptatem aut repudiandae nihil.,Bank Account,,T -2024-02-15,J-100025,REF-10000,,,,Animi quasi qui itaque aut possimus illum est magnam enim.,1900,0,Qui reprehenderit voluptate.,Bank Account,,T -2024-02-15,J-100025,REF-10000,,,,In assumenda dicta autem non est corrupti non et.,0,1900,Omnis tempora qui fugiat neque dolor voluptatem aut repudiandae nihil.,Bank Account,,T -2024-02-15,J-100026,REF-10000,,,,Animi quasi qui itaque aut possimus illum est magnam enim.,3494,0,Qui reprehenderit voluptate.,Bank Account,,T -2024-02-15,J-100026,REF-10000,,,,In assumenda dicta autem non est corrupti non et.,0,3494,Omnis tempora qui fugiat neque dolor voluptatem aut repudiandae nihil.,Bank Account,,T \ No newline at end of file diff --git a/packages/server/views/demo-sheets/sale-invoices.csv b/packages/server/views/demo-sheets/sale-invoices.csv deleted file mode 100644 index 354c20fef..000000000 --- a/packages/server/views/demo-sheets/sale-invoices.csv +++ /dev/null @@ -1,50 +0,0 @@ -Invoice No.,Reference No.,Invoice Date,Due Date,Customer,Exchange Rate,Invoice Message,Terms & Conditions,Delivered,Item,Quantity,Rate,Description -B-101,REF-0,2024-04-15,2024-04-17,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-102,REF-1,2024-04-16,2024-04-18,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-103,REF-2,2024-04-17,2024-04-19,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-104,REF-3,2024-04-18,2024-04-20,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-105,REF-4,2024-04-19,2024-04-21,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-106,REF-5,2024-04-20,2024-04-22,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-107,REF-6,2024-04-21,2024-04-23,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-108,REF-7,2024-04-22,2024-04-24,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-109,REF-8,2024-04-23,2024-04-25,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-110,REF-9,2024-04-24,2024-04-26,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-111,REF-10,2024-04-25,2024-04-27,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-112,REF-11,2024-04-26,2024-04-28,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-113,REF-12,2024-04-27,2024-04-29,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-114,REF-13,2024-04-28,2024-04-30,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-115,REF-14,2024-04-29,2024-05-01,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-116,REF-15,2024-04-30,2024-05-02,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-117,REF-16,2024-05-01,2024-05-03,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-118,REF-17,2024-05-02,2024-05-04,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-119,REF-18,2024-05-03,2024-05-05,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-120,REF-19,2024-05-04,2024-05-06,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-121,REF-20,2024-05-05,2024-05-07,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-122,REF-21,2024-05-06,2024-05-08,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-123,REF-22,2024-05-07,2024-05-09,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-124,REF-23,2024-05-08,2024-05-10,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-125,REF-24,2024-05-09,2024-05-11,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-126,REF-25,2024-05-10,2024-05-12,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-127,REF-26,2024-05-11,2024-05-13,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-128,REF-27,2024-05-12,2024-05-14,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-129,REF-28,2024-05-13,2024-05-15,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-130,REF-29,2024-05-14,2024-05-16,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-131,REF-30,2024-05-15,2024-05-17,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-132,REF-31,2024-05-16,2024-05-18,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-133,REF-32,2024-05-17,2024-05-19,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-134,REF-33,2024-05-18,2024-05-20,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-135,REF-34,2024-05-19,2024-05-21,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-136,REF-35,2024-05-20,2024-05-22,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-137,REF-36,2024-05-21,2024-05-23,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-138,REF-37,2024-05-22,2024-05-24,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-139,REF-38,2024-05-23,2024-05-25,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-140,REF-39,2024-05-24,2024-05-26,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-141,REF-40,2024-05-25,2024-05-27,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-142,REF-41,2024-05-26,2024-05-28,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-143,REF-42,2024-05-27,2024-05-29,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-144,REF-43,2024-05-28,2024-05-30,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-145,REF-44,2024-05-29,2024-05-31,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-146,REF-45,2024-05-30,2024-06-01,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-147,REF-46,2024-05-31,2024-06-02,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-148,REF-47,2024-06-01,2024-06-03,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description -B-149,REF-48,2024-06-02,2024-06-04,Harley Veum,1,Aspernatur doloremque amet quia aut.,Quia illum aut dolores.,T,Amoxicillin and Clavulanatea,100,100,Description \ No newline at end of file diff --git a/packages/server/views/demo-sheets/vendors.csv b/packages/server/views/demo-sheets/vendors.csv deleted file mode 100644 index 50287d2b9..000000000 --- a/packages/server/views/demo-sheets/vendors.csv +++ /dev/null @@ -1,5 +0,0 @@ -First Name,Last Name,Company Name,Display Name,Email,Personal Phone Number,Work Phone Number,Website,Opening Balance,Opening Balance At,Opening Balance Ex. Rate,Currency,Active,Note,Billing Address 1,Billing Address 2,Billing Address City,Billing Address Country,Billing Address Phone,Billing Address Postcode,Billing Address State,Shipping Address 1,Shipping Address 2,Shipping Address City,Shipping Address Country,Shipping Address Phone,Shipping Address Postcode,Shipping Address State -Nicolette,Schamberger,Homenick - Hane,Rowland Rowe,cicero86@yahoo.com,811-603-2235,906-993-5190,http://google.com,54302.23,2022-02-02,2,LYD,T,Doloribus autem optio temporibus dolores mollitia sit.,862 Jessika Well,1091 Dorthy Mount,Deckowfort,Ghana,825-011-5207,38228,Oregon,37626 Thiel Villages,132 Batz Avenue,Pagacburgh,Albania,171-546-3701,13709,Georgia -Hermann,Crooks,Veum - Schaefer,Harley Veum,immanuel56@hotmail.com,449-780-9999,970-473-5785,http://google.com,54302.23,2022-02-02,2,LYD,T,Doloribus dolore dolor dicta vitae in fugit nisi quibusdam.,532 Simonis Spring,3122 Nicolas Inlet,East Matteofort,Holy See (Vatican City State),366-084-8629,41607,Montana,2889 Tremblay Plaza,71355 Kutch Isle,D'Amorehaven,Monaco,614-189-3328,09634-0435,Nevada -Nellie,Gulgowski,"Boyle, Heller and Jones",Randall Kohler,anibal_frami@yahoo.com,498-578-0740,394-550-6827,http://google.com,54302.23,2022-02-02,2,LYD,T,Vero quibusdam rem fugit aperiam est modi.,214 Sauer Villages,30687 Kacey Square,Jayceborough,Benin,332-820-1127,16425-3887,Mississippi,562 Diamond Loaf,9595 Satterfield Trafficway,Alexandrinefort,Puerto Rico,776-500-8456,30258,South Dakota -Stone,Jerde,"Cassin, Casper and Maggio",Clint McLaughlin,nathanael22@yahoo.com,562-790-6059,686-838-0027,http://google.com,54302.23,2022-02-02,2,LYD,T,Quis cumque molestias rerum.,22590 Cathy Harbor,24493 Brycen Brooks,Elnorashire,Andorra,701-852-8005,5680,Nevada,5355 Erdman Bridge,421 Jeanette Camp,East Philip,Venezuela,426-119-0858,34929-0501,Tennessee \ No newline at end of file diff --git a/packages/server/views/images/bigcapital.png b/packages/server/views/images/bigcapital.png deleted file mode 100644 index 72cbc06089030e8f47da6b48ebee8b2a2c9527e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2427 zcmai0c|2768~)m|4#q7@i_xNyZOYJ1V(biNNc<3GxuJ5Sg^O$xl1M2_8%aZ?Xwje& zxn#(g#axxfZ7fL&A>jV)=(Tq0p7g;%L3MHoe~IY z2RI6FWEf{daWBBXM-~eJwgY%mfCmk@_81ikfKxBn+bN`BsbDVy;F-Xa0`OFTWdL`k zFz-SYl5q@(4?LIv-)&GJ0B$tkLI-#T!1VxkDsY9!J;GWyDsZ6zJbjrD>ELLE+ge8U1hSmFzh4C8#hP+y2H zsnM5F9L-3`6qbkxkOwhA)J1%R%9mR}wREGxg%wvc<9sL<*??^07{&z)D}v%KP+r_( z$*@RVXjlXZXJ3hzovhec;y@0?OmQzU6Y>K!6*?4&2=h?u6~U#!aS&%wxS7I55ejWX ztOuLn8kpC3*{DWf8O@`0tJ@@xOJ%RsTPL<`oD8 z1b$gE^qJ2_d*b&22}vm_X=#~NvT}0r3W|zKFqpE6Djcr%%jz}i8d_`DZ_q~QY}~YY z%NE_ONIiW+BV*L|9VTc~vzN92lG~+sh-Kw>EACa@udaFc_(?6PuD-sZ;rWZkmrc#huUcCE zY;9|MP44KVbkpbz=3l*U-@X69>i_#AdvIv@)5z!1FJoW7jZaK|pPHWeF*`TU`N{i- zzpzM=;W$F`ON6*O+0Xa0T!I0RvB%omc=@(YTuTV>a#&3c?>qcBu6^^TVAVQ!dRE&e zOC@>u8`CGRQWab_?>}Rho$jWCQzusHwJGGjdE+zxsN&vBCG;9ePaS7{7k#;_U4r6M zqaR(0BIodkYPTBlZuHEnhMQu#D8Z#l$gvWc9m-%ka z(}2fF8IJ8!xPi7JMy1z089(=zshQbXRvG&T(=BWy(JJe-?@Sy?@u&s&ZI#Z)k@ho@ z+6aDBslhM#yD=CHVkGyV+_Mi`Ey-BEcFD}__hOU`_xJ^Ts34HL&7)$tYTHAbkSQQHWP%{7(t$szk<)Hmd9 zvGdt$pXUQh;{|#udOEk zy+km5P#K;wktt_Vgb(!fD9sd{r4R`vIulPVjt$=@R&cL=o8$F8I}lVIG!;|L*JN|( zEvf?Lk84e{e-32Igl_kJCA;9rMmcJ+@3B1p>1C=nxtzXF*+&eXx_T#^_Ii8Z2FWI* za!g25yKXfJF__87U;WwYrDkl>napNacRr4r8nu7QEF)3xh0-di&x?0vo^70jZ{=UC z?|bFriXwk^(^axE=Bmd=Q`X+$#@bDXYo5OQ20!95)x2dOr8Vkn#dKOj7B}m9g?zxe zf@yE2f45b=A9C<}S_mwMM;Q9mcG{5j!91qbActo7Yii0lLPa~iAla`?I>6;8* z)dSD-YTJiu^p39D*xHL%8wY0SB@*`G5G#niA$-)UI#NLmWc+ zDsms_k~s}Zhj8wbgJbN+4(`+M@(FJz+87pQJ&(OZ{D{{&yMmZ8A&XtJbF{-7I?JCC zmA=CfXl{RLM1RP^;q;_!L&zcdDX^BVK&F?qjZQIoWeJpu4jUytgi zqwAjIMoxYg2Zf4n_UKhZ1HbfIJ0VALRSKHi0Je}dsZ z{O(Afh01wW&#}pb*o`e?2Qn@uDh3A{PFoqj$Dp~g(rmg>dJD39Q?fIL`9+D}5!u&I zjI6gqwPHxeBocndD)6NCJZ`)mmrGsvPoqUfN+;`P;dU;1=YSU3jHYYCKO7Jnpz%pp zDut<8)fgy`_&G8=Uv8F}CEqL8WH2;5{P&c{hh`JiZ^65Wmiu?~Y3%WPKEA0`E!?ol zAV1FThnxiF3O8I`3uYU5neM&a@`2~f$O52!y zh0#v%3=nELKfkanF3l)@hOdF?E!yuz*FLI?K(1@rx?p#LIB!*zk(}CXwQ(^Uk?>V! r-{79&=TjOH5fNz{1Rc>|9(+M`XN+FSfi=qrf15aLpw#~YXaQdT diff --git a/packages/server/views/mail/ResetPassword.html b/packages/server/views/mail/ResetPassword.html deleted file mode 100644 index fc7cbd624..000000000 --- a/packages/server/views/mail/ResetPassword.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - - Bigcapital | Reset your password - - - - This is preheader text. Some clients will show this text as a preview. - - - - - - - - - diff --git a/packages/server/views/mail/SignupVerifyEmail.html b/packages/server/views/mail/SignupVerifyEmail.html deleted file mode 100644 index 637e78c12..000000000 --- a/packages/server/views/mail/SignupVerifyEmail.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - - Bigcapital | Reset your password - - - - Verify your email. - - - - - - - - - diff --git a/packages/server/views/mail/UserInvite.html b/packages/server/views/mail/UserInvite.html deleted file mode 100644 index 60b2a75d4..000000000 --- a/packages/server/views/mail/UserInvite.html +++ /dev/null @@ -1,421 +0,0 @@ - - - - - - Bigcapital | Reset your password - - - - This is preheader text. Some clients will show this text as a preview. - - - - - - - - - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 20f0eb0c4..61518ffee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,451 +38,6 @@ importers: version: 9.1.2 packages/server: - dependencies: - '@aws-sdk/client-s3': - specifier: ^3.576.0 - version: 3.583.0 - '@aws-sdk/s3-request-presigner': - specifier: ^3.583.0 - version: 3.583.0 - '@bigcapital/email-components': - specifier: '*' - version: link:../../shared/email-components - '@bigcapital/pdf-templates': - specifier: '*' - version: link:../../shared/pdf-templates - '@bigcapital/utils': - specifier: '*' - version: link:../../shared/bigcapital-utils - '@casl/ability': - specifier: ^5.4.3 - version: 5.4.4 - '@hapi/boom': - specifier: ^7.4.3 - version: 7.4.11 - '@lemonsqueezy/lemonsqueezy.js': - specifier: ^2.2.0 - version: 2.2.0 - '@supercharge/promise-pool': - specifier: ^3.2.0 - version: 3.2.0 - '@types/express': - specifier: ^4.17.21 - version: 4.17.21 - '@types/i18n': - specifier: ^0.8.7 - version: 0.8.8 - '@types/knex': - specifier: ^0.16.1 - version: 0.16.1(mysql2@1.7.0)(mysql@2.18.1) - '@types/mathjs': - specifier: ^6.0.12 - version: 6.0.12 - '@types/yup': - specifier: ^0.29.13 - version: 0.29.14 - accepts: - specifier: ^1.3.7 - version: 1.3.8 - accounting: - specifier: ^0.4.1 - version: 0.4.1 - agenda: - specifier: ^4.2.1 - version: 4.4.0(@aws-sdk/client-sso-oidc@3.583.0) - agendash: - specifier: ^3.1.0 - version: 3.1.0(@aws-sdk/client-sso-oidc@3.583.0) - app-root-path: - specifier: ^3.0.0 - version: 3.1.0 - async: - specifier: ^3.2.0 - version: 3.2.5 - async-mutex: - specifier: ^0.5.0 - version: 0.5.0 - axios: - specifier: ^1.6.0 - version: 1.7.2 - babel-loader: - specifier: ^9.1.2 - version: 9.1.3(@babel/core@7.26.0)(webpack@5.91.0) - bcryptjs: - specifier: ^2.4.3 - version: 2.4.3 - bluebird: - specifier: ^3.7.2 - version: 3.7.2 - body-parser: - specifier: ^1.20.2 - version: 1.20.2 - compression: - specifier: ^1.7.4 - version: 1.7.4 - country-codes-list: - specifier: ^1.6.8 - version: 1.6.11 - cpy: - specifier: ^8.1.2 - version: 8.1.2 - cpy-cli: - specifier: ^3.1.1 - version: 3.1.1 - crypto-random-string: - specifier: ^3.2.0 - version: 3.3.1 - csurf: - specifier: ^1.10.0 - version: 1.11.0 - deep-map: - specifier: ^2.0.0 - version: 2.0.0 - deepdash: - specifier: ^5.3.9 - version: 5.3.9 - dotenv: - specifier: ^8.1.0 - version: 8.6.0 - errorhandler: - specifier: ^1.5.1 - version: 1.5.1 - es6-weak-map: - specifier: ^2.0.3 - version: 2.0.3 - esm: - specifier: ^3.2.25 - version: 3.2.25 - event-dispatch: - specifier: ^0.4.1 - version: 0.4.1 - eventemitter2: - specifier: ^6.4.5 - version: 6.4.9 - express: - specifier: ^4.17.1 - version: 4.19.2 - express-basic-auth: - specifier: ^1.2.0 - version: 1.2.1 - express-boom: - specifier: ^3.0.0 - version: 3.0.0 - express-oauth-server: - specifier: ^2.0.0 - version: 2.0.0 - express-validator: - specifier: ^6.12.2 - version: 6.15.0 - form-data: - specifier: ^4.0.0 - version: 4.0.0 - gulp: - specifier: ^4.0.2 - version: 4.0.2 - gulp-sass: - specifier: ^5.0.0 - version: 5.1.0 - helmet: - specifier: ^3.21.0 - version: 3.23.3 - i18n: - specifier: ^0.13.3 - version: 0.13.4 - is-my-json-valid: - specifier: ^2.20.5 - version: 2.20.6 - js-money: - specifier: ^0.6.3 - version: 0.6.3 - jsonwebtoken: - specifier: ^8.5.1 - version: 8.5.1 - knex: - specifier: ^3.1.0 - version: 3.1.0(mysql2@1.7.0)(mysql@2.18.1) - knex-cleaner: - specifier: ^1.3.0 - version: 1.3.1 - libphonenumber-js: - specifier: ^1.9.6 - version: 1.11.1 - lodash: - specifier: ^4.17.15 - version: 4.17.21 - lru-cache: - specifier: ^6.0.0 - version: 6.0.0 - mathjs: - specifier: ^9.4.0 - version: 9.5.2 - memory-cache: - specifier: ^0.2.0 - version: 0.2.0 - mime-types: - specifier: ^2.1.35 - version: 2.1.35 - moment: - specifier: ^2.24.0 - version: 2.30.1 - moment-range: - specifier: ^4.0.2 - version: 4.0.2(moment@2.30.1) - moment-timezone: - specifier: ^0.5.43 - version: 0.5.45 - mongodb: - specifier: ^6.1.0 - version: 6.6.2 - mongoose: - specifier: ^5.10.0 - version: 5.13.22 - multer: - specifier: 1.4.5-lts.1 - version: 1.4.5-lts.1 - multer-s3: - specifier: ^3.0.1 - version: 3.0.1(@aws-sdk/client-s3@3.583.0) - mustache: - specifier: ^3.0.3 - version: 3.2.1 - mysql: - specifier: ^2.17.1 - version: 2.18.1 - mysql2: - specifier: ^1.6.5 - version: 1.7.0 - newrelic: - specifier: ^11.15.0 - version: 11.17.0 - node-cache: - specifier: ^4.2.1 - version: 4.2.1 - nodemailer: - specifier: ^6.3.0 - version: 6.9.13 - nodemon: - specifier: ^1.19.1 - version: 1.19.4 - object-hash: - specifier: ^2.0.3 - version: 2.2.0 - objection: - specifier: ^3.0.0 - version: 3.1.4(knex@3.1.0) - objection-filter: - specifier: ^4.0.1 - version: 4.4.0(objection@3.1.4) - objection-soft-delete: - specifier: ^1.0.7 - version: 1.0.7(objection@3.1.4) - objection-unique: - specifier: ^1.2.2 - version: 1.2.2(objection@3.1.4) - plaid: - specifier: ^10.3.0 - version: 10.9.0 - pluralize: - specifier: ^8.0.0 - version: 8.0.0 - posthog-node: - specifier: ^4.3.2 - version: 4.3.2 - pug: - specifier: ^3.0.2 - version: 3.0.2 - puppeteer: - specifier: ^10.2.0 - version: 10.4.0 - qim: - specifier: 0.0.52 - version: 0.0.52 - ramda: - specifier: ^0.27.1 - version: 0.27.2 - rate-limiter-flexible: - specifier: ^2.1.14 - version: 2.4.2 - reflect-metadata: - specifier: ^0.1.13 - version: 0.1.14 - rtl-detect: - specifier: ^1.0.4 - version: 1.1.2 - socket.io: - specifier: ^4.7.4 - version: 4.7.5 - source-map-loader: - specifier: ^4.0.1 - version: 4.0.2(webpack@5.91.0) - stripe: - specifier: ^16.10.0 - version: 16.10.0 - tmp-promise: - specifier: ^3.0.3 - version: 3.0.3 - ts-transformer-keys: - specifier: ^0.4.2 - version: 0.4.4(typescript@3.9.10) - tsyringe: - specifier: ^4.3.0 - version: 4.8.0 - typedi: - specifier: ^0.8.0 - version: 0.8.0 - uniqid: - specifier: ^5.2.0 - version: 5.4.0 - uuid: - specifier: ^10.0.0 - version: 10.0.0 - winston: - specifier: ^3.2.1 - version: 3.13.0 - xlsx: - specifier: ^0.18.5 - version: 0.18.5 - yup: - specifier: ^0.28.1 - version: 0.28.5 - devDependencies: - '@types/lodash': - specifier: ^4.14.158 - version: 4.17.4 - '@types/multer': - specifier: ^1.4.11 - version: 1.4.11 - '@types/ramda': - specifier: ^0.27.64 - version: 0.27.66 - '@typescript-eslint/eslint-plugin': - specifier: ^5.50.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@3.9.10) - '@typescript-eslint/parser': - specifier: ^5.50.0 - version: 5.62.0(eslint@8.57.0)(typescript@3.9.10) - chai: - specifier: ^4.2.0 - version: 4.4.1 - chai-http: - specifier: ^4.3.0 - version: 4.4.0 - chai-things: - specifier: ^0.2.0 - version: 0.2.0 - colorette: - specifier: ^1.2.0 - version: 1.4.0 - commander: - specifier: ^5.0.0 - version: 5.1.0 - cross-env: - specifier: ^5.2.0 - version: 5.2.1 - eslint: - specifier: ^8.33.0 - version: 8.57.0 - eslint-config-airbnb-base: - specifier: ^15.0.0 - version: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-config-airbnb-typescript: - specifier: ^17.0.0 - version: 17.1.0(@typescript-eslint/eslint-plugin@5.62.0)(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-friendly-formatter: - specifier: ^4.0.1 - version: 4.0.1 - eslint-import-resolver-typescript: - specifier: ^3.5.3 - version: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-webpack@0.11.1)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-import-resolver-webpack: - specifier: ^0.11.1 - version: 0.11.1(eslint-plugin-import@2.29.1)(webpack@5.91.0) - eslint-loader: - specifier: ^2.2.1 - version: 2.2.1(eslint@8.57.0)(webpack@5.91.0) - eslint-plugin-import: - specifier: ^2.27.5 - version: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - faker: - specifier: ^4.1.0 - version: 4.1.0 - getopts: - specifier: ^2.2.5 - version: 2.3.0 - gulp-postcss: - specifier: ^9.0.0 - version: 9.1.0(postcss@8.4.47) - gulp-rename: - specifier: ^2.0.0 - version: 2.0.0 - knex-factory: - specifier: 0.0.6 - version: 0.0.6 - merge-stream: - specifier: ^2.0.0 - version: 2.0.0 - mocha: - specifier: ^5.2.0 - version: 5.2.0 - npm-run-all: - specifier: ^4.1.5 - version: 4.1.5 - nyc: - specifier: ^14.1.1 - version: 14.1.1 - progress-bar-webpack-plugin: - specifier: ^2.1.0 - version: 2.1.0(webpack@5.91.0) - regenerator-runtime: - specifier: ^0.13.7 - version: 0.13.11 - rimraf: - specifier: ^3.0.2 - version: 3.0.2 - rtlcss: - specifier: ^3.3.0 - version: 3.5.0 - run-script-webpack-plugin: - specifier: ^0.1.1 - version: 0.1.1 - sass: - specifier: ^1.58.0 - version: 1.77.2 - sinon: - specifier: ^7.4.2 - version: 7.5.0 - start-server-webpack-plugin: - specifier: ^2.2.5 - version: 2.2.5 - ts-loader: - specifier: ^9.4.2 - version: 9.5.1(typescript@3.9.10)(webpack@5.91.0) - ts-node: - specifier: ^9.0.0 - version: 9.1.1(typescript@3.9.10) - tsconfig-paths-webpack-plugin: - specifier: ^4.0.0 - version: 4.1.0 - typescript: - specifier: ^3.9.7 - version: 3.9.10 - webpack: - specifier: ^5.75.0 - version: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - webpack-cli: - specifier: ^4.10.0 - version: 4.10.0(webpack@5.91.0) - webpack-merge: - specifier: ^5.8.0 - version: 5.10.0 - webpack-node-externals: - specifier: ^3.0.0 - version: 3.0.0 - webpack-watch-changed: - specifier: ^1.0.0 - version: 1.0.0 - - packages/server-nest: dependencies: '@aws-sdk/client-s3': specifier: ^3.576.0 @@ -570,7 +125,7 @@ importers: version: 0.5.0 axios: specifier: ^1.6.0 - version: 1.7.7 + version: 1.7.2 bcrypt: specifier: ^5.1.1 version: 5.1.1 @@ -1453,13 +1008,13 @@ packages: - chokidar dev: true - /@apideck/better-ajv-errors@0.3.6(ajv@8.13.0): + /@apideck/better-ajv-errors@0.3.6(ajv@8.17.1): resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} engines: {node: '>=10'} peerDependencies: ajv: '>=8' dependencies: - ajv: 8.13.0 + ajv: 8.17.1 json-schema: 0.4.0 jsonpointer: 5.0.1 leven: 3.1.0 @@ -1541,57 +1096,6 @@ packages: tslib: 1.14.1 dev: false - /@aws-sdk/client-cognito-identity@3.583.0: - resolution: {integrity: sha512-FrkVjrDRsXofw1F/iJqR/DOKPbIakIB+Dr04l25Em4PTWBj29NcQyYW49qcCHF0CPkqQpin8ASXDWzGv7A0yxg==} - engines: {node: '>=16.0.0'} - requiresBuild: true - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/client-sts': 3.583.0 - '@aws-sdk/core': 3.582.0 - '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.583.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.583.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.8.0 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - /@aws-sdk/client-s3@3.583.0: resolution: {integrity: sha512-pS7wncugSuIQ8RgtRIE9Dystdmd3mMnjfjiO1iA1UhGXkyAgoJzQ4jH0r+5X+eWmYHYQcfy9fUQXT2gqV3t9GA==} engines: {node: '>=16.0.0'} @@ -1814,21 +1318,6 @@ packages: tslib: 2.8.0 dev: false - /@aws-sdk/credential-provider-cognito-identity@3.583.0: - resolution: {integrity: sha512-Z6VdDZApTxeI/n8qXBz3IkAdC0tL/mw+cz6EprqpkZG8bejHw78fVjeaVOBBkuskUikjwN4puv0SEJzoEMIqpA==} - engines: {node: '>=16.0.0'} - requiresBuild: true - dependencies: - '@aws-sdk/client-cognito-identity': 3.583.0 - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.8.0 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - /@aws-sdk/credential-provider-env@3.577.0: resolution: {integrity: sha512-Jxu255j0gToMGEiqufP8ZtKI8HW90lOLjwJ3LrdlD/NLsAY0tOQf1fWc53u28hWmmNGMxmCrL2p66IOgMDhDUw==} engines: {node: '>=16.0.0'} @@ -1938,33 +1427,6 @@ packages: tslib: 2.8.0 dev: false - /@aws-sdk/credential-providers@3.583.0(@aws-sdk/client-sso-oidc@3.583.0): - resolution: {integrity: sha512-aD/lw6LJW51f+LgdR54UxyGvXqWZs4HCT310Qf794qFItDWXqhHK4EgS1x41BgAvXPUx0+HSO8OI4eb+AklckA==} - engines: {node: '>=16.0.0'} - requiresBuild: true - dependencies: - '@aws-sdk/client-cognito-identity': 3.583.0 - '@aws-sdk/client-sso': 3.583.0 - '@aws-sdk/client-sts': 3.583.0 - '@aws-sdk/credential-provider-cognito-identity': 3.583.0 - '@aws-sdk/credential-provider-env': 3.577.0 - '@aws-sdk/credential-provider-http': 3.582.0 - '@aws-sdk/credential-provider-ini': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/types': 3.577.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.8.0 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - dev: false - optional: true - /@aws-sdk/lib-storage@3.583.0(@aws-sdk/client-s3@3.583.0): resolution: {integrity: sha512-To3mCeSpJiHWxAh00S5+cRfx8BkbdmWvZG2Rvcz20Qqh/GmhMWeDbN4OjDTqcewWpqNhU0n1ShZY/GcIWSn+Pg==} engines: {node: '>=16.0.0'} @@ -2325,6 +1787,7 @@ packages: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + dev: false /@babel/generator@7.26.0: resolution: {integrity: sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==} @@ -4808,15 +4271,6 @@ packages: dependencies: regenerator-runtime: 0.14.1 - /@babel/template@7.24.0: - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.26.0 - '@babel/parser': 7.26.1 - '@babel/types': 7.26.0 - dev: true - /@babel/template@7.25.9: resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} @@ -4841,6 +4295,7 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color + dev: false /@babel/traverse@7.25.9(supports-color@5.5.0): resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} @@ -5122,11 +4577,6 @@ packages: dev: true optional: true - /@colors/colors@1.6.0: - resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} - engines: {node: '>=0.1.90'} - dev: false - /@commitlint/cli@17.8.1: resolution: {integrity: sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==} engines: {node: '>=v14'} @@ -5175,7 +4625,7 @@ packages: engines: {node: '>=v14'} dependencies: '@commitlint/types': 17.8.1 - ajv: 8.13.0 + ajv: 8.17.1 dev: true /@commitlint/ensure@17.8.1: @@ -5311,16 +4761,6 @@ packages: chalk: 4.1.2 dev: true - /@contrast/fn-inspect@3.4.0: - resolution: {integrity: sha512-Jw6dMFEIt/FXF1ihJri2GFNayeEKQ6r+WRjjWl7MdgMup2D4vCPu99ZV8eHSMqNNkj3BEzUNC91ZaJVB1XJmfg==} - engines: {node: '>=12.13.0'} - requiresBuild: true - dependencies: - nan: 2.19.0 - node-gyp-build: 4.8.1 - dev: false - optional: true - /@craco/craco@5.9.0(react-scripts@5.0.1): resolution: {integrity: sha512-2Q8gIB4W0/nPiUxr9iAKUhGsFlXYN0/wngUdK1VWtfV2NtBv+yllNn2AjieaLbttgpQinuOYmDU65vocC0NMDg==} engines: {node: '>=6'} @@ -5497,14 +4937,6 @@ packages: postcss-selector-parser: 6.1.0 dev: false - /@dabh/diagnostics@2.0.3: - resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - dependencies: - colorspace: 1.1.4 - enabled: 2.0.0 - kuler: 2.0.0 - dev: false - /@discoveryjs/json-ext@0.5.7: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} @@ -6306,6 +5738,7 @@ packages: dependencies: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 + dev: false /@eslint-community/eslint-utils@4.4.0(eslint@9.13.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} @@ -6320,11 +5753,11 @@ packages: /@eslint-community/regexpp@4.10.0: resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: false /@eslint-community/regexpp@4.11.2: resolution: {integrity: sha512-2WwyTYNVaMNUWPZTOJdkax9iqTdirrApgTbk+Qoq5EPX6myqZvG8QGFRgdKmkjKVG6/G/a565vpPauHk0+hpBA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true /@eslint/config-array@0.18.0: resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} @@ -6357,6 +5790,7 @@ packages: strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color + dev: false /@eslint/eslintrc@3.1.0: resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} @@ -6378,6 +5812,7 @@ packages: /@eslint/js@8.57.0: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: false /@eslint/js@9.13.0: resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} @@ -6445,37 +5880,6 @@ packages: deprecated: the package is rather renamed to @formatjs/ecma-abstract with some changes in functionality (primarily selectUnit is removed and we don't plan to make any further changes to this package dev: false - /@grpc/grpc-js@1.10.8: - resolution: {integrity: sha512-vYVqYzHicDqyKB+NQhAc54I1QWCBLCrYG6unqOIcBTHx+7x8C9lcoLj3KVJXs2VB4lUbpWY+Kk9NipcbXYWmvg==} - engines: {node: '>=12.10.0'} - dependencies: - '@grpc/proto-loader': 0.7.13 - '@js-sdsl/ordered-map': 4.4.2 - dev: false - - /@grpc/proto-loader@0.7.13: - resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} - engines: {node: '>=6'} - hasBin: true - dependencies: - lodash.camelcase: 4.3.0 - long: 5.2.3 - protobufjs: 7.3.0 - yargs: 17.7.2 - dev: false - - /@hapi/boom@7.4.11: - resolution: {integrity: sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==} - deprecated: This version has been deprecated and is no longer supported or maintained - dependencies: - '@hapi/hoek': 8.5.1 - dev: false - - /@hapi/hoek@8.5.1: - resolution: {integrity: sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==} - deprecated: This version has been deprecated and is no longer supported or maintained - dev: false - /@humanfs/core@0.19.0: resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} engines: {node: '>=18.18.0'} @@ -6498,6 +5902,7 @@ packages: minimatch: 3.1.2 transitivePeerDependencies: - supports-color + dev: false /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -6505,6 +5910,7 @@ packages: /@humanwhocodes/object-schema@2.0.3: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + dev: false /@humanwhocodes/retry@0.3.1: resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} @@ -7078,10 +6484,6 @@ packages: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - /@js-sdsl/ordered-map@4.4.2: - resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - dev: false - /@juggle/resize-observer@3.4.0: resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} @@ -7313,20 +6715,6 @@ packages: resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} dev: false - /@mongodb-js/saslprep@1.1.7: - resolution: {integrity: sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==} - dependencies: - sparse-bitfield: 3.0.3 - dev: false - - /@mrmlnc/readdir-enhanced@2.2.1: - resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} - engines: {node: '>=4'} - dependencies: - call-me-maybe: 1.0.2 - glob-to-regexp: 0.3.0 - dev: false - /@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3: resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} cpu: [arm64] @@ -7772,63 +7160,6 @@ packages: reflect-metadata: 0.2.2 dev: false - /@newrelic/native-metrics@10.1.1: - resolution: {integrity: sha512-BvdTMAqS3d94ZwJ6u70dWqZVkX8ev3dybkxRInHMbKV2DE1koQR3nzH2ut3hf1MaRQh4SF6SpUNTUznzCZZtjw==} - engines: {node: '>=16', npm: '>=6'} - requiresBuild: true - dependencies: - nan: 2.19.0 - node-gyp: 10.1.0 - node-gyp-build: 4.8.1 - prebuildify: 6.0.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - dev: false - optional: true - - /@newrelic/ritm@7.2.0: - resolution: {integrity: sha512-I4iVhm+wlTEDJXQT8EydF/U5vlR9bBHrtBGyvd/D9WCucoMtrPrCNyILQh9bZ+46E8QRE7zh6QEGyQcnc3qNMg==} - engines: {node: '>=8.6.0'} - dependencies: - debug: 4.3.7(supports-color@5.5.0) - module-details-from-path: 1.0.3 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - dev: false - - /@newrelic/security-agent@1.2.0: - resolution: {integrity: sha512-Snk++TQmqHKuxPYOH5bEU4GCr5xKYurUZWx3oiuoQUV73pw61qeEMrb/8iuGgAghwpCEC/8n+308efqCIZkiiQ==} - dependencies: - axios: 1.7.7 - check-disk-space: 3.4.0 - content-type: 1.0.5 - fast-safe-stringify: 2.1.1 - find-package-json: 1.2.0 - hash.js: 1.1.7 - html-entities: 2.5.2 - is-invalid-path: 1.0.2 - js-yaml: 4.1.0 - jsonschema: 1.4.1 - lodash: 4.17.21 - log4js: 6.9.1 - pretty-bytes: 5.6.0 - request-ip: 3.3.0 - ringbufferjs: 2.0.0 - semver: 7.6.3 - sync-request: 6.1.0 - unescape: 1.0.1 - unescape-js: 1.1.4 - uuid: 9.0.1 - ws: 8.17.0 - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate - dev: false - /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: @@ -7842,11 +7173,6 @@ packages: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - /@nodelib/fs.stat@1.1.3: - resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} - engines: {node: '>= 6'} - dev: false - /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} @@ -7869,12 +7195,14 @@ packages: socks-proxy-agent: 8.0.3 transitivePeerDependencies: - supports-color + dev: true /@npmcli/fs@3.1.1: resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: semver: 7.6.3 + dev: true /@npmcli/git@5.0.7: resolution: {integrity: sha512-WaOVvto604d5IpdCRV2KjQu8PzkfE96d50CQGKgywXh2GxXmDeUO5EWcBC4V57uFyrNqx83+MewuJh3WTR3xPA==} @@ -8254,7 +7582,7 @@ packages: react-refresh: 0.11.0 schema-utils: 3.3.0 source-map: 0.7.4 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) webpack-dev-server: 4.15.2(webpack@5.91.0) dev: false @@ -8262,55 +7590,6 @@ packages: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} dev: false - /@prisma/prisma-fmt-wasm@4.17.0-16.27eb2449f178cd9fe1a4b892d732cc4795f75085: - resolution: {integrity: sha512-zYz3rFwPB82mVlHGknAPdnSY/a308dhPOblxQLcZgZTDRtDXOE1MgxoRAys+jekwR4/bm3+rZDPs1xsFMsPZig==} - requiresBuild: true - dev: false - optional: true - - /@protobufjs/aspromise@1.1.2: - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - dev: false - - /@protobufjs/base64@1.1.2: - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - dev: false - - /@protobufjs/codegen@2.0.4: - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - dev: false - - /@protobufjs/eventemitter@1.1.0: - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - dev: false - - /@protobufjs/fetch@1.1.0: - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - dev: false - - /@protobufjs/float@1.0.2: - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - dev: false - - /@protobufjs/inquire@1.1.0: - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - dev: false - - /@protobufjs/path@1.1.2: - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - dev: false - - /@protobufjs/pool@1.1.0: - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - dev: false - - /@protobufjs/utf8@1.1.0: - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - dev: false - /@radix-ui/number@1.0.1: resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} dependencies: @@ -9649,6 +8928,7 @@ packages: resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} dependencies: type-detect: 4.0.8 + dev: false /@sinonjs/commons@3.0.1: resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} @@ -9668,25 +8948,6 @@ packages: '@sinonjs/commons': 1.8.6 dev: false - /@sinonjs/formatio@3.2.2: - resolution: {integrity: sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==} - dependencies: - '@sinonjs/commons': 1.8.6 - '@sinonjs/samsam': 3.3.3 - dev: true - - /@sinonjs/samsam@3.3.3: - resolution: {integrity: sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==} - dependencies: - '@sinonjs/commons': 1.8.6 - array-from: 2.1.1 - lodash: 4.17.21 - dev: true - - /@sinonjs/text-encoding@0.7.2: - resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} - dev: true - /@smithy/abort-controller@3.0.0: resolution: {integrity: sha512-p6GlFGBt9K4MYLu72YuJ523NVR4A8oHlC5M2JO6OmQqN8kAc/uh1JqLE+FizTokrSJGg0CSvC+BrsmGzKtsZKA==} engines: {node: '>=16.0.0'} @@ -10651,7 +9912,7 @@ packages: ejs: 3.1.10 esbuild: 0.18.20 esbuild-plugin-alias: 0.2.1 - express: 4.19.2 + express: 4.21.1 find-cache-dir: 3.3.2 fs-extra: 11.2.0 process: 0.11.10 @@ -10895,7 +10156,7 @@ packages: find-cache-dir: 3.3.2 find-up: 5.0.0 fs-extra: 11.2.0 - glob: 10.4.1 + glob: 10.4.2 handlebars: 4.7.8 lazy-universal-dotenv: 4.0.0 node-fetch: 2.6.7 @@ -10926,7 +10187,7 @@ packages: find-cache-dir: 3.3.2 find-up: 5.0.0 fs-extra: 11.2.0 - glob: 10.4.1 + glob: 10.4.2 handlebars: 4.7.8 lazy-universal-dotenv: 4.0.0 node-fetch: 2.6.7 @@ -10983,7 +10244,7 @@ packages: cli-table3: 0.6.5 compression: 1.7.4 detect-port: 1.6.1 - express: 4.19.2 + express: 4.21.1 fs-extra: 11.2.0 globby: 11.1.0 ip: 2.0.1 @@ -12158,26 +11419,10 @@ packages: '@types/node': 20.5.1 dev: false - /@types/bson@4.0.5: - resolution: {integrity: sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==} - dependencies: - '@types/node': 20.5.1 - dev: false - - /@types/chai@4.3.16: - resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} - dev: true - - /@types/concat-stream@1.6.1: - resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} - dependencies: - '@types/node': 20.5.1 - dev: false - /@types/connect-history-api-fallback@1.5.4: resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} dependencies: - '@types/express-serve-static-core': 4.19.1 + '@types/express-serve-static-core': 5.0.1 '@types/node': 20.5.1 dev: false @@ -12186,20 +11431,10 @@ packages: dependencies: '@types/node': 20.5.1 - /@types/cookie@0.4.1: - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} - dev: false - /@types/cookiejar@2.1.5: resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} dev: true - /@types/cors@2.8.17: - resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} - dependencies: - '@types/node': 20.5.1 - dev: false - /@types/cross-spawn@6.0.6: resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} dependencies: @@ -12296,17 +11531,12 @@ packages: resolution: {integrity: sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==} dev: true - /@types/form-data@0.0.33: - resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} - dependencies: - '@types/node': 20.5.1 - dev: false - /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 '@types/node': 20.5.1 + dev: true /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -12337,10 +11567,6 @@ packages: '@types/node': 20.5.1 dev: false - /@types/i18n@0.8.8: - resolution: {integrity: sha512-RI4LFAraGrimMTxXkediCMXGVLC6ksXIIo3U+d3E4n+Mhw3uIDbmokO7DHlPB/eu6Tn6KBv4IUE1WrrEDRdNUQ==} - dev: false - /@types/ioredis@5.0.0: resolution: {integrity: sha512-zJbJ3FVE17CNl5KXzdeSPtdltc4tMT3TzC6fxQS0sQngkbFZ6h+0uTafsRqu+eSLIugf6Yb0Ea0SUuRr42Nk9g==} deprecated: This is a stub types definition. ioredis provides its own type definitions, so you do not need this installed. @@ -12390,6 +11616,7 @@ packages: /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: false /@types/jsonwebtoken@9.0.5: resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==} @@ -12397,27 +11624,6 @@ packages: '@types/node': 20.5.1 dev: false - /@types/keyv@3.1.4: - resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - dependencies: - '@types/node': 20.5.1 - dev: false - - /@types/knex@0.16.1(mysql2@1.7.0)(mysql@2.18.1): - resolution: {integrity: sha512-54gWD1HWwdVx5iLHaJ1qxH3I6KyBsj5fFqzRpXFn7REWiEB2jwspeVCombNsocSrqPd7IRPqKrsIME7/cD+TFQ==} - deprecated: This is a stub types definition. knex provides its own type definitions, so you do not need this installed. - dependencies: - knex: 0.95.15(mysql2@1.7.0)(mysql@2.18.1) - transitivePeerDependencies: - - mysql - - mysql2 - - pg - - pg-native - - sqlite3 - - supports-color - - tedious - dev: false - /@types/lodash.isempty@4.4.9: resolution: {integrity: sha512-DPSFfnT2JmZiAWNWOU8IRZws/Ha6zyGF5m06TydfsY+0dVoQqby2J61Na2QU4YtwiZ+moC6cJS6zWYBJq4wBVw==} dependencies: @@ -12435,6 +11641,7 @@ packages: resolution: {integrity: sha512-bpKs8CDJ0aOiiJguywryE/U6Wre/uftJ89xhp4aCgF4oRb3Yug2VyZ87958gmSeq4WMsvWPMs2Q5TtFv+dJtaA==} dependencies: decimal.js: 10.4.3 + dev: true /@types/mdx@2.0.13: resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} @@ -12457,21 +11664,17 @@ packages: /@types/minimatch@5.1.2: resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + dev: true /@types/minimist@1.2.5: resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - - /@types/mongodb@3.6.20: - resolution: {integrity: sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==} - dependencies: - '@types/bson': 4.0.5 - '@types/node': 20.5.1 - dev: false + dev: true /@types/multer@1.4.11: resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==} dependencies: - '@types/express': 4.17.21 + '@types/express': 5.0.0 + dev: false /@types/node-fetch@2.6.11: resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} @@ -12486,10 +11689,6 @@ packages: '@types/node': 20.5.1 dev: false - /@types/node@10.17.60: - resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} - dev: false - /@types/node@14.18.63: resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} dev: false @@ -12507,10 +11706,6 @@ packages: /@types/node@20.5.1: resolution: {integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==} - /@types/node@8.10.66: - resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} - dev: false - /@types/nodemailer@6.4.17: resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} dependencies: @@ -12519,6 +11714,7 @@ packages: /@types/normalize-package-data@2.4.4: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + dev: true /@types/parse-json@4.0.2: resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -12562,12 +11758,6 @@ packages: /@types/qs@6.9.15: resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - /@types/ramda@0.27.66: - resolution: {integrity: sha512-i2YW+E2U6NfMt3dp0RxNcejox+bxJUNDjB7BpYuRuoHIzv5juPHkJkNgcUOu+YSQEmaWu8cnAo/8r63C0NnuVA==} - dependencies: - ts-toolbelt: 6.15.5 - dev: true - /@types/ramda@0.28.25: resolution: {integrity: sha512-HrQNqQAGcITpn9HAJFamDxm7iZeeXiP/95pN5OMbNniDjzCCeOHbBKNGmUy8NRi0fhYS+/cXeo91MFC+06gbow==} dependencies: @@ -12642,12 +11832,6 @@ packages: '@types/node': 20.5.1 dev: false - /@types/responselike@1.0.3: - resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} - dependencies: - '@types/node': 20.5.1 - dev: false - /@types/retry@0.12.0: resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} dev: false @@ -12712,13 +11896,6 @@ packages: csstype: 3.1.3 dev: false - /@types/superagent@4.1.13: - resolution: {integrity: sha512-YIGelp3ZyMiH0/A09PMAORO0EBGlF5xIKfDpK74wdYvWUs2o96b5CItJcWPdH409b7SAXIIG6p8NdU/4U2Maww==} - dependencies: - '@types/cookiejar': 2.1.5 - '@types/node': 20.5.1 - dev: true - /@types/superagent@8.1.9: resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} dependencies: @@ -12756,10 +11933,6 @@ packages: pretty-format: 25.5.0 dev: false - /@types/triple-beam@1.3.5: - resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} - dev: false - /@types/trusted-types@2.0.7: resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} dev: false @@ -12775,23 +11948,6 @@ packages: /@types/validator@13.12.2: resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} - /@types/webidl-conversions@7.0.3: - resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} - dev: false - - /@types/whatwg-url@11.0.5: - resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==} - dependencies: - '@types/webidl-conversions': 7.0.3 - dev: false - - /@types/whatwg-url@8.2.2: - resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} - dependencies: - '@types/node': 20.5.1 - '@types/webidl-conversions': 7.0.3 - dev: false - /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: @@ -12823,14 +11979,6 @@ packages: dependencies: '@types/yargs-parser': 21.0.3 - /@types/yauzl@2.10.3: - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - requiresBuild: true - dependencies: - '@types/node': 20.5.1 - dev: false - optional: true - /@types/yup@0.29.14: resolution: {integrity: sha512-Ynb/CjHhE/Xp/4bhHmQC4U1Ox+I2OpfRYF3dnNgQqn1cHa6LK3H1wJMNPT02tSVZA6FYuXE2ITORfbnb6zBCSA==} @@ -12856,34 +12004,6 @@ packages: - supports-color dev: false - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@3.9.10): - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - debug: 4.3.4 - eslint: 8.57.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare-lite: 1.4.0 - semver: 7.6.2 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@4.9.5): resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -12895,7 +12015,7 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.10.0 + '@eslint-community/regexpp': 4.11.2 '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) @@ -12988,26 +12108,6 @@ packages: - supports-color dev: false - /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@3.9.10): - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@3.9.10) - debug: 4.3.4 - eslint: 8.57.0 - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@4.9.5): resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -13064,26 +12164,6 @@ packages: '@typescript-eslint/visitor-keys': 8.11.0 dev: true - /@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@3.9.10): - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@3.9.10) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - debug: 4.3.7(supports-color@5.5.0) - eslint: 8.57.0 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@4.9.5): resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -13153,27 +12233,6 @@ packages: - supports-color dev: false - /@typescript-eslint/typescript-estree@5.62.0(typescript@3.9.10): - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.7(supports-color@5.5.0) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.6.2 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5): resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -13188,7 +12247,7 @@ packages: debug: 4.3.7(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.6.2 + semver: 7.6.3 tsutils: 3.21.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: @@ -13209,7 +12268,7 @@ packages: debug: 4.3.7(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.6.2 + semver: 7.6.3 tsutils: 3.21.0(typescript@5.6.3) typescript: 5.6.3 transitivePeerDependencies: @@ -13231,33 +12290,13 @@ packages: fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.4 - semver: 7.6.2 + semver: 7.6.3 ts-api-utils: 1.3.0(typescript@5.6.3) typescript: 5.6.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@3.9.10): - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@3.9.10) - eslint: 8.57.0 - eslint-scope: 5.1.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@4.9.5): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -13329,10 +12368,6 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@tyriar/fibonacci-heap@2.0.9: - resolution: {integrity: sha512-bYuSNomfn4hu2tPiDN+JZtnzCpSpbJ/PNeulmocDy3xN2X5OkJL65zo6rPZp65cPPhLF9vfT/dgE+RtFRCSxOA==} - dev: false - /@ucast/core@1.10.2: resolution: {integrity: sha512-ons5CwXZ/51wrUPfoduC+cO7AS1/wRb0ybpQJ9RrssossDxVy4t49QxWoWgfBDvVKsz9VXzBk9z0wqTdZ+Cq8g==} dev: false @@ -13359,6 +12394,7 @@ packages: /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: false /@vitejs/plugin-react@3.1.0(vite@5.4.10): resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} @@ -13610,15 +12646,6 @@ packages: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 - /@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0)(webpack@5.91.0): - resolution: {integrity: sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==} - peerDependencies: - webpack: 4.x.x || 5.x.x - webpack-cli: 4.x.x - dependencies: - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - webpack-cli: 4.10.0(webpack@5.91.0) - /@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.91.0): resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} engines: {node: '>=14.15.0'} @@ -13629,14 +12656,6 @@ packages: webpack: 5.91.0(esbuild@0.18.20)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.91.0) - /@webpack-cli/info@1.5.0(webpack-cli@4.10.0): - resolution: {integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==} - peerDependencies: - webpack-cli: 4.x.x - dependencies: - envinfo: 7.13.0 - webpack-cli: 4.10.0(webpack@5.91.0) - /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.91.0): resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} engines: {node: '>=14.15.0'} @@ -13647,17 +12666,6 @@ packages: webpack: 5.91.0(esbuild@0.18.20)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.91.0) - /@webpack-cli/serve@1.7.0(webpack-cli@4.10.0): - resolution: {integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==} - peerDependencies: - webpack-cli: 4.x.x - webpack-dev-server: '*' - peerDependenciesMeta: - webpack-dev-server: - optional: true - dependencies: - webpack-cli: 4.10.0(webpack@5.91.0) - /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.91.0): resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} engines: {node: '>=14.15.0'} @@ -13817,14 +12825,6 @@ packages: dependencies: acorn: 8.11.3 - /acorn-import-attributes@1.9.5(acorn@8.14.0): - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} - peerDependencies: - acorn: ^8 - dependencies: - acorn: 8.14.0 - dev: false - /acorn-jsx@5.3.2(acorn@7.4.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -13839,13 +12839,14 @@ packages: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: acorn: 8.11.3 + dev: false - /acorn-jsx@5.3.2(acorn@8.13.0): + /acorn-jsx@5.3.2(acorn@8.14.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.13.0 + acorn: 8.14.0 dev: true /acorn-walk@7.2.0: @@ -13866,11 +12867,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /acorn@8.13.0: - resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} - engines: {node: '>=0.4.0'} - hasBin: true - /acorn@8.14.0: resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} @@ -13907,46 +12903,6 @@ packages: engines: {node: '>=0.8'} dev: false - /agenda@4.4.0(@aws-sdk/client-sso-oidc@3.583.0): - resolution: {integrity: sha512-7fIO4indmmrtkDmj2woOBJnhHIM7jPtkdGR4VOApB46eeBrPGUnO28RFrmjHebc3PMDnKJI0PWFyu9L9VotgJg==} - engines: {node: '>=12.9.0'} - dependencies: - cron-parser: 3.5.0 - date.js: 0.3.3 - debug: 4.3.4 - human-interval: 2.0.1 - moment-timezone: 0.5.45 - mongodb: 4.17.2(@aws-sdk/client-sso-oidc@3.583.0) - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - supports-color - dev: false - - /agendash@3.1.0(@aws-sdk/client-sso-oidc@3.583.0): - resolution: {integrity: sha512-p5LxPMDtUotWevZd19eeEyyx9OfbUHux4qplDTPJ09V72ay4lKN2TD44mQDZoCa5DBw7JzWOQMyzppaSdmXO1g==} - engines: {node: '>=10.0.0'} - hasBin: true - dependencies: - agenda: 4.4.0(@aws-sdk/client-sso-oidc@3.583.0) - body-parser: 1.20.2 - commander: 2.20.3 - express: 4.19.2 - mongodb: 6.6.2 - semver: 7.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - '@aws-sdk/credential-providers' - - '@mongodb-js/zstd' - - aws-crt - - gcp-metadata - - kerberos - - mongodb-client-encryption - - snappy - - socks - - supports-color - dev: false - /agent-base@5.1.1: resolution: {integrity: sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==} engines: {node: '>= 6.0.0'} @@ -13967,6 +12923,7 @@ packages: debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color + dev: true /agentkeepalive@4.5.0: resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} @@ -13981,6 +12938,7 @@ packages: dependencies: clean-stack: 2.2.0 indent-string: 4.0.0 + dev: true /ajv-draft-04@1.0.0(ajv@8.13.0): resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} @@ -14012,17 +12970,6 @@ packages: ajv: 8.12.0 dev: true - /ajv-formats@2.1.1(ajv@8.13.0): - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - dependencies: - ajv: 8.13.0 - dev: false - /ajv-formats@2.1.1(ajv@8.17.1): resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -14052,12 +12999,12 @@ packages: dependencies: ajv: 6.12.6 - /ajv-keywords@5.1.0(ajv@8.13.0): + /ajv-keywords@5.1.0(ajv@8.17.1): resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: ajv: ^8.8.2 dependencies: - ajv: 8.13.0 + ajv: 8.17.1 fast-deep-equal: 3.1.3 dev: false @@ -14084,6 +13031,7 @@ packages: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 uri-js: 4.4.1 + dev: false /ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -14092,19 +13040,6 @@ packages: fast-uri: 3.0.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - dev: false - - /ansi-align@2.0.0: - resolution: {integrity: sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA==} - dependencies: - string-width: 2.1.1 - dev: false - - /ansi-colors@1.1.0: - resolution: {integrity: sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -14117,31 +13052,16 @@ packages: dependencies: type-fest: 0.21.3 - /ansi-gray@0.1.1: - resolution: {integrity: sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - /ansi-html-community@0.0.8: resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} engines: {'0': node >= 0.8.0} hasBin: true dev: false - /ansi-regex@2.1.1: - resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} - engines: {node: '>=0.10.0'} - dev: false - - /ansi-regex@3.0.1: - resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} - engines: {node: '>=4'} - /ansi-regex@4.1.1: resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} engines: {node: '>=6'} + dev: false /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -14156,6 +13076,7 @@ packages: engines: {node: '>=4'} dependencies: color-convert: 1.9.3 + dev: false /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} @@ -14171,23 +13092,10 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - /ansi-wrap@0.1.0: - resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} - engines: {node: '>=0.10.0'} - /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} dev: false - /anymatch@2.0.0(supports-color@5.5.0): - resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} - dependencies: - micromatch: 3.1.10(supports-color@5.5.0) - normalize-path: 2.1.1 - transitivePeerDependencies: - - supports-color - dev: false - /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -14199,34 +13107,12 @@ packages: resolution: {integrity: sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==} dev: true - /app-root-path@3.1.0: - resolution: {integrity: sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==} - engines: {node: '>= 6.0.0'} - dev: false - - /append-buffer@1.0.2: - resolution: {integrity: sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==} - engines: {node: '>=0.10.0'} - dependencies: - buffer-equal: 1.0.1 - dev: false - /append-field@1.0.0: resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - /append-transform@1.0.0: - resolution: {integrity: sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==} - engines: {node: '>=4'} - dependencies: - default-require-extensions: 2.0.0 - dev: true - /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - /archy@1.0.0: - resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} - /are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} @@ -14292,25 +13178,11 @@ packages: engines: {node: '>=0.10.0'} dev: false - /arr-filter@1.1.2: - resolution: {integrity: sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==} - engines: {node: '>=0.10.0'} - dependencies: - make-iterator: 1.0.1 - dev: false - /arr-flatten@1.1.0: resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} engines: {node: '>=0.10.0'} dev: false - /arr-map@2.0.2: - resolution: {integrity: sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==} - engines: {node: '>=0.10.0'} - dependencies: - make-iterator: 1.0.1 - dev: false - /arr-union@3.1.0: resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} engines: {node: '>=0.10.0'} @@ -14328,22 +13200,9 @@ packages: engines: {node: '>=8'} dev: true - /array-each@1.0.1: - resolution: {integrity: sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==} - engines: {node: '>=0.10.0'} - dev: false - - /array-find@1.0.0: - resolution: {integrity: sha512-kO/vVCacW9mnpn3WPWbTVlEnOabK2L7LWi2HViURtCM46y1zb6I8UMjx4LgbiqadTgHnLInUronwn3ampNTJtQ==} - dev: true - /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - /array-from@2.1.1: - resolution: {integrity: sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==} - dev: true - /array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} dev: true @@ -14358,56 +13217,16 @@ packages: es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 is-string: 1.0.7 - - /array-initial@1.1.0: - resolution: {integrity: sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==} - engines: {node: '>=0.10.0'} - dependencies: - array-slice: 1.1.0 - is-number: 4.0.0 - dev: false - - /array-last@1.3.0: - resolution: {integrity: sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 4.0.0 - dev: false - - /array-slice@1.1.0: - resolution: {integrity: sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==} - engines: {node: '>=0.10.0'} - dev: false - - /array-sort@1.0.0: - resolution: {integrity: sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==} - engines: {node: '>=0.10.0'} - dependencies: - default-compare: 1.0.0 - get-value: 2.0.6 - kind-of: 5.1.0 dev: false /array-timsort@1.0.3: resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} dev: true - /array-union@1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} - dependencies: - array-uniq: 1.0.3 - dev: false - /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - /array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} - dev: false - /array-unique@0.3.2: resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} engines: {node: '>=0.10.0'} @@ -14435,6 +13254,7 @@ packages: es-errors: 1.3.0 es-object-atoms: 1.0.0 es-shim-unscopables: 1.0.2 + dev: false /array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} @@ -14444,6 +13264,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 + dev: false /array.prototype.flatmap@1.3.2: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} @@ -14453,6 +13274,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 + dev: false /array.prototype.reduce@1.0.7: resolution: {integrity: sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==} @@ -14498,41 +13320,25 @@ packages: get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 + dev: false /arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} + dev: true /arrify@2.0.1: resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} engines: {node: '>=8'} + dev: true /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - /asn1.js@4.10.1: - resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} - dependencies: - bn.js: 4.12.0 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - dev: true - /assert-never@1.2.1: resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} dev: false - /assert@1.5.1: - resolution: {integrity: sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==} - dependencies: - object.assign: 4.1.5 - util: 0.10.4 - dev: true - - /assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - dev: true - /assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -14568,20 +13374,6 @@ packages: tslib: 2.8.0 dev: true - /async-done@1.3.2: - resolution: {integrity: sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==} - engines: {node: '>= 0.10'} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - process-nextick-args: 2.0.1 - stream-exhaust: 1.0.2 - dev: false - - /async-each@1.0.6: - resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} - dev: false - /async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} dev: true @@ -14592,13 +13384,6 @@ packages: tslib: 2.6.2 dev: false - /async-settle@1.0.0: - resolution: {integrity: sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==} - engines: {node: '>= 0.10'} - dependencies: - async-done: 1.3.2 - dev: false - /async@3.2.5: resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} @@ -14779,20 +13564,7 @@ packages: loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - dev: false - - /babel-loader@9.1.3(@babel/core@7.26.0)(webpack@5.91.0): - resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==} - engines: {node: '>= 14.15.0'} - peerDependencies: - '@babel/core': ^7.12.0 - webpack: '>=5' - dependencies: - '@babel/core': 7.26.0 - find-cache-dir: 4.0.0 - schema-utils: 4.2.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /babel-plugin-emotion@10.2.2: @@ -15072,32 +13844,12 @@ packages: '@babel/types': 7.26.0 dev: false - /bach@1.2.0: - resolution: {integrity: sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==} - engines: {node: '>= 0.10'} - dependencies: - arr-filter: 1.1.2 - arr-flatten: 1.1.0 - arr-map: 2.0.2 - array-each: 1.0.1 - array-initial: 1.1.0 - array-last: 1.3.0 - async-done: 1.3.2 - async-settle: 1.0.0 - now-and-later: 2.0.1 - dev: false - /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - /base64id@2.0.0: - resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} - engines: {node: ^4.5.0 || >= 5.9} - dev: false - /base@0.11.2: resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} engines: {node: '>=0.10.0'} @@ -15111,18 +13863,6 @@ packages: pascalcase: 0.1.1 dev: false - /basic-auth@1.1.0: - resolution: {integrity: sha512-CtGuTyWf3ig+sgRyC7uP6DM3N+5ur/p8L+FPfsd+BbIfIs74TFfCajZTHnCw6K5dqM0bZEbRIqRy1fAdiUJhTA==} - engines: {node: '>= 0.6'} - dev: false - - /basic-auth@2.0.1: - resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} - engines: {node: '>= 0.8'} - dependencies: - safe-buffer: 5.1.2 - dev: false - /basscss-align@1.0.2: resolution: {integrity: sha512-T7XvlG6jqjBvQ27xSioO5p069E5jW12QbOy+V+QKnkmfwkU+SDTrcLI2DMSlTPGbPmtDZHeRrG9qwOhjbaMMbg==} dev: false @@ -15236,72 +13976,29 @@ packages: resolution: {integrity: sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==} dev: false - /bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - dev: false - - /binary-extensions@1.13.1: - resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} - engines: {node: '>=0.10.0'} - dev: false - /binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - /bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - requiresBuild: true - dependencies: - file-uri-to-path: 1.0.0 - dev: false - optional: true - - /bl@2.2.1: - resolution: {integrity: sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==} - dependencies: - readable-stream: 2.3.8 - safe-buffer: 5.2.1 - dev: false - /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 - - /bluebird@2.11.0: - resolution: {integrity: sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ==} - dev: false - - /bluebird@3.5.0: - resolution: {integrity: sha512-3LE8m8bqjGdoxfvf71yhFNrUcwy3NLy00SAo+b6MfJ8l+Bc2DzQ7mUHwX6pjK2AxfgV+YfsjCeVW3T5HLQTBsQ==} - dev: false - - /bluebird@3.5.1: - resolution: {integrity: sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==} - dev: false + dev: true /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: false - /bn.js@4.12.0: - resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - dev: true - - /bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - dev: true - /body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 http-errors: 2.0.0 @@ -15313,6 +14010,7 @@ packages: unpipe: 1.0.0 transitivePeerDependencies: - supports-color + dev: true /body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} @@ -15320,7 +14018,7 @@ packages: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 http-errors: 2.0.0 @@ -15344,13 +14042,6 @@ packages: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: false - /boom@7.3.0: - resolution: {integrity: sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==} - deprecated: This module has moved and is now available at @hapi/boom. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues. - dependencies: - hoek: 6.1.3 - dev: false - /bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} dev: false @@ -15359,19 +14050,6 @@ packages: resolution: {integrity: sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==} dev: false - /boxen@1.3.0: - resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==} - engines: {node: '>=4'} - dependencies: - ansi-align: 2.0.0 - camelcase: 4.1.0 - chalk: 2.4.2 - cli-boxes: 1.0.0 - string-width: 2.1.1 - term-size: 1.2.0 - widest-line: 2.0.1 - dev: false - /bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} engines: {node: '>= 5.10.0'} @@ -15390,7 +14068,7 @@ packages: dependencies: balanced-match: 1.0.2 - /braces@2.3.2(supports-color@5.5.0): + /braces@2.3.2: resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} engines: {node: '>=0.10.0'} dependencies: @@ -15400,7 +14078,7 @@ packages: fill-range: 4.0.0 isobject: 3.0.1 repeat-element: 1.1.4 - snapdragon: 0.8.2(supports-color@5.5.0) + snapdragon: 0.8.2 snapdragon-node: 2.1.1 split-string: 3.1.0 to-regex: 3.0.2 @@ -15427,10 +14105,6 @@ packages: unload: 2.2.0 dev: false - /brorand@1.1.0: - resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - dev: true - /browser-assert@1.2.1: resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} dev: true @@ -15439,73 +14113,12 @@ packages: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} dev: false - /browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - dev: true - - /browserify-aes@1.2.0: - resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} - dependencies: - buffer-xor: 1.0.3 - cipher-base: 1.0.4 - create-hash: 1.2.0 - evp_bytestokey: 1.0.3 - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - - /browserify-cipher@1.0.1: - resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} - dependencies: - browserify-aes: 1.2.0 - browserify-des: 1.0.2 - evp_bytestokey: 1.0.3 - dev: true - - /browserify-des@1.0.2: - resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} - dependencies: - cipher-base: 1.0.4 - des.js: 1.1.0 - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - - /browserify-rsa@4.1.0: - resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} - dependencies: - bn.js: 5.2.1 - randombytes: 2.1.0 - dev: true - - /browserify-sign@4.2.3: - resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} - engines: {node: '>= 0.12'} - dependencies: - bn.js: 5.2.1 - browserify-rsa: 4.1.0 - create-hash: 1.2.0 - create-hmac: 1.1.7 - elliptic: 6.5.5 - hash-base: 3.0.4 - inherits: 2.0.4 - parse-asn1: 5.1.7 - readable-stream: 2.3.8 - safe-buffer: 5.2.1 - dev: true - /browserify-zlib@0.1.4: resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} dependencies: pako: 0.2.9 dev: true - /browserify-zlib@0.2.0: - resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - dependencies: - pako: 1.0.11 - dev: true - /browserslist@4.14.2: resolution: {integrity: sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -15549,35 +14162,14 @@ packages: dependencies: node-int64: 0.4.0 - /bson@1.1.6: - resolution: {integrity: sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==} - engines: {node: '>=0.6.19'} - dev: false - - /bson@4.7.2: - resolution: {integrity: sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==} - engines: {node: '>=6.9.0'} - dependencies: - buffer: 5.7.1 - dev: false - - /bson@6.7.0: - resolution: {integrity: sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==} - engines: {node: '>=16.20.1'} - dev: false - /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true /buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} dev: false - /buffer-equal@1.0.1: - resolution: {integrity: sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==} - engines: {node: '>=0.4'} - dev: false - /buffer-from@0.1.2: resolution: {integrity: sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==} dev: false @@ -15585,18 +14177,6 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - /buffer-xor@1.0.3: - resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} - dev: true - - /buffer@4.9.2: - resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - isarray: 1.0.0 - dev: true - /buffer@5.6.0: resolution: {integrity: sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==} dependencies: @@ -15609,6 +14189,7 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + dev: true /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -15622,10 +14203,6 @@ packages: engines: {node: '>=6'} dev: false - /builtin-status-codes@3.0.0: - resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} - dev: true - /builtins@1.0.3: resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} dev: true @@ -15645,7 +14222,7 @@ packages: ioredis: 5.6.0 lodash: 4.17.21 msgpackr: 1.11.2 - semver: 7.6.2 + semver: 7.6.3 uuid: 8.3.2 transitivePeerDependencies: - supports-color @@ -15658,8 +14235,8 @@ packages: ioredis: 5.6.0 msgpackr: 1.11.2 node-abort-controller: 3.1.1 - semver: 7.6.2 - tslib: 2.6.2 + semver: 7.6.3 + tslib: 2.8.0 uuid: 9.0.1 transitivePeerDependencies: - supports-color @@ -15724,7 +14301,7 @@ packages: dependencies: '@npmcli/fs': 3.1.1 fs-minipass: 3.0.3 - glob: 10.4.1 + glob: 10.4.2 lru-cache: 7.18.3 minipass: 7.1.2 minipass-collect: 1.0.2 @@ -15742,7 +14319,7 @@ packages: dependencies: '@npmcli/fs': 3.1.1 fs-minipass: 3.0.3 - glob: 10.4.1 + glob: 10.4.2 lru-cache: 10.2.2 minipass: 7.1.2 minipass-collect: 2.0.1 @@ -15752,6 +14329,7 @@ packages: ssri: 10.0.6 tar: 6.2.1 unique-filename: 3.0.0 + dev: true /cache-base@1.0.1: resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} @@ -15781,16 +14359,6 @@ packages: keyv: 5.2.1 dev: false - /caching-transform@3.0.2: - resolution: {integrity: sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==} - engines: {node: '>=6'} - dependencies: - hasha: 3.0.0 - make-dir: 2.1.0 - package-hash: 3.0.0 - write-file-atomic: 2.4.3 - dev: true - /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -15801,10 +14369,6 @@ packages: get-intrinsic: 1.2.4 set-function-length: 1.2.2 - /call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: false - /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -15828,16 +14392,7 @@ packages: camelcase: 5.3.1 map-obj: 4.3.0 quick-lru: 4.0.1 - - /camelcase@3.0.0: - resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} - engines: {node: '>=0.10.0'} - dev: false - - /camelcase@4.1.0: - resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} - engines: {node: '>=4'} - dev: false + dev: true /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} @@ -15878,20 +14433,11 @@ packages: upper-case-first: 2.0.2 dev: false - /capture-stack-trace@1.0.2: - resolution: {integrity: sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==} - engines: {node: '>=0.10.0'} - dev: false - /case-sensitive-paths-webpack-plugin@2.4.0: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} dev: false - /caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: false - /cfb@1.2.2: resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} engines: {node: '>=0.8'} @@ -15900,39 +14446,6 @@ packages: crc-32: 1.2.2 dev: false - /chai-http@4.4.0: - resolution: {integrity: sha512-uswN3rZpawlRaa5NiDUHcDZ3v2dw5QgLyAwnQ2tnVNuP7CwIsOFuYJ0xR1WiR7ymD4roBnJIzOUep7w9jQMFJA==} - engines: {node: '>=10'} - dependencies: - '@types/chai': 4.3.16 - '@types/superagent': 4.1.13 - charset: 1.0.1 - cookiejar: 2.1.4 - is-ip: 2.0.0 - methods: 1.1.2 - qs: 6.12.1 - superagent: 8.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /chai-things@0.2.0: - resolution: {integrity: sha512-6ns0SU21xdRCoEXVKH3HGbwnsgfVMXQ+sU5V8PI9rfxaITos8lss1vUxbF1FAcJKjfqmmmLVlr/z3sLes00w+A==} - dev: true - - /chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - dev: true - /chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} @@ -15951,6 +14464,7 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 + dev: false /chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} @@ -15958,6 +14472,7 @@ packages: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + dev: false /chalk@4.1.0: resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} @@ -16015,22 +14530,6 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /charset@1.0.1: - resolution: {integrity: sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==} - engines: {node: '>=4.0.0'} - dev: true - - /check-disk-space@3.4.0: - resolution: {integrity: sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==} - engines: {node: '>=16'} - dev: false - - /check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - dependencies: - get-func-name: 2.0.2 - dev: true - /check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -16040,27 +14539,6 @@ packages: resolution: {integrity: sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==} dev: false - /chokidar@2.1.8(supports-color@5.5.0): - resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} - deprecated: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies - dependencies: - anymatch: 2.0.0(supports-color@5.5.0) - async-each: 1.0.6 - braces: 2.3.2(supports-color@5.5.0) - glob-parent: 3.1.0 - inherits: 2.0.4 - is-binary-path: 1.0.1 - is-glob: 4.0.3 - normalize-path: 3.0.0 - path-is-absolute: 1.0.1 - readdirp: 2.2.1(supports-color@5.5.0) - upath: 1.2.0 - optionalDependencies: - fsevents: 1.2.13 - transitivePeerDependencies: - - supports-color - dev: false - /chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -16077,6 +14555,7 @@ packages: /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} @@ -16086,21 +14565,10 @@ packages: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} - /ci-info@1.6.0: - resolution: {integrity: sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==} - dev: false - /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - /cipher-base@1.0.4: - resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - /citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} dependencies: @@ -16144,11 +14612,7 @@ packages: /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} - - /cli-boxes@1.0.0: - resolution: {integrity: sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==} - engines: {node: '>=0.10.0'} - dev: false + dev: true /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} @@ -16186,22 +14650,6 @@ packages: engines: {node: '>= 12'} dev: true - /cliui@3.2.0: - resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} - dependencies: - string-width: 1.0.2 - strip-ansi: 3.0.1 - wrap-ansi: 2.1.0 - dev: false - - /cliui@5.0.0: - resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} - dependencies: - string-width: 3.1.0 - strip-ansi: 5.2.0 - wrap-ansi: 5.1.0 - dev: true - /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -16216,11 +14664,7 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - - /clone-buffer@1.0.0: - resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} - engines: {node: '>= 0.10'} - dev: false + dev: true /clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} @@ -16230,28 +14674,11 @@ packages: kind-of: 6.0.3 shallow-clone: 3.0.1 - /clone-stats@1.0.0: - resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} - dev: false - /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} dev: true - /clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - dev: false - - /cloneable-readable@1.1.3: - resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} - dependencies: - inherits: 2.0.4 - process-nextick-args: 2.0.1 - readable-stream: 2.3.8 - dev: false - /clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -16271,19 +14698,6 @@ packages: resolution: {integrity: sha512-9sxWwwprkPNTVQnx92WYPEWCmyZRqbf9VWUYABU4rl0mLL17VAV2MvvOApkMA6bQVXRLJ8jN//8Yp6drElpLWA==} dev: false - /co-bluebird@1.1.0: - resolution: {integrity: sha512-JuoemMXxQjYAxbfRrNpOsLyiwDiY8mXvGqJyYLM7jMySDJtnMklW3V2o8uyubpc1eN2YoRsAdfZ1lfKCd3lsrA==} - engines: {node: '>=0.12.0'} - dependencies: - bluebird: 2.11.0 - co-use: 1.1.0 - dev: false - - /co-use@1.1.0: - resolution: {integrity: sha512-1lVRtdywv41zQO/xvI2wU8w6oFcUYT6T84YKSxN25KN4N4Kld3scLovt8FjDmD63Cm7HtyRWHjezt+IanXmkyA==} - engines: {node: '>=0.12.0'} - dev: false - /co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -16297,15 +14711,6 @@ packages: q: 1.5.1 dev: false - /coalescy@1.0.0: - resolution: {integrity: sha512-OmRR46eVfyaXZYI7Ai5/vnLHjWhhh99sugx+UTsmVhwaYzARb+Tcdit59/HkVxF8KdqJG5NN8ClUhzQXS3Hh+w==} - dev: true - - /code-point-at@1.1.0: - resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} - engines: {node: '>=0.10.0'} - dev: false - /codepage@1.15.0: resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} engines: {node: '>=0.8'} @@ -16314,15 +14719,6 @@ packages: /collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - /collection-map@1.0.0: - resolution: {integrity: sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-map: 2.0.2 - for-own: 1.0.0 - make-iterator: 1.0.1 - dev: false - /collection-visit@1.0.0: resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} engines: {node: '>=0.10.0'} @@ -16335,6 +14731,7 @@ packages: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 + dev: false /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} @@ -16344,40 +14741,19 @@ packages: /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: false /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - /color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - dev: false - /color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true - /color@3.2.1: - resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} - dependencies: - color-convert: 1.9.3 - color-string: 1.9.1 - dev: false - /colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} dev: false - /colorette@1.4.0: - resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} - dev: true - - /colorette@2.0.16: - resolution: {integrity: sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==} - dev: false - /colorette@2.0.19: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} dev: false @@ -16385,13 +14761,6 @@ packages: /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - /colorspace@1.1.4: - resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} - dependencies: - color: 3.2.1 - text-hex: 1.0.0 - dev: false - /columnify@1.6.0: resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} engines: {node: '>=8.0.0'} @@ -16410,10 +14779,6 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - /commander@2.15.1: - resolution: {integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==} - dev: true - /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -16421,11 +14786,6 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} - /commander@5.1.0: - resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} - engines: {node: '>= 6'} - dev: true - /commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -16434,6 +14794,7 @@ packages: /commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + dev: false /commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} @@ -16451,10 +14812,6 @@ packages: repeat-string: 1.6.1 dev: true - /common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - dev: false - /common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -16504,7 +14861,7 @@ packages: accepts: 1.3.8 bytes: 3.0.0 compressible: 2.0.18 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 on-headers: 1.0.2 safe-buffer: 5.1.2 vary: 1.1.2 @@ -16535,6 +14892,7 @@ packages: inherits: 2.0.4 readable-stream: 3.6.2 typedarray: 0.0.6 + dev: true /confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -16546,20 +14904,9 @@ packages: proto-list: 1.2.4 dev: false - /configstore@3.1.5: - resolution: {integrity: sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==} - engines: {node: '>=4'} - dependencies: - dot-prop: 4.2.1 - graceful-fs: 4.2.11 - make-dir: 1.3.0 - unique-string: 1.0.0 - write-file-atomic: 2.4.3 - xdg-basedir: 3.0.0 - dev: false - /confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + dev: false /connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} @@ -16573,10 +14920,6 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} - /console-browserify@1.2.0: - resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} - dev: true - /console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} @@ -16595,10 +14938,6 @@ packages: '@babel/types': 7.26.0 dev: false - /constants-browserify@1.0.0: - resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} - dev: true - /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -16718,16 +15057,6 @@ packages: engines: {node: '>= 0.6'} dev: false - /cookie@0.4.0: - resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==} - engines: {node: '>= 0.6'} - dev: false - - /cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} - dev: false - /cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} @@ -16736,6 +15065,7 @@ packages: /cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + dev: true /cookie@0.7.1: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} @@ -16755,13 +15085,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /copy-props@2.0.5: - resolution: {integrity: sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==} - dependencies: - each-props: 1.3.2 - is-plain-object: 5.0.0 - dev: false - /copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} dependencies: @@ -16850,100 +15173,12 @@ packages: path-type: 4.0.0 typescript: 5.6.3 - /country-codes-list@1.6.11: - resolution: {integrity: sha512-MsHoJ83tGyv9tFspeI8yHBomiTH4rruHxdWhNWGG9d1ykXgLyawh/VykmYPH5KqduY+9Q2RUNlL2/KGkXJqANA==} - dev: false - - /cp-file@6.2.0: - resolution: {integrity: sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==} - engines: {node: '>=6'} - dependencies: - graceful-fs: 4.2.11 - make-dir: 2.1.0 - nested-error-stacks: 2.1.1 - pify: 4.0.1 - safe-buffer: 5.2.1 - dev: true - - /cp-file@7.0.0: - resolution: {integrity: sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==} - engines: {node: '>=8'} - dependencies: - graceful-fs: 4.2.11 - make-dir: 3.1.0 - nested-error-stacks: 2.1.1 - p-event: 4.2.0 - dev: false - - /cpy-cli@3.1.1: - resolution: {integrity: sha512-HCpNdBkQy3rw+uARLuIf0YurqsMXYzBa9ihhSAuxYJcNIrqrSq3BstPfr0cQN38AdMrQiO9Dp4hYy7GtGJsLPg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - cpy: 8.1.2 - meow: 6.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /cpy@8.1.2: - resolution: {integrity: sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==} - engines: {node: '>=8'} - dependencies: - arrify: 2.0.1 - cp-file: 7.0.0 - globby: 9.2.0 - has-glob: 1.0.0 - junk: 3.1.0 - nested-error-stacks: 2.1.1 - p-all: 2.1.0 - p-filter: 2.1.0 - p-map: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: false - /crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} hasBin: true dev: false - /create-ecdh@4.0.4: - resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} - dependencies: - bn.js: 4.12.0 - elliptic: 6.5.5 - dev: true - - /create-error-class@3.0.2: - resolution: {integrity: sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==} - engines: {node: '>=0.10.0'} - dependencies: - capture-stack-trace: 1.0.2 - dev: false - - /create-hash@1.2.0: - resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} - dependencies: - cipher-base: 1.0.4 - inherits: 2.0.4 - md5.js: 1.3.5 - ripemd160: 2.0.2 - sha.js: 2.4.11 - dev: true - - /create-hmac@1.1.7: - resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - dependencies: - cipher-base: 1.0.4 - create-hash: 1.2.0 - inherits: 2.0.4 - ripemd160: 2.0.2 - safe-buffer: 5.2.1 - sha.js: 2.4.11 - dev: true - /create-jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -16970,14 +15205,6 @@ packages: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} dev: false - /cron-parser@3.5.0: - resolution: {integrity: sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==} - engines: {node: '>=0.8'} - dependencies: - is-nan: 1.3.2 - luxon: 1.28.1 - dev: false - /cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} @@ -16985,14 +15212,6 @@ packages: luxon: 3.5.0 dev: false - /cross-env@5.2.1: - resolution: {integrity: sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==} - engines: {node: '>=4.0'} - hasBin: true - dependencies: - cross-spawn: 6.0.5 - dev: true - /cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -17001,32 +15220,6 @@ packages: cross-spawn: 7.0.3 dev: false - /cross-spawn@4.0.2: - resolution: {integrity: sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==} - dependencies: - lru-cache: 4.1.5 - which: 1.3.1 - dev: true - - /cross-spawn@5.1.0: - resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} - dependencies: - lru-cache: 4.1.5 - shebang-command: 1.2.0 - which: 1.3.1 - dev: false - - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - dev: true - /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -17035,47 +15228,10 @@ packages: shebang-command: 2.0.0 which: 2.0.2 - /crypto-browserify@3.12.0: - resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} - dependencies: - browserify-cipher: 1.0.1 - browserify-sign: 4.2.3 - create-ecdh: 4.0.4 - create-hash: 1.2.0 - create-hmac: 1.1.7 - diffie-hellman: 5.0.3 - inherits: 2.0.4 - pbkdf2: 3.1.2 - public-encrypt: 4.0.3 - randombytes: 2.1.0 - randomfill: 1.0.4 - dev: true - - /crypto-random-string@1.0.0: - resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} - engines: {node: '>=4'} - dev: false - /crypto-random-string@2.0.0: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} - /crypto-random-string@3.3.1: - resolution: {integrity: sha512-5j88ECEn6h17UePrLi6pn1JcLtAiANa3KExyr9y9Z5vo2mv56Gh3I4Aja/B9P9uyMwyxNHAHWv+nE72f30T5Dg==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.8.1 - dev: false - - /csrf@3.1.0: - resolution: {integrity: sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==} - engines: {node: '>= 0.8'} - dependencies: - rndm: 1.2.0 - tsscmp: 1.0.6 - uid-safe: 2.1.5 - dev: false - /css-animation@1.6.1: resolution: {integrity: sha512-/48+/BaEaHRY6kNQ2OIPzKf9A6g8WjZYjhiNDNuIVbsm5tXCGIAsHDjB4Xu1C4vXJtUWZo26O68OQkDpNBaPog==} dependencies: @@ -17145,7 +15301,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.47) postcss-value-parser: 4.2.0 semver: 7.6.3 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) /css-loader@6.11.0(webpack@5.96.1): resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} @@ -17196,7 +15352,7 @@ packages: schema-utils: 4.2.0 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /css-prefers-color-scheme@6.0.3(postcss@8.4.38): @@ -17363,17 +15519,6 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - /csurf@1.11.0: - resolution: {integrity: sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==} - engines: {node: '>= 0.8.0'} - deprecated: Please use another csrf package - dependencies: - cookie: 0.4.0 - cookie-signature: 1.0.6 - csrf: 3.1.0 - http-errors: 1.7.3 - dev: false - /d@1.0.2: resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} engines: {node: '>=0.12'} @@ -17411,6 +15556,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 + dev: false /data-view-byte-length@1.0.1: resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} @@ -17419,6 +15565,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 + dev: false /data-view-byte-offset@1.0.0: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} @@ -17427,18 +15574,6 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 - - /date-format@4.0.14: - resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} - engines: {node: '>=4.0'} - dev: false - - /date.js@0.3.3: - resolution: {integrity: sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==} - dependencies: - debug: 3.1.0(supports-color@5.4.0) - transitivePeerDependencies: - - supports-color dev: false /dateformat@3.0.3: @@ -17453,7 +15588,7 @@ packages: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} dev: false - /debug@2.6.9(supports-color@5.5.0): + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: supports-color: '*' @@ -17462,20 +15597,8 @@ packages: optional: true dependencies: ms: 2.0.0 - supports-color: 5.5.0 - /debug@3.1.0(supports-color@5.4.0): - resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - supports-color: 5.4.0 - - /debug@3.2.7(supports-color@5.5.0): + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' @@ -17484,30 +15607,6 @@ packages: optional: true dependencies: ms: 2.1.3 - supports-color: 5.5.0 - - /debug@4.3.1: - resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: false - - /debug@4.3.2: - resolution: {integrity: sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 dev: false /debug@4.3.4: @@ -17520,6 +15619,7 @@ packages: optional: true dependencies: ms: 2.1.2 + dev: false /debug@4.3.7(supports-color@5.5.0): resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} @@ -17539,10 +15639,12 @@ packages: dependencies: decamelize: 1.2.0 map-obj: 1.0.1 + dev: true /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + dev: true /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} @@ -17568,13 +15670,6 @@ packages: optional: true dev: true - /deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} - engines: {node: '>=6'} - dependencies: - type-detect: 4.0.8 - dev: true - /deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -17616,22 +15711,9 @@ packages: which-typed-array: 1.1.15 dev: true - /deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - dev: false - /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - /deep-map@2.0.0: - resolution: {integrity: sha512-guIurpeZi1wiclCEEHpJmFx7Tr4gkmSBNcUpY67maP4BJeEa1JPVf9KXURcCI/cAHsvGtqVwQKI/X39rY735Rg==} - engines: {node: '>=6'} - dependencies: - lodash: 4.17.21 - tslib: 1.14.1 - dev: false - /deepdash@5.3.9: resolution: {integrity: sha512-GRzJ0q9PDj2T+J2fX+b+TlUa2NlZ11l6vJ8LHNKVGeZ8CfxCuJaCychTq07iDRTvlfO8435jlvVS1QXBrW9kMg==} dependencies: @@ -17656,13 +15738,6 @@ packages: untildify: 4.0.0 dev: true - /default-compare@1.0.0: - resolution: {integrity: sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 5.1.0 - dev: false - /default-gateway@6.0.3: resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} engines: {node: '>= 10'} @@ -17670,18 +15745,6 @@ packages: execa: 5.1.1 dev: false - /default-require-extensions@2.0.0: - resolution: {integrity: sha512-B0n2zDIXpzLzKeoEozorDSa1cHc1t0NjmxP0zuAxbizNU2MBqYJJKYXrrFdKuQliojXynrxgd7l4ahfg/+aA5g==} - engines: {node: '>=4'} - dependencies: - strip-bom: 3.0.0 - dev: true - - /default-resolution@2.0.0: - resolution: {integrity: sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==} - engines: {node: '>= 0.10'} - dev: false - /defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: @@ -17787,22 +15850,10 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - /des.js@1.1.0: - resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - dev: true - /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - /detect-file@1.0.0: - resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} - engines: {node: '>=0.10.0'} - dev: false - /detect-indent@5.0.0: resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} engines: {node: '>=4'} @@ -17844,7 +15895,7 @@ packages: hasBin: true dependencies: address: 1.1.2 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 transitivePeerDependencies: - supports-color dev: false @@ -17860,10 +15911,6 @@ packages: - supports-color dev: true - /devtools-protocol@0.0.901419: - resolution: {integrity: sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ==} - dev: false - /dezalgo@1.0.4: resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} dependencies: @@ -17885,30 +15932,10 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /diff@3.5.0: - resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} - engines: {node: '>=0.3.1'} - dev: true - /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - /diffie-hellman@5.0.3: - resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} - dependencies: - bn.js: 4.12.0 - miller-rabin: 4.0.1 - randombytes: 2.1.0 - dev: true - - /dir-glob@2.2.2: - resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} - engines: {node: '>=4'} - dependencies: - path-type: 3.0.0 - dev: false - /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -17931,6 +15958,7 @@ packages: engines: {node: '>=0.10.0'} dependencies: esutils: 2.0.3 + dev: false /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} @@ -17993,11 +16021,6 @@ packages: resolution: {integrity: sha512-JkCVGnN4ofKGbjf5Uvc8mmxaATIErKQKSgACdBXpsQ3fY6DlIpAyWfiBSrGkttATssbDCp3psiAKWXk5gmjycA==} dev: false - /domain-browser@1.2.0: - resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==} - engines: {node: '>=0.4', npm: '>=1.2'} - dev: true - /domelementtype@1.3.1: resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} dev: false @@ -18063,13 +16086,6 @@ packages: tslib: 2.8.0 dev: false - /dot-prop@4.2.1: - resolution: {integrity: sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==} - engines: {node: '>=4'} - dependencies: - is-obj: 1.0.1 - dev: false - /dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -18121,7 +16137,6 @@ packages: /dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} - dev: false /dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} @@ -18134,10 +16149,6 @@ packages: readable-stream: 2.3.8 dev: false - /duplexer3@0.1.5: - resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - dev: false - /duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -18148,13 +16159,7 @@ packages: inherits: 2.0.4 readable-stream: 2.3.8 stream-shift: 1.0.3 - - /each-props@1.3.2: - resolution: {integrity: sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==} - dependencies: - is-plain-object: 2.0.4 - object.defaults: 1.1.0 - dev: false + dev: true /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -18192,18 +16197,6 @@ packages: /electron-to-chromium@1.5.47: resolution: {integrity: sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==} - /elliptic@6.5.5: - resolution: {integrity: sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==} - dependencies: - bn.js: 4.12.0 - brorand: 1.1.0 - hash.js: 1.1.7 - hmac-drbg: 1.0.1 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - dev: true - /emittery@0.10.2: resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} engines: {node: '>=12'} @@ -18219,10 +16212,6 @@ packages: engines: {node: '>=10'} dev: false - /emoji-regex@7.0.3: - resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} - dev: true - /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -18233,10 +16222,6 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} - /enabled@2.0.0: - resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - dev: false - /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -18250,12 +16235,14 @@ packages: requiresBuild: true dependencies: iconv-lite: 0.6.3 + dev: true optional: true /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 + dev: true /engine.io-client@6.5.3: resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==} @@ -18276,35 +16263,6 @@ packages: engines: {node: '>=10.0.0'} dev: false - /engine.io@6.5.4: - resolution: {integrity: sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==} - engines: {node: '>=10.2.0'} - dependencies: - '@types/cookie': 0.4.1 - '@types/cors': 2.8.17 - '@types/node': 20.5.1 - accepts: 1.3.8 - base64id: 2.0.0 - cookie: 0.4.2 - cors: 2.8.5 - debug: 4.3.7(supports-color@5.5.0) - engine.io-parser: 5.2.2 - ws: 8.11.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: false - - /enhanced-resolve@0.9.1: - resolution: {integrity: sha512-kxpoMgrdtkXZ5h0SeraBS1iRntpTpQ3R8ussdb38+UAFnMGX5DDyJXePm+OCHOcoXvHDw7mc2erbJBpDnl7TPw==} - engines: {node: '>=0.6'} - dependencies: - graceful-fs: 4.2.11 - memory-fs: 0.2.0 - tapable: 0.1.10 - dev: true - /enhanced-resolve@5.16.1: resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==} engines: {node: '>=10.13.0'} @@ -18338,6 +16296,7 @@ packages: /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + dev: true /envinfo@7.13.0: resolution: {integrity: sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==} @@ -18352,6 +16311,7 @@ packages: /err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + dev: true /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} @@ -18372,14 +16332,6 @@ packages: stackframe: 1.3.4 dev: false - /errorhandler@1.5.1: - resolution: {integrity: sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==} - engines: {node: '>= 0.8'} - dependencies: - accepts: 1.3.8 - escape-html: 1.0.3 - dev: false - /es-abstract@1.23.3: resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} @@ -18430,6 +16382,7 @@ packages: typed-array-length: 1.0.6 unbox-primitive: 1.0.2 which-typed-array: 1.1.15 + dev: false /es-array-method-boxes-properly@1.0.0: resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} @@ -18491,6 +16444,7 @@ packages: engines: {node: '>= 0.4'} dependencies: es-errors: 1.3.0 + dev: false /es-set-tostringtag@2.0.3: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} @@ -18499,11 +16453,13 @@ packages: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 hasown: 2.0.2 + dev: false /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: hasown: 2.0.2 + dev: false /es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} @@ -18512,6 +16468,7 @@ packages: is-callable: 1.2.7 is-date-object: 1.0.5 is-symbol: 1.0.4 + dev: false /es5-ext@0.10.64: resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} @@ -18524,10 +16481,6 @@ packages: next-tick: 1.1.0 dev: false - /es6-error@4.1.1: - resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} - dev: true - /es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} dependencies: @@ -18544,15 +16497,6 @@ packages: ext: 1.7.0 dev: false - /es6-weak-map@2.0.3: - resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - dev: false - /esbuild-plugin-alias@0.2.1: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} dev: true @@ -18709,36 +16653,6 @@ packages: optionalDependencies: source-map: 0.6.1 - /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1)(eslint@8.57.0): - resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} - engines: {node: ^10.12.0 || >=12.0.0} - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.2 - dependencies: - confusing-browser-globals: 1.0.11 - eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - object.assign: 4.1.5 - object.entries: 1.1.8 - semver: 6.3.0 - dev: true - - /eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@5.62.0)(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0): - resolution: {integrity: sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.13.0 || ^6.0.0 - '@typescript-eslint/parser': ^5.0.0 || ^6.0.0 - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - dependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@3.9.10) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - dev: true - /eslint-config-prettier@9.1.0(eslint@9.13.0): resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true @@ -18783,118 +16697,15 @@ packages: - supports-color dev: false - /eslint-friendly-formatter@4.0.1: - resolution: {integrity: sha512-+EhkPwkl/nf/fxT60yXPLAMQ+thUzfJV5rCGdUDdyM+exO3NB+07dwWiZTuyuOtTo/Ckh7W/3LJvWsB214c7ag==} - engines: {node: '>=0.10.0'} - dependencies: - chalk: 2.4.2 - coalescy: 1.0.0 - extend: 3.0.2 - minimist: 1.2.8 - strip-ansi: 4.0.0 - text-table: 0.2.0 - dev: true - /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 is-core-module: 2.13.1 resolve: 1.22.8 transitivePeerDependencies: - supports-color - - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-webpack@0.11.1)(eslint-plugin-import@2.29.1)(eslint@8.57.0): - resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - dependencies: - debug: 4.3.4 - enhanced-resolve: 5.16.1 - eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - fast-glob: 3.3.2 - get-tsconfig: 4.7.5 - is-core-module: 2.13.1 - is-glob: 4.0.3 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - dev: true - - /eslint-import-resolver-webpack@0.11.1(eslint-plugin-import@2.29.1)(webpack@5.91.0): - resolution: {integrity: sha512-eK3zR7xVQR/MaoBWwGuD+CULYVuqe5QFlDukman71aI6IboCGzggDUohHNfu1ZeBnbHcUHJc0ywWoXUBNB6qdg==} - peerDependencies: - eslint-plugin-import: '>=1.4.0' - webpack: '>=1.11.0' - dependencies: - array-find: 1.0.0 - debug: 2.6.9(supports-color@5.5.0) - enhanced-resolve: 0.9.1 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - find-root: 1.1.0 - has: 1.0.4 - interpret: 1.4.0 - lodash: 4.17.21 - node-libs-browser: 2.2.1 - resolve: 1.22.8 - semver: 5.7.2 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-loader@2.2.1(eslint@8.57.0)(webpack@5.91.0): - resolution: {integrity: sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==} - deprecated: This loader has been deprecated. Please use eslint-webpack-plugin - peerDependencies: - eslint: '>=1.6.0 <7.0.0' - webpack: '>=2.0.0 <5.0.0' - dependencies: - eslint: 8.57.0 - loader-fs-cache: 1.0.3 - loader-utils: 1.4.2 - object-assign: 4.1.1 - object-hash: 1.3.1 - rimraf: 2.7.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - dev: true - - /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0): - resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - debug: 3.2.7(supports-color@5.5.0) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-webpack@0.11.1)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-import-resolver-webpack: 0.11.1(eslint-plugin-import@2.29.1)(webpack@5.91.0) - transitivePeerDependencies: - - supports-color - dev: true + dev: false /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} @@ -18918,7 +16729,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -18940,41 +16751,6 @@ packages: string-natural-compare: 3.0.1 dev: false - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0): - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@3.9.10) - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.5 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@5.5.0) - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.11.1)(eslint@8.57.0) - hasown: 2.0.2 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.0 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} @@ -18990,7 +16766,7 @@ packages: array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -19173,6 +16949,7 @@ packages: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 + dev: false /eslint-scope@8.1.0: resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} @@ -19221,7 +16998,7 @@ packages: micromatch: 4.0.7 normalize-path: 3.0.0 schema-utils: 4.2.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /eslint@8.57.0: @@ -19269,6 +17046,7 @@ packages: text-table: 0.2.0 transitivePeerDependencies: - supports-color + dev: false /eslint@9.13.0: resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} @@ -19338,8 +17116,8 @@ packages: resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - acorn: 8.13.0 - acorn-jsx: 5.3.2(acorn@8.13.0) + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 4.1.0 dev: true @@ -19350,6 +17128,7 @@ packages: acorn: 8.11.3 acorn-jsx: 5.3.2(acorn@8.11.3) eslint-visitor-keys: 3.4.3 + dev: false /esprima@1.2.2: resolution: {integrity: sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==} @@ -19414,13 +17193,6 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - /event-dispatch@0.4.1: - resolution: {integrity: sha512-+nfoCngxvUdziP3Svtt7Iuqu3mKf0Tjoxez0V/ew4BtW2scu3tPVZF8i4Kw3SsVCH75XSWjfV0zC0MWh2GQEeA==} - dependencies: - fs: 0.0.2 - path: 0.11.14 - dev: false - /event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} dependencies: @@ -19439,26 +17211,6 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - /evp_bytestokey@1.0.3: - resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - dependencies: - md5.js: 1.3.5 - safe-buffer: 5.2.1 - dev: true - - /execa@0.7.0: - resolution: {integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==} - engines: {node: '>=4'} - dependencies: - cross-spawn: 5.1.0 - get-stream: 3.0.0 - is-stream: 1.1.0 - npm-run-path: 2.0.2 - p-finally: 1.0.0 - signal-exit: 3.0.7 - strip-eof: 1.0.0 - dev: false - /execa@5.0.0: resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==} engines: {node: '>=10'} @@ -19511,28 +17263,21 @@ packages: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} - /expand-brackets@2.1.4(supports-color@5.5.0): + /expand-brackets@2.1.4: resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} engines: {node: '>=0.10.0'} dependencies: - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 define-property: 0.2.5 extend-shallow: 2.0.1 posix-character-classes: 0.1.1 regex-not: 1.0.2 - snapdragon: 0.8.2(supports-color@5.5.0) + snapdragon: 0.8.2 to-regex: 3.0.2 transitivePeerDependencies: - supports-color dev: false - /expand-tilde@2.0.2: - resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} - engines: {node: '>=0.10.0'} - dependencies: - homedir-polyfill: 1.0.3 - dev: false - /expect@27.5.1: resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -19556,37 +17301,7 @@ packages: /exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} - - /express-basic-auth@1.2.1: - resolution: {integrity: sha512-L6YQ1wQ/mNjVLAmK3AG1RK6VkokA1BIY6wmiH304Xtt/cLTps40EusZsU1Uop+v9lTDPxdtzbFmdXfFO3KEnwA==} - dependencies: - basic-auth: 2.0.1 - dev: false - - /express-boom@3.0.0: - resolution: {integrity: sha512-/esN6Am8YE1rzRsi+vBpJkdr8O+GX+oBjRE/hEuBu6Y3uyS9y026XptRZduAMYS8KxyLzXM5Qh+RlnqLOR1pVQ==} - dependencies: - boom: 7.3.0 - dev: false - - /express-oauth-server@2.0.0: - resolution: {integrity: sha512-+UrTbvU7u3LVnoUavzO7QJgSqiEZREKprCZYrDEVoSszrO4t8f/BBPbY3hQOuuatoS0PgDFLaDKQsGNtAgPm5w==} - engines: {node: '>=0.11'} - dependencies: - bluebird: 3.7.2 - express: 4.19.2 - oauth2-server: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /express-validator@6.15.0: - resolution: {integrity: sha512-r05VYoBL3i2pswuehoFSy+uM8NBuVaY7avp5qrYjQBDzagx2Z5A77FZqPT8/gNLF3HopWkIzaTFaC4JysWXLqg==} - engines: {node: '>= 8.0.0'} - dependencies: - lodash: 4.17.21 - validator: 13.12.0 - dev: false + dev: true /express-validator@7.2.0: resolution: {integrity: sha512-I2ByKD8panjtr8Y05l21Wph9xk7kk64UMyvJCl/fFM/3CTJq8isXYPLeKW/aZBCdb/LYNv63PwhY8khw8VWocA==} @@ -19607,7 +17322,7 @@ packages: content-type: 1.0.5 cookie: 0.6.0 cookie-signature: 1.0.6 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 depd: 2.0.0 encodeurl: 1.0.2 escape-html: 1.0.3 @@ -19633,6 +17348,7 @@ packages: vary: 1.1.2 transitivePeerDependencies: - supports-color + dev: true /express@4.21.1: resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} @@ -19645,7 +17361,7 @@ packages: content-type: 1.0.5 cookie: 0.7.1 cookie-signature: 1.0.6 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 @@ -19695,6 +17411,7 @@ packages: /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true /external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} @@ -19705,17 +17422,17 @@ packages: tmp: 0.0.33 dev: true - /extglob@2.0.4(supports-color@5.5.0): + /extglob@2.0.4: resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} engines: {node: '>=0.10.0'} dependencies: array-unique: 0.3.2 define-property: 1.0.0 - expand-brackets: 2.1.4(supports-color@5.5.0) + expand-brackets: 2.1.4 extend-shallow: 2.0.1 fragment-cache: 0.2.1 regex-not: 1.0.2 - snapdragon: 0.8.2(supports-color@5.5.0) + snapdragon: 0.8.2 to-regex: 3.0.2 transitivePeerDependencies: - supports-color @@ -19726,48 +17443,13 @@ packages: hasBin: true dependencies: concat-stream: 1.6.2 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 mkdirp: 0.5.6 yauzl: 2.10.0 transitivePeerDependencies: - supports-color dev: true - /extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - dependencies: - debug: 4.3.7(supports-color@5.5.0) - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - dev: false - - /faker@4.1.0: - resolution: {integrity: sha512-ILKg69P6y/D8/wSmDXw35Ly0re8QzQ8pMfBCflsGiZG2ZjMUNLYNexA6lz5pkmJlepVdsiDFUxYAzPQ9/+iGLA==} - dev: true - - /fancy-log@1.3.3: - resolution: {integrity: sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==} - engines: {node: '>= 0.10'} - dependencies: - ansi-gray: 0.1.1 - color-support: 1.1.3 - parse-node-version: 1.0.1 - time-stamp: 1.1.0 - dev: false - - /fancy-log@2.0.0: - resolution: {integrity: sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==} - engines: {node: '>=10.13.0'} - dependencies: - color-support: 1.1.3 - dev: true - /fast-deep-equal@2.0.1: resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} dev: false @@ -19779,20 +17461,6 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true - /fast-glob@2.2.7: - resolution: {integrity: sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==} - engines: {node: '>=4.0.0'} - dependencies: - '@mrmlnc/readdir-enhanced': 2.2.1 - '@nodelib/fs.stat': 1.1.3 - glob-parent: 3.1.0 - is-glob: 4.0.3 - merge2: 1.4.1 - micromatch: 3.1.10(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - dev: false - /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -19806,10 +17474,6 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - /fast-levenshtein@1.1.4: - resolution: {integrity: sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==} - dev: false - /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -19830,7 +17494,6 @@ packages: /fast-uri@3.0.3: resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} - dev: false /fast-xml-parser@4.2.5: resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} @@ -19868,6 +17531,7 @@ packages: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} dependencies: pend: 1.2.0 + dev: true /fdir@6.4.0(picomatch@4.0.2): resolution: {integrity: sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==} @@ -19885,10 +17549,6 @@ packages: engines: {node: '>=4.0.0'} dev: false - /fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - dev: false - /fetch-retry@5.0.6: resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} dev: true @@ -19905,6 +17565,7 @@ packages: engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.2.0 + dev: false /file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} @@ -19921,7 +17582,7 @@ packages: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /file-selector@0.4.0: @@ -19943,12 +17604,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - requiresBuild: true - dev: false - optional: true - /filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} dependencies: @@ -19989,7 +17644,7 @@ packages: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} dependencies: - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 encodeurl: 1.0.2 escape-html: 1.0.3 on-finished: 2.4.1 @@ -19998,12 +17653,13 @@ packages: unpipe: 1.0.0 transitivePeerDependencies: - supports-color + dev: true /finalhandler@1.3.1: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} dependencies: - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -20013,15 +17669,6 @@ packages: transitivePeerDependencies: - supports-color - /find-cache-dir@0.1.1: - resolution: {integrity: sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==} - engines: {node: '>=0.10.0'} - dependencies: - commondir: 1.0.1 - mkdirp: 0.5.6 - pkg-dir: 1.0.0 - dev: true - /find-cache-dir@2.1.0: resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} engines: {node: '>=6'} @@ -20039,27 +17686,9 @@ packages: make-dir: 3.1.0 pkg-dir: 4.2.0 - /find-cache-dir@4.0.0: - resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} - engines: {node: '>=14.16'} - dependencies: - common-path-prefix: 3.0.0 - pkg-dir: 7.0.0 - dev: false - - /find-package-json@1.2.0: - resolution: {integrity: sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==} - dev: false - /find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} - - /find-up@1.1.2: - resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} - engines: {node: '>=0.10.0'} - dependencies: - path-exists: 2.1.0 - pinkie-promise: 2.0.1 + dev: false /find-up@2.1.0: resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} @@ -20088,54 +17717,6 @@ packages: locate-path: 6.0.0 path-exists: 4.0.0 - /find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - dev: false - - /findup-sync@2.0.0: - resolution: {integrity: sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==} - engines: {node: '>= 0.10'} - dependencies: - detect-file: 1.0.0 - is-glob: 3.1.0 - micromatch: 3.1.10(supports-color@5.5.0) - resolve-dir: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /findup-sync@3.0.0: - resolution: {integrity: sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==} - engines: {node: '>= 0.10'} - dependencies: - detect-file: 1.0.0 - is-glob: 4.0.3 - micromatch: 3.1.10(supports-color@5.5.0) - resolve-dir: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /fined@1.2.0: - resolution: {integrity: sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==} - engines: {node: '>= 0.10'} - dependencies: - expand-tilde: 2.0.2 - is-plain-object: 2.0.4 - object.defaults: 1.1.0 - object.pick: 1.3.0 - parse-filepath: 1.0.2 - dev: false - - /flagged-respawn@1.0.1: - resolution: {integrity: sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==} - engines: {node: '>= 0.10'} - dev: false - /flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -20143,6 +17724,7 @@ packages: flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 + dev: false /flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -20164,22 +17746,11 @@ packages: engines: {node: '>=0.4.0'} dev: true - /flush-write-stream@1.1.1: - resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} - dependencies: - inherits: 2.0.4 - readable-stream: 2.3.8 - dev: false - /fn-name@3.0.0: resolution: {integrity: sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA==} engines: {node: '>=8'} dev: false - /fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - dev: false - /follow-redirects@1.15.6: resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} @@ -20199,20 +17770,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /for-own@1.0.0: - resolution: {integrity: sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - dev: false - - /foreground-child@1.5.6: - resolution: {integrity: sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==} - dependencies: - cross-spawn: 4.0.2 - signal-exit: 3.0.7 - dev: true - /foreground-child@2.0.0: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} @@ -20245,7 +17802,7 @@ packages: '@babel/code-frame': 7.26.0 chalk: 2.4.2 eslint: 8.57.0 - micromatch: 3.1.10(supports-color@5.5.0) + micromatch: 3.1.10 minimatch: 3.1.2 semver: 5.7.2 tapable: 1.1.3 @@ -20285,7 +17842,7 @@ packages: semver: 7.6.3 tapable: 1.1.3 typescript: 4.9.5 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /fork-ts-checker-webpack-plugin@9.0.2(typescript@5.6.3)(webpack@5.91.0): @@ -20334,15 +17891,6 @@ packages: webpack: 5.96.1(esbuild@0.23.1) dev: true - /form-data@2.5.1: - resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} @@ -20360,15 +17908,6 @@ packages: combined-stream: 1.0.8 mime-types: 2.1.35 - /formidable@2.1.2: - resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} - dependencies: - dezalgo: 1.0.4 - hexoid: 1.0.0 - once: 1.4.0 - qs: 6.12.1 - dev: true - /formidable@3.5.2: resolution: {integrity: sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==} dependencies: @@ -20423,6 +17962,7 @@ packages: /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} @@ -20459,15 +17999,6 @@ packages: universalify: 0.1.2 dev: false - /fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: false - /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -20489,14 +18020,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: minipass: 7.1.2 - - /fs-mkdirp-stream@1.0.0: - resolution: {integrity: sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==} - engines: {node: '>= 0.10'} - dependencies: - graceful-fs: 4.2.11 - through2: 2.0.5 - dev: false + dev: true /fs-monkey@1.0.6: resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} @@ -20504,22 +18028,6 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - /fs@0.0.2: - resolution: {integrity: sha512-YAiVokMCrSIFZiroB1oz51hPiPRVcUtSa4x2U5RYXyhS9VAPdiFigKbPTnOSq7XY8wd3FIVPYmXpo5lMzFmxgg==} - dev: false - - /fsevents@1.2.13: - resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} - engines: {node: '>= 4.0'} - os: [darwin] - deprecated: Upgrade to fsevents v2 to mitigate potential security issues - requiresBuild: true - dependencies: - bindings: 1.5.0 - nan: 2.19.0 - dev: false - optional: true - /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -20546,6 +18054,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.23.3 functions-have-names: 1.2.3 + dev: false /functional-red-black-tree@1.0.1: resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} @@ -20606,18 +18115,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - /get-caller-file@1.0.3: - resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} - dev: false - /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - /get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - dev: true - /get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -20657,27 +18158,10 @@ packages: yargs: 16.2.0 dev: true - /get-port@3.2.0: - resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} - engines: {node: '>=4'} - dev: false - /get-port@5.1.1: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} engines: {node: '>=8'} - /get-stream@3.0.0: - resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} - engines: {node: '>=4'} - dev: false - - /get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - dependencies: - pump: 3.0.0 - dev: false - /get-stream@6.0.0: resolution: {integrity: sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==} engines: {node: '>=10'} @@ -20699,24 +18183,16 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - - /get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} - dependencies: - resolve-pkg-maps: 1.0.0 - dev: true + dev: false /get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} dev: false - /getopts@2.2.5: - resolution: {integrity: sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==} - dev: false - /getopts@2.3.0: resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==} + dev: false /giget@1.2.3: resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} @@ -20794,13 +18270,6 @@ packages: resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} dev: true - /glob-parent@3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - dev: false - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -20823,55 +18292,9 @@ packages: glob: 7.2.3 dev: true - /glob-stream@6.1.0: - resolution: {integrity: sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==} - engines: {node: '>= 0.10'} - dependencies: - extend: 3.0.2 - glob: 7.2.3 - glob-parent: 3.1.0 - is-negated-glob: 1.0.0 - ordered-read-streams: 1.0.1 - pumpify: 1.5.1 - readable-stream: 2.3.8 - remove-trailing-separator: 1.1.0 - to-absolute-glob: 2.0.2 - unique-stream: 2.3.1 - dev: false - - /glob-to-regexp@0.3.0: - resolution: {integrity: sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==} - dev: false - /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - /glob-watcher@5.0.5: - resolution: {integrity: sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==} - engines: {node: '>= 0.10'} - dependencies: - anymatch: 2.0.0(supports-color@5.5.0) - async-done: 1.3.2 - chokidar: 2.1.8(supports-color@5.5.0) - is-negated-glob: 1.0.0 - just-debounce: 1.1.0 - normalize-path: 3.0.0 - object.defaults: 1.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /glob@10.4.1: - resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} - engines: {node: '>=16 || 14 >=14.18'} - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 3.1.2 - minimatch: 9.0.4 - minipass: 7.1.2 - path-scurry: 1.11.1 - /glob@10.4.2: resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} engines: {node: '>=16 || 14 >=14.18'} @@ -20883,21 +18306,10 @@ packages: minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - dev: true - - /glob@7.1.2: - resolution: {integrity: sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -20932,15 +18344,7 @@ packages: engines: {node: '>=4'} dependencies: ini: 1.3.8 - - /global-modules@1.0.0: - resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} - engines: {node: '>=0.10.0'} - dependencies: - global-prefix: 1.0.2 - is-windows: 1.0.2 - resolve-dir: 1.0.1 - dev: false + dev: true /global-modules@2.0.0: resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} @@ -20949,17 +18353,6 @@ packages: global-prefix: 3.0.0 dev: false - /global-prefix@1.0.2: - resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} - engines: {node: '>=0.10.0'} - dependencies: - expand-tilde: 2.0.2 - homedir-polyfill: 1.0.3 - ini: 1.3.8 - is-windows: 1.0.2 - which: 1.3.1 - dev: false - /global-prefix@3.0.0: resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} engines: {node: '>=6'} @@ -20978,6 +18371,7 @@ packages: engines: {node: '>=8'} dependencies: type-fest: 0.20.2 + dev: false /globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} @@ -20995,6 +18389,7 @@ packages: dependencies: define-properties: 1.2.1 gopd: 1.0.1 + dev: false /globby@11.0.1: resolution: {integrity: sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==} @@ -21019,149 +18414,21 @@ packages: merge2: 1.4.1 slash: 3.0.0 - /globby@9.2.0: - resolution: {integrity: sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==} - engines: {node: '>=6'} - dependencies: - '@types/glob': 7.2.0 - array-union: 1.0.2 - dir-glob: 2.2.2 - fast-glob: 2.2.7 - glob: 7.2.3 - ignore: 4.0.6 - pify: 4.0.1 - slash: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /glogg@1.0.2: - resolution: {integrity: sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==} - engines: {node: '>= 0.10'} - dependencies: - sparkles: 1.0.1 - dev: false - /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.4 - /got@6.7.1: - resolution: {integrity: sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==} - engines: {node: '>=4'} - dependencies: - '@types/keyv': 3.1.4 - '@types/responselike': 1.0.3 - create-error-class: 3.0.2 - duplexer3: 0.1.5 - get-stream: 3.0.0 - is-redirect: 1.0.0 - is-retry-allowed: 1.2.0 - is-stream: 1.1.0 - lowercase-keys: 1.0.1 - safe-buffer: 5.2.1 - timed-out: 4.0.1 - unzip-response: 2.0.1 - url-parse-lax: 1.0.0 - dev: false - /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - /growl@1.10.5: - resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} - engines: {node: '>=4.x'} - dev: true - /gud@1.0.0: resolution: {integrity: sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==} dev: false - /gulp-cli@2.3.0: - resolution: {integrity: sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==} - engines: {node: '>= 0.10'} - hasBin: true - dependencies: - ansi-colors: 1.1.0 - archy: 1.0.0 - array-sort: 1.0.0 - color-support: 1.1.3 - concat-stream: 1.6.2 - copy-props: 2.0.5 - fancy-log: 1.3.3 - gulplog: 1.0.0 - interpret: 1.4.0 - isobject: 3.0.1 - liftoff: 3.1.0 - matchdep: 2.0.0 - mute-stdout: 1.0.1 - pretty-hrtime: 1.0.3 - replace-homedir: 1.0.0 - semver-greatest-satisfied-range: 1.1.0 - v8flags: 3.2.0 - yargs: 7.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /gulp-postcss@9.1.0(postcss@8.4.47): - resolution: {integrity: sha512-a843mcKPApfeI987uqQbc8l50xXeWIXBsiVvYxtCI5XtVAMzTi/HnU2qzQpGwkB/PAOfsLV8OsqDv2iJZ9qvdw==} - engines: {node: '>=18'} - deprecated: Republished as 10.0.0 to follow the semver spec - peerDependencies: - postcss: ^8.0.0 - dependencies: - fancy-log: 2.0.0 - plugin-error: 2.0.1 - postcss: 8.4.47 - postcss-load-config: 5.1.0(postcss@8.4.47) - vinyl-sourcemaps-apply: 0.2.1 - transitivePeerDependencies: - - jiti - - tsx - dev: true - - /gulp-rename@2.0.0: - resolution: {integrity: sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==} - engines: {node: '>=4'} - dev: true - - /gulp-sass@5.1.0: - resolution: {integrity: sha512-7VT0uaF+VZCmkNBglfe1b34bxn/AfcssquLKVDYnCDJ3xNBaW7cUuI3p3BQmoKcoKFrs9jdzUxyb+u+NGfL4OQ==} - engines: {node: '>=12'} - dependencies: - lodash.clonedeep: 4.5.0 - picocolors: 1.0.1 - plugin-error: 1.0.1 - replace-ext: 2.0.0 - strip-ansi: 6.0.1 - vinyl-sourcemaps-apply: 0.2.1 - dev: false - - /gulp@4.0.2: - resolution: {integrity: sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==} - engines: {node: '>= 0.10'} - hasBin: true - dependencies: - glob-watcher: 5.0.5 - gulp-cli: 2.3.0 - undertaker: 1.3.0 - vinyl-fs: 3.0.3 - transitivePeerDependencies: - - supports-color - dev: false - - /gulplog@1.0.0: - resolution: {integrity: sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==} - engines: {node: '>= 0.10'} - dependencies: - glogg: 1.0.2 - dev: false - /gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} hasBin: true @@ -21209,6 +18476,7 @@ packages: /hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} + dev: true /harmony-reflect@1.6.2: resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} @@ -21225,13 +18493,6 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - /has-glob@1.0.0: - resolution: {integrity: sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g==} - engines: {node: '>=0.10.0'} - dependencies: - is-glob: 3.1.0 - dev: false - /has-own-prop@2.0.0: resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} engines: {node: '>=8'} @@ -21290,52 +18551,12 @@ packages: kind-of: 4.0.0 dev: false - /has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} - dev: true - - /hash-base@3.0.4: - resolution: {integrity: sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==} - engines: {node: '>=4'} - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - - /hash-base@3.1.0: - resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} - engines: {node: '>=4'} - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - safe-buffer: 5.2.1 - dev: true - - /hash.js@1.1.7: - resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - - /hasha@3.0.0: - resolution: {integrity: sha512-w0Kz8lJFBoyaurBiNrIvxPqr/gJ6fOfSkpAPOepN3oECqGJag37xPbOv57izi/KP8auHgNYxn5fXtAb+1LsJ6w==} - engines: {node: '>=4'} - dependencies: - is-stream: 1.1.0 - dev: true - /hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 - /he@1.1.1: - resolution: {integrity: sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==} - hasBin: true - dev: true - /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true @@ -21380,11 +18601,6 @@ packages: x-xss-protection: 1.3.0 dev: false - /hexoid@1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} - dev: true - /hexoid@2.0.0: resolution: {integrity: sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==} engines: {node: '>=8'} @@ -21406,32 +18622,12 @@ packages: value-equal: 1.0.1 dev: false - /hmac-drbg@1.0.1: - resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - dependencies: - hash.js: 1.1.7 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - dev: true - - /hoek@6.1.3: - resolution: {integrity: sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==} - deprecated: This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues. - dev: false - /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: react-is: 16.13.1 dev: false - /homedir-polyfill@1.0.3: - resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} - engines: {node: '>=0.10.0'} - dependencies: - parse-passwd: 1.0.0 - dev: false - /hoopy@0.1.4: resolution: {integrity: sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==} engines: {node: '>= 6.0.0'} @@ -21439,6 +18635,7 @@ packages: /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true /hosted-git-info@3.0.8: resolution: {integrity: sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==} @@ -21568,7 +18765,7 @@ packages: lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /htmlparser2@6.1.0: @@ -21589,18 +18786,9 @@ packages: entities: 4.5.0 dev: false - /http-basic@8.1.3: - resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} - engines: {node: '>=6.0.0'} - dependencies: - caseless: 0.12.0 - concat-stream: 1.6.2 - http-response-object: 3.0.2 - parse-cache-control: 1.0.1 - dev: false - /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: true /http-deceiver@1.2.7: resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} @@ -21616,17 +18804,6 @@ packages: statuses: 1.5.0 dev: false - /http-errors@1.7.3: - resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} - engines: {node: '>= 0.6'} - dependencies: - depd: 1.1.2 - inherits: 2.0.4 - setprototypeof: 1.1.1 - statuses: 1.5.0 - toidentifier: 1.0.0 - dev: false - /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -21671,6 +18848,7 @@ packages: debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color + dev: true /http-proxy-middleware@1.3.1: resolution: {integrity: sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==} @@ -21715,16 +18893,6 @@ packages: - debug dev: false - /http-response-object@3.0.2: - resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} - dependencies: - '@types/node': 10.17.60 - dev: false - - /https-browserify@1.0.0: - resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} - dev: true - /https-proxy-agent@4.0.0: resolution: {integrity: sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==} engines: {node: '>= 6.0.0'} @@ -21735,16 +18903,6 @@ packages: - supports-color dev: true - /https-proxy-agent@5.0.0: - resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.7(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - dev: false - /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -21762,12 +18920,7 @@ packages: debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color - - /human-interval@2.0.1: - resolution: {integrity: sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==} - dependencies: - numbered: 1.1.0 - dev: false + dev: true /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} @@ -21794,33 +18947,12 @@ packages: resolution: {integrity: sha512-fedL7PRwmeVkgyhu9hLeTBaI6wcGk7JGJswdaRsa5aUbkXI1kr1xZwTPBtaYPpwf56878iDek6VbVnuWMebJmw==} dev: false - /i18n@0.13.4: - resolution: {integrity: sha512-GZnXWeA15jTi9gc1jfgrJcSrNYDg7qbJXSYMuibqPYb1ThORmGCeM+gL6LrDagYRHh87/q/D0jRSOhAfv6wAow==} - engines: {node: '>=0.10.0'} - dependencies: - debug: 4.3.4 - make-plural: 7.4.0 - math-interval-parser: 2.0.1 - messageformat: 2.3.0 - mustache: 4.2.0 - sprintf-js: 1.1.3 - transitivePeerDependencies: - - supports-color - dev: false - /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - /iconv-lite@0.5.2: - resolution: {integrity: sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: false - /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -21849,10 +18981,6 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - /ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - dev: false - /ignore-walk@5.0.1: resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -21867,11 +18995,6 @@ packages: minimatch: 9.0.4 dev: true - /ignore@4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - dev: false - /ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -21893,6 +19016,7 @@ packages: /immutable@4.3.6: resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} + dev: false /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -21906,20 +19030,6 @@ packages: engines: {node: '>=12.2'} dev: true - /import-in-the-middle@1.7.4: - resolution: {integrity: sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==} - dependencies: - acorn: 8.14.0 - acorn-import-attributes: 1.9.5(acorn@8.14.0) - cjs-module-lexer: 1.3.1 - module-details-from-path: 1.0.3 - dev: false - - /import-lazy@2.1.0: - resolution: {integrity: sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==} - engines: {node: '>=4'} - dev: false - /import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} @@ -21940,6 +19050,7 @@ packages: /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + dev: true /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} @@ -21950,6 +19061,7 @@ packages: /inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: false /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -22027,13 +19139,10 @@ packages: hasown: 2.0.2 side-channel: 1.0.6 - /interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - /interpret@2.2.0: resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} engines: {node: '>= 0.10'} + dev: false /interpret@3.1.1: resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} @@ -22062,11 +19171,6 @@ packages: dependencies: loose-envify: 1.4.0 - /invert-kv@1.0.0: - resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} - engines: {node: '>=0.10.0'} - dev: false - /ioredis@4.29.1: resolution: {integrity: sha512-iq4u3AC9h9/P/gBXH1cUR7Ln0exKexqMaYDwUaoZJzkvvgJs9W5+CLQFS0APyG8uyvJJjn6q6Vx7LwmZQu3h5A==} engines: {node: '>=6'} @@ -22109,10 +19213,6 @@ packages: dependencies: jsbn: 1.1.0 sprintf-js: 1.1.3 - - /ip-regex@2.1.0: - resolution: {integrity: sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==} - engines: {node: '>=4'} dev: true /ip@2.0.1: @@ -22133,14 +19233,6 @@ packages: engines: {node: '>=8'} dev: true - /is-absolute@1.0.0: - resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} - engines: {node: '>=0.10.0'} - dependencies: - is-relative: 1.0.0 - is-windows: 1.0.2 - dev: false - /is-accessor-descriptor@1.0.1: resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} engines: {node: '>= 0.10'} @@ -22165,10 +19257,6 @@ packages: /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - /is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - dev: false - /is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -22181,13 +19269,6 @@ packages: dependencies: has-bigints: 1.0.2 - /is-binary-path@1.0.1: - resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} - engines: {node: '>=0.10.0'} - dependencies: - binary-extensions: 1.13.1 - dev: false - /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -22209,13 +19290,6 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - /is-ci@1.2.1: - resolution: {integrity: sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==} - hasBin: true - dependencies: - ci-info: 1.6.0 - dev: false - /is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true @@ -22240,6 +19314,7 @@ packages: engines: {node: '>= 0.4'} dependencies: is-typed-array: 1.1.13 + dev: false /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -22301,17 +19376,6 @@ packages: call-bind: 1.0.7 dev: false - /is-fullwidth-code-point@1.0.0: - resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} - engines: {node: '>=0.10.0'} - dependencies: - number-is-nan: 1.0.1 - dev: false - - /is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -22326,17 +19390,6 @@ packages: dependencies: has-tostringtag: 1.0.2 - /is-generator@1.0.3: - resolution: {integrity: sha512-G56jBpbJeg7ds83HW1LuShNs8J73Fv3CPz/bmROHOHlnKkN8sWb9ujiagjmxxMUywftgq48HlBZELKKqFLk0oA==} - dev: false - - /is-glob@3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: false - /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -22348,33 +19401,14 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-installed-globally@0.1.0: - resolution: {integrity: sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw==} - engines: {node: '>=4'} - dependencies: - global-dirs: 0.1.1 - is-path-inside: 1.0.1 - dev: false - /is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} dev: true - /is-invalid-path@1.0.2: - resolution: {integrity: sha512-6KLcFrPCEP3AFXMfnWrIFkZpYNBVzZAoBJJDEZKtI3LXkaDjM3uFMJQjxiizUuZTZ9Oh9FNv/soXbx5TcpaDmA==} - engines: {node: '>=6.0'} - dev: false - - /is-ip@2.0.0: - resolution: {integrity: sha512-9MTn0dteHETtyUx8pxqMwg5hMBi3pvlyglJ+b79KOCca0po23337LbVV2Hl4xmMvfw++ljnO0/+5G6G+0Szh6g==} - engines: {node: '>=4'} - dependencies: - ip-regex: 2.1.0 - dev: true - /is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + dev: true /is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} @@ -22398,26 +19432,9 @@ packages: xtend: 4.0.2 dev: false - /is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - dev: false - - /is-negated-glob@1.0.0: - resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==} - engines: {node: '>=0.10.0'} - dev: false - /is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - - /is-npm@1.0.0: - resolution: {integrity: sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==} - engines: {node: '>=0.10.0'} dev: false /is-number-object@1.0.7: @@ -22433,11 +19450,6 @@ packages: kind-of: 3.2.2 dev: false - /is-number@4.0.0: - resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} - engines: {node: '>=0.10.0'} - dev: false - /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -22457,13 +19469,6 @@ packages: engines: {node: '>=6'} dev: true - /is-path-inside@1.0.1: - resolution: {integrity: sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==} - engines: {node: '>=0.10.0'} - dependencies: - path-is-inside: 1.0.2 - dev: false - /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -22471,6 +19476,7 @@ packages: /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} + dev: true /is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} @@ -22491,6 +19497,7 @@ packages: /is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} + dev: true /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -22504,11 +19511,6 @@ packages: resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} dev: false - /is-redirect@1.0.0: - resolution: {integrity: sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==} - engines: {node: '>=0.10.0'} - dev: false - /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -22521,18 +19523,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /is-relative@1.0.0: - resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} - engines: {node: '>=0.10.0'} - dependencies: - is-unc-path: 1.0.0 - dev: false - - /is-retry-allowed@1.2.0: - resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} - engines: {node: '>=0.10.0'} - dev: false - /is-root@2.1.0: resolution: {integrity: sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==} engines: {node: '>=6'} @@ -22554,10 +19544,6 @@ packages: protocols: 2.0.1 dev: true - /is-stream@1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - /is-stream@2.0.0: resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} engines: {node: '>=8'} @@ -22600,27 +19586,11 @@ packages: /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - /is-unc-path@1.0.0: - resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} - engines: {node: '>=0.10.0'} - dependencies: - unc-path-regex: 0.1.2 - dev: false - /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} dev: true - /is-utf8@0.2.1: - resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} - dev: false - - /is-valid-glob@1.0.0: - resolution: {integrity: sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==} - engines: {node: '>=0.10.0'} - dev: false - /is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -22629,6 +19599,7 @@ packages: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.7 + dev: false /is-weakset@2.0.3: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} @@ -22653,6 +19624,7 @@ packages: /isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: false /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -22666,6 +19638,7 @@ packages: /isexe@3.1.1: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + dev: true /isobject@2.1.0: resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} @@ -22678,37 +19651,10 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} - /istanbul-lib-coverage@2.0.5: - resolution: {integrity: sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==} - engines: {node: '>=6'} - dev: true - /istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} - /istanbul-lib-hook@2.0.7: - resolution: {integrity: sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==} - engines: {node: '>=6'} - dependencies: - append-transform: 1.0.0 - dev: true - - /istanbul-lib-instrument@3.3.0: - resolution: {integrity: sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==} - engines: {node: '>=6'} - dependencies: - '@babel/generator': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5(supports-color@5.5.0) - '@babel/types': 7.24.5 - istanbul-lib-coverage: 2.0.5 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - /istanbul-lib-instrument@5.2.1: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} @@ -22734,15 +19680,6 @@ packages: - supports-color dev: true - /istanbul-lib-report@2.0.8: - resolution: {integrity: sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==} - engines: {node: '>=6'} - dependencies: - istanbul-lib-coverage: 2.0.5 - make-dir: 2.1.0 - supports-color: 6.1.0 - dev: true - /istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} @@ -22751,19 +19688,6 @@ packages: make-dir: 4.0.0 supports-color: 7.2.0 - /istanbul-lib-source-maps@3.0.6: - resolution: {integrity: sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==} - engines: {node: '>=6'} - dependencies: - debug: 4.3.7(supports-color@5.5.0) - istanbul-lib-coverage: 2.0.5 - make-dir: 2.1.0 - rimraf: 2.7.1 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - /istanbul-lib-source-maps@4.0.1: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} @@ -22774,13 +19698,6 @@ packages: transitivePeerDependencies: - supports-color - /istanbul-reports@2.2.7: - resolution: {integrity: sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==} - engines: {node: '>=6'} - dependencies: - html-escaper: 2.0.2 - dev: true - /istanbul-reports@3.1.7: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} @@ -23800,7 +20717,7 @@ packages: dependencies: config-chain: 1.1.13 editorconfig: 1.0.4 - glob: 10.4.1 + glob: 10.4.2 js-cookie: 3.0.5 nopt: 7.2.1 dev: false @@ -23846,6 +20763,7 @@ packages: /jsbn@1.1.0: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + dev: true /jscodeshift@0.14.0(@babel/preset-env@7.24.5): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} @@ -23927,18 +20845,13 @@ packages: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true + dev: false /jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} hasBin: true - /json-bigint@1.0.0: - resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} - dependencies: - bignumber.js: 9.1.2 - dev: false - /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -23969,12 +20882,14 @@ packages: /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true /json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true dependencies: minimist: 1.2.8 + dev: false /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} @@ -24024,26 +20939,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /jsonschema@1.4.1: - resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==} - dev: false - - /jsonwebtoken@8.5.1: - resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} - engines: {node: '>=4', npm: '>=1.4.28'} - dependencies: - jws: 3.2.2 - lodash.includes: 4.3.0 - lodash.isboolean: 3.0.3 - lodash.isinteger: 4.0.4 - lodash.isnumber: 3.0.3 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.once: 4.1.1 - ms: 2.1.3 - semver: 5.7.2 - dev: false - /jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} @@ -24057,7 +20952,7 @@ packages: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.6.2 + semver: 7.6.3 dev: false /jstransformer@1.0.0: @@ -24077,19 +20972,6 @@ packages: object.values: 1.2.0 dev: false - /junk@3.1.0: - resolution: {integrity: sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==} - engines: {node: '>=8'} - dev: false - - /just-debounce@1.1.0: - resolution: {integrity: sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==} - dev: false - - /just-extend@4.2.1: - resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} - dev: true - /jwa@1.4.1: resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} dependencies: @@ -24105,10 +20987,6 @@ packages: safe-buffer: 5.2.1 dev: false - /kareem@2.3.2: - resolution: {integrity: sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==} - dev: false - /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -24134,11 +21012,6 @@ packages: is-buffer: 1.1.6 dev: false - /kind-of@5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: false - /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -24152,111 +21025,6 @@ packages: engines: {node: '>= 8'} dev: false - /knex-cleaner@1.3.1: - resolution: {integrity: sha512-/cXEtcI3VNQ+hAaO5SNzGxDnnxAVN3BJDPdvuttMWL3jlQqaUHHoOfI2y5PKsSxfhZQau3Ryg00wDen+FajioQ==} - dependencies: - bluebird: 2.11.0 - lodash: 4.17.21 - dev: false - - /knex-factory@0.0.6: - resolution: {integrity: sha512-K8VAu9E1IZzmJ1XEuH1sGm9SP4vqQgRsE4yRfs7bSMVuVyI8yqbiv3I1J+HvtA//c6yp6EYikSpvtKfR0mi/Og==} - dependencies: - lodash: 4.17.21 - dev: true - - /knex@0.95.15(mysql2@1.7.0)(mysql@2.18.1): - resolution: {integrity: sha512-Loq6WgHaWlmL2bfZGWPsy4l8xw4pOE+tmLGkPG0auBppxpI0UcK+GYCycJcqz9W54f2LiGewkCVLBm3Wq4ur/w==} - engines: {node: '>=10'} - hasBin: true - peerDependencies: - mysql: '*' - mysql2: '*' - pg: '*' - pg-native: '*' - sqlite3: '*' - tedious: '*' - peerDependenciesMeta: - mysql: - optional: true - mysql2: - optional: true - pg: - optional: true - pg-native: - optional: true - sqlite3: - optional: true - tedious: - optional: true - dependencies: - colorette: 2.0.16 - commander: 7.2.0 - debug: 4.3.2 - escalade: 3.1.2 - esm: 3.2.25 - getopts: 2.2.5 - interpret: 2.2.0 - lodash: 4.17.21 - mysql: 2.18.1 - mysql2: 1.7.0 - pg-connection-string: 2.5.0 - rechoir: 0.7.0 - resolve-from: 5.0.0 - tarn: 3.0.2 - tildify: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /knex@3.1.0(mysql2@1.7.0)(mysql@2.18.1): - resolution: {integrity: sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==} - engines: {node: '>=16'} - hasBin: true - peerDependencies: - better-sqlite3: '*' - mysql: '*' - mysql2: '*' - pg: '*' - pg-native: '*' - sqlite3: '*' - tedious: '*' - peerDependenciesMeta: - better-sqlite3: - optional: true - mysql: - optional: true - mysql2: - optional: true - pg: - optional: true - pg-native: - optional: true - sqlite3: - optional: true - tedious: - optional: true - dependencies: - colorette: 2.0.19 - commander: 10.0.1 - debug: 4.3.4 - escalade: 3.2.0 - esm: 3.2.25 - get-package-type: 0.1.0 - getopts: 2.3.0 - interpret: 2.2.0 - lodash: 4.17.21 - mysql: 2.18.1 - mysql2: 1.7.0 - pg-connection-string: 2.6.2 - rechoir: 0.8.0 - resolve-from: 5.0.0 - tarn: 3.0.2 - tildify: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: false - /knex@3.1.0(mysql2@3.11.4)(mysql@2.18.1): resolution: {integrity: sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==} engines: {node: '>=16'} @@ -24309,10 +21077,6 @@ packages: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} dev: false - /kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - dev: false - /lamda@0.4.1: resolution: {integrity: sha512-0ITucytoxEWajbJAECVk12/yQ5NvpZg5RO50fSbXZ7/5eOcnNDTZ08jDp9OQk40M8flCN70MAmy1/nQ+9teOEA==} dev: false @@ -24328,21 +21092,6 @@ packages: language-subtag-registry: 0.3.23 dev: false - /last-run@1.1.1: - resolution: {integrity: sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==} - engines: {node: '>= 0.10'} - dependencies: - default-resolution: 2.0.0 - es6-weak-map: 2.0.3 - dev: false - - /latest-version@3.1.0: - resolution: {integrity: sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==} - engines: {node: '>=4'} - dependencies: - package-json: 4.0.1 - dev: false - /launch-editor@2.6.1: resolution: {integrity: sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==} dependencies: @@ -24355,35 +21104,14 @@ packages: engines: {node: '>=14.0.0'} dependencies: app-root-dir: 1.0.2 - dotenv: 16.3.2 + dotenv: 16.4.5 dotenv-expand: 10.0.0 dev: true - /lazystream@1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} - dependencies: - readable-stream: 2.3.8 - dev: false - - /lcid@1.0.0: - resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} - engines: {node: '>=0.10.0'} - dependencies: - invert-kv: 1.0.0 - dev: false - /leac@0.6.0: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} dev: false - /lead@1.0.0: - resolution: {integrity: sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==} - engines: {node: '>= 0.10'} - dependencies: - flush-write-stream: 1.1.1 - dev: false - /lerna@8.1.3: resolution: {integrity: sha512-Dg/r1dGnRCXKsOUC3lol7o6ggYTA6WWiPQzZJNKqyygn4fzYGuA3Dro2d5677pajaqFnFA72mdCjzSyF16Vi2Q==} engines: {node: '>=18.0.0'} @@ -24559,22 +21287,6 @@ packages: /libphonenumber-js@1.11.1: resolution: {integrity: sha512-Wze1LPwcnzvcKGcRHFGFECTaLzxOtujwpf924difr5zniyYv1C2PiW0419qDR7m8lKDxsImu5mwxFuXhXpjmvw==} - /liftoff@3.1.0: - resolution: {integrity: sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==} - engines: {node: '>= 0.8'} - dependencies: - extend: 3.0.2 - findup-sync: 3.0.0 - fined: 1.2.0 - flagged-respawn: 1.0.1 - is-plain-object: 2.0.4 - object.map: 1.0.1 - rechoir: 0.6.2 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - dev: false - /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -24583,6 +21295,7 @@ packages: /lilconfig@3.1.1: resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} engines: {node: '>=14'} + dev: false /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -24598,17 +21311,6 @@ packages: uc.micro: 2.1.0 dev: false - /load-json-file@1.1.0: - resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} - engines: {node: '>=0.10.0'} - dependencies: - graceful-fs: 4.2.11 - parse-json: 2.2.0 - pify: 2.3.0 - pinkie-promise: 2.0.1 - strip-bom: 2.0.0 - dev: false - /load-json-file@4.0.0: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} @@ -24634,13 +21336,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false - /loader-fs-cache@1.0.3: - resolution: {integrity: sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==} - dependencies: - find-cache-dir: 0.1.1 - mkdirp: 0.5.6 - dev: true - /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -24652,6 +21347,7 @@ packages: big.js: 5.2.2 emojis-list: 3.0.0 json5: 1.0.2 + dev: false /loader-utils@2.0.0: resolution: {integrity: sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==} @@ -24710,31 +21406,13 @@ packages: dependencies: p-locate: 5.0.0 - /locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-locate: 6.0.0 - dev: false - /lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} dev: false /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - - /lodash.castarray@4.4.0: - resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} - dev: false - - /lodash.clonedeep@4.5.0: - resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} - dev: false - - /lodash.compact@3.0.1: - resolution: {integrity: sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ==} - dev: false + dev: true /lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -24747,10 +21425,6 @@ packages: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: false - /lodash.flattendeep@4.4.0: - resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} - dev: true - /lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} dev: false @@ -24838,10 +21512,6 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - /lodash@4.17.4: - resolution: {integrity: sha512-6X37Sq9KCpLSXEh8uM12AKYlviHPNNk4RxiGBn4cmKGJinbXBneWIV7iE/nXkM928O7ytHcHb6+X6Svl0f4hXg==} - dev: false - /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -24850,45 +21520,6 @@ packages: is-unicode-supported: 0.1.0 dev: true - /log4js@6.9.1: - resolution: {integrity: sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==} - engines: {node: '>=8.0'} - dependencies: - date-format: 4.0.14 - debug: 4.3.7(supports-color@5.5.0) - flatted: 3.3.1 - rfdc: 1.3.1 - streamroller: 3.1.5 - transitivePeerDependencies: - - supports-color - dev: false - - /logform@2.6.0: - resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==} - engines: {node: '>= 12.0.0'} - dependencies: - '@colors/colors': 1.6.0 - '@types/triple-beam': 1.3.5 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.4.3 - triple-beam: 1.4.1 - dev: false - - /lolex@4.2.0: - resolution: {integrity: sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==} - dev: true - - /lolex@5.1.2: - resolution: {integrity: sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==} - dependencies: - '@sinonjs/commons': 1.8.6 - dev: true - - /long@4.0.0: - resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - dev: false - /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} dev: false @@ -24899,12 +21530,6 @@ packages: dependencies: js-tokens: 4.0.0 - /loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - dependencies: - get-func-name: 2.0.2 - dev: true - /loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} dev: false @@ -24915,21 +21540,10 @@ packages: tslib: 2.8.0 dev: false - /lowercase-keys@1.0.1: - resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} - engines: {node: '>=0.10.0'} - dev: false - /lru-cache@10.2.2: resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} engines: {node: 14 || >=16.14} - /lru-cache@4.1.5: - resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} - dependencies: - pseudomap: 1.0.2 - yallist: 2.1.2 - /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -24950,10 +21564,6 @@ packages: engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} dev: false - /luxon@1.28.1: - resolution: {integrity: sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==} - dev: false - /luxon@3.5.0: resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} engines: {node: '>=12'} @@ -24988,13 +21598,6 @@ packages: '@jridgewell/sourcemap-codec': 1.5.0 dev: true - /make-dir@1.3.0: - resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: false - /make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -25058,24 +21661,7 @@ packages: ssri: 10.0.6 transitivePeerDependencies: - supports-color - - /make-iterator@1.0.1: - resolution: {integrity: sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: false - - /make-plural@4.3.0: - resolution: {integrity: sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==} - hasBin: true - optionalDependencies: - minimist: 1.2.8 - dev: false - - /make-plural@7.4.0: - resolution: {integrity: sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==} - dev: false + dev: true /makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -25090,10 +21676,12 @@ packages: /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} + dev: true /map-obj@4.3.0: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} + dev: true /map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} @@ -25147,23 +21735,6 @@ packages: remove-accents: 0.5.0 dev: false - /matchdep@2.0.0: - resolution: {integrity: sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==} - engines: {node: '>= 0.10.0'} - dependencies: - findup-sync: 2.0.0 - micromatch: 3.1.10(supports-color@5.5.0) - resolve: 1.22.8 - stack-trace: 0.0.10 - transitivePeerDependencies: - - supports-color - dev: false - - /math-interval-parser@2.0.1: - resolution: {integrity: sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==} - engines: {node: '>=0.10.0'} - dev: false - /mathjs@9.5.2: resolution: {integrity: sha512-c0erTq0GP503/Ch2OtDOAn50GIOsuxTMjmE00NI/vKJFSWrDaQHRjx6ai+16xYv70yBSnnpUgHZGNf9FR9IwmA==} engines: {node: '>= 12'} @@ -25189,14 +21760,6 @@ packages: react: 18.3.1 dev: false - /md5.js@1.3.5: - resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} - dependencies: - hash-base: 3.1.0 - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - /mdast-util-definitions@4.0.0: resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==} dependencies: @@ -25239,41 +21802,6 @@ packages: map-or-similar: 1.5.0 dev: true - /memory-cache@0.2.0: - resolution: {integrity: sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==} - dev: false - - /memory-fs@0.2.0: - resolution: {integrity: sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng==} - dev: true - - /memory-pager@1.5.0: - resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} - requiresBuild: true - dev: false - - /memorystream@0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} - dev: true - - /meow@6.1.1: - resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} - engines: {node: '>=8'} - dependencies: - '@types/minimist': 1.2.5 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 2.5.0 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.13.1 - yargs-parser: 18.1.3 - dev: false - /meow@8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} @@ -25293,16 +21821,11 @@ packages: /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true /merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - /merge-source-map@1.1.0: - resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==} - dependencies: - source-map: 0.6.1 - dev: true - /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -25310,23 +21833,6 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - /messageformat-formatters@2.0.1: - resolution: {integrity: sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==} - dev: false - - /messageformat-parser@4.1.3: - resolution: {integrity: sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==} - dev: false - - /messageformat@2.3.0: - resolution: {integrity: sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==} - deprecated: Package renamed as '@messageformat/core', see messageformat.github.io for more details. 'messageformat@4' will eventually provide a polyfill for Intl.MessageFormat, once it's been defined by Unicode & ECMA. - dependencies: - make-plural: 4.3.0 - messageformat-formatters: 2.0.1 - messageformat-parser: 4.1.3 - dev: false - /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -25335,22 +21841,22 @@ packages: resolution: {integrity: sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==} dev: false - /micromatch@3.1.10(supports-color@5.5.0): + /micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} engines: {node: '>=0.10.0'} dependencies: arr-diff: 4.0.0 array-unique: 0.3.2 - braces: 2.3.2(supports-color@5.5.0) + braces: 2.3.2 define-property: 2.0.2 extend-shallow: 3.0.2 - extglob: 2.0.4(supports-color@5.5.0) + extglob: 2.0.4 fragment-cache: 0.2.1 kind-of: 6.0.3 - nanomatch: 1.2.13(supports-color@5.5.0) + nanomatch: 1.2.13 object.pick: 1.3.0 regex-not: 1.0.2 - snapdragon: 0.8.2(supports-color@5.5.0) + snapdragon: 0.8.2 to-regex: 3.0.2 transitivePeerDependencies: - supports-color @@ -25367,14 +21873,6 @@ packages: resolution: {integrity: sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==} dev: false - /miller-rabin@4.0.1: - resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} - hasBin: true - dependencies: - bn.js: 4.12.0 - brorand: 1.1.0 - dev: true - /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -25408,6 +21906,7 @@ packages: /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + dev: true /mini-css-extract-plugin@2.9.0(webpack@5.91.0): resolution: {integrity: sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==} @@ -25417,20 +21916,18 @@ packages: dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - - /minimalistic-crypto-utils@1.0.1: - resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - dev: true + dev: false /minimatch@3.0.4: resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} dependencies: brace-expansion: 1.1.11 + dev: false /minimatch@3.0.5: resolution: {integrity: sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==} @@ -25482,9 +21979,6 @@ packages: arrify: 1.0.1 is-plain-obj: 1.1.0 kind-of: 6.0.3 - - /minimist@0.0.8: - resolution: {integrity: sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==} dev: true /minimist@1.2.8: @@ -25502,6 +21996,7 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: minipass: 7.1.2 + dev: true /minipass-fetch@3.0.5: resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} @@ -25512,12 +22007,14 @@ packages: minizlib: 2.1.2 optionalDependencies: encoding: 0.1.13 + dev: true /minipass-flush@1.0.5: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} engines: {node: '>= 8'} dependencies: minipass: 3.3.6 + dev: true /minipass-json-stream@1.0.1: resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==} @@ -25531,12 +22028,14 @@ packages: engines: {node: '>=8'} dependencies: minipass: 3.3.6 + dev: true /minipass-sized@1.0.3: resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} engines: {node: '>=8'} dependencies: minipass: 3.3.6 + dev: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -25575,13 +22074,6 @@ packages: /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} requiresBuild: true - - /mkdirp@0.5.1: - resolution: {integrity: sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==} - deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) - hasBin: true - dependencies: - minimist: 0.0.8 dev: true /mkdirp@0.5.6: @@ -25603,33 +22095,11 @@ packages: pkg-types: 1.2.1 ufo: 1.5.4 - /mocha@5.2.0: - resolution: {integrity: sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==} - engines: {node: '>= 4.0.0'} - hasBin: true - dependencies: - browser-stdout: 1.3.1 - commander: 2.15.1 - debug: 3.1.0(supports-color@5.4.0) - diff: 3.5.0 - escape-string-regexp: 1.0.5 - glob: 7.1.2 - growl: 1.10.5 - he: 1.1.1 - minimatch: 3.0.4 - mkdirp: 0.5.1 - supports-color: 5.4.0 - dev: true - /modify-values@1.0.1: resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} engines: {node: '>=0.10.0'} dev: true - /module-details-from-path@1.0.3: - resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} - dev: false - /moment-range@4.0.2(moment@2.30.1): resolution: {integrity: sha512-n8sceWwSTjmz++nFHzeNEUsYtDqjgXgcOBzsHi+BoXQU2FW+eU92LUaK8gqOiSu5PG57Q9sYj1Fz4LRDj4FtKA==} peerDependencies: @@ -25649,154 +22119,6 @@ packages: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} dev: false - /mongodb-connection-string-url@2.6.0: - resolution: {integrity: sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==} - dependencies: - '@types/whatwg-url': 8.2.2 - whatwg-url: 11.0.0 - dev: false - - /mongodb-connection-string-url@3.0.1: - resolution: {integrity: sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==} - dependencies: - '@types/whatwg-url': 11.0.5 - whatwg-url: 13.0.0 - dev: false - - /mongodb@3.7.4: - resolution: {integrity: sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==} - engines: {node: '>=4'} - peerDependencies: - aws4: '*' - bson-ext: '*' - kerberos: '*' - mongodb-client-encryption: '*' - mongodb-extjson: '*' - snappy: '*' - peerDependenciesMeta: - aws4: - optional: true - bson-ext: - optional: true - kerberos: - optional: true - mongodb-client-encryption: - optional: true - mongodb-extjson: - optional: true - snappy: - optional: true - dependencies: - bl: 2.2.1 - bson: 1.1.6 - denque: 1.5.1 - optional-require: 1.1.8 - safe-buffer: 5.2.1 - optionalDependencies: - saslprep: 1.0.3 - dev: false - - /mongodb@4.17.2(@aws-sdk/client-sso-oidc@3.583.0): - resolution: {integrity: sha512-mLV7SEiov2LHleRJPMPrK2PMyhXFZt2UQLC4VD4pnth3jMjYKHhtqfwwkkvS/NXuo/Fp3vbhaNcXrIDaLRb9Tg==} - engines: {node: '>=12.9.0'} - dependencies: - bson: 4.7.2 - mongodb-connection-string-url: 2.6.0 - socks: 2.8.3 - optionalDependencies: - '@aws-sdk/credential-providers': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) - '@mongodb-js/saslprep': 1.1.7 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - dev: false - - /mongodb@6.6.2: - resolution: {integrity: sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==} - engines: {node: '>=16.20.1'} - peerDependencies: - '@aws-sdk/credential-providers': ^3.188.0 - '@mongodb-js/zstd': ^1.1.0 - gcp-metadata: ^5.2.0 - kerberos: ^2.0.1 - mongodb-client-encryption: '>=6.0.0 <7' - snappy: ^7.2.2 - socks: ^2.7.1 - peerDependenciesMeta: - '@aws-sdk/credential-providers': - optional: true - '@mongodb-js/zstd': - optional: true - gcp-metadata: - optional: true - kerberos: - optional: true - mongodb-client-encryption: - optional: true - snappy: - optional: true - socks: - optional: true - dependencies: - '@mongodb-js/saslprep': 1.1.7 - bson: 6.7.0 - mongodb-connection-string-url: 3.0.1 - dev: false - - /mongoose-legacy-pluralize@1.0.2(mongoose@5.13.22): - resolution: {integrity: sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==} - peerDependencies: - mongoose: '*' - dependencies: - mongoose: 5.13.22 - dev: false - - /mongoose@5.13.22: - resolution: {integrity: sha512-p51k/c4X/MfqeQ3I1ranlDiggLzNumZrTDD9CeezHwZxt2/btf+YZD7MCe07RAY2NgFYVMayq6jMamw02Jmf9w==} - engines: {node: '>=4.0.0'} - dependencies: - '@types/bson': 4.0.5 - '@types/mongodb': 3.6.20 - bson: 1.1.6 - kareem: 2.3.2 - mongodb: 3.7.4 - mongoose-legacy-pluralize: 1.0.2(mongoose@5.13.22) - mpath: 0.8.4 - mquery: 3.2.5 - ms: 2.1.2 - optional-require: 1.0.3 - regexp-clone: 1.0.0 - safe-buffer: 5.2.1 - sift: 13.5.2 - sliced: 1.0.1 - transitivePeerDependencies: - - aws4 - - bson-ext - - kerberos - - mongodb-client-encryption - - mongodb-extjson - - snappy - - supports-color - dev: false - - /mpath@0.8.4: - resolution: {integrity: sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==} - engines: {node: '>=4.0.0'} - dev: false - - /mquery@3.2.5: - resolution: {integrity: sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==} - engines: {node: '>=4.0.0'} - dependencies: - bluebird: 3.5.1 - debug: 3.1.0(supports-color@5.4.0) - regexp-clone: 1.0.0 - safe-buffer: 5.1.2 - sliced: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: false - /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -25806,6 +22128,7 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: false /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -25904,16 +22227,7 @@ packages: resolution: {integrity: sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==} engines: {npm: '>=1.4.0'} hasBin: true - - /mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} - hasBin: true - dev: false - - /mute-stdout@1.0.1: - resolution: {integrity: sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==} - engines: {node: '>= 0.10'} - dev: false + dev: true /mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} @@ -25924,20 +22238,6 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true - /mysql2@1.7.0: - resolution: {integrity: sha512-xTWWQPjP5rcrceZQ7CSTKR/4XIDeH/cRkNH/uzvVGQ7W5c7EJ0dXeJUusk7OKhIoHj7uFKUxDVSCfLIl+jluog==} - engines: {node: '>= 8.0'} - dependencies: - denque: 1.5.1 - generate-function: 2.3.1 - iconv-lite: 0.5.2 - long: 4.0.0 - lru-cache: 5.1.1 - named-placeholders: 1.1.3 - seq-queue: 0.0.5 - sqlstring: 2.3.3 - dev: false - /mysql2@3.11.4: resolution: {integrity: sha512-Z2o3tY4Z8EvSRDwknaC40MdZ3+m0sKbpnXrShQLdxPrAvcNli7jLrD2Zd2IzsRMw4eK9Yle500FDmlkIqp+krg==} engines: {node: '>= 8.0'} @@ -25978,12 +22278,6 @@ packages: lru-cache: 7.18.3 dev: false - /nan@2.19.0: - resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} - requiresBuild: true - dev: false - optional: true - /nano-css@5.6.1(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==} peerDependencies: @@ -26013,7 +22307,7 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /nanomatch@1.2.13(supports-color@5.5.0): + /nanomatch@1.2.13: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} engines: {node: '>=0.10.0'} dependencies: @@ -26026,7 +22320,7 @@ packages: kind-of: 6.0.3 object.pick: 1.3.0 regex-not: 1.0.2 - snapdragon: 0.8.2(supports-color@5.5.0) + snapdragon: 0.8.2 to-regex: 3.0.2 transitivePeerDependencies: - supports-color @@ -26034,6 +22328,7 @@ packages: /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: false /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -26055,9 +22350,6 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - /nested-error-stacks@2.1.1: - resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} - /nestjs-cls@5.2.0(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(reflect-metadata@0.2.2)(rxjs@7.8.1): resolution: {integrity: sha512-xabZQ7aPHttZ5TwC4rEyYgsxm3/ArM+Dz4oJPWc5Q1p+jOp+UaDe37fKna6sIMeUmYpvZxMVtUKIhv7CfLxbOw==} engines: {node: '>=18'} @@ -26117,54 +22409,10 @@ packages: - supports-color dev: false - /newrelic@11.17.0: - resolution: {integrity: sha512-gI5FGsfvHyGLUW/+q3op1SsF8jisW5wV+NVOoxV9J58GOEEsP1B4/9D5jyL3iiL5QO1REeWtK5n15d2OsiYAIg==} - engines: {node: '>=16', npm: '>=6.0.0'} - hasBin: true - dependencies: - '@grpc/grpc-js': 1.10.8 - '@grpc/proto-loader': 0.7.13 - '@newrelic/ritm': 7.2.0 - '@newrelic/security-agent': 1.2.0 - '@tyriar/fibonacci-heap': 2.0.9 - concat-stream: 2.0.0 - https-proxy-agent: 7.0.4 - import-in-the-middle: 1.7.4 - json-bigint: 1.0.0 - json-stringify-safe: 5.0.1 - module-details-from-path: 1.0.3 - readable-stream: 3.6.2 - semver: 7.6.2 - winston-transport: 4.7.0 - optionalDependencies: - '@contrast/fn-inspect': 3.4.0 - '@newrelic/native-metrics': 10.1.1 - '@prisma/prisma-fmt-wasm': 4.17.0-16.27eb2449f178cd9fe1a4b892d732cc4795f75085 - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate - dev: false - /next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} dev: false - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: true - - /nise@1.5.3: - resolution: {integrity: sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==} - dependencies: - '@sinonjs/formatio': 3.2.2 - '@sinonjs/text-encoding': 0.7.2 - just-extend: 4.2.1 - lolex: 5.1.2 - path-to-regexp: 1.8.0 - dev: true - /no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: @@ -26177,15 +22425,6 @@ packages: engines: {node: '>=4.0.0'} dev: false - /node-abi@3.62.0: - resolution: {integrity: sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==} - engines: {node: '>=10'} - requiresBuild: true - dependencies: - semver: 7.6.3 - dev: false - optional: true - /node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} @@ -26193,14 +22432,6 @@ packages: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} dev: false - /node-cache@4.2.1: - resolution: {integrity: sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==} - engines: {node: '>= 0.4.6'} - dependencies: - clone: 2.1.2 - lodash: 4.17.21 - dev: false - /node-dir@0.1.17: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} @@ -26218,11 +22449,6 @@ packages: resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} dev: true - /node-fetch@2.6.1: - resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} - engines: {node: 4.x || >=6.0.0} - dev: false - /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -26248,13 +22474,6 @@ packages: dev: false optional: true - /node-gyp-build@4.8.1: - resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} - hasBin: true - requiresBuild: true - dev: false - optional: true - /node-gyp@10.1.0: resolution: {integrity: sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA==} engines: {node: ^16.14.0 || >=18.0.0} @@ -26262,7 +22481,7 @@ packages: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.1 - glob: 10.4.1 + glob: 10.4.2 graceful-fs: 4.2.11 make-fetch-happen: 13.0.1 nopt: 7.2.1 @@ -26272,38 +22491,11 @@ packages: which: 4.0.0 transitivePeerDependencies: - supports-color + dev: true /node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - /node-libs-browser@2.2.1: - resolution: {integrity: sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==} - dependencies: - assert: 1.5.1 - browserify-zlib: 0.2.0 - buffer: 4.9.2 - console-browserify: 1.2.0 - constants-browserify: 1.0.0 - crypto-browserify: 3.12.0 - domain-browser: 1.2.0 - events: 3.3.0 - https-browserify: 1.0.0 - os-browserify: 0.3.0 - path-browserify: 0.0.1 - process: 0.11.10 - punycode: 1.4.1 - querystring-es3: 0.2.1 - readable-stream: 2.3.8 - stream-browserify: 2.0.2 - stream-http: 2.8.3 - string_decoder: 1.3.0 - timers-browserify: 2.0.12 - tty-browserify: 0.0.0 - url: 0.11.3 - util: 0.11.1 - vm-browserify: 1.1.2 - dev: true - /node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} dev: true @@ -26323,24 +22515,6 @@ packages: engines: {node: '>=6.0.0'} dev: false - /nodemon@1.19.4: - resolution: {integrity: sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==} - engines: {node: '>=4'} - hasBin: true - requiresBuild: true - dependencies: - chokidar: 2.1.8(supports-color@5.5.0) - debug: 3.2.7(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 5.7.2 - supports-color: 5.5.0 - touch: 3.1.1 - undefsafe: 2.0.5 - update-notifier: 2.5.0 - dev: false - /nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} @@ -26363,6 +22537,7 @@ packages: resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 + dev: true /normalize-package-data@3.0.3: resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} @@ -26394,13 +22569,6 @@ packages: validate-npm-package-license: 3.0.4 dev: true - /normalize-path@2.1.1: - resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} - engines: {node: '>=0.10.0'} - dependencies: - remove-trailing-separator: 1.1.0 - dev: false - /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -26419,13 +22587,6 @@ packages: resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==} dev: false - /now-and-later@2.0.1: - resolution: {integrity: sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==} - engines: {node: '>= 0.10'} - dependencies: - once: 1.4.0 - dev: false - /npm-bundled@1.1.2: resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==} dependencies: @@ -26543,38 +22704,6 @@ packages: - supports-color dev: true - /npm-run-all@4.1.5: - resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} - engines: {node: '>= 4'} - hasBin: true - dependencies: - ansi-styles: 3.2.1 - chalk: 2.4.2 - cross-spawn: 6.0.5 - memorystream: 0.3.1 - minimatch: 3.1.2 - pidtree: 0.3.1 - read-pkg: 3.0.0 - shell-quote: 1.8.1 - string.prototype.padend: 3.1.6 - dev: true - - /npm-run-path@2.0.2: - resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} - engines: {node: '>=4'} - dependencies: - path-key: 2.0.1 - dev: false - - /npm-run-path@3.1.0: - resolution: {integrity: sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==} - engines: {node: '>=8'} - requiresBuild: true - dependencies: - path-key: 3.1.1 - dev: false - optional: true - /npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -26621,15 +22750,6 @@ packages: boolbase: 1.0.0 dev: false - /number-is-nan@1.0.1: - resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} - engines: {node: '>=0.10.0'} - dev: false - - /numbered@1.1.0: - resolution: {integrity: sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g==} - dev: false - /nwsapi@2.2.10: resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} dev: false @@ -26695,40 +22815,6 @@ packages: - debug dev: true - /nyc@14.1.1: - resolution: {integrity: sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==} - engines: {node: '>=6'} - hasBin: true - dependencies: - archy: 1.0.0 - caching-transform: 3.0.2 - convert-source-map: 1.9.0 - cp-file: 6.2.0 - find-cache-dir: 2.1.0 - find-up: 3.0.0 - foreground-child: 1.5.6 - glob: 7.2.3 - istanbul-lib-coverage: 2.0.5 - istanbul-lib-hook: 2.0.7 - istanbul-lib-instrument: 3.3.0 - istanbul-lib-report: 2.0.8 - istanbul-lib-source-maps: 3.0.6 - istanbul-reports: 2.2.7 - js-yaml: 3.14.1 - make-dir: 2.1.0 - merge-source-map: 1.1.0 - resolve-from: 4.0.0 - rimraf: 2.7.1 - signal-exit: 3.0.7 - spawn-wrap: 1.4.3 - test-exclude: 5.2.3 - uuid: 3.4.0 - yargs: 13.3.2 - yargs-parser: 13.1.2 - transitivePeerDependencies: - - supports-color - dev: true - /nypm@0.3.12: resolution: {integrity: sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA==} engines: {node: ^14.16.0 || >=16.10.0} @@ -26742,18 +22828,6 @@ packages: ufo: 1.5.4 dev: true - /oauth2-server@3.0.0: - resolution: {integrity: sha512-TlDDkKECOTjQQ9pQobw/EESLbd7YVY1i0Ebos996Au88FqiLUbQ+X/cRBCq6gvpkoA0ByrDsF8c97SyRygfE6Q==} - engines: {node: '>=4.0'} - dependencies: - basic-auth: 1.1.0 - bluebird: 3.5.0 - lodash: 4.17.4 - promisify-any: 2.0.1 - statuses: 1.3.1 - type-is: 1.6.15 - dev: false - /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -26767,11 +22841,6 @@ packages: kind-of: 3.2.2 dev: false - /object-hash@1.3.1: - resolution: {integrity: sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==} - engines: {node: '>= 0.10.0'} - dev: true - /object-hash@2.1.1: resolution: {integrity: sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==} engines: {node: '>= 6'} @@ -26821,16 +22890,6 @@ packages: has-symbols: 1.0.3 object-keys: 1.1.1 - /object.defaults@1.1.0: - resolution: {integrity: sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==} - engines: {node: '>=0.10.0'} - dependencies: - array-each: 1.0.1 - array-slice: 1.1.0 - for-own: 1.0.0 - isobject: 3.0.1 - dev: false - /object.entries@1.1.8: resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} engines: {node: '>= 0.4'} @@ -26838,6 +22897,7 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 + dev: false /object.fromentries@2.0.8: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} @@ -26847,6 +22907,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 + dev: false /object.getownpropertydescriptors@2.1.8: resolution: {integrity: sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==} @@ -26868,6 +22929,7 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 + dev: false /object.hasown@1.1.4: resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} @@ -26878,14 +22940,6 @@ packages: es-object-atoms: 1.0.0 dev: false - /object.map@1.0.1: - resolution: {integrity: sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==} - engines: {node: '>=0.10.0'} - dependencies: - for-own: 1.0.0 - make-iterator: 1.0.1 - dev: false - /object.pick@1.3.0: resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} engines: {node: '>=0.10.0'} @@ -26893,14 +22947,6 @@ packages: isobject: 3.0.1 dev: false - /object.reduce@1.0.1: - resolution: {integrity: sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==} - engines: {node: '>=0.10.0'} - dependencies: - for-own: 1.0.0 - make-iterator: 1.0.1 - dev: false - /object.values@1.2.0: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} @@ -26908,50 +22954,6 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 - - /objection-filter@4.4.0(objection@3.1.4): - resolution: {integrity: sha512-P6HsNFM7IMFrhSzKdXOZcFqAHu8I735Z75/aF+UZLdSUwEiZKsiBsQq9wD1t9ruPCuW1OfsjP3lRnM2K8fuR+w==} - engines: {node: '>=14'} - peerDependencies: - objection: ^2.1.2 || ^3.0.0 - dependencies: - debug: 4.3.4 - lodash: 4.17.21 - objection: 3.1.4(knex@3.1.0) - transitivePeerDependencies: - - supports-color - dev: false - - /objection-soft-delete@1.0.7(objection@3.1.4): - resolution: {integrity: sha512-YGGk48DdLiK2gkyXCY4ByItWad+UCHm2VzfsYg8AnD+zhVuCN7FJhjkT8XOwQvCGprqLYuFN7ij/ClLnghUKxA==} - peerDependencies: - objection: '>= 0.8' - dependencies: - objection: 3.1.4(knex@3.1.0) - dev: false - - /objection-unique@1.2.2(objection@3.1.4): - resolution: {integrity: sha512-CbePk+pzzvxnqOWvjXYRBzQ03XTT0SWwBG++NcZZM1prLN3NViyyr/Ok7lNQg3F+9eGKN8Shcu4UFYA/x02Fpw==} - engines: {node: '>=6'} - peerDependencies: - objection: '>=1.0.0' - dependencies: - lodash.castarray: 4.4.0 - lodash.compact: 3.0.1 - lodash.isempty: 4.4.0 - objection: 3.1.4(knex@3.1.0) - dev: false - - /objection@3.1.4(knex@3.1.0): - resolution: {integrity: sha512-BI1YQ18JicfoODgCdKxmw4W8f24/e9hCEQpOTux0xmyd8hOidOzDd1WopOMxqxo7FA+Jfw8XTfZIUaqDnS7r0g==} - engines: {node: '>=14.0.0'} - peerDependencies: - knex: '>=1.0.1' - dependencies: - ajv: 8.13.0 - ajv-formats: 2.1.1(ajv@8.13.0) - db-errors: 0.2.3 - knex: 3.1.0(mysql2@1.7.0)(mysql@2.18.1) dev: false /objection@3.1.5(knex@3.1.0): @@ -26993,12 +22995,6 @@ packages: dependencies: wrappy: 1.0.2 - /one-time@1.0.0: - resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} - dependencies: - fn.name: 1.1.0 - dev: false - /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -27028,18 +23024,6 @@ packages: is-docker: 2.2.1 is-wsl: 2.2.0 - /optional-require@1.0.3: - resolution: {integrity: sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==} - engines: {node: '>=4'} - dev: false - - /optional-require@1.1.8: - resolution: {integrity: sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==} - engines: {node: '>=4'} - dependencies: - require-at: 1.0.6 - dev: false - /optionator@0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} @@ -27070,7 +23054,7 @@ packages: bl: 4.1.0 chalk: 4.1.2 cli-cursor: 3.1.0 - cli-spinners: 2.6.1 + cli-spinners: 2.9.2 is-interactive: 1.0.0 log-symbols: 4.1.0 strip-ansi: 6.0.1 @@ -27092,61 +23076,19 @@ packages: wcwidth: 1.0.1 dev: true - /ordered-read-streams@1.0.1: - resolution: {integrity: sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==} - dependencies: - readable-stream: 2.3.8 - dev: false - /orderedmap@2.1.1: resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} dev: false - /os-browserify@0.3.0: - resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} - dev: true - - /os-homedir@1.0.2: - resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} - engines: {node: '>=0.10.0'} - dev: true - - /os-locale@1.4.0: - resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} - engines: {node: '>=0.10.0'} - dependencies: - lcid: 1.0.0 - dev: false - /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} dev: true - /p-all@2.1.0: - resolution: {integrity: sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==} - engines: {node: '>=6'} - dependencies: - p-map: 2.1.0 - dev: false - - /p-event@4.2.0: - resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==} - engines: {node: '>=8'} - dependencies: - p-timeout: 3.2.0 - dev: false - - /p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} - dependencies: - p-map: 2.1.0 - dev: false - /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} + dev: true /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} @@ -27167,13 +23109,6 @@ packages: dependencies: yocto-queue: 0.1.0 - /p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - yocto-queue: 1.0.0 - dev: false - /p-locate@2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} @@ -27199,13 +23134,6 @@ packages: dependencies: p-limit: 3.1.0 - /p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-limit: 4.0.0 - dev: false - /p-map-series@2.1.0: resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} engines: {node: '>=8'} @@ -27216,18 +23144,12 @@ packages: engines: {node: '>=6'} dev: false - /p-map@3.0.0: - resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} - engines: {node: '>=8'} - dependencies: - aggregate-error: 3.1.0 - dev: false - /p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} dependencies: aggregate-error: 3.1.0 + dev: true /p-pipe@3.1.0: resolution: {integrity: sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==} @@ -27260,6 +23182,7 @@ packages: engines: {node: '>=8'} dependencies: p-finally: 1.0.0 + dev: true /p-try@1.0.0: resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} @@ -27277,29 +23200,8 @@ packages: p-reduce: 2.1.0 dev: true - /package-hash@3.0.0: - resolution: {integrity: sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==} - engines: {node: '>=6'} - dependencies: - graceful-fs: 4.2.11 - hasha: 3.0.0 - lodash.flattendeep: 4.4.0 - release-zalgo: 1.0.0 - dev: true - /package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - dev: true - - /package-json@4.0.1: - resolution: {integrity: sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA==} - engines: {node: '>=4'} - dependencies: - got: 6.7.1 - registry-auth-token: 3.4.0 - registry-url: 3.1.0 - semver: 5.7.2 - dev: false /pacote@17.0.7: resolution: {integrity: sha512-sgvnoUMlkv9xHwDUKjKQFXVyUi8dtJGKp3vg6sYy+TxbDic5RjZCHF3ygv0EJgNRZ2GfRONjlKPUfokJ9lDpwQ==} @@ -27333,10 +23235,6 @@ packages: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} dev: true - /pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - dev: true - /param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} dependencies: @@ -27350,38 +23248,6 @@ packages: dependencies: callsites: 3.1.0 - /parse-asn1@5.1.7: - resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} - engines: {node: '>= 0.10'} - dependencies: - asn1.js: 4.10.1 - browserify-aes: 1.2.0 - evp_bytestokey: 1.0.3 - hash-base: 3.0.4 - pbkdf2: 3.1.2 - safe-buffer: 5.2.1 - dev: true - - /parse-cache-control@1.0.1: - resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} - dev: false - - /parse-filepath@1.0.2: - resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} - engines: {node: '>=0.8'} - dependencies: - is-absolute: 1.0.0 - map-cache: 0.2.2 - path-root: 0.1.1 - dev: false - - /parse-json@2.2.0: - resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} - engines: {node: '>=0.10.0'} - dependencies: - error-ex: 1.3.2 - dev: false - /parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} @@ -27403,11 +23269,6 @@ packages: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} engines: {node: '>= 0.10'} - /parse-passwd@1.0.0: - resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} - engines: {node: '>=0.10.0'} - dev: false - /parse-path@7.0.0: resolution: {integrity: sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==} dependencies: @@ -27475,10 +23336,6 @@ packages: utils-merge: 1.0.1 dev: false - /path-browserify@0.0.1: - resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==} - dev: true - /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: false @@ -27490,16 +23347,6 @@ packages: tslib: 2.8.0 dev: false - /path-dirname@1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - dev: false - - /path-exists@2.1.0: - resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} - engines: {node: '>=0.10.0'} - dependencies: - pinkie-promise: 2.0.1 - /path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -27508,23 +23355,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - /path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false - /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - /path-is-inside@1.0.2: - resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} - dev: false - - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -27537,18 +23371,6 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - /path-root-regex@0.1.2: - resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} - engines: {node: '>=0.10.0'} - dev: false - - /path-root@0.1.1: - resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} - engines: {node: '>=0.10.0'} - dependencies: - path-root-regex: 0.1.2 - dev: false - /path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -27561,11 +23383,13 @@ packages: /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true /path-to-regexp@1.8.0: resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} dependencies: isarray: 0.0.1 + dev: false /path-to-regexp@3.2.0: resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} @@ -27574,36 +23398,20 @@ packages: /path-to-regexp@3.3.0: resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} - /path-type@1.1.0: - resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} - engines: {node: '>=0.10.0'} - dependencies: - graceful-fs: 4.2.11 - pify: 2.3.0 - pinkie-promise: 2.0.1 - dev: false - /path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} dependencies: pify: 3.0.0 + dev: true /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - /path@0.11.14: - resolution: {integrity: sha512-CzEXTDgcEfa0yqMe+DJCSbEB5YCv4JZoic5xulBNFF2ifIMjNrTWbNSPNhgKfSo0MjneGIx9RLy4pCFuZPaMSQ==} - dev: false - /pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - /pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - dev: true - /pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -27613,17 +23421,6 @@ packages: resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} dev: false - /pbkdf2@3.1.2: - resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} - engines: {node: '>=0.12'} - dependencies: - create-hash: 1.2.0 - create-hmac: 1.1.7 - ripemd160: 2.0.2 - safe-buffer: 5.2.1 - sha.js: 2.4.11 - dev: true - /peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} dev: false @@ -27638,15 +23435,12 @@ packages: /pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: true /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: false - /pg-connection-string@2.5.0: - resolution: {integrity: sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==} - dev: false - /pg-connection-string@2.6.2: resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} dev: false @@ -27657,6 +23451,7 @@ packages: /picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + dev: false /picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -27674,12 +23469,6 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - /pidtree@0.3.1: - resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} - engines: {node: '>=0.10'} - hasBin: true - dev: true - /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} @@ -27687,6 +23476,7 @@ packages: /pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} + dev: true /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} @@ -27697,27 +23487,10 @@ packages: engines: {node: '>=10'} dev: true - /pinkie-promise@2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} - dependencies: - pinkie: 2.0.4 - - /pinkie@2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - /pkg-dir@1.0.0: - resolution: {integrity: sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==} - engines: {node: '>=0.10.0'} - dependencies: - find-up: 1.1.2 - dev: true - /pkg-dir@3.0.0: resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} engines: {node: '>=6'} @@ -27738,13 +23511,6 @@ packages: find-up: 5.0.0 dev: true - /pkg-dir@7.0.0: - resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} - engines: {node: '>=14.16'} - dependencies: - find-up: 6.3.0 - dev: false - /pkg-types@1.2.1: resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} dependencies: @@ -27813,23 +23579,6 @@ packages: fsevents: 2.3.2 dev: true - /plugin-error@1.0.1: - resolution: {integrity: sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==} - engines: {node: '>= 0.10'} - dependencies: - ansi-colors: 1.1.0 - arr-diff: 4.0.0 - arr-union: 3.1.0 - extend-shallow: 3.0.2 - dev: false - - /plugin-error@2.0.1: - resolution: {integrity: sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==} - engines: {node: '>=10.13.0'} - dependencies: - ansi-colors: 1.1.0 - dev: true - /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -28166,26 +23915,6 @@ packages: yaml: 2.4.2 dev: false - /postcss-load-config@5.1.0(postcss@8.4.47): - resolution: {integrity: sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - dependencies: - lilconfig: 3.1.1 - postcss: 8.4.47 - yaml: 2.4.2 - dev: true - /postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -28218,7 +23947,7 @@ packages: klona: 2.0.6 postcss: 8.4.38 semver: 7.6.3 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.6.3)(webpack@5.91.0): @@ -28712,6 +24441,7 @@ packages: nanoid: 3.3.7 picocolors: 1.0.1 source-map-js: 1.2.0 + dev: false /postcss@8.4.47: resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} @@ -28731,20 +24461,6 @@ packages: - debug dev: false - /prebuildify@6.0.1: - resolution: {integrity: sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==} - hasBin: true - requiresBuild: true - dependencies: - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - node-abi: 3.62.0 - npm-run-path: 3.1.0 - pump: 3.0.0 - tar-fs: 2.1.1 - dev: false - optional: true - /prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} @@ -28754,11 +24470,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - /prepend-http@1.0.4: - resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} - engines: {node: '>=0.10.0'} - dev: false - /prettier-linter-helpers@1.0.0: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} @@ -28840,6 +24551,7 @@ packages: /pretty-hrtime@1.0.3: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} + dev: true /prism-react-renderer@1.3.5(react@18.3.1): resolution: {integrity: sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==} @@ -28857,10 +24569,12 @@ packages: /proc-log@3.0.0: resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true /proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -28870,21 +24584,6 @@ packages: engines: {node: '>= 0.6.0'} dev: true - /progress-bar-webpack-plugin@2.1.0(webpack@5.91.0): - resolution: {integrity: sha512-UtlZbnxpYk1wufEWfhIjRn2U52zlY38uvnzFhs8rRxJxC1hSqw88JNR2Mbpqq9Kix8L1nGb3uQ+/1BiUWbigAg==} - peerDependencies: - webpack: ^1.3.0 || ^2 || ^3 || ^4 || ^5 - dependencies: - chalk: 3.0.0 - progress: 2.0.3 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - dev: true - - /progress@2.0.1: - resolution: {integrity: sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==} - engines: {node: '>=0.4.0'} - dev: false - /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -28905,6 +24604,7 @@ packages: dependencies: err-code: 2.0.3 retry: 0.12.0 + dev: true /promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} @@ -28918,15 +24618,6 @@ packages: asap: 2.0.6 dev: false - /promisify-any@2.0.1: - resolution: {integrity: sha512-pVaGouFbTVxqpVJ+T5A15olNJDASAZHYq5cXz6mWdr6/X34mVWiG9MSdzHTcVBCv4aqBP7wGspi7BUSRbEmhsw==} - engines: {node: '>=0.10.0'} - dependencies: - bluebird: 2.11.0 - co-bluebird: 1.1.0 - is-generator: 1.0.3 - dev: false - /prompts@2.4.0: resolution: {integrity: sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==} engines: {node: '>= 6'} @@ -29106,25 +24797,6 @@ packages: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: false - /protobufjs@7.3.0: - resolution: {integrity: sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g==} - engines: {node: '>=12.0.0'} - requiresBuild: true - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 20.5.1 - long: 5.2.3 - dev: false - /protocols@2.0.1: resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==} dev: true @@ -29144,28 +24816,10 @@ packages: requiresBuild: true optional: true - /pseudomap@1.0.2: - resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} - /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: false - /pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - dev: false - - /public-encrypt@4.0.3: - resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} - dependencies: - bn.js: 4.12.0 - browserify-rsa: 4.1.0 - create-hash: 1.2.0 - parse-asn1: 5.1.7 - randombytes: 2.1.0 - safe-buffer: 5.2.1 - dev: true - /pug-attrs@3.0.0: resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} dependencies: @@ -29262,12 +24916,14 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 + dev: true /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 + dev: true /pumpify@1.5.1: resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} @@ -29275,16 +24931,13 @@ packages: duplexify: 3.7.1 inherits: 2.0.4 pump: 2.0.1 + dev: true /punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} dev: false - /punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - dev: true - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -29309,30 +24962,6 @@ packages: - utf-8-validate dev: true - /puppeteer@10.4.0: - resolution: {integrity: sha512-2cP8mBoqnu5gzAVpbZ0fRaobBWZM8GEUF4I1F6WbgHrKV/rz7SX8PG2wMymZgD0wo0UBlg2FBPNxlF/xlqW6+w==} - engines: {node: '>=10.18.1'} - deprecated: < 22.5.0 is no longer supported - requiresBuild: true - dependencies: - debug: 4.3.1 - devtools-protocol: 0.0.901419 - extract-zip: 2.0.1 - https-proxy-agent: 5.0.0 - node-fetch: 2.6.1 - pkg-dir: 4.2.0 - progress: 2.0.1 - proxy-from-env: 1.1.0 - rimraf: 3.0.2 - tar-fs: 2.0.0 - unbzip2-stream: 1.3.3 - ws: 7.4.6 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: false - /pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} dev: true @@ -29342,17 +24971,12 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} dev: false - /qim@0.0.52: - resolution: {integrity: sha512-CiCbUioNzXlTPQD4jt6lJRKW3/rJiwGaZzntLeohihOABi27kx2n3gmhDoOeO68OPGXHchYw9CUgauSdbFwqjg==} - dependencies: - object-assign: 4.1.1 - dev: false - /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} dependencies: side-channel: 1.0.6 + dev: true /qs@6.12.1: resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==} @@ -29376,11 +25000,6 @@ packages: strict-uri-encode: 2.0.0 dev: false - /querystring-es3@0.2.1: - resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} - engines: {node: '>=0.4.x'} - dev: true - /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: false @@ -29391,6 +25010,7 @@ packages: /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} + dev: true /raf@3.4.1: resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} @@ -29410,31 +25030,15 @@ packages: resolution: {integrity: sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==} dev: false - /random-bytes@1.0.0: - resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} - engines: {node: '>= 0.8'} - dev: false - /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 - /randomfill@1.0.4: - resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} - dependencies: - randombytes: 2.1.0 - safe-buffer: 5.2.1 - dev: true - /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - /rate-limiter-flexible@2.4.2: - resolution: {integrity: sha512-rMATGGOdO1suFyf/mI5LYhts71g1sbdhmd6YvdiXO2gJnd42Tt6QS4JUKJKSWVVkMtBacm6l40FR7Trjo6Iruw==} - dev: false - /raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} @@ -29510,16 +25114,6 @@ packages: shallowequal: 1.1.0 dev: false - /rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - dev: false - /react-app-polyfill@1.0.6: resolution: {integrity: sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==} engines: {node: '>=6'} @@ -29657,7 +25251,7 @@ packages: strip-ansi: 6.0.1 text-table: 0.2.0 typescript: 4.9.5 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) transitivePeerDependencies: - eslint - supports-color @@ -30128,7 +25722,7 @@ packages: tailwindcss: 3.4.14(ts-node@10.9.2) terser-webpack-plugin: 5.3.10(esbuild@0.23.1)(webpack@5.91.0) typescript: 4.9.5 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) webpack-dev-server: 4.15.2(webpack@5.91.0) webpack-manifest-plugin: 4.1.1(webpack@5.91.0) workbox-webpack-plugin: 6.6.0(webpack@5.91.0) @@ -30388,7 +25982,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} deprecated: This package is no longer supported. Please use @npmcli/package-json instead. dependencies: - glob: 10.4.1 + glob: 10.4.2 json-parse-even-better-errors: 3.0.2 normalize-package-data: 5.0.0 npm-normalize-package-bin: 3.0.1 @@ -30399,20 +25993,12 @@ packages: engines: {node: ^16.14.0 || >=18.0.0} deprecated: This package is no longer supported. Please use @npmcli/package-json instead. dependencies: - glob: 10.4.1 + glob: 10.4.2 json-parse-even-better-errors: 3.0.2 normalize-package-data: 6.0.1 npm-normalize-package-bin: 3.0.1 dev: true - /read-pkg-up@1.0.1: - resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} - engines: {node: '>=0.10.0'} - dependencies: - find-up: 1.1.2 - read-pkg: 1.1.0 - dev: false - /read-pkg-up@3.0.0: resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} engines: {node: '>=4'} @@ -30421,14 +26007,6 @@ packages: read-pkg: 3.0.0 dev: true - /read-pkg-up@4.0.0: - resolution: {integrity: sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==} - engines: {node: '>=6'} - dependencies: - find-up: 3.0.0 - read-pkg: 3.0.0 - dev: true - /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -30436,15 +26014,7 @@ packages: find-up: 4.1.0 read-pkg: 5.2.0 type-fest: 0.8.1 - - /read-pkg@1.1.0: - resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} - engines: {node: '>=0.10.0'} - dependencies: - load-json-file: 1.1.0 - normalize-package-data: 2.5.0 - path-type: 1.1.0 - dev: false + dev: true /read-pkg@3.0.0: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} @@ -30463,6 +26033,7 @@ packages: normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 + dev: true /read@2.1.0: resolution: {integrity: sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ==} @@ -30518,17 +26089,6 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 - /readdirp@2.2.1(supports-color@5.5.0): - resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} - engines: {node: '>=0.10'} - dependencies: - graceful-fs: 4.2.11 - micromatch: 3.1.10(supports-color@5.5.0) - readable-stream: 2.3.8 - transitivePeerDependencies: - - supports-color - dev: false - /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -30556,26 +26116,6 @@ packages: tslib: 2.8.0 dev: true - /rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.8 - dev: false - - /rechoir@0.7.0: - resolution: {integrity: sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.8 - dev: false - - /rechoir@0.7.1: - resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.8 - /rechoir@0.8.0: resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} engines: {node: '>= 10.13.0'} @@ -30602,6 +26142,7 @@ packages: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 + dev: true /redis-errors@1.2.0: resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} @@ -30686,10 +26227,6 @@ packages: engines: {node: '>=4.0.0'} dev: false - /reflect-metadata@0.1.14: - resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==} - dev: false - /reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -30721,6 +26258,7 @@ packages: /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: false /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -30741,10 +26279,6 @@ packages: /regex-parser@2.3.0: resolution: {integrity: sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==} - /regexp-clone@1.0.0: - resolution: {integrity: sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==} - dev: false - /regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -30770,20 +26304,6 @@ packages: unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.1.0 - /registry-auth-token@3.4.0: - resolution: {integrity: sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==} - dependencies: - rc: 1.2.8 - safe-buffer: 5.2.1 - dev: false - - /registry-url@3.1.0: - resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} - engines: {node: '>=0.10.0'} - dependencies: - rc: 1.2.8 - dev: false - /regjsparser@0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true @@ -30795,13 +26315,6 @@ packages: engines: {node: '>= 0.10'} dev: false - /release-zalgo@1.0.0: - resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} - engines: {node: '>=4'} - dependencies: - es6-error: 4.1.1 - dev: true - /remark-external-links@8.0.0: resolution: {integrity: sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==} dependencies: @@ -30834,27 +26347,6 @@ packages: resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} dev: false - /remove-bom-buffer@3.0.0: - resolution: {integrity: sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - is-utf8: 0.2.1 - dev: false - - /remove-bom-stream@1.2.0: - resolution: {integrity: sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==} - engines: {node: '>= 0.10'} - dependencies: - remove-bom-buffer: 3.0.0 - safe-buffer: 5.2.1 - through2: 2.0.5 - dev: false - - /remove-trailing-separator@1.1.0: - resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - dev: false - /renderkid@3.0.0: resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} dependencies: @@ -30874,34 +26366,6 @@ packages: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} - /replace-ext@1.0.1: - resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} - engines: {node: '>= 0.10'} - dev: false - - /replace-ext@2.0.0: - resolution: {integrity: sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==} - engines: {node: '>= 10'} - dev: false - - /replace-homedir@1.0.0: - resolution: {integrity: sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==} - engines: {node: '>= 0.10'} - dependencies: - homedir-polyfill: 1.0.3 - is-absolute: 1.0.0 - remove-trailing-separator: 1.1.0 - dev: false - - /request-ip@3.3.0: - resolution: {integrity: sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA==} - dev: false - - /require-at@1.0.6: - resolution: {integrity: sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==} - engines: {node: '>=4'} - dev: false - /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -30910,14 +26374,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - /require-main-filename@1.0.1: - resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} - dev: false - - /require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: true - /requireindex@1.2.0: resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} engines: {node: '>=0.10.5'} @@ -30945,14 +26401,6 @@ packages: dependencies: resolve-from: 5.0.0 - /resolve-dir@1.0.1: - resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} - engines: {node: '>=0.10.0'} - dependencies: - expand-tilde: 2.0.2 - global-modules: 1.0.0 - dev: false - /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -30968,21 +26416,10 @@ packages: global-dirs: 0.1.1 dev: true - /resolve-options@1.1.0: - resolution: {integrity: sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==} - engines: {node: '>= 0.10'} - dependencies: - value-or-function: 3.0.0 - dev: false - /resolve-pathname@3.0.0: resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} dev: false - /resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true - /resolve-url-loader@4.0.0: resolution: {integrity: sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==} engines: {node: '>=8.9'} @@ -31061,6 +26498,7 @@ packages: /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} + dev: true /retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} @@ -31071,10 +26509,6 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - /rfdc@1.3.1: - resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} - dev: false - /rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -31104,21 +26538,6 @@ packages: glob: 9.3.5 dev: true - /ringbufferjs@2.0.0: - resolution: {integrity: sha512-GCOqTzUsTHF7nrqcgtNGAFotXztLgiePpIDpyWZ7R5I02tmfJWV+/yuJc//Hlsd8G+WzI1t/dc2y/w2imDZdog==} - dev: false - - /ripemd160@2.0.2: - resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} - dependencies: - hash-base: 3.1.0 - inherits: 2.0.4 - dev: true - - /rndm@1.2.0: - resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==} - dev: false - /rollup-plugin-terser@7.0.2(rollup@2.79.1): resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser @@ -31189,16 +26608,6 @@ packages: strip-json-comments: 2.0.1 dev: false - /rtlcss@3.5.0: - resolution: {integrity: sha512-wzgMaMFHQTnyi9YOwsx9LjOxYXJPzS8sYnFaKm6R5ysvTkwzHiB0vxnbHwchHQT65PTdBjDG21/kQBWI7q9O7A==} - hasBin: true - dependencies: - find-up: 5.0.0 - picocolors: 1.0.1 - postcss: 8.4.38 - strip-json-comments: 3.1.1 - dev: true - /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -31214,11 +26623,6 @@ packages: dependencies: queue-microtask: 1.2.3 - /run-script-webpack-plugin@0.1.1: - resolution: {integrity: sha512-PrxBRLv1K9itDKMlootSCyGhdTU+KbKGJ2wF6/k0eyo6M0YGPC58HYbS/J/QsDiwM0t7G99WcuCqto0J7omOXA==} - engines: {node: '>=14'} - dev: true - /rusha@0.8.14: resolution: {integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==} dev: false @@ -31233,7 +26637,7 @@ packages: /rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} dependencies: - tslib: 2.6.2 + tslib: 2.8.0 /safe-array-concat@1.1.2: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} @@ -31243,6 +26647,7 @@ packages: get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 + dev: false /safe-buffer@5.1.1: resolution: {integrity: sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==} @@ -31261,6 +26666,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-regex: 1.1.4 + dev: false /safe-regex@1.1.0: resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} @@ -31268,11 +26674,6 @@ packages: ret: 0.1.15 dev: false - /safe-stable-stringify@2.4.3: - resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} - engines: {node: '>=10'} - dev: false - /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -31280,15 +26681,6 @@ packages: resolution: {integrity: sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==} dev: false - /saslprep@1.0.3: - resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==} - engines: {node: '>=6'} - requiresBuild: true - dependencies: - sparse-bitfield: 3.0.3 - dev: false - optional: true - /sass-loader@12.6.0(sass@1.77.2)(webpack@5.91.0): resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==} engines: {node: '>= 12.13.0'} @@ -31311,7 +26703,7 @@ packages: klona: 2.0.6 neo-async: 2.6.2 sass: 1.77.2 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /sass-loader@13.3.3(webpack@5.91.0): @@ -31368,6 +26760,7 @@ packages: chokidar: 3.6.0 immutable: 4.3.6 source-map-js: 1.2.0 + dev: false /sax@1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} @@ -31430,9 +26823,9 @@ packages: engines: {node: '>= 12.13.0'} dependencies: '@types/json-schema': 7.0.15 - ajv: 8.13.0 - ajv-formats: 2.1.1(ajv@8.13.0) - ajv-keywords: 5.1.0(ajv@8.13.0) + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) dev: false /screenfull@5.2.0: @@ -31462,20 +26855,6 @@ packages: node-forge: 1.3.1 dev: false - /semver-diff@2.1.0: - resolution: {integrity: sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==} - engines: {node: '>=0.10.0'} - dependencies: - semver: 5.7.2 - dev: false - - /semver-greatest-satisfied-range@1.1.0: - resolution: {integrity: sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==} - engines: {node: '>= 0.10'} - dependencies: - sver-compat: 1.5.0 - dev: false - /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -31509,7 +26888,7 @@ packages: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} dependencies: - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 encodeurl: 1.0.2 @@ -31524,12 +26903,13 @@ packages: statuses: 2.0.1 transitivePeerDependencies: - supports-color + dev: true /send@0.19.0: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} dependencies: - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 encodeurl: 1.0.2 @@ -31598,7 +26978,7 @@ packages: dependencies: accepts: 1.3.8 batch: 0.6.1 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 escape-html: 1.0.3 http-errors: 1.6.3 mime-types: 2.1.35 @@ -31617,6 +26997,7 @@ packages: send: 0.18.0 transitivePeerDependencies: - supports-color + dev: true /serve-static@1.16.2: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} @@ -31667,29 +27048,13 @@ packages: split-string: 3.1.0 dev: false - /setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: true - /setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} dev: false - /setprototypeof@1.1.1: - resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} - dev: false - /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - /sha.js@2.4.11: - resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} - hasBin: true - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: true - /shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} @@ -31700,22 +27065,12 @@ packages: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} dev: false - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} @@ -31726,6 +27081,7 @@ packages: /shell-quote@1.8.1: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + dev: false /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} @@ -31736,10 +27092,6 @@ packages: get-intrinsic: 1.2.4 object-inspect: 1.13.1 - /sift@13.5.2: - resolution: {integrity: sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==} - dev: false - /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: false @@ -31779,12 +27131,6 @@ packages: - supports-color dev: true - /simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - dependencies: - is-arrayish: 0.3.2 - dev: false - /simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} @@ -31792,27 +27138,9 @@ packages: semver: 7.6.3 dev: true - /sinon@7.5.0: - resolution: {integrity: sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==} - deprecated: 16.1.1 - dependencies: - '@sinonjs/commons': 1.8.6 - '@sinonjs/formatio': 3.2.2 - '@sinonjs/samsam': 3.3.3 - diff: 3.5.0 - lolex: 4.2.0 - nise: 1.5.3 - supports-color: 5.5.0 - dev: true - /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - /slash@2.0.0: - resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} - engines: {node: '>=6'} - dev: false - /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -31822,13 +27150,10 @@ packages: engines: {node: '>=12'} dev: false - /sliced@1.0.1: - resolution: {integrity: sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==} - dev: false - /smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: true /snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -31853,12 +27178,12 @@ packages: kind-of: 3.2.2 dev: false - /snapdragon@0.8.2(supports-color@5.5.0): + /snapdragon@0.8.2: resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} engines: {node: '>=0.10.0'} dependencies: base: 0.11.2 - debug: 2.6.9(supports-color@5.5.0) + debug: 2.6.9 define-property: 0.2.5 extend-shallow: 2.0.1 map-cache: 0.2.2 @@ -31869,17 +27194,6 @@ packages: - supports-color dev: false - /socket.io-adapter@2.5.4: - resolution: {integrity: sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==} - dependencies: - debug: 4.3.7(supports-color@5.5.0) - ws: 8.11.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: false - /socket.io-client@4.7.5: resolution: {integrity: sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==} engines: {node: '>=10.0.0'} @@ -31904,23 +27218,6 @@ packages: - supports-color dev: false - /socket.io@4.7.5: - resolution: {integrity: sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==} - engines: {node: '>=10.2.0'} - dependencies: - accepts: 1.3.8 - base64id: 2.0.0 - cors: 2.8.5 - debug: 4.3.4 - engine.io: 6.5.4 - socket.io-adapter: 2.5.4 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: false - /sockjs@0.3.24: resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} dependencies: @@ -31949,6 +27246,7 @@ packages: socks: 2.8.3 transitivePeerDependencies: - supports-color + dev: true /socks@2.8.3: resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} @@ -31956,6 +27254,7 @@ packages: dependencies: ip-address: 9.0.5 smart-buffer: 4.2.0 + dev: true /sort-keys@2.0.0: resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} @@ -31982,6 +27281,7 @@ packages: /source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + dev: false /source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} @@ -31996,18 +27296,7 @@ packages: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - dev: false - - /source-map-loader@4.0.2(webpack@5.91.0): - resolution: {integrity: sha512-oYwAqCuL0OZhBoSgmdrLa7mv9MjommVMiQIWgcztf+eS4+8BfcUee6nenFnDhKOhzAVnk5gpZdfnz1iiBv+5sg==} - engines: {node: '>= 14.15.0'} - peerDependencies: - webpack: ^5.72.1 - dependencies: - iconv-lite: 0.6.3 - source-map-js: 1.2.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /source-map-resolve@0.5.3: @@ -32047,6 +27336,7 @@ packages: /source-map@0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} + dev: false /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} @@ -32072,46 +27362,27 @@ packages: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} dev: true - /sparkles@1.0.1: - resolution: {integrity: sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==} - engines: {node: '>= 0.10'} - dev: false - - /sparse-bitfield@3.0.3: - resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} - requiresBuild: true - dependencies: - memory-pager: 1.5.0 - dev: false - - /spawn-wrap@1.4.3: - resolution: {integrity: sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==} - dependencies: - foreground-child: 1.5.6 - mkdirp: 0.5.6 - os-homedir: 1.0.2 - rimraf: 2.7.1 - signal-exit: 3.0.7 - which: 1.3.1 - dev: true - /spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.18 + dev: true /spdx-exceptions@2.5.0: resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + dev: true /spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} dependencies: spdx-exceptions: 2.5.0 spdx-license-ids: 3.0.18 + dev: true /spdx-license-ids@3.0.18: resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + dev: true /spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -32168,6 +27439,7 @@ packages: /sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + dev: true /sqlstring@2.3.1: resolution: {integrity: sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==} @@ -32191,6 +27463,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: minipass: 7.1.2 + dev: true /ssri@9.0.1: resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} @@ -32210,10 +27483,6 @@ packages: stackframe: 1.3.4 dev: false - /stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - dev: false - /stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -32247,10 +27516,6 @@ packages: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} dev: false - /start-server-webpack-plugin@2.2.5: - resolution: {integrity: sha512-DRCkciwCJoCFZ+wt3wWMkR1M2mpVhJbUKFXqhK3FWyIUKYb42NnocH5sMwqgo+nPNHupqNwK/v8lgfBbr2NKdg==} - dev: true - /static-eval@2.0.2: resolution: {integrity: sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==} dependencies: @@ -32265,11 +27530,6 @@ packages: object-copy: 0.1.0 dev: false - /statuses@1.3.1: - resolution: {integrity: sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==} - engines: {node: '>= 0.6'} - dev: false - /statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -32310,13 +27570,6 @@ packages: resolution: {integrity: sha512-oSSXKnD6mBC/7bqX7b2GPzFhwGRfjR9jbuPeBBmLS99grRWj9XZh47W3EihppKbWFWCEvTwTgaWdA56C9hpmxQ==} dev: false - /stream-browserify@2.0.2: - resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} - dependencies: - inherits: 2.0.4 - readable-stream: 2.3.8 - dev: true - /stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} dependencies: @@ -32324,33 +27577,9 @@ packages: readable-stream: 3.6.2 dev: false - /stream-exhaust@1.0.2: - resolution: {integrity: sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==} - dev: false - - /stream-http@2.8.3: - resolution: {integrity: sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==} - dependencies: - builtin-status-codes: 3.0.0 - inherits: 2.0.4 - readable-stream: 2.3.8 - to-arraybuffer: 1.0.1 - xtend: 4.0.2 - dev: true - /stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - - /streamroller@3.1.5: - resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} - engines: {node: '>=8.0'} - dependencies: - date-format: 4.0.14 - debug: 4.3.7(supports-color@5.5.0) - fs-extra: 8.1.0 - transitivePeerDependencies: - - supports-color - dev: false + dev: true /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} @@ -32389,32 +27618,6 @@ packages: resolution: {integrity: sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==} dev: false - /string-width@1.0.2: - resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} - engines: {node: '>=0.10.0'} - dependencies: - code-point-at: 1.1.0 - is-fullwidth-code-point: 1.0.0 - strip-ansi: 3.0.1 - dev: false - - /string-width@2.1.1: - resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} - engines: {node: '>=4'} - dependencies: - is-fullwidth-code-point: 2.0.0 - strip-ansi: 4.0.0 - dev: false - - /string-width@3.1.0: - resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} - engines: {node: '>=6'} - dependencies: - emoji-regex: 7.0.3 - is-fullwidth-code-point: 2.0.0 - strip-ansi: 5.2.0 - dev: true - /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -32431,10 +27634,6 @@ packages: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - /string.fromcodepoint@0.2.1: - resolution: {integrity: sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==} - dev: false - /string.prototype.matchall@4.0.11: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} @@ -32453,16 +27652,6 @@ packages: side-channel: 1.0.6 dev: false - /string.prototype.padend@3.1.6: - resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - dev: true - /string.prototype.trim@1.2.9: resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} @@ -32471,6 +27660,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 + dev: false /string.prototype.trimend@1.0.8: resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} @@ -32478,6 +27668,7 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 + dev: false /string.prototype.trimstart@1.0.8: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} @@ -32486,6 +27677,7 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 + dev: false /string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} @@ -32510,26 +27702,6 @@ packages: is-regexp: 1.0.0 dev: false - /strip-ansi@3.0.1: - resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-regex: 2.1.1 - dev: false - - /strip-ansi@4.0.0: - resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} - engines: {node: '>=4'} - dependencies: - ansi-regex: 3.0.1 - - /strip-ansi@5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - dependencies: - ansi-regex: 4.1.1 - dev: true - /strip-ansi@6.0.0: resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==} engines: {node: '>=8'} @@ -32549,13 +27721,6 @@ packages: dependencies: ansi-regex: 6.0.1 - /strip-bom@2.0.0: - resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} - engines: {node: '>=0.10.0'} - dependencies: - is-utf8: 0.2.1 - dev: false - /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -32569,11 +27734,6 @@ packages: engines: {node: '>=10'} dev: false - /strip-eof@1.0.0: - resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} - engines: {node: '>=0.10.0'} - dev: false - /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -32588,6 +27748,7 @@ packages: engines: {node: '>=8'} dependencies: min-indent: 1.0.1 + dev: true /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} @@ -32602,7 +27763,7 @@ packages: resolution: {integrity: sha512-H0qeSCkZVvk4fVchUbg0rNNviwOyw3Rsr9X6MKe84ajBeMz4ogEOZykaUcb/n0GSdvWlXAtbnB1gxl3xOlH+ZA==} engines: {node: '>=12.*'} dependencies: - '@types/node': 14.18.63 + '@types/node': 20.5.1 qs: 6.12.1 dev: false @@ -32634,7 +27795,7 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) /style-loader@3.3.4(webpack@5.96.1): resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==} @@ -32720,32 +27881,13 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.5 commander: 4.1.1 - glob: 10.4.1 + glob: 10.4.2 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.6 ts-interface-checker: 0.1.13 dev: false - /superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net - dependencies: - component-emitter: 1.3.1 - cookiejar: 2.1.4 - debug: 4.3.7(supports-color@5.5.0) - fast-safe-stringify: 2.1.1 - form-data: 4.0.0 - formidable: 2.1.2 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.12.1 - semver: 7.6.2 - transitivePeerDependencies: - - supports-color - dev: true - /superagent@9.0.2: resolution: {integrity: sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==} engines: {node: '>=14.18.0'} @@ -32758,7 +27900,7 @@ packages: formidable: 3.5.2 methods: 1.1.2 mime: 2.6.0 - qs: 6.12.1 + qs: 6.13.0 transitivePeerDependencies: - supports-color dev: true @@ -32773,25 +27915,12 @@ packages: - supports-color dev: true - /supports-color@5.4.0: - resolution: {integrity: sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 - /supports-color@6.1.0: - resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} - engines: {node: '>=6'} - dependencies: - has-flag: 3.0.0 - dev: true - /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -32816,13 +27945,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /sver-compat@1.5.0: - resolution: {integrity: sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==} - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - dev: false - /svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} dev: false @@ -32880,21 +28002,6 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: false - /sync-request@6.1.0: - resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} - engines: {node: '>=8.0.0'} - dependencies: - http-response-object: 3.0.2 - sync-rpc: 1.3.6 - then-request: 6.0.2 - dev: false - - /sync-rpc@1.3.6: - resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} - dependencies: - get-port: 3.2.0 - dev: false - /synchronous-promise@2.0.17: resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} @@ -32937,11 +28044,6 @@ packages: - ts-node dev: false - /tapable@0.1.10: - resolution: {integrity: sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ==} - engines: {node: '>=0.6'} - dev: true - /tapable@1.1.3: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} engines: {node: '>=6'} @@ -32951,15 +28053,6 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - /tar-fs@2.0.0: - resolution: {integrity: sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==} - dependencies: - chownr: 1.1.4 - mkdirp: 0.5.6 - pump: 3.0.0 - tar-stream: 2.2.0 - dev: false - /tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} requiresBuild: true @@ -32968,6 +28061,7 @@ packages: mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 2.2.0 + dev: true /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -32978,6 +28072,7 @@ packages: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 + dev: true /tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} @@ -33038,13 +28133,6 @@ packages: unique-string: 2.0.0 dev: true - /term-size@1.2.0: - resolution: {integrity: sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ==} - engines: {node: '>=4'} - dependencies: - execa: 0.7.0 - dev: false - /terminal-link@2.1.1: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} @@ -33124,7 +28212,7 @@ packages: schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.31.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) /terser-webpack-plugin@5.3.10(esbuild@0.23.1)(webpack@5.96.1): resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} @@ -33156,20 +28244,10 @@ packages: hasBin: true dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.13.0 + acorn: 8.14.0 commander: 2.20.3 source-map-support: 0.5.21 - /test-exclude@5.2.3: - resolution: {integrity: sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==} - engines: {node: '>=6'} - dependencies: - glob: 7.2.3 - minimatch: 3.1.2 - read-pkg-up: 4.0.0 - require-main-filename: 2.0.0 - dev: true - /test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -33183,10 +28261,6 @@ packages: engines: {node: '>=0.10'} dev: true - /text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - dev: false - /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -33206,23 +28280,6 @@ packages: react: 18.3.1 dev: false - /then-request@6.0.2: - resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} - engines: {node: '>=6.0.0'} - dependencies: - '@types/concat-stream': 1.6.1 - '@types/form-data': 0.0.33 - '@types/node': 8.10.66 - '@types/qs': 6.9.15 - caseless: 0.12.0 - concat-stream: 1.6.2 - form-data: 2.5.1 - http-basic: 8.1.3 - http-response-object: 3.0.2 - promise: 8.3.0 - qs: 6.13.0 - dev: false - /thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -33245,13 +28302,6 @@ packages: engines: {node: '>=8'} dev: false - /through2-filter@3.0.0: - resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==} - dependencies: - through2: 2.0.5 - xtend: 4.0.2 - dev: false - /through2@0.4.2: resolution: {integrity: sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==} dependencies: @@ -33264,6 +28314,7 @@ packages: dependencies: readable-stream: 2.3.8 xtend: 4.0.2 + dev: true /through2@4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} @@ -33283,23 +28334,6 @@ packages: engines: {node: '>=8'} dev: false - /time-stamp@1.1.0: - resolution: {integrity: sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==} - engines: {node: '>=0.10.0'} - dev: false - - /timed-out@4.0.1: - resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} - engines: {node: '>=0.10.0'} - dev: false - - /timers-browserify@2.0.12: - resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} - engines: {node: '>=0.6.0'} - dependencies: - setimmediate: 1.0.5 - dev: true - /tiny-emitter@2.1.0: resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} dev: false @@ -33348,12 +28382,6 @@ packages: '@popperjs/core': 2.11.8 dev: false - /tmp-promise@3.0.3: - resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} - dependencies: - tmp: 0.2.3 - dev: false - /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -33364,22 +28392,11 @@ packages: /tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} + dev: true /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - /to-absolute-glob@2.0.2: - resolution: {integrity: sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==} - engines: {node: '>=0.10.0'} - dependencies: - is-absolute: 1.0.0 - is-negated-glob: 1.0.0 - dev: false - - /to-arraybuffer@1.0.1: - resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} - dev: true - /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -33415,13 +28432,6 @@ packages: safe-regex: 1.1.0 dev: false - /to-through@2.0.0: - resolution: {integrity: sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==} - engines: {node: '>= 0.10'} - dependencies: - through2: 2.0.5 - dev: false - /tocbot@4.31.0: resolution: {integrity: sha512-Zd9tt6EQn2bvLSHIcug/Z1Sukyn/XJ62dMK9SjIbtHSDkI+Du40CmBvds6BedzXZe1sS1iPGl4Wup/k4cJkVhQ==} dev: true @@ -33430,11 +28440,6 @@ packages: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} dev: false - /toidentifier@1.0.0: - resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} - engines: {node: '>=0.6'} - dev: false - /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -33447,11 +28452,6 @@ packages: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} dev: false - /touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} - hasBin: true - dev: false - /tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -33478,20 +28478,6 @@ packages: punycode: 2.3.1 dev: false - /tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} - dependencies: - punycode: 2.3.1 - dev: false - - /tr46@4.1.1: - resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} - engines: {node: '>=14'} - dependencies: - punycode: 2.3.1 - dev: false - /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -33499,11 +28485,7 @@ packages: /trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} - - /triple-beam@1.4.1: - resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} - engines: {node: '>= 14.0.0'} - dev: false + dev: true /tryer@1.0.1: resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==} @@ -33570,22 +28552,6 @@ packages: yargs-parser: 21.1.1 dev: true - /ts-loader@9.5.1(typescript@3.9.10)(webpack@5.91.0): - resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==} - engines: {node: '>=12.0.0'} - peerDependencies: - typescript: '*' - webpack: ^5.0.0 - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.16.1 - micromatch: 4.0.7 - semver: 7.6.2 - source-map: 0.7.4 - typescript: 3.9.10 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - dev: true - /ts-loader@9.5.1(typescript@5.6.3)(webpack@5.91.0): resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==} engines: {node: '>=12.0.0'} @@ -33610,9 +28576,9 @@ packages: webpack: ^5.0.0 dependencies: chalk: 4.1.2 - enhanced-resolve: 5.16.1 + enhanced-resolve: 5.17.1 micromatch: 4.0.7 - semver: 7.6.2 + semver: 7.6.3 source-map: 0.7.4 typescript: 5.6.3 webpack: 5.96.1(esbuild@0.23.1) @@ -33638,7 +28604,7 @@ packages: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 20.5.1 - acorn: 8.13.0 + acorn: 8.14.0 acorn-walk: 8.3.2 arg: 4.1.3 create-require: 1.1.1 @@ -33648,43 +28614,20 @@ packages: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - /ts-node@9.1.1(typescript@3.9.10): - resolution: {integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==} - engines: {node: '>=10.0.0'} - hasBin: true - peerDependencies: - typescript: '>=2.7' - dependencies: - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - source-map-support: 0.5.21 - typescript: 3.9.10 - yn: 3.1.1 - dev: true - /ts-toolbelt@6.15.5: resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + dev: false /ts-toolbelt@9.6.0: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} dev: false - /ts-transformer-keys@0.4.4(typescript@3.9.10): - resolution: {integrity: sha512-LrqgvaFvar01/5mbunRyeLTSIkqoC2xfcpL/90aDY6vR07DGyH+UaYGdIEsUudnlAw2Sr0pxFgdZvE0QIyI4qA==} - peerDependencies: - typescript: '>=2.4.1' - dependencies: - typescript: 3.9.10 - dev: false - /tsconfig-paths-webpack-plugin@4.1.0: resolution: {integrity: sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==} engines: {node: '>=10.13.0'} dependencies: chalk: 4.1.2 - enhanced-resolve: 5.16.1 + enhanced-resolve: 5.17.1 tsconfig-paths: 4.2.0 dev: true @@ -33695,6 +28638,7 @@ packages: json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 + dev: false /tsconfig-paths@4.2.0: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} @@ -33722,6 +28666,7 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false /tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} @@ -33729,11 +28674,6 @@ packages: /tslib@2.8.0: resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} - /tsscmp@1.0.6: - resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} - engines: {node: '>=0.6.x'} - dev: false - /tsup@8.3.0(typescript@5.6.3): resolution: {integrity: sha512-ALscEeyS03IomcuNdFdc0YWGVIkwH1Ws7nfTbAPuoILvEV2hpGQAY72LIOjglGo4ShWpZfpBqP/jpQVCzqYQag==} engines: {node: '>=18'} @@ -33777,16 +28717,6 @@ packages: - yaml dev: false - /tsutils@3.21.0(typescript@3.9.10): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 3.9.10 - dev: true - /tsutils@3.21.0(typescript@4.9.5): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -33807,17 +28737,6 @@ packages: typescript: 5.6.3 dev: true - /tsyringe@4.8.0: - resolution: {integrity: sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==} - engines: {node: '>= 6.0.0'} - dependencies: - tslib: 1.14.1 - dev: false - - /tty-browserify@0.0.0: - resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} - dev: true - /tuf-js@1.1.7: resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -33857,11 +28776,6 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - /type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - dev: false - /type-fest@0.16.0: resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} engines: {node: '>=10'} @@ -33874,6 +28788,7 @@ packages: /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + dev: false /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} @@ -33887,10 +28802,12 @@ packages: /type-fest@0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} + dev: true /type-fest@0.8.1: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} + dev: true /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} @@ -33902,14 +28819,6 @@ packages: engines: {node: '>=16'} dev: false - /type-is@1.6.15: - resolution: {integrity: sha512-0uqZYZDiBICTVXEsNcDLueZLPgZ8FgGe8lmVDQ0FcVFUeaxsPbFWiz60ZChVw8VELIt7iGuCehOrZSYjYteWKQ==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - dev: false - /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -33928,6 +28837,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-typed-array: 1.1.13 + dev: false /typed-array-byte-length@1.0.1: resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} @@ -33938,6 +28848,7 @@ packages: gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 + dev: false /typed-array-byte-offset@1.0.2: resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} @@ -33949,6 +28860,7 @@ packages: gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 + dev: false /typed-array-length@1.0.6: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} @@ -33960,6 +28872,7 @@ packages: has-proto: 1.0.3 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 + dev: false /typed-function@2.1.0: resolution: {integrity: sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ==} @@ -33978,10 +28891,6 @@ packages: /typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - /typedi@0.8.0: - resolution: {integrity: sha512-/c7Bxnm6eh5kXx2I+mTuO+2OvoWni5+rXA3PhXwVWCtJRYmz3hMok5s1AKLzoDvNAZqj/Q/acGstN0ri5aQoOA==} - dev: false - /types-ramda@0.30.1: resolution: {integrity: sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==} dependencies: @@ -34006,11 +28915,6 @@ packages: - supports-color dev: true - /typescript@3.9.10: - resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==} - engines: {node: '>=4.2.0'} - hasBin: true - /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} @@ -34043,13 +28947,6 @@ packages: dev: true optional: true - /uid-safe@2.1.5: - resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} - engines: {node: '>= 0.8'} - dependencies: - random-bytes: 1.0.0 - dev: false - /uid@2.0.2: resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} engines: {node: '>=8'} @@ -34063,65 +28960,16 @@ packages: has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - - /unbzip2-stream@1.3.3: - resolution: {integrity: sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==} - dependencies: - buffer: 5.7.1 - through: 2.3.8 - dev: false - - /unc-path-regex@0.1.2: - resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} - engines: {node: '>=0.10.0'} - dev: false - - /undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} dev: false /underscore@1.12.1: resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} dev: false - /undertaker-registry@1.0.1: - resolution: {integrity: sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==} - engines: {node: '>= 0.10'} - dev: false - - /undertaker@1.3.0: - resolution: {integrity: sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==} - engines: {node: '>= 0.10'} - dependencies: - arr-flatten: 1.1.0 - arr-map: 2.0.2 - bach: 1.2.0 - collection-map: 1.0.0 - es6-weak-map: 2.0.3 - fast-levenshtein: 1.1.4 - last-run: 1.1.1 - object.defaults: 1.1.0 - object.reduce: 1.0.1 - undertaker-registry: 1.0.1 - dev: false - /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: true - /unescape-js@1.1.4: - resolution: {integrity: sha512-42SD8NOQEhdYntEiUQdYq/1V/YHwr1HLwlHuTJB5InVVdOSbgI6xu8jK5q65yIzuFCfczzyDF/7hbGzVbyCw0g==} - dependencies: - string.fromcodepoint: 0.2.1 - dev: false - - /unescape@1.0.1: - resolution: {integrity: sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - dev: false - /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -34160,26 +29008,14 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: unique-slug: 4.0.0 + dev: true /unique-slug@4.0.0: resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: imurmurhash: 0.1.4 - - /unique-stream@2.3.1: - resolution: {integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==} - dependencies: - json-stable-stringify-without-jsonify: 1.0.1 - through2-filter: 3.0.0 - dev: false - - /unique-string@1.0.0: - resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==} - engines: {node: '>=4'} - dependencies: - crypto-random-string: 1.0.0 - dev: false + dev: true /unique-string@2.0.0: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} @@ -34265,11 +29101,6 @@ packages: engines: {node: '>=8'} dev: true - /unzip-response@2.0.1: - resolution: {integrity: sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==} - engines: {node: '>=4'} - dev: false - /upath@1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} @@ -34300,22 +29131,6 @@ packages: escalade: 3.2.0 picocolors: 1.1.1 - /update-notifier@2.5.0: - resolution: {integrity: sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==} - engines: {node: '>=4'} - dependencies: - boxen: 1.3.0 - chalk: 2.4.2 - configstore: 3.1.5 - import-lazy: 2.1.0 - is-ci: 1.2.1 - is-installed-globally: 0.1.0 - is-npm: 1.0.0 - latest-version: 3.1.0 - semver-diff: 2.1.0 - xdg-basedir: 3.0.0 - dev: false - /upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} dependencies: @@ -34338,13 +29153,6 @@ packages: deprecated: Please see https://github.com/lydell/urix#deprecated dev: false - /url-parse-lax@1.0.0: - resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} - engines: {node: '>=0.10.0'} - dependencies: - prepend-http: 1.0.4 - dev: false - /url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} dependencies: @@ -34352,13 +29160,6 @@ packages: requires-port: 1.0.0 dev: false - /url@0.11.3: - resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==} - dependencies: - punycode: 1.4.1 - qs: 6.12.1 - dev: true - /use-callback-ref@1.3.2(@types/react@18.3.4)(react@18.3.1): resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} engines: {node: '>=10'} @@ -34418,18 +29219,6 @@ packages: object.getownpropertydescriptors: 2.1.8 dev: false - /util@0.10.4: - resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} - dependencies: - inherits: 2.0.3 - dev: true - - /util@0.11.1: - resolution: {integrity: sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==} - dependencies: - inherits: 2.0.3 - dev: true - /util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} dependencies: @@ -34453,12 +29242,6 @@ packages: hasBin: true dev: false - /uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: true - /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -34489,18 +29272,12 @@ packages: convert-source-map: 2.0.0 dev: true - /v8flags@3.2.0: - resolution: {integrity: sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==} - engines: {node: '>= 0.10'} - dependencies: - homedir-polyfill: 1.0.3 - dev: false - /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + dev: true /validate-npm-package-name@3.0.0: resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} @@ -34523,68 +29300,10 @@ packages: resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} dev: false - /value-or-function@3.0.0: - resolution: {integrity: sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==} - engines: {node: '>= 0.10'} - dev: false - /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - /vinyl-fs@3.0.3: - resolution: {integrity: sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==} - engines: {node: '>= 0.10'} - dependencies: - fs-mkdirp-stream: 1.0.0 - glob-stream: 6.1.0 - graceful-fs: 4.2.11 - is-valid-glob: 1.0.0 - lazystream: 1.0.1 - lead: 1.0.0 - object.assign: 4.1.5 - pumpify: 1.5.1 - readable-stream: 2.3.8 - remove-bom-buffer: 3.0.0 - remove-bom-stream: 1.2.0 - resolve-options: 1.1.0 - through2: 2.0.5 - to-through: 2.0.0 - value-or-function: 3.0.0 - vinyl: 2.2.1 - vinyl-sourcemap: 1.1.0 - dev: false - - /vinyl-sourcemap@1.1.0: - resolution: {integrity: sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==} - engines: {node: '>= 0.10'} - dependencies: - append-buffer: 1.0.2 - convert-source-map: 1.9.0 - graceful-fs: 4.2.11 - normalize-path: 2.1.1 - now-and-later: 2.0.1 - remove-bom-buffer: 3.0.0 - vinyl: 2.2.1 - dev: false - - /vinyl-sourcemaps-apply@0.2.1: - resolution: {integrity: sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==} - dependencies: - source-map: 0.5.7 - - /vinyl@2.2.1: - resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} - engines: {node: '>= 0.10'} - dependencies: - clone: 2.1.2 - clone-buffer: 1.0.0 - clone-stats: 1.0.0 - cloneable-readable: 1.1.3 - remove-trailing-separator: 1.1.0 - replace-ext: 1.0.1 - dev: false - /vite-node@2.1.3(@types/node@20.5.1)(less@4.2.0): resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -34729,10 +29448,6 @@ packages: - terser dev: false - /vm-browserify@1.1.2: - resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} - dev: true - /void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} @@ -34815,45 +29530,6 @@ packages: engines: {node: '>=10.4'} dev: false - /webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - dev: false - - /webpack-cli@4.10.0(webpack@5.91.0): - resolution: {integrity: sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - '@webpack-cli/generators': '*' - '@webpack-cli/migrate': '*' - webpack: 4.x.x || 5.x.x - webpack-bundle-analyzer: '*' - webpack-dev-server: '*' - peerDependenciesMeta: - '@webpack-cli/generators': - optional: true - '@webpack-cli/migrate': - optional: true - webpack-bundle-analyzer: - optional: true - webpack-dev-server: - optional: true - dependencies: - '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 1.2.0(webpack-cli@4.10.0)(webpack@5.91.0) - '@webpack-cli/info': 1.5.0(webpack-cli@4.10.0) - '@webpack-cli/serve': 1.7.0(webpack-cli@4.10.0) - colorette: 2.0.20 - commander: 7.2.0 - cross-spawn: 7.0.3 - fastest-levenshtein: 1.0.16 - import-local: 3.1.0 - interpret: 2.2.0 - rechoir: 0.7.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) - webpack-merge: 5.10.0 - /webpack-cli@5.1.4(webpack@5.91.0): resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} engines: {node: '>=14.15.0'} @@ -34897,7 +29573,7 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) dev: false /webpack-dev-server@4.15.2(webpack@5.91.0): @@ -34927,7 +29603,7 @@ packages: compression: 1.7.4 connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 - express: 4.19.2 + express: 4.21.1 graceful-fs: 4.2.11 html-entities: 2.5.2 http-proxy-middleware: 2.0.6(@types/express@4.17.21) @@ -34941,7 +29617,7 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) webpack-dev-middleware: 5.3.4(webpack@5.91.0) ws: 8.17.0 transitivePeerDependencies: @@ -34958,7 +29634,7 @@ packages: webpack: ^4.44.2 || ^5.47.0 dependencies: tapable: 2.2.1 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) webpack-sources: 2.3.1 dev: false @@ -35004,12 +29680,6 @@ packages: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} dev: true - /webpack-watch-changed@1.0.0: - resolution: {integrity: sha512-CYreNkGzQxRW5mKpij9Mnh/WXSRn9wM9fW16SAD9Gu8yQzdmbk3wVarbnrOl5v90dwWFWIVXPHA+4Z3VjJRHYQ==} - dependencies: - chalk: 2.4.2 - dev: true - /webpack@5.91.0(esbuild@0.18.20)(webpack-cli@5.1.4): resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} engines: {node: '>=10.13.0'} @@ -35050,7 +29720,7 @@ packages: - esbuild - uglify-js - /webpack@5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0): + /webpack@5.91.0(esbuild@0.23.1): resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} engines: {node: '>=10.13.0'} hasBin: true @@ -35083,7 +29753,6 @@ packages: tapable: 2.2.1 terser-webpack-plugin: 5.3.10(esbuild@0.23.1)(webpack@5.91.0) watchpack: 2.4.1 - webpack-cli: 4.10.0(webpack@5.91.0) webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' @@ -35195,22 +29864,6 @@ packages: resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} dev: false - /whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: false - - /whatwg-url@13.0.0: - resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==} - engines: {node: '>=16'} - dependencies: - tr46: 4.1.1 - webidl-conversions: 7.0.0 - dev: false - /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -35270,14 +29923,6 @@ packages: is-weakmap: 2.0.2 is-weakset: 2.0.3 - /which-module@1.0.0: - resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} - dev: false - - /which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - dev: true - /which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -35293,6 +29938,7 @@ packages: hasBin: true dependencies: isexe: 2.0.0 + dev: false /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -35307,6 +29953,7 @@ packages: hasBin: true dependencies: isexe: 3.1.1 + dev: true /why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} @@ -35322,42 +29969,9 @@ packages: dependencies: string-width: 4.2.3 - /widest-line@2.0.1: - resolution: {integrity: sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==} - engines: {node: '>=4'} - dependencies: - string-width: 2.1.1 - dev: false - /wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} - /winston-transport@4.7.0: - resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==} - engines: {node: '>= 12.0.0'} - dependencies: - logform: 2.6.0 - readable-stream: 3.6.2 - triple-beam: 1.4.1 - dev: false - - /winston@3.13.0: - resolution: {integrity: sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==} - engines: {node: '>= 12.0.0'} - dependencies: - '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.3 - async: 3.2.5 - is-stream: 2.0.1 - logform: 2.6.0 - one-time: 1.0.0 - readable-stream: 3.6.2 - safe-stable-stringify: 2.4.3 - stack-trace: 0.0.10 - triple-beam: 1.4.1 - winston-transport: 4.7.0 - dev: false - /with@7.0.2: resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} engines: {node: '>= 10.0.0'} @@ -35403,7 +30017,7 @@ packages: resolution: {integrity: sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==} engines: {node: '>=10.0.0'} dependencies: - '@apideck/better-ajv-errors': 0.3.6(ajv@8.13.0) + '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) '@babel/core': 7.26.0 '@babel/preset-env': 7.24.5(@babel/core@7.26.0) '@babel/runtime': 7.24.5 @@ -35411,7 +30025,7 @@ packages: '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1) '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) '@surma/rollup-plugin-off-main-thread': 2.2.3 - ajv: 8.13.0 + ajv: 8.17.1 common-tags: 1.8.2 fast-json-stable-stringify: 2.1.0 fs-extra: 9.1.0 @@ -35536,7 +30150,7 @@ packages: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0) + webpack: 5.91.0(esbuild@0.23.1) webpack-sources: 1.4.3 workbox-build: 6.6.0 transitivePeerDependencies: @@ -35557,23 +30171,6 @@ packages: microevent.ts: 0.1.1 dev: false - /wrap-ansi@2.1.0: - resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} - engines: {node: '>=0.10.0'} - dependencies: - string-width: 1.0.2 - strip-ansi: 3.0.1 - dev: false - - /wrap-ansi@5.1.0: - resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} - engines: {node: '>=6'} - dependencies: - ansi-styles: 3.2.1 - string-width: 3.1.0 - strip-ansi: 5.2.0 - dev: true - /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -35608,6 +30205,7 @@ packages: graceful-fs: 4.2.11 imurmurhash: 0.1.4 signal-exit: 3.0.7 + dev: true /write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} @@ -35680,19 +30278,6 @@ packages: async-limiter: 1.0.1 dev: true - /ws@7.4.6: - resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /ws@7.5.9: resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} engines: {node: '>=8.3.0'} @@ -35736,11 +30321,6 @@ packages: engines: {node: '>=4.0.0'} dev: false - /xdg-basedir@3.0.0: - resolution: {integrity: sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==} - engines: {node: '>=4'} - dev: false - /xlsx@0.18.5: resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} engines: {node: '>=0.8'} @@ -35779,21 +30359,10 @@ packages: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - /y18n@3.2.2: - resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} - dev: false - - /y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: true - /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - /yallist@2.1.2: - resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} - /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -35808,20 +30377,6 @@ packages: resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} engines: {node: '>= 14'} hasBin: true - - /yargs-parser@13.1.2: - resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - dev: true - - /yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 dev: false /yargs-parser@20.2.9: @@ -35831,27 +30386,6 @@ packages: /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - - /yargs-parser@5.0.1: - resolution: {integrity: sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==} - dependencies: - camelcase: 3.0.0 - object.assign: 4.1.5 - dev: false - - /yargs@13.3.2: - resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} - dependencies: - cliui: 5.0.0 - find-up: 3.0.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 3.1.0 - which-module: 2.0.1 - y18n: 4.0.3 - yargs-parser: 13.1.2 dev: true /yargs@16.2.0: @@ -35877,30 +30411,14 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - - /yargs@7.1.2: - resolution: {integrity: sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==} - dependencies: - camelcase: 3.0.0 - cliui: 3.2.0 - decamelize: 1.2.0 - get-caller-file: 1.0.3 - os-locale: 1.4.0 - read-pkg-up: 1.0.1 - require-directory: 2.1.1 - require-main-filename: 1.0.1 - set-blocking: 2.0.0 - string-width: 1.0.2 - which-module: 1.0.0 - y18n: 3.2.2 - yargs-parser: 5.0.1 - dev: false + dev: true /yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 + dev: true /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} @@ -35910,11 +30428,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - /yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - dev: false - /yup@0.28.5: resolution: {integrity: sha512-7JZcvpUGUxMKoaEtcoMEM8lCWRaueGNH/A3EhL/UWqfbFm3uloiI+x59Yq4nzhbbYWUTwAsCteaZOJ+VbqI1uw==} dependencies: