mirror of
https://github.com/frappe/books.git
synced 2025-01-22 14:48:25 +00:00
incr: type renderer
- move setup logic outside components, type it
This commit is contained in:
parent
c56850d08f
commit
835deb4ce8
@ -1,78 +0,0 @@
|
||||
import frappe from 'fyo';
|
||||
import standardCOA from '../fixtures/verified/standardCOA.json';
|
||||
import { getCOAList } from '../src/utils';
|
||||
const accountFields = ['accountType', 'accountNumber', 'rootType', 'isGroup'];
|
||||
|
||||
function getAccountName(accountName, accountNumber) {
|
||||
if (accountNumber) {
|
||||
return `${accountName} - ${accountNumber}`;
|
||||
}
|
||||
return accountName;
|
||||
}
|
||||
|
||||
async function importAccounts(children, parentAccount, rootType, rootAccount) {
|
||||
for (let rootName in children) {
|
||||
if (accountFields.includes(rootName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const child = children[rootName];
|
||||
|
||||
if (rootAccount) {
|
||||
rootType = child.rootType;
|
||||
}
|
||||
|
||||
const { accountType, accountNumber } = child;
|
||||
const accountName = getAccountName(rootName, accountNumber);
|
||||
const isGroup = identifyIsGroup(child);
|
||||
const doc = frappe.doc.getNewDoc('Account', {
|
||||
name: accountName,
|
||||
parentAccount,
|
||||
isGroup,
|
||||
rootType,
|
||||
balance: 0,
|
||||
accountType,
|
||||
});
|
||||
|
||||
await doc.insert();
|
||||
await importAccounts(child, accountName, rootType);
|
||||
}
|
||||
}
|
||||
|
||||
function identifyIsGroup(child) {
|
||||
if (child.isGroup) {
|
||||
return child.isGroup;
|
||||
}
|
||||
|
||||
const keys = Object.keys(child);
|
||||
const children = keys.filter((key) => !accountFields.includes(key));
|
||||
|
||||
if (children.length) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export async function getCountryCOA(chartOfAccounts) {
|
||||
const coaList = getCOAList();
|
||||
const coa = coaList.find(({ name }) => name === chartOfAccounts);
|
||||
const conCode = coa.countryCode;
|
||||
if (!conCode) {
|
||||
return standardCOA;
|
||||
}
|
||||
|
||||
try {
|
||||
const countryCoa = (
|
||||
await import('../fixtures/verified/' + conCode + '.json')
|
||||
).default;
|
||||
return countryCoa.tree;
|
||||
} catch (e) {
|
||||
return standardCOA;
|
||||
}
|
||||
}
|
||||
|
||||
export default async function importCharts(chartOfAccounts) {
|
||||
const chart = await getCountryCOA(chartOfAccounts);
|
||||
await importAccounts(chart, '', '', true);
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
import { t } from 'fyo';
|
||||
|
||||
export default {
|
||||
[t`Application of Funds (Assets)`]: {
|
||||
[t`Current Assets`]: {
|
||||
[t`Accounts Receivable`]: {
|
||||
[t`Debtors`]: {
|
||||
accountType: 'Receivable',
|
||||
},
|
||||
},
|
||||
[t`Bank Accounts`]: {
|
||||
accountType: 'Bank',
|
||||
isGroup: 1,
|
||||
},
|
||||
[t`Cash In Hand`]: {
|
||||
[t`Cash`]: {
|
||||
accountType: 'Cash',
|
||||
},
|
||||
accountType: 'Cash',
|
||||
},
|
||||
[t`Loans and Advances (Assets)`]: {
|
||||
isGroup: 1,
|
||||
},
|
||||
[t`Securities and Deposits`]: {
|
||||
[t`Earnest Money`]: {},
|
||||
},
|
||||
[t`Stock Assets`]: {
|
||||
[t`Stock In Hand`]: {
|
||||
accountType: 'Stock',
|
||||
},
|
||||
accountType: 'Stock',
|
||||
},
|
||||
[t`Tax Assets`]: {
|
||||
isGroup: 1,
|
||||
},
|
||||
},
|
||||
[t`Fixed Assets`]: {
|
||||
[t`Capital Equipments`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Electronic Equipments`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Furnitures and Fixtures`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Office Equipments`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Plants and Machineries`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Buildings`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Softwares`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Accumulated Depreciation`]: {
|
||||
accountType: 'Accumulated Depreciation',
|
||||
},
|
||||
},
|
||||
[t`Investments`]: {
|
||||
isGroup: 1,
|
||||
},
|
||||
[t`Temporary Accounts`]: {
|
||||
[t`Temporary Opening`]: {
|
||||
accountType: 'Temporary',
|
||||
},
|
||||
},
|
||||
rootType: 'Asset',
|
||||
},
|
||||
[t`Expenses`]: {
|
||||
[t`Direct Expenses`]: {
|
||||
[t`Stock Expenses`]: {
|
||||
[t`Cost of Goods Sold`]: {
|
||||
accountType: 'Cost of Goods Sold',
|
||||
},
|
||||
[t`Expenses Included In Valuation`]: {
|
||||
accountType: 'Expenses Included In Valuation',
|
||||
},
|
||||
[t`Stock Adjustment`]: {
|
||||
accountType: 'Stock Adjustment',
|
||||
},
|
||||
},
|
||||
},
|
||||
[t`Indirect Expenses`]: {
|
||||
[t`Administrative Expenses`]: {},
|
||||
[t`Commission on Sales`]: {},
|
||||
[t`Depreciation`]: {
|
||||
accountType: 'Depreciation',
|
||||
},
|
||||
[t`Entertainment Expenses`]: {},
|
||||
[t`Freight and Forwarding Charges`]: {
|
||||
accountType: 'Chargeable',
|
||||
},
|
||||
[t`Legal Expenses`]: {},
|
||||
[t`Marketing Expenses`]: {
|
||||
accountType: 'Chargeable',
|
||||
},
|
||||
[t`Miscellaneous Expenses`]: {
|
||||
accountType: 'Chargeable',
|
||||
},
|
||||
[t`Office Maintenance Expenses`]: {},
|
||||
[t`Office Rent`]: {},
|
||||
[t`Postal Expenses`]: {},
|
||||
[t`Print and Stationery`]: {},
|
||||
[t`Round Off`]: {
|
||||
accountType: 'Round Off',
|
||||
},
|
||||
[t`Salary`]: {},
|
||||
[t`Sales Expenses`]: {},
|
||||
[t`Telephone Expenses`]: {},
|
||||
[t`Travel Expenses`]: {},
|
||||
[t`Utility Expenses`]: {},
|
||||
[t`Write Off`]: {},
|
||||
[t`Exchange Gain/Loss`]: {},
|
||||
[t`Gain/Loss on Asset Disposal`]: {},
|
||||
},
|
||||
rootType: 'Expense',
|
||||
},
|
||||
[t`Income`]: {
|
||||
[t`Direct Income`]: {
|
||||
[t`Sales`]: {},
|
||||
[t`Service`]: {},
|
||||
},
|
||||
[t`Indirect Income`]: {
|
||||
isGroup: 1,
|
||||
},
|
||||
rootType: 'Income',
|
||||
},
|
||||
[t`Source of Funds (Liabilities)`]: {
|
||||
[t`Current Liabilities`]: {
|
||||
[t`Accounts Payable`]: {
|
||||
[t`Creditors`]: {
|
||||
accountType: 'Payable',
|
||||
},
|
||||
[t`Payroll Payable`]: {},
|
||||
},
|
||||
[t`Stock Liabilities`]: {
|
||||
[t`Stock Received But Not Billed`]: {
|
||||
accountType: 'Stock Received But Not Billed',
|
||||
},
|
||||
},
|
||||
[t`Duties and Taxes`]: {
|
||||
accountType: 'Tax',
|
||||
isGroup: 1,
|
||||
},
|
||||
[t`Loans (Liabilities)`]: {
|
||||
[t`Secured Loans`]: {},
|
||||
[t`Unsecured Loans`]: {},
|
||||
[t`Bank Overdraft Account`]: {},
|
||||
},
|
||||
},
|
||||
rootType: 'Liability',
|
||||
},
|
||||
[t`Equity`]: {
|
||||
[t`Capital Stock`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
[t`Dividends Paid`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
[t`Opening Balance Equity`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
[t`Retained Earnings`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
rootType: 'Equity',
|
||||
},
|
||||
};
|
@ -386,7 +386,7 @@
|
||||
},
|
||||
"Duties and Taxes": {
|
||||
"accountType": "Tax",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Reservations & Credit Notes": {
|
||||
"Credit Notes": {
|
||||
|
@ -11,7 +11,7 @@
|
||||
},
|
||||
"Banque": {
|
||||
"accountType": "Bank",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Comptes \u00e0 recevoir": {
|
||||
"Comptes clients": {
|
||||
@ -20,7 +20,7 @@
|
||||
"Provision pour cr\u00e9ances douteuses": {}
|
||||
},
|
||||
"Encaisse": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Frais pay\u00e9s d\u2019avance": {
|
||||
"Assurances pay\u00e9s d'avance": {},
|
||||
@ -29,7 +29,7 @@
|
||||
},
|
||||
"Petite caisse": {
|
||||
"accountType": "Cash",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Stocks": {
|
||||
"Mati\u00e8res premi\u00e8res": {},
|
||||
@ -175,7 +175,7 @@
|
||||
"Loyer - b\u00e2timent": {},
|
||||
"Loyer - entrep\u00f4t": {},
|
||||
"Op\u00e9rations indirectes de la main-d\u2019\u0153uvre directe": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"R\u00e9parations et entretien - b\u00e2timent": {},
|
||||
"R\u00e9parations et entretien - machinerie et \u00e9quipement": {},
|
||||
|
@ -9,12 +9,12 @@
|
||||
"Animales": {
|
||||
"accountNumber": "1.5.2.1",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Plantas": {
|
||||
"accountNumber": "1.5.2.2",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.5.2",
|
||||
"accountType": "Stock"
|
||||
@ -22,7 +22,7 @@
|
||||
"Activos Biol\u00f3gicos al Costo": {
|
||||
"accountNumber": "1.5.1",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.5",
|
||||
"accountType": "Stock"
|
||||
@ -32,7 +32,7 @@
|
||||
"Cr\u00e9dito Fiscal (IVA Por Cobrar)": {
|
||||
"accountNumber": "1.1.2.1",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.1.2",
|
||||
"accountType": "Chargeable"
|
||||
@ -47,22 +47,22 @@
|
||||
"Activos Adicionales y Otros": {
|
||||
"accountNumber": "1.6.6",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Cobrables Relacionados con Impuestos": {
|
||||
"accountNumber": "1.6.2",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Contratos de Construccion": {
|
||||
"accountNumber": "1.6.4",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Costos de Montaje": {
|
||||
"accountNumber": "1.6.5",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Pagos Anticipados y Otros Activos Circulantes": {
|
||||
"Seguro Pagado Anticipadamente": {
|
||||
@ -75,7 +75,7 @@
|
||||
"Proveedores de Servicio": {
|
||||
"accountNumber": "1.6.3",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.6",
|
||||
"accountType": "Chargeable"
|
||||
@ -84,32 +84,32 @@
|
||||
"Activos Financieros Clasificados por Designaci\u00f3n": {
|
||||
"accountNumber": "1.4.6",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Activos Financieros Derivados": {
|
||||
"accountNumber": "1.4.3",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Inversion o Participaci\u00f3n Accionaria en Empresas Afiliadas": {
|
||||
"accountNumber": "1.4.1",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Inversiones Burs\u00e1tiles e Instrumentos Financieros": {
|
||||
"accountNumber": "1.4.2",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Otros Activos Financieros": {
|
||||
"accountNumber": "1.4.4",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Provisi\u00f3n por Riesgo de Cr\u00e9dito (agregado) (Contra-activo)": {
|
||||
"accountNumber": "1.4.5",
|
||||
"accountType": "Round Off",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.4",
|
||||
"accountType": "Chargeable"
|
||||
@ -117,13 +117,13 @@
|
||||
"Activos Intangibles": {
|
||||
"accountNumber": "1.3",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Caja y Equivalentes": {
|
||||
"Caja": {
|
||||
"accountNumber": "1.9.1",
|
||||
"accountType": "Cash",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Equivalentes de Efectivo (Bancos)": {
|
||||
"Bancos Internacionales": {
|
||||
@ -146,7 +146,7 @@
|
||||
"Banco Industrial": {
|
||||
"accountNumber": "1.9.2.1.1",
|
||||
"accountType": "Bank",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Banco Internacional": {
|
||||
"accountNumber": "1.9.2.1.6",
|
||||
@ -189,12 +189,12 @@
|
||||
"Inversiones a Corto Plazo": {
|
||||
"accountNumber": "1.9.3",
|
||||
"accountType": "Bank",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Otros Equivalentes de Caja y Bancos": {
|
||||
"accountNumber": "1.9.4",
|
||||
"accountType": "Cash",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.9",
|
||||
"accountType": "Bank"
|
||||
@ -203,12 +203,12 @@
|
||||
"Activos bajo Contrato": {
|
||||
"accountNumber": "1.8.2",
|
||||
"accountType": "Receivable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Ajustes": {
|
||||
"accountNumber": "1.8.4",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Otras Cuentas por Cobrar": {
|
||||
"Cuentas Por Cobrar Compa\u00f1\u00edas Afiliadas": {
|
||||
@ -241,7 +241,7 @@
|
||||
"Ventas al Cr\u00e9dito": {
|
||||
"accountNumber": "1.8.1",
|
||||
"accountType": "Receivable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.8",
|
||||
"accountType": "Receivable"
|
||||
@ -253,38 +253,38 @@
|
||||
"Art\u00edculos de Inventario Adicionales": {
|
||||
"accountNumber": "1.7.8",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Combustibles": {
|
||||
"accountNumber": "1.7.5",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Inventarios Pignorados Como Garant\u00eda de Pasivo": {
|
||||
"accountNumber": "1.7.10",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Inventarios a Valor Razonable Menos Costos de Venta": {
|
||||
"accountNumber": "1.7.11",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Materia Prima": {
|
||||
"accountNumber": "1.7.1",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Mercader\u00eda (Mercanc\u00edas)": {
|
||||
"accountNumber": "1.7.2",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Otros Inventarios": {
|
||||
"Merma o Ajuste de Inventario": {
|
||||
"accountNumber": "1.7.9.1",
|
||||
"accountType": "Stock Adjustment",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.7.9",
|
||||
"accountType": "Stock"
|
||||
@ -292,13 +292,13 @@
|
||||
"Producto Terminado": {
|
||||
"accountNumber": "1.7.7",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Repuestos": {
|
||||
"Respuestos en Transito": {
|
||||
"accountNumber": "1.7.4.0",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.7.4",
|
||||
"accountType": "Stock"
|
||||
@ -306,12 +306,12 @@
|
||||
"Suministros de Producci\u00f3n y Consumibles": {
|
||||
"accountNumber": "1.7.3",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Trabajo en Progeso": {
|
||||
"accountNumber": "1.7.6",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.7",
|
||||
"accountType": "Stock"
|
||||
@ -324,7 +324,7 @@
|
||||
"Inversion Inmobiliaria Construida": {
|
||||
"accountNumber": "1.2.2",
|
||||
"accountType": "Chargeable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1.2",
|
||||
"accountType": "Chargeable"
|
||||
|
@ -29,16 +29,16 @@
|
||||
},
|
||||
"123. \u00c9p\u00fcletek, \u00e9p\u00fcletr\u00e9szek, tulajdoni h\u00e1nyadok ": {
|
||||
"accountType": "Fixed Asset",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"124. Egy\u00e9b ingatlanok": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"125. \u00dczemk\u00f6r\u00f6n k\u00edv\u00fcli ingatlanok, \u00e9p\u00fcletek ": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"126. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"127. Ingatlanok \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {},
|
||||
"129. Kis \u00e9rt\u00e9k\u0171 ingatlanok": {}
|
||||
@ -148,7 +148,7 @@
|
||||
"239. Befejezetlen termel\u00e9s \u00e9s f\u00e9lk\u00e9sz term\u00e9kek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"24. N\u00d6VEND\u00c9K-, H\u00cdZ\u00d3- \u00c9S EGY\u00c9B \u00c1LLATOK": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"25. K\u00c9SZTERM\u00c9KEK": {
|
||||
"251-257. K\u00e9szterm\u00e9kek": {},
|
||||
@ -158,23 +158,23 @@
|
||||
"26-28. \u00c1RUK ": {
|
||||
"261. Kereskedelmi \u00e1ruk": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 0
|
||||
"isGroup": false
|
||||
},
|
||||
"262. Idegen helyen t\u00e1rolt, bizom\u00e1nyba \u00e1tadott \u00e1ruk": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 0
|
||||
"isGroup": false
|
||||
},
|
||||
"263. T\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6z\u00fcl \u00e1tsorolt \u00e1ruk": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 0
|
||||
"isGroup": false
|
||||
},
|
||||
"264. Bels\u0151 (egys\u00e9gek, tev\u00e9kenys\u00e9gek k\u00f6z\u00f6tti) \u00e1tad\u00e1s-\u00e1tv\u00e9tel \u00fctk\u00f6z\u0151sz\u00e1mla": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 0
|
||||
"isGroup": false
|
||||
},
|
||||
"269. Kereskedelmi \u00e1ruk \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 0
|
||||
"isGroup": false
|
||||
},
|
||||
"accountType": "Stock"
|
||||
},
|
||||
@ -183,7 +183,7 @@
|
||||
"279. K\u00f6zvet\u00edtett szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"28. BET\u00c9TD\u00cdJAS G\u00d6NGY\u00d6LEGEK": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"rootType": "Asset"
|
||||
},
|
||||
@ -205,13 +205,13 @@
|
||||
"319. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"32. K\u00d6VETEL\u00c9SEK KAPCSOLT V\u00c1LLALKOZ\u00c1SSAL SZEMBEN": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"33. K\u00d6VETEL\u00c9SEK EGY\u00c9B R\u00c9SZESED\u00c9SI VISZONYBAN L\u00c9V\u00d5 V\u00c1LLALKOZ\u00c1SSAL SZEMBEN ": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"34. V\u00c1LT\u00d3K\u00d6VETEL\u00c9SEK": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"35. ADOTT EL\u00d5LEGEK": {
|
||||
"351. Immateri\u00e1lis javakra adott el\u0151legek": {},
|
||||
@ -227,17 +227,17 @@
|
||||
"3613. Egy\u00e9b elsz\u00e1mol\u00e1sok a munkav\u00e1llal\u00f3kkal": {}
|
||||
},
|
||||
"362. K\u00f6lts\u00e9gvet\u00e9ssel szembeni k\u00f6vetel\u00e9sek": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"363. R\u00f6vid lej\u00e1ratra k\u00f6lcs\u00f6nadott p\u00e9nzeszk\u00f6z\u00f6k": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"364. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6vetel\u00e9sek": {
|
||||
"3641. R\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k": {},
|
||||
"3642. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6kb\u0151l \u00e1tsorolt k\u00f6vetel\u00e9sek": {}
|
||||
},
|
||||
"365. V\u00e1s\u00e1rolt \u00e9s kapott k\u00f6vetel\u00e9sek ": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"366. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6vetel\u00e9sek": {},
|
||||
"367. Hat\u00e1rid\u0151s, opci\u00f3s \u00e9s swap \u00fcgyletekkel kapcsolatos k\u00f6vetel\u00e9sek": {},
|
||||
@ -285,7 +285,7 @@
|
||||
"383. Csekkek": {},
|
||||
"384. Elsz\u00e1mol\u00e1si bet\u00e9tsz\u00e1mla ": {
|
||||
"accountType": "Bank",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"385. Elk\u00fcl\u00f6n\u00edtett bet\u00e9tsz\u00e1ml\u00e1k ": {
|
||||
"3851. Kamatoz\u00f3 bet\u00e9tsz\u00e1ml\u00e1k": {},
|
||||
@ -373,7 +373,7 @@
|
||||
"4452. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek deviz\u00e1ban": {}
|
||||
},
|
||||
"446. Tart\u00f3s k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"447. Tart\u00f3s k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
|
||||
"448. P\u00e9nz\u00fcgyi l\u00edzing miatti k\u00f6telezetts\u00e9gek ": {},
|
||||
@ -449,7 +449,7 @@
|
||||
"463-9. C\u00e9gaut\u00f3ad\u00f3 ": {}
|
||||
},
|
||||
"464. G\u00e9pj\u00e1rm\u0171 ad\u00f3 (c\u00e9gaut\u00f3ad\u00f3) elsz\u00e1mol\u00e1sa": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"465. V\u00e1m- \u00e9s p\u00e9nz\u00fcgy\u0151rs\u00e9g elsz\u00e1mol\u00e1si sz\u00e1mla ": {
|
||||
"4651. V\u00e1mk\u00f6lts\u00e9gek \u00e9s egy\u00e9b v\u00e1mterhek elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
@ -619,7 +619,7 @@
|
||||
"589. Aktiv\u00e1lt saj\u00e1t teljes\u00edtm\u00e9nyek \u00e1tvezet\u00e9si sz\u00e1mla": {}
|
||||
},
|
||||
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"rootType": "Expense"
|
||||
},
|
||||
@ -647,7 +647,7 @@
|
||||
"rootType": "Expense"
|
||||
},
|
||||
"7. SZ\u00c1MLAOSZT\u00c1LY TEV\u00c9KENYS\u00c9GEKK\u00d6LTS\u00c9GEI": {
|
||||
"isGroup": 1,
|
||||
"isGroup": true,
|
||||
"rootType": "Expense"
|
||||
},
|
||||
"8. SZ\u00c1MLAOSZT\u00c1LY \u00c9RT\u00c9KES\u00cdT\u00c9S ELSZ\u00c1MOLT \u00d6NK\u00d6LTS\u00c9GE \u00c9S R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
@ -812,7 +812,7 @@
|
||||
"9684. R\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"969. K\u00fcl\u00f6nf\u00e9le egy\u00e9b bev\u00e9telek": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"97. P\u00c9NZ\u00dcGYI M\u0170VELETEK BEV\u00c9TELEI": {
|
||||
|
@ -14,11 +14,11 @@
|
||||
"Bank ": {
|
||||
"Bank Other Currency": {
|
||||
"accountNumber": "1122.000",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Bank Rupiah": {
|
||||
"accountNumber": "1121.000",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountNumber": "1120.000",
|
||||
"accountType": "Bank"
|
||||
@ -70,7 +70,7 @@
|
||||
"Persediaan Barang": {
|
||||
"accountNumber": "1141.000",
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Uang Muka Pembelian": {
|
||||
"Uang Muka Pembelian": {
|
||||
@ -122,7 +122,7 @@
|
||||
"Investasi": {
|
||||
"Deposito": {
|
||||
"accountNumber": "1231.003",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Investai Saham": {
|
||||
"Investasi Saham": {
|
||||
|
@ -6,13 +6,13 @@
|
||||
"Current Assets": {
|
||||
"Accounts Receivable": {
|
||||
"Debtors": {
|
||||
"isGroup": 0,
|
||||
"isGroup": false,
|
||||
"accountType": "Receivable"
|
||||
}
|
||||
},
|
||||
"Bank Accounts": {
|
||||
"accountType": "Bank",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Cash In Hand": {
|
||||
"Cash": {
|
||||
@ -21,7 +21,7 @@
|
||||
"accountType": "Cash"
|
||||
},
|
||||
"Loans and Advances (Assets)": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Securities and Deposits": {
|
||||
"Earnest Money": {}
|
||||
@ -33,7 +33,7 @@
|
||||
"accountType": "Stock"
|
||||
},
|
||||
"Tax Assets": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Fixed Assets": {
|
||||
@ -60,7 +60,7 @@
|
||||
}
|
||||
},
|
||||
"Investments": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Temporary Accounts": {
|
||||
"Temporary Opening": {
|
||||
@ -126,7 +126,7 @@
|
||||
},
|
||||
"Indirect Income": {
|
||||
"accountType": "Income Account",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"rootType": "Income"
|
||||
},
|
||||
|
@ -110,7 +110,7 @@
|
||||
},
|
||||
"INVENTARIOS": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"ACTIVO LARGO PLAZO": {
|
||||
|
@ -57,7 +57,7 @@
|
||||
},
|
||||
"Otros Equivalentes a Efectivo": {
|
||||
"accountType": "Cash",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Impuestos Acreditables": {
|
||||
@ -91,41 +91,41 @@
|
||||
},
|
||||
"Todos los Almacenes": {
|
||||
"accountType": "Stock",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"accountType": "Stock"
|
||||
},
|
||||
"Otras Cuentas por Cobrar": {
|
||||
"accountType": "Receivable",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Activo no Corriente": {
|
||||
"Activo por Impuestos Diferidos": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Activos Intangibles": {
|
||||
"Amortizacion de Activos Intangibles": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Concesiones": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Derechos de Autor": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Deterioro de Valor de Activos Intangibles": {},
|
||||
"Gastos de investigacion": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Licencias": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Marcas Registradas": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Patentes": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Amortizables": {
|
||||
@ -138,7 +138,7 @@
|
||||
"accountType": "Expenses Included In Valuation"
|
||||
},
|
||||
"Mejoras en Bienes Arrendados": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Bienes en Arrendamiento Financiero": {
|
||||
@ -147,28 +147,28 @@
|
||||
},
|
||||
"Cuentas por Cobrar a Largo Plazo": {
|
||||
"Creditos a Largo Plazo": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Inversiones Permanentes": {
|
||||
"Inversiones Permanentes 1": {
|
||||
"accountType": "Fixed Asset",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Negocios Conjuntos": {
|
||||
"accountType": "Fixed Asset",
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Inversiones a Largo Plazo": {
|
||||
"Depositos Bancarios a Plazo": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Intereses percibidos por adelantado": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Titulos y Acciones": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Propiedad Planta y Equipo": {
|
||||
@ -203,7 +203,7 @@
|
||||
}
|
||||
},
|
||||
"Donaciones": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Ganancias Acumuladas": {
|
||||
"Reservas": {
|
||||
@ -319,7 +319,7 @@
|
||||
},
|
||||
"Pasivo": {
|
||||
"Obligaciones por Arrendamiento Financiero a Largo Plazo": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Pasivo Corriente": {
|
||||
"Anticipos de Clientes": {},
|
||||
@ -345,11 +345,11 @@
|
||||
},
|
||||
"Gastos por Pagar": {
|
||||
"Prestaciones Sociales": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Salarios por Pagar": {},
|
||||
"Servicios Basicos 1": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Impuestos por Pagar": {
|
||||
@ -372,17 +372,17 @@
|
||||
}
|
||||
},
|
||||
"Otras Cuentas por Pagar": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Pasivos Financieros a Corto Plazo": {
|
||||
"Otras Deudas Bancarias": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Prestamos por Pagar a Corto Plazo": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Sobregiros Bancarios": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Provisiones por Pagar": {
|
||||
@ -473,20 +473,20 @@
|
||||
},
|
||||
"Pasivo No Corriente": {
|
||||
"Cuentas por Pagar a Largo Plaso": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Otras Cuentas por Pagar a Largo Plazo": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Otros Pasivos Financieros a Largo Plaso": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Prestamos a Largo Plazo": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Pasivo por Impuestos Diferidos": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"rootType": "Liability"
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "Netherlands - Grootboekschema",
|
||||
"tree": {
|
||||
"FABRIKAGEREKENINGEN": {
|
||||
"isGroup": 1,
|
||||
"isGroup": true,
|
||||
"rootType": "Expense"
|
||||
},
|
||||
"FINANCIELE REKENINGEN, KORTLOPENDE VORDERINGEN EN SCHULDEN": {
|
||||
@ -106,7 +106,7 @@
|
||||
"rootType": "Asset"
|
||||
},
|
||||
"INDIRECTE KOSTEN": {
|
||||
"isGroup": 1,
|
||||
"isGroup": true,
|
||||
"rootType": "Expense"
|
||||
},
|
||||
"KOSTENREKENINGEN": {
|
||||
|
@ -7,8 +7,8 @@
|
||||
}
|
||||
},
|
||||
"Bank Accounts": {
|
||||
"accountType": "Bank",
|
||||
"isGroup": 1
|
||||
"accountType": "Bank",
|
||||
"isGroup": true
|
||||
},
|
||||
"Cash In Hand": {
|
||||
"Cash": {
|
||||
@ -17,7 +17,7 @@
|
||||
"accountType": "Cash"
|
||||
},
|
||||
"Loans and Advances (Assets)": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Securities and Deposits": {
|
||||
"Earnest Money": {}
|
||||
@ -29,7 +29,7 @@
|
||||
"accountType": "Stock"
|
||||
},
|
||||
"Tax Assets": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
}
|
||||
},
|
||||
"Fixed Assets": {
|
||||
@ -59,7 +59,7 @@
|
||||
}
|
||||
},
|
||||
"Investments": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"Temporary Accounts": {
|
||||
"Temporary Opening": {
|
||||
@ -123,7 +123,7 @@
|
||||
"Service": {}
|
||||
},
|
||||
"Indirect Income": {
|
||||
"isGroup": 1
|
||||
"isGroup": true
|
||||
},
|
||||
"rootType": "Income"
|
||||
},
|
||||
@ -141,8 +141,8 @@
|
||||
}
|
||||
},
|
||||
"Duties and Taxes": {
|
||||
"accountType": "Tax",
|
||||
"isGroup": 1
|
||||
"accountType": "Tax",
|
||||
"isGroup": true
|
||||
},
|
||||
"Loans (Liabilities)": {
|
||||
"Secured Loans": {},
|
||||
|
@ -21,6 +21,7 @@ export class DatabaseHandler extends DatabaseBase {
|
||||
#fyo: Fyo;
|
||||
converter: Converter;
|
||||
#demux: DatabaseDemuxBase;
|
||||
dbPath?: string;
|
||||
schemaMap: Readonly<SchemaMap> = {};
|
||||
fieldValueMap: Record<string, Record<string, Field>> = {};
|
||||
|
||||
@ -39,12 +40,14 @@ export class DatabaseHandler extends DatabaseBase {
|
||||
async createNewDatabase(dbPath: string, countryCode: string) {
|
||||
countryCode = await this.#demux.createNewDatabase(dbPath, countryCode);
|
||||
await this.init();
|
||||
this.dbPath = dbPath;
|
||||
return countryCode;
|
||||
}
|
||||
|
||||
async connectToDatabase(dbPath: string, countryCode?: string) {
|
||||
countryCode = await this.#demux.connectToDatabase(dbPath, countryCode);
|
||||
await this.init();
|
||||
this.dbPath = dbPath;
|
||||
return countryCode;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ export enum ConfigKeys {
|
||||
export interface ConfigFile {
|
||||
id: string;
|
||||
companyName: string;
|
||||
filePath: string;
|
||||
dbPath: string;
|
||||
}
|
||||
|
||||
export interface FyoConfig {
|
||||
|
@ -676,6 +676,14 @@ export default class Doc extends Observable<DocValue | Doc[]> {
|
||||
return this.fyo.doc.getCachedValue(schemaName, name, fieldname);
|
||||
}
|
||||
|
||||
async setAndUpdate(
|
||||
fieldname: string | DocValueMap,
|
||||
value?: DocValue | Doc[]
|
||||
) {
|
||||
await this.set(fieldname, value);
|
||||
return await this.update();
|
||||
}
|
||||
|
||||
async duplicate(shouldInsert: boolean = true): Promise<Doc> {
|
||||
const updateMap: DocValueMap = {};
|
||||
const docValueMap = this.getValidDict();
|
||||
|
@ -79,7 +79,7 @@ function addNewFile(
|
||||
): UniqueId {
|
||||
const newFile: ConfigFile = {
|
||||
companyName,
|
||||
filePath: fyo.config.get(ConfigKeys.LastSelectedFilePath, '') as string,
|
||||
dbPath: fyo.config.get(ConfigKeys.LastSelectedFilePath, '') as string,
|
||||
id: getId(),
|
||||
};
|
||||
|
||||
|
@ -25,3 +25,19 @@ export type AccountRootType =
|
||||
| 'Equity'
|
||||
| 'Income'
|
||||
| 'Expense';
|
||||
|
||||
export interface COARootAccount {
|
||||
rootType: AccountRootType;
|
||||
[key: string]: COAChildAccount | AccountRootType;
|
||||
}
|
||||
|
||||
export interface COAChildAccount {
|
||||
accountType?: AccountType;
|
||||
accountNumber?: string;
|
||||
isGroup?: boolean;
|
||||
[key: string]: COAChildAccount | boolean | AccountType | string | undefined;
|
||||
}
|
||||
|
||||
export interface COATree {
|
||||
[key: string]: COARootAccount;
|
||||
}
|
||||
|
@ -1,109 +0,0 @@
|
||||
import frappe from 'fyo';
|
||||
import telemetry from '../src/telemetry/telemetry';
|
||||
import { Verb } from '../src/telemetry/types';
|
||||
import { getSavePath, saveData, showExportInFolder } from '../src/utils';
|
||||
|
||||
function templateToInnerText(innerHTML) {
|
||||
const temp = document.createElement('template');
|
||||
temp.innerHTML = innerHTML.trim();
|
||||
return temp.content.firstChild.innerText;
|
||||
}
|
||||
|
||||
function deObjectify(value) {
|
||||
if (typeof value !== 'object') return value;
|
||||
if (value === null) return '';
|
||||
|
||||
const innerHTML = value.template;
|
||||
if (!innerHTML) return '';
|
||||
return templateToInnerText(innerHTML);
|
||||
}
|
||||
|
||||
function csvFormat(value) {
|
||||
if (typeof value === 'string') {
|
||||
return `"${value}"`;
|
||||
} else if (value === null) {
|
||||
return '';
|
||||
} else if (typeof value === 'object') {
|
||||
const innerHTML = value.template;
|
||||
if (!innerHTML) return '';
|
||||
return csvFormat(deObjectify(value));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function exportCsv(rows, columns, filePath) {
|
||||
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])).join(',')),
|
||||
];
|
||||
|
||||
saveExportData(csvRows.join('\n'), filePath);
|
||||
}
|
||||
|
||||
async function exportJson(rows, columns, filePath, filters, reportName) {
|
||||
const exportObject = {};
|
||||
const fieldnames = columns.map(({ fieldname }) => fieldname);
|
||||
|
||||
exportObject.columns = columns.map(({ fieldname, label }) => ({
|
||||
fieldname,
|
||||
label,
|
||||
}));
|
||||
|
||||
exportObject.rows = rows.map((row) =>
|
||||
fieldnames.reduce((acc, f) => {
|
||||
acc[f] = deObjectify(row[f]);
|
||||
return acc;
|
||||
}, {})
|
||||
);
|
||||
|
||||
exportObject.filters = Object.keys(filters)
|
||||
.filter((name) => filters[name] !== null && filters[name] !== undefined)
|
||||
.reduce((acc, name) => {
|
||||
acc[name] = filters[name];
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
exportObject.timestamp = new Date().toISOString();
|
||||
exportObject.reportName = reportName;
|
||||
exportObject.softwareName = 'Frappe Books';
|
||||
exportObject.softwareVersion = frappe.store.appVersion;
|
||||
|
||||
await saveExportData(JSON.stringify(exportObject), filePath);
|
||||
}
|
||||
|
||||
async function exportReport(extention, reportName, 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;
|
||||
}
|
||||
|
||||
telemetry.log(Verb.Exported, reportName, { extention });
|
||||
}
|
||||
|
||||
export default function getCommonExportActions(reportName) {
|
||||
return ['csv', 'json'].map((ext) => ({
|
||||
group: frappe.t`Export`,
|
||||
label: ext.toUpperCase(),
|
||||
type: 'primary',
|
||||
action: async (getReportData) =>
|
||||
await exportReport(ext, reportName, getReportData),
|
||||
}));
|
||||
}
|
||||
|
||||
export async function saveExportData(data, filePath) {
|
||||
await saveData(data, filePath);
|
||||
showExportInFolder(frappe.t`Export Successful`, filePath);
|
||||
}
|
@ -1,3 +1,15 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import models, { getRegionalModels } from 'models';
|
||||
|
||||
export const fyo = new Fyo({ isTest: false, isElectron: true });
|
||||
|
||||
export async function initializeModels(dbPath: string, countryCode?: string) {
|
||||
if (countryCode) {
|
||||
countryCode = await fyo.db.createNewDatabase(dbPath, countryCode);
|
||||
} else {
|
||||
countryCode = await fyo.db.connectToDatabase(dbPath);
|
||||
}
|
||||
|
||||
const regionalModels = await getRegionalModels(countryCode);
|
||||
await fyo.initializeAndRegister(models, regionalModels);
|
||||
}
|
||||
|
@ -1,9 +1,3 @@
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import SearchBar from 'src/components/SearchBar';
|
||||
import { openQuickEdit } from 'src/utils';
|
||||
import frappe from 'frappe';
|
||||
import { nextTick } from 'vue';
|
||||
import { handleErrorWithDialog } from '../errorHandling';
|
||||
<template>
|
||||
<div class="flex flex-col overflow-y-hidden">
|
||||
<PageHeader>
|
||||
|
@ -101,9 +101,8 @@
|
||||
</template>
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import { getYMax } from 'src/components/Charts/chartUtils';
|
||||
import LineChart from 'src/components/Charts/LineChart.vue';
|
||||
import { formatXLabels } from 'src/utils';
|
||||
import { formatXLabels, getYMax } from 'src/utils/chart';
|
||||
import Cashflow from '../../../reports/Cashflow/Cashflow';
|
||||
import { getDatesAndPeriodicity } from './getDatesAndPeriodicity';
|
||||
import PeriodSelector from './PeriodSelector';
|
||||
|
@ -30,8 +30,7 @@
|
||||
<script>
|
||||
import frappe from 'frappe';
|
||||
import BarChart from 'src/components/Charts/BarChart.vue';
|
||||
import { getYMax, getYMin } from 'src/components/Charts/chartUtils';
|
||||
import { formatXLabels } from 'src/utils';
|
||||
import { formatXLabels, getYMax, getYMin } from 'src/utils/chart';
|
||||
import ProfitAndLoss from '../../../reports/ProfitAndLoss/ProfitAndLoss';
|
||||
import { getDatesAndPeriodicity } from './getDatesAndPeriodicity';
|
||||
import PeriodSelector from './PeriodSelector';
|
||||
|
@ -1,25 +0,0 @@
|
||||
import Account from '../../../models/doctype/Account/AccountList';
|
||||
import AccountingLedgerEntry from '../../../models/doctype/AccountingLedgerEntry/AccountingLedgerEntryList';
|
||||
import Item from '../../../models/doctype/Item/ItemList';
|
||||
import JournalEntry from '../../../models/doctype/JournalEntry/JournalEntryList';
|
||||
import Customer from '../../../models/doctype/Party/CustomerList';
|
||||
import Party from '../../../models/doctype/Party/PartyList';
|
||||
import Supplier from '../../../models/doctype/Party/SupplierList';
|
||||
import Payment from '../../../models/doctype/Payment/PaymentList';
|
||||
import PurchaseInvoice from '../../../models/doctype/PurchaseInvoice/PurchaseInvoiceList';
|
||||
import SalesInvoice from '../../../models/doctype/SalesInvoice/SalesInvoiceList';
|
||||
import Tax from '../../../models/doctype/Tax/TaxList';
|
||||
|
||||
export default {
|
||||
SalesInvoice,
|
||||
PurchaseInvoice,
|
||||
Customer,
|
||||
Supplier,
|
||||
Party,
|
||||
Item,
|
||||
Payment,
|
||||
Tax,
|
||||
JournalEntry,
|
||||
Account,
|
||||
AccountingLedgerEntry,
|
||||
};
|
@ -1,192 +0,0 @@
|
||||
import countryList from 'fixtures/countryInfo.json';
|
||||
import frappe from 'fyo';
|
||||
import { DEFAULT_LOCALE } from 'fyo/utils/consts';
|
||||
import config from 'src/config';
|
||||
import importCharts from '../../../accounting/importCOA';
|
||||
import generateTaxes from '../../../models/doctype/Tax/RegionalEntries';
|
||||
import regionalModelUpdates from '../../../models/regionalModelUpdates';
|
||||
import { getId } from '../../telemetry/helpers';
|
||||
import { callInitializeMoneyMaker } from '../../utils';
|
||||
|
||||
export default async function setupCompany(setupWizardValues) {
|
||||
const {
|
||||
companyLogo,
|
||||
companyName,
|
||||
country,
|
||||
name,
|
||||
email,
|
||||
bankName,
|
||||
currency: companyCurrency,
|
||||
fiscalYearStart,
|
||||
fiscalYearEnd,
|
||||
chartOfAccounts,
|
||||
} = setupWizardValues;
|
||||
|
||||
const accountingSettings = frappe.AccountingSettings;
|
||||
const currency = companyCurrency || countryList[country]['currency'];
|
||||
const locale = countryList[country]['locale'] ?? DEFAULT_LOCALE;
|
||||
await callInitializeMoneyMaker(currency);
|
||||
|
||||
const accountingSettingsUpdateMap = {
|
||||
companyName,
|
||||
country,
|
||||
fullname: name,
|
||||
email,
|
||||
bankName,
|
||||
fiscalYearStart,
|
||||
fiscalYearEnd,
|
||||
currency,
|
||||
};
|
||||
|
||||
await accountingSettings.setMultiple(accountingSettingsUpdateMap);
|
||||
await accountingSettings.update();
|
||||
|
||||
const printSettings = await frappe.getSingle('PrintSettings');
|
||||
const printSettingsUpdateMap = {
|
||||
logo: companyLogo,
|
||||
companyName,
|
||||
email,
|
||||
displayLogo: companyLogo ? true : false,
|
||||
};
|
||||
|
||||
await printSettings.setMultiple(printSettingsUpdateMap);
|
||||
await printSettings.update();
|
||||
|
||||
await setupGlobalCurrencies(countryList);
|
||||
await setupChartOfAccounts(bankName, country, chartOfAccounts);
|
||||
await setupRegionalChanges(country);
|
||||
updateInitializationConfig();
|
||||
|
||||
await accountingSettings.setMultiple({ setupComplete: true });
|
||||
await accountingSettings.update();
|
||||
frappe.AccountingSettings = accountingSettings;
|
||||
|
||||
const systemSettings = await frappe.getSingle('SystemSettings');
|
||||
systemSettings.setMultiple({ locale });
|
||||
systemSettings.update();
|
||||
}
|
||||
|
||||
async function setupGlobalCurrencies(countries) {
|
||||
const promises = [];
|
||||
const queue = [];
|
||||
for (let country of Object.values(countries)) {
|
||||
const {
|
||||
currency,
|
||||
currency_fraction: fraction,
|
||||
currency_fraction_units: fractionUnits,
|
||||
smallest_currency_fraction_value: smallestValue,
|
||||
currency_symbol: symbol,
|
||||
} = country;
|
||||
|
||||
if (!currency || queue.includes(currency)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const docObject = {
|
||||
doctype: 'Currency',
|
||||
name: currency,
|
||||
fraction,
|
||||
fractionUnits,
|
||||
smallestValue,
|
||||
symbol,
|
||||
};
|
||||
|
||||
const doc = checkAndCreateDoc(docObject);
|
||||
if (doc) {
|
||||
promises.push(doc);
|
||||
queue.push(currency);
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
async function setupChartOfAccounts(bankName, country, chartOfAccounts) {
|
||||
await importCharts(chartOfAccounts);
|
||||
const parentAccount = await getBankAccountParentName(country);
|
||||
const docObject = {
|
||||
doctype: 'Account',
|
||||
name: bankName,
|
||||
rootType: 'Asset',
|
||||
parentAccount,
|
||||
accountType: 'Bank',
|
||||
isGroup: 0,
|
||||
};
|
||||
await checkAndCreateDoc(docObject);
|
||||
}
|
||||
|
||||
async function setupRegionalChanges(country) {
|
||||
await generateTaxes(country);
|
||||
await regionalModelUpdates({ country });
|
||||
await frappe.db.migrate();
|
||||
}
|
||||
|
||||
function updateInitializationConfig(language) {
|
||||
let filePath = frappe.db.dbPath;
|
||||
let files = config.get('files', []);
|
||||
files.forEach((file) => {
|
||||
if (file.filePath === filePath) {
|
||||
file.companyName = frappe.AccountingSettings.companyName;
|
||||
file.id = getId();
|
||||
}
|
||||
});
|
||||
config.set('files', files);
|
||||
}
|
||||
|
||||
export async function checkIfExactRecordAbsent(docObject) {
|
||||
const { doctype, name } = docObject;
|
||||
const newDocObject = Object.assign({}, docObject);
|
||||
delete newDocObject.doctype;
|
||||
const rows = await frappe.db.getAllRaw(doctype, {
|
||||
fields: ['*'],
|
||||
filters: { name },
|
||||
});
|
||||
|
||||
if (rows.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const storedDocObject = rows[0];
|
||||
const matchList = Object.keys(newDocObject).map((key) => {
|
||||
const newValue = newDocObject[key];
|
||||
const storedValue = storedDocObject[key];
|
||||
return newValue == storedValue; // Should not be type sensitive.
|
||||
});
|
||||
|
||||
if (!matchList.every(Boolean)) {
|
||||
await frappe.db.delete(doctype, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async function checkAndCreateDoc(docObject) {
|
||||
const canCreate = await checkIfExactRecordAbsent(docObject);
|
||||
if (!canCreate) {
|
||||
return;
|
||||
}
|
||||
|
||||
const doc = await frappe.doc.getNewDoc(docObject.doctype, docObject);
|
||||
return doc.insert();
|
||||
}
|
||||
|
||||
async function getBankAccountParentName(country) {
|
||||
const parentBankAccount = await frappe.db.getAllRaw('Account', {
|
||||
fields: ['*'],
|
||||
filters: { isGroup: true, accountType: 'Bank' },
|
||||
});
|
||||
|
||||
if (parentBankAccount.length === 0) {
|
||||
// This should not happen if the fixtures are correct.
|
||||
return 'Bank Accounts';
|
||||
} else if (parentBankAccount.length > 1) {
|
||||
switch (country) {
|
||||
case 'Indonesia':
|
||||
return 'Bank Rupiah - 1121.000';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return parentBankAccount[0].name;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
export type TaxType = 'GST' | 'IGST' | 'Exempt-GST' | 'Exempt-IGST';
|
||||
|
||||
export default async function generateTaxes(country: string) {
|
||||
if (country === 'India') {
|
||||
const GSTs = {
|
||||
GST: [28, 18, 12, 6, 5, 3, 0.25, 0],
|
||||
IGST: [28, 18, 12, 6, 5, 3, 0.25, 0],
|
||||
'Exempt-GST': [0],
|
||||
'Exempt-IGST': [0],
|
||||
};
|
||||
const newTax = await fyo.doc.getEmptyDoc('Tax');
|
||||
|
||||
for (const type of Object.keys(GSTs)) {
|
||||
for (const percent of GSTs[type as TaxType]) {
|
||||
const name = `${type}-${percent}`;
|
||||
|
||||
// Not cross checking cause hardcoded values.
|
||||
await fyo.db.delete('Tax', name);
|
||||
|
||||
const details = getTaxDetails(type as TaxType, percent);
|
||||
await newTax.set({ name, details });
|
||||
await newTax.insert();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTaxDetails(type: TaxType, percent: number) {
|
||||
if (type === 'GST') {
|
||||
return [
|
||||
{
|
||||
account: 'CGST',
|
||||
rate: percent / 2,
|
||||
},
|
||||
{
|
||||
account: 'SGST',
|
||||
rate: percent / 2,
|
||||
},
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
account: type.toString().split('-')[0],
|
||||
rate: percent,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
52
src/regional/in/in.ts
Normal file
52
src/regional/in/in.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
export type TaxType = 'GST' | 'IGST' | 'Exempt-GST' | 'Exempt-IGST';
|
||||
|
||||
export async function createIndianRecords() {
|
||||
await generateTaxes();
|
||||
}
|
||||
|
||||
async function generateTaxes() {
|
||||
const GSTs = {
|
||||
GST: [28, 18, 12, 6, 5, 3, 0.25, 0],
|
||||
IGST: [28, 18, 12, 6, 5, 3, 0.25, 0],
|
||||
'Exempt-GST': [0],
|
||||
'Exempt-IGST': [0],
|
||||
};
|
||||
const newTax = await fyo.doc.getEmptyDoc('Tax');
|
||||
|
||||
for (const type of Object.keys(GSTs)) {
|
||||
for (const percent of GSTs[type as TaxType]) {
|
||||
const name = `${type}-${percent}`;
|
||||
|
||||
// Not cross checking cause hardcoded values.
|
||||
await fyo.db.delete('Tax', name);
|
||||
|
||||
const details = getTaxDetails(type as TaxType, percent);
|
||||
await newTax.set({ name, details });
|
||||
await newTax.insert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTaxDetails(type: TaxType, percent: number) {
|
||||
if (type === 'GST') {
|
||||
return [
|
||||
{
|
||||
account: 'CGST',
|
||||
rate: percent / 2,
|
||||
},
|
||||
{
|
||||
account: 'SGST',
|
||||
rate: percent / 2,
|
||||
},
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
account: type.toString().split('-')[0],
|
||||
rate: percent,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
9
src/regional/index.ts
Normal file
9
src/regional/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { createIndianRecords } from './in/in';
|
||||
|
||||
export async function createRegionalRecords(country: string) {
|
||||
if (country === 'India') {
|
||||
await createIndianRecords();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
@ -1,55 +1,45 @@
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { createApp } from 'vue';
|
||||
import App from './App';
|
||||
import FeatherIcon from './components/FeatherIcon';
|
||||
import config, { ConfigKeys } from './config';
|
||||
import { ConfigKeys } from 'fyo/core/types';
|
||||
import { IPC_ACTIONS } from 'utils/messages';
|
||||
import { App as VueApp, createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import Badge from './components/Badge.vue';
|
||||
import FeatherIcon from './components/FeatherIcon.vue';
|
||||
import { getErrorHandled, handleError } from './errorHandling';
|
||||
import { fyo } from './initFyo';
|
||||
import { IPC_ACTIONS } from './messages';
|
||||
import { incrementOpenCount } from './renderer/helpers';
|
||||
import { incrementOpenCount, outsideClickDirective } from './renderer/helpers';
|
||||
import registerIpcRendererListeners from './renderer/registerIpcRendererListeners';
|
||||
import router from './router';
|
||||
import { outsideClickDirective } from './ui';
|
||||
import { setLanguageMap, stringifyCircular } from './utils';
|
||||
import { stringifyCircular } from './utils';
|
||||
import { setLanguageMap } from './utils/language';
|
||||
|
||||
(async () => {
|
||||
const language = fyo.config.get(ConfigKeys.Language);
|
||||
const language = fyo.config.get(ConfigKeys.Language) as string;
|
||||
if (language) {
|
||||
await setLanguageMap(language);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
window.config = config;
|
||||
}
|
||||
|
||||
fyo.isElectron = true;
|
||||
|
||||
const models = (await import('../models')).default;
|
||||
await fyo.initializeAndRegister(models);
|
||||
setOnWindow();
|
||||
|
||||
ipcRenderer.send = getErrorHandled(ipcRenderer.send);
|
||||
ipcRenderer.invoke = getErrorHandled(ipcRenderer.invoke);
|
||||
|
||||
window.frappe = fyo;
|
||||
|
||||
window.onerror = (message, source, lineno, colno, error) => {
|
||||
error = error ?? new Error('triggered in window.onerror');
|
||||
handleError(true, error, { message, source, lineno, colno });
|
||||
};
|
||||
|
||||
registerIpcRendererListeners();
|
||||
|
||||
const app = createApp({
|
||||
template: '<App/>',
|
||||
template: '<h1>Hellow, World</h1>',
|
||||
});
|
||||
setErrorHandlers(app);
|
||||
|
||||
app.use(router);
|
||||
app.component('App', App);
|
||||
app.component('feather-icon', FeatherIcon);
|
||||
app.component('Badge', Badge);
|
||||
|
||||
app.directive('on-outside-click', outsideClickDirective);
|
||||
app.mixin({
|
||||
computed: {
|
||||
frappe() {
|
||||
fyo() {
|
||||
return fyo;
|
||||
},
|
||||
platform() {
|
||||
@ -71,8 +61,20 @@ import { setLanguageMap, stringifyCircular } from './utils';
|
||||
},
|
||||
});
|
||||
|
||||
fyo.store.appVersion = await ipcRenderer.invoke(IPC_ACTIONS.GET_VERSION);
|
||||
|
||||
incrementOpenCount();
|
||||
app.mount('body');
|
||||
})();
|
||||
|
||||
function setErrorHandlers(app: VueApp) {
|
||||
window.onerror = (message, source, lineno, colno, error) => {
|
||||
error = error ?? new Error('triggered in window.onerror');
|
||||
handleError(true, error, { message, source, lineno, colno });
|
||||
};
|
||||
|
||||
app.config.errorHandler = (err, vm, info) => {
|
||||
const more = {
|
||||
const more: Record<string, unknown> = {
|
||||
info,
|
||||
};
|
||||
|
||||
@ -84,19 +86,26 @@ import { setLanguageMap, stringifyCircular } from './utils';
|
||||
more.props = stringifyCircular(vm.$props ?? {}, true, true);
|
||||
}
|
||||
|
||||
handleError(false, err, more);
|
||||
handleError(false, err as Error, more);
|
||||
console.error(err, vm, info);
|
||||
};
|
||||
|
||||
fyo.store.appVersion = await ipcRenderer.invoke(IPC_ACTIONS.GET_VERSION);
|
||||
incrementOpenCount();
|
||||
app.mount('body');
|
||||
|
||||
process.on('unhandledRejection', (error) => {
|
||||
handleError(true, error);
|
||||
handleError(true, error as Error);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', (error) => {
|
||||
handleError(true, error, {}, () => process.exit(1));
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
function setOnWindow() {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// @ts-ignore
|
||||
window.config = config;
|
||||
// @ts-ignore
|
||||
window.router = router;
|
||||
// @ts-ignore
|
||||
window.fyo = fyo;
|
||||
}
|
||||
}
|
@ -1,5 +1,40 @@
|
||||
import { ConfigKeys } from 'fyo/core/types';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { Directive } from 'vue';
|
||||
|
||||
const instances: OutsideClickCallback[] = [];
|
||||
type OutsideClickCallback = (e: Event) => void;
|
||||
|
||||
export const outsideClickDirective: Directive<
|
||||
HTMLElement,
|
||||
OutsideClickCallback
|
||||
> = {
|
||||
beforeMount(el, binding) {
|
||||
el.dataset.outsideClickIndex = String(instances.length);
|
||||
|
||||
const fn = binding.value;
|
||||
const click = function (e: Event) {
|
||||
onDocumentClick(e, el, fn);
|
||||
};
|
||||
|
||||
document.addEventListener('click', click);
|
||||
instances.push(click);
|
||||
},
|
||||
unmounted(el) {
|
||||
const index = parseInt(el.dataset.outsideClickIndex ?? '0');
|
||||
const handler = instances[index];
|
||||
document.addEventListener('click', handler);
|
||||
instances.splice(index, 1);
|
||||
},
|
||||
};
|
||||
|
||||
function onDocumentClick(e: Event, el: HTMLElement, fn: OutsideClickCallback) {
|
||||
const target = e.target;
|
||||
|
||||
if (el !== target && !el.contains(target as Node)) {
|
||||
fn(e);
|
||||
}
|
||||
}
|
||||
|
||||
export function incrementOpenCount() {
|
||||
let openCount = fyo.config.get(ConfigKeys.OpenCount);
|
||||
|
@ -10,10 +10,10 @@ 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 } from 'vue-router';
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
|
||||
import { fyo } from './initFyo';
|
||||
|
||||
const routes = [
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
component: Dashboard,
|
||||
@ -62,9 +62,12 @@ const routes = [
|
||||
},
|
||||
props: {
|
||||
default: (route) => {
|
||||
let { doctype, filters, fieldname, value } = route.params;
|
||||
const { doctype, fieldname, value } = route.params;
|
||||
let { filters } = route.params;
|
||||
|
||||
if (filters === undefined && fieldname && value) {
|
||||
filters = { [fieldname]: value };
|
||||
// @ts-ignore
|
||||
filters = { [fieldname as string]: value };
|
||||
}
|
||||
|
||||
return {
|
||||
@ -114,7 +117,7 @@ const routes = [
|
||||
|
||||
const router = createRouter({ routes, history: createWebHistory() });
|
||||
|
||||
function removeDetails(path) {
|
||||
function removeDetails(path: string) {
|
||||
if (!path) {
|
||||
return path;
|
||||
}
|
||||
@ -124,7 +127,7 @@ function removeDetails(path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
return path.slice(0, match.index + 4);
|
||||
return path.slice(0, match.index! + 4);
|
||||
}
|
||||
|
||||
router.afterEach((to, from) => {
|
||||
@ -136,8 +139,4 @@ router.afterEach((to, from) => {
|
||||
fyo.telemetry.log(Verb.Navigated, NounEnum.Route, more);
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
window.router = router;
|
||||
}
|
||||
|
||||
export default router;
|
||||
|
98
src/setup/createCOA.ts
Normal file
98
src/setup/createCOA.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import {
|
||||
AccountRootType,
|
||||
COAChildAccount,
|
||||
COARootAccount,
|
||||
COATree,
|
||||
} from 'models/baseModels/Account/types';
|
||||
import { getCOAList } from 'models/baseModels/SetupWizard/SetupWizard';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getStandardCOA } from './standardCOA';
|
||||
|
||||
const accountFields = ['accountType', 'accountNumber', 'rootType', 'isGroup'];
|
||||
|
||||
function getAccountName(accountName: string, accountNumber?: string) {
|
||||
if (accountNumber) {
|
||||
return `${accountName} - ${accountNumber}`;
|
||||
}
|
||||
|
||||
return accountName;
|
||||
}
|
||||
|
||||
async function createCOAAccounts(
|
||||
children: COATree | COARootAccount | COAChildAccount,
|
||||
parentAccount: string,
|
||||
rootType: AccountRootType | '',
|
||||
rootAccount: boolean
|
||||
) {
|
||||
for (const rootName in children) {
|
||||
if (accountFields.includes(rootName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const child = children[rootName];
|
||||
|
||||
if (rootAccount) {
|
||||
rootType = (child as COARootAccount).rootType as AccountRootType;
|
||||
}
|
||||
|
||||
const accountType = (child as COAChildAccount).accountType ?? '';
|
||||
const accountNumber = (child as COAChildAccount).accountNumber;
|
||||
const accountName = getAccountName(rootName, accountNumber);
|
||||
|
||||
const isGroup = identifyIsGroup(child as COAChildAccount | COARootAccount);
|
||||
const doc = fyo.doc.getNewDoc('Account', {
|
||||
name: accountName,
|
||||
parentAccount,
|
||||
isGroup,
|
||||
rootType,
|
||||
balance: 0,
|
||||
accountType,
|
||||
});
|
||||
|
||||
await doc.insert();
|
||||
await createCOAAccounts(
|
||||
child as COAChildAccount,
|
||||
accountName,
|
||||
rootType,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function identifyIsGroup(child: COARootAccount | COAChildAccount): boolean {
|
||||
if (child.isGroup !== undefined) {
|
||||
return child.isGroup as boolean;
|
||||
}
|
||||
|
||||
const keys = Object.keys(child);
|
||||
const children = keys.filter((key) => !accountFields.includes(key));
|
||||
|
||||
if (children.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async function getCOA(chartOfAccounts: string) {
|
||||
const coaList = getCOAList();
|
||||
const coa = coaList.find(({ name }) => name === chartOfAccounts);
|
||||
|
||||
const conCode = coa?.countryCode;
|
||||
if (!conCode) {
|
||||
return getStandardCOA();
|
||||
}
|
||||
|
||||
try {
|
||||
const countryCoa = (await import('fixtures/verified/' + conCode + '.json'))
|
||||
.default;
|
||||
return countryCoa.tree;
|
||||
} catch (e) {
|
||||
return getStandardCOA();
|
||||
}
|
||||
}
|
||||
|
||||
export async function createCOA(chartOfAccounts: string) {
|
||||
const chart = await getCOA(chartOfAccounts);
|
||||
await createCOAAccounts(chart, '', '', true);
|
||||
}
|
217
src/setup/setupInstance.ts
Normal file
217
src/setup/setupInstance.ts
Normal file
@ -0,0 +1,217 @@
|
||||
import countryInfo from 'fixtures/countryInfo.json';
|
||||
import { ConfigFile, DocValueMap } from 'fyo/core/types';
|
||||
import Doc from 'fyo/model/doc';
|
||||
import { getId } from 'fyo/telemetry/helpers';
|
||||
import { DEFAULT_CURRENCY, DEFAULT_LOCALE } from 'fyo/utils/consts';
|
||||
import { AccountingSettings } from 'models/baseModels/AccountingSettings/AccountingSettings';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { createRegionalRecords } from 'src/regional';
|
||||
import { createCOA } from './createCOA';
|
||||
import { CountrySettings, SetupWizardOptions } from './types';
|
||||
|
||||
export default async function setupInstance(
|
||||
setupWizardOptions: SetupWizardOptions
|
||||
) {
|
||||
const { companyName, country, bankName, chartOfAccounts } =
|
||||
setupWizardOptions;
|
||||
await updateSystemSettings(setupWizardOptions);
|
||||
await updateAccountingSettings(setupWizardOptions);
|
||||
await updatePrintSettings(setupWizardOptions);
|
||||
|
||||
await createCurrencyRecords();
|
||||
await createAccountRecords(bankName, country, chartOfAccounts);
|
||||
await createRegionalRecords(country);
|
||||
|
||||
await completeSetup(companyName);
|
||||
}
|
||||
|
||||
async function updateAccountingSettings({
|
||||
companyName,
|
||||
country,
|
||||
name,
|
||||
email,
|
||||
bankName,
|
||||
fiscalYearStart,
|
||||
fiscalYearEnd,
|
||||
}: SetupWizardOptions) {
|
||||
const accountingSettings = (await fyo.doc.getSingle(
|
||||
'AccountingSettings'
|
||||
)) as AccountingSettings;
|
||||
await accountingSettings.setAndUpdate({
|
||||
companyName,
|
||||
country,
|
||||
fullname: name,
|
||||
email,
|
||||
bankName,
|
||||
fiscalYearStart,
|
||||
fiscalYearEnd,
|
||||
});
|
||||
return accountingSettings;
|
||||
}
|
||||
|
||||
async function updatePrintSettings({
|
||||
companyLogo,
|
||||
companyName,
|
||||
email,
|
||||
}: SetupWizardOptions) {
|
||||
const printSettings = await fyo.doc.getSingle('PrintSettings');
|
||||
await printSettings.setAndUpdate({
|
||||
logo: companyLogo,
|
||||
companyName,
|
||||
email,
|
||||
displayLogo: companyLogo ? true : false,
|
||||
});
|
||||
}
|
||||
|
||||
async function updateSystemSettings({
|
||||
country,
|
||||
currency: companyCurrency,
|
||||
}: SetupWizardOptions) {
|
||||
// @ts-ignore
|
||||
const countryOptions = countryInfo[country] as CountrySettings;
|
||||
const currency =
|
||||
companyCurrency ?? countryOptions.currency ?? DEFAULT_CURRENCY;
|
||||
const locale = countryOptions.locale ?? DEFAULT_LOCALE;
|
||||
const systemSettings = await fyo.doc.getSingle('SystemSettings');
|
||||
systemSettings.setAndUpdate({
|
||||
locale,
|
||||
currency,
|
||||
});
|
||||
}
|
||||
|
||||
async function createCurrencyRecords() {
|
||||
const promises: Promise<Doc | undefined>[] = [];
|
||||
const queue: string[] = [];
|
||||
const countrySettings: CountrySettings[] = Object.values(
|
||||
// @ts-ignore
|
||||
countryInfo as Record<string, CountrySettings>
|
||||
);
|
||||
|
||||
for (const country of countrySettings) {
|
||||
const {
|
||||
currency,
|
||||
currency_fraction,
|
||||
currency_fraction_units,
|
||||
smallest_currency_fraction_value,
|
||||
currency_symbol,
|
||||
} = country;
|
||||
|
||||
if (!currency || queue.includes(currency)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const docObject = {
|
||||
name: currency,
|
||||
fraction: currency_fraction ?? '',
|
||||
fractionUnits: currency_fraction_units ?? 100,
|
||||
smallestValue: smallest_currency_fraction_value ?? 0.01,
|
||||
symbol: currency_symbol ?? '',
|
||||
};
|
||||
|
||||
const doc = checkAndCreateDoc('Currency', docObject);
|
||||
if (doc) {
|
||||
promises.push(doc);
|
||||
queue.push(currency);
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
async function createAccountRecords(
|
||||
bankName: string,
|
||||
country: string,
|
||||
chartOfAccounts: string
|
||||
) {
|
||||
await createCOA(chartOfAccounts);
|
||||
const parentAccount = await getBankAccountParentName(country);
|
||||
const docObject = {
|
||||
name: bankName,
|
||||
rootType: 'Asset',
|
||||
parentAccount,
|
||||
accountType: 'Bank',
|
||||
isGroup: false,
|
||||
};
|
||||
await checkAndCreateDoc('Account', docObject);
|
||||
}
|
||||
|
||||
async function completeSetup(companyName: string) {
|
||||
updateInitializationConfig(companyName);
|
||||
await fyo.singles.AccountingSettings!.set('setupComplete', true);
|
||||
await fyo.singles.AccountingSettings!.update();
|
||||
}
|
||||
|
||||
function updateInitializationConfig(companyName: string) {
|
||||
const dbPath = fyo.db.dbPath;
|
||||
const files = fyo.config.get('files', []) as ConfigFile[];
|
||||
|
||||
files.forEach((file) => {
|
||||
if (file.dbPath === dbPath) {
|
||||
file.companyName = companyName;
|
||||
file.id = getId();
|
||||
}
|
||||
});
|
||||
|
||||
fyo.config.set('files', files);
|
||||
}
|
||||
|
||||
async function checkAndCreateDoc(schemaName: string, docObject: DocValueMap) {
|
||||
const canCreate = await checkIfExactRecordAbsent(schemaName, docObject);
|
||||
if (!canCreate) {
|
||||
return;
|
||||
}
|
||||
|
||||
const doc = await fyo.doc.getNewDoc(schemaName, docObject);
|
||||
return doc.insert();
|
||||
}
|
||||
|
||||
async function checkIfExactRecordAbsent(
|
||||
schemaName: string,
|
||||
docMap: DocValueMap
|
||||
) {
|
||||
const name = docMap.name as string;
|
||||
const newDocObject = Object.assign({}, docMap);
|
||||
|
||||
const rows = await fyo.db.getAllRaw(schemaName, {
|
||||
fields: ['*'],
|
||||
filters: { name },
|
||||
});
|
||||
|
||||
if (rows.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const storedDocObject = rows[0];
|
||||
const matchList = Object.keys(newDocObject).map((key) => {
|
||||
const newValue = newDocObject[key];
|
||||
const storedValue = storedDocObject[key];
|
||||
return newValue == storedValue; // Should not be type sensitive.
|
||||
});
|
||||
|
||||
if (!matchList.every(Boolean)) {
|
||||
await fyo.db.delete(schemaName, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async function getBankAccountParentName(country: string) {
|
||||
const parentBankAccount = await fyo.db.getAllRaw('Account', {
|
||||
fields: ['*'],
|
||||
filters: { isGroup: true, accountType: 'Bank' },
|
||||
});
|
||||
|
||||
if (parentBankAccount.length === 0) {
|
||||
// This should not happen if the fixtures are correct.
|
||||
return 'Bank Accounts';
|
||||
} else if (parentBankAccount.length > 1) {
|
||||
switch (country) {
|
||||
case 'Indonesia':
|
||||
return 'Bank Rupiah - 1121.000';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return parentBankAccount[0].name;
|
||||
}
|
175
src/setup/standardCOA.ts
Normal file
175
src/setup/standardCOA.ts
Normal file
@ -0,0 +1,175 @@
|
||||
import { t } from 'fyo';
|
||||
import { COATree } from 'models/baseModels/Account/types';
|
||||
|
||||
export function getStandardCOA(): COATree {
|
||||
return {
|
||||
[t`Application of Funds (Assets)`]: {
|
||||
[t`Current Assets`]: {
|
||||
[t`Accounts Receivable`]: {
|
||||
[t`Debtors`]: {
|
||||
accountType: 'Receivable',
|
||||
},
|
||||
},
|
||||
[t`Bank Accounts`]: {
|
||||
accountType: 'Bank',
|
||||
isGroup: true,
|
||||
},
|
||||
[t`Cash In Hand`]: {
|
||||
[t`Cash`]: {
|
||||
accountType: 'Cash',
|
||||
},
|
||||
accountType: 'Cash',
|
||||
},
|
||||
[t`Loans and Advances (Assets)`]: {
|
||||
isGroup: true,
|
||||
},
|
||||
[t`Securities and Deposits`]: {
|
||||
[t`Earnest Money`]: {},
|
||||
},
|
||||
[t`Stock Assets`]: {
|
||||
[t`Stock In Hand`]: {
|
||||
accountType: 'Stock',
|
||||
},
|
||||
accountType: 'Stock',
|
||||
},
|
||||
[t`Tax Assets`]: {
|
||||
isGroup: true,
|
||||
},
|
||||
},
|
||||
[t`Fixed Assets`]: {
|
||||
[t`Capital Equipments`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Electronic Equipments`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Furnitures and Fixtures`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Office Equipments`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Plants and Machineries`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Buildings`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Softwares`]: {
|
||||
accountType: 'Fixed Asset',
|
||||
},
|
||||
[t`Accumulated Depreciation`]: {
|
||||
accountType: 'Accumulated Depreciation',
|
||||
},
|
||||
},
|
||||
[t`Investments`]: {
|
||||
isGroup: true,
|
||||
},
|
||||
[t`Temporary Accounts`]: {
|
||||
[t`Temporary Opening`]: {
|
||||
accountType: 'Temporary',
|
||||
},
|
||||
},
|
||||
rootType: 'Asset',
|
||||
},
|
||||
[t`Expenses`]: {
|
||||
[t`Direct Expenses`]: {
|
||||
[t`Stock Expenses`]: {
|
||||
[t`Cost of Goods Sold`]: {
|
||||
accountType: 'Cost of Goods Sold',
|
||||
},
|
||||
[t`Expenses Included In Valuation`]: {
|
||||
accountType: 'Expenses Included In Valuation',
|
||||
},
|
||||
[t`Stock Adjustment`]: {
|
||||
accountType: 'Stock Adjustment',
|
||||
},
|
||||
},
|
||||
},
|
||||
[t`Indirect Expenses`]: {
|
||||
[t`Administrative Expenses`]: {},
|
||||
[t`Commission on Sales`]: {},
|
||||
[t`Depreciation`]: {
|
||||
accountType: 'Depreciation',
|
||||
},
|
||||
[t`Entertainment Expenses`]: {},
|
||||
[t`Freight and Forwarding Charges`]: {
|
||||
accountType: 'Chargeable',
|
||||
},
|
||||
[t`Legal Expenses`]: {},
|
||||
[t`Marketing Expenses`]: {
|
||||
accountType: 'Chargeable',
|
||||
},
|
||||
[t`Miscellaneous Expenses`]: {
|
||||
accountType: 'Chargeable',
|
||||
},
|
||||
[t`Office Maintenance Expenses`]: {},
|
||||
[t`Office Rent`]: {},
|
||||
[t`Postal Expenses`]: {},
|
||||
[t`Print and Stationery`]: {},
|
||||
[t`Round Off`]: {
|
||||
accountType: 'Round Off',
|
||||
},
|
||||
[t`Salary`]: {},
|
||||
[t`Sales Expenses`]: {},
|
||||
[t`Telephone Expenses`]: {},
|
||||
[t`Travel Expenses`]: {},
|
||||
[t`Utility Expenses`]: {},
|
||||
[t`Write Off`]: {},
|
||||
[t`Exchange Gain/Loss`]: {},
|
||||
[t`Gain/Loss on Asset Disposal`]: {},
|
||||
},
|
||||
rootType: 'Expense',
|
||||
},
|
||||
[t`Income`]: {
|
||||
[t`Direct Income`]: {
|
||||
[t`Sales`]: {},
|
||||
[t`Service`]: {},
|
||||
},
|
||||
[t`Indirect Income`]: {
|
||||
isGroup: true,
|
||||
},
|
||||
rootType: 'Income',
|
||||
},
|
||||
[t`Source of Funds (Liabilities)`]: {
|
||||
[t`Current Liabilities`]: {
|
||||
[t`Accounts Payable`]: {
|
||||
[t`Creditors`]: {
|
||||
accountType: 'Payable',
|
||||
},
|
||||
[t`Payroll Payable`]: {},
|
||||
},
|
||||
[t`Stock Liabilities`]: {
|
||||
[t`Stock Received But Not Billed`]: {
|
||||
accountType: 'Stock Received But Not Billed',
|
||||
},
|
||||
},
|
||||
[t`Duties and Taxes`]: {
|
||||
accountType: 'Tax',
|
||||
isGroup: true,
|
||||
},
|
||||
[t`Loans (Liabilities)`]: {
|
||||
[t`Secured Loans`]: {},
|
||||
[t`Unsecured Loans`]: {},
|
||||
[t`Bank Overdraft Account`]: {},
|
||||
},
|
||||
},
|
||||
rootType: 'Liability',
|
||||
},
|
||||
[t`Equity`]: {
|
||||
[t`Capital Stock`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
[t`Dividends Paid`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
[t`Opening Balance Equity`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
[t`Retained Earnings`]: {
|
||||
accountType: 'Equity',
|
||||
},
|
||||
rootType: 'Equity',
|
||||
},
|
||||
};
|
||||
}
|
25
src/setup/types.ts
Normal file
25
src/setup/types.ts
Normal file
@ -0,0 +1,25 @@
|
||||
export interface SetupWizardOptions {
|
||||
companyLogo: string;
|
||||
companyName: string;
|
||||
country: string;
|
||||
fullname: string;
|
||||
name: string;
|
||||
email: string;
|
||||
bankName: string;
|
||||
currency: string;
|
||||
fiscalYearStart: string;
|
||||
fiscalYearEnd: string;
|
||||
chartOfAccounts: string;
|
||||
}
|
||||
|
||||
export interface CountrySettings {
|
||||
code: string;
|
||||
currency: string;
|
||||
fiscal_year_start: string;
|
||||
fiscal_year_end: string;
|
||||
locale: string;
|
||||
currency_fraction?: string;
|
||||
currency_fraction_units?: number;
|
||||
smallest_currency_fraction_value?: number;
|
||||
currency_symbol?: string;
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import frappe, { t } from 'frappe';
|
||||
import { t } from 'fyo';
|
||||
import { fyo } from './initFyo';
|
||||
|
||||
const config = {
|
||||
getTitle: async () => {
|
||||
const { companyName } = await frappe.getSingle('AccountingSettings');
|
||||
const { companyName } = await fyo.doc.getSingle('AccountingSettings');
|
||||
return companyName;
|
||||
},
|
||||
getGroups: () => [
|
||||
@ -113,12 +114,12 @@ const config = {
|
||||
{
|
||||
label: t`GSTR1`,
|
||||
route: '/report/gstr-1',
|
||||
hidden: () => frappe.AccountingSettings.country !== 'India',
|
||||
hidden: () => fyo.singles.AccountingSettings!.country !== 'India',
|
||||
},
|
||||
{
|
||||
label: t`GSTR2`,
|
||||
route: '/report/gstr-2',
|
||||
hidden: () => frappe.AccountingSettings.country !== 'India',
|
||||
hidden: () => fyo.singles.AccountingSettings!.country !== 'India',
|
||||
},
|
||||
],
|
||||
},
|
30
src/ui.js
30
src/ui.js
@ -1,30 +0,0 @@
|
||||
let instances = [];
|
||||
|
||||
function onDocumentClick(e, el, fn) {
|
||||
let target = e.target;
|
||||
if (el !== target && !el.contains(target)) {
|
||||
fn(e);
|
||||
}
|
||||
}
|
||||
|
||||
export const outsideClickDirective = {
|
||||
beforeMount(el, binding) {
|
||||
el.dataset.outsideClickIndex = instances.length;
|
||||
|
||||
const fn = binding.value;
|
||||
const click = function (e) {
|
||||
onDocumentClick(e, el, fn);
|
||||
};
|
||||
|
||||
document.addEventListener('click', click);
|
||||
instances.push(click);
|
||||
},
|
||||
unmounted(el) {
|
||||
const index = el.dataset.outsideClickIndex;
|
||||
const handler = instances[index];
|
||||
document.addEventListener('click', handler);
|
||||
instances.splice(index, 1);
|
||||
},
|
||||
};
|
||||
|
||||
// https://github.com/frappe/frappejs/commits/master/ui/plugins/outsideClickDirective.js
|
@ -60,3 +60,12 @@ export function getYMin(points: Array<Array<number>>): number {
|
||||
|
||||
return getVal(minVal);
|
||||
}
|
||||
|
||||
export function formatXLabels(label: string) {
|
||||
// Format: Mmm YYYY -> Mm YY
|
||||
const splits = label.split(' ');
|
||||
const month = splits[0];
|
||||
const year = splits[1].slice(2);
|
||||
|
||||
return `${month} ${year}`;
|
||||
}
|
@ -67,15 +67,6 @@ export function fuzzyMatch(keyword: string, candidate: string) {
|
||||
return { isMatch, distance };
|
||||
}
|
||||
|
||||
export function formatXLabels(label: string) {
|
||||
// Format: Mmm YYYY -> Mm YY
|
||||
const splits = label.split(' ');
|
||||
const month = splits[0];
|
||||
const year = splits[1].slice(2);
|
||||
|
||||
return `${month} ${year}`;
|
||||
}
|
||||
|
||||
export function convertPesaValuesToFloat(obj: Record<string, unknown>) {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
const value = obj[key];
|
||||
@ -86,12 +77,3 @@ export function convertPesaValuesToFloat(obj: Record<string, unknown>) {
|
||||
obj[key] = (value as Money).float;
|
||||
});
|
||||
}
|
||||
|
||||
export async function getIsSetupComplete() {
|
||||
try {
|
||||
const { setupComplete } = await fyo.doc.getSingle('AccountingSettings');
|
||||
return !!setupComplete;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
import frappe from 'frappe';
|
||||
import { DateTime } from 'luxon';
|
||||
import { fyo } from 'src/initFyo';
|
||||
|
||||
export async function getDatesAndPeriodicity(period) {
|
||||
export async function getDatesAndPeriodicity(
|
||||
period: 'This Year' | 'This Quarter' | 'This Month'
|
||||
) {
|
||||
let fromDate, toDate;
|
||||
let periodicity = 'Monthly';
|
||||
let accountingSettings = await frappe.getSingle('AccountingSettings');
|
||||
const periodicity = 'Monthly';
|
||||
const accountingSettings = await fyo.doc.getSingle('AccountingSettings');
|
||||
|
||||
if (period === 'This Year') {
|
||||
fromDate = accountingSettings.fiscalYearStart;
|
@ -26,4 +26,4 @@ export interface QuickEditOptions {
|
||||
hideFields?: string[];
|
||||
showFields?: string[];
|
||||
defaults?: Record<string, unknown>;
|
||||
}
|
||||
}
|
@ -27,11 +27,11 @@ module.exports = {
|
||||
},
|
||||
pages: {
|
||||
index: {
|
||||
entry: 'src/main.js',
|
||||
entry: 'src/renderer.ts',
|
||||
filename: 'index.html',
|
||||
},
|
||||
print: {
|
||||
entry: 'src/print.js',
|
||||
entry: 'src/print.ts',
|
||||
filename: 'print.html',
|
||||
},
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user