diff --git a/client/src/containers/Dialogs/QuickPaymentMadeFormDialog/QuickPaymentMadeFormFields.js b/client/src/containers/Dialogs/QuickPaymentMadeFormDialog/QuickPaymentMadeFormFields.js
index c5f16d93c..dc0ea26ea 100644
--- a/client/src/containers/Dialogs/QuickPaymentMadeFormDialog/QuickPaymentMadeFormFields.js
+++ b/client/src/containers/Dialogs/QuickPaymentMadeFormDialog/QuickPaymentMadeFormFields.js
@@ -14,6 +14,7 @@ import classNames from 'classnames';
import { CLASSES } from 'common/classes';
import { DateInput } from '@blueprintjs/datetime';
import { FieldRequiredHint, Col, Row } from 'components';
+import { ACCOUNT_TYPE } from 'common/accountTypes';
import {
AccountsSuggestField,
InputPrependText,
@@ -164,6 +165,11 @@ export default function QuickPaymentMadeFormFields() {
id: 'select_account',
}),
}}
+ filterByTypes={[
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ]}
/>
)}
diff --git a/client/src/containers/Dialogs/QuickPaymentReceiveFormDialog/QuickPaymentReceiveFormFields.js b/client/src/containers/Dialogs/QuickPaymentReceiveFormDialog/QuickPaymentReceiveFormFields.js
index 083d8f2a2..c47a07896 100644
--- a/client/src/containers/Dialogs/QuickPaymentReceiveFormDialog/QuickPaymentReceiveFormFields.js
+++ b/client/src/containers/Dialogs/QuickPaymentReceiveFormDialog/QuickPaymentReceiveFormFields.js
@@ -20,7 +20,7 @@ import {
MoneyInputGroup,
Icon,
} from 'components';
-
+import { ACCOUNT_TYPE } from 'common/accountTypes';
import {
inputIntent,
momentFormatter,
@@ -166,6 +166,11 @@ export default function QuickPaymentReceiveFormFields({}) {
id: 'select_account',
}),
}}
+ filterByTypes={[
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ]}
/>
)}
diff --git a/client/src/containers/Expenses/ExpenseForm/ExpenseFormPageProvider.js b/client/src/containers/Expenses/ExpenseForm/ExpenseFormPageProvider.js
index c9fc648ba..23b72b704 100644
--- a/client/src/containers/Expenses/ExpenseForm/ExpenseFormPageProvider.js
+++ b/client/src/containers/Expenses/ExpenseForm/ExpenseFormPageProvider.js
@@ -15,16 +15,16 @@ const ExpenseFormPageContext = createContext();
* Accounts chart data provider.
*/
function ExpenseFormPageProvider({ expenseId, ...props }) {
- const { data: currencies, isFetching: isCurrenciesLoading } = useCurrencies();
+ const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
// Fetches customers list.
const {
data: { customers },
- isFetching: isFieldsLoading,
+ isLoading: isCustomersLoading,
} = useCustomers();
// Fetch the expense details.
- const { data: expense, isFetching: isExpenseLoading } = useExpense(
+ const { data: expense, isLoading: isExpenseLoading } = useExpense(
expenseId,
{
enabled: !!expenseId,
@@ -32,7 +32,7 @@ function ExpenseFormPageProvider({ expenseId, ...props }) {
);
// Fetch accounts list.
- const { data: accounts, isFetching: isAccountsLoading } = useAccounts();
+ const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
// Create and edit expense mutate.
const { mutateAsync: createExpenseMutate } = useCreateExpense();
@@ -57,7 +57,7 @@ function ExpenseFormPageProvider({ expenseId, ...props }) {
isCurrenciesLoading,
isExpenseLoading,
- isFieldsLoading,
+ isCustomersLoading,
isAccountsLoading,
createExpenseMutate,
@@ -70,7 +70,7 @@ function ExpenseFormPageProvider({ expenseId, ...props }) {
loading={
isCurrenciesLoading ||
isExpenseLoading ||
- isFieldsLoading ||
+ isCustomersLoading ||
isAccountsLoading
}
name={'expense-form'}
diff --git a/client/src/containers/FinancialStatements/InventoryValuation/InventoryValuationTable.js b/client/src/containers/FinancialStatements/InventoryValuation/InventoryValuationTable.js
index 177a406e0..43efa58cb 100644
--- a/client/src/containers/FinancialStatements/InventoryValuation/InventoryValuationTable.js
+++ b/client/src/containers/FinancialStatements/InventoryValuation/InventoryValuationTable.js
@@ -56,6 +56,7 @@ export default function InventoryValuationTable({
expandColumnSpace={1}
sticky={true}
rowClassNames={rowClassNames}
+ noResults={'There were no inventory transactions during the selected date range.'}
/>
);
diff --git a/client/src/containers/FinancialStatements/Journal/components.js b/client/src/containers/FinancialStatements/Journal/components.js
index c8667a724..a658be52a 100644
--- a/client/src/containers/FinancialStatements/Journal/components.js
+++ b/client/src/containers/FinancialStatements/Journal/components.js
@@ -29,7 +29,7 @@ export const useJournalTableColumns = () => {
},
{
Header: formatMessage({ id: 'num' }),
- accessor: 'reference_id',
+ accessor: 'transaction_number',
className: 'reference_id',
width: 70,
},
diff --git a/client/src/containers/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.js b/client/src/containers/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.js
index 140bd28ae..662f8ae76 100644
--- a/client/src/containers/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.js
+++ b/client/src/containers/FinancialStatements/PurchasesByItems/PurchasesByItemsTable.js
@@ -55,6 +55,7 @@ export default function PurchasesByItemsTable({ companyName }) {
expandColumnSpace={1}
sticky={true}
rowClassNames={rowClassNames}
+ noResults={'There were no purchases during the selected date range.'}
/>
);
diff --git a/client/src/containers/FinancialStatements/SalesByItems/SalesByItemsTable.js b/client/src/containers/FinancialStatements/SalesByItems/SalesByItemsTable.js
index 94611e888..74580b570 100644
--- a/client/src/containers/FinancialStatements/SalesByItems/SalesByItemsTable.js
+++ b/client/src/containers/FinancialStatements/SalesByItems/SalesByItemsTable.js
@@ -53,6 +53,7 @@ export default function SalesByItemsTable({ companyName }) {
expandColumnSpace={1}
sticky={true}
rowClassNames={rowClassNames}
+ noResults={'There were no sales during the selected date range.'}
/>
);
diff --git a/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js b/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js
index adb12da66..d107cdb5e 100644
--- a/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js
+++ b/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js
@@ -25,6 +25,7 @@ import {
} from 'components';
import withSettings from 'containers/Settings/withSettings';
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
+import { ACCOUNT_TYPE } from 'common/accountTypes';
import {
momentFormatter,
tansformDateValue,
@@ -205,6 +206,11 @@ function PaymentMadeFormHeaderFields({ baseCurrency }) {
}}
defaultSelectText={}
selectedAccountId={value}
+ filterByTypes={[
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ]}
/>
)}
diff --git a/client/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js b/client/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js
index 2df4dbdc4..091d38e24 100644
--- a/client/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js
+++ b/client/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js
@@ -33,6 +33,7 @@ import {
Money,
} from 'components';
import { usePaymentReceiveFormContext } from './PaymentReceiveFormProvider';
+import { ACCOUNT_TYPE } from 'common/accountTypes';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withSettings from 'containers/Settings/withSettings';
@@ -263,6 +264,11 @@ function PaymentReceiveHeaderFields({
}}
defaultSelectText={}
selectedAccountId={value}
+ filterByTypes={[
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ]}
/>
)}
diff --git a/client/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js b/client/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js
index 5f04fc976..a3e2ecb7b 100644
--- a/client/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js
+++ b/client/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js
@@ -19,6 +19,7 @@ import {
} from 'components';
import withSettings from 'containers/Settings/withSettings';
import withDialogActions from 'containers/Dialog/withDialogActions';
+import { ACCOUNT_TYPE } from 'common/accountTypes';
import {
momentFormatter,
compose,
@@ -113,8 +114,12 @@ function ReceiptFormHeader({
}}
defaultSelectText={}
selectedAccountId={value}
- // filterByTypes={['current_asset']}
popoverFill={true}
+ filterByTypes={[
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ]}
/>
)}
diff --git a/client/src/style/pages/FinancialStatements/APAgingSummary.scss b/client/src/style/pages/FinancialStatements/APAgingSummary.scss
index e833471a5..f61ee093e 100644
--- a/client/src/style/pages/FinancialStatements/APAgingSummary.scss
+++ b/client/src/style/pages/FinancialStatements/APAgingSummary.scss
@@ -26,7 +26,7 @@
font-weight: 500;
.td{
- border-top: 1px solid #333;
+ border-top: 1px solid #BBB;
border-bottom: 3px double #333;
}
}
diff --git a/client/src/style/pages/FinancialStatements/ARAgingSummary.scss b/client/src/style/pages/FinancialStatements/ARAgingSummary.scss
index f3602b66f..d663e5f8a 100644
--- a/client/src/style/pages/FinancialStatements/ARAgingSummary.scss
+++ b/client/src/style/pages/FinancialStatements/ARAgingSummary.scss
@@ -26,7 +26,7 @@
font-weight: 500;
.td{
- border-top: 1px solid #333;
+ border-top: 1px solid #BBB;
border-bottom: 3px double #333;
}
}
diff --git a/client/src/style/pages/FinancialStatements/SalesAndPurchasesSheet.scss b/client/src/style/pages/FinancialStatements/SalesAndPurchasesSheet.scss
index 3607c8a94..48f9656b6 100644
--- a/client/src/style/pages/FinancialStatements/SalesAndPurchasesSheet.scss
+++ b/client/src/style/pages/FinancialStatements/SalesAndPurchasesSheet.scss
@@ -19,7 +19,7 @@
padding-bottom: 0.4rem;
}
.tr.row_type--total .td {
- border-top: 1px solid #000;
+ border-top: 1px solid #BBB;
font-weight: 500;
border-bottom: 3px double #000;
}
diff --git a/client/src/style/pages/FinancialStatements/TrialBalanceSheet.scss b/client/src/style/pages/FinancialStatements/TrialBalanceSheet.scss
index acf0a843c..2eff7447d 100644
--- a/client/src/style/pages/FinancialStatements/TrialBalanceSheet.scss
+++ b/client/src/style/pages/FinancialStatements/TrialBalanceSheet.scss
@@ -22,7 +22,7 @@
border-top-color: #000;
}
.tr.row_type--total .td{
- border-top: 1px solid #000;
+ border-top: 1px solid #bbb;
font-weight: 500;
border-bottom: 3px double #000;
}
diff --git a/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js b/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js
index 9871e5d15..bf8de6184 100644
--- a/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js
+++ b/server/src/database/migrations/20200722164251_create_inventory_transactions_table.js
@@ -16,6 +16,7 @@ exports.up = function (knex) {
table.integer('transaction_id').unsigned().index();
table.integer('entry_id').unsigned().index();
+ table.integer('cost_account_id').unsigned();
table.timestamps();
});
};
diff --git a/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js b/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js
index 55bcbcbb1..7f45dbdef 100644
--- a/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js
+++ b/server/src/database/migrations/20200810121807_create_inventory_cost_lot_tracker_table.js
@@ -14,6 +14,8 @@ exports.up = function (knex) {
table.integer('transaction_id').unsigned().index();
table.integer('entry_id').unsigned().index();
+ table.integer('cost_account_id').unsigned();
+
table.datetime('created_at').index();
});
};
diff --git a/server/src/interfaces/Account.ts b/server/src/interfaces/Account.ts
index fd48ae3da..1893a3ade 100644
--- a/server/src/interfaces/Account.ts
+++ b/server/src/interfaces/Account.ts
@@ -28,6 +28,10 @@ export interface IAccount {
accountParentType: string,
};
+export interface IAccountResponse extends IAccount {
+
+}
+
export interface IAccountsFilter extends IDynamicListFilterDTO {
stringifiedFilterRoles?: string,
};
diff --git a/server/src/interfaces/FinancialStatements.ts b/server/src/interfaces/FinancialStatements.ts
index 52ae49478..c956afd17 100644
--- a/server/src/interfaces/FinancialStatements.ts
+++ b/server/src/interfaces/FinancialStatements.ts
@@ -14,6 +14,6 @@ export interface IFormatNumberSettings {
thousand?: string;
decimal?: string;
zeroSign?: string;
- symbol?: string;
+ currencyCode?: string;
money?: boolean,
}
diff --git a/server/src/interfaces/IInventoryValuationSheet.ts b/server/src/interfaces/IInventoryValuationSheet.ts
index 9bf4f151b..8a6cf5f40 100644
--- a/server/src/interfaces/IInventoryValuationSheet.ts
+++ b/server/src/interfaces/IInventoryValuationSheet.ts
@@ -12,6 +12,7 @@ export interface IInventoryValuationReportQuery {
export interface IInventoryValuationSheetMeta {
organizationName: string,
baseCurrency: string,
+ isCostComputeRunning: boolean
};
export interface IInventoryValuationItem {
@@ -35,8 +36,8 @@ export interface IInventoryValuationTotal {
quantityFormatted: string,
}
-export interface IInventoryValuationStatement {
+export type IInventoryValuationStatement = {
items: IInventoryValuationItem[],
total: IInventoryValuationTotal
-};
+} | {};
diff --git a/server/src/interfaces/InventoryTransaction.ts b/server/src/interfaces/InventoryTransaction.ts
index 7c2a668c7..47e4d4219 100644
--- a/server/src/interfaces/InventoryTransaction.ts
+++ b/server/src/interfaces/InventoryTransaction.ts
@@ -11,6 +11,7 @@ export interface IInventoryTransaction {
transactionType: string,
transactionId: number,
entryId: number,
+ costAccountId: number,
createdAt?: Date,
updatedAt?: Date,
};
@@ -27,7 +28,6 @@ export interface IInventoryLotCost {
transactionType: string,
transactionId: number,
costAccountId: number,
- sellAccountId: number,
entryId: number,
createdAt: Date,
};
diff --git a/server/src/interfaces/SalesByItemsSheet.ts b/server/src/interfaces/SalesByItemsSheet.ts
index 50ddfaea0..d90fff55e 100644
--- a/server/src/interfaces/SalesByItemsSheet.ts
+++ b/server/src/interfaces/SalesByItemsSheet.ts
@@ -36,8 +36,8 @@ export interface ISalesByItemsTotal {
currencyCode: string,
};
-export interface ISalesByItemsSheetStatement {
+export type ISalesByItemsSheetStatement = {
items: ISalesByItemsItem[],
total: ISalesByItemsTotal
-};
+} | {};
diff --git a/server/src/services/Accounting/JournalCommands.ts b/server/src/services/Accounting/JournalCommands.ts
index 2f73a3cf0..15f731f3c 100644
--- a/server/src/services/Accounting/JournalCommands.ts
+++ b/server/src/services/Accounting/JournalCommands.ts
@@ -350,7 +350,7 @@ export default class JournalCommands {
const costEntry = new JournalEntry({
...commonEntry,
debit: inventoryCostLot.cost,
- account: inventoryCostLot.itemEntry.costAccountId,
+ account: inventoryCostLot.costAccountId,
itemId: inventoryCostLot.itemId,
index: getIndexIncrement(),
});
diff --git a/server/src/services/Accounts/AccountsService.ts b/server/src/services/Accounts/AccountsService.ts
index 6d3647dfe..9a190454d 100644
--- a/server/src/services/Accounts/AccountsService.ts
+++ b/server/src/services/Accounts/AccountsService.ts
@@ -8,6 +8,7 @@ import {
IAccount,
IAccountsFilter,
IFilterMeta,
+ IAccountResponse
} from 'interfaces';
import {
EventDispatcher,
@@ -38,11 +39,9 @@ export default class AccountsService {
* @param {number} accountTypeId -
* @return {IAccountType}
*/
- private getAccountTypeOrThrowError(
- accountTypeKey: string
- ) {
+ private getAccountTypeOrThrowError(accountTypeKey: string) {
this.logger.info('[accounts] validating account type existance.', {
- accountTypeKey
+ accountTypeKey,
});
const accountType = AccountTypesUtils.getType(accountTypeKey);
@@ -298,7 +297,7 @@ export default class AccountsService {
}
// Update the account on the storage.
const account = await accountRepository.update(
- { ...accountDTO, },
+ { ...accountDTO },
{ id: oldAccount.id }
);
this.logger.info('[account] account edited successfully.', {
@@ -549,9 +548,9 @@ export default class AccountsService {
{ accountsIds }
);
// Activate or inactivate the given accounts ids in bulk.
- (activate) ?
- await accountRepository.activateByIds(patchAccountsIds) :
- await accountRepository.inactivateByIds(patchAccountsIds);
+ activate
+ ? await accountRepository.activateByIds(patchAccountsIds)
+ : await accountRepository.inactivateByIds(patchAccountsIds);
this.logger.info('[account] accounts have been activated successfully.', {
tenantId,
@@ -587,9 +586,9 @@ export default class AccountsService {
const patchAccountsIds = [...dependenciesAccounts, accountId];
// Activate and inactivate the given accounts ids.
- (activate) ?
- await accountRepository.activateByIds(patchAccountsIds) :
- await accountRepository.inactivateByIds(patchAccountsIds);
+ activate
+ ? await accountRepository.activateByIds(patchAccountsIds)
+ : await accountRepository.inactivateByIds(patchAccountsIds);
this.logger.info('[account] account have been activated successfully.', {
tenantId,
@@ -607,7 +606,7 @@ export default class AccountsService {
public async getAccountsList(
tenantId: number,
filter: IAccountsFilter
- ): Promise<{ accounts: IAccount[]; filterMeta: IFilterMeta }> {
+ ): Promise<{ accounts: IAccountResponse[]; filterMeta: IFilterMeta }> {
const { Account } = this.tenancy.models(tenantId);
const dynamicList = await this.dynamicListService.dynamicList(
tenantId,
@@ -624,11 +623,27 @@ export default class AccountsService {
});
return {
- accounts,
+ accounts: this.transformAccountsResponse(tenantId, accounts),
filterMeta: dynamicList.getResponseMeta(),
};
}
+ /**
+ * Transformes the accounts models to accounts response.
+ */
+ private transformAccountsResponse(tenantId: number, accounts: IAccount[]) {
+ const settings = this.tenancy.settings(tenantId);
+ const baseCurrency = settings.get({
+ group: 'organization',
+ key: 'base_currency',
+ });
+
+ return accounts.map((account) => ({
+ ...account,
+ currencyCode: baseCurrency,
+ }));
+ }
+
/**
* Closes the given account.
* -----------
@@ -655,9 +670,7 @@ export default class AccountsService {
deleteAfterClosing,
});
const { AccountTransaction } = this.tenancy.models(tenantId);
- const {
- accountRepository,
- } = this.tenancy.repositories(tenantId);
+ const { accountRepository } = this.tenancy.repositories(tenantId);
const account = await this.getAccountOrThrowError(tenantId, accountId);
const toAccount = await this.getAccountOrThrowError(tenantId, toAccountId);
diff --git a/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts b/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts
index 2fd256057..c166e123a 100644
--- a/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts
+++ b/server/src/services/FinancialStatements/BalanceSheet/BalanceSheet.ts
@@ -8,6 +8,7 @@ import {
IAccount,
IJournalPoster,
IAccountType,
+ INumberFormatQuery,
} from 'interfaces';
import { dateRangeCollection, flatToNestedArray } from 'utils';
import BalanceSheetStructure from 'data/BalanceSheetStructure';
@@ -21,6 +22,7 @@ export default class BalanceSheetStatement extends FinancialSheet {
readonly comparatorDateType: string;
readonly dateRangeSet: string[];
readonly baseCurrency: string;
+ readonly numberFormat: INumberFormatQuery;
/**
* Constructor method.
diff --git a/server/src/services/FinancialStatements/FinancialSheet.ts b/server/src/services/FinancialStatements/FinancialSheet.ts
index df78de504..64ef0cc5b 100644
--- a/server/src/services/FinancialStatements/FinancialSheet.ts
+++ b/server/src/services/FinancialStatements/FinancialSheet.ts
@@ -2,7 +2,8 @@ import { IFormatNumberSettings, INumberFormatQuery } from 'interfaces';
import { formatNumber } from 'utils';
export default class FinancialSheet {
- numberFormat: INumberFormatQuery;
+ readonly numberFormat: INumberFormatQuery;
+ readonly baseCurrency: string;
/**
* Transformes the number format query to settings
@@ -16,6 +17,7 @@ export default class FinancialSheet {
excerptZero: !numberFormat.showZero,
negativeFormat: numberFormat.negativeFormat,
money: numberFormat.formatMoney === 'always',
+ currencyCode: this.baseCurrency,
};
}
diff --git a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts
index 98e9b0823..0a27147ce 100644
--- a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts
+++ b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts
@@ -48,7 +48,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* @param {number} itemId
* @returns
*/
- getItemTransaction(
+ private getItemTransaction(
transactionsMap: Map,
itemId: number,
): { cost: number, quantity: number } {
@@ -64,7 +64,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* Retrieve the cost and quantity of the givne item from `IN` transactions.
* @param {number} itemId -
*/
- getItemINTransaction(
+ private getItemINTransaction(
itemId: number,
): { cost: number, quantity: number } {
return this.getItemTransaction(this.INInventoryCostLots, itemId);
@@ -74,7 +74,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* Retrieve the cost and quantity of the given item from `OUT` transactions.
* @param {number} itemId -
*/
- getItemOUTTransaction(
+ private getItemOUTTransaction(
itemId: number,
): { cost: number, quantity: number } {
return this.getItemTransaction(this.OUTInventoryCostLots, itemId);
@@ -84,7 +84,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* Retrieve the item closing valuation.
* @param {number} itemId - Item id.
*/
- getItemValuation(itemId: number): number {
+ private getItemValuation(itemId: number): number {
const { cost: INValuation } = this.getItemINTransaction(itemId);
const { cost: OUTValuation } = this.getItemOUTTransaction(itemId);
@@ -95,7 +95,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* Retrieve the item closing quantity.
* @param {number} itemId - Item id.
*/
- getItemQuantity(itemId: number): number {
+ private getItemQuantity(itemId: number): number {
const { quantity: INQuantity } = this.getItemINTransaction(itemId);
const { quantity: OUTQuantity } = this.getItemOUTTransaction(itemId);
@@ -108,7 +108,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* @param {number} quantity
* @returns {number}
*/
- calcAverage(valuation: number, quantity: number): number {
+ private calcAverage(valuation: number, quantity: number): number {
return quantity ? valuation / quantity : 0;
}
@@ -117,7 +117,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* @param {IItem} item
* @returns {IInventoryValuationItem}
*/
- itemMapper(item: IItem): IInventoryValuationItem {
+ private itemMapper(item: IItem): IInventoryValuationItem {
const valuation = this.getItemValuation(item.id);
const quantity = this.getItemQuantity(item.id);
const average = this.calcAverage(valuation, quantity);
@@ -140,7 +140,7 @@ export default class InventoryValuationSheet extends FinancialSheet {
* Retrieve the inventory valuation items.
* @returns {IInventoryValuationItem[]}
*/
- itemsSection(): IInventoryValuationItem[] {
+ private itemsSection(): IInventoryValuationItem[] {
return this.items.map(this.itemMapper.bind(this));
}
@@ -149,15 +149,15 @@ export default class InventoryValuationSheet extends FinancialSheet {
* @param {IInventoryValuationItem[]} items
* @returns {IInventoryValuationTotal}
*/
- totalSection(items: IInventoryValuationItem[]): IInventoryValuationTotal {
+ private totalSection(items: IInventoryValuationItem[]): IInventoryValuationTotal {
const valuation = sumBy(items, item => item.valuation);
const quantity = sumBy(items, item => item.quantity);
return {
valuation,
quantity,
- valuationFormatted: this.formatNumber(valuation),
- quantityFormatted: this.formatNumber(quantity, { money: false }),
+ valuationFormatted: this.formatTotalNumber(valuation),
+ quantityFormatted: this.formatTotalNumber(quantity, { money: false }),
};
}
@@ -165,10 +165,10 @@ export default class InventoryValuationSheet extends FinancialSheet {
* Retrieve the inventory valuation report data.
* @returns {IInventoryValuationStatement}
*/
- reportData(): IInventoryValuationStatement {
+ public reportData(): IInventoryValuationStatement {
const items = this.itemsSection();
const total = this.totalSection(items);
- return { items, total };
+ return items.length > 0 ? { items, total } : {};
}
}
\ No newline at end of file
diff --git a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts
index d9f833b58..fe818b419 100644
--- a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts
+++ b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts
@@ -6,6 +6,7 @@ import {
} from 'interfaces';
import TenancyService from 'services/Tenancy/TenancyService';
import InventoryValuationSheet from './InventoryValuationSheet';
+import InventoryService from 'services/Inventory/Inventory';
@Service()
export default class InventoryValuationSheetService {
@@ -15,6 +16,9 @@ export default class InventoryValuationSheetService {
@Inject('logger')
logger: any;
+ @Inject()
+ inventoryService: InventoryService;
+
/**
* Defaults balance sheet filter query.
* @return {IBalanceSheetQuery}
@@ -41,6 +45,9 @@ export default class InventoryValuationSheetService {
reportMetadata(tenantId: number): IInventoryValuationSheetMeta {
const settings = this.tenancy.settings(tenantId);
+ const isCostComputeRunning = this.inventoryService
+ .isItemsCostComputeRunning(tenantId);
+
const organizationName = settings.get({
group: 'organization',
key: 'name',
@@ -53,6 +60,7 @@ export default class InventoryValuationSheetService {
return {
organizationName,
baseCurrency,
+ isCostComputeRunning
};
}
diff --git a/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts b/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts
index 313eb58f9..3c8df9d5e 100644
--- a/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts
+++ b/server/src/services/FinancialStatements/JournalSheet/JournalSheet.ts
@@ -10,10 +10,10 @@ import {
import FinancialSheet from '../FinancialSheet';
export default class JournalSheet extends FinancialSheet {
- tenantId: number;
- journal: IJournalPoster;
- query: IJournalReportQuery;
- baseCurrency: string;
+ readonly tenantId: number;
+ readonly journal: IJournalPoster;
+ readonly query: IJournalReportQuery;
+ readonly baseCurrency: string;
readonly contactsById: Map;
/**
diff --git a/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts b/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts
index 99455a886..7723b1598 100644
--- a/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts
+++ b/server/src/services/FinancialStatements/JournalSheet/JournalSheetService.ts
@@ -76,6 +76,8 @@ export default class JournalSheetService {
contactRepository,
} = this.tenancy.repositories(tenantId);
+ const { AccountTransaction } = this.tenancy.models(tenantId);
+
const filter = {
...this.defaultQuery,
...query,
@@ -98,12 +100,12 @@ export default class JournalSheetService {
const contactsByIdMap = transformToMap(contacts, 'id');
// Retrieve all journal transactions based on the given query.
- const transactions = await transactionsRepository.journal({
- fromDate: filter.fromDate,
- toDate: filter.toDate,
- transactionsTypes: filter.transactionTypes,
- fromAmount: filter.fromRange,
- toAmount: filter.toRange,
+ const transactions = await AccountTransaction.query().onBuild((query) => {
+ if (filter.fromRange || filter.toRange) {
+ query.modify('filterAmountRange', filter.fromRange, filter.toRange);
+ }
+ query.modify('filterDateRange', filter.fromDate, filter.toDate);
+ query.orderBy(['date', 'createdAt', 'indexGroup', 'index']);
});
// Transform the transactions array to journal collection.
const transactionsJournal = Journal.fromTransactions(
diff --git a/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts b/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts
index c6b119ae7..a507ba590 100644
--- a/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts
+++ b/server/src/services/FinancialStatements/PurchasesByItems/PurchasesByItems.ts
@@ -99,10 +99,10 @@ export default class InventoryValuationReport extends FinancialSheet {
return {
quantityPurchased,
purchaseCost,
- quantityPurchasedFormatted: this.formatNumber(quantityPurchased, {
+ quantityPurchasedFormatted: this.formatTotalNumber(quantityPurchased, {
money: false,
}),
- purchaseCostFormatted: this.formatNumber(purchaseCost),
+ purchaseCostFormatted: this.formatTotalNumber(purchaseCost),
currencyCode: this.baseCurrency,
};
}
@@ -115,6 +115,6 @@ export default class InventoryValuationReport extends FinancialSheet {
const items = this.itemsSection();
const total = this.totalSection(items);
- return { items, total };
+ return items.length > 0 ? { items, total } : {};
}
}
diff --git a/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts b/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts
index d527609a7..cde8721b0 100644
--- a/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts
+++ b/server/src/services/FinancialStatements/SalesByItems/SalesByItems.ts
@@ -99,10 +99,10 @@ export default class SalesByItemsReport extends FinancialSheet {
return {
quantitySold,
soldCost,
- quantitySoldFormatted: this.formatNumber(quantitySold, {
+ quantitySoldFormatted: this.formatTotalNumber(quantitySold, {
money: false,
}),
- soldCostFormatted: this.formatNumber(soldCost),
+ soldCostFormatted: this.formatTotalNumber(soldCost),
currencyCode: this.baseCurrency,
};
}
@@ -115,6 +115,6 @@ export default class SalesByItemsReport extends FinancialSheet {
const items = this.itemsSection();
const total = this.totalSection(items);
- return { items, total };
+ return items.length > 0 ? { items, total } : {};
}
}
diff --git a/server/src/services/Inventory/Inventory.ts b/server/src/services/Inventory/Inventory.ts
index d98686548..64b03fa15 100644
--- a/server/src/services/Inventory/Inventory.ts
+++ b/server/src/services/Inventory/Inventory.ts
@@ -55,6 +55,7 @@ export default class InventoryService {
date: transaction.date,
entryId: entry.id,
createdAt: transaction.createdAt,
+ costAccountId: entry.costAccountId,
}));
}
diff --git a/server/src/services/Inventory/InventoryAdjustmentService.ts b/server/src/services/Inventory/InventoryAdjustmentService.ts
index b953859ec..2019c4a94 100644
--- a/server/src/services/Inventory/InventoryAdjustmentService.ts
+++ b/server/src/services/Inventory/InventoryAdjustmentService.ts
@@ -20,7 +20,6 @@ import ItemsService from 'services/Items/ItemsService';
import DynamicListingService from 'services/DynamicListing/DynamicListService';
import HasTenancyService from 'services/Tenancy/TenancyService';
import InventoryService from './Inventory';
-import { increment } from 'utils';
const ERRORS = {
INVENTORY_ADJUSTMENT_NOT_FOUND: 'INVENTORY_ADJUSTMENT_NOT_FOUND',
diff --git a/server/src/services/Inventory/InventoryAverageCost.ts b/server/src/services/Inventory/InventoryAverageCost.ts
index f5a55c42f..ca7801dd6 100644
--- a/server/src/services/Inventory/InventoryAverageCost.ts
+++ b/server/src/services/Inventory/InventoryAverageCost.ts
@@ -165,6 +165,8 @@ export default class InventoryAverageCostMethod
'transactionId',
'transactionType',
'createdAt',
+
+ 'costAccountId',
]),
};
switch (invTransaction.direction) {
diff --git a/server/src/services/Purchases/BillPayments/BillPayments.ts b/server/src/services/Purchases/BillPayments/BillPayments.ts
index 28947c38d..896f6c5dc 100644
--- a/server/src/services/Purchases/BillPayments/BillPayments.ts
+++ b/server/src/services/Purchases/BillPayments/BillPayments.ts
@@ -25,7 +25,7 @@ import TenancyService from 'services/Tenancy/TenancyService';
import DynamicListingService from 'services/DynamicListing/DynamicListService';
import { entriesAmountDiff, formatDateFields } from 'utils';
import { ServiceError } from 'exceptions';
-import { ACCOUNT_PARENT_TYPE } from 'data/AccountTypes';
+import { ACCOUNT_PARENT_TYPE, ACCOUNT_TYPE } from 'data/AccountTypes';
import VendorsService from 'services/Contacts/VendorsService';
import { ERRORS } from './constants';
@@ -113,7 +113,14 @@ export default class BillPaymentsService implements IBillPaymentsService {
if (!paymentAccount) {
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_FOUND);
}
- if (!paymentAccount.isParentType(ACCOUNT_PARENT_TYPE.CURRENT_ASSET)) {
+ // Validate the payment account type.
+ if (
+ !paymentAccount.isAccountType([
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ])
+ ) {
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE);
}
return paymentAccount;
diff --git a/server/src/services/Sales/PaymentReceives/PaymentsReceives.ts b/server/src/services/Sales/PaymentReceives/PaymentsReceives.ts
index 51aa786c0..0db0a1931 100644
--- a/server/src/services/Sales/PaymentReceives/PaymentsReceives.ts
+++ b/server/src/services/Sales/PaymentReceives/PaymentsReceives.ts
@@ -30,7 +30,7 @@ import { ServiceError } from 'exceptions';
import CustomersService from 'services/Contacts/CustomersService';
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
import JournalCommands from 'services/Accounting/JournalCommands';
-import { ACCOUNT_PARENT_TYPE } from 'data/AccountTypes';
+import { ACCOUNT_PARENT_TYPE, ACCOUNT_TYPE } from 'data/AccountTypes';
import AutoIncrementOrdersService from '../AutoIncrementOrdersService';
import { ERRORS } from './constants';
@@ -129,8 +129,14 @@ export default class PaymentReceiveService implements IPaymentsReceiveService {
if (!depositAccount) {
throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_NOT_FOUND);
}
- // Detarmines whether the account is cash equivalents.
- if (!depositAccount.isParentType(ACCOUNT_PARENT_TYPE.CURRENT_ASSET)) {
+ // Detarmines whether the account is cash, bank or other current asset.
+ if (
+ !depositAccount.isAccountType([
+ ACCOUNT_TYPE.CASH,
+ ACCOUNT_TYPE.BANK,
+ ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
+ ])
+ ) {
throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_INVALID_TYPE);
}
return depositAccount;
diff --git a/server/src/utils/index.ts b/server/src/utils/index.ts
index 82246a0f2..0e1f83bd4 100644
--- a/server/src/utils/index.ts
+++ b/server/src/utils/index.ts
@@ -2,6 +2,7 @@ import bcrypt from 'bcryptjs';
import moment from 'moment';
import _ from 'lodash';
import accounting from 'accounting';
+import Currencies from 'js-money/lib/currency';
import definedOptions from 'data/options';
const hashPassword = (password) =>
@@ -224,6 +225,10 @@ const getNegativeFormat = (formatName) => {
}
};
+const getCurrencySign = (currencyCode) => {
+ return _.get(Currencies, `${currencyCode}.symbol`);
+};
+
const formatNumber = (
balance,
{
@@ -234,10 +239,11 @@ const formatNumber = (
thousand = ',',
decimal = '.',
zeroSign = '',
- symbol = '$',
money = true,
+ currencyCode
}
) => {
+ const symbol = getCurrencySign(currencyCode);
const negForamt = getNegativeFormat(negativeFormat);
const format = '%s%v';