mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
Compare commits
9 Commits
hotfix-pdf
...
v0.13.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eb84474a5 | ||
|
|
e42adcae63 | ||
|
|
abffdd1029 | ||
|
|
d052c23560 | ||
|
|
f02afd3c9f | ||
|
|
3df17390e2 | ||
|
|
df38f8893d | ||
|
|
8882bc677e | ||
|
|
f03d01113c |
@@ -87,6 +87,24 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "xprnio",
|
||||||
|
"name": "Ragnar Laud",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/3042904?v=4",
|
||||||
|
"profile": "https://ragnarlaud.dev",
|
||||||
|
"contributions": [
|
||||||
|
"bug"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "asenawritescode",
|
||||||
|
"name": "Asena",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/67445192?v=4",
|
||||||
|
"profile": "https://github.com/asenawritescode",
|
||||||
|
"contributions": [
|
||||||
|
"bug"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="http://cschuijt.nl"><img src="https://avatars.githubusercontent.com/u/5460015?v=4?s=100" width="100px;" alt="Casper Schuijt"/><br /><sub><b>Casper Schuijt</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Acschuijt" title="Bug reports">🐛</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="http://cschuijt.nl"><img src="https://avatars.githubusercontent.com/u/5460015?v=4?s=100" width="100px;" alt="Casper Schuijt"/><br /><sub><b>Casper Schuijt</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Acschuijt" title="Bug reports">🐛</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ANasouf"><img src="https://avatars.githubusercontent.com/u/19536487?v=4?s=100" width="100px;" alt="ANasouf"/><br /><sub><b>ANasouf</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=ANasouf" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ANasouf"><img src="https://avatars.githubusercontent.com/u/19536487?v=4?s=100" width="100px;" alt="ANasouf"/><br /><sub><b>ANasouf</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=ANasouf" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://ragnarlaud.dev"><img src="https://avatars.githubusercontent.com/u/3042904?v=4?s=100" width="100px;" alt="Ragnar Laud"/><br /><sub><b>Ragnar Laud</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Axprnio" title="Bug reports">🐛</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/asenawritescode"><img src="https://avatars.githubusercontent.com/u/67445192?v=4?s=100" width="100px;" alt="Asena"/><br /><sub><b>Asena</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aasenawritescode" title="Bug reports">🐛</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ export default class BillsController extends BaseController {
|
|||||||
try {
|
try {
|
||||||
const bill = await this.billsApplication.getBill(tenantId, billId);
|
const bill = await this.billsApplication.getBill(tenantId, billId);
|
||||||
|
|
||||||
return res.status(200).send(this.transfromToResponse({ bill }));
|
return res.status(200).send({ bill });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -348,14 +348,11 @@ export default class BillsController extends BaseController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { bills, pagination, filterMeta } =
|
const billsWithPagination = await this.billsApplication.getBills(
|
||||||
await this.billsApplication.getBills(tenantId, filter);
|
tenantId,
|
||||||
|
filter
|
||||||
return res.status(200).send({
|
);
|
||||||
bills: this.transfromToResponse(bills),
|
return res.status(200).send(billsWithPagination);
|
||||||
pagination: this.transfromToResponse(pagination),
|
|
||||||
filter_meta: this.transfromToResponse(filterMeta),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,15 +158,11 @@ export default class BillsPayments extends BaseController {
|
|||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { vendorId } = this.matchedQueryData(req);
|
const { vendorId } = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
const entries = await this.billPaymentsPages.getNewPageEntries(
|
||||||
const entries = await this.billPaymentsPages.getNewPageEntries(
|
tenantId,
|
||||||
tenantId,
|
vendorId
|
||||||
vendorId
|
);
|
||||||
);
|
return res.status(200).send({ entries });
|
||||||
return res.status(200).send({
|
|
||||||
entries: this.transfromToResponse(entries),
|
|
||||||
});
|
|
||||||
} catch (error) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,16 +179,12 @@ export default class BillsPayments extends BaseController {
|
|||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { billPayment, entries } =
|
const billPaymentsWithEditEntries =
|
||||||
await this.billPaymentsPages.getBillPaymentEditPage(
|
await this.billPaymentsPages.getBillPaymentEditPage(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceiveId
|
paymentReceiveId
|
||||||
);
|
);
|
||||||
|
return res.status(200).send(billPaymentsWithEditEntries);
|
||||||
return res.status(200).send({
|
|
||||||
bill_payment: this.transfromToResponse(billPayment),
|
|
||||||
entries: this.transfromToResponse(entries),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -304,9 +296,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
tenantId,
|
tenantId,
|
||||||
billPaymentId
|
billPaymentId
|
||||||
);
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({ billPayment });
|
||||||
bill_payment: this.transfromToResponse(billPayment),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -359,17 +349,12 @@ export default class BillsPayments extends BaseController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { billPayments, pagination, filterMeta } =
|
const billPaymentsWithPagination =
|
||||||
await this.billPaymentsApplication.getBillPayments(
|
await this.billPaymentsApplication.getBillPayments(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPaymentsFilter
|
billPaymentsFilter
|
||||||
);
|
);
|
||||||
|
return res.status(200).send(billPaymentsWithPagination);
|
||||||
return res.status(200).send({
|
|
||||||
bill_payments: this.transfromToResponse(billPayments),
|
|
||||||
pagination: this.transfromToResponse(pagination),
|
|
||||||
filter_meta: this.transfromToResponse(filterMeta),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import GetCreditNoteAssociatedInvoicesToApply from '@/services/CreditNotes/GetCr
|
|||||||
import GetCreditNoteAssociatedAppliedInvoices from '@/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices';
|
import GetCreditNoteAssociatedAppliedInvoices from '@/services/CreditNotes/GetCreditNoteAssociatedAppliedInvoices';
|
||||||
import GetRefundCreditTransaction from '@/services/CreditNotes/GetRefundCreditNoteTransaction';
|
import GetRefundCreditTransaction from '@/services/CreditNotes/GetRefundCreditNoteTransaction';
|
||||||
import GetCreditNotePdf from '../../../services/CreditNotes/GetCreditNotePdf';
|
import GetCreditNotePdf from '../../../services/CreditNotes/GetCreditNotePdf';
|
||||||
|
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
||||||
/**
|
/**
|
||||||
* Credit notes controller.
|
* Credit notes controller.
|
||||||
* @service
|
* @service
|
||||||
@@ -438,7 +439,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the payment receive details.
|
* Retrieve the credit note details.
|
||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
@@ -451,38 +452,28 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: creditNoteId } = req.params;
|
const { id: creditNoteId } = req.params;
|
||||||
|
|
||||||
try {
|
const accept = this.accepts(req);
|
||||||
|
|
||||||
|
const acceptType = accept.types([
|
||||||
|
ACCEPT_TYPE.APPLICATION_JSON,
|
||||||
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
|
]);
|
||||||
|
if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) {
|
||||||
|
const pdfContent = await this.creditNotePdf.getCreditNotePdf(
|
||||||
|
tenantId,
|
||||||
|
creditNoteId
|
||||||
|
);
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'application/pdf',
|
||||||
|
'Content-Length': pdfContent.length,
|
||||||
|
});
|
||||||
|
res.send(pdfContent);
|
||||||
|
} else {
|
||||||
const creditNote = await this.getCreditNoteService.getCreditNote(
|
const creditNote = await this.getCreditNoteService.getCreditNote(
|
||||||
tenantId,
|
tenantId,
|
||||||
creditNoteId
|
creditNoteId
|
||||||
);
|
);
|
||||||
const ACCEPT_TYPE = {
|
return res.status(200).send({ creditNote });
|
||||||
APPLICATION_PDF: 'application/pdf',
|
|
||||||
APPLICATION_JSON: 'application/json',
|
|
||||||
};
|
|
||||||
// Response formatter.
|
|
||||||
res.format({
|
|
||||||
// Json content type.
|
|
||||||
[ACCEPT_TYPE.APPLICATION_JSON]: () => {
|
|
||||||
return res
|
|
||||||
.status(200)
|
|
||||||
.send({ credit_note: this.transfromToResponse(creditNote) });
|
|
||||||
},
|
|
||||||
// Pdf content type.
|
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
|
||||||
const pdfContent = await this.creditNotePdf.getCreditNotePdf(
|
|
||||||
tenantId,
|
|
||||||
creditNote
|
|
||||||
);
|
|
||||||
res.set({
|
|
||||||
'Content-Type': 'application/pdf',
|
|
||||||
'Content-Length': pdfContent.length,
|
|
||||||
});
|
|
||||||
res.send(pdfContent);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
next(error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import DynamicListingService from '@/services/DynamicListing/DynamicListService'
|
|||||||
import { PaymentReceivesApplication } from '@/services/Sales/PaymentReceives/PaymentReceivesApplication';
|
import { PaymentReceivesApplication } from '@/services/Sales/PaymentReceives/PaymentReceivesApplication';
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class PaymentReceivesController extends BaseController {
|
export default class PaymentReceivesController extends BaseController {
|
||||||
@@ -348,17 +349,12 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { paymentReceives, pagination, filterMeta } =
|
const paymentsReceivedWithPagination =
|
||||||
await this.paymentReceiveApplication.getPaymentReceives(
|
await this.paymentReceiveApplication.getPaymentReceives(
|
||||||
tenantId,
|
tenantId,
|
||||||
filter
|
filter
|
||||||
);
|
);
|
||||||
|
return res.status(200).send(paymentsReceivedWithPagination);
|
||||||
return res.status(200).send({
|
|
||||||
payment_receives: this.transfromToResponse(paymentReceives),
|
|
||||||
pagination: this.transfromToResponse(pagination),
|
|
||||||
filter_meta: this.transfromToResponse(filterMeta),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -435,37 +431,34 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
try {
|
const accept = this.accepts(req);
|
||||||
const ACCEPT_TYPE = {
|
|
||||||
APPLICATION_PDF: 'application/pdf',
|
const acceptType = accept.types([
|
||||||
APPLICATION_JSON: 'application/json',
|
ACCEPT_TYPE.APPLICATION_JSON,
|
||||||
};
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
res.format({
|
]);
|
||||||
[ACCEPT_TYPE.APPLICATION_JSON]: async () => {
|
// Response in pdf format.
|
||||||
const paymentReceive =
|
if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) {
|
||||||
await this.paymentReceiveApplication.getPaymentReceive(
|
const pdfContent =
|
||||||
tenantId,
|
await this.paymentReceiveApplication.getPaymentReceivePdf(
|
||||||
paymentReceiveId
|
tenantId,
|
||||||
);
|
paymentReceiveId
|
||||||
return res.status(200).send({
|
);
|
||||||
payment_receive: paymentReceive,
|
res.set({
|
||||||
});
|
'Content-Type': 'application/pdf',
|
||||||
},
|
'Content-Length': pdfContent.length,
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
});
|
||||||
const pdfContent =
|
res.send(pdfContent);
|
||||||
await this.paymentReceiveApplication.getPaymentReceivePdf(
|
// Response in json format.
|
||||||
tenantId,
|
} else {
|
||||||
paymentReceiveId
|
const paymentReceive =
|
||||||
);
|
await this.paymentReceiveApplication.getPaymentReceive(
|
||||||
res.set({
|
tenantId,
|
||||||
'Content-Type': 'application/pdf',
|
paymentReceiveId
|
||||||
'Content-Length': pdfContent.length,
|
);
|
||||||
});
|
return res.status(200).send({
|
||||||
res.send(pdfContent);
|
payment_receive: paymentReceive,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
next(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +492,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Retrieves the sms details of the given payment receive.
|
||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
@@ -588,10 +581,10 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles service errors.
|
* Handles service errors.
|
||||||
* @param error
|
* @param {Error} error
|
||||||
* @param req
|
* @param {Request} req
|
||||||
* @param res
|
* @param {Response} res
|
||||||
* @param next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
private handleServiceErrors(
|
private handleServiceErrors(
|
||||||
error: Error,
|
error: Error,
|
||||||
|
|||||||
@@ -334,7 +334,6 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
tenantId,
|
tenantId,
|
||||||
estimateId
|
estimateId
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
message: 'The sale estimate has been approved successfully.',
|
message: 'The sale estimate has been approved successfully.',
|
||||||
@@ -363,7 +362,6 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
tenantId,
|
tenantId,
|
||||||
estimateId
|
estimateId
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
message: 'The sale estimate has been rejected successfully.',
|
message: 'The sale estimate has been rejected successfully.',
|
||||||
@@ -383,33 +381,30 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
const accept = this.accepts(req);
|
||||||
// Response formatter.
|
|
||||||
res.format({
|
const acceptType = accept.types([
|
||||||
// JSON content type.
|
ACCEPT_TYPE.APPLICATION_JSON,
|
||||||
[ACCEPT_TYPE.APPLICATION_JSON]: async () => {
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
const estimate = await this.saleEstimatesApplication.getSaleEstimate(
|
]);
|
||||||
tenantId,
|
// Retrieves estimate in pdf format.
|
||||||
estimateId
|
if (ACCEPT_TYPE.APPLICATION_PDF == acceptType) {
|
||||||
);
|
const pdfContent = await this.saleEstimatesApplication.getSaleEstimatePdf(
|
||||||
return res.status(200).send({ estimate });
|
tenantId,
|
||||||
},
|
estimateId
|
||||||
// PDF content type.
|
);
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
res.set({
|
||||||
const pdfContent =
|
'Content-Type': 'application/pdf',
|
||||||
await this.saleEstimatesApplication.getSaleEstimatePdf(
|
'Content-Length': pdfContent.length,
|
||||||
tenantId,
|
|
||||||
estimateId
|
|
||||||
);
|
|
||||||
res.set({
|
|
||||||
'Content-Type': 'application/pdf',
|
|
||||||
'Content-Length': pdfContent.length,
|
|
||||||
});
|
|
||||||
res.send(pdfContent);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} catch (error) {
|
res.send(pdfContent);
|
||||||
next(error);
|
// Retrieves estimates in json format.
|
||||||
|
} else {
|
||||||
|
const estimate = await this.saleEstimatesApplication.getSaleEstimate(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
|
return res.status(200).send({ estimate });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,22 +422,11 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
...this.matchedQueryData(req),
|
...this.matchedQueryData(req),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { salesEstimates, pagination, filterMeta } =
|
const salesEstimatesWithPagination =
|
||||||
await this.saleEstimatesApplication.getSaleEstimates(tenantId, filter);
|
await this.saleEstimatesApplication.getSaleEstimates(tenantId, filter);
|
||||||
|
|
||||||
res.format({
|
return res.status(200).send(salesEstimatesWithPagination);
|
||||||
[ACCEPT_TYPE.APPLICATION_JSON]: () => {
|
|
||||||
return res.status(200).send(
|
|
||||||
this.transfromToResponse({
|
|
||||||
salesEstimates,
|
|
||||||
pagination,
|
|
||||||
filterMeta,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,8 @@ import {
|
|||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import { SaleInvoiceApplication } from '@/services/Sales/Invoices/SaleInvoicesApplication';
|
import { SaleInvoiceApplication } from '@/services/Sales/Invoices/SaleInvoicesApplication';
|
||||||
|
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
||||||
|
|
||||||
const ACCEPT_TYPE = {
|
|
||||||
APPLICATION_PDF: 'application/pdf',
|
|
||||||
APPLICATION_JSON: 'application/json',
|
|
||||||
};
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class SaleInvoicesController extends BaseController {
|
export default class SaleInvoicesController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
@@ -403,7 +400,6 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleInvoiceId,
|
id: saleInvoiceId,
|
||||||
message: 'The sale invoice has been deleted successfully.',
|
message: 'The sale invoice has been deleted successfully.',
|
||||||
@@ -422,30 +418,32 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const { id: saleInvoiceId } = req.params;
|
const { id: saleInvoiceId } = req.params;
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
|
|
||||||
// Response formatter.
|
const accept = this.accepts(req);
|
||||||
return res.format({
|
|
||||||
// JSON content type.
|
const acceptType = accept.types([
|
||||||
[ACCEPT_TYPE.APPLICATION_JSON]: async () => {
|
ACCEPT_TYPE.APPLICATION_JSON,
|
||||||
const saleInvoice = await this.saleInvoiceApplication.getSaleInvoice(
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
tenantId,
|
]);
|
||||||
saleInvoiceId,
|
// Retrieves invoice in pdf format.
|
||||||
user
|
if (ACCEPT_TYPE.APPLICATION_PDF == acceptType) {
|
||||||
);
|
const pdfContent = await this.saleInvoiceApplication.saleInvoicePdf(
|
||||||
return res.status(200).send(this.transfromToResponse({ saleInvoice }));
|
tenantId,
|
||||||
},
|
saleInvoiceId
|
||||||
// PDF content type.
|
);
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
res.set({
|
||||||
const pdfContent = await this.saleInvoiceApplication.saleInvoicePdf(
|
'Content-Type': 'application/pdf',
|
||||||
tenantId,
|
'Content-Length': pdfContent.length,
|
||||||
saleInvoiceId
|
});
|
||||||
);
|
res.send(pdfContent);
|
||||||
res.set({
|
// Retrieves invoice in json format.
|
||||||
'Content-Type': 'application/pdf',
|
} else {
|
||||||
'Content-Length': pdfContent.length,
|
const saleInvoice = await this.saleInvoiceApplication.getSaleInvoice(
|
||||||
});
|
tenantId,
|
||||||
res.send(pdfContent);
|
saleInvoiceId,
|
||||||
},
|
user
|
||||||
});
|
);
|
||||||
|
return res.status(200).send({ saleInvoice });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieve paginated sales invoices with custom view metadata.
|
* Retrieve paginated sales invoices with custom view metadata.
|
||||||
@@ -467,14 +465,10 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
...this.matchedQueryData(req),
|
...this.matchedQueryData(req),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { salesInvoices, filterMeta, pagination } =
|
const salesInvoicesWithPagination =
|
||||||
await this.saleInvoiceApplication.getSaleInvoices(tenantId, filter);
|
await this.saleInvoiceApplication.getSaleInvoices(tenantId, filter);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send(salesInvoicesWithPagination);
|
||||||
sales_invoices: this.transfromToResponse(salesInvoices),
|
|
||||||
pagination: this.transfromToResponse(pagination),
|
|
||||||
filter_meta: this.transfromToResponse(filterMeta),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -501,9 +495,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
tenantId,
|
tenantId,
|
||||||
customerId
|
customerId
|
||||||
);
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({ salesInvoices });
|
||||||
sales_invoices: this.transfromToResponse(salesInvoices),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -531,7 +523,6 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
invoiceId,
|
invoiceId,
|
||||||
writeoffDTO
|
writeoffDTO
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleInvoice.id,
|
id: saleInvoice.id,
|
||||||
message: 'The given sale invoice has been written-off successfully.',
|
message: 'The given sale invoice has been written-off successfully.',
|
||||||
|
|||||||
@@ -3,12 +3,17 @@ import { body, check, param, query } from 'express-validator';
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import BaseController from '../BaseController';
|
import BaseController from '../BaseController';
|
||||||
import { ISaleReceiptDTO, SaleReceiptMailOpts, SaleReceiptMailOptsDTO } from '@/interfaces/SaleReceipt';
|
import {
|
||||||
|
ISaleReceiptDTO,
|
||||||
|
SaleReceiptMailOpts,
|
||||||
|
SaleReceiptMailOptsDTO,
|
||||||
|
} from '@/interfaces/SaleReceipt';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import { AbilitySubject, SaleReceiptAction } from '@/interfaces';
|
import { AbilitySubject, SaleReceiptAction } from '@/interfaces';
|
||||||
import { SaleReceiptApplication } from '@/services/Sales/Receipts/SaleReceiptApplication';
|
import { SaleReceiptApplication } from '@/services/Sales/Receipts/SaleReceiptApplication';
|
||||||
|
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class SalesReceiptsController extends BaseController {
|
export default class SalesReceiptsController extends BaseController {
|
||||||
@@ -62,9 +67,7 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
);
|
);
|
||||||
router.get(
|
router.get(
|
||||||
'/:id/mail',
|
'/:id/mail',
|
||||||
[
|
[...this.specificReceiptValidationSchema],
|
||||||
...this.specificReceiptValidationSchema,
|
|
||||||
],
|
|
||||||
this.validationResult,
|
this.validationResult,
|
||||||
asyncMiddleware(this.getSaleReceiptMail.bind(this)),
|
asyncMiddleware(this.getSaleReceiptMail.bind(this)),
|
||||||
this.handleServiceErrors
|
this.handleServiceErrors
|
||||||
@@ -228,7 +231,6 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
tenantId,
|
tenantId,
|
||||||
saleReceiptId
|
saleReceiptId
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleReceiptId,
|
id: saleReceiptId,
|
||||||
message: 'Sale receipt has been deleted successfully.',
|
message: 'Sale receipt has been deleted successfully.',
|
||||||
@@ -317,15 +319,10 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
...this.matchedQueryData(req),
|
...this.matchedQueryData(req),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { data, pagination, filterMeta } =
|
const salesReceiptsWithPagination =
|
||||||
await this.saleReceiptsApplication.getSaleReceipts(tenantId, filter);
|
await this.saleReceiptsApplication.getSaleReceipts(tenantId, filter);
|
||||||
|
|
||||||
const response = this.transfromToResponse({
|
return res.status(200).send(salesReceiptsWithPagination);
|
||||||
data,
|
|
||||||
pagination,
|
|
||||||
filterMeta,
|
|
||||||
});
|
|
||||||
return res.status(200).send(response);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -337,34 +334,34 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
public async getSaleReceipt(req: Request, res: Response, next: NextFunction) {
|
public async getSaleReceipt(req: Request, res: Response) {
|
||||||
const { id: saleReceiptId } = req.params;
|
const { id: saleReceiptId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
const accept = this.accepts(req);
|
||||||
res.format({
|
|
||||||
'application/json': async () => {
|
const acceptType = accept.types([
|
||||||
const saleReceipt = await this.saleReceiptsApplication.getSaleReceipt(
|
ACCEPT_TYPE.APPLICATION_JSON,
|
||||||
tenantId,
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
saleReceiptId
|
]);
|
||||||
);
|
// Retrieves receipt in pdf format.
|
||||||
return res.status(200).send({ saleReceipt });
|
if (ACCEPT_TYPE.APPLICATION_PDF == acceptType) {
|
||||||
},
|
const pdfContent = await this.saleReceiptsApplication.getSaleReceiptPdf(
|
||||||
'application/pdf': async () => {
|
tenantId,
|
||||||
const pdfContent =
|
saleReceiptId
|
||||||
await this.saleReceiptsApplication.getSaleReceiptPdf(
|
);
|
||||||
tenantId,
|
res.set({
|
||||||
saleReceiptId
|
'Content-Type': 'application/pdf',
|
||||||
);
|
'Content-Length': pdfContent.length,
|
||||||
res.set({
|
|
||||||
'Content-Type': 'application/pdf',
|
|
||||||
'Content-Length': pdfContent.length,
|
|
||||||
});
|
|
||||||
res.send(pdfContent);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} catch (error) {
|
res.send(pdfContent);
|
||||||
next(error);
|
// Retrieves receipt in json format.
|
||||||
|
} else {
|
||||||
|
const saleReceipt = await this.saleReceiptsApplication.getSaleReceipt(
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId
|
||||||
|
);
|
||||||
|
return res.status(200).send({ saleReceipt });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ import {
|
|||||||
} from '@/services/Cashflow/utils';
|
} from '@/services/Cashflow/utils';
|
||||||
import AccountTransaction from './AccountTransaction';
|
import AccountTransaction from './AccountTransaction';
|
||||||
import { CASHFLOW_DIRECTION } from '@/services/Cashflow/constants';
|
import { CASHFLOW_DIRECTION } from '@/services/Cashflow/constants';
|
||||||
|
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||||
export default class CashflowTransaction extends TenantModel {
|
export default class CashflowTransaction extends TenantModel {
|
||||||
|
transactionType: string;
|
||||||
|
amount: number;
|
||||||
|
exchangeRate: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
*/
|
*/
|
||||||
@@ -55,9 +59,10 @@ export default class CashflowTransaction extends TenantModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction type formatted.
|
* Transaction type formatted.
|
||||||
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
get transactionTypeFormatted() {
|
get transactionTypeFormatted() {
|
||||||
return AccountTransaction.getReferenceTypeFormatted(this.transactionType);
|
return getTransactionTypeLabel(this.transactionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
get typeMeta() {
|
get typeMeta() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy';
|
import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy';
|
||||||
import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable';
|
import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable';
|
||||||
|
import GetCreditNote from './GetCreditNote';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class GetCreditNotePdf {
|
export default class GetCreditNotePdf {
|
||||||
@@ -10,11 +11,19 @@ export default class GetCreditNotePdf {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private templateInjectable: TemplateInjectable;
|
private templateInjectable: TemplateInjectable;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getCreditNoteService: GetCreditNote;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve sale invoice pdf content.
|
* Retrieve sale invoice pdf content.
|
||||||
* @param {} saleInvoice -
|
* @param {number} tenantId - Tenant id.
|
||||||
|
* @param {number} creditNoteId - Credit note id.
|
||||||
*/
|
*/
|
||||||
public async getCreditNotePdf(tenantId: number, creditNote) {
|
public async getCreditNotePdf(tenantId: number, creditNoteId: number) {
|
||||||
|
const creditNote = await this.getCreditNoteService.getCreditNote(
|
||||||
|
tenantId,
|
||||||
|
creditNoteId
|
||||||
|
);
|
||||||
const htmlContent = await this.templateInjectable.render(
|
const htmlContent = await this.templateInjectable.render(
|
||||||
tenantId,
|
tenantId,
|
||||||
'modules/credit-note-standard',
|
'modules/credit-note-standard',
|
||||||
|
|||||||
@@ -259,6 +259,6 @@ export class InventoryValuationSheet extends FinancialSheet {
|
|||||||
const items = this.itemsSection();
|
const items = this.itemsSection();
|
||||||
const total = this.totalSection(items);
|
const total = this.totalSection(items);
|
||||||
|
|
||||||
return items.length > 0 ? { items, total } : {};
|
return { items, total };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ export class InventoryValuationSheetTable extends R.compose(
|
|||||||
const itemsRows = this.itemsRowsMapper(this.data.items);
|
const itemsRows = this.itemsRowsMapper(this.data.items);
|
||||||
const totalRow = this.totalRowMapper(this.data.total);
|
const totalRow = this.totalRowMapper(this.data.total);
|
||||||
|
|
||||||
return [...itemsRows, totalRow];
|
return R.compose(
|
||||||
|
R.when(R.always(R.not(R.isEmpty(itemsRows))), R.append(totalRow))
|
||||||
|
)([...itemsRows]) as ITableRow[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
IAccountTransaction,
|
IAccountTransaction,
|
||||||
ISalesByItemsItem,
|
ISalesByItemsItem,
|
||||||
ISalesByItemsTotal,
|
ISalesByItemsTotal,
|
||||||
ISalesByItemsSheetStatement,
|
ISalesByItemsSheetData,
|
||||||
IItem,
|
IItem,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ export default class SalesByItemsReport extends FinancialSheet {
|
|||||||
* @param {IInventoryValuationItem[]} items
|
* @param {IInventoryValuationItem[]} items
|
||||||
* @returns {IInventoryValuationTotal}
|
* @returns {IInventoryValuationTotal}
|
||||||
*/
|
*/
|
||||||
totalSection(items: ISalesByItemsItem[]): ISalesByItemsTotal {
|
private totalSection(items: ISalesByItemsItem[]): ISalesByItemsTotal {
|
||||||
const quantitySold = sumBy(items, (item) => item.quantitySold);
|
const quantitySold = sumBy(items, (item) => item.quantitySold);
|
||||||
const soldCost = sumBy(items, (item) => item.soldCost);
|
const soldCost = sumBy(items, (item) => item.soldCost);
|
||||||
|
|
||||||
@@ -163,12 +163,12 @@ export default class SalesByItemsReport extends FinancialSheet {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the sheet data.
|
* Retrieve the sheet data.
|
||||||
* @returns {ISalesByItemsSheetStatement}
|
* @returns {ISalesByItemsSheetData}
|
||||||
*/
|
*/
|
||||||
reportData(): ISalesByItemsSheetStatement {
|
public reportData(): ISalesByItemsSheetData {
|
||||||
const items = this.itemsSection();
|
const items = this.itemsSection();
|
||||||
const total = this.totalSection(items);
|
const total = this.totalSection(items);
|
||||||
|
|
||||||
return items.length > 0 ? { items, total } : {};
|
return { items, total };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,9 @@ export class SalesByItemsTable extends R.compose(
|
|||||||
const itemsRows = this.itemsMap(this.data.items);
|
const itemsRows = this.itemsMap(this.data.items);
|
||||||
const totalRow = this.totalMap(this.data.total);
|
const totalRow = this.totalMap(this.data.total);
|
||||||
|
|
||||||
return [...itemsRows, totalRow];
|
return R.compose(
|
||||||
|
R.when(R.always(R.not(R.isEmpty(itemsRows))), R.append(totalRow))
|
||||||
|
)([...itemsRows]) as ITableRow[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const AccountInactivateAlert = React.lazy(
|
|||||||
() => import('@/containers/Alerts/Accounts/AccountInactivateAlert'),
|
() => import('@/containers/Alerts/Accounts/AccountInactivateAlert'),
|
||||||
);
|
);
|
||||||
const AccountActivateAlert = React.lazy(
|
const AccountActivateAlert = React.lazy(
|
||||||
() => import('@/containers/Alerts/Accounts/AccountDeleteAlert'),
|
() => import('@/containers/Alerts/Accounts/AccountActivateAlert'),
|
||||||
);
|
);
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
|
||||||
import { MoneyInDialogProvider } from './MoneyInDialogProvider';
|
import { MoneyInDialogProvider } from './MoneyInDialogProvider';
|
||||||
import MoneyInForm from './MoneyInForm';
|
import MoneyInForm from './MoneyInForm';
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ function MoneyInForm({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handles the form submit.
|
// Handles the form submit.
|
||||||
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
const handleFormSubmit = (values, { setSubmitting }) => {
|
||||||
const form = {
|
const form = {
|
||||||
...omit(values, ['currency_code']),
|
...omit(values, ['currency_code']),
|
||||||
publish: true,
|
publish: true,
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ function MoneyOutForm({
|
|||||||
accountId,
|
accountId,
|
||||||
accountType,
|
accountType,
|
||||||
createCashflowTransactionMutate,
|
createCashflowTransactionMutate,
|
||||||
submitPayload,
|
|
||||||
} = useMoneyOutDialogContext();
|
} = useMoneyOutDialogContext();
|
||||||
|
|
||||||
// transaction number.
|
// transaction number.
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { useUpdateEffect } from '@/hooks';
|
|||||||
|
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import { transactionNumber } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncs cashflow auto-increment settings to the form once update.
|
* Syncs cashflow auto-increment settings to the form once update.
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import ReferenceNumberForm from '@/containers/JournalNumber/ReferenceNumberForm'
|
|||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
import { compose } from '@/utils';
|
|
||||||
import {
|
import {
|
||||||
transformFormToSettings,
|
transformFormToSettings,
|
||||||
transformSettingsToForm,
|
transformSettingsToForm,
|
||||||
} from '@/containers/JournalNumber/utils';
|
} from '@/containers/JournalNumber/utils';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction number dialog content.
|
* Transaction number dialog content.
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import useApiRequest from '../useRequest';
|
|||||||
import t from './types';
|
import t from './types';
|
||||||
|
|
||||||
const commonInvalidateQueries = (queryClient) => {
|
const commonInvalidateQueries = (queryClient) => {
|
||||||
|
// Invalidate settings.
|
||||||
|
queryClient.invalidateQueries([t.SETTING, t.SETTING_CASHFLOW]);
|
||||||
|
|
||||||
// Invalidate accounts.
|
// Invalidate accounts.
|
||||||
queryClient.invalidateQueries(t.ACCOUNTS);
|
queryClient.invalidateQueries(t.ACCOUNTS);
|
||||||
queryClient.invalidateQueries(t.ACCOUNT);
|
queryClient.invalidateQueries(t.ACCOUNT);
|
||||||
|
|||||||
Reference in New Issue
Block a user