mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 00:00:31 +00:00
fix: base currency from organization metadata.
This commit is contained in:
@@ -58,11 +58,6 @@ export default class ItemsController extends BaseController {
|
|||||||
asyncMiddleware(this.deleteItem.bind(this)),
|
asyncMiddleware(this.deleteItem.bind(this)),
|
||||||
this.handlerServiceErrors
|
this.handlerServiceErrors
|
||||||
);
|
);
|
||||||
router.get(
|
|
||||||
'/auto-complete',
|
|
||||||
this.autocompleteQuerySchema,
|
|
||||||
this.asyncMiddleware(this.autocompleteList.bind(this)),
|
|
||||||
);
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:id',
|
'/:id',
|
||||||
[...this.validateSpecificItemSchema],
|
[...this.validateSpecificItemSchema],
|
||||||
@@ -325,10 +320,10 @@ export default class ItemsController extends BaseController {
|
|||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const storedItem = await this.itemsService.getItem(tenantId, itemId);
|
const item = await this.itemsService.getItem(tenantId, itemId);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
item: this.transfromToResponse(storedItem)
|
item: this.transfromToResponse(item)
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
@@ -369,38 +364,6 @@ export default class ItemsController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Auto-complete list.
|
|
||||||
* @param {Request} req
|
|
||||||
* @param {Response} res
|
|
||||||
* @param {NextFunction} next
|
|
||||||
*/
|
|
||||||
async autocompleteList(req: Request, res: Response, next: NextFunction) {
|
|
||||||
const { tenantId } = req;
|
|
||||||
const filter = {
|
|
||||||
filterRoles: [],
|
|
||||||
sortOrder: 'asc',
|
|
||||||
columnSortBy: 'name',
|
|
||||||
limit: 10,
|
|
||||||
keyword: '',
|
|
||||||
...this.matchedQueryData(req),
|
|
||||||
};
|
|
||||||
if (filter.stringifiedFilterRoles) {
|
|
||||||
filter.filterRoles = JSON.parse(filter.stringifiedFilterRoles);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const items = await this.itemsService.autocompleteItems(
|
|
||||||
tenantId,
|
|
||||||
filter
|
|
||||||
);
|
|
||||||
return res.status(200).send({
|
|
||||||
items: this.transfromToResponse(items),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
next(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles service errors.
|
* Handles service errors.
|
||||||
* @param {Error} error
|
* @param {Error} error
|
||||||
|
|||||||
@@ -2,6 +2,14 @@ import moment from "moment";
|
|||||||
import { isEmpty, isObject, isUndefined } from 'lodash';
|
import { isEmpty, isObject, isUndefined } from 'lodash';
|
||||||
|
|
||||||
export class Transformer {
|
export class Transformer {
|
||||||
|
meta: any;
|
||||||
|
|
||||||
|
setMeta(meta) {
|
||||||
|
this.meta = meta;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Includeded attributes.
|
* Includeded attributes.
|
||||||
* @returns
|
* @returns
|
||||||
@@ -23,7 +31,7 @@ export class Transformer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Transformes the given item to desired output.
|
||||||
* @param item
|
* @param item
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { IAccount } from 'interfaces';
|
|||||||
import { Transformer } from 'lib/Transformer/Transformer';
|
import { Transformer } from 'lib/Transformer/Transformer';
|
||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class AccountTransformer extends Transformer {
|
export default class AccountTransformer extends Transformer {
|
||||||
/**
|
/**
|
||||||
* Include these attributes to sale invoice object.
|
* Include these attributes to sale invoice object.
|
||||||
@@ -12,6 +11,7 @@ export default class AccountTransformer extends Transformer {
|
|||||||
protected includeAttributes = (): string[] => {
|
protected includeAttributes = (): string[] => {
|
||||||
return [
|
return [
|
||||||
'formattedAmount',
|
'formattedAmount',
|
||||||
|
'currencyCode'
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,7 +22,15 @@ export default class AccountTransformer extends Transformer {
|
|||||||
*/
|
*/
|
||||||
protected formattedAmount = (account: IAccount): string => {
|
protected formattedAmount = (account: IAccount): string => {
|
||||||
return formatNumber(account.amount, {
|
return formatNumber(account.amount, {
|
||||||
currencyCode: account.currencyCode,
|
currencyCode: this.meta.baseCurrency,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve account currency code.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected currencyCode = (): string => {
|
||||||
|
return this.meta.baseCurrency;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { ERRORS } from './constants';
|
|||||||
import { flatToNestedArray } from 'utils';
|
import { flatToNestedArray } from 'utils';
|
||||||
import I18nService from 'services/I18n/I18nService';
|
import I18nService from 'services/I18n/I18nService';
|
||||||
import AccountTransformer from './AccountTransform';
|
import AccountTransformer from './AccountTransform';
|
||||||
|
import { Tenant } from 'system/models';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class AccountsService {
|
export default class AccountsService {
|
||||||
@@ -331,9 +332,13 @@ export default class AccountsService {
|
|||||||
public async getAccount(tenantId: number, accountId: number) {
|
public async getAccount(tenantId: number, accountId: number) {
|
||||||
const account = await this.getAccountOrThrowError(tenantId, accountId);
|
const account = await this.getAccountOrThrowError(tenantId, accountId);
|
||||||
|
|
||||||
return this.accountTransformer.transform(
|
const tenant = await Tenant.query()
|
||||||
this.transformAccountResponse(tenantId, account)
|
.findById(tenantId)
|
||||||
);
|
.withGraphFetched('metadata');
|
||||||
|
|
||||||
|
return new AccountTransformer()
|
||||||
|
.setMeta({ baseCurrency: tenant.metadata.baseCurrency })
|
||||||
|
.transform(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -649,8 +654,12 @@ export default class AccountsService {
|
|||||||
builder.modify('inactiveMode', filter.inactiveMode);
|
builder.modify('inactiveMode', filter.inactiveMode);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const transformedAccounts = await this.transformAccountsResponse(
|
||||||
|
tenantId,
|
||||||
|
accounts
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
accounts: this.transformAccountsResponse(tenantId, accounts),
|
accounts: transformedAccounts,
|
||||||
filterMeta: dynamicList.getResponseMeta(),
|
filterMeta: dynamicList.getResponseMeta(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -733,21 +742,26 @@ export default class AccountsService {
|
|||||||
/**
|
/**
|
||||||
* Transformes the accounts models to accounts response.
|
* Transformes the accounts models to accounts response.
|
||||||
*/
|
*/
|
||||||
private transformAccountsResponse(tenantId: number, accounts: IAccount[]) {
|
private async transformAccountsResponse(
|
||||||
const settings = this.tenancy.settings(tenantId);
|
tenantId: number,
|
||||||
const baseCurrency = settings.get({
|
accounts: IAccount[]
|
||||||
group: 'organization',
|
) {
|
||||||
key: 'base_currency',
|
const tenant = await Tenant.query()
|
||||||
});
|
.findById(tenantId)
|
||||||
|
.withGraphFetched('metadata');
|
||||||
|
|
||||||
|
const transformed = new AccountTransformer()
|
||||||
|
.setMeta({
|
||||||
|
baseCurrency: tenant.metadata?.baseCurrency,
|
||||||
|
})
|
||||||
|
.transform(accounts);
|
||||||
|
|
||||||
const _accounts = this.accountTransformer.transform(
|
|
||||||
accounts.map((account) => ({
|
|
||||||
...account.toJSON(),
|
|
||||||
currencyCode: baseCurrency,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
return flatToNestedArray(
|
return flatToNestedArray(
|
||||||
this.i18nService.i18nMapper(_accounts, ['account_type_label'], tenantId),
|
this.i18nService.i18nMapper(
|
||||||
|
transformed,
|
||||||
|
['account_type_label'],
|
||||||
|
tenantId
|
||||||
|
),
|
||||||
{
|
{
|
||||||
id: 'id',
|
id: 'id',
|
||||||
parentId: 'parent_account_id',
|
parentId: 'parent_account_id',
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { Transformer } from 'lib/Transformer/Transformer';
|
|||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
import { IContact } from 'interfaces';
|
import { IContact } from 'interfaces';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class ContactTransfromer extends Transformer {
|
export default class ContactTransfromer extends Transformer {
|
||||||
/**
|
/**
|
||||||
* Retrieve formatted expense amount.
|
* Retrieve formatted expense amount.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import ContactTransfromer from '../ContactTransformer';
|
import ContactTransfromer from '../ContactTransformer';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class CustomerTransfromer extends ContactTransfromer {
|
export default class CustomerTransfromer extends ContactTransfromer {
|
||||||
/**
|
/**
|
||||||
* Include these attributes to expense object.
|
* Include these attributes to expense object.
|
||||||
@@ -11,7 +10,16 @@ export default class CustomerTransfromer extends ContactTransfromer {
|
|||||||
return [
|
return [
|
||||||
'formattedBalance',
|
'formattedBalance',
|
||||||
'formattedOpeningBalance',
|
'formattedOpeningBalance',
|
||||||
'formattedOpeningBalanceAt'
|
'formattedOpeningBalanceAt',
|
||||||
|
'customerType'
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve customer type.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected customerType = (customer): string => {
|
||||||
|
return customer.contactType;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,6 @@ export default class CustomersService {
|
|||||||
@Inject('SalesEstimates')
|
@Inject('SalesEstimates')
|
||||||
estimatesService: ISalesEstimatesService;
|
estimatesService: ISalesEstimatesService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
customerTransformer: CustomerTransfromer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts customer to contact DTO.
|
* Converts customer to contact DTO.
|
||||||
* @param {ICustomerNewDTO|ICustomerEditDTO} customerDTO
|
* @param {ICustomerNewDTO|ICustomerEditDTO} customerDTO
|
||||||
@@ -266,10 +263,7 @@ export default class CustomersService {
|
|||||||
customerId,
|
customerId,
|
||||||
'customer'
|
'customer'
|
||||||
);
|
);
|
||||||
return R.compose(
|
return new CustomerTransfromer().transform(contact);
|
||||||
this.customerTransformer.transform,
|
|
||||||
this.transformContactToCustomer,
|
|
||||||
)(contact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -315,8 +309,10 @@ export default class CustomersService {
|
|||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
const transformedCustomers = new CustomerTransfromer().transform(results);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customers: results.map(this.transformContactToCustomer),
|
customers: transformedCustomers,
|
||||||
pagination,
|
pagination,
|
||||||
filterMeta: dynamicList.getResponseMeta(),
|
filterMeta: dynamicList.getResponseMeta(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import ContactTransfromer from '../ContactTransformer';
|
import ContactTransfromer from '../ContactTransformer';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class VendorTransfromer extends ContactTransfromer {
|
export default class VendorTransfromer extends ContactTransfromer {
|
||||||
/**
|
/**
|
||||||
* Include these attributes to expense object.
|
* Include these attributes to expense object.
|
||||||
|
|||||||
@@ -52,9 +52,6 @@ export default class VendorsService {
|
|||||||
@Inject('BillPayments')
|
@Inject('BillPayments')
|
||||||
billPaymentsService: IBillPaymentsService;
|
billPaymentsService: IBillPaymentsService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
vendorTransformer: VendorTransfromer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts vendor to contact DTO.
|
* Converts vendor to contact DTO.
|
||||||
* @param {IVendorNewDTO|IVendorEditDTO} vendorDTO
|
* @param {IVendorNewDTO|IVendorEditDTO} vendorDTO
|
||||||
@@ -202,9 +199,13 @@ export default class VendorsService {
|
|||||||
* @param {number} vendorId
|
* @param {number} vendorId
|
||||||
*/
|
*/
|
||||||
public async getVendor(tenantId: number, vendorId: number) {
|
public async getVendor(tenantId: number, vendorId: number) {
|
||||||
const vendor = await this.contactService.getContact(tenantId, vendorId, 'vendor');
|
const vendor = await this.contactService.getContact(
|
||||||
|
tenantId,
|
||||||
|
vendorId,
|
||||||
|
'vendor'
|
||||||
|
);
|
||||||
|
|
||||||
return this.vendorTransformer.transform(vendor);
|
return new VendorTransfromer().transform(vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,8 +303,11 @@ export default class VendorsService {
|
|||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
// Transform the vendors.
|
||||||
|
const transformedVendors = new VendorTransfromer().transform(results);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
vendors: this.vendorTransformer.transform(results),
|
vendors: transformedVendors,
|
||||||
pagination,
|
pagination,
|
||||||
filterMeta: dynamicList.getResponseMeta(),
|
filterMeta: dynamicList.getResponseMeta(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export default class FinancialReportService {
|
||||||
|
transformOrganizationMeta(tenant) {
|
||||||
|
return {
|
||||||
|
organizationName: tenant.metadata?.name,
|
||||||
|
baseCurrency: tenant.metadata?.baseCurrency,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
34
server/src/services/Items/ItemTransformer.ts
Normal file
34
server/src/services/Items/ItemTransformer.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Transformer } from 'lib/Transformer/Transformer';
|
||||||
|
import { formatNumber } from 'utils';
|
||||||
|
|
||||||
|
export default class ItemTransformer extends Transformer {
|
||||||
|
/**
|
||||||
|
* Include these attributes to sale invoice object.
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
protected includeAttributes = (): string[] => {
|
||||||
|
return ['sellPriceFormatted', 'costPriceFormatted'];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatted sell price.
|
||||||
|
* @param item
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
public sellPriceFormatted(item): string {
|
||||||
|
return formatNumber(item.sellPrice, {
|
||||||
|
currencyCode: this.meta.baseCurrency,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatted cost price.
|
||||||
|
* @param item
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
public costPriceFormatted(item): string {
|
||||||
|
return formatNumber(item.costPrice, {
|
||||||
|
currencyCode: this.meta.baseCurrency,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,8 @@ import {
|
|||||||
ACCOUNT_TYPE,
|
ACCOUNT_TYPE,
|
||||||
} from 'data/AccountTypes';
|
} from 'data/AccountTypes';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import { formatNumber } from 'utils';
|
import ItemTransformer from './ItemTransformer';
|
||||||
|
import { Tenant } from 'system/models';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class ItemsService implements IItemsService {
|
export default class ItemsService implements IItemsService {
|
||||||
@@ -506,11 +507,6 @@ export default class ItemsService implements IItemsService {
|
|||||||
public async getItem(tenantId: number, itemId: number): Promise<IItem> {
|
public async getItem(tenantId: number, itemId: number): Promise<IItem> {
|
||||||
const { Item } = this.tenancy.models(tenantId);
|
const { Item } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
this.logger.info('[items] trying to get the specific item.', {
|
|
||||||
tenantId,
|
|
||||||
itemId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const item = await Item.query()
|
const item = await Item.query()
|
||||||
.findById(itemId)
|
.findById(itemId)
|
||||||
.withGraphFetched('sellAccount')
|
.withGraphFetched('sellAccount')
|
||||||
@@ -518,10 +514,19 @@ export default class ItemsService implements IItemsService {
|
|||||||
.withGraphFetched('category')
|
.withGraphFetched('category')
|
||||||
.withGraphFetched('costAccount');
|
.withGraphFetched('costAccount');
|
||||||
|
|
||||||
|
// Can't continue if the item not found.
|
||||||
if (!item) {
|
if (!item) {
|
||||||
throw new ServiceError(ERRORS.NOT_FOUND);
|
throw new ServiceError(ERRORS.NOT_FOUND);
|
||||||
}
|
}
|
||||||
return this.transformItemToResponse(tenantId, item);
|
// Retrieve tenant and tenant information.
|
||||||
|
const tenant = await Tenant.query()
|
||||||
|
.findById(tenantId)
|
||||||
|
.withGraphFetched('metadata');
|
||||||
|
|
||||||
|
const baseCurrency = tenant.metadata?.baseCurrency;
|
||||||
|
|
||||||
|
// Transformes the item model.
|
||||||
|
return new ItemTransformer().setMeta({ baseCurrency }).transform(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -529,9 +534,7 @@ export default class ItemsService implements IItemsService {
|
|||||||
* @param {} filterDTO - Filter DTO.
|
* @param {} filterDTO - Filter DTO.
|
||||||
*/
|
*/
|
||||||
private parseItemsListFilterDTO(filterDTO) {
|
private parseItemsListFilterDTO(filterDTO) {
|
||||||
return R.compose(
|
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
||||||
this.dynamicListService.parseStringifiedFilter,
|
|
||||||
)(filterDTO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -564,45 +567,24 @@ export default class ItemsService implements IItemsService {
|
|||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
const results = items.map((item) =>
|
// Retrieve tenant and tenant information.
|
||||||
this.transformItemToResponse(tenantId, item)
|
const tenant = await Tenant.query()
|
||||||
);
|
.findById(tenantId)
|
||||||
|
.withGraphFetched('metadata');
|
||||||
|
|
||||||
|
const transformedItems = new ItemTransformer()
|
||||||
|
.setMeta({
|
||||||
|
baseCurrency: tenant?.metadata.baseCurrency,
|
||||||
|
})
|
||||||
|
.transform(items);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
items: results,
|
items: transformedItems,
|
||||||
pagination,
|
pagination,
|
||||||
filterMeta: dynamicFilter.getResponseMeta(),
|
filterMeta: dynamicFilter.getResponseMeta(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve auto-complete items list.
|
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {IItemsAutoCompleteFilter} itemsFilter -
|
|
||||||
*/
|
|
||||||
public async autocompleteItems(
|
|
||||||
tenantId: number,
|
|
||||||
itemsFilter: IItemsAutoCompleteFilter
|
|
||||||
) {
|
|
||||||
const { Item } = this.tenancy.models(tenantId);
|
|
||||||
const dynamicFilter = await this.dynamicListService.dynamicList(
|
|
||||||
tenantId,
|
|
||||||
Item,
|
|
||||||
itemsFilter
|
|
||||||
);
|
|
||||||
const items = await Item.query().onBuild((builder) => {
|
|
||||||
builder.withGraphFetched('category');
|
|
||||||
|
|
||||||
dynamicFilter.buildQuery()(builder);
|
|
||||||
builder.limit(itemsFilter.limit);
|
|
||||||
|
|
||||||
if (itemsFilter.keyword) {
|
|
||||||
builder.where('name', 'LIKE', `%${itemsFilter.keyword}%`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return items.map((item) => this.transformItemToResponse(tenantId, item));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the given item or items have no associated invoices or bills.
|
* Validates the given item or items have no associated invoices or bills.
|
||||||
* @param {number} tenantId - Tenant id.
|
* @param {number} tenantId - Tenant id.
|
||||||
@@ -647,24 +629,4 @@ export default class ItemsService implements IItemsService {
|
|||||||
throw new ServiceError(ERRORS.ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT);
|
throw new ServiceError(ERRORS.ITEM_HAS_ASSOCIATED_INVENTORY_ADJUSTMENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transformes the item object to response.
|
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {IItem} item -
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
private transformItemToResponse(tenantId: number, item: IItem) {
|
|
||||||
// Settings tenant service.
|
|
||||||
const settings = this.tenancy.settings(tenantId);
|
|
||||||
const currencyCode = settings.get({
|
|
||||||
group: 'organization', key: 'base_currency',
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
...item.toObject ? item.toObject() : item,
|
|
||||||
sellPriceFormatted: formatNumber(item.sellPrice, { currencyCode }),
|
|
||||||
costPriceFormatted: formatNumber(item.costPrice, { currencyCode }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import JournalPosterService from 'services/Sales/JournalPosterService';
|
|||||||
import AutoIncrementOrdersService from 'services/Sales/AutoIncrementOrdersService';
|
import AutoIncrementOrdersService from 'services/Sales/AutoIncrementOrdersService';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import ManualJournalTransfromer from './ManualJournalTransformer';
|
import ManualJournalTransfromer from './ManualJournalTransformer';
|
||||||
|
import { Tenant } from 'system/models';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class ManualJournalsService implements IManualJournalsService {
|
export default class ManualJournalsService implements IManualJournalsService {
|
||||||
@@ -363,7 +364,8 @@ export default class ManualJournalsService implements IManualJournalsService {
|
|||||||
private transformNewDTOToModel(
|
private transformNewDTOToModel(
|
||||||
tenantId,
|
tenantId,
|
||||||
manualJournalDTO: IManualJournalDTO,
|
manualJournalDTO: IManualJournalDTO,
|
||||||
authorizedUser: ISystemUser
|
authorizedUser: ISystemUser,
|
||||||
|
tenantMetadata
|
||||||
) {
|
) {
|
||||||
const amount = sumBy(manualJournalDTO.entries, 'credit') || 0;
|
const amount = sumBy(manualJournalDTO.entries, 'credit') || 0;
|
||||||
const date = moment(manualJournalDTO.date).format('YYYY-MM-DD');
|
const date = moment(manualJournalDTO.date).format('YYYY-MM-DD');
|
||||||
@@ -373,12 +375,6 @@ export default class ManualJournalsService implements IManualJournalsService {
|
|||||||
|
|
||||||
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
||||||
|
|
||||||
// Settings tenant service.
|
|
||||||
const settings = this.tenancy.settings(tenantId);
|
|
||||||
const currencyCode = settings.get({
|
|
||||||
group: 'organization',
|
|
||||||
key: 'base_currency',
|
|
||||||
});
|
|
||||||
// Validate manual journal number require.
|
// Validate manual journal number require.
|
||||||
this.validateJournalNoRequire(journalNumber);
|
this.validateJournalNoRequire(journalNumber);
|
||||||
|
|
||||||
@@ -388,7 +384,7 @@ export default class ManualJournalsService implements IManualJournalsService {
|
|||||||
? { publishedAt: moment().toMySqlDateTime() }
|
? { publishedAt: moment().toMySqlDateTime() }
|
||||||
: {}),
|
: {}),
|
||||||
amount,
|
amount,
|
||||||
currencyCode,
|
currencyCode: tenantMetadata.baseCurrency,
|
||||||
date,
|
date,
|
||||||
journalNumber,
|
journalNumber,
|
||||||
userId: authorizedUser.id,
|
userId: authorizedUser.id,
|
||||||
@@ -431,11 +427,17 @@ export default class ManualJournalsService implements IManualJournalsService {
|
|||||||
): Promise<{ manualJournal: IManualJournal }> {
|
): Promise<{ manualJournal: IManualJournal }> {
|
||||||
const { ManualJournal } = this.tenancy.models(tenantId);
|
const { ManualJournal } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
//
|
||||||
|
const tenant = await Tenant.query()
|
||||||
|
.findById(tenantId)
|
||||||
|
.withGraphFetched('metadata');
|
||||||
|
|
||||||
// Transformes the next DTO to model.
|
// Transformes the next DTO to model.
|
||||||
const manualJournalObj = this.transformNewDTOToModel(
|
const manualJournalObj = this.transformNewDTOToModel(
|
||||||
tenantId,
|
tenantId,
|
||||||
manualJournalDTO,
|
manualJournalDTO,
|
||||||
authorizedUser
|
authorizedUser,
|
||||||
|
tenant.metadata,
|
||||||
);
|
);
|
||||||
// Validate the total credit should equals debit.
|
// Validate the total credit should equals debit.
|
||||||
this.valdiateCreditDebitTotalEquals(manualJournalDTO);
|
this.valdiateCreditDebitTotalEquals(manualJournalDTO);
|
||||||
@@ -657,13 +659,11 @@ export default class ManualJournalsService implements IManualJournalsService {
|
|||||||
manualJournalsIds
|
manualJournalsIds
|
||||||
);
|
);
|
||||||
// Filters the not published journals.
|
// Filters the not published journals.
|
||||||
const notPublishedJournals = this.getNonePublishedManualJournals(
|
const notPublishedJournals =
|
||||||
oldManualJournals
|
this.getNonePublishedManualJournals(oldManualJournals);
|
||||||
);
|
|
||||||
// Filters the published journals.
|
// Filters the published journals.
|
||||||
const publishedJournals = this.getPublishedManualJournals(
|
const publishedJournals =
|
||||||
oldManualJournals
|
this.getPublishedManualJournals(oldManualJournals);
|
||||||
);
|
|
||||||
// Mappes the not-published journals to get id.
|
// Mappes the not-published journals to get id.
|
||||||
const notPublishedJournalsIds = map(notPublishedJournals, 'id');
|
const notPublishedJournalsIds = map(notPublishedJournals, 'id');
|
||||||
|
|
||||||
@@ -775,18 +775,16 @@ export default class ManualJournalsService implements IManualJournalsService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses filter DTO of the manual journals list.
|
* Parses filter DTO of the manual journals list.
|
||||||
* @param filterDTO
|
* @param filterDTO
|
||||||
*/
|
*/
|
||||||
private parseListFilterDTO(filterDTO) {
|
private parseListFilterDTO(filterDTO) {
|
||||||
return R.compose(
|
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
||||||
this.dynamicListService.parseStringifiedFilter
|
|
||||||
)(filterDTO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve manual journals datatable list.
|
* Retrieve manual journals datatable list.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
* @param {IManualJournalsFilter} filter -
|
* @param {IManualJournalsFilter} filter -
|
||||||
*/
|
*/
|
||||||
public async getManualJournals(
|
public async getManualJournals(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { ISaleEstimate } from 'interfaces';
|
|||||||
import { Transformer } from 'lib/Transformer/Transformer';
|
import { Transformer } from 'lib/Transformer/Transformer';
|
||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class SaleEstimateTransfromer extends Transformer {
|
export default class SaleEstimateTransfromer extends Transformer {
|
||||||
/**
|
/**
|
||||||
* Include these attributes to sale invoice object.
|
* Include these attributes to sale invoice object.
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { IPaymentReceive } from 'interfaces';
|
|||||||
import { Transformer } from 'lib/Transformer/Transformer';
|
import { Transformer } from 'lib/Transformer/Transformer';
|
||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class PaymentReceiveTransfromer extends Transformer {
|
export default class PaymentReceiveTransfromer extends Transformer {
|
||||||
/**
|
/**
|
||||||
* Include these attributes to payment receive object.
|
* Include these attributes to payment receive object.
|
||||||
|
|||||||
@@ -69,9 +69,6 @@ export default class PaymentReceiveService implements IPaymentsReceiveService {
|
|||||||
@EventDispatcher()
|
@EventDispatcher()
|
||||||
eventDispatcher: EventDispatcherInterface;
|
eventDispatcher: EventDispatcherInterface;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
paymentReceiveTransformer: PaymentReceiveTransfromer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the payment receive number existance.
|
* Validates the payment receive number existance.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
@@ -587,8 +584,7 @@ export default class PaymentReceiveService implements IPaymentsReceiveService {
|
|||||||
if (!paymentReceive) {
|
if (!paymentReceive) {
|
||||||
throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS);
|
throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
return new PaymentReceiveTransfromer().transform(paymentReceive);
|
||||||
return this.paymentReceiveTransformer.transform(paymentReceive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -664,8 +660,10 @@ export default class PaymentReceiveService implements IPaymentsReceiveService {
|
|||||||
filter.pageSize
|
filter.pageSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const transformedPayments = new PaymentReceiveTransfromer().transform(results);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
paymentReceives: this.paymentReceiveTransformer.transform(results),
|
paymentReceives: transformedPayments,
|
||||||
pagination,
|
pagination,
|
||||||
filterMeta: dynamicList.getResponseMeta(),
|
filterMeta: dynamicList.getResponseMeta(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';;
|
||||||
import { ISaleInvoice } from 'interfaces';
|
|
||||||
import { Transformer } from 'lib/Transformer/Transformer';
|
import { Transformer } from 'lib/Transformer/Transformer';
|
||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
|
|
||||||
@Service()
|
|
||||||
export default class SaleInvoiceTransformer extends Transformer {
|
export default class SaleInvoiceTransformer extends Transformer {
|
||||||
/**
|
/**
|
||||||
* Include these attributes to sale invoice object.
|
* Include these attributes to sale invoice object.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import CustomersService from 'services/Contacts/CustomersService';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import AutoIncrementOrdersService from './AutoIncrementOrdersService';
|
import AutoIncrementOrdersService from './AutoIncrementOrdersService';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import SaleEstimateTransfromer from './Estimates/SaleEstimateTransformer';
|
import SaleEstimateTransformer from './Estimates/SaleEstimateTransformer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sale estimate service.
|
* Sale estimate service.
|
||||||
@@ -52,9 +52,6 @@ export default class SaleEstimateService implements ISalesEstimatesService{
|
|||||||
@Inject()
|
@Inject()
|
||||||
autoIncrementOrdersService: AutoIncrementOrdersService;
|
autoIncrementOrdersService: AutoIncrementOrdersService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleEstimateTransformer: SaleEstimateTransfromer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve sale estimate or throw service error.
|
* Retrieve sale estimate or throw service error.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -401,7 +398,7 @@ export default class SaleEstimateService implements ISalesEstimatesService{
|
|||||||
if (!estimate) {
|
if (!estimate) {
|
||||||
throw new ServiceError(ERRORS.SALE_ESTIMATE_NOT_FOUND);
|
throw new ServiceError(ERRORS.SALE_ESTIMATE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
return this.saleEstimateTransformer.transform(estimate);
|
return new SaleEstimateTransformer().transform(estimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,8 +444,10 @@ export default class SaleEstimateService implements ISalesEstimatesService{
|
|||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
const transformedEstimates = new SaleEstimateTransformer().transform(results);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
salesEstimates: this.saleEstimateTransformer.transform(results),
|
salesEstimates: transformedEstimates,
|
||||||
pagination,
|
pagination,
|
||||||
filterMeta: dynamicFilter.getResponseMeta(),
|
filterMeta: dynamicFilter.getResponseMeta(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ import CustomersService from 'services/Contacts/CustomersService';
|
|||||||
import SaleEstimateService from 'services/Sales/SalesEstimate';
|
import SaleEstimateService from 'services/Sales/SalesEstimate';
|
||||||
import JournalPosterService from './JournalPosterService';
|
import JournalPosterService from './JournalPosterService';
|
||||||
import AutoIncrementOrdersService from './AutoIncrementOrdersService';
|
import AutoIncrementOrdersService from './AutoIncrementOrdersService';
|
||||||
import SaleInvoiceTransfromer from './SaleInvoiceTransformer';
|
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
|
import SaleInvoiceTransformer from './SaleInvoiceTransformer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sales invoices service
|
* Sales invoices service
|
||||||
@@ -75,9 +75,6 @@ export default class SaleInvoicesService implements ISalesInvoicesService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
autoIncrementOrdersService: AutoIncrementOrdersService;
|
autoIncrementOrdersService: AutoIncrementOrdersService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleInvoiceTransformer: SaleInvoiceTransfromer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate whether sale invoice number unqiue on the storage.
|
* Validate whether sale invoice number unqiue on the storage.
|
||||||
*/
|
*/
|
||||||
@@ -649,7 +646,7 @@ export default class SaleInvoicesService implements ISalesInvoicesService {
|
|||||||
if (!saleInvoice) {
|
if (!saleInvoice) {
|
||||||
throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND);
|
throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
return this.saleInvoiceTransformer.transform(saleInvoice);
|
return new SaleInvoiceTransformer().transform(saleInvoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -702,7 +699,7 @@ export default class SaleInvoicesService implements ISalesInvoicesService {
|
|||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
salesInvoices: this.saleInvoiceTransformer.transform(results),
|
salesInvoices: new SaleInvoiceTransformer().transform(results),
|
||||||
pagination,
|
pagination,
|
||||||
filterMeta: dynamicFilter.getResponseMeta(),
|
filterMeta: dynamicFilter.getResponseMeta(),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user