diff --git a/packages/server/src/api/controllers/Accounts.ts b/packages/server/src/api/controllers/Accounts.ts index d377b2b0a..001a5edb7 100644 --- a/packages/server/src/api/controllers/Accounts.ts +++ b/packages/server/src/api/controllers/Accounts.ts @@ -349,7 +349,7 @@ export default class AccountsController extends BaseController { // Filter query. const filter = { sortOrder: 'desc', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', inactiveMode: false, structure: IAccountsStructureType.Tree, ...this.matchedQueryData(req), diff --git a/packages/server/src/api/controllers/Contacts/Customers.ts b/packages/server/src/api/controllers/Contacts/Customers.ts index 3615cb6dc..41fafdd67 100644 --- a/packages/server/src/api/controllers/Contacts/Customers.ts +++ b/packages/server/src/api/controllers/Contacts/Customers.ts @@ -289,7 +289,7 @@ export default class CustomersController extends ContactsController { const filter = { inactiveMode: false, sortOrder: 'desc', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', page: 1, pageSize: 12, ...this.matchedQueryData(req), diff --git a/packages/server/src/api/controllers/Contacts/Vendors.ts b/packages/server/src/api/controllers/Contacts/Vendors.ts index e02e9a2c4..679719a0f 100644 --- a/packages/server/src/api/controllers/Contacts/Vendors.ts +++ b/packages/server/src/api/controllers/Contacts/Vendors.ts @@ -272,7 +272,7 @@ export default class VendorsController extends ContactsController { const vendorsFilter: IVendorsFilter = { inactiveMode: false, sortOrder: 'desc', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', page: 1, pageSize: 12, ...this.matchedQueryData(req), diff --git a/packages/server/src/api/controllers/Expenses/Expenses.ts b/packages/server/src/api/controllers/Expenses/Expenses.ts index 5d6fbe327..fe3746910 100644 --- a/packages/server/src/api/controllers/Expenses/Expenses.ts +++ b/packages/server/src/api/controllers/Expenses/Expenses.ts @@ -317,7 +317,7 @@ export class ExpensesController extends BaseController { const { tenantId } = req; const filter = { sortOrder: 'desc', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', page: 1, pageSize: 12, ...this.matchedQueryData(req), diff --git a/packages/server/src/api/controllers/Items/Items.ts b/packages/server/src/api/controllers/Items/Items.ts index fda90b80e..a77f991e9 100644 --- a/packages/server/src/api/controllers/Items/Items.ts +++ b/packages/server/src/api/controllers/Items/Items.ts @@ -344,7 +344,7 @@ export default class ItemsController extends BaseController { const filter = { sortOrder: 'DESC', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', page: 1, pageSize: 12, inactiveMode: false, diff --git a/packages/server/src/api/controllers/ManualJournals.ts b/packages/server/src/api/controllers/ManualJournals.ts index a7ff994e8..8af8c13b5 100644 --- a/packages/server/src/api/controllers/ManualJournals.ts +++ b/packages/server/src/api/controllers/ManualJournals.ts @@ -328,7 +328,7 @@ export default class ManualJournalsController extends BaseController { const { tenantId } = req; const filter = { sortOrder: 'desc', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', page: 1, pageSize: 12, ...this.matchedQueryData(req), diff --git a/packages/server/src/api/controllers/Sales/SalesInvoices.ts b/packages/server/src/api/controllers/Sales/SalesInvoices.ts index b8ee3a6e2..b45604e43 100644 --- a/packages/server/src/api/controllers/Sales/SalesInvoices.ts +++ b/packages/server/src/api/controllers/Sales/SalesInvoices.ts @@ -459,7 +459,7 @@ export default class SaleInvoicesController extends BaseController { const { tenantId } = req; const filter = { sortOrder: 'desc', - columnSortBy: 'createdAt', + columnSortBy: 'created_at', page: 1, pageSize: 12, ...this.matchedQueryData(req), diff --git a/packages/server/src/models/Account.Settings.ts b/packages/server/src/models/Account.Settings.ts index 9ea061df3..5fb8ea8a7 100644 --- a/packages/server/src/models/Account.Settings.ts +++ b/packages/server/src/models/Account.Settings.ts @@ -12,18 +12,11 @@ export default { name: 'account.field.name', column: 'name', fieldType: 'text', - unique: true, - required: true, - importable: true, - exportable: true, - order: 1, }, description: { name: 'account.field.description', column: 'description', fieldType: 'text', - importable: true, - exportable: true, }, slug: { name: 'account.field.slug', @@ -31,20 +24,13 @@ export default { fieldType: 'text', columnable: false, filterable: false, - importable: false, }, code: { name: 'account.field.code', column: 'code', fieldType: 'text', - exportable: true, - importable: true, - minLength: 3, - maxLength: 6, - unique: true, - importHint: 'Unique number to identify the account.', }, - rootType: { + root_type: { name: 'account.field.root_type', fieldType: 'enumeration', options: [ @@ -56,7 +42,6 @@ export default { ], filterCustomQuery: RootTypeFieldFilterQuery, sortable: false, - importable: false, }, normal: { name: 'account.field.normal', @@ -67,9 +52,8 @@ export default { ], filterCustomQuery: NormalTypeFieldFilterQuery, sortable: false, - importable: false, }, - accountType: { + type: { name: 'account.field.type', column: 'account_type', fieldType: 'enumeration', @@ -77,46 +61,28 @@ export default { label: accountType.label, key: accountType.key, })), - required: true, - importable: true, - exportable: true, - order: 2, }, active: { name: 'account.field.active', column: 'active', fieldType: 'boolean', filterable: false, - exportable: true, - importable: true, }, balance: { name: 'account.field.balance', column: 'amount', fieldType: 'number', - importable: false, }, - currencyCode: { + currency: { name: 'account.field.currency', column: 'currency_code', fieldType: 'text', filterable: false, - importable: true, - exportable: true, }, - parentAccount: { - name: 'account.field.parent_account', - column: 'parent_account_id', - fieldType: 'relation', - to: { model: 'Account', to: 'id' }, - importable: false, - }, - createdAt: { + created_at: { name: 'account.field.created_at', column: 'created_at', fieldType: 'date', - importable: false, - exportable: true, }, }, fields2: { diff --git a/packages/server/src/models/CreditNote.Meta.ts b/packages/server/src/models/CreditNote.Meta.ts index c28081d87..16f9c13a7 100644 --- a/packages/server/src/models/CreditNote.Meta.ts +++ b/packages/server/src/models/CreditNote.Meta.ts @@ -12,6 +12,10 @@ export default { sortOrder: 'DESC', sortField: 'name', }, + importable: true, + importAggregator: 'group', + importAggregateOn: 'entries', + importAggregateBy: 'creditNoteNumber', fields: { customer: { name: 'credit_note.field.customer', @@ -77,10 +81,6 @@ export default { fieldType: 'date', }, }, - importable: true, - importAggregator: 'group', - importAggregateOn: 'entries', - importAggregateBy: 'creditNoteNumber', fields2: { customerId: { name: 'Customer', @@ -125,7 +125,7 @@ export default { collectionMinLength: 1, fields: { itemId: { - name: 'Item', + name: 'Item', fieldType: 'relation', relationModel: 'Item', relationImportMatch: ['name', 'code'], diff --git a/packages/server/src/models/Customer.Settings.ts b/packages/server/src/models/Customer.Settings.ts index 10ef4ac1e..fa7bcc2d2 100644 --- a/packages/server/src/models/Customer.Settings.ts +++ b/packages/server/src/models/Customer.Settings.ts @@ -3,213 +3,91 @@ export default { defaultFilterField: 'displayName', defaultSort: { sortOrder: 'DESC', - sortField: 'createdAt', + sortField: 'created_at', }, fields: { - customerType: { - name: 'Customer Type', - column: 'contact_type', - fieldType: 'enumeration', - options: [ - { key: 'business', label: 'Business' }, - { key: 'individual', label: 'Individual' }, - ], - importable: true, - required: true, - }, - firstName: { - name: 'customer.field.first_name', + first_name: { + name: 'vendor.field.first_name', column: 'first_name', fieldType: 'text', - importable: true, }, - lastName: { - name: 'customer.field.last_name', + last_name: { + name: 'vendor.field.last_name', column: 'last_name', fieldType: 'text', - importable: true, }, - displayName: { - name: 'customer.field.display_name', + display_name: { + name: 'vendor.field.display_name', column: 'display_name', fieldType: 'text', - required: true, - importable: true, }, email: { - name: 'customer.field.email', + name: 'vendor.field.email', column: 'email', fieldType: 'text', - importable: true, }, - workPhone: { - name: 'customer.field.work_phone', + work_phone: { + name: 'vendor.field.work_phone', column: 'work_phone', fieldType: 'text', - importable: true, }, - personalPhone: { - name: 'customer.field.personal_phone', + personal_phone: { + name: 'vendor.field.personal_pone', column: 'personal_phone', fieldType: 'text', - importable: true, }, - companyName: { - name: 'customer.field.company_name', + company_name: { + name: 'vendor.field.company_name', column: 'company_name', fieldType: 'text', - importable: true, }, website: { - name: 'customer.field.website', + name: 'vendor.field.website', column: 'website', - fieldType: 'url', - importable: true, + fieldType: 'text', + }, + created_at: { + name: 'vendor.field.created_at', + column: 'created_at', + fieldType: 'date', }, balance: { - name: 'customer.field.balance', + name: 'vendor.field.balance', column: 'balance', fieldType: 'number', }, - openingBalance: { - name: 'customer.field.opening_balance', + opening_balance: { + name: 'vendor.field.opening_balance', column: 'opening_balance', fieldType: 'number', - importable: true, }, - openingBalanceAt: { - name: 'customer.field.opening_balance_at', + opening_balance_at: { + name: 'vendor.field.opening_balance_at', column: 'opening_balance_at', - filterable: false, fieldType: 'date', - importable: true, }, - openingBalanceExchangeRate: { - name: 'Opening Balance Ex. Rate', - column: 'opening_balance_exchange_rate', - fieldType: 'number', - importable: true, - }, - currencyCode: { - name: 'customer.field.currency', + currency_code: { + name: 'vendor.field.currency', column: 'currency_code', fieldType: 'text', - importable: true, - }, - note: { - name: 'Note', - column: 'note', - fieldType: 'text', - importable: true, - }, - active: { - name: 'Active', - column: 'active', - fieldType: 'boolean', - importable: true, }, status: { - name: 'customer.field.status', - fieldType: 'enumeration', + name: 'vendor.field.status', + type: 'enumeration', options: [ - { key: 'active', label: 'customer.field.status.active' }, - { key: 'inactive', label: 'customer.field.status.inactive' }, - { key: 'overdue', label: 'customer.field.status.overdue' }, - { key: 'unpaid', label: 'customer.field.status.unpaid' }, + { key: 'overdue', label: 'vendor.field.status.overdue' }, + { key: 'unpaid', label: 'vendor.field.status.unpaid' }, ], - filterCustomQuery: statusFieldFilterQuery, - }, - // Billing Address - billingAddress1: { - name: 'Billing Address 1', - column: 'billing_address1', - fieldType: 'text', - importable: true, - }, - billingAddress2: { - name: 'Billing Address 2', - column: 'billing_address2', - fieldType: 'text', - importable: true, - }, - billingAddressCity: { - name: 'Billing Address City', - column: 'billing_address_city', - fieldType: 'text', - importable: true, - }, - billingAddressCountry: { - name: 'Billing Address Country', - column: 'billing_address_country', - fieldType: 'text', - importable: true, - }, - billingAddressPostcode: { - name: 'Billing Address Postcode', - column: 'billing_address_postcode', - fieldType: 'text', - importable: true, - }, - billingAddressState: { - name: 'Billing Address State', - column: 'billing_address_state', - fieldType: 'text', - importable: true, - }, - billingAddressPhone: { - name: 'Billing Address Phone', - column: 'billing_address_phone', - fieldType: 'text', - importable: true, - }, - // Shipping Address - shippingAddress1: { - name: 'Shipping Address 1', - column: 'shipping_address1', - fieldType: 'text', - importable: true, - }, - shippingAddress2: { - name: 'Shipping Address 2', - column: 'shipping_address2', - fieldType: 'text', - importable: true, - }, - shippingAddressCity: { - name: 'Shipping Address City', - column: 'shipping_address_city', - fieldType: 'text', - importable: true, - }, - shippingAddressCountry: { - name: 'Shipping Address Country', - column: 'shipping_address_country', - fieldType: 'text', - importable: true, - }, - shippingAddressPostcode: { - name: 'Shipping Address Postcode', - column: 'shipping_address_postcode', - fieldType: 'text', - importable: true, - }, - shippingAddressPhone: { - name: 'Shipping Address Phone', - column: 'shipping_address_phone', - fieldType: 'text', - importable: true, - }, - shippingAddressState: { - name: 'Shipping Address State', - column: 'shipping_address_state', - fieldType: 'text', - importable: true, - }, - // - createdAt: { - name: 'customer.field.created_at', - column: 'created_at', - fieldType: 'date', + filterCustomQuery: (query, role) => { + switch (role.value) { + case 'overdue': + query.modify('overdue'); + break; + case 'unpaid': + query.modify('unpaid'); + break; + } + }, }, }, fields2: { diff --git a/packages/server/src/models/Expense.Settings.ts b/packages/server/src/models/Expense.Settings.ts index e56089560..75b395a79 100644 --- a/packages/server/src/models/Expense.Settings.ts +++ b/packages/server/src/models/Expense.Settings.ts @@ -55,7 +55,7 @@ export default { filterCustomQuery: StatusFieldFilterQuery, sortCustomQuery: StatusFieldSortQuery, }, - createdAt: { + created_at: { name: 'expense.field.created_at', column: 'created_at', fieldType: 'date', @@ -66,7 +66,7 @@ export default { name: 'expense.field.payment_account', fieldType: 'relation', relationModel: 'Account', - relationImportMatch: ['name', 'code'], + relationImportMatch: ['name', 'code'], required: true, }, referenceNo: { diff --git a/packages/server/src/models/Item.Settings.ts b/packages/server/src/models/Item.Settings.ts index 740bd9b16..7447ff3d3 100644 --- a/packages/server/src/models/Item.Settings.ts +++ b/packages/server/src/models/Item.Settings.ts @@ -5,96 +5,6 @@ export default { sortField: 'name', sortOrder: 'DESC', }, - 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, - unique: true, - }, - code: { - name: 'item.field.code', - fieldType: 'text', - unique: true, - }, - sellable: { - name: 'item.field.sellable', - fieldType: 'boolean', - required: true, - }, - purchasable: { - name: 'item.field.purchasable', - fieldType: 'boolean', - required: true, - }, - sellPrice: { - name: 'item.field.sell_price', - fieldType: 'number', - required: true, - }, - costPrice: { - name: 'item.field.cost_price', - fieldType: 'number', - required: true, - }, - costAccount: { - name: 'item.field.cost_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - }, - sellAccount: { - name: 'item.field.sell_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - }, - inventoryAccount: { - name: 'item.field.inventory_account', - fieldType: 'relation', - relationModel: 'Account', - relationImportMatch: ['name', 'code'], - required: true, - }, - sellDescription: { - name: 'Sell description', - column: 'sell_description', - fieldType: 'text', - }, - purchaseDescription: { - name: 'Purchase description', - column: 'purchase_description', - fieldType: 'text', - importable: true, - }, - note: { - name: 'item.field.note', - fieldType: 'text', - }, - category: { - name: 'item.field.category', - fieldType: 'relation', - relationModel: 'ItemCategory', - relationImportMatch: 'name', - }, - active: { - name: 'item.field.active', - fieldType: 'boolean', - importable: true, - }, - }, fields: { type: { name: 'item.field.type', @@ -105,109 +15,80 @@ export default { { key: 'service', label: 'item.field.type.service' }, { key: 'non-inventory', label: 'item.field.type.non-inventory' }, ], - importable: true, - required: true, }, name: { name: 'item.field.name', column: 'name', fieldType: 'text', - importable: true, - required: true, - unique: true, }, code: { name: 'item.field.code', column: 'code', fieldType: 'text', - importable: true, }, sellable: { name: 'item.field.sellable', column: 'sellable', fieldType: 'boolean', - importable: true, - required: true, }, purchasable: { name: 'item.field.purchasable', column: 'purchasable', fieldType: 'boolean', - importable: true, - required: true, }, - sellPrice: { - name: 'item.field.sell_price', + sell_price: { + name: 'item.field.cost_price', column: 'sell_price', fieldType: 'number', - importable: true, - required: true, }, - costPrice: { - name: 'item.field.cost_price', + cost_price: { + name: 'item.field.cost_account', column: 'cost_price', fieldType: 'number', - importable: true, - required: true, }, - costAccount: { - name: 'item.field.cost_account', + cost_account: { + name: 'item.field.sell_account', column: 'cost_account_id', fieldType: 'relation', + relationType: 'enumeration', relationKey: 'costAccount', relationEntityLabel: 'name', relationEntityKey: 'slug', - - importableRelationLabel: ['name', 'code'], - importable: true, - required: true, }, - sellAccount: { - name: 'item.field.sell_account', + sell_account: { + name: 'item.field.sell_description', column: 'sell_account_id', fieldType: 'relation', + relationType: 'enumeration', relationKey: 'sellAccount', - relationType: 'one-to-many', relationEntityLabel: 'name', relationEntityKey: 'slug', - - importableRelationLabel: ['name', 'code'], - importable: true, - - required: true, }, - inventoryAccount: { + inventory_account: { name: 'item.field.inventory_account', column: 'inventory_account_id', - fieldType: 'relation', + relationType: 'enumeration', relationKey: 'inventoryAccount', relationEntityLabel: 'name', relationEntityKey: 'slug', - - importableRelationLabel: ['name', 'code'], - importable: true, - - required: true, }, - sellDescription: { + sell_description: { name: 'Sell description', column: 'sell_description', fieldType: 'text', - importable: true, }, - purchaseDescription: { + purchase_description: { name: 'Purchase description', column: 'purchase_description', fieldType: 'text', - importable: true, }, - quantityOnHand: { + quantity_on_hand: { name: 'item.field.quantity_on_hand', column: 'quantity_on_hand', fieldType: 'number', @@ -216,28 +97,140 @@ export default { name: 'item.field.note', column: 'note', fieldType: 'text', - importable: true, }, category: { name: 'item.field.category', column: 'category_id', - fieldType: 'relation', + relationType: 'enumeration', relationKey: 'category', relationEntityLabel: 'name', relationEntityKey: 'id', - - importableRelationLabel: 'name', - importable: true, }, active: { name: 'item.field.active', column: 'active', fieldType: 'boolean', - importable: true, + filterable: false, }, - createdAt: { + created_at: { + name: 'item.field.created_at', + column: 'created_at', + columnType: 'date', + fieldType: 'date', + }, + }, + fields2: { + 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.cost_price', + column: 'sell_price', + fieldType: 'number', + }, + cost_price: { + name: 'item.field.cost_account', + column: 'cost_price', + fieldType: 'number', + }, + cost_account: { + name: 'item.field.sell_account', + column: 'cost_account_id', + fieldType: 'relation', + + relationType: 'enumeration', + relationKey: 'costAccount', + + relationEntityLabel: 'name', + relationEntityKey: 'slug', + }, + sell_account: { + name: 'item.field.sell_description', + 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', diff --git a/packages/server/src/models/ItemCategory.Settings.ts b/packages/server/src/models/ItemCategory.Settings.ts index c0d329f0f..32a29cd10 100644 --- a/packages/server/src/models/ItemCategory.Settings.ts +++ b/packages/server/src/models/ItemCategory.Settings.ts @@ -10,13 +10,11 @@ export default { name: 'item_category.field.name', column: 'name', fieldType: 'text', - importable: true, }, description: { name: 'item_category.field.description', column: 'description', fieldType: 'text', - importable: true, }, count: { name: 'item_category.field.count', diff --git a/packages/server/src/models/ManualJournal.Settings.ts b/packages/server/src/models/ManualJournal.Settings.ts index 210f07682..11409e1aa 100644 --- a/packages/server/src/models/ManualJournal.Settings.ts +++ b/packages/server/src/models/ManualJournal.Settings.ts @@ -13,23 +13,18 @@ export default { name: 'manual_journal.field.date', column: 'date', fieldType: 'date', - importable: true, - required: true, }, - journalNumber: { + journal_number: { name: 'manual_journal.field.journal_number', column: 'journal_number', fieldType: 'text', - importable: true, - required: true, }, reference: { name: 'manual_journal.field.reference', column: 'reference', fieldType: 'text', - importable: true, }, - journalType: { + journal_type: { name: 'manual_journal.field.journal_type', column: 'journal_type', fieldType: 'text', @@ -43,63 +38,6 @@ export default { name: 'manual_journal.field.description', column: 'description', fieldType: 'text', - importable: true, - }, - entries: { - name: 'Entries', - fieldType: 'collection', - collectionOf: 'object', - collectionMinLength: 2, - required: true, - importable: true, - filterable: false, - fields: { - credit: { - name: 'Credit', - fieldType: 'number', - importable: true, - required: true, - }, - debit: { - name: 'Debit', - fieldType: 'number', - importable: true, - required: true, - }, - accountId: { - name: 'Account', - fieldType: 'relation', - - relationKey: 'account', - relationModel: 'Account', - - importable: true, - required: true, - importableRelationLabel: ['name', 'code'], - }, - contactId: { - name: 'Contact', - fieldType: 'relation', - - relationKey: 'contact', - relationModel: 'Contact', - - required: false, - - importable: true, - importableRelationLabel: 'displayName', - }, - note: { - name: 'Note', - fieldType: 'text', - importable: true, - }, - }, - }, - publish: { - name: 'Publish', - fieldType: 'boolean', - importable: true, }, status: { name: 'manual_journal.field.status', @@ -112,7 +50,7 @@ export default { filterCustomQuery: StatusFieldFilterQuery, sortCustomQuery: StatusFieldSortQuery, }, - createdAt: { + created_at: { name: 'manual_journal.field.created_at', column: 'created_at', fieldType: 'date', @@ -132,7 +70,6 @@ export default { reference: { name: 'manual_journal.field.reference', fieldType: 'text', - importable: true, }, journalType: { name: 'manual_journal.field.journal_type', diff --git a/packages/server/src/models/SaleInvoice.Settings.ts b/packages/server/src/models/SaleInvoice.Settings.ts index f8b7c8136..0bdab53a2 100644 --- a/packages/server/src/models/SaleInvoice.Settings.ts +++ b/packages/server/src/models/SaleInvoice.Settings.ts @@ -2,7 +2,7 @@ export default { defaultFilterField: 'customer', defaultSort: { sortOrder: 'DESC', - sortField: 'createdAt', + sortField: 'created_at', }, importable: true, importAggregator: 'group', @@ -81,7 +81,7 @@ export default { filterCustomQuery: StatusFieldFilterQuery, sortCustomQuery: StatusFieldSortQuery, }, - createdAt: { + created_at: { name: 'invoice.field.created_at', column: 'created_at', fieldType: 'date', diff --git a/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts b/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts index 10cced266..2a6529c0d 100644 --- a/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts +++ b/packages/server/src/models/UncategorizedCashflowTransaction.meta.ts @@ -2,7 +2,7 @@ export default { defaultFilterField: 'createdAt', defaultSort: { sortOrder: 'DESC', - sortField: 'createdAt', + sortField: 'created_at', }, importable: true, fields: { @@ -10,33 +10,27 @@ export default { name: 'Date', column: 'date', fieldType: 'date', - importable: true, - required: true, }, payee: { name: 'Payee', column: 'payee', fieldType: 'text', - importable: true, }, description: { name: 'Description', column: 'description', fieldType: 'text', - importable: true, }, referenceNo: { name: 'Reference No.', column: 'reference_no', fieldType: 'text', - importable: true, }, amount: { name: 'Amount', column: 'Amount', fieldType: 'numeric', required: true, - importable: true, }, account: { name: 'Account', @@ -78,6 +72,5 @@ export default { fieldType: 'numeric', required: true, }, - - } + }, }; diff --git a/packages/server/src/models/Vendor.Settings.ts b/packages/server/src/models/Vendor.Settings.ts index 9551be723..7f22d5ba4 100644 --- a/packages/server/src/models/Vendor.Settings.ts +++ b/packages/server/src/models/Vendor.Settings.ts @@ -2,99 +2,74 @@ export default { defaultFilterField: 'displayName', defaultSort: { sortOrder: 'DESC', - sortField: 'createdAt', + sortField: 'created_at', }, importable: true, fields: { - firstName: { + first_name: { name: 'vendor.field.first_name', column: 'first_name', fieldType: 'text', - importable: true, }, - lastName: { + last_name: { name: 'vendor.field.last_name', column: 'last_name', fieldType: 'text', - importable: true, }, - displayName: { + display_name: { name: 'vendor.field.display_name', column: 'display_name', fieldType: 'text', - required: true, - importable: true, }, email: { name: 'vendor.field.email', column: 'email', fieldType: 'text', - importable: true, }, - workPhone: { + work_phone: { name: 'vendor.field.work_phone', column: 'work_phone', fieldType: 'text', - importable: true, }, - personalPhone: { - name: 'vendor.field.personal_phone', + personal_phone: { + name: 'vendor.field.personal_pone', column: 'personal_phone', fieldType: 'text', - importable: true, }, - companyName: { + company_name: { name: 'vendor.field.company_name', column: 'company_name', fieldType: 'text', - importable: true, }, website: { name: 'vendor.field.website', column: 'website', fieldType: 'text', - importable: true, + }, + created_at: { + name: 'vendor.field.created_at', + column: 'created_at', + fieldType: 'date', }, balance: { name: 'vendor.field.balance', column: 'balance', fieldType: 'number', }, - openingBalance: { + opening_balance: { name: 'vendor.field.opening_balance', column: 'opening_balance', fieldType: 'number', - importable: true, }, - openingBalanceAt: { + opening_balance_at: { name: 'vendor.field.opening_balance_at', column: 'opening_balance_at', fieldType: 'date', - importable: true, }, - openingBalanceExchangeRate: { - name: 'Opening Balance Ex. Rate', - column: 'opening_balance_exchange_rate', - fieldType: 'number', - importable: true, - }, - currencyCode: { + currency_code: { name: 'vendor.field.currency', column: 'currency_code', fieldType: 'text', - importable: true, - }, - note: { - name: 'Note', - column: 'note', - fieldType: 'text', - importable: true, - }, - active: { - name: 'Active', - column: 'active', - fieldType: 'boolean', - importable: true, }, status: { name: 'vendor.field.status', @@ -114,97 +89,6 @@ export default { } }, }, - // Billing Address - billingAddress1: { - name: 'Billing Address 1', - column: 'billing_address1', - fieldType: 'text', - importable: true, - }, - billingAddress2: { - name: 'Billing Address 2', - column: 'billing_address2', - fieldType: 'text', - importable: true, - }, - billingAddressCity: { - name: 'Billing Address City', - column: 'billing_address_city', - fieldType: 'text', - importable: true, - }, - billingAddressCountry: { - name: 'Billing Address Country', - column: 'billing_address_country', - fieldType: 'text', - importable: true, - }, - billingAddressPostcode: { - name: 'Billing Address Postcode', - column: 'billing_address_postcode', - fieldType: 'text', - importable: true, - }, - billingAddressState: { - name: 'Billing Address State', - column: 'billing_address_state', - fieldType: 'text', - importable: true, - }, - billingAddressPhone: { - name: 'Billing Address Phone', - column: 'billing_address_phone', - fieldType: 'text', - importable: true, - }, - // Shipping Address - shippingAddress1: { - name: 'Shipping Address 1', - column: 'shipping_address1', - fieldType: 'text', - importable: true, - }, - shippingAddress2: { - name: 'Shipping Address 2', - column: 'shipping_address2', - fieldType: 'text', - importable: true, - }, - shippingAddressCity: { - name: 'Shipping Address City', - column: 'shipping_address_city', - fieldType: 'text', - importable: true, - }, - shippingAddressCountry: { - name: 'Shipping Address Country', - column: 'shipping_address_country', - fieldType: 'text', - importable: true, - }, - shippingAddressPostcode: { - name: 'Shipping Address Postcode', - column: 'shipping_address_postcode', - fieldType: 'text', - importable: true, - }, - shippingAddressState: { - name: 'Shipping Address State', - column: 'shipping_address_state', - fieldType: 'text', - importable: true, - }, - shippingAddressPhone: { - name: 'Shipping Address Phone', - column: 'shipping_address_phone', - fieldType: 'text', - importable: true, - }, - createdAt: { - name: 'vendor.field.created_at', - column: 'created_at', - fieldType: 'date', - }, }, fields2: { firstName: { diff --git a/packages/server/src/services/Import/_utils.ts b/packages/server/src/services/Import/_utils.ts index 67fb7f5cc..80afe17f2 100644 --- a/packages/server/src/services/Import/_utils.ts +++ b/packages/server/src/services/Import/_utils.ts @@ -33,7 +33,12 @@ export const ERRORS = { IMPORTED_SHEET_EMPTY: 'IMPORTED_SHEET_EMPTY', }; -export function trimObject(obj) { +/** + * 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(); @@ -46,6 +51,11 @@ export function trimObject(obj) { }, {}); } +/** + * Generates the Yup validation schema based on the given resource fields. + * @param {ResourceMetaFieldsMap} fields + * @returns {Yup} + */ export const convertFieldsToYupValidation = (fields: ResourceMetaFieldsMap) => { const yupSchema = {}; @@ -123,15 +133,18 @@ export const convertFieldsToYupValidation = (fields: ResourceMetaFieldsMap) => { const parseFieldName = (fieldName: string, field: IModelMetaField) => { let _key = fieldName; - // if (field.fieldType === 'relation') { - // _key = `${fieldName}Id`; - // } 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) @@ -315,13 +328,13 @@ export const valueParser = 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( - /** - * - * @param {{ [key: string]: IModelMetaField2 }} fields - * @param {string} key - Mapped key path. formats: `group.key` or `key`. - * @returns {string} - */ (fields: { [key: string]: IModelMetaField2 }, key: string) => { const fieldKey = getFieldKey(key); const field = fields[fieldKey]; @@ -344,6 +357,11 @@ export const parseKey = R.curry( } ); +/** + * 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 diff --git a/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts b/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts index 2b6709e29..65129125f 100644 --- a/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts +++ b/packages/server/src/services/Sales/Receipts/CreateSaleReceipt.ts @@ -4,6 +4,7 @@ import { ISaleReceipt, ISaleReceiptCreatedPayload, ISaleReceiptCreatingPayload, + ISaleReceiptDTO, } from '@/interfaces'; import events from '@/subscribers/events'; import TenancyService from '@/services/Tenancy/TenancyService'; @@ -41,7 +42,7 @@ export class CreateSaleReceipt { */ public async createSaleReceipt( tenantId: number, - saleReceiptDTO: any, + saleReceiptDTO: ISaleReceiptDTO, trx?: Knex.Transaction ): Promise { const { SaleReceipt, Contact } = this.tenancy.models(tenantId); diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts index c8036d894..2aecec404 100644 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts +++ b/packages/server/src/services/Sales/Receipts/SaleReceiptsImportable.ts @@ -1,6 +1,6 @@ import { Inject, Service } from 'typedi'; import { Knex } from 'knex'; -import { IAccountCreateDTO } from '@/interfaces'; +import { IAccountCreateDTO, ISaleReceiptDTO } from '@/interfaces'; import { CreateSaleReceipt } from './CreateSaleReceipt'; import { Importable } from '@/services/Import/Importable'; import { SaleReceiptsSampleData } from './constants'; @@ -18,7 +18,7 @@ export class SaleReceiptsImportable extends Importable { */ public importable( tenantId: number, - createAccountDTO: IAccountCreateDTO, + createAccountDTO: ISaleReceiptDTO, trx?: Knex.Transaction ) { return this.createReceiptService.createSaleReceipt( diff --git a/packages/webapp/src/containers/Import/_utils.ts b/packages/webapp/src/containers/Import/_utils.ts index 233026241..fdd62f0cf 100644 --- a/packages/webapp/src/containers/Import/_utils.ts +++ b/packages/webapp/src/containers/Import/_utils.ts @@ -1,7 +1,20 @@ // @ts-nocheck import { useMemo } from 'react'; -import { chain, isEmpty, lowerCase, head, last, set, get } from 'lodash'; -import { useImportFileContext } from './ImportFileProvider'; +import { + chain, + isEmpty, + lowerCase, + head, + last, + set, + get, + assign, +} from 'lodash'; +import { + EntityColumn, + SheetColumn, + useImportFileContext, +} from './ImportFileProvider'; import { useImportFileMapBootContext } from './ImportFileMappingBoot'; import { deepdash, transformToForm } from '@/utils'; import { ImportFileMappingFormValues } from './_types'; @@ -34,15 +47,40 @@ export const transformValueToReq = ( }; /** - * - * @param value - * @returns + * Transformes the mapping response to form values. + * @param {{ from: string; to: string, group: string }[]} value + * @returns {Record} */ export const transformResToFormValues = ( - value: { from: string; to: string }[], -) => { + value: { from: string; to: string , group: string }[], +): Record => { return value?.reduce((acc, map) => { - acc[map.to] = map.from; + const path = map?.group ? `${map.group}.${map.to}` : map.to; + set(acc, path, map.from); + return acc; + }, {}); +}; + +/** + * Retrieves the initial values of mapping form. + * @param {EntityColumn[]} entityColumns + * @param {SheetColumn[]} sheetColumns + */ +const getInitialDefaultValues = ( + entityColumns: EntityColumn[], + sheetColumns: SheetColumn[], +) => { + return entityColumns.reduce((acc, { fields, groupKey }) => { + fields.forEach(({ key, name }) => { + const _name = lowerCase(name); + const _matched = sheetColumns.find( + (column) => lowerCase(column) === _name, + ); + const _key = groupKey ? `${groupKey}.${key}` : key; + const _value = _matched ? _matched : ''; + + set(acc, _key, _value); + }); return acc; }, {}); }; @@ -59,30 +97,18 @@ export const useImportFileMappingInitialValues = () => { () => transformResToFormValues(importFile?.map || []), [importFile?.map], ); - - const initialValues = useMemo( - () => - entityColumns.reduce((acc, { fields, groupKey }) => { - fields.forEach(({ key, name }) => { - const _name = lowerCase(name); - const _matched = sheetColumns.find( - (column) => lowerCase(column) === _name, - ); - const _key = groupKey ? `${groupKey}.${key}` : key; - const _value = _matched ? _matched : ''; - - set(acc, _key, _value); - }); - return acc; - }, {}), + // Retrieves the initial default values. + const initialDefaultValues = useMemo( + () => getInitialDefaultValues(entityColumns, sheetColumns), [entityColumns, sheetColumns], ); return useMemo>( - () => ({ - ...transformToForm(initialResValues, initialValues), - ...initialValues, - }), - [initialValues, initialResValues], + () => + assign( + initialDefaultValues, + transformToForm(initialResValues, initialDefaultValues), + ), + [initialDefaultValues, initialResValues], ); };