mirror of
https://github.com/frappe/books.git
synced 2025-01-03 07:12:21 +00:00
incr: type some files, frappe -> fyo
- get books to serve albiet broken - one step at a time
This commit is contained in:
parent
835deb4ce8
commit
27aed52044
@ -1,5 +1,6 @@
|
||||
import frappe, { t } from 'fyo';
|
||||
import { t } from 'fyo';
|
||||
import { DateTime } from 'luxon';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { showMessageDialog } from 'src/utils';
|
||||
import { stateCodeMap } from '../regional/in';
|
||||
import { exportCsv, saveExportData } from '../reports/commonExporter';
|
||||
@ -46,7 +47,7 @@ const IGST = {
|
||||
};
|
||||
|
||||
export async function generateGstr1Json(getReportData) {
|
||||
const { gstin } = frappe.AccountingSettings;
|
||||
const { gstin } = fyo.AccountingSettings;
|
||||
if (!gstin) {
|
||||
showMessageDialog({
|
||||
message: t`Export Failed`,
|
||||
@ -106,7 +107,7 @@ async function generateB2bData(rows) {
|
||||
itms: [],
|
||||
};
|
||||
|
||||
const items = await frappe.db.getAllRaw('SalesInvoiceItem', {
|
||||
const items = await fyo.db.getAllRaw('SalesInvoiceItem', {
|
||||
fields: ['*'],
|
||||
filters: { parent: invRecord.inum },
|
||||
});
|
||||
@ -115,18 +116,18 @@ async function generateB2bData(rows) {
|
||||
const itemRecord = {
|
||||
num: item.hsnCode,
|
||||
itm_det: {
|
||||
txval: frappe.pesa(item.baseAmount).float,
|
||||
txval: fyo.pesa(item.baseAmount).float,
|
||||
rt: GST[item.tax],
|
||||
csamt: 0,
|
||||
camt: frappe
|
||||
camt: fyo
|
||||
.pesa(CSGST[item.tax] || 0)
|
||||
.mul(item.baseAmount)
|
||||
.div(100).float,
|
||||
samt: frappe
|
||||
samt: fyo
|
||||
.pesa(CSGST[item.tax] || 0)
|
||||
.mul(item.baseAmount)
|
||||
.div(100).float,
|
||||
iamt: frappe
|
||||
iamt: fyo
|
||||
.pesa(IGST[item.tax] || 0)
|
||||
.mul(item.baseAmount)
|
||||
.div(100).float,
|
||||
@ -167,7 +168,7 @@ async function generateB2clData(invoices) {
|
||||
itms: [],
|
||||
};
|
||||
|
||||
const items = await frappe.db.getAllRaw('SalesInvoiceItem', {
|
||||
const items = await fyo.db.getAllRaw('SalesInvoiceItem', {
|
||||
fields: ['*'],
|
||||
filters: { parent: invRecord.inum },
|
||||
});
|
||||
@ -176,10 +177,10 @@ async function generateB2clData(invoices) {
|
||||
const itemRecord = {
|
||||
num: item.hsnCode,
|
||||
itm_det: {
|
||||
txval: frappe.pesa(item.baseAmount).float,
|
||||
txval: fyo.pesa(item.baseAmount).float,
|
||||
rt: GST[item.tax],
|
||||
csamt: 0,
|
||||
iamt: frappe
|
||||
iamt: fyo
|
||||
.pesa(invoice.rate || 0)
|
||||
.mul(item.baseAmount)
|
||||
.div(100).float,
|
||||
@ -228,7 +229,7 @@ async function generateB2csData(invoices) {
|
||||
}
|
||||
|
||||
export async function generateGstr2Csv(getReportData) {
|
||||
const { gstin } = frappe.AccountingSettings;
|
||||
const { gstin } = fyo.AccountingSettings;
|
||||
if (!gstin) {
|
||||
showMessageDialog({
|
||||
message: t`Export Failed`,
|
||||
@ -309,7 +310,7 @@ async function generateB2bCsvGstr2(rows, columns) {
|
||||
}
|
||||
|
||||
export async function generateGstr1Csv(getReportData) {
|
||||
const { gstin } = frappe.AccountingSettings;
|
||||
const { gstin } = fyo.AccountingSettings;
|
||||
if (!gstin) {
|
||||
showMessageDialog({
|
||||
message: t`Export Failed`,
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Doc from 'fyo/model/doc';
|
||||
import { DocMap, ModelMap, SinglesMap } from 'fyo/model/types';
|
||||
import { coreModels } from 'fyo/models';
|
||||
import { getRandomString } from 'fyo/utils';
|
||||
import Observable from 'fyo/utils/observable';
|
||||
import { getRandomString } from 'utils';
|
||||
import { Fyo } from '..';
|
||||
import { DocValue, DocValueMap } from './types';
|
||||
|
||||
|
@ -4,7 +4,14 @@ import { RawValue } from 'schemas/types';
|
||||
import { AuthDemuxBase } from 'utils/auth/types';
|
||||
import { DatabaseDemuxBase } from 'utils/db/types';
|
||||
|
||||
export type DocValue = string | number | boolean | Date | Money | null;
|
||||
export type DocValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| Date
|
||||
| Money
|
||||
| null
|
||||
| undefined;
|
||||
export type DocValueMap = Record<string, DocValue | Doc[] | DocValueMap[]>;
|
||||
export type RawValueMap = Record<string, RawValue | RawValueMap[]>;
|
||||
|
||||
|
@ -165,6 +165,11 @@ export class Fyo {
|
||||
await this.auth.logout();
|
||||
}
|
||||
|
||||
getField(schemaName: string, fieldname: string) {
|
||||
const schema = this.schemaMap[schemaName];
|
||||
return schema?.fields.find((f) => f.fieldname === fieldname);
|
||||
}
|
||||
|
||||
store = {
|
||||
isDevelopment: false,
|
||||
appVersion: '',
|
||||
|
@ -16,8 +16,8 @@ import {
|
||||
Schema,
|
||||
TargetField,
|
||||
} from 'schemas/types';
|
||||
import { getIsNullOrUndef, getMapFromList } from 'utils';
|
||||
import { getRandomString, isPesa } from '../utils/index';
|
||||
import { getIsNullOrUndef, getMapFromList, getRandomString } from 'utils';
|
||||
import { isPesa } from '../utils/index';
|
||||
import {
|
||||
areDocValuesEqual,
|
||||
getMissingMandatoryMessage,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import NumberSeries from 'fyo/models/NumberSeries';
|
||||
import { getRandomString } from 'fyo/utils';
|
||||
import { DEFAULT_SERIES_START } from 'fyo/utils/consts';
|
||||
import { BaseError } from 'fyo/utils/errors';
|
||||
import { Field, Schema } from 'schemas/types';
|
||||
import { getRandomString } from 'utils';
|
||||
import Doc from './doc';
|
||||
|
||||
export function getNumberSeries(schema: Schema): Field | undefined {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as assert from 'assert';
|
||||
import 'mocha';
|
||||
import models, { getRegionalModels } from 'models';
|
||||
import { getRegionalModels, models } from 'models';
|
||||
import { getSchemas } from 'schemas';
|
||||
import { Fyo } from '..';
|
||||
import { DatabaseManager } from '../../backend/database/manager';
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import Doc from 'fyo/model/doc';
|
||||
import { Action } from 'fyo/model/types';
|
||||
import { pesa } from 'pesa';
|
||||
@ -11,23 +10,13 @@ export function slug(str: string) {
|
||||
.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
export function getRandomString() {
|
||||
return Math.random().toString(36).substr(3);
|
||||
}
|
||||
|
||||
export async function sleep(seconds: number) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, seconds * 1000);
|
||||
});
|
||||
}
|
||||
|
||||
export function range(n: number) {
|
||||
return Array(n)
|
||||
.fill(null)
|
||||
.map((_, i) => i);
|
||||
}
|
||||
|
||||
export function unique(list: unknown[], key = (it: unknown) => String(it)) {
|
||||
export function unique<T>(list: T[], key = (it: T) => String(it)) {
|
||||
const seen: Record<string, boolean> = {};
|
||||
return list.filter((item) => {
|
||||
const k = key(item);
|
||||
@ -54,11 +43,11 @@ export function isPesa(value: unknown): boolean {
|
||||
return value instanceof pesa().constructor;
|
||||
}
|
||||
|
||||
export function getActions(doc: Doc, fyo: Fyo): Action[] {
|
||||
const Model = fyo.models[doc.schemaName];
|
||||
export function getActions(doc: Doc): Action[] {
|
||||
const Model = doc.fyo.models[doc.schemaName];
|
||||
if (Model === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Model.getActions(fyo);
|
||||
return Model.getActions(doc.fyo);
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ export default function registerIpcMainActionListeners(main: Main) {
|
||||
countryCode
|
||||
);
|
||||
} catch (error) {
|
||||
response.error = error.toString();
|
||||
response.error = (error as Error).toString();
|
||||
}
|
||||
|
||||
return response;
|
||||
@ -151,7 +151,7 @@ export default function registerIpcMainActionListeners(main: Main) {
|
||||
countryCode
|
||||
);
|
||||
} catch (error) {
|
||||
response.error = error.toString();
|
||||
response.error = (error as Error).toString();
|
||||
}
|
||||
|
||||
return response;
|
||||
@ -165,7 +165,7 @@ export default function registerIpcMainActionListeners(main: Main) {
|
||||
try {
|
||||
response.data = await databaseManager.call(method, ...args);
|
||||
} catch (error) {
|
||||
response.error = error.toString();
|
||||
response.error = (error as Error).toString();
|
||||
}
|
||||
|
||||
return response;
|
||||
@ -179,7 +179,7 @@ export default function registerIpcMainActionListeners(main: Main) {
|
||||
try {
|
||||
response.data = await databaseManager.callBespoke(method, ...args);
|
||||
} catch (error) {
|
||||
response.error = error.toString();
|
||||
response.error = (error as Error).toString();
|
||||
}
|
||||
|
||||
return response;
|
||||
|
@ -26,6 +26,7 @@ export type AccountRootType =
|
||||
| 'Income'
|
||||
| 'Expense';
|
||||
|
||||
|
||||
export interface COARootAccount {
|
||||
rootType: AccountRootType;
|
||||
[key: string]: COAChildAccount | AccountRootType;
|
||||
|
@ -17,7 +17,7 @@ import { SetupWizard } from './baseModels/SetupWizard/SetupWizard';
|
||||
import { Tax } from './baseModels/Tax/Tax';
|
||||
import { TaxSummary } from './baseModels/TaxSummary/TaxSummary';
|
||||
|
||||
export default {
|
||||
export const models = {
|
||||
Account,
|
||||
AccountingLedgerEntry,
|
||||
AccountingSettings,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import frappe from 'fyo';
|
||||
import fyo from 'fyo';
|
||||
|
||||
export default class AccountsReceivablePayable {
|
||||
async run(reportType, { date }) {
|
||||
@ -65,7 +65,7 @@ async function getReceivablePayable({ reportType = 'Receivable', date }) {
|
||||
// helpers
|
||||
|
||||
async function getVouchers() {
|
||||
return await frappe.db.getAll({
|
||||
return await fyo.db.getAll({
|
||||
doctype: referenceType,
|
||||
fields: ['name', 'date'],
|
||||
filters: {
|
||||
@ -140,7 +140,7 @@ async function getReceivablePayable({ reportType = 'Receivable', date }) {
|
||||
|
||||
const partyType = reportType === 'Receivable' ? 'customer' : 'supplier';
|
||||
const partyList = (
|
||||
await frappe.db.getAll({
|
||||
await fyo.db.getAll({
|
||||
doctype: 'Party',
|
||||
filters: {
|
||||
[partyType]: 1,
|
||||
@ -148,7 +148,7 @@ async function getReceivablePayable({ reportType = 'Receivable', date }) {
|
||||
})
|
||||
).map((d) => d.name);
|
||||
|
||||
return await frappe.db.getAll({
|
||||
return await fyo.db.getAll({
|
||||
doctype: 'AccountingLedgerEntry',
|
||||
fields: [
|
||||
'name',
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { unique } from 'fyo/utils';
|
||||
import { getData } from '../FinancialStatements/FinancialStatements';
|
||||
import { FinancialStatements } from 'reports/FinancialStatements/financialStatements';
|
||||
import { FinancialStatementOptions } from 'reports/types';
|
||||
|
||||
class BalanceSheet {
|
||||
async run({ fromDate, toDate, periodicity }) {
|
||||
let asset = await getData({
|
||||
async run(options: FinancialStatementOptions, fyo: Fyo) {
|
||||
const { fromDate, toDate, periodicity } = options;
|
||||
const fs = new FinancialStatements(fyo);
|
||||
const asset = await fs.getData({
|
||||
rootType: 'Asset',
|
||||
balanceMustBe: 'Debit',
|
||||
fromDate,
|
||||
@ -12,7 +16,7 @@ class BalanceSheet {
|
||||
accumulateValues: true,
|
||||
});
|
||||
|
||||
let liability = await getData({
|
||||
const liability = await fs.getData({
|
||||
rootType: 'Liability',
|
||||
balanceMustBe: 'Credit',
|
||||
fromDate,
|
||||
@ -21,7 +25,7 @@ class BalanceSheet {
|
||||
accumulateValues: true,
|
||||
});
|
||||
|
||||
let equity = await getData({
|
||||
const equity = await fs.getData({
|
||||
rootType: 'Equity',
|
||||
balanceMustBe: 'Credit',
|
||||
fromDate,
|
@ -1,5 +1,6 @@
|
||||
import frappe, { t } from 'fyo';
|
||||
import { t } from 'fyo';
|
||||
import getCommonExportActions from '../commonExporter';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
const periodicityMap = {
|
||||
Monthly: t`Monthly`,
|
||||
@ -19,7 +20,7 @@ export default {
|
||||
label: t`To Date`,
|
||||
required: 1,
|
||||
default: async () => {
|
||||
return (await frappe.getSingle('AccountingSettings')).fiscalYearEnd;
|
||||
return (await fyo.doc.getSingle('AccountingSettings')).fiscalYearEnd;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import frappe from 'fyo';
|
||||
import { fyo } from 'src/initFyo'
|
||||
|
||||
class BankReconciliation {
|
||||
async run(params) {
|
||||
@ -15,7 +15,7 @@ class BankReconciliation {
|
||||
|
||||
filters.paymentMethod = ['in', ['Cheque', 'Transfer']];
|
||||
|
||||
let data = await frappe.db.getAll({
|
||||
let data = await fyo.db.getAll({
|
||||
doctype: 'Payment',
|
||||
fields: [
|
||||
'date',
|
||||
@ -31,7 +31,7 @@ class BankReconciliation {
|
||||
});
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
let ledger = await frappe.db.getAll({
|
||||
let ledger = await fyo.db.getAll({
|
||||
doctype: 'AccountingLedgerEntry',
|
||||
fields: ['date', 'referenceType', 'referenceName', 'debit', 'credit'],
|
||||
filters: {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import csv2json from 'csvjson-csv2json';
|
||||
import frappe from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import ReconciliationValidation from '../../src/components/ReconciliationValidation';
|
||||
|
||||
export const fileImportHandler = (file, report) => {
|
||||
@ -42,7 +42,7 @@ export const findMatchingReferences = async (json, report) => {
|
||||
const references = json.map((row) => {
|
||||
return row[referenceField];
|
||||
});
|
||||
const payments = await frappe.db.getAll({
|
||||
const payments = await fyo.db.getAll({
|
||||
doctype: 'Payment',
|
||||
fields: ['*'],
|
||||
filters: {
|
||||
@ -60,11 +60,11 @@ export const findMatchingReferences = async (json, report) => {
|
||||
});
|
||||
const normalizedEntries = entries.map((entry) => {
|
||||
return {
|
||||
'Posting Date': frappe.format(entry.date, 'Date'),
|
||||
'Posting Date': fyo.format(entry.date, 'Date'),
|
||||
'Payment Entry': entry.name,
|
||||
'Ref/Cheq. ID': entry[referenceField],
|
||||
'Cr/Dr':
|
||||
frappe.parseNumber(entry[debitField]) > 0
|
||||
fyo.parseNumber(entry[debitField]) > 0
|
||||
? entry[debitField] + ' Dr.'
|
||||
: entry[creditField] + ' Cr.',
|
||||
'Clearance Date': entry[clearanceDateField],
|
||||
|
@ -1,40 +0,0 @@
|
||||
import frappe from 'fyo';
|
||||
import { DateTime } from 'luxon';
|
||||
import {
|
||||
getFiscalYear,
|
||||
getPeriodList,
|
||||
} from '../FinancialStatements/FinancialStatements';
|
||||
|
||||
class Cashflow {
|
||||
async run({ fromDate, toDate, periodicity }) {
|
||||
const res = await frappe.db.getCashflow(fromDate, toDate);
|
||||
let fiscalYear = await getFiscalYear();
|
||||
let periodList = getPeriodList(fromDate, toDate, periodicity, fiscalYear);
|
||||
|
||||
let data = periodList.map((periodKey) => {
|
||||
let monthYear = this.getMonthYear(periodKey, 'MMM yyyy');
|
||||
let cashflowForPeriod = res.find((d) => d['month-year'] === monthYear);
|
||||
if (cashflowForPeriod) {
|
||||
cashflowForPeriod.periodKey = periodKey;
|
||||
return cashflowForPeriod;
|
||||
}
|
||||
return {
|
||||
inflow: 0,
|
||||
outflow: 0,
|
||||
periodKey,
|
||||
'month-year': monthYear,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
data,
|
||||
periodList,
|
||||
};
|
||||
}
|
||||
|
||||
getMonthYear(periodKey, format) {
|
||||
return DateTime.fromFormat(periodKey, format).toFormat('MM-yyyy');
|
||||
}
|
||||
}
|
||||
|
||||
export default Cashflow;
|
52
reports/Cashflow/Cashflow.ts
Normal file
52
reports/Cashflow/Cashflow.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { DateTime } from 'luxon';
|
||||
import {
|
||||
getFiscalYear,
|
||||
getPeriodList,
|
||||
} from 'reports/FinancialStatements/financialStatements';
|
||||
import { FinancialStatementOptions } from 'reports/types';
|
||||
|
||||
class Cashflow {
|
||||
fyo: Fyo;
|
||||
constructor(fyo: Fyo) {
|
||||
this.fyo = fyo;
|
||||
}
|
||||
async run(options: FinancialStatementOptions) {
|
||||
const { fromDate, toDate, periodicity } = options;
|
||||
const res = await this.fyo.db.getCashflow(fromDate, toDate);
|
||||
const fiscalYear = await getFiscalYear(this.fyo);
|
||||
const periodList = getPeriodList(
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity!,
|
||||
fiscalYear
|
||||
);
|
||||
|
||||
const data = periodList.map((periodKey) => {
|
||||
const monthYear = this.getMonthYear(periodKey, 'MMM yyyy');
|
||||
const cashflowForPeriod = res.find((d) => d['month-year'] === monthYear);
|
||||
|
||||
if (cashflowForPeriod) {
|
||||
return { ...cashflowForPeriod, periodKey };
|
||||
}
|
||||
|
||||
return {
|
||||
inflow: 0,
|
||||
outflow: 0,
|
||||
periodKey,
|
||||
'month-year': monthYear,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
data,
|
||||
periodList,
|
||||
};
|
||||
}
|
||||
|
||||
getMonthYear(periodKey: string, format: string) {
|
||||
return DateTime.fromFormat(periodKey, format).toFormat('MM-yyyy');
|
||||
}
|
||||
}
|
||||
|
||||
export default Cashflow;
|
@ -1,334 +0,0 @@
|
||||
import frappe from 'fyo';
|
||||
import { DateTime } from 'luxon';
|
||||
import { convertPesaValuesToFloat } from '../../src/utils';
|
||||
|
||||
export async function getData({
|
||||
rootType,
|
||||
balanceMustBe = 'Debit',
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity = 'Monthly',
|
||||
accumulateValues = false,
|
||||
}) {
|
||||
let accounts = await getAccounts(rootType);
|
||||
let fiscalYear = await getFiscalYear();
|
||||
let ledgerEntries = await getLedgerEntries(fromDate, toDate, accounts);
|
||||
let periodList = getPeriodList(fromDate, toDate, periodicity, fiscalYear);
|
||||
|
||||
for (let account of accounts) {
|
||||
const entries = ledgerEntries.filter(
|
||||
(entry) => entry.account === account.name
|
||||
);
|
||||
|
||||
for (let entry of entries) {
|
||||
let periodKey = getPeriodKey(entry.date, periodicity, fiscalYear);
|
||||
|
||||
if (!account[periodKey]) {
|
||||
account[periodKey] = frappe.pesa(0.0);
|
||||
}
|
||||
|
||||
const multiplier = balanceMustBe === 'Debit' ? 1 : -1;
|
||||
const value = entry.debit.sub(entry.credit).mul(multiplier);
|
||||
account[periodKey] = value.add(account[periodKey]);
|
||||
}
|
||||
}
|
||||
|
||||
if (accumulateValues) {
|
||||
periodList.forEach((periodKey, i) => {
|
||||
if (i === 0) return;
|
||||
const previousPeriodKey = periodList[i - 1];
|
||||
|
||||
for (let account of accounts) {
|
||||
if (!account[periodKey]) {
|
||||
account[periodKey] = frappe.pesa(0.0);
|
||||
}
|
||||
|
||||
account[periodKey] = account[periodKey].add(
|
||||
account[previousPeriodKey] ?? 0
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// calculate totalRow
|
||||
let totalRow = {
|
||||
account: `Total ${rootType} (${balanceMustBe})`,
|
||||
};
|
||||
|
||||
periodList.forEach((periodKey) => {
|
||||
if (!totalRow[periodKey]) {
|
||||
totalRow[periodKey] = frappe.pesa(0.0);
|
||||
}
|
||||
|
||||
for (let account of accounts) {
|
||||
totalRow[periodKey] = totalRow[periodKey].add(account[periodKey] ?? 0.0);
|
||||
}
|
||||
});
|
||||
|
||||
convertPesaValuesToFloat(totalRow);
|
||||
accounts.forEach(convertPesaValuesToFloat);
|
||||
|
||||
return { accounts, totalRow, periodList };
|
||||
}
|
||||
|
||||
export async function getTrialBalance({ rootType, fromDate, toDate }) {
|
||||
let accounts = await getAccounts(rootType);
|
||||
let ledgerEntries = await getLedgerEntries(null, toDate, accounts);
|
||||
|
||||
for (let account of accounts) {
|
||||
const accountEntries = ledgerEntries.filter(
|
||||
(entry) => entry.account === account.name
|
||||
);
|
||||
// opening
|
||||
const beforePeriodEntries = accountEntries.filter(
|
||||
(entry) => entry.date < fromDate
|
||||
);
|
||||
account.opening = beforePeriodEntries.reduce(
|
||||
(acc, entry) => acc.add(entry.debit).sub(entry.credit),
|
||||
frappe.pesa(0)
|
||||
);
|
||||
|
||||
if (account.opening.gte(0)) {
|
||||
account.openingDebit = account.opening;
|
||||
account.openingCredit = frappe.pesa(0);
|
||||
} else {
|
||||
account.openingCredit = account.opening.neg();
|
||||
account.openingDebit = frappe.pesa(0);
|
||||
}
|
||||
|
||||
// debit / credit
|
||||
const periodEntries = accountEntries.filter(
|
||||
(entry) => entry.date >= fromDate && entry.date < toDate
|
||||
);
|
||||
account.debit = periodEntries.reduce(
|
||||
(acc, entry) => acc.add(entry.debit),
|
||||
frappe.pesa(0)
|
||||
);
|
||||
account.credit = periodEntries.reduce(
|
||||
(acc, entry) => acc.add(entry.credit),
|
||||
frappe.pesa(0)
|
||||
);
|
||||
|
||||
// closing
|
||||
account.closing = account.opening.add(account.debit).sub(account.credit);
|
||||
|
||||
if (account.closing.gte(0)) {
|
||||
account.closingDebit = account.closing;
|
||||
account.closingCredit = frappe.pesa(0);
|
||||
} else {
|
||||
account.closingCredit = account.closing.neg();
|
||||
account.closingDebit = frappe.pesa(0);
|
||||
}
|
||||
|
||||
if (account.debit.neq(0) || account.credit.neq(0)) {
|
||||
setParentEntry(account, account.parentAccount);
|
||||
}
|
||||
}
|
||||
|
||||
function setParentEntry(leafAccount, parentName) {
|
||||
for (let acc of accounts) {
|
||||
if (acc.name === parentName) {
|
||||
acc.debit = acc.debit.add(leafAccount.debit);
|
||||
acc.credit = acc.credit.add(leafAccount.credit);
|
||||
acc.closing = acc.opening.add(acc.debit).sub(acc.credit);
|
||||
if (acc.closing.gte(0)) {
|
||||
acc.closingDebit = acc.closing;
|
||||
} else {
|
||||
acc.closingCredit = acc.closing.neg();
|
||||
}
|
||||
if (acc.parentAccount) {
|
||||
setParentEntry(leafAccount, acc.parentAccount);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accounts.forEach(convertPesaValuesToFloat);
|
||||
return accounts;
|
||||
}
|
||||
|
||||
export function getPeriodList(fromDate, toDate, periodicity, fiscalYear) {
|
||||
if (!fromDate) {
|
||||
fromDate = fiscalYear.start;
|
||||
}
|
||||
|
||||
let monthsToAdd = {
|
||||
Monthly: 1,
|
||||
Quarterly: 3,
|
||||
'Half Yearly': 6,
|
||||
Yearly: 12,
|
||||
}[periodicity];
|
||||
|
||||
let startDate = DateTime.fromISO(fromDate).startOf('month');
|
||||
let endDate = DateTime.fromISO(toDate).endOf('month');
|
||||
let curDate = startDate;
|
||||
let out = [];
|
||||
|
||||
while (curDate <= endDate) {
|
||||
out.push(getPeriodKey(curDate, periodicity, fiscalYear));
|
||||
curDate = curDate.plus({ months: monthsToAdd });
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function getPeriodKey(date, periodicity, fiscalYear) {
|
||||
let key;
|
||||
let { start, end, quarters, isSplit } = fiscalYear;
|
||||
let dateObj = DateTime.fromISO(date);
|
||||
let { month, quarter, year } = dateObj;
|
||||
let fisacalStart = DateTime.fromISO(start);
|
||||
let fisacalEnd = DateTime.fromISO(end);
|
||||
|
||||
let getKey = {
|
||||
Monthly: () => `${dateObj.monthShort} ${year}`,
|
||||
Quarterly: () => {
|
||||
const key =
|
||||
month < fisacalStart.month
|
||||
? `${year - 1} - ${year}`
|
||||
: `${year} - ${year + 1}`;
|
||||
let strYear = isSplit ? key : `${year}`;
|
||||
return {
|
||||
1: `Q1 ${strYear}`,
|
||||
2: `Q2 ${strYear}`,
|
||||
3: `Q3 ${strYear}`,
|
||||
4: `Q4 ${strYear}`,
|
||||
}[quarters[month - 1]];
|
||||
},
|
||||
'Half Yearly': () => {
|
||||
const key =
|
||||
month < fisacalStart.month
|
||||
? `${year - 1} - ${year}`
|
||||
: `${year} - ${year + 1}`;
|
||||
let strYear = isSplit ? key : `${year}`;
|
||||
return {
|
||||
1: `1st Half ${strYear}`,
|
||||
2: `1st Half ${strYear}`,
|
||||
3: `2nd Half ${strYear}`,
|
||||
4: `2nd Half ${strYear}`,
|
||||
}[quarters[month - 1]];
|
||||
},
|
||||
Yearly: () => {
|
||||
const key =
|
||||
month < fisacalStart.month
|
||||
? `${year - 1} - ${year}`
|
||||
: `${year} - ${year + 1}`;
|
||||
let strYear = isSplit ? key : `${year}`;
|
||||
return `FY ${strYear}`;
|
||||
},
|
||||
}[periodicity];
|
||||
|
||||
return getKey();
|
||||
}
|
||||
|
||||
function setIndentLevel(accounts, parentAccount, level) {
|
||||
if (!parentAccount) {
|
||||
// root
|
||||
parentAccount = null;
|
||||
level = 0;
|
||||
}
|
||||
|
||||
accounts.forEach((account) => {
|
||||
if (
|
||||
account.parentAccount === parentAccount &&
|
||||
account.indent === undefined
|
||||
) {
|
||||
account.indent = level;
|
||||
setIndentLevel(accounts, account.name, level + 1);
|
||||
}
|
||||
});
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
function sortAccounts(accounts) {
|
||||
let out = [];
|
||||
let pushed = {};
|
||||
|
||||
pushToOut(null);
|
||||
|
||||
function pushToOut(parentAccount) {
|
||||
accounts.forEach((account) => {
|
||||
if (account.parentAccount === parentAccount && !pushed[account.name]) {
|
||||
out.push(account);
|
||||
pushed[account.name] = 1;
|
||||
|
||||
pushToOut(account.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
async function getLedgerEntries(fromDate, toDate, accounts) {
|
||||
const dateFilter = () => {
|
||||
const before = ['<=', toDate];
|
||||
const after = ['>=', fromDate];
|
||||
if (fromDate) {
|
||||
return [...after, ...before];
|
||||
}
|
||||
return before;
|
||||
};
|
||||
|
||||
const ledgerEntries = await frappe.db.getAll({
|
||||
doctype: 'AccountingLedgerEntry',
|
||||
fields: ['account', 'debit', 'credit', 'date'],
|
||||
filters: {
|
||||
account: ['in', accounts.map((d) => d.name)],
|
||||
date: dateFilter(),
|
||||
},
|
||||
});
|
||||
|
||||
return ledgerEntries;
|
||||
}
|
||||
|
||||
async function getAccounts(rootType) {
|
||||
let accounts = await frappe.db.getAll({
|
||||
doctype: 'Account',
|
||||
fields: ['name', 'parentAccount', 'isGroup'],
|
||||
filters: {
|
||||
rootType,
|
||||
},
|
||||
});
|
||||
|
||||
accounts = setIndentLevel(accounts);
|
||||
accounts = sortAccounts(accounts);
|
||||
|
||||
accounts.forEach((account) => {
|
||||
account.account = account.name;
|
||||
});
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
export async function getFiscalYear() {
|
||||
let { fiscalYearStart, fiscalYearEnd } = await frappe.getSingle(
|
||||
'AccountingSettings'
|
||||
);
|
||||
|
||||
//right now quaters received from luxon lib is fixed to Jan as starting quarter
|
||||
//moving the financial quarters, according to of start of fiscal year month
|
||||
let quarters = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
|
||||
let start = DateTime.fromISO(fiscalYearStart);
|
||||
quarters.unshift(...quarters.splice(13 - start.month, 11));
|
||||
|
||||
//check if fiscal year ends in next year
|
||||
let end = DateTime.fromISO(fiscalYearEnd);
|
||||
let isFiscalSplit = start.year - end.year;
|
||||
|
||||
return {
|
||||
start: fiscalYearStart,
|
||||
end: fiscalYearEnd,
|
||||
quarters: quarters,
|
||||
isSplit: isFiscalSplit,
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
getData,
|
||||
getTrialBalance,
|
||||
getPeriodList,
|
||||
};
|
426
reports/FinancialStatements/financialStatements.ts
Normal file
426
reports/FinancialStatements/financialStatements.ts
Normal file
@ -0,0 +1,426 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { DocValueMap } from 'fyo/core/types';
|
||||
import { DateTime } from 'luxon';
|
||||
import { AccountRootType } from 'models/baseModels/Account/types';
|
||||
import Money from 'pesa/dist/types/src/money';
|
||||
import {
|
||||
BalanceType,
|
||||
FinancialStatementOptions,
|
||||
Periodicity,
|
||||
} from 'reports/types';
|
||||
import { convertPesaValuesToFloat } from 'src/utils';
|
||||
|
||||
interface FiscalYear {
|
||||
start: string;
|
||||
end: string;
|
||||
quarters: number[];
|
||||
isSplit: number;
|
||||
}
|
||||
|
||||
interface AccountInfo extends DocValueMap {
|
||||
name: string;
|
||||
parentAccount: string;
|
||||
isGroup: boolean;
|
||||
account?: string;
|
||||
indent?: number;
|
||||
}
|
||||
|
||||
interface LedgerInfo extends DocValueMap {
|
||||
account: string;
|
||||
debit: Money;
|
||||
credit: Money;
|
||||
date: string;
|
||||
}
|
||||
|
||||
export class FinancialStatements {
|
||||
fyo: Fyo;
|
||||
constructor(fyo: Fyo) {
|
||||
this.fyo = fyo;
|
||||
}
|
||||
|
||||
async getData(options: FinancialStatementOptions) {
|
||||
const rootType = options.rootType;
|
||||
const balanceMustBe = options.balanceMustBe ?? 'Debit';
|
||||
const fromDate = options.fromDate;
|
||||
const toDate = options.toDate;
|
||||
const periodicity = options.periodicity ?? 'Monthly';
|
||||
const accumulateValues = options.accumulateValues ?? false;
|
||||
|
||||
const accounts = await this.getAccounts(rootType);
|
||||
const fiscalYear = await getFiscalYear(this.fyo);
|
||||
const ledgerEntries = await this.getLedgerEntries(
|
||||
fromDate,
|
||||
toDate,
|
||||
accounts
|
||||
);
|
||||
const periodList = getPeriodList(fromDate, toDate, periodicity, fiscalYear);
|
||||
this.setPeriodAmounts(
|
||||
accounts,
|
||||
ledgerEntries,
|
||||
periodicity,
|
||||
fiscalYear,
|
||||
balanceMustBe
|
||||
);
|
||||
|
||||
if (accumulateValues) {
|
||||
this.accumulateValues(accounts, periodList);
|
||||
}
|
||||
|
||||
const totalRow = this.getTotalRow(
|
||||
rootType,
|
||||
balanceMustBe,
|
||||
periodList,
|
||||
accounts
|
||||
);
|
||||
accounts.forEach(convertPesaValuesToFloat);
|
||||
|
||||
return { accounts, totalRow, periodList };
|
||||
}
|
||||
|
||||
setPeriodAmounts(
|
||||
accounts: AccountInfo[],
|
||||
ledgerEntries: LedgerInfo[],
|
||||
periodicity: Periodicity,
|
||||
fiscalYear: FiscalYear,
|
||||
balanceMustBe: BalanceType
|
||||
) {
|
||||
for (const account of accounts) {
|
||||
const entries = ledgerEntries.filter(
|
||||
(entry) => entry.account === account.name
|
||||
);
|
||||
|
||||
for (const entry of entries) {
|
||||
const periodKey = getPeriodKey(entry.date, periodicity, fiscalYear);
|
||||
|
||||
if (account[periodKey] === undefined) {
|
||||
account[periodKey] = this.fyo.pesa(0.0);
|
||||
}
|
||||
|
||||
const multiplier = balanceMustBe === 'Debit' ? 1 : -1;
|
||||
const value = entry.debit.sub(entry.credit).mul(multiplier);
|
||||
account[periodKey] = value.add(account[periodKey] as Money);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getTotalRow(
|
||||
rootType: AccountRootType,
|
||||
balanceMustBe: BalanceType,
|
||||
periodList: string[],
|
||||
accounts: AccountInfo[]
|
||||
) {
|
||||
const totalRow: DocValueMap = {
|
||||
account: `Total ${rootType} (${balanceMustBe})`,
|
||||
};
|
||||
|
||||
periodList.forEach((periodKey) => {
|
||||
if (totalRow[periodKey] === undefined) {
|
||||
totalRow[periodKey] = this.fyo.pesa(0.0);
|
||||
}
|
||||
|
||||
for (const account of accounts) {
|
||||
totalRow[periodKey] = (totalRow[periodKey] as Money).add(
|
||||
(account[periodKey] as Money) ?? 0.0
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
convertPesaValuesToFloat(totalRow);
|
||||
return totalRow;
|
||||
}
|
||||
|
||||
async accumulateValues(accounts: AccountInfo[], periodList: string[]) {
|
||||
periodList.forEach((periodKey, i) => {
|
||||
if (i === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const previousPeriodKey = periodList[i - 1];
|
||||
|
||||
for (const account of accounts) {
|
||||
if (!account[periodKey]) {
|
||||
account[periodKey] = this.fyo.pesa(0.0);
|
||||
}
|
||||
|
||||
account[periodKey] = (account[periodKey] as Money).add(
|
||||
(account[previousPeriodKey] as Money | undefined) ?? 0
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getAccounts(rootType: AccountRootType) {
|
||||
let accounts = (await this.fyo.db.getAll('Account', {
|
||||
fields: ['name', 'parentAccount', 'isGroup'],
|
||||
filters: {
|
||||
rootType,
|
||||
},
|
||||
})) as AccountInfo[];
|
||||
|
||||
accounts = setIndentLevel(accounts);
|
||||
accounts = sortAccounts(accounts);
|
||||
|
||||
accounts.forEach((account) => {
|
||||
account.account = account.name;
|
||||
});
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
async getLedgerEntries(
|
||||
fromDate: string | null,
|
||||
toDate: string,
|
||||
accounts: AccountInfo[]
|
||||
) {
|
||||
const accountFilter = ['in', accounts.map((d) => d.name)];
|
||||
let dateFilter: string[] = ['<=', toDate];
|
||||
if (fromDate) {
|
||||
dateFilter = ['>=', fromDate, '<=', toDate];
|
||||
}
|
||||
|
||||
const ledgerEntries = (await this.fyo.db.getAll('AccountingLedgerEntry', {
|
||||
fields: ['account', 'debit', 'credit', 'date'],
|
||||
filters: {
|
||||
account: accountFilter,
|
||||
date: dateFilter,
|
||||
},
|
||||
})) as LedgerInfo[];
|
||||
|
||||
return ledgerEntries;
|
||||
}
|
||||
|
||||
async getTrialBalance(options: FinancialStatementOptions) {
|
||||
const { rootType, fromDate, toDate } = options;
|
||||
const accounts = await this.getAccounts(rootType);
|
||||
const ledgerEntries = await this.getLedgerEntries(null, toDate, accounts);
|
||||
|
||||
for (const account of accounts) {
|
||||
const accountEntries = ledgerEntries.filter(
|
||||
(entry) => entry.account === account.name
|
||||
);
|
||||
// opening
|
||||
const beforePeriodEntries = accountEntries.filter(
|
||||
(entry) => entry.date < fromDate
|
||||
);
|
||||
|
||||
account.opening = beforePeriodEntries.reduce(
|
||||
(acc, entry) => acc.add(entry.debit).sub(entry.credit),
|
||||
this.fyo.pesa(0)
|
||||
);
|
||||
|
||||
if (account.opening.gte(0)) {
|
||||
account.openingDebit = account.opening;
|
||||
account.openingCredit = this.fyo.pesa(0);
|
||||
} else {
|
||||
account.openingCredit = account.opening.neg();
|
||||
account.openingDebit = this.fyo.pesa(0);
|
||||
}
|
||||
|
||||
// debit / credit
|
||||
const periodEntries = accountEntries.filter(
|
||||
(entry) => entry.date >= fromDate && entry.date < toDate
|
||||
);
|
||||
account.debit = periodEntries.reduce(
|
||||
(acc, entry) => acc.add(entry.debit),
|
||||
this.fyo.pesa(0)
|
||||
);
|
||||
account.credit = periodEntries.reduce(
|
||||
(acc, entry) => acc.add(entry.credit),
|
||||
this.fyo.pesa(0)
|
||||
);
|
||||
|
||||
// closing
|
||||
account.closing = account.opening.add(account.debit).sub(account.credit);
|
||||
|
||||
if (account.closing.gte(0)) {
|
||||
account.closingDebit = account.closing;
|
||||
account.closingCredit = this.fyo.pesa(0);
|
||||
} else {
|
||||
account.closingCredit = account.closing.neg();
|
||||
account.closingDebit = this.fyo.pesa(0);
|
||||
}
|
||||
|
||||
if (account.debit.neq(0) || account.credit.neq(0)) {
|
||||
setParentEntry(account, account.parentAccount);
|
||||
}
|
||||
}
|
||||
|
||||
function setParentEntry(leafAccount: AccountInfo, parentName: string) {
|
||||
for (const acc of accounts) {
|
||||
if (acc.name === parentName) {
|
||||
acc.debit = (acc.debit as Money).add(leafAccount.debit as Money);
|
||||
acc.credit = (acc.credit as Money).add(leafAccount.credit as Money);
|
||||
acc.closing = (acc.opening as Money).add(acc.debit).sub(acc.credit);
|
||||
|
||||
if (acc.closing.gte(0)) {
|
||||
acc.closingDebit = acc.closing;
|
||||
} else {
|
||||
acc.closingCredit = acc.closing.neg();
|
||||
}
|
||||
|
||||
if (acc.parentAccount) {
|
||||
setParentEntry(leafAccount, acc.parentAccount);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accounts.forEach(convertPesaValuesToFloat);
|
||||
return accounts;
|
||||
}
|
||||
}
|
||||
|
||||
function setIndentLevel(
|
||||
accounts: AccountInfo[],
|
||||
parentAccount?: string | null,
|
||||
level?: number
|
||||
): AccountInfo[] {
|
||||
if (parentAccount === undefined) {
|
||||
parentAccount = null;
|
||||
level = 0;
|
||||
}
|
||||
|
||||
accounts.forEach((account) => {
|
||||
if (
|
||||
account.parentAccount === parentAccount &&
|
||||
account.indent === undefined
|
||||
) {
|
||||
account.indent = level;
|
||||
setIndentLevel(accounts, account.name, (level ?? 0) + 1);
|
||||
}
|
||||
});
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
function sortAccounts(accounts: AccountInfo[]) {
|
||||
const out: AccountInfo[] = [];
|
||||
const pushed: Record<string, boolean> = {};
|
||||
|
||||
pushToOut(null);
|
||||
|
||||
function pushToOut(parentAccount: string | null) {
|
||||
accounts.forEach((account) => {
|
||||
if (pushed[account.name] && account.parentAccount !== parentAccount) {
|
||||
return;
|
||||
}
|
||||
|
||||
out.push(account);
|
||||
pushed[account.name] = true;
|
||||
|
||||
pushToOut(account.name);
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
export function getPeriodList(
|
||||
fromDate: string,
|
||||
toDate: string,
|
||||
periodicity: Periodicity,
|
||||
fiscalYear: FiscalYear
|
||||
) {
|
||||
if (!fromDate) {
|
||||
fromDate = fiscalYear.start;
|
||||
}
|
||||
|
||||
const monthsToAdd = {
|
||||
Monthly: 1,
|
||||
Quarterly: 3,
|
||||
'Half Yearly': 6,
|
||||
Yearly: 12,
|
||||
}[periodicity];
|
||||
|
||||
const startDate = DateTime.fromISO(fromDate).startOf('month');
|
||||
const endDate = DateTime.fromISO(toDate).endOf('month');
|
||||
let curDate = startDate;
|
||||
const periodKeyList: string[] = [];
|
||||
|
||||
while (curDate <= endDate) {
|
||||
const periodKey = getPeriodKey(curDate, periodicity, fiscalYear);
|
||||
periodKeyList.push(periodKey);
|
||||
curDate = curDate.plus({ months: monthsToAdd });
|
||||
}
|
||||
|
||||
return periodKeyList;
|
||||
}
|
||||
|
||||
function getPeriodKey(
|
||||
dateObj: DateTime | string,
|
||||
periodicity: Periodicity,
|
||||
fiscalYear: FiscalYear
|
||||
) {
|
||||
if (typeof dateObj === 'string') {
|
||||
dateObj = DateTime.fromISO(dateObj);
|
||||
}
|
||||
|
||||
const { start, quarters, isSplit } = fiscalYear;
|
||||
const { month, year } = dateObj;
|
||||
const fisacalStart = DateTime.fromISO(start);
|
||||
|
||||
if (periodicity === 'Monthly') {
|
||||
return `${dateObj.monthShort} ${year}`;
|
||||
}
|
||||
|
||||
if (periodicity === 'Quarterly') {
|
||||
const key =
|
||||
month < fisacalStart.month
|
||||
? `${year - 1} - ${year}`
|
||||
: `${year} - ${year + 1}`;
|
||||
const strYear = isSplit ? key : `${year}`;
|
||||
return {
|
||||
1: `Q1 ${strYear}`,
|
||||
2: `Q2 ${strYear}`,
|
||||
3: `Q3 ${strYear}`,
|
||||
4: `Q4 ${strYear}`,
|
||||
}[quarters[month - 1]] as string;
|
||||
}
|
||||
|
||||
if (periodicity === 'Half Yearly') {
|
||||
const key =
|
||||
month < fisacalStart.month
|
||||
? `${year - 1} - ${year}`
|
||||
: `${year} - ${year + 1}`;
|
||||
const strYear = isSplit ? key : `${year}`;
|
||||
return {
|
||||
1: `1st Half ${strYear}`,
|
||||
2: `1st Half ${strYear}`,
|
||||
3: `2nd Half ${strYear}`,
|
||||
4: `2nd Half ${strYear}`,
|
||||
}[quarters[month - 1]] as string;
|
||||
}
|
||||
|
||||
const key =
|
||||
month < fisacalStart.month
|
||||
? `${year - 1} - ${year}`
|
||||
: `${year} - ${year + 1}`;
|
||||
const strYear = isSplit ? key : `${year}`;
|
||||
return `FY ${strYear}`;
|
||||
}
|
||||
|
||||
export async function getFiscalYear(fyo: Fyo): Promise<FiscalYear> {
|
||||
const accountingSettings = await fyo.doc.getSingle('AccountingSettings');
|
||||
|
||||
const fiscalYearStart = accountingSettings.fiscalYearStart as string;
|
||||
const fiscalYearEnd = accountingSettings.fiscalYearEnd as string;
|
||||
|
||||
//right now quaters received from luxon lib is fixed to Jan as starting quarter
|
||||
//moving the financial quarters, according to of start of fiscal year month
|
||||
const quarters = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
|
||||
const start = DateTime.fromISO(fiscalYearStart);
|
||||
quarters.unshift(...quarters.splice(13 - start.month, 11));
|
||||
|
||||
//check if fiscal year ends in next year
|
||||
const end = DateTime.fromISO(fiscalYearEnd);
|
||||
const isFiscalSplit = start.year - end.year;
|
||||
|
||||
return {
|
||||
start: fiscalYearStart,
|
||||
end: fiscalYearEnd,
|
||||
quarters: quarters,
|
||||
isSplit: isFiscalSplit,
|
||||
};
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import frappe from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
class GeneralLedger {
|
||||
async run(params) {
|
||||
@ -15,7 +15,7 @@ class GeneralLedger {
|
||||
}
|
||||
|
||||
let data = (
|
||||
await frappe.db.getAll({
|
||||
await fyo.db.getAll({
|
||||
doctype: 'AccountingLedgerEntry',
|
||||
fields: [
|
||||
'date',
|
||||
@ -40,6 +40,7 @@ class GeneralLedger {
|
||||
|
||||
return this.appendOpeningEntry(data);
|
||||
}
|
||||
|
||||
appendOpeningEntry(data) {
|
||||
let glEntries = [];
|
||||
let balance = 0,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import frappe from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { stateCodeMap } from '../../accounting/gst';
|
||||
import { convertPesaValuesToFloat } from '../../src/utils';
|
||||
|
||||
@ -7,7 +7,7 @@ class BaseGSTR {
|
||||
if (['GSTR-1', 'GSTR-2'].includes(gstrType)) {
|
||||
const place = filters.place;
|
||||
delete filters.place;
|
||||
let entries = await frappe.db.getAll({
|
||||
let entries = await fyo.db.getAll({
|
||||
doctype: gstrType === 'GSTR-1' ? 'SalesInvoice' : 'PurchaseInvoice',
|
||||
filters,
|
||||
});
|
||||
@ -39,21 +39,18 @@ class BaseGSTR {
|
||||
}
|
||||
|
||||
async getRow(ledgerEntry) {
|
||||
ledgerEntry = await frappe.doc.getDoc(
|
||||
ledgerEntry.doctype,
|
||||
ledgerEntry.name
|
||||
);
|
||||
ledgerEntry = await fyo.doc.getDoc(ledgerEntry.doctype, ledgerEntry.name);
|
||||
|
||||
const row = {};
|
||||
const { gstin } = frappe.AccountingSettings;
|
||||
const { gstin } = fyo.AccountingSettings;
|
||||
|
||||
let party = await frappe.doc.getDoc(
|
||||
let party = await fyo.doc.getDoc(
|
||||
'Party',
|
||||
ledgerEntry.customer || ledgerEntry.supplier
|
||||
);
|
||||
|
||||
if (party.address) {
|
||||
let addressDetails = await frappe.doc.getDoc('Address', party.address);
|
||||
let addressDetails = await fyo.doc.getDoc('Address', party.address);
|
||||
row.place = addressDetails.pos || '';
|
||||
}
|
||||
|
||||
|
@ -1,83 +0,0 @@
|
||||
import { unique } from 'fyo/utils';
|
||||
import { getData } from '../FinancialStatements/FinancialStatements';
|
||||
|
||||
class ProfitAndLoss {
|
||||
async run({ fromDate, toDate, periodicity }) {
|
||||
let income = await getData({
|
||||
rootType: 'Income',
|
||||
balanceMustBe: 'Credit',
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity,
|
||||
});
|
||||
|
||||
let expense = await getData({
|
||||
rootType: 'Expense',
|
||||
balanceMustBe: 'Debit',
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity,
|
||||
});
|
||||
|
||||
let incomeTotalRow = income.totalRow;
|
||||
incomeTotalRow.account = {
|
||||
template: `<span class="font-semibold">${income.totalRow.account}</span>`,
|
||||
};
|
||||
|
||||
let expenseTotalRow = expense.totalRow;
|
||||
expenseTotalRow.account = {
|
||||
template: `<span class="font-semibold">${expense.totalRow.account}</span>`,
|
||||
};
|
||||
|
||||
let rows = [
|
||||
...income.accounts,
|
||||
incomeTotalRow,
|
||||
{
|
||||
account: {
|
||||
template: '<span> </span>',
|
||||
},
|
||||
isGroup: 1,
|
||||
},
|
||||
...expense.accounts,
|
||||
expenseTotalRow,
|
||||
{
|
||||
account: {
|
||||
template: '<span> </span>',
|
||||
},
|
||||
isGroup: 1,
|
||||
},
|
||||
];
|
||||
|
||||
rows = rows.map((row) => {
|
||||
if (row.indent === 0) {
|
||||
row.account = {
|
||||
template: `<span class="font-semibold">${row.account}</span>`,
|
||||
};
|
||||
}
|
||||
return row;
|
||||
});
|
||||
|
||||
const columns = unique([...income.periodList, ...expense.periodList]);
|
||||
|
||||
let profitRow = {
|
||||
account: 'Total Profit',
|
||||
};
|
||||
|
||||
for (let column of columns) {
|
||||
profitRow[column] =
|
||||
(income.totalRow[column] || 0.0) - (expense.totalRow[column] || 0.0);
|
||||
|
||||
rows.forEach((row) => {
|
||||
if (!row.isGroup) {
|
||||
row[column] = row[column] || 0.0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
rows.push(profitRow);
|
||||
|
||||
return { rows, columns };
|
||||
}
|
||||
}
|
||||
|
||||
export default ProfitAndLoss;
|
107
reports/ProfitAndLoss/ProfitAndLoss.ts
Normal file
107
reports/ProfitAndLoss/ProfitAndLoss.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { unique } from 'fyo/utils';
|
||||
import { FinancialStatements } from 'reports/FinancialStatements/financialStatements';
|
||||
import { FinancialStatementOptions } from 'reports/types';
|
||||
|
||||
interface Row {
|
||||
indent?: number;
|
||||
account: string | { template: string };
|
||||
isGroup?: boolean;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export default class ProfitAndLoss {
|
||||
fyo: Fyo;
|
||||
constructor(fyo: Fyo) {
|
||||
this.fyo = fyo;
|
||||
}
|
||||
|
||||
async run(options: FinancialStatementOptions) {
|
||||
const { fromDate, toDate, periodicity } = options;
|
||||
const fs = new FinancialStatements(this.fyo);
|
||||
const income = await fs.getData({
|
||||
rootType: 'Income',
|
||||
balanceMustBe: 'Credit',
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity,
|
||||
});
|
||||
|
||||
const expense = await fs.getData({
|
||||
rootType: 'Expense',
|
||||
balanceMustBe: 'Debit',
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity,
|
||||
});
|
||||
|
||||
const incomeAccount = income.totalRow.account as string;
|
||||
const incomeTotalRow = {
|
||||
...income.totalRow,
|
||||
account: {
|
||||
template: `<span class="font-semibold">${incomeAccount}</span>`,
|
||||
},
|
||||
};
|
||||
|
||||
const expenseAccount = expense.totalRow.account as string;
|
||||
const expenseTotalRow = {
|
||||
...expense.totalRow,
|
||||
account: {
|
||||
template: `<span class="font-semibold">${expenseAccount}</span>`,
|
||||
},
|
||||
};
|
||||
|
||||
let rows = [
|
||||
...income.accounts,
|
||||
incomeTotalRow,
|
||||
{
|
||||
account: {
|
||||
template: '<span> </span>',
|
||||
},
|
||||
isGroup: true,
|
||||
},
|
||||
...expense.accounts,
|
||||
expenseTotalRow,
|
||||
{
|
||||
account: {
|
||||
template: '<span> </span>',
|
||||
},
|
||||
isGroup: true,
|
||||
},
|
||||
] as Row[];
|
||||
|
||||
rows = rows.map((row) => {
|
||||
if (row.indent === 0) {
|
||||
row.account = {
|
||||
template: `<span class="font-semibold">${row.account}</span>`,
|
||||
};
|
||||
}
|
||||
return row;
|
||||
});
|
||||
|
||||
const columns = unique([...income.periodList, ...expense.periodList]);
|
||||
|
||||
const profitRow: Row = {
|
||||
account: 'Total Profit',
|
||||
};
|
||||
|
||||
for (const column of columns) {
|
||||
const incomeAmount =
|
||||
(income.totalRow[column] as number | undefined) ?? 0.0;
|
||||
const expenseAmount =
|
||||
(expense.totalRow[column] as number | undefined) ?? 0.0;
|
||||
|
||||
profitRow[column] = incomeAmount - expenseAmount;
|
||||
|
||||
rows.forEach((row) => {
|
||||
if (!row.isGroup) {
|
||||
row[column] = row[column] || 0.0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
rows.push(profitRow);
|
||||
|
||||
return { rows, columns };
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import frappe, { t } from 'fyo';
|
||||
import { t } from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import getCommonExportActions from '../commonExporter';
|
||||
|
||||
const title = t`Profit and Loss`;
|
||||
@ -22,7 +23,7 @@ export default {
|
||||
label: t`From Date`,
|
||||
required: 1,
|
||||
default: async () => {
|
||||
return (await frappe.getSingle('AccountingSettings')).fiscalYearStart;
|
||||
return (await fyo.getSingle('AccountingSettings')).fiscalYearStart;
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -33,7 +34,7 @@ export default {
|
||||
label: t`To Date`,
|
||||
required: 1,
|
||||
default: async () => {
|
||||
return (await frappe.getSingle('AccountingSettings')).fiscalYearEnd;
|
||||
return (await fyo.getSingle('AccountingSettings')).fiscalYearEnd;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import frappe from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
class PurchaseRegister {
|
||||
async run({ fromDate, toDate, supplier }) {
|
||||
@ -18,7 +18,7 @@ class PurchaseRegister {
|
||||
}
|
||||
filters.submitted = 1;
|
||||
|
||||
const bills = await frappe.db.getAll({
|
||||
const bills = await fyo.db.getAll({
|
||||
doctype: 'PurchaseInvoice',
|
||||
fields: ['name', 'date', 'supplier', 'account', 'netTotal', 'grandTotal'],
|
||||
filters,
|
||||
@ -28,7 +28,7 @@ class PurchaseRegister {
|
||||
|
||||
const billNames = bills.map((d) => d.name);
|
||||
|
||||
const taxes = await frappe.db.getAll({
|
||||
const taxes = await fyo.db.getAll({
|
||||
doctype: 'TaxSummary',
|
||||
fields: ['parent', 'amount'],
|
||||
filters: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import frappe from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
class SalesRegister {
|
||||
async run({ fromDate, toDate, customer }) {
|
||||
@ -17,7 +17,7 @@ class SalesRegister {
|
||||
filters.date = ['<=', toDate];
|
||||
}
|
||||
|
||||
const invoices = await frappe.db.getAll({
|
||||
const invoices = await fyo.db.getAll({
|
||||
doctype: 'SalesInvoice',
|
||||
fields: ['name', 'date', 'customer', 'account', 'netTotal', 'grandTotal'],
|
||||
filters: filters,
|
||||
@ -27,7 +27,7 @@ class SalesRegister {
|
||||
|
||||
const invoiceNames = invoices.map((d) => d.name);
|
||||
|
||||
const taxes = await frappe.db.getAll({
|
||||
const taxes = await fyo.db.getAll({
|
||||
doctype: 'TaxSummary',
|
||||
fields: ['parent', 'amount'],
|
||||
filters: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getTrialBalance } from '../FinancialStatements/FinancialStatements';
|
||||
import { getTrialBalance } from '../helpers/financialStatements';
|
||||
|
||||
export default class TrialBalance {
|
||||
async run({ fromDate, toDate }) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import frappe, { t } from 'fyo';
|
||||
import { t } from 'fyo';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import getCommonExportActions from '../commonExporter';
|
||||
|
||||
const title = t`Trial Balance`;
|
||||
@ -16,7 +17,7 @@ export default {
|
||||
placeholder: t`From Date`,
|
||||
required: 1,
|
||||
default: async () => {
|
||||
return (await frappe.getSingle('AccountingSettings')).fiscalYearStart;
|
||||
return (await fyo.getSingle('AccountingSettings')).fiscalYearStart;
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -27,7 +28,7 @@ export default {
|
||||
label: t`To Date`,
|
||||
required: 1,
|
||||
default: async () => {
|
||||
return (await frappe.getSingle('AccountingSettings')).fiscalYearEnd;
|
||||
return (await fyo.getSingle('AccountingSettings')).fiscalYearEnd;
|
||||
},
|
||||
},
|
||||
],
|
||||
|
161
reports/commonExporter.ts
Normal file
161
reports/commonExporter.ts
Normal file
@ -0,0 +1,161 @@
|
||||
import { DocValue, DocValueMap } from 'fyo/core/types';
|
||||
import { Verb } from 'fyo/telemetry/types';
|
||||
import { Field } from 'schemas/types';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getSavePath, saveData, showExportInFolder } from 'src/utils/ipcCalls';
|
||||
|
||||
interface JSONExport {
|
||||
columns: { fieldname: string; label: string }[];
|
||||
rows: Record<string, DocValue>[];
|
||||
filters: Record<string, string>;
|
||||
timestamp: string;
|
||||
reportName: string;
|
||||
softwareName: string;
|
||||
softwareVersion: string;
|
||||
}
|
||||
|
||||
type GetReportData = () => {
|
||||
rows: DocValueMap[];
|
||||
columns: Field[];
|
||||
filters: Record<string, string>;
|
||||
};
|
||||
|
||||
type TemplateObject = { template: string };
|
||||
|
||||
function templateToInnerText(innerHTML: string): string {
|
||||
const temp = document.createElement('template');
|
||||
temp.innerHTML = innerHTML.trim();
|
||||
// @ts-ignore
|
||||
return temp.content.firstChild!.innerText;
|
||||
}
|
||||
|
||||
function deObjectify(value: TemplateObject | DocValue) {
|
||||
if (typeof value !== 'object') return value;
|
||||
if (value === null) return '';
|
||||
|
||||
const innerHTML = (value as TemplateObject).template;
|
||||
if (!innerHTML) return '';
|
||||
return templateToInnerText(innerHTML);
|
||||
}
|
||||
|
||||
function csvFormat(value: TemplateObject | DocValue): string {
|
||||
if (typeof value === 'string') {
|
||||
return `"${value}"`;
|
||||
} else if (value === null) {
|
||||
return '';
|
||||
} else if (typeof value === 'object') {
|
||||
const innerHTML = (value as TemplateObject).template;
|
||||
|
||||
if (!innerHTML) return '';
|
||||
return csvFormat(deObjectify(value as TemplateObject));
|
||||
}
|
||||
|
||||
return String(value);
|
||||
}
|
||||
|
||||
export async function exportCsv(
|
||||
rows: DocValueMap[],
|
||||
columns: Field[],
|
||||
filePath: string
|
||||
) {
|
||||
const fieldnames = columns.map(({ fieldname }) => fieldname);
|
||||
const labels = columns.map(({ label }) => csvFormat(label));
|
||||
const csvRows = [
|
||||
labels.join(','),
|
||||
...rows.map((row) =>
|
||||
fieldnames.map((f) => csvFormat(row[f] as DocValue)).join(',')
|
||||
),
|
||||
];
|
||||
|
||||
saveExportData(csvRows.join('\n'), filePath);
|
||||
}
|
||||
|
||||
async function exportJson(
|
||||
rows: DocValueMap[],
|
||||
columns: Field[],
|
||||
filePath: string,
|
||||
filters: Record<string, string>,
|
||||
reportName: string
|
||||
) {
|
||||
const exportObject: JSONExport = {
|
||||
columns: [],
|
||||
rows: [],
|
||||
filters: {},
|
||||
timestamp: '',
|
||||
reportName: '',
|
||||
softwareName: '',
|
||||
softwareVersion: '',
|
||||
};
|
||||
const fieldnames = columns.map(({ fieldname }) => fieldname);
|
||||
|
||||
exportObject.columns = columns.map(({ fieldname, label }) => ({
|
||||
fieldname,
|
||||
label,
|
||||
}));
|
||||
|
||||
exportObject.rows = rows.map((row) =>
|
||||
fieldnames.reduce((acc, f) => {
|
||||
const value = row[f];
|
||||
if (value === undefined) {
|
||||
acc[f] = '';
|
||||
} else {
|
||||
acc[f] = deObjectify(value as DocValue | TemplateObject);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {} as Record<string, DocValue>)
|
||||
);
|
||||
|
||||
exportObject.filters = Object.keys(filters)
|
||||
.filter((name) => filters[name] !== null && filters[name] !== undefined)
|
||||
.reduce((acc, name) => {
|
||||
acc[name] = filters[name];
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
|
||||
exportObject.timestamp = new Date().toISOString();
|
||||
exportObject.reportName = reportName;
|
||||
exportObject.softwareName = 'Frappe Books';
|
||||
exportObject.softwareVersion = fyo.store.appVersion;
|
||||
|
||||
await saveExportData(JSON.stringify(exportObject), filePath);
|
||||
}
|
||||
|
||||
async function exportReport(
|
||||
extention: string,
|
||||
reportName: string,
|
||||
getReportData: GetReportData
|
||||
) {
|
||||
const { rows, columns, filters } = getReportData();
|
||||
|
||||
const { filePath, canceled } = await getSavePath(reportName, extention);
|
||||
if (canceled || !filePath) return;
|
||||
|
||||
switch (extention) {
|
||||
case 'csv':
|
||||
await exportCsv(rows, columns, filePath);
|
||||
break;
|
||||
case 'json':
|
||||
await exportJson(rows, columns, filePath, filters, reportName);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
fyo.telemetry.log(Verb.Exported, reportName, { extention });
|
||||
}
|
||||
|
||||
export default function getCommonExportActions(reportName: string) {
|
||||
return ['csv', 'json'].map((ext) => ({
|
||||
group: fyo.t`Export`,
|
||||
label: ext.toUpperCase(),
|
||||
type: 'primary',
|
||||
action: async (getReportData: GetReportData) =>
|
||||
await exportReport(ext, reportName, getReportData),
|
||||
}));
|
||||
}
|
||||
|
||||
export async function saveExportData(data: string, filePath: string) {
|
||||
await saveData(data, filePath);
|
||||
showExportInFolder(fyo.t`Export Successful`, filePath);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
/*
|
||||
import AccountsReceivablePayable from './AccountsReceivablePayable/AccountsReceivablePayable';
|
||||
import BalanceSheet from './BalanceSheet/BalanceSheet';
|
||||
import BankReconciliation from './BankReconciliation/BankReconciliation';
|
||||
@ -33,3 +34,7 @@ export function getReportData(method, filters) {
|
||||
const ReportClass = reports[method];
|
||||
return new ReportClass().run(filters);
|
||||
}
|
||||
*/
|
||||
export function getReportData(method, filters) {
|
||||
return { rows: [], columns: [] };
|
||||
}
|
||||
|
23
reports/types.ts
Normal file
23
reports/types.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { AccountRootType } from 'models/baseModels/Account/types';
|
||||
|
||||
export type ExportExtension = 'csv' | 'json';
|
||||
|
||||
export interface ReportData {
|
||||
rows: unknown[];
|
||||
columns: unknown[];
|
||||
}
|
||||
|
||||
export abstract class Report {
|
||||
abstract run(filters: Record<string, unknown>): ReportData;
|
||||
}
|
||||
|
||||
export type BalanceType = 'Credit' | 'Debit';
|
||||
export type Periodicity = 'Monthly' | 'Quarterly' | 'Half Yearly' | 'Yearly';
|
||||
export interface FinancialStatementOptions {
|
||||
rootType: AccountRootType;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
balanceMustBe?: BalanceType;
|
||||
periodicity?: Periodicity;
|
||||
accumulateValues?: boolean;
|
||||
}
|
@ -1,19 +1,21 @@
|
||||
import BalanceSheetViewConfig from './BalanceSheet/viewConfig';
|
||||
import GeneralLedgerViewConfig from './GeneralLedger/viewConfig';
|
||||
import GoodsAndServiceTaxGSTR1View from './GoodsAndServiceTax/GSTR1View';
|
||||
import GoodsAndServiceTaxGSTR2View from './GoodsAndServiceTax/GSTR2View';
|
||||
import ProfitAndLossViewConfig from './ProfitAndLoss/viewConfig';
|
||||
import PurchaseRegisterViewConfig from './PurchaseRegister/viewConfig';
|
||||
import SalesRegisterViewConfig from './SalesRegister/viewConfig';
|
||||
import TrialBalanceViewConfig from './TrialBalance/viewConfig';
|
||||
// import BalanceSheetViewConfig from './BalanceSheet/viewConfig';
|
||||
// import GeneralLedgerViewConfig from './GeneralLedger/viewConfig';
|
||||
// import GoodsAndServiceTaxGSTR1View from './GoodsAndServiceTax/GSTR1View';
|
||||
// import GoodsAndServiceTaxGSTR2View from './GoodsAndServiceTax/GSTR2View';
|
||||
// import ProfitAndLossViewConfig from './ProfitAndLoss/viewConfig';
|
||||
// import PurchaseRegisterViewConfig from './PurchaseRegister/viewConfig';
|
||||
// import SalesRegisterViewConfig from './SalesRegister/viewConfig';
|
||||
// import TrialBalanceViewConfig from './TrialBalance/viewConfig';
|
||||
|
||||
export default {
|
||||
'general-ledger': GeneralLedgerViewConfig,
|
||||
'sales-register': SalesRegisterViewConfig,
|
||||
'purchase-register': PurchaseRegisterViewConfig,
|
||||
'balance-sheet': BalanceSheetViewConfig,
|
||||
'profit-and-loss': ProfitAndLossViewConfig,
|
||||
'trial-balance': TrialBalanceViewConfig,
|
||||
'gstr-1': GoodsAndServiceTaxGSTR1View,
|
||||
'gstr-2': GoodsAndServiceTaxGSTR2View,
|
||||
};
|
||||
// export default {
|
||||
// 'general-ledger': GeneralLedgerViewConfig,
|
||||
// 'sales-register': SalesRegisterViewConfig,
|
||||
// 'purchase-register': PurchaseRegisterViewConfig,
|
||||
// 'balance-sheet': BalanceSheetViewConfig,
|
||||
// 'profit-and-loss': ProfitAndLossViewConfig,
|
||||
// 'trial-balance': TrialBalanceViewConfig,
|
||||
// 'gstr-1': GoodsAndServiceTaxGSTR1View,
|
||||
// 'gstr-2': GoodsAndServiceTaxGSTR2View,
|
||||
// };
|
||||
|
||||
export default {};
|
||||
|
56
src/App.vue
56
src/App.vue
@ -3,17 +3,17 @@
|
||||
id="app"
|
||||
class="h-screen flex flex-col font-sans overflow-hidden antialiased"
|
||||
>
|
||||
<WindowsTitleBar v-if="platform === 'Windows'" />
|
||||
<!-- <WindowsTitleBar v-if="platform === 'Windows'" />
|
||||
<Desk
|
||||
class="flex-1"
|
||||
v-if="activeScreen === 'Desk'"
|
||||
@change-db-file="changeDbFile"
|
||||
/>
|
||||
/>-->
|
||||
<DatabaseSelector
|
||||
v-if="activeScreen === 'DatabaseSelector'"
|
||||
@database-connect="showSetupWizardOrDesk(true)"
|
||||
/>
|
||||
<SetupWizard
|
||||
<!--<SetupWizard
|
||||
v-if="activeScreen === 'SetupWizard'"
|
||||
@setup-complete="setupComplete"
|
||||
@setup-canceled="setupCanceled"
|
||||
@ -25,29 +25,19 @@
|
||||
>
|
||||
<div id="toast-target" />
|
||||
</div>
|
||||
<TelemetryModal />
|
||||
<TelemetryModal />-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import fs from 'fs/promises';
|
||||
import frappe from 'fyo';
|
||||
import WindowsTitleBar from 'src/components/WindowsTitleBar';
|
||||
import config from 'src/config';
|
||||
import {
|
||||
connectToLocalDatabase,
|
||||
postSetup,
|
||||
purgeCache
|
||||
} from 'src/initialization';
|
||||
import { IPC_ACTIONS, IPC_MESSAGES } from 'utils/messages';
|
||||
import TelemetryModal from './components/once/TelemetryModal.vue';
|
||||
import { showErrorDialog } from './errorHandling';
|
||||
import { IPC_MESSAGES } from 'utils/messages';
|
||||
import { fyo } from './initFyo';
|
||||
import DatabaseSelector from './pages/DatabaseSelector';
|
||||
import Desk from './pages/Desk';
|
||||
import SetupWizard from './pages/SetupWizard/SetupWizard';
|
||||
// import Desk from './pages/Desk';
|
||||
// import SetupWizard from './pages/SetupWizard/SetupWizard';
|
||||
import './styles/index.css';
|
||||
import telemetry from './telemetry/telemetry';
|
||||
import { checkForUpdates, routeTo } from './utils';
|
||||
|
||||
export default {
|
||||
@ -77,15 +67,16 @@ export default {
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Desk,
|
||||
SetupWizard,
|
||||
// Desk,
|
||||
// SetupWizard,
|
||||
DatabaseSelector,
|
||||
WindowsTitleBar,
|
||||
TelemetryModal,
|
||||
// WindowsTitleBar,
|
||||
// TelemetryModal,
|
||||
},
|
||||
async mounted() {
|
||||
telemetry.platform = this.platform;
|
||||
const lastSelectedFilePath = config.get('lastSelectedFilePath', null);
|
||||
fyo.telemetry.platform = this.platform;
|
||||
/*
|
||||
const lastSelectedFilePath = fyo.config.get('lastSelectedFilePath', null);
|
||||
const { connectionSuccess, reason } = await connectToLocalDatabase(
|
||||
lastSelectedFilePath
|
||||
);
|
||||
@ -101,16 +92,18 @@ export default {
|
||||
|
||||
await showErrorDialog(title, content);
|
||||
}
|
||||
*/
|
||||
|
||||
this.activeScreen = 'DatabaseSelector';
|
||||
},
|
||||
methods: {
|
||||
async setupComplete() {
|
||||
await postSetup();
|
||||
// TODO: Complete this
|
||||
// await postSetup();
|
||||
await this.showSetupWizardOrDesk(true);
|
||||
},
|
||||
async showSetupWizardOrDesk(resetRoute = false) {
|
||||
const { setupComplete } = frappe.AccountingSettings;
|
||||
const { setupComplete } = fyo.singles.AccountingSettings;
|
||||
if (!setupComplete) {
|
||||
this.activeScreen = 'SetupWizard';
|
||||
} else {
|
||||
@ -122,8 +115,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const { onboardingComplete } = await frappe.getSingle('GetStarted');
|
||||
const { hideGetStarted } = await frappe.getSingle('SystemSettings');
|
||||
const { onboardingComplete } = await fyo.getSingle('GetStarted');
|
||||
const { hideGetStarted } = await fyo.getSingle('SystemSettings');
|
||||
|
||||
if (hideGetStarted || onboardingComplete) {
|
||||
routeTo('/');
|
||||
@ -132,13 +125,14 @@ export default {
|
||||
}
|
||||
},
|
||||
async changeDbFile() {
|
||||
config.set('lastSelectedFilePath', null);
|
||||
fyo.config.set('lastSelectedFilePath', null);
|
||||
telemetry.stop();
|
||||
await purgeCache(true);
|
||||
// TODO: purgeCache(true)
|
||||
// await purgeCache(true);
|
||||
this.activeScreen = 'DatabaseSelector';
|
||||
},
|
||||
async setupCanceled() {
|
||||
const filePath = config.get('lastSelectedFilePath');
|
||||
const filePath = fyo.config.get('lastSelectedFilePath');
|
||||
await fs.unlink(filePath);
|
||||
this.changeDbFile();
|
||||
},
|
||||
|
@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getBgTextColorClass } from '../colors';
|
||||
import { getBgTextColorClass } from 'src/utils/colors';
|
||||
|
||||
export default {
|
||||
name: 'Badge',
|
||||
|
@ -134,7 +134,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import Tooltip from '../Tooltip.vue';
|
||||
import { prefixFormat } from './chartUtils';
|
||||
import { prefixFormat } from 'src/utils/chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
@ -131,8 +131,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { euclideanDistance, prefixFormat } from 'src/utils/chart';
|
||||
import Tooltip from '../Tooltip.vue';
|
||||
import { euclideanDistance, prefixFormat } from './chartUtils';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
@ -56,12 +56,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import Base from './Base';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
import Base from './Base';
|
||||
|
||||
export default {
|
||||
name: 'AttachImage',
|
||||
@ -75,7 +75,7 @@ export default {
|
||||
methods: {
|
||||
async openFileSelector() {
|
||||
const options = {
|
||||
title: frappe.t`Select Image`,
|
||||
title: fyo.t`Select Image`,
|
||||
properties: ['openFile'],
|
||||
filters: [
|
||||
{ name: 'Image', extensions: ['png', 'jpg', 'jpeg', 'webp'] },
|
||||
|
@ -28,7 +28,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import Float from './Float';
|
||||
|
||||
export default {
|
||||
@ -48,12 +48,12 @@ export default {
|
||||
this.$emit('focus', e);
|
||||
},
|
||||
parse(value) {
|
||||
return frappe.pesa(value);
|
||||
return fyo.pesa(value);
|
||||
},
|
||||
onBlur(e) {
|
||||
let { value } = e.target;
|
||||
if (value !== 0 && !value) {
|
||||
value = frappe.pesa(0).round();
|
||||
value = fyo.pesa(0).round();
|
||||
}
|
||||
|
||||
this.showInput = false;
|
||||
@ -68,7 +68,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
formattedValue() {
|
||||
return frappe.format(this.value, this.df, this.doc);
|
||||
return fyo.format(this.value, this.df, this.doc);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import Base from './Base';
|
||||
import DatePicker from '../DatePicker/DatePicker';
|
||||
|
||||
@ -33,7 +33,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
formatValue(value) {
|
||||
return frappe.format(value, this.df);
|
||||
return fyo.format(value, this.df);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -7,10 +7,10 @@
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
import { DEFAULT_LANGUAGE } from 'frappe/utils/consts';
|
||||
import config from 'src/config';
|
||||
import { languageCodeMap } from 'src/languageCodeMap';
|
||||
import { DEFAULT_LANGUAGE } from 'fyo/utils/consts';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { setLanguageMap } from 'src/utils';
|
||||
import { languageCodeMap } from 'src/utils/language';
|
||||
import FormControl from './FormControl';
|
||||
|
||||
export default {
|
||||
@ -31,16 +31,15 @@ export default {
|
||||
components: { FormControl },
|
||||
computed: {
|
||||
value() {
|
||||
return config.get('language') ?? DEFAULT_LANGUAGE;
|
||||
return fyo.config.get('language') ?? DEFAULT_LANGUAGE;
|
||||
},
|
||||
languageDf() {
|
||||
languageCodeMap;
|
||||
return {
|
||||
fieldname: 'language',
|
||||
label: this.t`Language`,
|
||||
fieldtype: 'Select',
|
||||
options: Object.keys(languageCodeMap),
|
||||
default: config.get('language') ?? DEFAULT_LANGUAGE,
|
||||
default: fyo.config.get('language') ?? DEFAULT_LANGUAGE,
|
||||
description: this.t`Set the display language.`,
|
||||
};
|
||||
},
|
||||
|
@ -1,11 +1,7 @@
|
||||
import Badge from 'src/components/Badge';
|
||||
import { openQuickEdit } from 'src/utils';
|
||||
import frappe, { t } from 'frappe';
|
||||
import { markRaw } from 'vue';
|
||||
import AutoComplete from './AutoComplete';
|
||||
<script>
|
||||
import frappe, { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import Badge from 'src/components/Badge';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { openQuickEdit } from 'src/utils';
|
||||
import { markRaw } from 'vue';
|
||||
import AutoComplete from './AutoComplete';
|
||||
@ -19,7 +15,7 @@ export default {
|
||||
let doctype = this.getTarget();
|
||||
let meta;
|
||||
try {
|
||||
meta = frappe.getMeta(doctype);
|
||||
meta = fyo.getMeta(doctype);
|
||||
} catch (err) {
|
||||
if (err.message.includes('not a registered doctype')) {
|
||||
return [];
|
||||
@ -30,7 +26,7 @@ export default {
|
||||
if (keyword && !filters.keywords) {
|
||||
filters.keywords = ['like', keyword];
|
||||
}
|
||||
let results = await frappe.db.getAll({
|
||||
let results = await fyo.db.getAll({
|
||||
doctype,
|
||||
filters,
|
||||
fields: [
|
||||
@ -108,7 +104,7 @@ export default {
|
||||
},
|
||||
async openNewDoc() {
|
||||
let doctype = this.df.target;
|
||||
let doc = await frappe.getEmptyDoc(doctype);
|
||||
let doc = await fyo.getEmptyDoc(doctype);
|
||||
let filters = await this.getFilters();
|
||||
openQuickEdit({
|
||||
doctype,
|
||||
|
@ -61,8 +61,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import Row from 'src/components/Row';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import Base from './Base';
|
||||
import TableRow from './TableRow';
|
||||
|
||||
@ -122,7 +122,7 @@ export default {
|
||||
return [0.3].concat(this.tableFields.map(() => 1));
|
||||
},
|
||||
tableFields() {
|
||||
let meta = frappe.getMeta(this.df.childtype);
|
||||
let meta = fyo.getMeta(this.df.childtype);
|
||||
return meta.tableFields.map((fieldname) => meta.getField(fieldname));
|
||||
},
|
||||
},
|
||||
|
@ -32,6 +32,4 @@ export default {
|
||||
return svg;
|
||||
},
|
||||
};
|
||||
|
||||
// https://github.com/frappe/frappejs/commits/master/ui/components/FeatherIcon.vue
|
||||
</script>
|
||||
|
@ -116,8 +116,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { t } from 'frappe';
|
||||
import { getRandomString } from 'frappe/utils';
|
||||
import { t } from 'fyo';
|
||||
import { getRandomString } from 'utils';
|
||||
import Button from './Button';
|
||||
import FormControl from './Controls/FormControl';
|
||||
import Icon from './Icon';
|
||||
@ -153,9 +153,7 @@ export default {
|
||||
this.addNewFilter();
|
||||
},
|
||||
methods: {
|
||||
getRandomString() {
|
||||
return getRandomString();
|
||||
},
|
||||
getRandomString,
|
||||
addNewFilter() {
|
||||
let df = this.fields[0];
|
||||
this.addFilter(df.fieldname, 'like', '');
|
||||
|
@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="doc" class="p-4">
|
||||
<div class="row">
|
||||
<div class="col-6 text-center">
|
||||
<h4>Customize</h4>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<f-button secondary @click="saveAndClose">{{
|
||||
t`Save & Close`
|
||||
}}</f-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 mt-4">
|
||||
<form-layout :doc="doc" :fields="fields" @updateDoc="saveDoc" />
|
||||
<sketch-picker v-model="color" class="shadow-none" />
|
||||
<div class="mt-3">
|
||||
<f-button secondary @click="openCompanySettings">{{
|
||||
t`Company Settings`
|
||||
}}</f-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import FormLayout from 'frappe/ui/components/Form/FormLayout';
|
||||
import { Sketch } from 'vue-color';
|
||||
|
||||
export default {
|
||||
name: 'InvoiceCustomizer',
|
||||
emits: [
|
||||
'changeTemplate',
|
||||
'changeFont',
|
||||
'closeInvoiceCustomizer',
|
||||
'updateTemplateView',
|
||||
'changeColor',
|
||||
],
|
||||
components: {
|
||||
FormLayout,
|
||||
'sketch-picker': Sketch,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
doc: null,
|
||||
fields: [],
|
||||
color: {},
|
||||
};
|
||||
},
|
||||
async created() {
|
||||
this.doc = await frappe.doc.getDoc('SalesInvoiceSettings');
|
||||
this.color.hex = this.doc.themeColor;
|
||||
const meta = frappe.getMeta('SalesInvoiceSettings');
|
||||
this.fields = meta.fields.filter(
|
||||
(field) => field.fieldname !== 'numberSeries'
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
async saveDoc(updatedValue) {
|
||||
let { fieldname, value } = updatedValue;
|
||||
if (fieldname === 'template') {
|
||||
this.$emit('changeTemplate', value);
|
||||
} else if (fieldname === 'font') {
|
||||
this.$emit('changeFont', value);
|
||||
}
|
||||
},
|
||||
async saveAndClose() {
|
||||
this.doc.themeColor = this.color.hex;
|
||||
await this.doc.update();
|
||||
this.$emit('closeInvoiceCustomizer');
|
||||
},
|
||||
async openCompanySettings() {
|
||||
const settings = await frappe.getSingle('CompanySettings');
|
||||
settings.on('afterSave', async () => {
|
||||
this.$formModal.close();
|
||||
this.$emit('updateTemplateView');
|
||||
});
|
||||
this.$formModal.open(settings);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
color: async function () {
|
||||
if (this.doc) {
|
||||
if (this.doc.themeColor != this.color.hex) {
|
||||
this.$emit('changeColor', this.color.hex);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -36,6 +36,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import luxon from 'luxon';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
export default {
|
||||
props: ['entries', 'afterReconcile'],
|
||||
@ -66,7 +67,7 @@ export default {
|
||||
this.selectedEntries.push(this.entries[i]);
|
||||
}
|
||||
for (let entry of this.selectedEntries) {
|
||||
const payment = await frappe.doc.getDoc('Payment', entry['Payment Entry']);
|
||||
const payment = await fyo.doc.getDoc('Payment', entry['Payment Entry']);
|
||||
const clearanceDate =
|
||||
luxon.DateTime.fromFormat(
|
||||
entry['Clearance Date'],
|
||||
|
@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row no-gutters">
|
||||
<div v-if="showInvoiceCustomizer" class="col-3 mt-4 mx-auto"></div>
|
||||
<div class="col-8 mx-auto text-right mt-4">
|
||||
<f-button
|
||||
primary
|
||||
@click="$emit('send', $refs.printComponent.innerHTML)"
|
||||
>{{ t`Send` }}</f-button
|
||||
>
|
||||
<f-button secondary @click="toggleCustomizer">{{
|
||||
t`Customize`
|
||||
}}</f-button>
|
||||
<f-button
|
||||
secondary
|
||||
@click="$emit('makePDF', $refs.printComponent.innerHTML)"
|
||||
>{{ t`PDF` }}</f-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-gutters">
|
||||
<div v-if="showInvoiceCustomizer" class="col-3 mt-4 mx-auto">
|
||||
<invoice-customizer
|
||||
class="border"
|
||||
style="position: fixed"
|
||||
@closeInvoiceCustomizer="toggleCustomizer"
|
||||
@changeColor="changeColor($event)"
|
||||
@changeTemplate="changeTemplate($event)"
|
||||
@changeFont="changeFont($event)"
|
||||
@updateTemplateView="updateTemplateView"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="col-8 bg-white mt-4 mx-auto border shadow"
|
||||
ref="printComponent"
|
||||
>
|
||||
<component
|
||||
:themeColor="themeColor"
|
||||
:font="font"
|
||||
:is="template"
|
||||
v-if="doc"
|
||||
:doc="doc"
|
||||
:key="usedForReRender"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import InvoiceTemplate1 from 'src/../models/doctype/SalesInvoice/Templates/InvoiceTemplate1';
|
||||
import InvoiceTemplate2 from 'src/../models/doctype/SalesInvoice/Templates/InvoiceTemplate2';
|
||||
import InvoiceTemplate3 from 'src/../models/doctype/SalesInvoice/Templates/InvoiceTemplate3';
|
||||
import InvoiceCustomizer from 'src/components/InvoiceCustomizer';
|
||||
|
||||
const invoiceTemplates = {
|
||||
'Basic I': InvoiceTemplate1,
|
||||
'Basic II': InvoiceTemplate2,
|
||||
Modern: InvoiceTemplate3,
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'InvoicePrint',
|
||||
props: ['doc'],
|
||||
emits: ['send', 'makePDF'],
|
||||
components: {
|
||||
InvoiceCustomizer,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showInvoiceCustomizer: false,
|
||||
themeColor: undefined,
|
||||
template: undefined,
|
||||
font: undefined,
|
||||
usedForReRender: 0,
|
||||
};
|
||||
},
|
||||
async created() {
|
||||
await this.loadInvoice();
|
||||
},
|
||||
methods: {
|
||||
async loadInvoice() {
|
||||
await this.getTemplate();
|
||||
await this.getColor();
|
||||
await this.getFont();
|
||||
},
|
||||
async getTemplate() {
|
||||
let invoiceSettings = await frappe.doc.getDoc('SalesInvoiceSettings');
|
||||
this.template = invoiceTemplates[invoiceSettings.template];
|
||||
},
|
||||
async getColor() {
|
||||
let invoiceSettings = await frappe.doc.getDoc('SalesInvoiceSettings');
|
||||
this.themeColor = invoiceSettings.themeColor;
|
||||
},
|
||||
async getFont() {
|
||||
let invoiceSettings = await frappe.doc.getDoc('SalesInvoiceSettings');
|
||||
this.font = invoiceSettings.font;
|
||||
},
|
||||
async toggleCustomizer() {
|
||||
await this.loadInvoice();
|
||||
this.showInvoiceCustomizer = !this.showInvoiceCustomizer;
|
||||
},
|
||||
changeColor(color) {
|
||||
this.themeColor = color;
|
||||
},
|
||||
changeTemplate(template) {
|
||||
this.template = invoiceTemplates[template];
|
||||
},
|
||||
changeFont(font) {
|
||||
this.font = font;
|
||||
},
|
||||
updateTemplateView() {
|
||||
this.usedForReRender += 1;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
export default {
|
||||
name: 'Base',
|
||||
props: ['doc', 'printSettings'],
|
||||
@ -7,7 +7,7 @@ export default {
|
||||
methods: {
|
||||
format(row, fieldname) {
|
||||
let value = row.get(fieldname);
|
||||
return frappe.format(value, row.meta.getField(fieldname));
|
||||
return fyo.format(value, row.meta.getField(fieldname));
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -14,7 +14,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="text-xl text-gray-700 font-semibold" v-else>
|
||||
{{ frappe.AccountingSettings.companyName }}
|
||||
{{ fyo.singles.AccountingSettings.companyName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3">
|
||||
@ -23,8 +23,8 @@
|
||||
</div>
|
||||
<div class="w-1/3">
|
||||
<div v-if="companyAddress">{{ companyAddress.addressDisplay }}</div>
|
||||
<div v-if="frappe.AccountingSettings && frappe.AccountingSettings.gstin">
|
||||
GSTIN: {{ frappe.AccountingSettings.gstin }}
|
||||
<div v-if="fyo.singles.AccountingSettings && fyo.singles.AccountingSettings.gstin">
|
||||
GSTIN: {{ fyo.singles.AccountingSettings.gstin }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -36,7 +36,7 @@
|
||||
{{ doc.name }}
|
||||
</h1>
|
||||
<div class="py-2 text-base">
|
||||
{{ frappe.format(doc.date, 'Date') }}
|
||||
{{ fyo.format(doc.date, 'Date') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3" v-if="party">
|
||||
@ -97,7 +97,7 @@
|
||||
<div class="w-1/2">
|
||||
<div class="flex pl-2 justify-between py-3 border-b">
|
||||
<div>{{ t`Subtotal` }}</div>
|
||||
<div>{{ frappe.format(doc.netTotal, 'Currency') }}</div>
|
||||
<div>{{ fyo.format(doc.netTotal, 'Currency') }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex pl-2 justify-between py-3"
|
||||
@ -105,13 +105,13 @@
|
||||
:key="tax.name"
|
||||
>
|
||||
<div>{{ tax.account }}</div>
|
||||
<div>{{ frappe.format(tax.amount, 'Currency') }}</div>
|
||||
<div>{{ fyo.format(tax.amount, 'Currency') }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex pl-2 justify-between py-3 border-t text-green-600 font-semibold text-base"
|
||||
>
|
||||
<div>{{ t`Grand Total` }}</div>
|
||||
<div>{{ frappe.format(doc.grandTotal, 'Currency') }}</div>
|
||||
<div>{{ fyo.format(doc.grandTotal, 'Currency') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -18,16 +18,16 @@
|
||||
class="font-semibold text-xl"
|
||||
:style="{ color: printSettings.color }"
|
||||
>
|
||||
{{ frappe.AccountingSettings.companyName }}
|
||||
{{ fyo.singles.AccountingSettings.companyName }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-800" v-if="companyAddress">
|
||||
{{ companyAddress.addressDisplay }}
|
||||
</div>
|
||||
<div
|
||||
class="text-sm text-gray-800"
|
||||
v-if="frappe.AccountingSettings && frappe.AccountingSettings.gstin"
|
||||
v-if="fyo.singles.AccountingSettings && fyo.singles.AccountingSettings.gstin"
|
||||
>
|
||||
GSTIN: {{ frappe.AccountingSettings.gstin }}
|
||||
GSTIN: {{ fyo.singles.AccountingSettings.gstin }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -41,7 +41,7 @@
|
||||
{{ doc.name }}
|
||||
</div>
|
||||
<div>
|
||||
{{ frappe.format(doc.date, 'Date') }}
|
||||
{{ fyo.format(doc.date, 'Date') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -84,7 +84,7 @@
|
||||
<div class="text-right">
|
||||
<div class="text-gray-800">{{ t`Subtotal` }}</div>
|
||||
<div class="text-xl mt-2">
|
||||
{{ frappe.format(doc.netTotal, 'Currency') }}
|
||||
{{ fyo.format(doc.netTotal, 'Currency') }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -96,7 +96,7 @@
|
||||
{{ tax.account }}
|
||||
</div>
|
||||
<div class="text-xl mt-2">
|
||||
{{ frappe.format(tax.amount, 'Currency') }}
|
||||
{{ fyo.format(tax.amount, 'Currency') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -107,7 +107,7 @@
|
||||
<div>
|
||||
<div>{{ t`Grand Total` }}</div>
|
||||
<div class="text-2xl mt-2 font-semibold">
|
||||
{{ frappe.format(doc.grandTotal, 'Currency') }}
|
||||
{{ fyo.format(doc.grandTotal, 'Currency') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -18,10 +18,10 @@
|
||||
class="font-semibold text-xl"
|
||||
:style="{ color: printSettings.color }"
|
||||
>
|
||||
{{ frappe.AccountingSettings.companyName }}
|
||||
{{ fyo.singles.AccountingSettings.companyName }}
|
||||
</div>
|
||||
<div>
|
||||
{{ frappe.format(doc.date, 'Date') }}
|
||||
{{ fyo.format(doc.date, 'Date') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -73,9 +73,9 @@
|
||||
</div>
|
||||
<div
|
||||
class="mt-4 ml-8 text-black leading-relaxed text-lg"
|
||||
v-if="frappe.AccountingSettings && frappe.AccountingSettings.gstin"
|
||||
v-if="fyo.singles.AccountingSettings && fyo.singles.AccountingSettings.gstin"
|
||||
>
|
||||
GSTIN: {{ frappe.AccountingSettings.gstin }}
|
||||
GSTIN: {{ fyo.singles.AccountingSettings.gstin }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -117,7 +117,7 @@
|
||||
<div class="w-1/2 text-lg">
|
||||
<div class="flex pl-2 justify-between py-1">
|
||||
<div>{{ t`Subtotal` }}</div>
|
||||
<div>{{ frappe.format(doc.netTotal, 'Currency') }}</div>
|
||||
<div>{{ fyo.format(doc.netTotal, 'Currency') }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex pl-2 justify-between py-1"
|
||||
@ -125,14 +125,14 @@
|
||||
:key="tax.name"
|
||||
>
|
||||
<div>{{ tax.account }}</div>
|
||||
<div>{{ frappe.format(tax.amount, 'Currency') }}</div>
|
||||
<div>{{ fyo.format(tax.amount, 'Currency') }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex pl-2 justify-between py-1 font-semibold"
|
||||
:style="{ color: printSettings.color }"
|
||||
>
|
||||
<div>{{ t`Grand Total` }}</div>
|
||||
<div>{{ frappe.format(doc.grandTotal, 'Currency') }}</div>
|
||||
<div>{{ fyo.format(doc.grandTotal, 'Currency') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,10 +41,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe, { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import reports from 'reports/view';
|
||||
import Dropdown from 'src/components/Dropdown';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { routeTo } from 'src/utils';
|
||||
import reports from '../../reports/view';
|
||||
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -91,8 +93,8 @@ export default {
|
||||
});
|
||||
},
|
||||
getDoctypes() {
|
||||
let doctypes = Object.keys(frappe.models).sort();
|
||||
let doctypeMetas = doctypes.map((doctype) => frappe.getMeta(doctype));
|
||||
let doctypes = Object.keys(fyo.models).sort();
|
||||
let doctypeMetas = doctypes.map((doctype) => fyo.getMeta(doctype));
|
||||
let searchableDoctypes = doctypeMetas.filter((meta) => {
|
||||
return !meta.isSingle && !meta.isChild;
|
||||
});
|
||||
|
@ -99,6 +99,7 @@
|
||||
import path from 'path';
|
||||
import Button from 'src/components/Button';
|
||||
import { reportIssue } from 'src/errorHandling';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { routeTo } from 'src/utils';
|
||||
import router from '../router';
|
||||
import sidebarConfig from '../sidebarConfig';
|
||||
@ -117,10 +118,10 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
appVersion() {
|
||||
return frappe.store.appVersion;
|
||||
return fyo.store.appVersion;
|
||||
},
|
||||
dbPath() {
|
||||
const splits = frappe.db.dbPath.split(path.sep);
|
||||
const splits = fyo.db.dbPath.split(path.sep);
|
||||
return path.join(...splits.slice(splits.length - 2));
|
||||
},
|
||||
},
|
||||
@ -134,7 +135,7 @@ export default {
|
||||
groups = groups.filter((group) => {
|
||||
if (
|
||||
group.route === '/get-started' &&
|
||||
frappe.SystemSettings.hideGetStarted
|
||||
fyo.singles.SystemSettings.hideGetStarted
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -4,8 +4,7 @@
|
||||
}}</Badge>
|
||||
</template>
|
||||
<script>
|
||||
import Badge from 'src/components/Badge';
|
||||
import { statusColor } from '../colors';
|
||||
import { statusColor } from 'src/utils/colors';
|
||||
|
||||
export default {
|
||||
name: 'StatusBadge',
|
||||
|
@ -17,7 +17,7 @@
|
||||
:style="{ opacity }"
|
||||
v-if="show"
|
||||
>
|
||||
<FeatherIcon :name="iconName" class="w-6 h-6 mr-3" :class="iconColor" />
|
||||
<feather-icon :name="iconName" class="w-6 h-6 mr-3" :class="iconColor" />
|
||||
<div @click="actionClicked" :class="actionText ? 'cursor-pointer' : ''">
|
||||
<p class="text-base">{{ message }}</p>
|
||||
<button
|
||||
@ -35,8 +35,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getColorClass } from '../colors';
|
||||
import FeatherIcon from './FeatherIcon.vue';
|
||||
import { getColorClass } from 'src/utils/colors';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -1,7 +1,3 @@
|
||||
import Button from 'src/components/Button';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import frappe from 'frappe';
|
||||
import { getErrorMessage, handleErrorWithDialog } from '../errorHandling';
|
||||
<template>
|
||||
<div class="text-sm" :class="{ 'border-t': !noBorder }">
|
||||
<template v-for="df in formFields">
|
||||
@ -90,9 +86,9 @@ import { getErrorMessage, handleErrorWithDialog } from '../errorHandling';
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import Button from 'src/components/Button';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getErrorMessage, handleErrorWithDialog } from '../errorHandling';
|
||||
|
||||
let TwoColumnForm = {
|
||||
@ -224,7 +220,7 @@ let TwoColumnForm = {
|
||||
|
||||
this.inlineEditField = df;
|
||||
if (!this.doc[df.fieldname]) {
|
||||
this.inlineEditDoc = await frappe.getEmptyDoc(df.target);
|
||||
this.inlineEditDoc = await fyo.doc.getEmptyDoc(df.target);
|
||||
this.inlineEditDoc.once('afterInsert', () => {
|
||||
this.onChangeCommon(df, this.inlineEditDoc.name);
|
||||
});
|
||||
@ -234,7 +230,7 @@ let TwoColumnForm = {
|
||||
|
||||
this.inlineEditDisplayField =
|
||||
this.doc.meta.inlineEditDisplayField || 'name';
|
||||
this.inlineEditFields = frappe.getMeta(df.target).getQuickEditFields();
|
||||
this.inlineEditFields = fyo.getMeta(df.target).getQuickEditFields();
|
||||
},
|
||||
async saveInlineEditDoc(df) {
|
||||
if (!this.inlineEditDoc) {
|
||||
|
@ -20,14 +20,14 @@
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>
|
||||
{{ frappe.format(invoice.date, invoiceMeta.getField('date')) }}
|
||||
{{ fyo.format(invoice.date, invoiceMeta.getField('date')) }}
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="font-medium text-gray-900"
|
||||
>
|
||||
{{
|
||||
frappe.format(
|
||||
fyo.format(
|
||||
amountPaid(invoice),
|
||||
invoiceMeta.getField('baseGrandTotal')
|
||||
)
|
||||
@ -35,7 +35,7 @@
|
||||
</span>
|
||||
<span class="text-gray-600" v-if="!fullyPaid(invoice)">
|
||||
({{
|
||||
frappe.format(
|
||||
fyo.format(
|
||||
invoice.outstandingAmount,
|
||||
invoiceMeta.getField('outstandingAmount')
|
||||
)
|
||||
@ -49,7 +49,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { routeTo } from 'src/utils';
|
||||
import { getStatusColumn } from '../Transaction/Transaction';
|
||||
|
||||
@ -67,7 +67,7 @@ export default {
|
||||
return isCustomer ? 'SalesInvoice' : 'PurchaseInvoice';
|
||||
},
|
||||
invoiceMeta() {
|
||||
return frappe.getMeta(this.invoiceDoctype);
|
||||
return fyo.getMeta(this.invoiceDoctype);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
@ -78,7 +78,7 @@ export default {
|
||||
let isCustomer = this.doc.doctype === 'Customer';
|
||||
let doctype = this.invoiceDoctype;
|
||||
let partyField = isCustomer ? 'customer' : 'supplier';
|
||||
this.pendingInvoices = await frappe.db.getAll({
|
||||
this.pendingInvoices = await fyo.db.getAll({
|
||||
doctype,
|
||||
fields: [
|
||||
'name',
|
||||
|
@ -49,10 +49,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config, { ConfigKeys, TelemetrySetting } from 'src/config';
|
||||
import { getTelemetryOptions } from 'src/telemetry/helpers';
|
||||
import telemetry from 'src/telemetry/telemetry';
|
||||
import { NounEnum, Verb } from 'src/telemetry/types';
|
||||
import { ConfigKeys } from 'fyo/core/types';
|
||||
import { getTelemetryOptions } from 'fyo/telemetry/helpers';
|
||||
import { TelemetrySetting } from 'fyo/telemetry/types';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import Button from '../Button.vue';
|
||||
import FormControl from '../Controls/FormControl';
|
||||
import FeatherIcon from '../FeatherIcon.vue';
|
||||
@ -119,12 +119,12 @@ export default {
|
||||
},
|
||||
|
||||
setOpen(telemetry) {
|
||||
const openCount = config.get(ConfigKeys.OpenCount);
|
||||
const openCount = fyo.config.get(ConfigKeys.OpenCount);
|
||||
this.shouldOpen = !this.getIsSet(telemetry) && openCount >= 4;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const telemetry = config.get(ConfigKeys.Telemetry);
|
||||
const telemetry = fyo.config.get(ConfigKeys.Telemetry);
|
||||
this.setOpen(telemetry);
|
||||
this.value = telemetry;
|
||||
},
|
||||
|
@ -1,11 +1,17 @@
|
||||
import { t } from 'fyo';
|
||||
import { Fyo, t } from 'fyo';
|
||||
import { DocValueMap } from 'fyo/core/types';
|
||||
import Doc from 'fyo/model/doc';
|
||||
import { isNameAutoSet } from 'fyo/model/naming';
|
||||
import { Noun, Verb } from 'fyo/telemetry/types';
|
||||
import { FieldType, FieldTypeEnum } from 'schemas/types';
|
||||
import {
|
||||
Field,
|
||||
FieldType,
|
||||
FieldTypeEnum,
|
||||
OptionField,
|
||||
SelectOption,
|
||||
TargetField,
|
||||
} from 'schemas/types';
|
||||
import { parseCSV } from '../utils/csvParser';
|
||||
import { fyo } from './initFyo';
|
||||
|
||||
export const importable = [
|
||||
'SalesInvoice',
|
||||
@ -44,8 +50,8 @@ interface TemplateField {
|
||||
label: string;
|
||||
fieldname: string;
|
||||
required: boolean;
|
||||
doctype: string;
|
||||
options?: string[];
|
||||
schemaName: string;
|
||||
options?: SelectOption[];
|
||||
fieldtype: FieldType;
|
||||
parentField: string;
|
||||
}
|
||||
@ -59,7 +65,7 @@ function formatValue(value: string, fieldtype: FieldType): unknown {
|
||||
return new Date(value);
|
||||
case FieldTypeEnum.Currency:
|
||||
// @ts-ignore
|
||||
return frappe.pesa(value || 0);
|
||||
return this.fyo.pesa(value || 0);
|
||||
case FieldTypeEnum.Int:
|
||||
case FieldTypeEnum.Float: {
|
||||
const n = parseFloat(value);
|
||||
@ -80,33 +86,26 @@ const exclusion: Exclusion = {
|
||||
};
|
||||
|
||||
function getFilteredDocFields(
|
||||
df: string | string[]
|
||||
df: string | string[],
|
||||
fyo: Fyo
|
||||
): [TemplateField[], string[][]] {
|
||||
let doctype = df[0];
|
||||
let schemaName = df[0];
|
||||
let parentField = df[1] ?? '';
|
||||
|
||||
if (typeof df === 'string') {
|
||||
doctype = df;
|
||||
schemaName = df;
|
||||
parentField = '';
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const primaryFields: Field[] = frappe.models[doctype].fields;
|
||||
const primaryFields: Field[] = fyo.schemaMap[schemaName]?.fields ?? [];
|
||||
const fields: TemplateField[] = [];
|
||||
const tableTypes: string[][] = [];
|
||||
const exclusionFields: string[] = exclusion[doctype] ?? [];
|
||||
const exclusionFields: string[] = exclusion[schemaName] ?? [];
|
||||
|
||||
primaryFields.forEach((field) => {
|
||||
const { label, fieldtype, fieldname, readOnly, required, hidden } = field;
|
||||
|
||||
primaryFields.forEach(
|
||||
({
|
||||
label,
|
||||
fieldtype,
|
||||
childtype,
|
||||
fieldname,
|
||||
readOnly,
|
||||
required,
|
||||
hidden,
|
||||
options,
|
||||
}) => {
|
||||
if (
|
||||
!(fieldname === 'name' && !parentField) &&
|
||||
(readOnly ||
|
||||
@ -116,41 +115,46 @@ function getFilteredDocFields(
|
||||
return;
|
||||
}
|
||||
|
||||
if (fieldtype === FieldTypeEnum.Table && childtype) {
|
||||
tableTypes.push([childtype, fieldname]);
|
||||
if (fieldtype === FieldTypeEnum.Table && (field as TargetField).target) {
|
||||
tableTypes.push([(field as TargetField).target, fieldname]);
|
||||
return;
|
||||
}
|
||||
|
||||
let options: SelectOption[] = [];
|
||||
if ((field as OptionField).options !== undefined) {
|
||||
options = (field as OptionField).options;
|
||||
}
|
||||
|
||||
fields.push({
|
||||
label,
|
||||
fieldname,
|
||||
doctype,
|
||||
schemaName: schemaName,
|
||||
options,
|
||||
fieldtype,
|
||||
parentField,
|
||||
required: Boolean(required ?? false),
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return [fields, tableTypes];
|
||||
}
|
||||
|
||||
function getTemplateFields(doctype: string): TemplateField[] {
|
||||
function getTemplateFields(schemaName: string, fyo: Fyo): TemplateField[] {
|
||||
const fields: TemplateField[] = [];
|
||||
if (!doctype) {
|
||||
if (!schemaName) {
|
||||
return [];
|
||||
}
|
||||
const doctypes: string[][] = [[doctype]];
|
||||
while (doctypes.length > 0) {
|
||||
const dt = doctypes.pop();
|
||||
|
||||
const schemaNames: string[][] = [[schemaName]];
|
||||
while (schemaNames.length > 0) {
|
||||
const dt = schemaNames.pop();
|
||||
if (!dt) {
|
||||
break;
|
||||
}
|
||||
|
||||
const [templateFields, tableTypes] = getFilteredDocFields(dt);
|
||||
const [templateFields, tableTypes] = getFilteredDocFields(dt, fyo);
|
||||
fields.push(...templateFields);
|
||||
doctypes.push(...tableTypes);
|
||||
schemaNames.push(...tableTypes);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
@ -173,7 +177,7 @@ function getTemplate(templateFields: TemplateField[]): string {
|
||||
}
|
||||
|
||||
export class Importer {
|
||||
doctype: string;
|
||||
schemaName: string;
|
||||
templateFields: TemplateField[];
|
||||
map: Map;
|
||||
template: string;
|
||||
@ -186,10 +190,12 @@ export class Importer {
|
||||
shouldSubmit: boolean = false;
|
||||
labelIndex: number = -1;
|
||||
csv: string[][] = [];
|
||||
fyo: Fyo;
|
||||
|
||||
constructor(doctype: string) {
|
||||
this.doctype = doctype;
|
||||
this.templateFields = getTemplateFields(doctype);
|
||||
constructor(schemaName: string, fyo: Fyo) {
|
||||
this.schemaName = schemaName;
|
||||
this.fyo = fyo;
|
||||
this.templateFields = getTemplateFields(schemaName, this.fyo);
|
||||
this.map = getLabelFieldMap(this.templateFields);
|
||||
this.template = getTemplate(this.templateFields);
|
||||
this.assignedMap = this.assignableLabels.reduce((acc: Map, k) => {
|
||||
@ -364,7 +370,7 @@ export class Importer {
|
||||
|
||||
async importData(setLoadingStatus: LoadingStatusCallback): Promise<Status> {
|
||||
const status: Status = { success: false, names: [], message: '' };
|
||||
const shouldDeleteName = isNameAutoSet(this.doctype, fyo);
|
||||
const shouldDeleteName = isNameAutoSet(this.schemaName, this.fyo);
|
||||
const docObjs = this.getDocs();
|
||||
|
||||
let entriesMade = 0;
|
||||
@ -383,7 +389,7 @@ export class Importer {
|
||||
delete docObj[key];
|
||||
}
|
||||
|
||||
const doc: Doc = fyo.doc.getEmptyDoc(this.doctype, false);
|
||||
const doc: Doc = this.fyo.doc.getEmptyDoc(this.schemaName, false);
|
||||
try {
|
||||
await this.makeEntry(doc, docObj);
|
||||
entriesMade += 1;
|
||||
@ -391,7 +397,7 @@ export class Importer {
|
||||
} catch (err) {
|
||||
setLoadingStatus(false, entriesMade, docObjs.length);
|
||||
|
||||
fyo.telemetry.log(Verb.Imported, this.doctype as Noun, {
|
||||
this.fyo.telemetry.log(Verb.Imported, this.schemaName as Noun, {
|
||||
success: false,
|
||||
count: entriesMade,
|
||||
});
|
||||
@ -405,7 +411,7 @@ export class Importer {
|
||||
setLoadingStatus(false, entriesMade, docObjs.length);
|
||||
status.success = true;
|
||||
|
||||
fyo.telemetry.log(Verb.Imported, this.doctype as Noun, {
|
||||
this.fyo.telemetry.log(Verb.Imported, this.schemaName as Noun, {
|
||||
success: true,
|
||||
count: entriesMade,
|
||||
});
|
||||
@ -426,7 +432,7 @@ export class Importer {
|
||||
}
|
||||
|
||||
handleError(doc: Doc, err: Error, status: Status): Status {
|
||||
const messages = [t`Could not import ${this.doctype} ${doc.name!}.`];
|
||||
const messages = [t`Could not import ${this.schemaName} ${doc.name!}.`];
|
||||
|
||||
const message = err.message;
|
||||
if (message?.includes('UNIQUE constraint failed')) {
|
||||
|
@ -10,8 +10,9 @@
|
||||
const fs = require('fs/promises');
|
||||
const path = require('path');
|
||||
const fetch = require('node-fetch').default;
|
||||
const { splitCsvLine } = require('../scripts/helpers');
|
||||
import { LanguageMap } from '../utils/types';
|
||||
|
||||
import { splitCsvLine } from 'utils/translationHelpers';
|
||||
import { LanguageMap } from 'utils/types';
|
||||
|
||||
const VALENTINES_DAY = 1644796800000;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import models, { getRegionalModels } from 'models';
|
||||
import { getRegionalModels, models } from 'models';
|
||||
|
||||
export const fyo = new Fyo({ isTest: false, isElectron: true });
|
||||
|
||||
|
@ -129,9 +129,9 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import SearchBar from 'src/components/SearchBar';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { openQuickEdit } from 'src/utils';
|
||||
import { nextTick } from 'vue';
|
||||
import { handleErrorWithDialog } from '../errorHandling';
|
||||
@ -158,8 +158,8 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchAccounts() {
|
||||
this.settings = frappe.getMeta(this.doctype).treeSettings;
|
||||
const { currency } = await frappe.getSingle('AccountingSettings');
|
||||
this.settings = fyo.getMeta(this.doctype).treeSettings;
|
||||
const { currency } = await fyo.getSingle('AccountingSettings');
|
||||
this.root = {
|
||||
label: await this.settings.getRootLabel(),
|
||||
balance: 0,
|
||||
@ -191,7 +191,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async getChildren(parent = null) {
|
||||
const children = await frappe.db.getAll({
|
||||
const children = await fyo.db.getAll({
|
||||
doctype: this.doctype,
|
||||
filters: {
|
||||
parentAccount: parent,
|
||||
@ -240,7 +240,7 @@ export default {
|
||||
this.insertingAccount = true;
|
||||
|
||||
accountName = accountName.trim();
|
||||
let account = await frappe.getEmptyDoc('Account');
|
||||
let account = await fyo.getEmptyDoc('Account');
|
||||
try {
|
||||
let { name, rootType, accountType } = parentAccount;
|
||||
await account.set({
|
||||
|
@ -100,11 +100,11 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import LineChart from 'src/components/Charts/LineChart.vue';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { formatXLabels, getYMax } from 'src/utils/chart';
|
||||
import { getDatesAndPeriodicity } from 'src/utils/misc';
|
||||
import Cashflow from '../../../reports/Cashflow/Cashflow';
|
||||
import { getDatesAndPeriodicity } from './getDatesAndPeriodicity';
|
||||
import PeriodSelector from './PeriodSelector';
|
||||
|
||||
export default {
|
||||
@ -136,7 +136,7 @@ export default {
|
||||
this.data.map((d) => d[k])
|
||||
);
|
||||
const colors = ['#2490EF', '#B7BFC6'];
|
||||
const format = (value) => frappe.format(value ?? 0, 'Currency');
|
||||
const format = (value) => fyo.format(value ?? 0, 'Currency');
|
||||
const yMax = getYMax(points);
|
||||
return { points, xLabels, colors, format, yMax, formatX: formatXLabels };
|
||||
},
|
||||
@ -147,7 +147,7 @@ export default {
|
||||
this.period
|
||||
);
|
||||
|
||||
const { data, periodList } = await new Cashflow().run({
|
||||
const { data, periodList } = await new Cashflow(this.fyo).run({
|
||||
fromDate,
|
||||
toDate,
|
||||
periodicity,
|
||||
|
@ -22,7 +22,7 @@
|
||||
<div class="ml-3">{{ d.account }}</div>
|
||||
</div>
|
||||
<p class="whitespace-nowrap">
|
||||
{{ frappe.format(d.total, 'Currency') }}
|
||||
{{ fyo.format(d.total, 'Currency') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -33,7 +33,7 @@
|
||||
:offset-x="3"
|
||||
:thickness="11.5"
|
||||
:text-offset-x="6.5"
|
||||
:value-formatter="(value) => frappe.format(value, 'Currency')"
|
||||
:value-formatter="(value) => fyo.format(value, 'Currency')"
|
||||
:total-label="t`Total Spending`"
|
||||
@change="(value) => (active = value)"
|
||||
/>
|
||||
@ -50,10 +50,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import theme from 'src/theme';
|
||||
import { getDatesAndPeriodicity } from 'src/utils/misc';
|
||||
import DonutChart from '../../components/Charts/DonutChart.vue';
|
||||
import { getDatesAndPeriodicity } from './getDatesAndPeriodicity';
|
||||
import PeriodSelector from './PeriodSelector';
|
||||
import SectionHeader from './SectionHeader';
|
||||
|
||||
@ -95,7 +95,7 @@ export default {
|
||||
methods: {
|
||||
async setData() {
|
||||
const { fromDate, toDate } = await getDatesAndPeriodicity(this.period);
|
||||
let topExpenses = await frappe.db.getTopExpenses(fromDate, toDate);
|
||||
let topExpenses = await fyo.db.getTopExpenses(fromDate, toDate);
|
||||
const shades = [
|
||||
{ class: 'bg-gray-800', hex: theme.backgroundColor.gray['800'] },
|
||||
{ class: 'bg-gray-600', hex: theme.backgroundColor.gray['600'] },
|
||||
|
@ -36,7 +36,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import Dropdown from 'src/components/Dropdown';
|
||||
|
||||
export default {
|
||||
|
@ -28,11 +28,11 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import BarChart from 'src/components/Charts/BarChart.vue';
|
||||
import { formatXLabels, getYMax, getYMin } from 'src/utils/chart';
|
||||
import { getDatesAndPeriodicity } from 'src/utils/misc';
|
||||
import ProfitAndLoss from '../../../reports/ProfitAndLoss/ProfitAndLoss';
|
||||
import { getDatesAndPeriodicity } from './getDatesAndPeriodicity';
|
||||
import PeriodSelector from './PeriodSelector';
|
||||
import SectionHeader from './SectionHeader';
|
||||
|
||||
@ -58,7 +58,7 @@ export default {
|
||||
chartData() {
|
||||
const points = [this.periodList.map((p) => this.data[p])];
|
||||
const colors = [{ positive: '#2490EF', negative: '#B7BFC6' }];
|
||||
const format = (value) => frappe.format(value ?? 0, 'Currency');
|
||||
const format = (value) => fyo.format(value ?? 0, 'Currency');
|
||||
const yMax = getYMax(points);
|
||||
const yMin = getYMin(points);
|
||||
return {
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
this.period
|
||||
);
|
||||
|
||||
let pl = new ProfitAndLoss();
|
||||
let pl = new ProfitAndLoss(this.fyo);
|
||||
let res = await pl.run({
|
||||
fromDate,
|
||||
toDate,
|
||||
|
@ -29,7 +29,7 @@
|
||||
class="text-sm bold"
|
||||
:class="{ 'bg-gray-200 text-gray-200 rounded': !invoice.hasData }"
|
||||
>
|
||||
{{ frappe.format(invoice.paid, 'Currency') }}
|
||||
{{ fyo.format(invoice.paid, 'Currency') }}
|
||||
<span :class="{ 'text-gray-900': invoice.hasData }">{{
|
||||
t`Paid`
|
||||
}}</span>
|
||||
@ -38,7 +38,7 @@
|
||||
class="text-sm"
|
||||
:class="{ 'bg-gray-200 text-gray-200 rounded': !invoice.hasData }"
|
||||
>
|
||||
{{ frappe.format(invoice.unpaid, 'Currency') }}
|
||||
{{ fyo.format(invoice.unpaid, 'Currency') }}
|
||||
<span :class="{ 'text-gray-900': invoice.hasData }">{{
|
||||
t`Unpaid`
|
||||
}}</span>
|
||||
@ -68,10 +68,11 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe, { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import Button from 'src/components/Button';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { routeTo } from 'src/utils';
|
||||
import { getDatesAndPeriodicity } from './getDatesAndPeriodicity';
|
||||
import { getDatesAndPeriodicity } from 'src/utils/misc';
|
||||
import PeriodSelector from './PeriodSelector';
|
||||
import SectionHeader from './SectionHeader';
|
||||
|
||||
@ -124,7 +125,7 @@ export default {
|
||||
this.$data[d.periodKey]
|
||||
);
|
||||
|
||||
let result = await frappe.db.getTotalOutstanding(
|
||||
let result = await fyo.db.getTotalOutstanding(
|
||||
d.doctype,
|
||||
fromDate,
|
||||
toDate
|
||||
@ -142,7 +143,7 @@ export default {
|
||||
this.invoices = await Promise.all(promises);
|
||||
},
|
||||
async newInvoice(invoice) {
|
||||
let doc = await frappe.getEmptyDoc(invoice.doctype);
|
||||
let doc = await fyo.doc.getEmptyDoc(invoice.doctype);
|
||||
routeTo(`/edit/${invoice.doctype}/${doc.name}`);
|
||||
},
|
||||
},
|
||||
|
@ -70,7 +70,7 @@
|
||||
w-40
|
||||
"
|
||||
>
|
||||
<p>{{ frappe.t`Submit on Import` }}</p>
|
||||
<p>{{ t`Submit on Import` }}</p>
|
||||
<FormControl
|
||||
size="small"
|
||||
input-class="bg-gray-100"
|
||||
@ -337,7 +337,6 @@
|
||||
</template>
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import frappe from 'frappe';
|
||||
import Button from 'src/components/Button.vue';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import DropdownWithActions from 'src/components/DropdownWithActions.vue';
|
||||
@ -345,6 +344,7 @@ import FeatherIcon from 'src/components/FeatherIcon.vue';
|
||||
import HowTo from 'src/components/HowTo.vue';
|
||||
import PageHeader from 'src/components/PageHeader.vue';
|
||||
import { importable, Importer } from 'src/dataImport';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getSavePath, saveData, showMessageDialog } from 'src/utils';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
import Loading from '../components/Loading.vue';
|
||||
@ -440,7 +440,7 @@ export default {
|
||||
isSubmittable() {
|
||||
const doctype = this.importer?.doctype;
|
||||
if (doctype) {
|
||||
return frappe.models[doctype].isSubmittable ?? false;
|
||||
return fyo.models[doctype].isSubmittable ?? false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@ -450,14 +450,14 @@ export default {
|
||||
label: this.t`Import Type`,
|
||||
fieldtype: 'AutoComplete',
|
||||
placeholder: this.t`Import Type`,
|
||||
getList: () => importable.map((i) => frappe.models[i].label),
|
||||
getList: () => importable.map((i) => fyo.models[i].label),
|
||||
};
|
||||
},
|
||||
labelDoctypeMap() {
|
||||
return importable
|
||||
.map((i) => ({
|
||||
name: i,
|
||||
label: frappe.models[i].label,
|
||||
label: fyo.models[i].label,
|
||||
}))
|
||||
.reduce((acc, { name, label }) => {
|
||||
acc[label] = name;
|
||||
@ -585,7 +585,7 @@ export default {
|
||||
this.clear();
|
||||
}
|
||||
this.importType = importType;
|
||||
this.importer = new Importer(this.labelDoctypeMap[this.importType]);
|
||||
this.importer = new Importer(this.labelDoctypeMap[this.importType], fyo);
|
||||
},
|
||||
setLoadingStatus(isMakingEntries, entriesMade, totalEntries) {
|
||||
this.isMakingEntries = isMakingEntries;
|
||||
|
@ -162,10 +162,8 @@ import { ipcRenderer } from 'electron';
|
||||
import fs from 'fs';
|
||||
import { DateTime } from 'luxon';
|
||||
import LanguageSelector from 'src/components/Controls/LanguageSelector.vue';
|
||||
import config from 'src/config';
|
||||
import { connectToLocalDatabase, createNewDatabase } from 'src/initialization';
|
||||
import { DB_CONN_FAILURE, IPC_ACTIONS } from '../../utils/messages';
|
||||
import { showErrorDialog } from '../errorHandling';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
|
||||
export default {
|
||||
name: 'DatabaseSelector',
|
||||
@ -189,14 +187,17 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
setFiles() {
|
||||
this.files = config
|
||||
this.files = fyo.config
|
||||
.get('files', [])
|
||||
.filter(({ filePath }) => fs.existsSync(filePath));
|
||||
},
|
||||
async newDatabase() {
|
||||
/*
|
||||
TODO: Refactor this
|
||||
this.fileSelectedFrom = 'New File';
|
||||
let filePath = await createNewDatabase();
|
||||
this.connectToDatabase(filePath);
|
||||
*/
|
||||
},
|
||||
async existingDatabase() {
|
||||
this.fileSelectedFrom = 'Existing File';
|
||||
@ -214,6 +215,8 @@ export default {
|
||||
await this.connectToDatabase(file.filePath);
|
||||
},
|
||||
async connectToDatabase(filePath) {
|
||||
/*
|
||||
TODO: Refactor this
|
||||
if (!filePath) {
|
||||
return;
|
||||
}
|
||||
@ -235,6 +238,7 @@ export default {
|
||||
.t`Can't open database file: ${filePath}. Please create a new file.`;
|
||||
}
|
||||
await showErrorDialog(title, content);
|
||||
*/
|
||||
},
|
||||
getFileLastModified(filePath) {
|
||||
let stats = fs.statSync(filePath);
|
||||
|
@ -85,10 +85,11 @@
|
||||
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import frappe, { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import Button from 'src/components/Button';
|
||||
import Icon from 'src/components/Icon';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { openSettings, routeTo } from 'src/utils';
|
||||
import { IPC_MESSAGES } from 'utils/messages';
|
||||
import { h } from 'vue';
|
||||
@ -252,7 +253,7 @@ export default {
|
||||
};
|
||||
},
|
||||
async activated() {
|
||||
frappe.GetStarted = await frappe.getSingle('GetStarted');
|
||||
fyo.GetStarted = await fyo.getSingle('GetStarted');
|
||||
this.checkForCompletedTasks();
|
||||
},
|
||||
methods: {
|
||||
@ -292,12 +293,12 @@ export default {
|
||||
}
|
||||
},
|
||||
async checkIsOnboardingComplete() {
|
||||
if (frappe.GetStarted.onboardingComplete) {
|
||||
if (fyo.GetStarted.onboardingComplete) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const meta = await frappe.getMeta('GetStarted');
|
||||
const doc = await frappe.getSingle('GetStarted');
|
||||
const meta = await fyo.getMeta('GetStarted');
|
||||
const doc = await fyo.getSingle('GetStarted');
|
||||
const onboardingComplete = !!meta.fields
|
||||
.filter(({ fieldname }) => fieldname !== 'onboardingComplete')
|
||||
.map(({ fieldname }) => doc.get(fieldname))
|
||||
@ -305,7 +306,7 @@ export default {
|
||||
|
||||
if (onboardingComplete) {
|
||||
await this.updateChecks({ onboardingComplete });
|
||||
const systemSettings = await frappe.getSingle('SystemSettings');
|
||||
const systemSettings = await fyo.getSingle('SystemSettings');
|
||||
await systemSettings.set({ hideGetStarted: 1 });
|
||||
await systemSettings.update();
|
||||
}
|
||||
@ -318,22 +319,22 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frappe.GetStarted.itemCreated) {
|
||||
const count = await frappe.db.count('Item');
|
||||
if (!fyo.GetStarted.itemCreated) {
|
||||
const count = await fyo.db.count('Item');
|
||||
if (count > 0) {
|
||||
toUpdate.itemCreated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!frappe.GetStarted.invoiceCreated) {
|
||||
const count = await frappe.db.count('SalesInvoice');
|
||||
if (!fyo.GetStarted.invoiceCreated) {
|
||||
const count = await fyo.db.count('SalesInvoice');
|
||||
if (count > 0) {
|
||||
toUpdate.invoiceCreated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!frappe.GetStarted.customerCreated) {
|
||||
const count = frappe.db.count('Party', {
|
||||
if (!fyo.GetStarted.customerCreated) {
|
||||
const count = fyo.db.count('Party', {
|
||||
filters: { role: 'Customer' },
|
||||
});
|
||||
if (count > 0) {
|
||||
@ -341,15 +342,15 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (!frappe.GetStarted.billCreated) {
|
||||
const count = await frappe.db.count('SalesInvoice');
|
||||
if (!fyo.GetStarted.billCreated) {
|
||||
const count = await fyo.db.count('SalesInvoice');
|
||||
if (count > 0) {
|
||||
toUpdate.billCreated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!frappe.GetStarted.supplierCreated) {
|
||||
const count = frappe.db.count('Party', {
|
||||
if (!fyo.GetStarted.supplierCreated) {
|
||||
const count = fyo.db.count('Party', {
|
||||
filters: { role: 'Supplier' },
|
||||
});
|
||||
if (count > 0) {
|
||||
@ -359,15 +360,15 @@ export default {
|
||||
await this.updateChecks(toUpdate);
|
||||
},
|
||||
async updateChecks(toUpdate) {
|
||||
await frappe.GetStarted.setMultiple(toUpdate);
|
||||
await frappe.GetStarted.update();
|
||||
frappe.GetStarted = await frappe.getSingle('GetStarted');
|
||||
await fyo.GetStarted.setMultiple(toUpdate);
|
||||
await fyo.GetStarted.update();
|
||||
fyo.GetStarted = await fyo.getSingle('GetStarted');
|
||||
},
|
||||
isCompleted(item) {
|
||||
return frappe.GetStarted.get(item.fieldname) || 0;
|
||||
return fyo.GetStarted.get(item.fieldname) || 0;
|
||||
},
|
||||
getIconComponent(item) {
|
||||
let completed = frappe.GetStarted[item.fieldname] || 0;
|
||||
let completed = fyo.GetStarted[item.fieldname] || 0;
|
||||
let name = completed ? 'green-check' : item.icon;
|
||||
let size = completed ? '24' : '18';
|
||||
return {
|
||||
|
@ -153,7 +153,7 @@
|
||||
<div>{{ tax.account }}</div>
|
||||
<div>
|
||||
{{
|
||||
frappe.format(tax.amount, {
|
||||
fyo.format(tax.amount, {
|
||||
fieldtype: 'Currency',
|
||||
currency: doc.currency,
|
||||
})
|
||||
@ -198,7 +198,6 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { getInvoiceStatus } from 'models/helpers';
|
||||
import BackLink from 'src/components/BackLink';
|
||||
import Button from 'src/components/Button';
|
||||
@ -206,6 +205,7 @@ import FormControl from 'src/components/Controls/FormControl';
|
||||
import DropdownWithActions from 'src/components/DropdownWithActions';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import StatusBadge from 'src/components/StatusBadge';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import {
|
||||
getActionsForDocument,
|
||||
openSettings,
|
||||
@ -242,7 +242,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta(this.doctype);
|
||||
return fyo.getMeta(this.doctype);
|
||||
},
|
||||
partyField() {
|
||||
let fieldname = {
|
||||
@ -263,18 +263,18 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
try {
|
||||
this.doc = await frappe.doc.getDoc(this.doctype, this.name);
|
||||
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
|
||||
window.d = this.doc;
|
||||
} catch (error) {
|
||||
if (error instanceof frappe.errors.NotFoundError) {
|
||||
if (error instanceof fyo.errors.NotFoundError) {
|
||||
routeTo(`/list/${this.doctype}`);
|
||||
return;
|
||||
}
|
||||
this.handleError(error);
|
||||
}
|
||||
this.printSettings = await frappe.getSingle('PrintSettings');
|
||||
this.printSettings = await fyo.getSingle('PrintSettings');
|
||||
this.companyName = (
|
||||
await frappe.getSingle('AccountingSettings')
|
||||
await fyo.getSingle('AccountingSettings')
|
||||
).companyName;
|
||||
|
||||
let query = this.$route.query;
|
||||
@ -327,7 +327,7 @@ export default {
|
||||
doc = this.doc;
|
||||
}
|
||||
let df = doc.meta.getField(fieldname);
|
||||
return frappe.format(doc[fieldname], df, doc);
|
||||
return fyo.format(doc[fieldname], df, doc);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -128,13 +128,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import BackLink from 'src/components/BackLink';
|
||||
import Button from 'src/components/Button';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import DropdownWithActions from 'src/components/DropdownWithActions';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import StatusBadge from 'src/components/StatusBadge';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getActionsForDocument, routeTo, showMessageDialog } from 'src/utils';
|
||||
import { handleErrorWithDialog } from '../errorHandling';
|
||||
|
||||
@ -163,7 +163,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta(this.doctype);
|
||||
return fyo.getMeta(this.doctype);
|
||||
},
|
||||
status() {
|
||||
if (this.doc._notInserted || !this.doc.submitted) {
|
||||
@ -177,14 +177,14 @@ export default {
|
||||
if (this.doc.accounts) {
|
||||
value = this.doc.getSum('accounts', 'debit');
|
||||
}
|
||||
return frappe.format(value, 'Currency');
|
||||
return fyo.format(value, 'Currency');
|
||||
},
|
||||
totalCredit() {
|
||||
let value = 0;
|
||||
if (this.doc.accounts) {
|
||||
value = this.doc.getSum('accounts', 'credit');
|
||||
}
|
||||
return frappe.format(value, 'Currency');
|
||||
return fyo.format(value, 'Currency');
|
||||
},
|
||||
actions() {
|
||||
return getActionsForDocument(this.doc);
|
||||
@ -192,10 +192,10 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
try {
|
||||
this.doc = await frappe.doc.getDoc(this.doctype, this.name);
|
||||
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
|
||||
window.je = this.doc;
|
||||
} catch (error) {
|
||||
if (error instanceof frappe.errors.NotFoundError) {
|
||||
if (error instanceof fyo.errors.NotFoundError) {
|
||||
routeTo(`/list/${this.doctype}`);
|
||||
return;
|
||||
}
|
||||
|
@ -56,11 +56,11 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import Avatar from 'src/components/Avatar';
|
||||
import Button from 'src/components/Button';
|
||||
import Row from 'src/components/Row';
|
||||
import { openQuickEdit, routeTo } from 'src/utils';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { openQuickEdit, routeTo } from 'src/utils/ui';
|
||||
import ListCell from './ListCell';
|
||||
|
||||
export default {
|
||||
@ -90,7 +90,7 @@ export default {
|
||||
return this.prepareColumns();
|
||||
},
|
||||
meta() {
|
||||
return frappe.getMeta(this.listConfig.doctype);
|
||||
return fyo.getMeta(this.listConfig.doctype);
|
||||
},
|
||||
hasImage() {
|
||||
return this.meta.hasField('image');
|
||||
@ -98,7 +98,7 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
await this.setupColumnsAndData();
|
||||
frappe.db.on(`change:${this.listConfig.doctype}`, () => {
|
||||
fyo.db.on(`change:${this.listConfig.doctype}`, () => {
|
||||
this.updateData();
|
||||
});
|
||||
},
|
||||
@ -119,7 +119,7 @@ export default {
|
||||
},
|
||||
async updateData(filters) {
|
||||
if (!filters) filters = this.getFilters();
|
||||
this.data = await frappe.db.getAll({
|
||||
this.data = await fyo.db.getAll({
|
||||
doctype: this.doctype,
|
||||
fields: ['*'],
|
||||
filters,
|
||||
|
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
export default {
|
||||
name: 'ListCell',
|
||||
@ -14,7 +14,7 @@ export default {
|
||||
columnValue() {
|
||||
let { column, doc } = this;
|
||||
let value = doc[column.fieldname];
|
||||
return frappe.format(value, column, doc);
|
||||
return fyo.format(value, column, doc);
|
||||
},
|
||||
customRenderer() {
|
||||
if (!this.column.render) return;
|
||||
@ -24,7 +24,7 @@ export default {
|
||||
return ['Int', 'Float', 'Currency'].includes(this.column.fieldtype)
|
||||
? 'justify-end'
|
||||
: '';
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -30,11 +30,11 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'fyo';
|
||||
import Button from 'src/components/Button';
|
||||
import FilterDropdown from 'src/components/FilterDropdown';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import SearchBar from 'src/components/SearchBar';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { routeTo } from 'src/utils';
|
||||
import List from './List';
|
||||
|
||||
@ -63,7 +63,7 @@ export default {
|
||||
methods: {
|
||||
async makeNewDoc() {
|
||||
const doctype = this.listConfig.doctype;
|
||||
const doc = await frappe.getEmptyDoc(doctype);
|
||||
const doc = await fyo.doc.getEmptyDoc(doctype);
|
||||
if (this.listConfig.filters) {
|
||||
doc.set(this.listConfig.filters);
|
||||
}
|
||||
@ -104,9 +104,6 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta(this.doctype);
|
||||
},
|
||||
listConfig() {
|
||||
if (this?.listConfigs?.[this?.doctype]) {
|
||||
return this.listConfigs[this.doctype];
|
||||
@ -114,7 +111,7 @@ export default {
|
||||
return {
|
||||
title: this.doctype,
|
||||
doctype: this.doctype,
|
||||
columns: this.meta.getKeywordFields(),
|
||||
columns: fyo.schemaMap[this.doctype].keywordFields ?? ['name'],
|
||||
};
|
||||
}
|
||||
},
|
||||
|
@ -52,14 +52,12 @@
|
||||
</template>
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import frappe from 'fyo';
|
||||
import { Verb } from 'fyo/telemetry/types';
|
||||
import BackLink from 'src/components/BackLink';
|
||||
import Button from 'src/components/Button';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import SearchBar from 'src/components/SearchBar';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import telemetry from 'src/telemetry/telemetry';
|
||||
import { Verb } from 'src/telemetry/types';
|
||||
import { makePDF } from 'src/utils';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
|
||||
@ -81,12 +79,12 @@ export default {
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.doc = await frappe.doc.getDoc(this.doctype, this.name);
|
||||
this.printSettings = await frappe.getSingle('PrintSettings');
|
||||
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
|
||||
this.printSettings = await fyo.getSingle('PrintSettings');
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta(this.doctype);
|
||||
return fyo.getMeta(this.doctype);
|
||||
},
|
||||
printTemplate() {
|
||||
return this.meta.printTemplate;
|
||||
@ -98,7 +96,7 @@ export default {
|
||||
if (!savePath) return;
|
||||
|
||||
const html = this.$refs.printContainer.innerHTML;
|
||||
telemetry.log(Verb.Exported, 'SalesInvoice', { extension: 'pdf' });
|
||||
fyo.telemetry.log(Verb.Exported, 'SalesInvoice', { extension: 'pdf' });
|
||||
makePDF(html, savePath);
|
||||
},
|
||||
async getSavePath() {
|
||||
|
@ -77,12 +77,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe, { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import Button from 'src/components/Button';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import DropdownWithActions from 'src/components/DropdownWithActions';
|
||||
import StatusBadge from 'src/components/StatusBadge';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getActionsForDocument, openQuickEdit } from 'src/utils';
|
||||
|
||||
export default {
|
||||
@ -126,7 +127,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta(this.doctype);
|
||||
return fyo.getMeta(this.doctype);
|
||||
},
|
||||
status() {
|
||||
if (this.doc && this.doc._notInserted) {
|
||||
@ -186,7 +187,7 @@ export default {
|
||||
},
|
||||
async fetchDoc() {
|
||||
try {
|
||||
this.doc = await frappe.doc.getDoc(this.doctype, this.name);
|
||||
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
|
||||
|
||||
this.doc.once('afterRename', () => {
|
||||
openQuickEdit({
|
||||
|
@ -136,18 +136,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import reportViewConfig from 'src/../reports/view';
|
||||
import { getReportData } from 'reports/index';
|
||||
import reportViewConfig from 'reports/view';
|
||||
import Button from 'src/components/Button';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import DropdownWithActions from 'src/components/DropdownWithActions.vue';
|
||||
import FeatherIcon from 'src/components/FeatherIcon.vue';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import Row from 'src/components/Row';
|
||||
import SearchBar from 'src/components/SearchBar';
|
||||
import WithScroll from 'src/components/WithScroll';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { h, markRaw } from 'vue';
|
||||
import { getReportData } from '../../reports/index';
|
||||
import DropdownWithActions from '../components/DropdownWithActions.vue';
|
||||
|
||||
export default {
|
||||
name: 'Report',
|
||||
@ -296,7 +296,7 @@ export default {
|
||||
// default cell component
|
||||
let formattedValue =
|
||||
cellValue != null && cellValue !== ''
|
||||
? frappe.format(cellValue, column)
|
||||
? fyo.format(cellValue, column)
|
||||
: '';
|
||||
return {
|
||||
render() {
|
||||
|
@ -1,6 +1,4 @@
|
||||
<template>
|
||||
|
||||
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<PageHeader>
|
||||
<template #title>
|
||||
@ -52,16 +50,16 @@
|
||||
</template>
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import frappe, { t } from 'fyo';
|
||||
import { t } from 'fyo';
|
||||
import Button from 'src/components/Button';
|
||||
import Icon from 'src/components/Icon';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import Row from 'src/components/Row';
|
||||
import StatusBadge from 'src/components/StatusBadge';
|
||||
import WindowControls from 'src/components/WindowControls';
|
||||
import { showToast } from 'src/utils/ui';
|
||||
import { IPC_MESSAGES } from 'utils/messages';
|
||||
import { h, markRaw } from 'vue';
|
||||
import { callInitializeMoneyMaker, showToast } from '../../utils';
|
||||
import TabGeneral from './TabGeneral.vue';
|
||||
import TabInvoice from './TabInvoice.vue';
|
||||
import TabSystem from './TabSystem.vue';
|
||||
@ -113,23 +111,20 @@ export default {
|
||||
|
||||
if (
|
||||
fieldnames.includes('displayPrecision') ||
|
||||
fieldnames.includes('hideGetStarted')
|
||||
fieldnames.includes('hideGetStarted') ||
|
||||
fieldnames.includes('displayPrecision')
|
||||
) {
|
||||
this.showReloadToast();
|
||||
}
|
||||
|
||||
if (fieldnames.includes('displayPrecision')) {
|
||||
callInitializeMoneyMaker(undefined, true);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showReloadToast() {
|
||||
showToast({
|
||||
message: t`Settings changes will be visible on reload`,
|
||||
actionText: frappe.t`Reload App`,
|
||||
actionText: t`Reload App`,
|
||||
type: 'info',
|
||||
action: async () => {
|
||||
ipcRenderer.send(IPC_MESSAGES.RELOAD_MAIN_WINDOW)
|
||||
ipcRenderer.send(IPC_MESSAGES.RELOAD_MAIN_WINDOW);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
@ -12,8 +12,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'fyo';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
export default {
|
||||
name: 'TabGeneral',
|
||||
@ -27,13 +27,16 @@ export default {
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.doc = await frappe.doc.getDoc('AccountingSettings', 'AccountingSettings', {
|
||||
this.doc = await fyo.doc.getDoc(
|
||||
'AccountingSettings',
|
||||
'AccountingSettings',
|
||||
{
|
||||
skipDocumentCache: true,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
let meta = frappe.getMeta('AccountingSettings');
|
||||
return [
|
||||
'companyName',
|
||||
'country',
|
||||
@ -44,7 +47,7 @@ export default {
|
||||
'fiscalYearStart',
|
||||
'fiscalYearEnd',
|
||||
'gstin',
|
||||
].map((fieldname) => meta.getField(fieldname));
|
||||
].map((fieldname) => fyo.getField('AccountingSettings', fieldname));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -2,13 +2,13 @@
|
||||
<div v-if="doc">
|
||||
<div class="flex items-center">
|
||||
<FormControl
|
||||
:df="meta.getField('logo')"
|
||||
:df="getField('logo')"
|
||||
:value="doc.logo"
|
||||
@change="
|
||||
(value) => {
|
||||
doc.set('logo', value);
|
||||
doc.update();
|
||||
forwardChangeEvent(meta.getField('logo'));
|
||||
forwardChangeEvent(getField('logo'));
|
||||
}
|
||||
"
|
||||
/>
|
||||
@ -21,14 +21,14 @@
|
||||
</span>
|
||||
<FormControl
|
||||
class="mt-2"
|
||||
:df="meta.getField('displayLogo')"
|
||||
:df="getField('displayLogo')"
|
||||
:value="doc.displayLogo"
|
||||
:show-label="true"
|
||||
@change="
|
||||
(value) => {
|
||||
doc.set('displayLogo', value);
|
||||
doc.update();
|
||||
forwardChangeEvent(meta.getField('displayLogo'));
|
||||
forwardChangeEvent(getField('displayLogo'));
|
||||
}
|
||||
"
|
||||
size="small"
|
||||
@ -47,9 +47,9 @@
|
||||
</template>
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import frappe from 'fyo';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
|
||||
export default {
|
||||
@ -73,25 +73,25 @@ export default {
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.doc = await frappe.getSingle('PrintSettings');
|
||||
this.doc = await fyo.doc.getSingle('PrintSettings');
|
||||
this.companyName = (
|
||||
await frappe.getSingle('AccountingSettings')
|
||||
await fyo.doc.getSingle('AccountingSettings')
|
||||
).companyName;
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta('PrintSettings');
|
||||
},
|
||||
fields() {
|
||||
return ['template', 'color', 'font', 'email', 'phone', 'address'].map(
|
||||
(field) => this.meta.getField(field)
|
||||
(field) => this.getField(field)
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getField(fieldname) {
|
||||
return fyo.getField('PrintSettings', fieldname);
|
||||
},
|
||||
async openFileSelector() {
|
||||
const options = {
|
||||
title: frappe.t`Select Logo`,
|
||||
title: t`Select Logo`,
|
||||
properties: ['openFile'],
|
||||
filters: [{ name: 'Invoice Logo', extensions: ['png', 'jpg', 'svg'] }],
|
||||
};
|
||||
|
@ -38,16 +38,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import frappe from 'fyo';
|
||||
import { ConfigKeys } from 'fyo/core/types';
|
||||
import { getTelemetryOptions } from 'fyo/telemetry/helpers';
|
||||
import { TelemetrySetting } from 'fyo/telemetry/types';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import LanguageSelector from 'src/components/Controls/LanguageSelector.vue';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import config, {
|
||||
ConfigKeys,
|
||||
TelemetrySetting
|
||||
} from 'src/config';
|
||||
import { getTelemetryOptions } from 'src/telemetry/helpers';
|
||||
import telemetry from 'src/telemetry/telemetry';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { checkForUpdates } from 'src/utils';
|
||||
|
||||
export default {
|
||||
@ -65,9 +62,9 @@ export default {
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.doc = frappe.SystemSettings;
|
||||
this.companyName = frappe.AccountingSettings.companyName;
|
||||
this.telemetry = config.get(ConfigKeys.Telemetry);
|
||||
this.doc = fyo.singles.SystemSettings;
|
||||
this.companyName = fyo.singles.AccountingSettings.companyName;
|
||||
this.telemetry = fyo.config.get(ConfigKeys.Telemetry);
|
||||
},
|
||||
computed: {
|
||||
df() {
|
||||
@ -84,7 +81,7 @@ export default {
|
||||
};
|
||||
},
|
||||
fields() {
|
||||
let meta = frappe.getMeta('SystemSettings');
|
||||
let meta = fyo.getMeta('SystemSettings');
|
||||
return meta.getQuickEditFields();
|
||||
},
|
||||
},
|
||||
@ -93,12 +90,12 @@ export default {
|
||||
setValue(value) {
|
||||
this.telemetry = value;
|
||||
if (value === TelemetrySetting.dontLogAnything) {
|
||||
telemetry.finalLogAndStop();
|
||||
fyo.telemetry.finalLogAndStop();
|
||||
} else {
|
||||
telemetry.log(Verb.Started, NounEnum.Telemetry);
|
||||
fyo.telemetry.log(Verb.Started, NounEnum.Telemetry);
|
||||
}
|
||||
|
||||
config.set(ConfigKeys.Telemetry, value);
|
||||
fyo.config.set(ConfigKeys.Telemetry, value);
|
||||
},
|
||||
forwardChangeEvent(...args) {
|
||||
this.$emit('change', ...args);
|
||||
|
@ -91,14 +91,14 @@
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
import fs from 'fs';
|
||||
import frappe from 'fyo';
|
||||
import path from 'path';
|
||||
import FormControl from 'src/components/Controls/FormControl';
|
||||
import LanguageSelector from 'src/components/Controls/LanguageSelector.vue';
|
||||
import Popover from 'src/components/Popover';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import config from 'src/config';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { connectToLocalDatabase, purgeCache } from 'src/initialization';
|
||||
import { setupInstance } from 'src/setup/setupInstance';
|
||||
import { setLanguageMap, showMessageDialog } from 'src/utils';
|
||||
import { IPC_MESSAGES } from 'utils/messages';
|
||||
import {
|
||||
@ -106,7 +106,6 @@ getErrorMessage,
|
||||
handleErrorWithDialog,
|
||||
showErrorDialog
|
||||
} from '../../errorHandling';
|
||||
import setupCompany from './setupCompany';
|
||||
import Slide from './Slide.vue';
|
||||
|
||||
export default {
|
||||
@ -135,11 +134,11 @@ export default {
|
||||
LanguageSelector,
|
||||
},
|
||||
async mounted() {
|
||||
if (config.get('language') !== undefined) {
|
||||
if (fyo.config.get('language') !== undefined) {
|
||||
this.index = 1;
|
||||
}
|
||||
|
||||
this.doc = await frappe.doc.getNewDoc('SetupWizard');
|
||||
this.doc = await fyo.doc.getNewDoc('SetupWizard');
|
||||
this.doc.on('change', () => {
|
||||
this.valuesFilled = this.allValuesFilled();
|
||||
});
|
||||
@ -192,11 +191,11 @@ export default {
|
||||
|
||||
try {
|
||||
this.loading = true;
|
||||
await setupCompany(this.doc);
|
||||
await setupInstance(this.doc);
|
||||
this.$emit('setup-complete');
|
||||
} catch (e) {
|
||||
this.loading = false;
|
||||
if (e.type === frappe.errors.DuplicateEntryError) {
|
||||
if (e.type === fyo.errors.DuplicateEntryError) {
|
||||
console.log(e);
|
||||
console.log('retrying');
|
||||
await this.renameDbFileAndRerunSetup();
|
||||
@ -206,7 +205,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async renameDbFileAndRerunSetup() {
|
||||
const filePath = config.get('lastSelectedFilePath');
|
||||
const filePath = fyo.config.get('lastSelectedFilePath');
|
||||
renameDbFile(filePath);
|
||||
|
||||
await purgeCache();
|
||||
@ -216,7 +215,7 @@ export default {
|
||||
);
|
||||
|
||||
if (connectionSuccess) {
|
||||
await setupCompany(this.doc);
|
||||
await setupInstance(this.doc);
|
||||
this.$emit('setup-complete');
|
||||
} else {
|
||||
const title = this.t`DB Connection Error`;
|
||||
@ -227,7 +226,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
meta() {
|
||||
return frappe.getMeta('SetupWizard');
|
||||
return fyo.getMeta('SetupWizard');
|
||||
},
|
||||
fields() {
|
||||
return this.meta.getQuickEditFields();
|
||||
|
@ -3,7 +3,7 @@ import { DEFAULT_SERIES_START } from 'fyo/utils/consts';
|
||||
import { getValueMapFromList } from 'utils';
|
||||
import { fyo } from './initFyo';
|
||||
|
||||
export default async function postStart() {
|
||||
export async function postStart() {
|
||||
await createDefaultNumberSeries();
|
||||
await setSingles();
|
||||
await setCurrencySymbols();
|
||||
|
@ -101,8 +101,6 @@ function setErrorHandlers(app: VueApp) {
|
||||
|
||||
function setOnWindow() {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// @ts-ignore
|
||||
window.config = config;
|
||||
// @ts-ignore
|
||||
window.router = router;
|
||||
// @ts-ignore
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { NounEnum, Verb } from 'fyo/telemetry/types';
|
||||
import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
|
||||
import Dashboard from 'src/pages/Dashboard/Dashboard.vue';
|
||||
import DataImport from 'src/pages/DataImport.vue';
|
||||
import GetStarted from 'src/pages/GetStarted.vue';
|
||||
import InvoiceForm from 'src/pages/InvoiceForm.vue';
|
||||
import JournalEntryForm from 'src/pages/JournalEntryForm.vue';
|
||||
import ListView from 'src/pages/ListView/ListView.vue';
|
||||
import PrintView from 'src/pages/PrintView/PrintView.vue';
|
||||
import QuickEditForm from 'src/pages/QuickEditForm.vue';
|
||||
import Report from 'src/pages/Report.vue';
|
||||
import Settings from 'src/pages/Settings/Settings.vue';
|
||||
// import GetStarted from 'src/pages/GetStarted.vue';
|
||||
// import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
|
||||
// import DataImport from 'src/pages/DataImport.vue';
|
||||
// import InvoiceForm from 'src/pages/InvoiceForm.vue';
|
||||
// import JournalEntryForm from 'src/pages/JournalEntryForm.vue';
|
||||
// import ListView from 'src/pages/ListView/ListView.vue';
|
||||
// import PrintView from 'src/pages/PrintView/PrintView.vue';
|
||||
// import QuickEditForm from 'src/pages/QuickEditForm.vue';
|
||||
// import Report from 'src/pages/Report.vue';
|
||||
// import Settings from 'src/pages/Settings/Settings.vue';
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
|
||||
import { fyo } from './initFyo';
|
||||
|
||||
@ -18,6 +18,7 @@ const routes: RouteRecordRaw[] = [
|
||||
path: '/',
|
||||
component: Dashboard,
|
||||
},
|
||||
/*
|
||||
{
|
||||
path: '/get-started',
|
||||
component: GetStarted,
|
||||
@ -113,6 +114,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: Settings,
|
||||
props: true,
|
||||
},
|
||||
*/
|
||||
];
|
||||
|
||||
const router = createRouter({ routes, history: createWebHistory() });
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BrowserWindow } from 'electron';
|
||||
import { sleep } from 'frappe/utils';
|
||||
import fs from 'fs/promises';
|
||||
import { sleep } from 'utils';
|
||||
|
||||
const PRINT_OPTIONS = {
|
||||
marginsType: 1, // no margin
|
||||
|
@ -246,7 +246,7 @@ export function getActionsForDocument(doc?: Doc): Action[] {
|
||||
if (!doc) return [];
|
||||
|
||||
const actions: Action[] = [
|
||||
...getActions(doc, fyo),
|
||||
...getActions(doc),
|
||||
getDuplicateAction(doc),
|
||||
getDeleteAction(doc),
|
||||
getCancelAction(doc),
|
||||
|
@ -12,15 +12,18 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": ["webpack-env"],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"src/*": ["src/*"],
|
||||
"schemas/*": ["schemas/*"],
|
||||
"main/*": ["main/*"],
|
||||
"backend/*": ["backend/*"],
|
||||
"regional/*": ["regional/*"],
|
||||
"fixtures/*": ["fixtures/*"],
|
||||
"utils/*": ["utils/*"]
|
||||
"reports/*": ["reports/*"],
|
||||
"models/*": ["models/*"],
|
||||
"utils/*": ["utils/*"],
|
||||
},
|
||||
"lib": ["esnext", "dom", "dom.iterable", "scripthost"]
|
||||
},
|
||||
@ -29,23 +32,20 @@
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
|
||||
"schemas/**/*.ts",
|
||||
"backend/**/*.ts",
|
||||
|
||||
"fyo/**/*.ts",
|
||||
"models/**/*.ts",
|
||||
"patches/**/*.ts",
|
||||
"patches/**/*.js",
|
||||
"reports/**/*.ts",
|
||||
"accounting/**/*.ts",
|
||||
"accounting/**/*.ts",
|
||||
|
||||
"scripts/**/*.ts",
|
||||
"utils/csvParser.ts",
|
||||
"utils/config.ts"
|
||||
"main/**/*.ts",
|
||||
"regional/**/*.ts",
|
||||
"reports/**/*.ts",
|
||||
"utils/**/*.ts",
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
@ -13,10 +13,12 @@ module.exports = {
|
||||
chainWebpackRendererProcess: (config) => {
|
||||
config.target('electron-renderer');
|
||||
config.resolve.alias.set('fyo', path.resolve(__dirname, './fyo'));
|
||||
config.resolve.alias.set('utils', path.resolve(__dirname, './utils'));
|
||||
},
|
||||
chainWebpackMainProcess: (config) => {
|
||||
config.target('electron-main');
|
||||
config.resolve.alias.set('fyo', path.resolve(__dirname, './fyo'));
|
||||
config.resolve.alias.set('utils', path.resolve(__dirname, './utils'));
|
||||
config.module
|
||||
.rule('js')
|
||||
.test(/\.js$/)
|
||||
@ -43,8 +45,10 @@ module.exports = {
|
||||
src: path.resolve(__dirname, './src'),
|
||||
schemas: path.resolve(__dirname, './schemas'),
|
||||
backend: path.resolve(__dirname, './backend'),
|
||||
models: path.resolve(__dirname, './models'),
|
||||
utils: path.resolve(__dirname, './utils'),
|
||||
regional: path.resolve(__dirname, './regional'),
|
||||
reports: path.resolve(__dirname, './reports'),
|
||||
fixtures: path.resolve(__dirname, './fixtures'),
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user