mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
111 lines
4.5 KiB
TypeScript
111 lines
4.5 KiB
TypeScript
import { Inject, Injectable } from '@nestjs/common';
|
|
import * as R from 'ramda';
|
|
import { sumBy, omit } from 'lodash';
|
|
import * as composeAsync from 'async/compose';
|
|
import * as moment from 'moment';
|
|
import { SaleReceiptIncrement } from './SaleReceiptIncrement.service';
|
|
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
|
|
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
|
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
|
import { SaleReceiptValidators } from './SaleReceiptValidators.service';
|
|
import { BrandingTemplateDTOTransformer } from '@/modules/PdfTemplate/BrandingTemplateDTOTransformer';
|
|
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
|
import { formatDateFields } from '@/utils/format-date-fields';
|
|
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
|
|
import { SaleReceipt } from '../models/SaleReceipt';
|
|
import { ISaleReceiptDTO } from '../types/SaleReceipts.types';
|
|
import { Customer } from '@/modules/Customers/models/Customer';
|
|
|
|
@Injectable()
|
|
export class SaleReceiptDTOTransformer {
|
|
/**
|
|
* @param {ItemsEntriesService} itemsEntriesService - Items entries service.
|
|
* @param {BranchTransactionDTOTransformer} branchDTOTransform - Branch transaction DTO transformer.
|
|
* @param {WarehouseTransactionDTOTransform} warehouseDTOTransform - Warehouse transaction DTO transformer.
|
|
* @param {SaleReceiptValidators} validators - Sale receipt validators.
|
|
* @param {SaleReceiptIncrement} receiptIncrement - Sale receipt increment.
|
|
* @param {BrandingTemplateDTOTransformer} brandingTemplatesTransformer - Branding template DTO transformer.
|
|
* @param {typeof ItemEntry} itemEntryModel - Item entry model.
|
|
*/
|
|
constructor(
|
|
private readonly itemsEntriesService: ItemsEntriesService,
|
|
private readonly branchDTOTransform: BranchTransactionDTOTransformer,
|
|
private readonly warehouseDTOTransform: WarehouseTransactionDTOTransform,
|
|
private readonly validators: SaleReceiptValidators,
|
|
private readonly receiptIncrement: SaleReceiptIncrement,
|
|
private readonly brandingTemplatesTransformer: BrandingTemplateDTOTransformer,
|
|
|
|
@Inject(ItemEntry.name)
|
|
private readonly itemEntryModel: typeof ItemEntry,
|
|
) {}
|
|
|
|
/**
|
|
* Transform create DTO object to model object.
|
|
* @param {ISaleReceiptDTO} saleReceiptDTO -
|
|
* @param {ISaleReceipt} oldSaleReceipt -
|
|
* @returns {ISaleReceipt}
|
|
*/
|
|
async transformDTOToModel(
|
|
saleReceiptDTO: ISaleReceiptDTO,
|
|
paymentCustomer: Customer,
|
|
oldSaleReceipt?: SaleReceipt,
|
|
): Promise<SaleReceipt> {
|
|
const amount = sumBy(saleReceiptDTO.entries, (e) =>
|
|
this.itemEntryModel.calcAmount(e),
|
|
);
|
|
// Retrieve the next invoice number.
|
|
const autoNextNumber = await this.receiptIncrement.getNextReceiptNumber();
|
|
|
|
// Retrieve the receipt number.
|
|
const receiptNumber =
|
|
saleReceiptDTO.receiptNumber ||
|
|
oldSaleReceipt?.receiptNumber ||
|
|
autoNextNumber;
|
|
|
|
// Validate receipt number require.
|
|
this.validators.validateReceiptNoRequire(receiptNumber);
|
|
|
|
const initialEntries = saleReceiptDTO.entries.map((entry) => ({
|
|
reference_type: 'SaleReceipt',
|
|
...entry,
|
|
}));
|
|
const asyncEntries = await composeAsync(
|
|
// Sets default cost and sell account to receipt items entries.
|
|
this.itemsEntriesService.setItemsEntriesDefaultAccounts,
|
|
)(initialEntries);
|
|
|
|
const entries = R.compose(
|
|
// Associate the default index for each item entry.
|
|
assocItemEntriesDefaultIndex,
|
|
)(asyncEntries);
|
|
|
|
const initialDTO = {
|
|
amount,
|
|
...formatDateFields(
|
|
omit(saleReceiptDTO, ['closed', 'entries', 'attachments']),
|
|
['receiptDate'],
|
|
),
|
|
currencyCode: paymentCustomer.currencyCode,
|
|
exchangeRate: saleReceiptDTO.exchangeRate || 1,
|
|
receiptNumber,
|
|
// Avoid rewrite the deliver date in edit mode when already published.
|
|
...(saleReceiptDTO.closed &&
|
|
!oldSaleReceipt?.closedAt && {
|
|
closedAt: moment().toMySqlDateTime(),
|
|
}),
|
|
entries,
|
|
};
|
|
const initialAsyncDTO = await composeAsync(
|
|
// Assigns the default branding template id to the invoice DTO.
|
|
this.brandingTemplatesTransformer.assocDefaultBrandingTemplate(
|
|
'SaleReceipt',
|
|
),
|
|
)(initialDTO);
|
|
|
|
return R.compose(
|
|
this.branchDTOTransform.transformDTO<SaleReceipt>,
|
|
this.warehouseDTOTransform.transformDTO<SaleReceipt>,
|
|
)(initialAsyncDTO) as SaleReceipt;
|
|
}
|
|
}
|