mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
refactor(nestjs): seed migrations
This commit is contained in:
@@ -9,5 +9,5 @@ export default registerAs('tenantDatabase', () => ({
|
||||
password: process.env.TENANT_DB_PASSWORD || process.env.DB_PASSWORD,
|
||||
dbNamePrefix: process.env.TENANT_DB_NAME_PERFIX || 'bigcapital_tenant_',
|
||||
migrationsDir: path.join(__dirname, '../../database/migrations'),
|
||||
seedsDir: path.join(__dirname, '../../database/migrations'),
|
||||
seedsDir: path.join(__dirname, '../../database/seeds'),
|
||||
}));
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
import AccountsData from '../data/accounts';
|
||||
|
||||
export default class SeedAccounts extends TenantSeeder {
|
||||
/**
|
||||
* Seeds initial accounts to the organization.
|
||||
*/
|
||||
up(knex) {
|
||||
const data = AccountsData.map((account) => ({
|
||||
...account,
|
||||
name: this.i18n.__(account.name),
|
||||
description: this.i18n(account.description),
|
||||
currencyCode: this.tenant.metadata.baseCurrency,
|
||||
seededAt: new Date(),
|
||||
}));
|
||||
return knex('accounts').then(async () => {
|
||||
// Inserts seed entries.
|
||||
return knex('accounts').insert(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
|
||||
export default class SeedSettings extends TenantSeeder {
|
||||
/**
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
up() {
|
||||
const settings = [
|
||||
// Orgnization settings.
|
||||
{ group: 'organization', key: 'accounting_basis', value: 'accrual' },
|
||||
|
||||
// Accounts settings.
|
||||
{ group: 'accounts', key: 'account_code_unique', value: true },
|
||||
|
||||
// Manual journals settings.
|
||||
{ group: 'manual_journals', key: 'next_number', value: '00001' },
|
||||
{ group: 'manual_journals', key: 'number_prefix', value: 'J-' },
|
||||
{ group: 'manual_journals', key: 'auto_increment', value: true },
|
||||
|
||||
// Sale invoices settings.
|
||||
{ group: 'sales_invoices', key: 'next_number', value: '00001' },
|
||||
{ group: 'sales_invoices', key: 'number_prefix', value: 'INV-' },
|
||||
{ group: 'sales_invoices', key: 'auto_increment', value: true },
|
||||
|
||||
// Sale receipts settings.
|
||||
{ group: 'sales_receipts', key: 'next_number', value: '00001' },
|
||||
{ group: 'sales_receipts', key: 'number_prefix', value: 'REC-' },
|
||||
{ group: 'sales_receipts', key: 'auto_increment', value: true },
|
||||
|
||||
// Sale estimates settings.
|
||||
{ group: 'sales_estimates', key: 'next_number', value: '00001' },
|
||||
{ group: 'sales_estimates', key: 'number_prefix', value: 'EST-' },
|
||||
{ group: 'sales_estimates', key: 'auto_increment', value: true },
|
||||
|
||||
// Payment receives settings.
|
||||
{ group: 'payment_receives', key: 'number_prefix', value: 'PAY-' },
|
||||
{ group: 'payment_receives', key: 'next_number', value: '00001' },
|
||||
{ group: 'payment_receives', key: 'auto_increment', value: true },
|
||||
|
||||
// Cashflow settings.
|
||||
{ group: 'cashflow', key: 'number_prefix', value: 'CF-' },
|
||||
{ group: 'cashflow', key: 'next_number', value: '00001' },
|
||||
{ group: 'cashflow', key: 'auto_increment', value: true },
|
||||
|
||||
// warehouse transfers settings.
|
||||
{ group: 'warehouse_transfers', key: 'next_number', value: '00001' },
|
||||
{ group: 'warehouse_transfers', key: 'number_prefix', value: 'WT-' },
|
||||
{ group: 'warehouse_transfers', key: 'auto_increment', value: true },
|
||||
];
|
||||
return this.knex('settings').insert(settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
|
||||
export default class SeedSettings extends TenantSeeder {
|
||||
/**
|
||||
*
|
||||
* @param knex
|
||||
* @returns
|
||||
*/
|
||||
async up(knex) {
|
||||
const costAccount = await knex('accounts')
|
||||
.where('slug', 'cost-of-goods-sold')
|
||||
.first();
|
||||
|
||||
const sellAccount = await knex('accounts')
|
||||
.where('slug', 'sales-of-product-income')
|
||||
.first();
|
||||
|
||||
const inventoryAccount = await knex('accounts')
|
||||
.where('slug', 'inventory-asset')
|
||||
.first();
|
||||
|
||||
const settings = [
|
||||
// Items settings.
|
||||
{ group: 'items', key: 'preferred_sell_account', value: sellAccount?.id },
|
||||
{ group: 'items', key: 'preferred_cost_account', value: costAccount?.id },
|
||||
{
|
||||
group: 'items',
|
||||
key: 'preferred_inventory_account',
|
||||
value: inventoryAccount?.id,
|
||||
},
|
||||
];
|
||||
return knex('settings').insert(settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
|
||||
export default class SeedRolesAndPermissions extends TenantSeeder {
|
||||
/**
|
||||
* Seeds roles and associated permissiojns.
|
||||
* @param knex
|
||||
* @returns
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async up(knex) {
|
||||
return knex('roles').insert([
|
||||
{
|
||||
id: 1,
|
||||
name: 'role.admin.name',
|
||||
predefined: true,
|
||||
slug: 'admin',
|
||||
description: 'role.admin.desc',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'role.staff.name',
|
||||
predefined: true,
|
||||
slug: 'staff',
|
||||
description: 'role.staff.desc',
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
|
||||
export default class SeedRolesAndPermissions extends TenantSeeder {
|
||||
/**
|
||||
* Seeds roles and associated permissiojns.
|
||||
* @param knex
|
||||
* @returns
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async up(knex) {
|
||||
return knex('role_permissions').insert([
|
||||
// Assign sale invoice permissions to staff role.
|
||||
{ roleId: 2, subject: 'SaleInvoice', ability: 'create' },
|
||||
{ roleId: 2, subject: 'SaleInvoice', ability: 'delete' },
|
||||
{ roleId: 2, subject: 'SaleInvoice', ability: 'view' },
|
||||
{ roleId: 2, subject: 'SaleInvoice', ability: 'edit' },
|
||||
|
||||
// Assign sale estimate permissions to staff role.
|
||||
{ roleId: 2, subject: 'SaleEstimate', ability: 'create' },
|
||||
{ roleId: 2, subject: 'SaleEstimate', ability: 'delete' },
|
||||
{ roleId: 2, subject: 'SaleEstimate', ability: 'view' },
|
||||
{ roleId: 2, subject: 'SaleEstimate', ability: 'edit' },
|
||||
|
||||
// Assign sale receipt permissions to staff role.
|
||||
{ roleId: 2, subject: 'SaleReceipt', ability: 'create' },
|
||||
{ roleId: 2, subject: 'SaleReceipt', ability: 'delete' },
|
||||
{ roleId: 2, subject: 'SaleReceipt', ability: 'view' },
|
||||
{ roleId: 2, subject: 'SaleReceipt', ability: 'edit' },
|
||||
|
||||
// Assign payment receive permissions to staff role.
|
||||
{ roleId: 2, subject: 'PaymentReceive', ability: 'create' },
|
||||
{ roleId: 2, subject: 'PaymentReceive', ability: 'delete' },
|
||||
{ roleId: 2, subject: 'PaymentReceive', ability: 'view' },
|
||||
{ roleId: 2, subject: 'PaymentReceive', ability: 'edit' },
|
||||
|
||||
// Assign bill permissions to staff role.
|
||||
{ roleId: 2, subject: 'Bill', ability: 'create' },
|
||||
{ roleId: 2, subject: 'Bill', ability: 'delete' },
|
||||
{ roleId: 2, subject: 'Bill', ability: 'view' },
|
||||
{ roleId: 2, subject: 'Bill', ability: 'edit' },
|
||||
|
||||
// Assign payment made permissions to staff role.
|
||||
{ roleId: 2, subject: 'PaymentMade', ability: 'create' },
|
||||
{ roleId: 2, subject: 'PaymentMade', ability: 'delete' },
|
||||
{ roleId: 2, subject: 'PaymentMade', ability: 'view' },
|
||||
{ roleId: 2, subject: 'PaymentMade', ability: 'edit' },
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
|
||||
export default class SeedCustomerVendorCreditSettings extends TenantSeeder {
|
||||
/**
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
up() {
|
||||
const settings = [
|
||||
// Credit note.
|
||||
{ group: 'credit_note', key: 'number_prefix', value: 'CN-' },
|
||||
{ group: 'credit_note', key: 'next_number', value: '00001' },
|
||||
{ group: 'credit_note', key: 'auto_increment', value: true },
|
||||
|
||||
// Vendor credit.
|
||||
{ group: 'vendor_credit', key: 'number_prefix', value: 'VC-' },
|
||||
{ group: 'vendor_credit', key: 'next_number', value: '00001' },
|
||||
{ group: 'vendor_credit', key: 'auto_increment', value: true },
|
||||
];
|
||||
return this.knex('settings').insert(settings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
import { InitialTaxRates } from '../data/TaxRates';
|
||||
|
||||
export default class SeedTaxRates extends TenantSeeder {
|
||||
/**
|
||||
* Seeds initial tax rates to the organization.
|
||||
*/
|
||||
up(knex) {
|
||||
return knex('tax_rates').then(async () => {
|
||||
// Inserts seed entries.
|
||||
return knex('tax_rates').insert(InitialTaxRates);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TenantSeeder } from '@/libs/migration-seed/TenantSeeder';
|
||||
import { InitialTaxRates } from '../data/TaxRates';
|
||||
|
||||
export default class UpdateTaxPayableAccount extends TenantSeeder {
|
||||
/**
|
||||
* Seeds initial tax rates to the organization.
|
||||
*/
|
||||
up(knex) {
|
||||
return knex('accounts').then(async () => {
|
||||
// Inserts seed entries.
|
||||
return knex('accounts').where('slug', 'tax-payable').update({
|
||||
account_type: 'tax-payable',
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
1
packages/server-nest/src/database/seeds/core/index.ts
Normal file
1
packages/server-nest/src/database/seeds/core/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
// .gitkeep
|
||||
30
packages/server-nest/src/database/seeds/data/TaxRates.ts
Normal file
30
packages/server-nest/src/database/seeds/data/TaxRates.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export const InitialTaxRates = [
|
||||
{
|
||||
name: 'Tax Exempt',
|
||||
code: 'TAX-EXEMPT',
|
||||
description: 'Exempts goods or services from taxes.',
|
||||
rate: 0,
|
||||
active: 1,
|
||||
},
|
||||
{
|
||||
name: 'Tax on Purchases',
|
||||
code: 'TAX-PURCHASES',
|
||||
description: 'Fee added to the cost when you buy items.',
|
||||
rate: 0,
|
||||
active: 1,
|
||||
},
|
||||
{
|
||||
name: 'Tax on Sales',
|
||||
code: 'TAX-SALES',
|
||||
description: 'Fee added to the cost when you sell items.',
|
||||
rate: 0,
|
||||
active: 1,
|
||||
},
|
||||
{
|
||||
name: 'Sales Tax on Imports',
|
||||
code: 'TAX-IMPORTS',
|
||||
description: 'Fee added to the cost when you sale to another country.',
|
||||
rate: 0,
|
||||
active: 1,
|
||||
},
|
||||
];
|
||||
395
packages/server-nest/src/database/seeds/data/accounts.js
Normal file
395
packages/server-nest/src/database/seeds/data/accounts.js
Normal file
@@ -0,0 +1,395 @@
|
||||
export const OtherExpensesAccount = {
|
||||
name: 'Other Expenses',
|
||||
slug: 'other-expenses',
|
||||
account_type: 'other-expense',
|
||||
code: '40011',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
};
|
||||
|
||||
export const TaxPayableAccount = {
|
||||
name: 'Tax Payable',
|
||||
slug: 'tax-payable',
|
||||
account_type: 'tax-payable',
|
||||
code: '20006',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
};
|
||||
|
||||
export const UnearnedRevenueAccount = {
|
||||
name: 'Unearned Revenue',
|
||||
slug: 'unearned-revenue',
|
||||
account_type: 'other-current-liability',
|
||||
parent_account_id: null,
|
||||
code: '50005',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const PrepardExpenses = {
|
||||
name: 'Prepaid Expenses',
|
||||
slug: 'prepaid-expenses',
|
||||
account_type: 'other-current-asset',
|
||||
parent_account_id: null,
|
||||
code: '100010',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const StripeClearingAccount = {
|
||||
name: 'Stripe Clearing',
|
||||
slug: 'stripe-clearing',
|
||||
account_type: 'other-current-asset',
|
||||
parent_account_id: null,
|
||||
code: '100020',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const DiscountExpenseAccount = {
|
||||
name: 'Discount',
|
||||
slug: 'discount',
|
||||
account_type: 'other-income',
|
||||
code: '40008',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const PurchaseDiscountAccount = {
|
||||
name: 'Purchase Discount',
|
||||
slug: 'purchase-discount',
|
||||
account_type: 'other-expense',
|
||||
code: '40009',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const OtherChargesAccount = {
|
||||
name: 'Other Charges',
|
||||
slug: 'other-charges',
|
||||
account_type: 'other-income',
|
||||
code: '40010',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
name: 'Bank Account',
|
||||
slug: 'bank-account',
|
||||
account_type: 'bank',
|
||||
code: '10001',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Saving Bank Account',
|
||||
slug: 'saving-bank-account',
|
||||
account_type: 'bank',
|
||||
code: '10002',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Undeposited Funds',
|
||||
slug: 'undeposited-funds',
|
||||
account_type: 'cash',
|
||||
code: '10003',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Petty Cash',
|
||||
slug: 'petty-cash',
|
||||
account_type: 'cash',
|
||||
code: '10004',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Computer Equipment',
|
||||
slug: 'computer-equipment',
|
||||
code: '10005',
|
||||
account_type: 'fixed-asset',
|
||||
predefined: 0,
|
||||
parent_account_id: null,
|
||||
index: 1,
|
||||
active: 1,
|
||||
description: '',
|
||||
},
|
||||
{
|
||||
name: 'Office Equipment',
|
||||
slug: 'office-equipment',
|
||||
code: '10006',
|
||||
account_type: 'fixed-asset',
|
||||
predefined: 0,
|
||||
parent_account_id: null,
|
||||
index: 1,
|
||||
active: 1,
|
||||
description: '',
|
||||
},
|
||||
{
|
||||
name: 'Accounts Receivable (A/R)',
|
||||
slug: 'accounts-receivable',
|
||||
account_type: 'accounts-receivable',
|
||||
code: '10007',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Inventory Asset',
|
||||
slug: 'inventory-asset',
|
||||
code: '10008',
|
||||
account_type: 'inventory',
|
||||
predefined: 1,
|
||||
parent_account_id: null,
|
||||
index: 1,
|
||||
active: 1,
|
||||
description:
|
||||
'An account that holds valuation of products or goods that available for sale.',
|
||||
},
|
||||
|
||||
// Libilities
|
||||
{
|
||||
name: 'Accounts Payable (A/P)',
|
||||
slug: 'accounts-payable',
|
||||
account_type: 'accounts-payable',
|
||||
parent_account_id: null,
|
||||
code: '20001',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Owner A Drawings',
|
||||
slug: 'owner-drawings',
|
||||
account_type: 'other-current-liability',
|
||||
parent_account_id: null,
|
||||
code: '20002',
|
||||
description: 'Withdrawals by the owners.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Loan',
|
||||
slug: 'owner-drawings',
|
||||
account_type: 'other-current-liability',
|
||||
code: '20003',
|
||||
description: 'Money that has been borrowed from a creditor.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Opening Balance Liabilities',
|
||||
slug: 'opening-balance-liabilities',
|
||||
account_type: 'other-current-liability',
|
||||
code: '20004',
|
||||
description:
|
||||
'This account will hold the difference in the debits and credits entered during the opening balance..',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Revenue Received in Advance',
|
||||
slug: 'revenue-received-in-advance',
|
||||
account_type: 'other-current-liability',
|
||||
parent_account_id: null,
|
||||
code: '20005',
|
||||
description: 'When customers pay in advance for products/services.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
TaxPayableAccount,
|
||||
|
||||
// Equity
|
||||
{
|
||||
name: 'Retained Earnings',
|
||||
slug: 'retained-earnings',
|
||||
account_type: 'equity',
|
||||
code: '30001',
|
||||
description:
|
||||
'Retained earnings tracks net income from previous fiscal years.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Opening Balance Equity',
|
||||
slug: 'opening-balance-equity',
|
||||
account_type: 'equity',
|
||||
code: '30002',
|
||||
description:
|
||||
'When you enter opening balances to the accounts, the amounts enter in Opening balance equity. This ensures that you have a correct trial balance sheet for your company, without even specific the second credit or debit entry.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: "Owner's Equity",
|
||||
slug: 'owner-equity',
|
||||
account_type: 'equity',
|
||||
code: '30003',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: `Drawings`,
|
||||
slug: 'drawings',
|
||||
account_type: 'equity',
|
||||
code: '30003',
|
||||
description:
|
||||
'Goods purchased with the intention of selling these to customers',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
|
||||
// Expenses
|
||||
OtherExpensesAccount,
|
||||
{
|
||||
name: 'Cost of Goods Sold',
|
||||
slug: 'cost-of-goods-sold',
|
||||
account_type: 'cost-of-goods-sold',
|
||||
parent_account_id: null,
|
||||
code: '40002',
|
||||
description: 'Tracks the direct cost of the goods sold.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Office expenses',
|
||||
slug: 'office-expenses',
|
||||
account_type: 'expense',
|
||||
parent_account_id: null,
|
||||
code: '40003',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Rent',
|
||||
slug: 'rent',
|
||||
account_type: 'expense',
|
||||
parent_account_id: null,
|
||||
code: '40004',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Exchange Gain or Loss',
|
||||
slug: 'exchange-grain-loss',
|
||||
account_type: 'other-expense',
|
||||
parent_account_id: null,
|
||||
code: '40005',
|
||||
description: 'Tracks the gain and losses of the exchange differences.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Bank Fees and Charges',
|
||||
slug: 'bank-fees-and-charges',
|
||||
account_type: 'expense',
|
||||
parent_account_id: null,
|
||||
code: '40006',
|
||||
description:
|
||||
'Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
{
|
||||
name: 'Depreciation Expense',
|
||||
slug: 'depreciation-expense',
|
||||
account_type: 'expense',
|
||||
parent_account_id: null,
|
||||
code: '40007',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
|
||||
// Income
|
||||
{
|
||||
name: 'Sales of Product Income',
|
||||
slug: 'sales-of-product-income',
|
||||
account_type: 'income',
|
||||
predefined: 1,
|
||||
parent_account_id: null,
|
||||
code: '50001',
|
||||
index: 1,
|
||||
active: 1,
|
||||
description: '',
|
||||
},
|
||||
{
|
||||
name: 'Sales of Service Income',
|
||||
slug: 'sales-of-service-income',
|
||||
account_type: 'income',
|
||||
predefined: 0,
|
||||
parent_account_id: null,
|
||||
code: '50002',
|
||||
index: 1,
|
||||
active: 1,
|
||||
description: '',
|
||||
},
|
||||
{
|
||||
name: 'Uncategorized Income',
|
||||
slug: 'uncategorized-income',
|
||||
account_type: 'income',
|
||||
parent_account_id: null,
|
||||
code: '50003',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
},
|
||||
{
|
||||
name: 'Other Income',
|
||||
slug: 'other-income',
|
||||
account_type: 'other-income',
|
||||
parent_account_id: null,
|
||||
code: '50004',
|
||||
description:
|
||||
'The income activities are not associated to the core business.',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 0,
|
||||
},
|
||||
UnearnedRevenueAccount,
|
||||
PrepardExpenses,
|
||||
DiscountExpenseAccount,
|
||||
PurchaseDiscountAccount,
|
||||
OtherChargesAccount,
|
||||
];
|
||||
@@ -16,10 +16,12 @@ import { JournalSheetModule } from './modules/JournalSheet/JournalSheet.module';
|
||||
import { ProfitLossSheetModule } from './modules/ProfitLossSheet/ProfitLossSheet.module';
|
||||
import { CashflowStatementModule } from './modules/CashFlowStatement/CashflowStatement.module';
|
||||
import { VendorBalanceSummaryModule } from './modules/VendorBalanceSummary/VendorBalanceSummary.module';
|
||||
import { BalanceSheetModule } from './modules/BalanceSheet/BalanceSheet.module';
|
||||
|
||||
@Module({
|
||||
providers: [],
|
||||
imports: [
|
||||
BalanceSheetModule,
|
||||
PurchasesByItemsModule,
|
||||
CustomerBalanceSummaryModule,
|
||||
VendorBalanceSummaryModule,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Response } from 'express';
|
||||
import { Controller, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { IBalanceSheetQuery } from './BalanceSheet.types';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { BalanceSheetApplication } from './BalanceSheetApplication';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@Controller('/reports/balance-sheet')
|
||||
@ApiTags('reports')
|
||||
export class BalanceSheetStatementController {
|
||||
constructor(private readonly balanceSheetApp: BalanceSheetApplication) {}
|
||||
|
||||
@@ -14,6 +16,9 @@ export class BalanceSheetStatementController {
|
||||
* @param {Response} res - Response.
|
||||
* @param {string} acceptHeader - Accept header.
|
||||
*/
|
||||
@Get('')
|
||||
@ApiOperation({ summary: 'Get balance sheet statement' })
|
||||
@ApiResponse({ status: 200, description: 'Balance sheet statement' })
|
||||
public async balanceSheet(
|
||||
@Query() query: IBalanceSheetQuery,
|
||||
@Res() res: Response,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { I18nService } from 'nestjs-i18n';
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { defaultTo, toArray } from 'lodash';
|
||||
import { FinancialSheetStructure } from '../../common/FinancialSheetStructure';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
BALANCE_SHEET_SCHEMA_NODE_TYPE,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
IBalanceSheetDataNode,
|
||||
@@ -5,11 +6,14 @@ import {
|
||||
} from './BalanceSheet.types';
|
||||
import { GConstructor } from '@/common/types/Constructor';
|
||||
import { FinancialSheet } from '../../common/FinancialSheet';
|
||||
import { BalanceSheetQuery } from './BalanceSheetQuery';
|
||||
|
||||
export const BalanceSheetBase = <T extends GConstructor<FinancialSheet>>(
|
||||
Base: T,
|
||||
) =>
|
||||
class BalanceSheetBase extends Base {
|
||||
query: BalanceSheetQuery;
|
||||
|
||||
/**
|
||||
* Determines the node type of the given schema node.
|
||||
* @param {IBalanceSheetStructureSection} node -
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { sumBy } from 'lodash';
|
||||
import {
|
||||
@@ -11,6 +12,8 @@ import { FinancialPreviousPeriod } from '../../common/FinancialPreviousPeriod';
|
||||
import { FinancialHorizTotals } from '../../common/FinancialHorizTotals';
|
||||
import { GConstructor } from '@/common/types/Constructor';
|
||||
import { FinancialSheet } from '../../common/FinancialSheet';
|
||||
import { BalanceSheetQuery } from './BalanceSheetQuery';
|
||||
import { BalanceSheetRepository } from './BalanceSheetRepository';
|
||||
|
||||
export const BalanceSheetComparsionPreviousPeriod = <
|
||||
T extends GConstructor<FinancialSheet>,
|
||||
@@ -21,6 +24,9 @@ export const BalanceSheetComparsionPreviousPeriod = <
|
||||
FinancialHorizTotals,
|
||||
FinancialPreviousPeriod,
|
||||
)(Base) {
|
||||
query: BalanceSheetQuery;
|
||||
repository: BalanceSheetRepository;
|
||||
|
||||
// ------------------------------
|
||||
// # Account
|
||||
// ------------------------------
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { sumBy, isEmpty } from 'lodash';
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { sumBy } from 'lodash';
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { get } from 'lodash';
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import {
|
||||
IBalanceSheetDOO,
|
||||
IBalanceSheetQuery,
|
||||
@@ -19,8 +20,6 @@ export class BalanceSheetInjectable {
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
private readonly tenancyContext: TenancyContext,
|
||||
private readonly i18n: I18nService,
|
||||
|
||||
@Inject(BalanceSheetRepository.name)
|
||||
private readonly balanceSheetRepository: BalanceSheetRepository,
|
||||
) {}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
BALANCE_SHEET_SCHEMA_NODE_TYPE,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
IBalanceSheetNetIncomeNode,
|
||||
IBalanceSheetTotalPeriod,
|
||||
} from '@/interfaces';
|
||||
} from './BalanceSheet.types';
|
||||
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
|
||||
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
|
||||
import { FinancialPreviousPeriod } from '../../common/FinancialPreviousPeriod';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
|
||||
import { FinancialPreviousPeriod } from '../../common/FinancialPreviousPeriod';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
|
||||
import { FinancialPreviousPeriod } from '../../common/FinancialPreviousPeriod';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
IBalanceSheetDataNode,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { IBalanceSheetNetIncomeNode } from './BalanceSheet.types';
|
||||
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
|
||||
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
|
||||
import { FinancialPreviousPeriod } from '../../common/FinancialPreviousPeriod';
|
||||
import { FinancialHorizTotals } from '../../common/FinancialHorizTotals';
|
||||
import { BalanceSheetRepository } from './BalanceSheetRepository';
|
||||
import { BalanceSheetQuery } from './BalanceSheetQuery';
|
||||
import { BalanceSheetNetIncomeDatePeriodsPY } from './BalanceSheetNetIncomeDatePeriodsPY';
|
||||
import { FinancialSheet } from '../../common/FinancialSheet';
|
||||
import { GConstructor } from '@/common/types/Constructor';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { get } from 'lodash';
|
||||
import { BalanceSheetQuery } from './BalanceSheetQuery';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import { merge } from 'lodash';
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import { Inject, Injectable, Scope } from '@nestjs/common';
|
||||
import * as R from 'ramda';
|
||||
import { Knex } from 'knex';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { FinancialDatePeriods } from '../../common/FinancialDatePeriods';
|
||||
import { ModelObject } from 'objection';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
IBalanceSheetStatementData,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import * as moment from 'moment';
|
||||
import { ITableColumn, ITableColumnAccessor } from '../../types/Table.types';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { I18nService } from 'nestjs-i18n';
|
||||
import { ITableColumn } from '../../types/Table.types';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { BalanceSheetQuery } from './BalanceSheetQuery';
|
||||
import { FinancialTablePreviousPeriod } from '../../common/FinancialTablePreviousPeriod';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { IDateRange } from '../../types/Report.types';
|
||||
import { ITableColumn } from '../../types/Table.types';
|
||||
@@ -5,6 +6,7 @@ import { FinancialTablePreviousYear } from '../../common/FinancialTablePreviousY
|
||||
import { FinancialDateRanges } from '../../common/FinancialDateRanges';
|
||||
import { GConstructor } from '@/common/types/Constructor';
|
||||
import { FinancialSheet } from '../../common/FinancialSheet';
|
||||
import { BalanceSheetQuery } from './BalanceSheetQuery';
|
||||
|
||||
export const BalanceSheetTablePreviousYear = <
|
||||
T extends GConstructor<FinancialSheet>,
|
||||
@@ -12,6 +14,8 @@ export const BalanceSheetTablePreviousYear = <
|
||||
Base: T,
|
||||
) =>
|
||||
class extends R.pipe(FinancialTablePreviousYear, FinancialDateRanges)(Base) {
|
||||
query: BalanceSheetQuery;
|
||||
|
||||
// --------------------
|
||||
// # Columns.
|
||||
// --------------------
|
||||
|
||||
@@ -47,16 +47,7 @@ export class BuildOrganizationService {
|
||||
await this.tenantsManager.dropDatabaseIfExists();
|
||||
await this.tenantsManager.createDatabase();
|
||||
await this.tenantsManager.migrateTenant();
|
||||
|
||||
// Migrated tenant.
|
||||
const migratedTenant = await tenant.$query().withGraphFetched('metadata');
|
||||
|
||||
// Creates a tenancy object from given tenant model.
|
||||
// const tenancyContext =
|
||||
// this.tenantsManager.getSeedMigrationContext(migratedTenant);
|
||||
|
||||
// Seed tenant.
|
||||
await this.tenantsManager.seedTenant(migratedTenant, {});
|
||||
await this.tenantsManager.seedTenant()
|
||||
|
||||
// Throws `onOrganizationBuild` event.
|
||||
await this.eventPublisher.emitAsync(events.organization.build, {
|
||||
@@ -79,8 +70,8 @@ export class BuildOrganizationService {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {BuildOrganizationDto} buildDTO
|
||||
* Execute the tenant database build process.
|
||||
* @param {BuildOrganizationDto} buildDTO - Organization build dto.
|
||||
* @returns {Promise<{ nextRunAt: Date; jobId: string }>} - Returns the next run date and job id.
|
||||
*/
|
||||
async buildRunJob(
|
||||
@@ -121,8 +112,6 @@ export class BuildOrganizationService {
|
||||
|
||||
/**
|
||||
* Unlocks tenant build run job.
|
||||
* @param {number} tenantId
|
||||
* @param {number} jobId
|
||||
*/
|
||||
public async revertBuildRunJob() {
|
||||
const tenant = await this.tenancyContext.getTenant();
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
import { Response } from 'express';
|
||||
import { Controller, Get, Param, Res } from '@nestjs/common';
|
||||
import { PaymentLinksApplication } from './PaymentLinksApplication';
|
||||
import { ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@Controller('payment-links')
|
||||
@ApiTags('payment-links')
|
||||
export class PaymentLinksController {
|
||||
constructor(private readonly paymentLinkApp: PaymentLinksApplication) {}
|
||||
|
||||
@Get('/:paymentLinkId/invoice')
|
||||
@ApiOperation({
|
||||
summary: 'Get payment link public metadata',
|
||||
description: 'Retrieves public metadata for an invoice payment link',
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'paymentLinkId',
|
||||
description: 'The ID of the payment link',
|
||||
type: 'string',
|
||||
required: true,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Successfully retrieved payment link metadata',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
data: {
|
||||
type: 'object',
|
||||
description: 'Payment link metadata',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Payment link not found' })
|
||||
public async getPaymentLinkPublicMeta(
|
||||
@Param('paymentLinkId') paymentLinkId: string,
|
||||
) {
|
||||
@@ -16,6 +42,34 @@ export class PaymentLinksController {
|
||||
}
|
||||
|
||||
@Get('/:paymentLinkId/stripe_checkout_session')
|
||||
@ApiOperation({
|
||||
summary: 'Create Stripe checkout session',
|
||||
description: 'Creates a Stripe checkout session for an invoice payment link',
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'paymentLinkId',
|
||||
description: 'The ID of the payment link',
|
||||
type: 'string',
|
||||
required: true,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Successfully created Stripe checkout session',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'Stripe checkout session ID',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: 'Stripe checkout session URL',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Payment link not found' })
|
||||
public async createInvoicePaymentLinkCheckoutSession(
|
||||
@Param('paymentLinkId') paymentLinkId: string,
|
||||
) {
|
||||
@@ -27,6 +81,29 @@ export class PaymentLinksController {
|
||||
}
|
||||
|
||||
@Get('/:paymentLinkId/invoice/pdf')
|
||||
@ApiOperation({
|
||||
summary: 'Get payment link invoice PDF',
|
||||
description: 'Retrieves the PDF of the invoice associated with a payment link',
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'paymentLinkId',
|
||||
description: 'The ID of the payment link',
|
||||
type: 'string',
|
||||
required: true,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Successfully retrieved invoice PDF',
|
||||
content: {
|
||||
'application/pdf': {
|
||||
schema: {
|
||||
type: 'string',
|
||||
format: 'binary',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Payment link or invoice not found' })
|
||||
public async getPaymentLinkInvoicePdf(
|
||||
@Param('paymentLinkId') paymentLinkId: string,
|
||||
@Res() res: Response,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TenantDBManager } from './TenantDBManager';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { I18nService } from 'nestjs-i18n';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { TenantDBManager } from './TenantDBManager';
|
||||
import { events } from '@/common/events/events';
|
||||
import { TenantModel } from '../System/models/TenantModel';
|
||||
import {
|
||||
@@ -11,6 +13,7 @@ import {
|
||||
import { SeedMigration } from '@/libs/migration-seed/SeedMigration';
|
||||
import { TenantRepository } from '../System/repositories/Tenant.repository';
|
||||
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
import { TENANCY_DB_CONNECTION } from '../Tenancy/TenancyDB/TenancyDB.constants';
|
||||
|
||||
@Injectable()
|
||||
export class TenantsManagerService {
|
||||
@@ -19,6 +22,10 @@ export class TenantsManagerService {
|
||||
private readonly tenancyContext: TenancyContext,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly tenantRepository: TenantRepository,
|
||||
private readonly i18nService: I18nService,
|
||||
|
||||
@Inject(TENANCY_DB_CONNECTION)
|
||||
private readonly tenantKnex: () => Knex,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -84,15 +91,19 @@ export class TenantsManagerService {
|
||||
* Seeds the tenant database.
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
public async seedTenant(tenant: TenantModel, tenancyContext): Promise<void> {
|
||||
public async seedTenant(): Promise<void> {
|
||||
const tenant = await this.tenancyContext.getTenant();
|
||||
|
||||
// Throw error if the tenant is not built yet.
|
||||
throwErrorIfTenantNotBuilt(tenant);
|
||||
|
||||
// Throw error if the tenant is not seeded yet.
|
||||
throwErrorIfTenantAlreadySeeded(tenant);
|
||||
|
||||
const seedContext = await this.getSeedMigrationContext();
|
||||
|
||||
// Seeds the organization database data.
|
||||
await new SeedMigration(tenancyContext.knex, tenancyContext).latest();
|
||||
await new SeedMigration(this.tenantKnex(), seedContext).latest();
|
||||
|
||||
// Mark the tenant as seeded in specific date.
|
||||
await this.tenantRepository.markAsSeeded().findById(tenant.id);
|
||||
@@ -102,4 +113,19 @@ export class TenantsManagerService {
|
||||
tenantId: tenant.id,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize seed migration contxt.
|
||||
* @param {ITenant} tenant
|
||||
* @returns
|
||||
*/
|
||||
public async getSeedMigrationContext() {
|
||||
const tenant = await this.tenancyContext.getTenant();
|
||||
|
||||
return {
|
||||
knex: this.tenantKnex(),
|
||||
i18n: this.i18nService,
|
||||
tenant,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user