diff --git a/fyo/model/doc.ts b/fyo/model/doc.ts index f7eed3ca..b4b804a2 100644 --- a/fyo/model/doc.ts +++ b/fyo/model/doc.ts @@ -191,7 +191,6 @@ export class Doc extends Observable { if (typeof fieldname === 'object') { return await this.setMultiple(fieldname as DocValueMap); } - console.log(fieldname, value); if (!this._canSet(fieldname, value)) { return false; diff --git a/fyo/models/SystemSettings.ts b/fyo/models/SystemSettings.ts index 7eb5c327..6d6f1d74 100644 --- a/fyo/models/SystemSettings.ts +++ b/fyo/models/SystemSettings.ts @@ -7,6 +7,16 @@ import { SelectOption } from 'schemas/types'; import { getCountryInfo } from 'utils/misc'; export default class SystemSettings extends Doc { + dateFormat?: string; + locale?: string; + displayPrecision?: number; + internalPrecision?: number; + hideGetStarted?: boolean; + countryCode?: string; + currency?: string; + version?: string; + instanceId?: string; + validations: ValidationMap = { async displayPrecision(value: DocValue) { if ((value as number) >= 0 && (value as number) <= 9) { diff --git a/fyo/utils/format.ts b/fyo/utils/format.ts index 6abd0f47..8e6be3b5 100644 --- a/fyo/utils/format.ts +++ b/fyo/utils/format.ts @@ -70,7 +70,7 @@ function formatCurrency( doc: Doc | null, fyo: Fyo ): string { - const currency = getCurrency(field, doc, fyo); + const currency = getCurrency(value as Money, field, doc, fyo); let valueString; try { @@ -128,7 +128,20 @@ function getNumberFormatter(fyo: Fyo) { })); } -function getCurrency(field: Field, doc: Doc | null, fyo: Fyo): string { +function getCurrency( + value: Money, + field: Field, + doc: Doc | null, + fyo: Fyo +): string { + const currency = value?.getCurrency?.(); + const defaultCurrency = + fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY; + + if (currency && currency !== defaultCurrency) { + return currency; + } + let getCurrency = doc?.getCurrencies?.[field.fieldname]; if (getCurrency !== undefined) { return getCurrency(); @@ -139,7 +152,7 @@ function getCurrency(field: Field, doc: Doc | null, fyo: Fyo): string { return getCurrency(); } - return (fyo.singles.SystemSettings?.currency as string) ?? DEFAULT_CURRENCY; + return defaultCurrency; } function getField(df: string | Field): Field { diff --git a/models/baseModels/Invoice/Invoice.ts b/models/baseModels/Invoice/Invoice.ts index d1c8002b..6bc3925a 100644 --- a/models/baseModels/Invoice/Invoice.ts +++ b/models/baseModels/Invoice/Invoice.ts @@ -1,11 +1,20 @@ -import { DocValue } from 'fyo/core/types'; +import { Fyo } from 'fyo'; +import { DocValue, DocValueMap } from 'fyo/core/types'; import { Doc } from 'fyo/model/doc'; -import { DefaultMap, FiltersMap, FormulaMap, HiddenMap } from 'fyo/model/types'; +import { + CurrenciesMap, + DefaultMap, + FiltersMap, + FormulaMap, + HiddenMap +} from 'fyo/model/types'; +import { DEFAULT_CURRENCY } from 'fyo/utils/consts'; import { ValidationError } from 'fyo/utils/errors'; import { getExchangeRate } from 'models/helpers'; import { Transactional } from 'models/Transactional/Transactional'; import { ModelNameEnum } from 'models/types'; import { Money } from 'pesa'; +import { FieldTypeEnum, Schema } from 'schemas/types'; import { getIsNullOrUndef } from 'utils'; import { InvoiceItem } from '../InvoiceItem/InvoiceItem'; import { Party } from '../Party/Party'; @@ -50,6 +59,11 @@ export abstract class Invoice extends Transactional { return this.fyo.singles.SystemSettings!.currency !== this.currency; } + constructor(schema: Schema, data: DocValueMap, fyo: Fyo) { + super(schema, data, fyo); + this._setGetCurrencies(); + } + async validate() { await super.validate(); if ( @@ -363,4 +377,22 @@ export abstract class Invoice extends Transactional { role: doc.isSales ? 'Customer' : 'Supplier', }), }; + + getCurrencies: CurrenciesMap = {}; + _getCurrency() { + if (this.exchangeRate === 1) { + return this.fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY; + } + + return this.currency ?? DEFAULT_CURRENCY; + } + _setGetCurrencies() { + const currencyFields = this.schema.fields.filter( + ({ fieldtype }) => fieldtype === FieldTypeEnum.Currency + ); + + for (const { fieldname } of currencyFields) { + this.getCurrencies[fieldname] = this._getCurrency.bind(this); + } + } } diff --git a/models/baseModels/InvoiceItem/InvoiceItem.ts b/models/baseModels/InvoiceItem/InvoiceItem.ts index 58fa4606..82d2e2d5 100644 --- a/models/baseModels/InvoiceItem/InvoiceItem.ts +++ b/models/baseModels/InvoiceItem/InvoiceItem.ts @@ -1,21 +1,24 @@ -import { DocValue } from 'fyo/core/types'; +import { Fyo } from 'fyo'; +import { DocValue, DocValueMap } from 'fyo/core/types'; import { Doc } from 'fyo/model/doc'; import { + CurrenciesMap, FiltersMap, FormulaMap, HiddenMap, ValidationMap } from 'fyo/model/types'; +import { DEFAULT_CURRENCY } from 'fyo/utils/consts'; import { ValidationError } from 'fyo/utils/errors'; import { ModelNameEnum } from 'models/types'; import { Money } from 'pesa'; +import { FieldTypeEnum, Schema } from 'schemas/types'; import { Invoice } from '../Invoice/Invoice'; export abstract class InvoiceItem extends Doc { account?: string; amount?: Money; baseAmount?: Money; - exchangeRate?: number; parentdoc?: Invoice; rate?: Money; quantity?: number; @@ -39,6 +42,23 @@ export abstract class InvoiceItem extends Doc { return !!this.fyo.singles?.AccountingSettings?.enableDiscounting; } + get currency() { + return this.parentdoc?.currency ?? DEFAULT_CURRENCY; + } + + get exchangeRate() { + return this.parentdoc?.exchangeRate ?? 1; + } + + get isMultiCurrency() { + return this.parentdoc?.isMultiCurrency ?? false; + } + + constructor(schema: Schema, data: DocValueMap, fyo: Fyo) { + super(schema, data, fyo); + this._setGetCurrencies(); + } + async getTotalTaxRate(): Promise { if (!this.tax) { return 0; @@ -338,6 +358,24 @@ export abstract class InvoiceItem extends Doc { return { for: doc.isSales ? 'Sales' : 'Purchases' }; }, }; + + getCurrencies: CurrenciesMap = {}; + _getCurrency() { + if (this.exchangeRate === 1) { + return this.fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY; + } + + return this.currency; + } + _setGetCurrencies() { + const currencyFields = this.schema.fields.filter( + ({ fieldtype }) => fieldtype === FieldTypeEnum.Currency + ); + + for (const { fieldname } of currencyFields) { + this.getCurrencies[fieldname] = this._getCurrency.bind(this); + } + } } function getDiscountedTotalBeforeTaxation( diff --git a/src/pages/InvoiceForm.vue b/src/pages/InvoiceForm.vue index 8fe6b237..2d722fee 100644 --- a/src/pages/InvoiceForm.vue +++ b/src/pages/InvoiceForm.vue @@ -390,7 +390,6 @@ export default { } }, methods: { - log: console.log, routeTo, toggleInvoiceSettings() { if (!this.schemaName) {