mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
refactoring: payment made form.
This commit is contained in:
@@ -17,14 +17,32 @@ export default class FinancialStatementsService {
|
||||
router() {
|
||||
const router = Router();
|
||||
|
||||
router.use('/balance_sheet', Container.get(BalanceSheetController).router());
|
||||
router.use('/profit_loss_sheet', Container.get(ProfitLossController).router());
|
||||
router.use('/general_ledger', Container.get(GeneralLedgerController).router());
|
||||
router.use('/trial_balance_sheet', Container.get(TrialBalanceSheetController).router());
|
||||
router.use(
|
||||
'/balance_sheet',
|
||||
Container.get(BalanceSheetController).router()
|
||||
);
|
||||
router.use(
|
||||
'/profit_loss_sheet',
|
||||
Container.get(ProfitLossController).router()
|
||||
);
|
||||
router.use(
|
||||
'/general_ledger',
|
||||
Container.get(GeneralLedgerController).router()
|
||||
);
|
||||
router.use(
|
||||
'/trial_balance_sheet',
|
||||
Container.get(TrialBalanceSheetController).router()
|
||||
);
|
||||
router.use('/journal', Container.get(JournalSheetController).router());
|
||||
router.use('/receivable_aging_summary', Container.get(ARAgingSummary).router());
|
||||
router.use('/payable_aging_summary', Container.get(APAgingSummary).router());
|
||||
router.use(
|
||||
'/receivable_aging_summary',
|
||||
Container.get(ARAgingSummary).router()
|
||||
);
|
||||
router.use(
|
||||
'/payable_aging_summary',
|
||||
Container.get(APAgingSummary).router()
|
||||
);
|
||||
|
||||
return router;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import BillPaymentsService from 'services/Purchases/BillPayments';
|
||||
import DynamicListingService from 'services/DynamicListing/DynamicListService';
|
||||
import AccountsService from 'services/Accounts/AccountsService';
|
||||
import ResourceController from '../Resources';
|
||||
import { Request } from 'express-validator/src/base';
|
||||
|
||||
/**
|
||||
* Bills payments controller.
|
||||
@@ -30,6 +31,20 @@ export default class BillsPayments extends BaseController {
|
||||
router() {
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/new-page/entries',
|
||||
[query('vendor_id').exists()],
|
||||
this.validationResult,
|
||||
asyncMiddleware(this.getBillPaymentNewPageEntries.bind(this)),
|
||||
this.handleServiceError
|
||||
);
|
||||
router.get(
|
||||
'/:id/edit-page',
|
||||
this.specificBillPaymentValidateSchema,
|
||||
this.validationResult,
|
||||
asyncMiddleware(this.getBillPaymentEditPage.bind(this)),
|
||||
this.handleServiceError
|
||||
);
|
||||
router.post(
|
||||
'/',
|
||||
[...this.billPaymentSchemaValidation],
|
||||
@@ -76,6 +91,7 @@ export default class BillsPayments extends BaseController {
|
||||
this.handleServiceError,
|
||||
this.dynamicListService.handlerErrorsToResponse
|
||||
);
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
@@ -118,6 +134,53 @@ export default class BillsPayments extends BaseController {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve bill payment new page entries.
|
||||
* @param {Request} req -
|
||||
* @param {Response} res -
|
||||
*/
|
||||
async getBillPaymentNewPageEntries(req: Request, res: Response) {
|
||||
const { tenantId } = req;
|
||||
const { vendorId } = this.matchedQueryData(req);
|
||||
|
||||
try {
|
||||
const entries = await this.billPaymentService.getNewPageEntries(
|
||||
tenantId,
|
||||
vendorId
|
||||
);
|
||||
return res.status(200).send({
|
||||
entries: this.transfromToResponse(entries),
|
||||
});
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the bill payment edit page details.
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getBillPaymentEditPage(req: Request, res: Response, next: NextFunction) {
|
||||
const { tenantId } = req;
|
||||
const { id: paymentReceiveId } = req.params;
|
||||
|
||||
try {
|
||||
const {
|
||||
billPayment,
|
||||
entries,
|
||||
} = await this.billPaymentService.getBillPaymentEditPage(
|
||||
tenantId,
|
||||
paymentReceiveId,
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
bill_payment: this.transfromToResponse(billPayment),
|
||||
entries: this.transfromToResponse(entries),
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bill payment.
|
||||
* @async
|
||||
|
||||
@@ -54,6 +54,15 @@ export default class PaymentReceivesController extends BaseController {
|
||||
asyncMiddleware(this.getPaymentReceiveEditPage.bind(this)),
|
||||
this.handleServiceErrors
|
||||
);
|
||||
router.get(
|
||||
'/new-page/entries',
|
||||
[
|
||||
query('customer_id').exists().isNumeric().toInt(),
|
||||
],
|
||||
this.validationResult,
|
||||
asyncMiddleware(this.getPaymentReceiveNewPageEntries.bind(this)),
|
||||
this.getPaymentReceiveNewPageEntries.bind(this)
|
||||
);
|
||||
router.get(
|
||||
'/',
|
||||
this.validatePaymentReceiveList,
|
||||
@@ -303,6 +312,26 @@ export default class PaymentReceivesController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve payment receive new page receivable entries.
|
||||
* @param {Request} req - Request.
|
||||
* @param {Response} res - Response.
|
||||
*/
|
||||
async getPaymentReceiveNewPageEntries(req, res) {
|
||||
const { tenantId } = req;
|
||||
const { customerId } = this.matchedQueryData(req);
|
||||
|
||||
try {
|
||||
const entries = await this.paymentReceiveService.getNewPageEntries(
|
||||
tenantId,
|
||||
customerId
|
||||
);
|
||||
return res.status(200).send({
|
||||
entries: this.transfromToResponse(entries),
|
||||
});
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles service errors.
|
||||
* @param error
|
||||
|
||||
@@ -32,4 +32,15 @@ export interface IBillPaymentDTO {
|
||||
description: string,
|
||||
reference: string,
|
||||
entries: IBillPaymentEntryDTO[],
|
||||
};
|
||||
|
||||
export interface IBillReceivePageEntry {
|
||||
billId: number,
|
||||
entryType: string,
|
||||
billNo: string,
|
||||
dueAmount: number,
|
||||
amount: number,
|
||||
totalPaymentAmount: number,
|
||||
paymentAmount: number,
|
||||
date: Date|string,
|
||||
};
|
||||
@@ -52,7 +52,7 @@ export interface IPaymentReceivesFilter extends IDynamicListFilterDTO {
|
||||
stringifiedFilterRoles?: string,
|
||||
}
|
||||
|
||||
export interface IPaymentReceiveEditPageEntry {
|
||||
export interface IPaymentReceivePageEntry {
|
||||
invoiceId: number,
|
||||
entryType: string,
|
||||
invoiceNo: string,
|
||||
@@ -65,5 +65,5 @@ export interface IPaymentReceiveEditPageEntry {
|
||||
|
||||
export interface IPaymentReceiveEditPage {
|
||||
paymentReceive: IPaymentReceive,
|
||||
entries: IPaymentReceiveEditPageEntry[];
|
||||
entries: IPaymentReceivePageEntry[];
|
||||
};
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
IPaginationMeta,
|
||||
IFilterMeta,
|
||||
IBillPaymentEntry,
|
||||
IBillReceivePageEntry,
|
||||
} from 'interfaces';
|
||||
import AccountsService from 'services/Accounts/AccountsService';
|
||||
import JournalPoster from 'services/Accounting/JournalPoster';
|
||||
@@ -26,6 +27,7 @@ import DynamicListingService from 'services/DynamicListing/DynamicListService';
|
||||
import { entriesAmountDiff, formatDateFields } from 'utils';
|
||||
import { ServiceError } from 'exceptions';
|
||||
import { ACCOUNT_PARENT_TYPE } from 'data/AccountTypes';
|
||||
import PayableAgingSummaryService from 'services/FinancialStatements/AgingSummary/APAgingSummaryService';
|
||||
|
||||
const ERRORS = {
|
||||
BILL_VENDOR_NOT_FOUND: 'VENDOR_NOT_FOUND',
|
||||
@@ -598,48 +600,43 @@ export default class BillPaymentsService {
|
||||
* @param {number} billPaymentId - The bill payment id.
|
||||
* @return {object}
|
||||
*/
|
||||
public async getBillPayment(
|
||||
public async getBillPaymentEditPage(
|
||||
tenantId: number,
|
||||
billPaymentId: number
|
||||
): Promise<{
|
||||
billPayment: IBillPayment;
|
||||
payableBills: IBill[];
|
||||
paymentMadeBills: IBill[];
|
||||
billPayment: Omit<IBillPayment, "entries">;
|
||||
entries: IBillReceivePageEntry[];
|
||||
}> {
|
||||
const { BillPayment, Bill } = this.tenancy.models(tenantId);
|
||||
const billPayment = await BillPayment.query()
|
||||
.findById(billPaymentId)
|
||||
.withGraphFetched('entries.bill')
|
||||
.withGraphFetched('vendor')
|
||||
.withGraphFetched('paymentAccount');
|
||||
.withGraphFetched('entries.bill');
|
||||
|
||||
// Throw not found the bill payment.
|
||||
if (!billPayment) {
|
||||
throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND);
|
||||
}
|
||||
const billsIds = billPayment.entries.map((entry) => entry.billId);
|
||||
|
||||
// Retrieve all payable bills that assocaited to the payment made transaction.
|
||||
const payableBills = await Bill.query()
|
||||
.modify('dueBills')
|
||||
.whereNotIn('id', billsIds)
|
||||
.where('vendor_id', billPayment.vendorId)
|
||||
.orderBy('bill_date', 'ASC');
|
||||
|
||||
// Retrieve all payment made assocaited bills.
|
||||
const paymentMadeBills = billPayment.entries.map((entry) => ({
|
||||
...entry.bill,
|
||||
dueAmount: entry.bill.dueAmount + entry.paymentAmount,
|
||||
const paymentEntries = billPayment.entries.map((entry) => ({
|
||||
...this.mapBillToPageEntry(entry.bill),
|
||||
paymentAmount: entry.paymentAmount,
|
||||
}));
|
||||
|
||||
const resPayableBills = await Bill.query()
|
||||
.modify('dueBills')
|
||||
.where('vendor_id', billPayment.vendorId)
|
||||
.whereNotIn(
|
||||
'id',
|
||||
billPayment.entries.map((e) => e.billId),
|
||||
)
|
||||
.orderBy('bill_date', 'ASC');
|
||||
|
||||
// Mapping the payable bills to entries.
|
||||
const restPayableEntries = resPayableBills.map(this.mapBillToPageEntry);
|
||||
const entries = [...paymentEntries, ...restPayableEntries];
|
||||
|
||||
return {
|
||||
billPayment: {
|
||||
...billPayment,
|
||||
entries: billPayment.entries.map((entry) => ({
|
||||
...omit(entry, ['bill']),
|
||||
})),
|
||||
},
|
||||
payableBills,
|
||||
paymentMadeBills,
|
||||
billPayment: omit(billPayment, ['entries']),
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
@@ -678,4 +675,55 @@ export default class BillPaymentsService {
|
||||
);
|
||||
await Promise.all(opers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive edit page invoices entries from the given sale invoices models.
|
||||
* @param {ISaleInvoice[]} invoices - Invoices.
|
||||
* @return {IPaymentReceiveEditPageEntry}
|
||||
*/
|
||||
public mapBillToPageEntry(bill: IBill): IBillReceivePageEntry {
|
||||
return {
|
||||
entryType: 'invoice',
|
||||
billId: bill.id,
|
||||
dueAmount: bill.dueAmount + bill.paymentAmount,
|
||||
amount: bill.amount,
|
||||
billNo: bill.billNumber,
|
||||
totalPaymentAmount: bill.paymentAmount,
|
||||
paymentAmount: bill.paymentAmount,
|
||||
date: bill.billDate,
|
||||
};
|
||||
}
|
||||
|
||||
public mapBillToNewPageEntry(bill: IBill): IBillReceivePageEntry {
|
||||
return {
|
||||
entryType: 'invoice',
|
||||
billId: bill.id,
|
||||
dueAmount: bill.dueAmount,
|
||||
amount: bill.amount,
|
||||
billNo: bill.billNumber,
|
||||
date: bill.billDate,
|
||||
totalPaymentAmount: bill.paymentAmount,
|
||||
paymentAmount: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the payable entries of the new page once vendor be selected.
|
||||
* @param {number} tenantId
|
||||
* @param {number} vendorId
|
||||
*/
|
||||
async getNewPageEntries(
|
||||
tenantId: number,
|
||||
vendorId: number,
|
||||
): Promise<IBillReceivePageEntry[]> {
|
||||
const { Bill } = this.tenancy.models(tenantId);
|
||||
|
||||
// Retrieve all payable bills that assocaited to the payment made transaction.
|
||||
const payableBills = await Bill.query()
|
||||
.modify('dueBills')
|
||||
.where('vendor_id', vendorId)
|
||||
.orderBy('bill_date', 'ASC');
|
||||
|
||||
return payableBills.map(this.mapBillToNewPageEntry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
ISaleInvoice,
|
||||
ISystemService,
|
||||
ISystemUser,
|
||||
IPaymentReceiveEditPageEntry,
|
||||
IPaymentReceivePageEntry,
|
||||
} from 'interfaces';
|
||||
import AccountsService from 'services/Accounts/AccountsService';
|
||||
import JournalPoster from 'services/Accounting/JournalPoster';
|
||||
@@ -471,7 +471,7 @@ export default class PaymentReceiveService {
|
||||
* @param {ISaleInvoice[]} invoices - Invoices.
|
||||
* @return {IPaymentReceiveEditPageEntry}
|
||||
*/
|
||||
public invoicesToEditPageEntries(
|
||||
public invoiceToPageEntry(
|
||||
invoice: ISaleInvoice
|
||||
): IPaymentReceiveEditPageEntry {
|
||||
return {
|
||||
@@ -485,7 +485,7 @@ export default class PaymentReceiveService {
|
||||
date: invoice.invoiceDate,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the payment receive details of the given id.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
@@ -494,9 +494,10 @@ export default class PaymentReceiveService {
|
||||
public async getPaymentReceiveEditPage(
|
||||
tenantId: number,
|
||||
paymentReceiveId: number,
|
||||
authorizedUser: ISystemUser
|
||||
): Promise<{
|
||||
paymentReceive: IPaymentReceive;
|
||||
entries: IPaymentReceiveEditPageEntry[];
|
||||
paymentReceive: Omit<IPaymentReceive, "entries">;
|
||||
entries: IPaymentReceivePageEntry[];
|
||||
}> {
|
||||
const { PaymentReceive, SaleInvoice } = this.tenancy.models(tenantId);
|
||||
|
||||
@@ -509,14 +510,8 @@ export default class PaymentReceiveService {
|
||||
if (!paymentReceive) {
|
||||
throw new ServiceError(ERRORS.PAYMENT_RECEIVE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// Mapping the entries invoices.
|
||||
const entriesInvoicesIds = paymentReceive.entries.map(
|
||||
(entry) => entry.invoiceId
|
||||
);
|
||||
|
||||
const paymentEntries = paymentReceive.entries.map((entry) => ({
|
||||
...this.invoicesToEditPageEntries(entry.invoice),
|
||||
...this.invoiceToPageEntry(entry.invoice),
|
||||
paymentAmount: entry.paymentAmount,
|
||||
}));
|
||||
|
||||
@@ -524,17 +519,16 @@ export default class PaymentReceiveService {
|
||||
const restReceivableInvoices = await SaleInvoice.query()
|
||||
.modify('dueInvoices')
|
||||
.where('customer_id', paymentReceive.customerId)
|
||||
.whereNotIn('id', entriesInvoicesIds)
|
||||
.whereNotIn(
|
||||
'id',
|
||||
paymentReceive.entries.map((entry) => entry.invoiceId)
|
||||
)
|
||||
.orderBy('invoice_date', 'ASC');
|
||||
|
||||
const restReceivableEntries = restReceivableInvoices.map(
|
||||
this.invoicesToEditPageEntries
|
||||
this.invoiceToPageEntry
|
||||
);
|
||||
|
||||
const entries = [
|
||||
...paymentEntries,
|
||||
...restReceivableEntries,
|
||||
];
|
||||
const entries = [...paymentEntries, ...restReceivableEntries];
|
||||
|
||||
return {
|
||||
paymentReceive: omit(paymentReceive, ['entries']),
|
||||
@@ -616,6 +610,7 @@ export default class PaymentReceiveService {
|
||||
paymentReceiveId: number
|
||||
) {
|
||||
const { PaymentReceive } = this.tenancy.models(tenantId);
|
||||
|
||||
return PaymentReceive.query()
|
||||
.where('id', paymentReceiveId)
|
||||
.withGraphFetched('invoices')
|
||||
@@ -739,7 +734,6 @@ export default class PaymentReceiveService {
|
||||
if (diffEntry.paymentAmount === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oper = SaleInvoice.changePaymentAmount(
|
||||
diffEntry.invoiceId,
|
||||
diffEntry.paymentAmount
|
||||
@@ -748,4 +742,22 @@ export default class PaymentReceiveService {
|
||||
});
|
||||
await Promise.all([...opers]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve payment receive new page receivable entries.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {number} vendorId - Vendor id.
|
||||
* @return {IPaymentReceivePageEntry[]}
|
||||
*/
|
||||
async getNewPageEntries(tenantId: number, customerId: number) {
|
||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||
|
||||
// Retrieve due invoices.
|
||||
const entries = await SaleInvoice.query()
|
||||
.modify('dueInvoices')
|
||||
.where('customer_id', customerId)
|
||||
.orderBy('invoice_date', 'ASC');
|
||||
|
||||
return entries.map(this.invoiceToPageEntry);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user