2
0
mirror of https://github.com/frappe/books.git synced 2025-01-23 15:18:24 +00:00

fix: update ledger posting calculations

This commit is contained in:
18alantom 2021-12-28 13:35:53 +05:30
parent 5c6ac0e161
commit c9349b0570

View File

@ -1,5 +1,4 @@
import frappe from 'frappejs'; import frappe from 'frappejs';
import { round } from 'frappejs/utils/numberFormat';
export default class LedgerPosting { export default class LedgerPosting {
constructor({ reference, party, date, description }) { constructor({ reference, party, date, description }) {
@ -16,13 +15,13 @@ export default class LedgerPosting {
async debit(account, amount, referenceType, referenceName) { async debit(account, amount, referenceType, referenceName) {
const entry = this.getEntry(account, referenceType, referenceName); const entry = this.getEntry(account, referenceType, referenceName);
entry.debit += amount; entry.debit = entry.debit.add(amount);
await this.setAccountBalanceChange(account, 'debit', amount); await this.setAccountBalanceChange(account, 'debit', amount);
} }
async credit(account, amount, referenceType, referenceName) { async credit(account, amount, referenceType, referenceName) {
const entry = this.getEntry(account, referenceType, referenceName); const entry = this.getEntry(account, referenceType, referenceName);
entry.credit += amount; entry.credit = entry.credit.add(amount);
await this.setAccountBalanceChange(account, 'credit', amount); await this.setAccountBalanceChange(account, 'credit', amount);
} }
@ -30,16 +29,16 @@ export default class LedgerPosting {
const debitAccounts = ['Asset', 'Expense']; const debitAccounts = ['Asset', 'Expense'];
const { rootType } = await frappe.getDoc('Account', accountName); const { rootType } = await frappe.getDoc('Account', accountName);
if (debitAccounts.indexOf(rootType) === -1) { if (debitAccounts.indexOf(rootType) === -1) {
const change = type == 'credit' ? amount : -1 * amount; const change = type == 'credit' ? amount : amount.mul(-1);
this.accountEntries.push({ this.accountEntries.push({
name: accountName, name: accountName,
balanceChange: change balanceChange: change,
}); });
} else { } else {
const change = type == 'debit' ? amount : -1 * amount; const change = type == 'debit' ? amount : amount.mul(-1);
this.accountEntries.push({ this.accountEntries.push({
name: accountName, name: accountName,
balanceChange: change balanceChange: change,
}); });
} }
} }
@ -54,8 +53,8 @@ export default class LedgerPosting {
referenceName: referenceName || this.reference.name, referenceName: referenceName || this.reference.name,
description: this.description, description: this.description,
reverted: this.reverted, reverted: this.reverted,
debit: 0, debit: frappe.pesa(0),
credit: 0 credit: frappe.pesa(0),
}; };
this.entries.push(entry); this.entries.push(entry);
@ -78,8 +77,8 @@ export default class LedgerPosting {
fields: ['name'], fields: ['name'],
filters: { filters: {
referenceName: this.reference.name, referenceName: this.reference.name,
reverted: 0 reverted: 0,
} },
}); });
for (let entry of data) { for (let entry of data) {
@ -96,24 +95,23 @@ export default class LedgerPosting {
entry.reverted = 1; entry.reverted = 1;
} }
for (let entry of this.accountEntries) { for (let entry of this.accountEntries) {
entry.balanceChange = -1 * entry.balanceChange; entry.balanceChange = entry.balanceChange.mul(-1);
} }
await this.insertEntries(); await this.insertEntries();
} }
makeRoundOffEntry() { makeRoundOffEntry() {
let { debit, credit } = this.getTotalDebitAndCredit(); let { debit, credit } = this.getTotalDebitAndCredit();
let precision = this.getPrecision(); let difference = debit.sub(credit);
let difference = round(debit - credit, precision); let absoluteValue = difference.abs();
let absoluteValue = Math.abs(difference);
let allowance = 0.5; let allowance = 0.5;
if (absoluteValue === 0) { if (absoluteValue.eq(0)) {
return; return;
} }
let roundOffAccount = this.getRoundOffAccount(); let roundOffAccount = this.getRoundOffAccount();
if (absoluteValue <= allowance) { if (absoluteValue.lte(allowance)) {
if (difference > 0) { if (difference.gt(0)) {
this.credit(roundOffAccount, absoluteValue); this.credit(roundOffAccount, absoluteValue);
} else { } else {
this.debit(roundOffAccount, absoluteValue); this.debit(roundOffAccount, absoluteValue);
@ -123,49 +121,41 @@ export default class LedgerPosting {
validateEntries() { validateEntries() {
let { debit, credit } = this.getTotalDebitAndCredit(); let { debit, credit } = this.getTotalDebitAndCredit();
if (debit !== credit) { if (!debit.eq(credit)) {
throw new Error( throw new Error(
`Total Debit (${debit}) must be equal to Total Credit (${credit})` `Total Debit (${debit.round()}) must be equal to Total Credit (${credit.round()})`
); );
} }
} }
getTotalDebitAndCredit() { getTotalDebitAndCredit() {
let debit = 0; let debit = frappe.pesa(0);
let credit = 0; let credit = frappe.pesa(0);
for (let entry of this.entries) { for (let entry of this.entries) {
debit += entry.debit; debit = debit.add(entry.debit);
credit += entry.credit; credit = credit.add(entry.credit);
} }
let precision = this.getPrecision();
debit = round(debit, precision);
credit = round(credit, precision);
return { debit, credit }; return { debit, credit };
} }
async insertEntries() { async insertEntries() {
for (let entry of this.entries) { for (let entry of this.entries) {
let entryDoc = frappe.newDoc({ let entryDoc = frappe.newDoc({
doctype: 'AccountingLedgerEntry' doctype: 'AccountingLedgerEntry',
}); });
Object.assign(entryDoc, entry); Object.assign(entryDoc, entry);
await entryDoc.insert(); await entryDoc.insert();
} }
for (let entry of this.accountEntries) { for (let entry of this.accountEntries) {
let entryDoc = await frappe.getDoc('Account', entry.name); let entryDoc = await frappe.getDoc('Account', entry.name);
entryDoc.balance += entry.balanceChange; entryDoc.balance = entryDoc.balance.add(entry.balanceChange);
await entryDoc.update(); await entryDoc.update();
} }
} }
getPrecision() {
return frappe.SystemSettings.internalPrecision;
}
getRoundOffAccount() { getRoundOffAccount() {
return frappe.AccountingSettings.roundOffAccount; return frappe.AccountingSettings.roundOffAccount;
} }
}; }