fix: Date format in sales/purchases APIs.

fix: Algorithm FIFO cost calculate method.
This commit is contained in:
Ahmed Bouhuolia
2020-08-19 00:13:53 +02:00
parent a202a21df5
commit 52d01b4ed8
21 changed files with 291 additions and 133 deletions

View File

@@ -15,6 +15,7 @@ import JournalPosterService from '@/services/Sales/JournalPosterService';
import ServiceItemsEntries from '@/services/Sales/ServiceItemsEntries';
import PaymentReceiveEntryRepository from '@/repositories/PaymentReceiveEntryRepository';
import CustomerRepository from '@/repositories/CustomerRepository';
import { formatDateFields } from '@/utils';
/**
* Payment receive service.
@@ -33,7 +34,7 @@ export default class PaymentReceiveService {
.query()
.insert({
amount: paymentAmount,
...omit(paymentReceive, ['entries']),
...formatDateFields(omit(paymentReceive, ['entries']), ['payment_date']),
});
const storeOpers: Array<any> = [];
@@ -97,7 +98,7 @@ export default class PaymentReceiveService {
.where('id', paymentReceiveId)
.update({
amount: paymentAmount,
...omit(paymentReceive, ['entries']),
...formatDateFields(omit(paymentReceive, ['entries']), ['payment_date']),
});
const opers = [];
const entriesIds = paymentReceive.entries.filter((i: any) => i.id);

View File

@@ -2,21 +2,23 @@ import { omit, difference, sumBy, mixin } from 'lodash';
import moment from 'moment';
import { SaleEstimate, ItemEntry } from '@/models';
import HasItemsEntries from '@/services/Sales/HasItemsEntries';
import { formatDateFields } from '@/utils';
export default class SaleEstimateService {
/**
* Creates a new estimate with associated entries.
* @async
* @param {IEstimate} estimate
* @param {EstimateDTO} estimate
* @return {void}
*/
static async createEstimate(estimate: any) {
const amount = sumBy(estimate.entries, 'amount');
static async createEstimate(estimateDTO: any) {
const estimate = {
amount: sumBy(estimateDTO.entries, 'amount'),
...formatDateFields(estimateDTO, ['estimate_date', 'expiration_date']),
};
const storedEstimate = await SaleEstimate.tenant()
.query()
.insert({
amount,
...omit(estimate, ['entries']),
});
const storeEstimateEntriesOpers: any[] = [];
@@ -36,34 +38,21 @@ export default class SaleEstimateService {
return storedEstimate;
}
/**
* Deletes the given estimate id with associated entries.
* @async
* @param {IEstimate} estimateId
* @return {void}
*/
static async deleteEstimate(estimateId: number) {
await ItemEntry.tenant()
.query()
.where('reference_id', estimateId)
.where('reference_type', 'SaleEstimate')
.delete();
await SaleEstimate.tenant().query().where('id', estimateId).delete();
}
/**
* Edit details of the given estimate with associated entries.
* @async
* @param {Integer} estimateId
* @param {IEstimate} estimate
* @param {EstimateDTO} estimate
* @return {void}
*/
static async editEstimate(estimateId: number, estimate: any) {
const amount = sumBy(estimate.entries, 'amount');
static async editEstimate(estimateId: number, estimateDTO: any) {
const estimate = {
amount: sumBy(estimateDTO.entries, 'amount'),
...formatDateFields(estimateDTO, ['estimate_date', 'expiration_date']),
};
const updatedEstimate = await SaleEstimate.tenant()
.query()
.update({
amount,
...omit(estimate, ['entries']),
});
const storedEstimateEntries = await ItemEntry.tenant()
@@ -79,6 +68,26 @@ export default class SaleEstimateService {
]);
}
/**
* Deletes the given estimate id with associated entries.
* @async
* @param {IEstimate} estimateId
* @return {void}
*/
static async deleteEstimate(estimateId: number) {
await ItemEntry.tenant()
.query()
.where('reference_id', estimateId)
.where('reference_type', 'SaleEstimate')
.delete();
await SaleEstimate.tenant()
.query()
.where('id', estimateId)
.delete();
}
/**
* Validates the given estimate ID exists.
* @async

View File

@@ -1,4 +1,4 @@
import { omit, sumBy, difference } from 'lodash';
import { omit, sumBy, difference, pick } from 'lodash';
import { Container } from 'typedi';
import {
SaleInvoice,
@@ -12,6 +12,7 @@ import JournalPoster from '@/services/Accounting/JournalPoster';
import HasItemsEntries from '@/services/Sales/HasItemsEntries';
import CustomerRepository from '@/repositories/CustomerRepository';
import InventoryService from '@/services/Inventory/Inventory';
import { formatDateFields } from '@/utils';
/**
* Sales invoices service
@@ -25,14 +26,19 @@ export default class SaleInvoicesService {
* @param {ISaleInvoice}
* @return {ISaleInvoice}
*/
static async createSaleInvoice(saleInvoice: any) {
const balance = sumBy(saleInvoice.entries, 'amount');
static async createSaleInvoice(saleInvoiceDTO: any) {
const balance = sumBy(saleInvoiceDTO.entries, 'amount');
const invLotNumber = await InventoryService.nextLotNumber();
const saleInvoice = {
...formatDateFields(saleInvoiceDTO, ['invoide_date', 'due_date']),
balance,
paymentAmount: 0,
invLotNumber,
};
const storedInvoice = await SaleInvoice.tenant()
.query()
.insert({
...omit(saleInvoice, ['entries']),
balance,
payment_amount: 0,
});
const opers: Array<any> = [];
@@ -52,8 +58,8 @@ export default class SaleInvoicesService {
balance,
);
// Records the inventory transactions for inventory items.
const recordInventoryTransOpers = InventoryService.recordInventoryTransactions(
saleInvoice.entries, saleInvoice.invoice_date, 'SaleInvoice', storedInvoice.id, 'OUT',
const recordInventoryTransOpers = this.recordInventoryTranscactions(
saleInvoice, storedInvoice.id
);
// Await all async operations.
await Promise.all([
@@ -79,11 +85,33 @@ export default class SaleInvoicesService {
}
/**
* Records the inventory transactions from the givne sale invoice input.
* @param {SaleInvoice} saleInvoice -
* @param {number} saleInvoiceId -
* @param {boolean} override -
*/
static recordInventoryTranscactions(saleInvoice, saleInvoiceId: number, override?: boolean){
const inventortyTransactions = saleInvoice.entries
.map((entry) => ({
...pick(entry, ['item_id', 'quantity', 'rate']),
lotNumber: saleInvoice.invLotNumber,
transactionType: 'SaleInvoice',
transactionId: saleInvoiceId,
direction: 'OUT',
date: saleInvoice.invoice_date,
}));
return InventoryService.recordInventoryTransactions(
inventortyTransactions, override,
);
}
/**
* Schedule sale invoice re-compute based on the item
* cost method and starting date
*
* @param saleInvoice
* @param {SaleInvoice} saleInvoice -
* @return {Promise<Agenda>}
*/
static scheduleComputeItemsCost(saleInvoice) {
@@ -102,18 +130,22 @@ export default class SaleInvoicesService {
* @param {Number} saleInvoiceId -
* @param {ISaleInvoice} saleInvoice -
*/
static async editSaleInvoice(saleInvoiceId: number, saleInvoice: any) {
const balance = sumBy(saleInvoice.entries, 'amount');
static async editSaleInvoice(saleInvoiceId: number, saleInvoiceDTO: any) {
const balance = sumBy(saleInvoiceDTO.entries, 'amount');
const oldSaleInvoice = await SaleInvoice.tenant().query()
.where('id', saleInvoiceId)
.first();
const saleInvoice = {
...formatDateFields(saleInvoiceDTO, ['invoice_date', 'due_date']),
balance,
invLotNumber: oldSaleInvoice.invLotNumber,
};
const updatedSaleInvoices = await SaleInvoice.tenant()
.query()
.where('id', saleInvoiceId)
.update({
balance,
...omit(saleInvoice, ['entries']),
...omit(saleInvoice, ['entries', 'invLotNumber']),
});
// Fetches the sale invoice items entries.
const storedEntries = await ItemEntry.tenant()
@@ -132,9 +164,14 @@ export default class SaleInvoicesService {
balance,
oldSaleInvoice.balance,
);
// Records the inventory transactions for inventory items.
const recordInventoryTransOper = this.recordInventoryTranscactions(
saleInvoice, saleInvoiceId, true,
);
await Promise.all([
patchItemsEntriesOper,
changeCustomerBalanceOper,
recordInventoryTransOper,
]);
// Schedule sale invoice re-compute based on the item cost
@@ -221,7 +258,6 @@ export default class SaleInvoicesService {
const revertInventoryTransactionsOper = this.revertInventoryTransactions(
inventoryTransactions
);
// Await all async operations.
await Promise.all([
journal.deleteEntries(),

View File

@@ -7,6 +7,7 @@ import {
import JournalPoster from '@/services/Accounting/JournalPoster';
import JournalPosterService from '@/services/Sales/JournalPosterService';
import HasItemEntries from '@/services/Sales/HasItemsEntries';
import { formatDateFields } from '@/utils';
export default class SalesReceipt {
/**
@@ -15,12 +16,14 @@ export default class SalesReceipt {
* @param {ISaleReceipt} saleReceipt
* @return {Object}
*/
static async createSaleReceipt(saleReceipt: any) {
const amount = sumBy(saleReceipt.entries, 'amount');
static async createSaleReceipt(saleReceiptDTO: any) {
const saleReceipt = {
amount: sumBy(saleReceiptDTO.entries, 'amount');
...formatDateFields(saleReceiptDTO, ['receipt_date'])
};
const storedSaleReceipt = await SaleReceipt.tenant()
.query()
.insert({
amount,
...omit(saleReceipt, ['entries']),
});
const storeSaleReceiptEntriesOpers: Array<any> = [];
@@ -39,29 +42,21 @@ export default class SalesReceipt {
return storedSaleReceipt;
}
/**
* Records journal transactions for sale receipt.
* @param {ISaleReceipt} saleReceipt
* @return {Promise}
*/
static async _recordJournalTransactions(saleReceipt: any) {
const accountsDepGraph = await Account.tenant().depGraph().query();
const journalPoster = new JournalPoster(accountsDepGraph);
}
/**
* Edit details sale receipt with associated entries.
* @param {Integer} saleReceiptId
* @param {ISaleReceipt} saleReceipt
* @return {void}
*/
static async editSaleReceipt(saleReceiptId: number, saleReceipt: any) {
const amount = sumBy(saleReceipt.entries, 'amount');
static async editSaleReceipt(saleReceiptId: number, saleReceiptDTO: any) {
const saleReceipt = {
amount: sumBy(saleReceiptDTO.entries, 'amount'),
...formatDateFields(saleReceiptDTO, ['receipt_date'])
};
const updatedSaleReceipt = await SaleReceipt.tenant()
.query()
.where('id', saleReceiptId)
.update({
amount,
...omit(saleReceipt, ['entries']),
});
const storedSaleReceiptEntries = await ItemEntry.tenant()
@@ -82,7 +77,11 @@ export default class SalesReceipt {
* @return {void}
*/
static async deleteSaleReceipt(saleReceiptId: number) {
const deleteSaleReceiptOper = SaleReceipt.tenant().query().where('id', saleReceiptId).delete();
const deleteSaleReceiptOper = SaleReceipt.tenant()
.query()
.where('id', saleReceiptId)
.delete();
const deleteItemsEntriesOper = ItemEntry.tenant()
.query()
.where('reference_id', saleReceiptId)
@@ -148,4 +147,14 @@ export default class SalesReceipt {
return saleReceipt;
}
/**
* Records journal transactions for sale receipt.
* @param {ISaleReceipt} saleReceipt
* @return {Promise}
*/
static async _recordJournalTransactions(saleReceipt: any) {
const accountsDepGraph = await Account.tenant().depGraph().query();
const journalPoster = new JournalPoster(accountsDepGraph);
}
}