diff --git a/packages/server/src/modules/Accounts/Accounts.module.ts b/packages/server/src/modules/Accounts/Accounts.module.ts index 6017a3189..42abb8fcf 100644 --- a/packages/server/src/modules/Accounts/Accounts.module.ts +++ b/packages/server/src/modules/Accounts/Accounts.module.ts @@ -18,6 +18,7 @@ import { BankAccount } from '../BankingTransactions/models/BankAccount'; import { GetAccountsService } from './GetAccounts.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { AccountsExportable } from './AccountsExportable.service'; +import { AccountsImportable } from './AccountsImportable.service'; const models = [RegisterTenancyModel(BankAccount)]; @@ -39,12 +40,14 @@ const models = [RegisterTenancyModel(BankAccount)]; GetAccountTransactionsService, GetAccountsService, AccountsExportable, + AccountsImportable ], exports: [ AccountRepository, CreateAccountService, ...models, AccountsExportable, + AccountsImportable ], }) export class AccountsModule {} diff --git a/packages/server/src/modules/Accounts/AccountsImportable.service.ts b/packages/server/src/modules/Accounts/AccountsImportable.service.ts index 84a8fcd5b..dfd0548f6 100644 --- a/packages/server/src/modules/Accounts/AccountsImportable.service.ts +++ b/packages/server/src/modules/Accounts/AccountsImportable.service.ts @@ -4,8 +4,11 @@ import { Importable } from '../Import/Importable'; import { AccountsSampleData } from './AccountsImportable.SampleData'; import { CreateAccountDTO } from './CreateAccount.dto'; import { CreateAccountService } from './CreateAccount.service'; +import { ImportableService } from '../Import/decorators/Import.decorator'; +import { Account } from './models/Account.model'; @Injectable() +@ImportableService({ name: Account.name }) export class AccountsImportable extends Importable { constructor(private readonly createAccountService: CreateAccountService) { super(); diff --git a/packages/server/src/modules/Accounts/models/Account.model.ts b/packages/server/src/modules/Accounts/models/Account.model.ts index 73b3503aa..d4f034607 100644 --- a/packages/server/src/modules/Accounts/models/Account.model.ts +++ b/packages/server/src/modules/Accounts/models/Account.model.ts @@ -13,8 +13,10 @@ import { flatToNestedArray } from '@/utils/flat-to-nested-array'; import { ExportableModel } from '../../Export/decorators/ExportableModel.decorator'; import { AccountMeta } from './Account.meta'; import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; @ExportableModel() +@ImportableModel() @InjectModelMeta(AccountMeta) export class Account extends TenantBaseModel { public name!: string; diff --git a/packages/server/src/modules/BillPayments/BillPayments.module.ts b/packages/server/src/modules/BillPayments/BillPayments.module.ts index 9bd5f345f..f6ce8ce61 100644 --- a/packages/server/src/modules/BillPayments/BillPayments.module.ts +++ b/packages/server/src/modules/BillPayments/BillPayments.module.ts @@ -18,6 +18,7 @@ import { LedgerModule } from '../Ledger/Ledger.module'; import { AccountsModule } from '../Accounts/Accounts.module'; import { BillPaymentsExportable } from './queries/BillPaymentsExportable'; import { GetBillPayments } from '../Bills/queries/GetBillPayments'; +import { BillPaymentsImportable } from './commands/BillPaymentsImportable'; @Module({ imports: [LedgerModule, AccountsModule], @@ -37,9 +38,15 @@ import { GetBillPayments } from '../Bills/queries/GetBillPayments'; BillPaymentGLEntries, BillPaymentGLEntriesSubscriber, GetBillPayments, - BillPaymentsExportable + BillPaymentsExportable, + BillPaymentsImportable, + ], + exports: [ + BillPaymentValidators, + CreateBillPaymentService, + BillPaymentsExportable, + BillPaymentsImportable, ], - exports: [BillPaymentValidators, CreateBillPaymentService], controllers: [BillPaymentsController], }) export class BillPaymentsModule {} diff --git a/packages/server/src/modules/BillPayments/commands/BillPaymentsImportable.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentsImportable.ts index 70d8feb34..ad890f897 100644 --- a/packages/server/src/modules/BillPayments/commands/BillPaymentsImportable.ts +++ b/packages/server/src/modules/BillPayments/commands/BillPaymentsImportable.ts @@ -1,45 +1,49 @@ -// 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'; +import { Injectable } from '@nestjs/common'; +import { Knex } from 'knex'; +import { CreateBillPaymentService } from './CreateBillPayment.service'; +import { Importable } from '@/modules/Import/Importable'; +import { CreateBillPaymentDto } from '../dtos/BillPayment.dto'; +import { BillsPaymentsSampleData } from '../constants'; +import { ImportableService } from '@/modules/Import/decorators/Import.decorator'; +import { BillPayment } from '../models/BillPayment'; -// @Service() -// export class BillPaymentsImportable extends Importable { -// @Inject() -// private createBillPaymentService: CreateBillPayment; +@Injectable() +@ImportableService({ name: BillPayment.name }) +export class BillPaymentsImportable extends Importable { + constructor( + private readonly createBillPaymentService: CreateBillPaymentService + ) { + super(); + } -// /** -// * 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 -// ); -// } + /** + * Importing to account service. + * @param {number} tenantId + * @param {IAccountCreateDTO} createAccountDTO + * @returns + */ + public importable( + billPaymentDTO: CreateBillPaymentDto, + trx?: Knex.Transaction + ) { + return this.createBillPaymentService.createBillPayment( + billPaymentDTO, + trx + ); + } -// /** -// * Concurrrency controlling of the importing process. -// * @returns {number} -// */ -// public get concurrency() { -// return 1; -// } + /** + * 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; -// } -// } + /** + * Retrieves the sample data that used to download accounts sample sheet. + */ + public sampleData(): any[] { + return BillsPaymentsSampleData; + } +} diff --git a/packages/server/src/modules/BillPayments/models/BillPayment.meta.ts b/packages/server/src/modules/BillPayments/models/BillPayment.meta.ts new file mode 100644 index 000000000..cd218a044 --- /dev/null +++ b/packages/server/src/modules/BillPayments/models/BillPayment.meta.ts @@ -0,0 +1,224 @@ +import { Features } from "@/common/types/Features"; + +export const BillPaymentMeta = { + 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, + }, + }, +}; \ No newline at end of file diff --git a/packages/server/src/modules/BillPayments/models/BillPayment.ts b/packages/server/src/modules/BillPayments/models/BillPayment.ts index db27dd530..6b3cbf8fb 100644 --- a/packages/server/src/modules/BillPayments/models/BillPayment.ts +++ b/packages/server/src/modules/BillPayments/models/BillPayment.ts @@ -9,8 +9,15 @@ import { BaseModel } from '@/models/Model'; import { BillPaymentEntry } from './BillPaymentEntry'; import { Vendor } from '@/modules/Vendors/models/Vendor'; import { Document } from '@/modules/ChromiumlyTenancy/models/Document'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; +import { BillPaymentMeta } from './BillPayment.meta'; -export class BillPayment extends BaseModel{ +@ImportableModel() +@ExportableModel() +@InjectModelMeta(BillPaymentMeta) +export class BillPayment extends BaseModel { vendorId: number; amount: number; currencyCode: string; diff --git a/packages/server/src/modules/CreditNotes/CreditNotes.module.ts b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts index 11d61daba..6f6241adb 100644 --- a/packages/server/src/modules/CreditNotes/CreditNotes.module.ts +++ b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts @@ -25,6 +25,7 @@ import { AccountsModule } from '../Accounts/Accounts.module'; import { GetCreditNotesService } from './queries/GetCreditNotes.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { CreditNotesExportable } from './commands/CreditNotesExportable'; +import { CreditNotesImportable } from './commands/CreditNotesImportable'; @Module({ imports: [ @@ -55,6 +56,7 @@ import { CreditNotesExportable } from './commands/CreditNotesExportable'; CreditNoteGLEntries, CreditNoteGLEntriesSubscriber, CreditNotesExportable, + CreditNotesImportable, ], exports: [ CreateCreditNoteService, @@ -69,6 +71,7 @@ import { CreditNotesExportable } from './commands/CreditNotesExportable'; CreditNoteApplication, CreditNoteBrandingTemplate, CreditNotesExportable, + CreditNotesImportable, ], controllers: [CreditNotesController], }) diff --git a/packages/server/src/modules/CreditNotes/commands/CreditNotesImportable.ts b/packages/server/src/modules/CreditNotes/commands/CreditNotesImportable.ts index ba9e4cac8..2fcf55028 100644 --- a/packages/server/src/modules/CreditNotes/commands/CreditNotesImportable.ts +++ b/packages/server/src/modules/CreditNotes/commands/CreditNotesImportable.ts @@ -1,44 +1,45 @@ -// import { Inject, Service } from 'typedi'; -// import { Knex } from 'knex'; -// import { ICreditNoteNewDTO } from '@/interfaces'; -// import { Importable } from '../Import/Importable'; -// import CreateCreditNote from './commands/CreateCreditNote.service'; +import { Knex } from 'knex'; +import { Injectable } from '@nestjs/common'; +import { CreateCreditNoteService } from './CreateCreditNote.service'; +import { Importable } from '@/modules/Import/Importable'; +import { CreateCreditNoteDto } from '../dtos/CreditNote.dto'; +import { ImportableService } from '@/modules/Import/decorators/Import.decorator'; +import { CreditNote } from '../models/CreditNote'; -// @Service() -// export class CreditNotesImportable extends Importable { -// @Inject() -// private createCreditNoteImportable: CreateCreditNote; +@Injectable() +@ImportableService({ name: CreditNote.name }) +export class CreditNotesImportable extends Importable { + constructor( + private readonly createCreditNoteImportable: CreateCreditNoteService, + ) { + super(); + } -// /** -// * 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 -// ); -// } + /** + * Importing to credit note service. + */ + public importable( + createAccountDTO: CreateCreditNoteDto, + trx?: Knex.Transaction, + ) { + return this.createCreditNoteImportable.creditCreditNote( + createAccountDTO, + trx, + ); + } -// /** -// * Concurrrency controlling of the importing process. -// * @returns {number} -// */ -// public get concurrency() { -// return 1; -// } + /** + * 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 []; -// } -// } + /** + * Retrieves the sample data that used to download accounts sample sheet. + */ + public sampleData(): any[] { + return []; + } +} diff --git a/packages/server/src/modules/CreditNotes/models/CreditNote.meta.ts b/packages/server/src/modules/CreditNotes/models/CreditNote.meta.ts new file mode 100644 index 000000000..305252b30 --- /dev/null +++ b/packages/server/src/modules/CreditNotes/models/CreditNote.meta.ts @@ -0,0 +1,249 @@ +import { Features } from "@/common/types/Features"; + +function StatusFieldFilterQuery(query, role) { + query.modify('filterByStatus', role.value); +} + +function StatusFieldSortQuery(query, role) { + query.modify('sortByStatus', role.order); +} + +export const CreditNoteMeta = { + 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, + }, + }, +}; \ No newline at end of file diff --git a/packages/server/src/modules/CreditNotes/models/CreditNote.ts b/packages/server/src/modules/CreditNotes/models/CreditNote.ts index 603338142..ec029ca62 100644 --- a/packages/server/src/modules/CreditNotes/models/CreditNote.ts +++ b/packages/server/src/modules/CreditNotes/models/CreditNote.ts @@ -3,12 +3,17 @@ import { BaseModel } from '@/models/Model'; import { Branch } from '@/modules/Branches/models/Branch.model'; import { Customer } from '@/modules/Customers/models/Customer'; import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry'; import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model'; import { mixin, Model, raw } from 'objection'; +import { CreditNoteMeta } from './CreditNote.meta'; @ExportableModel() +@ImportableModel() +@InjectModelMeta(CreditNoteMeta) export class CreditNote extends TenantBaseModel { public amount: number; public exchangeRate: number; diff --git a/packages/server/src/modules/Expenses/ExpensesImportable.ts b/packages/server/src/modules/Expenses/ExpensesImportable.ts index 3bc85b90f..1767cc241 100644 --- a/packages/server/src/modules/Expenses/ExpensesImportable.ts +++ b/packages/server/src/modules/Expenses/ExpensesImportable.ts @@ -1,27 +1,28 @@ import { Knex } from 'knex'; +import { Injectable } from '@nestjs/common'; import { Importable } from '../Import/Importable'; import { ExpensesSampleData } from './constants'; -import { Injectable } from '@nestjs/common'; import { CreateExpense } from './commands/CreateExpense.service'; import { CreateExpenseDto } from './dtos/Expense.dto'; +import { ImportableService } from '../Import/decorators/Import.decorator'; +import { ManualJournal } from '../ManualJournals/models/ManualJournal'; @Injectable() +@ImportableService({ name: ManualJournal.name }) export class ExpensesImportable extends Importable { constructor(private readonly createExpenseService: CreateExpense) { super(); } /** - * Importing to account service. - * @param {number} tenantId - * @param {IAccountCreateDTO} createAccountDTO - * @returns + * Importing to expense service. + * @param {CreateExpenseDto} createAccountDTO */ public importable( - createAccountDTO: CreateExpenseDto, + createExpenseDto: CreateExpenseDto, trx?: Knex.Transaction, ) { - return this.createExpenseService.newExpense(createAccountDTO, trx); + return this.createExpenseService.newExpense(createExpenseDto, trx); } /** diff --git a/packages/server/src/modules/Expenses/models/Expense.meta.ts b/packages/server/src/modules/Expenses/models/Expense.meta.ts new file mode 100644 index 000000000..1c065d008 --- /dev/null +++ b/packages/server/src/modules/Expenses/models/Expense.meta.ts @@ -0,0 +1,206 @@ +import { Features } from "@/common/types/Features"; + +/** + * Expense - Settings. + */ +export const ExpenseMeta = { + 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); +} \ No newline at end of file diff --git a/packages/server/src/modules/Expenses/models/Expense.model.ts b/packages/server/src/modules/Expenses/models/Expense.model.ts index 6dcc408d3..99305b96e 100644 --- a/packages/server/src/modules/Expenses/models/Expense.model.ts +++ b/packages/server/src/modules/Expenses/models/Expense.model.ts @@ -4,8 +4,13 @@ import { ExpenseCategory } from './ExpenseCategory.model'; import { Account } from '@/modules/Accounts/models/Account.model'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; +import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; +import { ExpenseMeta } from './Expense.meta'; @ExportableModel() +@ImportableModel() +@InjectModelMeta(ExpenseMeta) export class Expense extends TenantBaseModel { totalAmount!: number; currencyCode!: string; diff --git a/packages/server/src/modules/ManualJournals/commands/ManualJournalsImport.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalsImport.ts index 7e4ed8ff3..64985882e 100644 --- a/packages/server/src/modules/ManualJournals/commands/ManualJournalsImport.ts +++ b/packages/server/src/modules/ManualJournals/commands/ManualJournalsImport.ts @@ -1,11 +1,16 @@ import { Knex } from 'knex'; import * as Yup from 'yup'; +import { Injectable } from '@nestjs/common'; import { Importable } from '../../Import/Importable'; import { CreateManualJournalService } from './CreateManualJournal.service'; import { ImportableContext } from '../../Import/interfaces'; import { ManualJournalsSampleData } from '../constants'; import { CreateManualJournalDto } from '../dtos/ManualJournal.dto'; +import { ImportableService } from '@/modules/Import/decorators/Import.decorator'; +import { ManualJournal } from '../models/ManualJournal'; +@Injectable() +@ImportableService({ name: ManualJournal.name }) export class ManualJournalImportable extends Importable { constructor( private readonly createManualJournalService: CreateManualJournalService, diff --git a/packages/server/src/modules/ManualJournals/models/ManualJournal.ts b/packages/server/src/modules/ManualJournals/models/ManualJournal.ts index a8c0e78ef..beaba77e9 100644 --- a/packages/server/src/modules/ManualJournals/models/ManualJournal.ts +++ b/packages/server/src/modules/ManualJournals/models/ManualJournal.ts @@ -12,8 +12,10 @@ import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; import { ManualJournalMeta } from './ManualJournal.meta'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; @ExportableModel() +@ImportableModel() @InjectModelMeta(ManualJournalMeta) export class ManualJournal extends TenantBaseModel { date: Date; diff --git a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts index 45010c89e..8867d8b39 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts @@ -1,4 +1,5 @@ import { Module } from '@nestjs/common'; +import { BullModule } from '@nestjs/bull'; import { PaymentReceivesController } from './PaymentsReceived.controller'; import { PaymentReceivesApplication } from './PaymentReceived.application'; import { CreatePaymentReceivedService } from './commands/CreatePaymentReceived.serivce'; @@ -32,7 +33,6 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { MailModule } from '../Mail/Mail.module'; import { SendPaymentReceivedMailProcessor } from './processors/PaymentReceivedMailNotification.processor'; -import { BullModule } from '@nestjs/bull'; import { SEND_PAYMENT_RECEIVED_MAIL_QUEUE } from './constants'; import { PaymentsReceivedExportable } from './commands/PaymentsReceivedExportable'; import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportable'; @@ -62,12 +62,14 @@ import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportabl SendPaymentReceiveMailNotification, SendPaymentReceivedMailProcessor, PaymentsReceivedExportable, - PaymentsReceivedImportable + PaymentsReceivedImportable, ], exports: [ PaymentReceivesApplication, CreatePaymentReceivedService, PaymentReceivedGLEntries, + PaymentsReceivedExportable, + PaymentsReceivedImportable, ], imports: [ ChromiumlyTenancyModule, diff --git a/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts index abdd81a95..1cc934610 100644 --- a/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts +++ b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts @@ -3,8 +3,11 @@ import { PaymentReceivesApplication } from '../PaymentReceived.application'; import { IPaymentsReceivedFilter } from '../types/PaymentReceived.types'; import { EXPORT_SIZE_LIMIT } from '@/modules/Export/constants'; import { Exportable } from '@/modules/Export/Exportable'; +import { ExportableService } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { PaymentReceived } from '../models/PaymentReceived'; @Injectable() +@ExportableService({ name: PaymentReceived.name }) export class PaymentsReceivedExportable extends Exportable { constructor(private readonly paymentReceivedApp: PaymentReceivesApplication) { super(); diff --git a/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts index d215273fc..32a958720 100644 --- a/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts +++ b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedImportable.ts @@ -4,8 +4,11 @@ import { Injectable } from '@nestjs/common'; import { PaymentsReceiveSampleData } from '../constants'; import { CreatePaymentReceivedService } from './CreatePaymentReceived.serivce'; import { Importable } from '@/modules/Import/Importable'; +import { ImportableService } from '@/modules/Import/decorators/Import.decorator'; +import { PaymentReceived } from '../models/PaymentReceived'; @Injectable() +@ImportableService({ name: PaymentReceived.name }) export class PaymentsReceivedImportable extends Importable { constructor( private readonly createPaymentReceiveService: CreatePaymentReceivedService, diff --git a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.meta.ts b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.meta.ts new file mode 100644 index 000000000..95e299121 --- /dev/null +++ b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.meta.ts @@ -0,0 +1,210 @@ +import { Features } from "@/common/types/Features"; + +export const PaymentReceivedMeta = { + 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, + }, + }, +}; \ No newline at end of file diff --git a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts index 181a910e4..ef3a1a253 100644 --- a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts +++ b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts @@ -2,8 +2,13 @@ import { Model } from 'objection'; import { PaymentReceivedEntry } from './PaymentReceivedEntry'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; +import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; +import { PaymentReceivedMeta } from './PaymentReceived.meta'; @ExportableModel() +@ImportableModel() +@InjectModelMeta(PaymentReceivedMeta) export class PaymentReceived extends TenantBaseModel { customerId: number; paymentDate: string; diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimatesImportable.ts b/packages/server/src/modules/SaleEstimates/SaleEstimatesImportable.ts index 2ba4fca79..f60c8e2a2 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimatesImportable.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimatesImportable.ts @@ -4,8 +4,11 @@ import { SaleEstimatesSampleData } from './constants'; import { Injectable } from '@nestjs/common'; import { CreateSaleEstimateDto } from './dtos/SaleEstimate.dto'; import { Importable } from '../Import/Importable'; +import { ImportableService } from '../Import/decorators/Import.decorator'; +import { SaleEstimate } from './models/SaleEstimate'; @Injectable() +@ImportableService({ name: SaleEstimate.name }) export class SaleEstimatesImportable extends Importable{ constructor( private readonly createEstimateService: CreateSaleEstimate diff --git a/packages/server/src/modules/SaleEstimates/models/SaleEstimate.meta.ts b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.meta.ts new file mode 100644 index 000000000..af394f1a8 --- /dev/null +++ b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.meta.ts @@ -0,0 +1,294 @@ +import { Features } from "@/common/types/Features"; + +export const SaleEstimateMeta = { + 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); +} \ No newline at end of file diff --git a/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts index c772eb544..a7aabd836 100644 --- a/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts +++ b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts @@ -3,8 +3,13 @@ import { Model } from 'objection'; import { Injectable } from '@nestjs/common'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; +import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; +import { SaleEstimateMeta } from './SaleEstimate.meta'; @ExportableModel() +@ImportableModel() +@InjectModelMeta(SaleEstimateMeta) export class SaleEstimate extends TenantBaseModel { exchangeRate!: number; amount!: number; diff --git a/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts b/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts index 6e4e6cee6..af299cea4 100644 --- a/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts +++ b/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesImportable.ts @@ -4,8 +4,11 @@ import { CreateSaleInvoice } from './CreateSaleInvoice.service'; import { Importable } from '@/modules/Import/Importable'; import { CreateSaleInvoiceDto } from '../dtos/SaleInvoice.dto'; import { SaleInvoicesSampleData } from '../constants'; +import { ImportableService } from '@/modules/Import/decorators/Import.decorator'; +import { ManualJournal } from '@/modules/ManualJournals/models/ManualJournal'; @Injectable() +@ImportableService({ name: ManualJournal.name }) export class SaleInvoicesImportable extends Importable { constructor(private readonly createInvoiceService: CreateSaleInvoice) { super(); diff --git a/packages/server/src/modules/VendorCredit/VendorCredits.module.ts b/packages/server/src/modules/VendorCredit/VendorCredits.module.ts index 915119f4a..5ef29d008 100644 --- a/packages/server/src/modules/VendorCredit/VendorCredits.module.ts +++ b/packages/server/src/modules/VendorCredit/VendorCredits.module.ts @@ -20,12 +20,13 @@ import { VendorCreditGlEntriesSubscriber } from './subscribers/VendorCreditGLEnt import { VendorCreditGLEntries } from './commands/VendorCreditGLEntries'; import { LedgerModule } from '../Ledger/Ledger.module'; import { AccountsModule } from '../Accounts/Accounts.module'; -import VendorCreditInventoryTransactionsSubscriber from './subscribers/VendorCreditInventoryTransactionsSusbcriber'; +import { VendorCreditInventoryTransactionsSubscriber } from './subscribers/VendorCreditInventoryTransactionsSusbcriber'; import { VendorCreditInventoryTransactions } from './commands/VendorCreditInventoryTransactions'; import { GetVendorCreditsService } from './queries/GetVendorCredits.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; import { VendorCreditsExportable } from './commands/VendorCreditsExportable'; +import { VendorCreditsImportable } from './commands/VendorCreditsImportable'; @Module({ imports: [ @@ -39,7 +40,7 @@ import { VendorCreditsExportable } from './commands/VendorCreditsExportable'; LedgerModule, AccountsModule, DynamicListModule, - InventoryCostModule + InventoryCostModule, ], providers: [ CreateVendorCreditService, @@ -56,7 +57,8 @@ import { VendorCreditsExportable } from './commands/VendorCreditsExportable'; VendorCreditGlEntriesSubscriber, VendorCreditInventoryTransactions, VendorCreditInventoryTransactionsSubscriber, - VendorCreditsExportable + VendorCreditsExportable, + VendorCreditsImportable, ], exports: [ CreateVendorCreditService, @@ -67,7 +69,9 @@ import { VendorCreditsExportable } from './commands/VendorCreditsExportable'; GetRefundVendorCreditService, GetVendorCreditService, VendorCreditsApplicationService, - OpenVendorCreditService + OpenVendorCreditService, + VendorCreditsExportable, + VendorCreditsImportable, ], controllers: [VendorCreditsController], }) diff --git a/packages/server/src/modules/VendorCredit/commands/VendorCreditsImportable.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditsImportable.ts index 922da3bc6..e5006bf27 100644 --- a/packages/server/src/modules/VendorCredit/commands/VendorCreditsImportable.ts +++ b/packages/server/src/modules/VendorCredit/commands/VendorCreditsImportable.ts @@ -1,45 +1,49 @@ -// import { Inject, Service } from 'typedi'; -// import { Knex } from 'knex'; -// import { Importable } from '@/services/Import/Importable'; -// import CreateVendorCredit from './CreateVendorCredit.service'; -// import { IVendorCreditCreateDTO } from '@/interfaces'; -// import { VendorCreditsSampleData } from '../constants'; +import { Knex } from 'knex'; +import { VendorCreditsSampleData } from '../constants'; +import { Injectable } from '@nestjs/common'; +import { CreateVendorCreditService } from './CreateVendorCredit.service'; +import { CreateVendorCreditDto } from '../dtos/VendorCredit.dto'; +import { Importable } from '@/modules/Import/Importable'; +import { ImportableService } from '@/modules/Import/decorators/Import.decorator'; +import { VendorCredit } from '../models/VendorCredit'; -// @Service() -// export class VendorCreditsImportable extends Importable { -// @Inject() -// private createVendorCreditService: CreateVendorCredit; +@Injectable() +@ImportableService({ name: VendorCredit.name }) +export class VendorCreditsImportable extends Importable { + constructor( + private readonly createVendorCreditService: CreateVendorCreditService, + ) { + super() + } -// /** -// * 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 -// ); -// } + /** + * Importing to account service. + * @param {number} tenantId + * @param {IAccountCreateDTO} createAccountDTO + * @returns + */ + public importable( + createPaymentDTO: CreateVendorCreditDto, + trx?: Knex.Transaction + ) { + return this.createVendorCreditService.newVendorCredit( + createPaymentDTO, + trx + ); + } -// /** -// * Concurrrency controlling of the importing process. -// * @returns {number} -// */ -// public get concurrency() { -// return 1; -// } + /** + * 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; -// } -// } + /** + * Retrieves the sample data that used to download accounts sample sheet. + */ + public sampleData(): any[] { + return VendorCreditsSampleData; + } +} diff --git a/packages/server/src/modules/VendorCredit/models/VendorCredit.meta.ts b/packages/server/src/modules/VendorCredit/models/VendorCredit.meta.ts new file mode 100644 index 000000000..e3321d57a --- /dev/null +++ b/packages/server/src/modules/VendorCredit/models/VendorCredit.meta.ts @@ -0,0 +1,259 @@ +import { Features } from '@/common/types/Features'; + +function StatusFieldFilterQuery(query, role) { + query.modify('filterByStatus', role.value); +} + +function StatusFieldSortQuery(query, role) { + query.modify('sortByStatus', role.order); +} + +export const VendorCreditMeta = { + 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 + }, + }, +}; \ No newline at end of file diff --git a/packages/server/src/modules/VendorCredit/models/VendorCredit.ts b/packages/server/src/modules/VendorCredit/models/VendorCredit.ts index 1dfbbac29..009918ab0 100644 --- a/packages/server/src/modules/VendorCredit/models/VendorCredit.ts +++ b/packages/server/src/modules/VendorCredit/models/VendorCredit.ts @@ -6,8 +6,13 @@ import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry'; import { DiscountType } from '@/common/types/Discount'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { ImportableModel } from '@/modules/Import/decorators/Import.decorator'; +import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator'; +import { VendorCreditMeta } from './VendorCredit.meta'; @ExportableModel() +@ImportableModel() +@InjectModelMeta(VendorCreditMeta) export class VendorCredit extends TenantBaseModel { vendorId: number; amount: number; diff --git a/packages/server/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts b/packages/server/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts index a7619b625..ff1d14de8 100644 --- a/packages/server/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts +++ b/packages/server/src/modules/VendorCredit/subscribers/VendorCreditInventoryTransactionsSusbcriber.ts @@ -9,7 +9,7 @@ import { Injectable } from '@nestjs/common'; import { events } from '@/common/events/events'; @Injectable() -export default class VendorCreditInventoryTransactionsSubscriber { +export class VendorCreditInventoryTransactionsSubscriber { constructor( private readonly inventoryTransactions: VendorCreditInventoryTransactions, ) {}