mirror of
https://github.com/frappe/books.git
synced 2024-11-09 15:20:56 +00:00
incr: remove redundant fields
- complete the feature
This commit is contained in:
parent
d986471323
commit
cd09d31b9b
@ -59,6 +59,10 @@ export abstract class Invoice extends Transactional {
|
||||
return this.fyo.singles.SystemSettings!.currency !== this.currency;
|
||||
}
|
||||
|
||||
get companyCurrency() {
|
||||
return this.fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY;
|
||||
}
|
||||
|
||||
constructor(schema: Schema, data: DocValueMap, fyo: Fyo) {
|
||||
super(schema, data, fyo);
|
||||
this._setGetCurrencies();
|
||||
@ -163,7 +167,6 @@ export abstract class Invoice extends Transactional {
|
||||
account: string;
|
||||
rate: number;
|
||||
amount: Money;
|
||||
baseAmount: Money;
|
||||
[key: string]: DocValue;
|
||||
}
|
||||
> = {};
|
||||
@ -181,7 +184,6 @@ export abstract class Invoice extends Transactional {
|
||||
account,
|
||||
rate,
|
||||
amount: this.fyo.pesa(0),
|
||||
baseAmount: this.fyo.pesa(0),
|
||||
};
|
||||
|
||||
let amount = item.amount!;
|
||||
@ -196,9 +198,7 @@ export abstract class Invoice extends Transactional {
|
||||
|
||||
return Object.keys(taxes)
|
||||
.map((account) => {
|
||||
const tax = taxes[account];
|
||||
tax.baseAmount = tax.amount.mul(this.exchangeRate!);
|
||||
return tax;
|
||||
return taxes[account];
|
||||
})
|
||||
.filter((tax) => !tax.amount.isZero());
|
||||
}
|
||||
@ -311,6 +311,13 @@ export abstract class Invoice extends Transactional {
|
||||
},
|
||||
exchangeRate: {
|
||||
formula: async () => {
|
||||
if (
|
||||
this.currency ===
|
||||
(this.fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY)
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this.exchangeRate && this.exchangeRate !== 1) {
|
||||
return this.exchangeRate;
|
||||
}
|
||||
@ -319,13 +326,11 @@ export abstract class Invoice extends Transactional {
|
||||
},
|
||||
},
|
||||
netTotal: { formula: async () => this.getSum('items', 'amount', false) },
|
||||
baseNetTotal: {
|
||||
formula: async () => this.netTotal!.mul(this.exchangeRate!),
|
||||
},
|
||||
taxes: { formula: async () => await this.getTaxSummary() },
|
||||
grandTotal: { formula: async () => await this.getGrandTotal() },
|
||||
baseGrandTotal: {
|
||||
formula: async () => (this.grandTotal as Money).mul(this.exchangeRate!),
|
||||
formula: async () =>
|
||||
(this.grandTotal as Money).mul(this.exchangeRate! ?? 1),
|
||||
},
|
||||
outstandingAmount: {
|
||||
formula: async () => {
|
||||
@ -378,10 +383,13 @@ export abstract class Invoice extends Transactional {
|
||||
}),
|
||||
};
|
||||
|
||||
getCurrencies: CurrenciesMap = {};
|
||||
getCurrencies: CurrenciesMap = {
|
||||
baseGrandTotal: () => this.companyCurrency,
|
||||
outstandingAmount: () => this.companyCurrency,
|
||||
};
|
||||
_getCurrency() {
|
||||
if (this.exchangeRate === 1) {
|
||||
return this.fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY;
|
||||
return this.companyCurrency;
|
||||
}
|
||||
|
||||
return this.currency ?? DEFAULT_CURRENCY;
|
||||
@ -392,7 +400,7 @@ export abstract class Invoice extends Transactional {
|
||||
);
|
||||
|
||||
for (const { fieldname } of currencyFields) {
|
||||
this.getCurrencies[fieldname] = this._getCurrency.bind(this);
|
||||
this.getCurrencies[fieldname] ??= this._getCurrency.bind(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import { Invoice } from '../Invoice/Invoice';
|
||||
export abstract class InvoiceItem extends Doc {
|
||||
account?: string;
|
||||
amount?: Money;
|
||||
baseAmount?: Money;
|
||||
parentdoc?: Invoice;
|
||||
rate?: Money;
|
||||
quantity?: number;
|
||||
@ -93,7 +92,7 @@ export abstract class InvoiceItem extends Doc {
|
||||
fieldname !== 'itemTaxedTotal' &&
|
||||
fieldname !== 'itemDiscountedTotal'
|
||||
) {
|
||||
return rate ?? this.fyo.pesa(0);
|
||||
return rate?.div(this.exchangeRate) ?? this.fyo.pesa(0);
|
||||
}
|
||||
|
||||
const quantity = this.quantity ?? 0;
|
||||
@ -122,17 +121,14 @@ export abstract class InvoiceItem extends Doc {
|
||||
return rateFromTotals ?? rate ?? this.fyo.pesa(0);
|
||||
},
|
||||
dependsOn: [
|
||||
'party',
|
||||
'exchangeRate',
|
||||
'item',
|
||||
'itemTaxedTotal',
|
||||
'itemDiscountedTotal',
|
||||
'setItemDiscountAmount',
|
||||
],
|
||||
},
|
||||
baseRate: {
|
||||
formula: () =>
|
||||
(this.rate as Money).mul(this.parentdoc!.exchangeRate as number),
|
||||
dependsOn: ['item', 'rate'],
|
||||
},
|
||||
quantity: {
|
||||
formula: async () => {
|
||||
if (!this.item) {
|
||||
@ -177,11 +173,6 @@ export abstract class InvoiceItem extends Doc {
|
||||
formula: () => (this.rate as Money).mul(this.quantity as number),
|
||||
dependsOn: ['item', 'rate', 'quantity'],
|
||||
},
|
||||
baseAmount: {
|
||||
formula: () =>
|
||||
(this.amount as Money).mul(this.parentdoc!.exchangeRate as number),
|
||||
dependsOn: ['item', 'amount', 'rate', 'quantity'],
|
||||
},
|
||||
hsnCode: {
|
||||
formula: async () =>
|
||||
await this.fyo.getValue('Item', this.item as string, 'hsnCode'),
|
||||
@ -373,7 +364,7 @@ export abstract class InvoiceItem extends Doc {
|
||||
);
|
||||
|
||||
for (const { fieldname } of currencyFields) {
|
||||
this.getCurrencies[fieldname] = this._getCurrency.bind(this);
|
||||
this.getCurrencies[fieldname] ??= this._getCurrency.bind(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,16 +10,17 @@ export class PurchaseInvoice extends Invoice {
|
||||
items?: PurchaseInvoiceItem[];
|
||||
|
||||
async getPosting() {
|
||||
const exchangeRate = this.exchangeRate ?? 1;
|
||||
const posting: LedgerPosting = new LedgerPosting(this, this.fyo);
|
||||
await posting.credit(this.account!, this.baseGrandTotal!);
|
||||
|
||||
for (const item of this.items!) {
|
||||
await posting.debit(item.account!, item.baseAmount!);
|
||||
await posting.debit(item.account!, item.amount!.mul(exchangeRate));
|
||||
}
|
||||
|
||||
if (this.taxes) {
|
||||
for (const tax of this.taxes) {
|
||||
await posting.debit(tax.account!, tax.baseAmount!);
|
||||
await posting.debit(tax.account!, tax.amount!.mul(exchangeRate));
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +28,7 @@ export class PurchaseInvoice extends Invoice {
|
||||
const discountAccount = this.fyo.singles.AccountingSettings
|
||||
?.discountAccount as string | undefined;
|
||||
if (discountAccount && discountAmount.isPositive()) {
|
||||
await posting.credit(discountAccount, discountAmount);
|
||||
await posting.credit(discountAccount, discountAmount.mul(exchangeRate));
|
||||
}
|
||||
|
||||
await posting.makeRoundOffEntry();
|
||||
|
@ -10,16 +10,17 @@ export class SalesInvoice extends Invoice {
|
||||
items?: SalesInvoiceItem[];
|
||||
|
||||
async getPosting() {
|
||||
const exchangeRate = this.exchangeRate ?? 1;
|
||||
const posting: LedgerPosting = new LedgerPosting(this, this.fyo);
|
||||
await posting.debit(this.account!, this.baseGrandTotal!);
|
||||
|
||||
for (const item of this.items!) {
|
||||
await posting.credit(item.account!, item.baseAmount!);
|
||||
await posting.credit(item.account!, item.amount!.mul(exchangeRate));
|
||||
}
|
||||
|
||||
if (this.taxes) {
|
||||
for (const tax of this.taxes!) {
|
||||
await posting.credit(tax.account!, tax.baseAmount!);
|
||||
await posting.credit(tax.account!, tax.amount!.mul(exchangeRate));
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +28,7 @@ export class SalesInvoice extends Invoice {
|
||||
const discountAccount = this.fyo.singles.AccountingSettings
|
||||
?.discountAccount as string | undefined;
|
||||
if (discountAccount && discountAmount.isPositive()) {
|
||||
await posting.debit(discountAccount, discountAmount);
|
||||
await posting.debit(discountAccount, discountAmount.mul(exchangeRate));
|
||||
}
|
||||
|
||||
await posting.makeRoundOffEntry();
|
||||
|
@ -1,21 +1,8 @@
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import { FormulaMap } from 'fyo/model/types';
|
||||
import { Money } from 'pesa';
|
||||
|
||||
export class TaxSummary extends Doc {
|
||||
account?: string;
|
||||
rate?: number;
|
||||
amount?: Money;
|
||||
baseAmount?: Money;
|
||||
|
||||
formulas: FormulaMap = {
|
||||
baseAmount: {
|
||||
formula: async () => {
|
||||
const amount = this.amount as Money;
|
||||
const exchangeRate = (this.parentdoc?.exchangeRate ?? 1) as number;
|
||||
return amount.mul(exchangeRate);
|
||||
},
|
||||
dependsOn: ['amount'],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -218,6 +218,11 @@ async function generateB2bData(report: BaseGSTR): Promise<B2BCustomer[]> {
|
||||
? ModelNameEnum.SalesInvoiceItem
|
||||
: ModelNameEnum.PurchaseInvoiceItem;
|
||||
|
||||
const parentSchemaName =
|
||||
report.gstrType === 'GSTR-1'
|
||||
? ModelNameEnum.SalesInvoice
|
||||
: ModelNameEnum.PurchaseInvoice;
|
||||
|
||||
for (const row of report.gstrRows ?? []) {
|
||||
const invRecord: B2BInvRecord = {
|
||||
inum: row.invNo,
|
||||
@ -229,20 +234,29 @@ async function generateB2bData(report: BaseGSTR): Promise<B2BCustomer[]> {
|
||||
itms: [],
|
||||
};
|
||||
|
||||
const exchangeRate = (
|
||||
await fyo.db.getAllRaw(parentSchemaName, {
|
||||
fields: ['exchangeRate'],
|
||||
filters: { name: invRecord.inum },
|
||||
})
|
||||
)[0].exchangeRate as number;
|
||||
|
||||
const items = await fyo.db.getAllRaw(schemaName, {
|
||||
fields: ['baseAmount', 'tax', 'hsnCode'],
|
||||
filters: { parent: invRecord.inum as string },
|
||||
fields: ['amount', 'tax', 'hsnCode'],
|
||||
filters: { parent: invRecord.inum },
|
||||
});
|
||||
|
||||
items.forEach((item) => {
|
||||
const hsnCode = item.hsnCode as number;
|
||||
const tax = item.tax as string;
|
||||
const baseAmount = (item.baseAmount ?? 0) as string;
|
||||
const baseAmount = fyo
|
||||
.pesa((item.amount as string) ?? 0)
|
||||
.mul(exchangeRate);
|
||||
|
||||
const itemRecord: B2BItmRecord = {
|
||||
num: hsnCode,
|
||||
itm_det: {
|
||||
txval: fyo.pesa(baseAmount).float,
|
||||
txval: baseAmount.float,
|
||||
rt: GST[tax],
|
||||
csamt: 0,
|
||||
camt: fyo
|
||||
@ -292,6 +306,11 @@ async function generateB2clData(
|
||||
? ModelNameEnum.SalesInvoiceItem
|
||||
: ModelNameEnum.PurchaseInvoiceItem;
|
||||
|
||||
const parentSchemaName =
|
||||
report.gstrType === 'GSTR-1'
|
||||
? ModelNameEnum.SalesInvoice
|
||||
: ModelNameEnum.PurchaseInvoice;
|
||||
|
||||
for (const row of report.gstrRows ?? []) {
|
||||
const invRecord: B2CLInvRecord = {
|
||||
inum: row.invNo,
|
||||
@ -300,20 +319,29 @@ async function generateB2clData(
|
||||
itms: [],
|
||||
};
|
||||
|
||||
const exchangeRate = (
|
||||
await fyo.db.getAllRaw(parentSchemaName, {
|
||||
fields: ['exchangeRate'],
|
||||
filters: { name: invRecord.inum },
|
||||
})
|
||||
)[0].exchangeRate as number;
|
||||
|
||||
const items = await fyo.db.getAllRaw(schemaName, {
|
||||
fields: ['hsnCode', 'tax', 'baseAmount'],
|
||||
fields: ['amount', 'tax', 'hsnCode'],
|
||||
filters: { parent: invRecord.inum },
|
||||
});
|
||||
|
||||
items.forEach((item) => {
|
||||
const hsnCode = item.hsnCode as number;
|
||||
const tax = item.tax as string;
|
||||
const baseAmount = (item.baseAmount ?? 0) as string;
|
||||
const baseAmount = fyo
|
||||
.pesa((item.amount as string) ?? 0)
|
||||
.mul(exchangeRate);
|
||||
|
||||
const itemRecord: B2CLItmRecord = {
|
||||
num: hsnCode,
|
||||
itm_det: {
|
||||
txval: fyo.pesa(baseAmount).float,
|
||||
txval: baseAmount.float,
|
||||
rt: GST[tax] ?? 0,
|
||||
csamt: 0,
|
||||
iamt: fyo
|
||||
|
@ -54,12 +54,6 @@
|
||||
"fieldtype": "Currency",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"fieldname": "baseNetTotal",
|
||||
"label": "Net Total (Company Currency)",
|
||||
"fieldtype": "Currency",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes",
|
||||
"label": "Taxes",
|
||||
|
@ -30,12 +30,6 @@
|
||||
"fieldtype": "Currency",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"fieldname": "baseRate",
|
||||
"label": "Rate (Company Currency)",
|
||||
"fieldtype": "Currency",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"fieldname": "account",
|
||||
"label": "Account",
|
||||
@ -56,12 +50,6 @@
|
||||
"fieldtype": "Currency",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"fieldname": "baseAmount",
|
||||
"label": "Amount (Company Currency)",
|
||||
"fieldtype": "Currency",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"fieldname": "setItemDiscountAmount",
|
||||
"label": "Set Discount Amount",
|
||||
|
@ -21,12 +21,6 @@
|
||||
"label": "Amount",
|
||||
"fieldtype": "Currency",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"fieldname": "baseAmount",
|
||||
"label": "Amount (Company Currency)",
|
||||
"fieldtype": "Currency",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
@ -77,8 +77,8 @@
|
||||
:border="true"
|
||||
:df="getField('party')"
|
||||
:value="doc.party"
|
||||
@change="(value) => doc.set('party', value)"
|
||||
@new-doc="(party) => doc.set('party', party.name)"
|
||||
@change="(value) => doc.set('party', value, true)"
|
||||
@new-doc="(party) => doc.set('party', party.name, true)"
|
||||
:read-only="doc?.submitted"
|
||||
/>
|
||||
<FormControl
|
||||
@ -230,6 +230,21 @@
|
||||
<div>{{ formattedValue('grandTotal') }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Base Grand Total -->
|
||||
<div
|
||||
v-if="doc.isMultiCurrency"
|
||||
class="
|
||||
flex
|
||||
justify-between
|
||||
text-green-600
|
||||
font-semibold
|
||||
text-base
|
||||
"
|
||||
>
|
||||
<div>{{ t`Base Grand Total` }}</div>
|
||||
<div>{{ formattedValue('baseGrandTotal') }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Outstanding Amount -->
|
||||
<hr v-if="doc.outstandingAmount?.float > 0" />
|
||||
<div
|
||||
|
Loading…
Reference in New Issue
Block a user