mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
incr: type ledgerposting
This commit is contained in:
parent
781c1d70e9
commit
71800dffd6
@ -1,33 +1,66 @@
|
||||
import frappe from 'frappe';
|
||||
import Doc from 'frappe/model/doc';
|
||||
import Money from 'pesa/dist/types/src/money';
|
||||
import {
|
||||
AccountEntry,
|
||||
LedgerEntry,
|
||||
LedgerPostingOptions,
|
||||
TransactionType,
|
||||
} from './types';
|
||||
|
||||
export default class LedgerPosting {
|
||||
constructor({ reference, party, date, description }) {
|
||||
export class LedgerPosting {
|
||||
reference: Doc;
|
||||
party?: string;
|
||||
date?: string;
|
||||
description?: string;
|
||||
entries: LedgerEntry[];
|
||||
entryMap: Record<string, LedgerEntry>;
|
||||
reverted: boolean;
|
||||
accountEntries: AccountEntry[];
|
||||
|
||||
constructor({ reference, party, date, description }: LedgerPostingOptions) {
|
||||
this.reference = reference;
|
||||
this.party = party;
|
||||
this.date = date;
|
||||
this.description = description;
|
||||
this.description = description ?? '';
|
||||
this.entries = [];
|
||||
this.entryMap = {};
|
||||
this.reverted = 0;
|
||||
this.reverted = false;
|
||||
// To change balance while entering ledger entries
|
||||
this.accountEntries = [];
|
||||
}
|
||||
|
||||
async debit(account, amount, referenceType, referenceName) {
|
||||
async debit(
|
||||
account: string,
|
||||
amount: Money,
|
||||
referenceType?: string,
|
||||
referenceName?: string
|
||||
) {
|
||||
const entry = this.getEntry(account, referenceType, referenceName);
|
||||
entry.debit = entry.debit.add(amount);
|
||||
await this.setAccountBalanceChange(account, 'debit', amount);
|
||||
}
|
||||
|
||||
async credit(account, amount, referenceType, referenceName) {
|
||||
async credit(
|
||||
account: string,
|
||||
amount: Money,
|
||||
referenceType?: string,
|
||||
referenceName?: string
|
||||
) {
|
||||
const entry = this.getEntry(account, referenceType, referenceName);
|
||||
entry.credit = entry.credit.add(amount);
|
||||
await this.setAccountBalanceChange(account, 'credit', amount);
|
||||
}
|
||||
|
||||
async setAccountBalanceChange(accountName, type, amount) {
|
||||
async setAccountBalanceChange(
|
||||
accountName: string,
|
||||
type: TransactionType,
|
||||
amount: Money
|
||||
) {
|
||||
const debitAccounts = ['Asset', 'Expense'];
|
||||
const { rootType } = await frappe.doc.getDoc('Account', accountName);
|
||||
const accountDoc = await frappe.doc.getDoc('Account', accountName);
|
||||
const rootType = accountDoc.rootType as string;
|
||||
|
||||
if (debitAccounts.indexOf(rootType) === -1) {
|
||||
const change = type == 'credit' ? amount : amount.neg();
|
||||
this.accountEntries.push({
|
||||
@ -43,14 +76,14 @@ export default class LedgerPosting {
|
||||
}
|
||||
}
|
||||
|
||||
getEntry(account, referenceType, referenceName) {
|
||||
getEntry(account: string, referenceType?: string, referenceName?: string) {
|
||||
if (!this.entryMap[account]) {
|
||||
const entry = {
|
||||
const entry: LedgerEntry = {
|
||||
account: account,
|
||||
party: this.party || '',
|
||||
date: this.date || this.reference.date,
|
||||
referenceType: referenceType || this.reference.doctype,
|
||||
referenceName: referenceName || this.reference.name,
|
||||
party: this.party ?? '',
|
||||
date: this.date ?? (this.reference.date as string),
|
||||
referenceType: referenceType ?? this.reference.schemaName,
|
||||
referenceName: referenceName ?? this.reference.name!,
|
||||
description: this.description,
|
||||
reverted: this.reverted,
|
||||
debit: frappe.pesa(0),
|
||||
@ -72,47 +105,46 @@ export default class LedgerPosting {
|
||||
async postReverse() {
|
||||
this.validateEntries();
|
||||
|
||||
let data = await frappe.db.getAll({
|
||||
doctype: 'AccountingLedgerEntry',
|
||||
const data = await frappe.db.getAll('AccountingLedgerEntry', {
|
||||
fields: ['name'],
|
||||
filters: {
|
||||
referenceName: this.reference.name,
|
||||
reverted: 0,
|
||||
referenceName: this.reference.name!,
|
||||
reverted: false,
|
||||
},
|
||||
});
|
||||
|
||||
for (let entry of data) {
|
||||
let entryDoc = await frappe.doc.getDoc(
|
||||
for (const entry of data) {
|
||||
const entryDoc = await frappe.doc.getDoc(
|
||||
'AccountingLedgerEntry',
|
||||
entry.name
|
||||
entry.name as string
|
||||
);
|
||||
entryDoc.reverted = 1;
|
||||
entryDoc.reverted = true;
|
||||
await entryDoc.update();
|
||||
}
|
||||
|
||||
let temp;
|
||||
for (let entry of this.entries) {
|
||||
for (const entry of this.entries) {
|
||||
temp = entry.debit;
|
||||
entry.debit = entry.credit;
|
||||
entry.credit = temp;
|
||||
entry.reverted = 1;
|
||||
entry.reverted = true;
|
||||
}
|
||||
for (let entry of this.accountEntries) {
|
||||
entry.balanceChange = entry.balanceChange.neg();
|
||||
for (const entry of this.accountEntries) {
|
||||
entry.balanceChange = (entry.balanceChange as Money).neg();
|
||||
}
|
||||
await this.insertEntries();
|
||||
}
|
||||
|
||||
makeRoundOffEntry() {
|
||||
let { debit, credit } = this.getTotalDebitAndCredit();
|
||||
let difference = debit.sub(credit);
|
||||
let absoluteValue = difference.abs();
|
||||
let allowance = 0.5;
|
||||
const { debit, credit } = this.getTotalDebitAndCredit();
|
||||
const difference = debit.sub(credit);
|
||||
const absoluteValue = difference.abs();
|
||||
const allowance = 0.5;
|
||||
if (absoluteValue.eq(0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let roundOffAccount = this.getRoundOffAccount();
|
||||
const roundOffAccount = this.getRoundOffAccount();
|
||||
if (absoluteValue.lte(allowance)) {
|
||||
if (difference.gt(0)) {
|
||||
this.credit(roundOffAccount, absoluteValue);
|
||||
@ -123,7 +155,7 @@ export default class LedgerPosting {
|
||||
}
|
||||
|
||||
validateEntries() {
|
||||
let { debit, credit } = this.getTotalDebitAndCredit();
|
||||
const { debit, credit } = this.getTotalDebitAndCredit();
|
||||
if (debit.neq(credit)) {
|
||||
throw new frappe.errors.ValidationError(
|
||||
`Total Debit: ${frappe.format(
|
||||
@ -138,7 +170,7 @@ export default class LedgerPosting {
|
||||
let debit = frappe.pesa(0);
|
||||
let credit = frappe.pesa(0);
|
||||
|
||||
for (let entry of this.entries) {
|
||||
for (const entry of this.entries) {
|
||||
debit = debit.add(entry.debit);
|
||||
credit = credit.add(entry.credit);
|
||||
}
|
||||
@ -147,19 +179,20 @@ export default class LedgerPosting {
|
||||
}
|
||||
|
||||
async insertEntries() {
|
||||
for (let entry of this.entries) {
|
||||
let entryDoc = frappe.doc.getNewDoc('AccountingLedgerEntry');
|
||||
for (const entry of this.entries) {
|
||||
const entryDoc = frappe.doc.getNewDoc('AccountingLedgerEntry');
|
||||
Object.assign(entryDoc, entry);
|
||||
await entryDoc.insert();
|
||||
}
|
||||
for (let entry of this.accountEntries) {
|
||||
let entryDoc = await frappe.doc.getDoc('Account', entry.name);
|
||||
entryDoc.balance = entryDoc.balance.add(entry.balanceChange);
|
||||
for (const entry of this.accountEntries) {
|
||||
const entryDoc = await frappe.doc.getDoc('Account', entry.name);
|
||||
const balance = entryDoc.get('balance') as Money;
|
||||
entryDoc.balance = balance.add(entry.balanceChange);
|
||||
await entryDoc.update();
|
||||
}
|
||||
}
|
||||
|
||||
getRoundOffAccount() {
|
||||
return frappe.AccountingSettings.roundOffAccount;
|
||||
return frappe.singles.AccountingSettings!.roundOffAccount as string;
|
||||
}
|
||||
}
|
27
accounting/types.ts
Normal file
27
accounting/types.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import Doc from 'frappe/model/doc';
|
||||
import Money from 'pesa/dist/types/src/money';
|
||||
|
||||
export interface LedgerPostingOptions {
|
||||
reference: Doc;
|
||||
party?: string;
|
||||
date?: string;
|
||||
description?: string;
|
||||
}
|
||||
export interface LedgerEntry {
|
||||
account: string;
|
||||
party: string;
|
||||
date: string;
|
||||
referenceType: string;
|
||||
referenceName: string;
|
||||
description?: string;
|
||||
reverted: boolean;
|
||||
debit: Money;
|
||||
credit: Money;
|
||||
}
|
||||
|
||||
export interface AccountEntry {
|
||||
name: string;
|
||||
balanceChange: Money;
|
||||
}
|
||||
|
||||
export type TransactionType = 'credit' | 'debit';
|
@ -72,6 +72,10 @@ export class Frappe {
|
||||
return this.doc.models;
|
||||
}
|
||||
|
||||
get singles() {
|
||||
return this.doc.singles;
|
||||
}
|
||||
|
||||
get schemaMap() {
|
||||
return this.db.schemaMap;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user