mirror of
https://github.com/frappe/books.git
synced 2024-12-23 03:19:01 +00:00
incr: convert simple models to .ts Doc subclass
This commit is contained in:
parent
309c5c7474
commit
cb54100db4
@ -29,8 +29,12 @@ import { setName } from './naming';
|
|||||||
import {
|
import {
|
||||||
DefaultMap,
|
DefaultMap,
|
||||||
DependsOnMap,
|
DependsOnMap,
|
||||||
|
FiltersMap,
|
||||||
FormulaMap,
|
FormulaMap,
|
||||||
|
ListsMap,
|
||||||
|
ListViewSettings,
|
||||||
RequiredMap,
|
RequiredMap,
|
||||||
|
TreeViewSettings,
|
||||||
ValidationMap,
|
ValidationMap,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { validateSelect } from './validationFunction';
|
import { validateSelect } from './validationFunction';
|
||||||
@ -697,4 +701,9 @@ export default class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
validations: ValidationMap = {};
|
validations: ValidationMap = {};
|
||||||
required: RequiredMap = {};
|
required: RequiredMap = {};
|
||||||
dependsOn: DependsOnMap = {};
|
dependsOn: DependsOnMap = {};
|
||||||
|
|
||||||
|
static lists: ListsMap = {};
|
||||||
|
static filters: FiltersMap = {};
|
||||||
|
static listSettings: ListViewSettings = {};
|
||||||
|
static treeSettings?: TreeViewSettings;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { DocValue } from 'frappe/core/types';
|
import { DocValue } from 'frappe/core/types';
|
||||||
|
import { FieldType } from 'schemas/types';
|
||||||
|
import { QueryFilter } from 'utils/db/types';
|
||||||
import Doc from './doc';
|
import Doc from './doc';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,7 +15,7 @@ import Doc from './doc';
|
|||||||
* - `Validation`: Async function that throw an error if the value is invalid.
|
* - `Validation`: Async function that throw an error if the value is invalid.
|
||||||
* - `Required`: Regular function used to decide if a value is mandatory (there are !notnul in the db).
|
* - `Required`: Regular function used to decide if a value is mandatory (there are !notnul in the db).
|
||||||
*/
|
*/
|
||||||
export type Formula = () => Promise<DocValue>;
|
export type Formula = () => Promise<DocValue | undefined>;
|
||||||
export type Default = () => DocValue;
|
export type Default = () => DocValue;
|
||||||
export type Validation = (value: DocValue) => Promise<void>;
|
export type Validation = (value: DocValue) => Promise<void>;
|
||||||
export type Required = () => boolean;
|
export type Required = () => boolean;
|
||||||
@ -23,11 +25,38 @@ export type DefaultMap = Record<string, Default | undefined>;
|
|||||||
export type ValidationMap = Record<string, Validation | undefined>;
|
export type ValidationMap = Record<string, Validation | undefined>;
|
||||||
export type RequiredMap = Record<string, Required | undefined>;
|
export type RequiredMap = Record<string, Required | undefined>;
|
||||||
|
|
||||||
export type DependsOnMap = Record<string, string[]>
|
export type DependsOnMap = Record<string, string[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should add this for hidden too
|
* Should add this for hidden too
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type ModelMap = Record< string, typeof Doc | undefined>
|
export type ModelMap = Record<string, typeof Doc | undefined>;
|
||||||
export type DocMap = Record<string, Doc | undefined>;
|
export type DocMap = Record<string, Doc | undefined>;
|
||||||
|
|
||||||
|
// Static Config properties
|
||||||
|
|
||||||
|
export type FilterFunction = (doc: Doc) => QueryFilter;
|
||||||
|
export type FiltersMap = Record<string, FilterFunction>;
|
||||||
|
|
||||||
|
export type ListFunction = () => string[];
|
||||||
|
export type ListsMap = Record<string, ListFunction>;
|
||||||
|
|
||||||
|
export interface ColumnConfig {
|
||||||
|
label: string;
|
||||||
|
fieldtype: FieldType;
|
||||||
|
size?: string;
|
||||||
|
render?: (doc: Doc) => { template: string };
|
||||||
|
getValue?: (doc: Doc) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ListViewColumn = string | ColumnConfig;
|
||||||
|
export interface ListViewSettings {
|
||||||
|
formRoute?: (name: string) => string;
|
||||||
|
columns?: ListViewColumn[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TreeViewSettings {
|
||||||
|
parentField: string;
|
||||||
|
getRootLabel: () => Promise<string>;
|
||||||
|
}
|
||||||
|
50
models/baseModels/Account/Account.ts
Normal file
50
models/baseModels/Account/Account.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import frappe from 'frappe';
|
||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import {
|
||||||
|
FiltersMap,
|
||||||
|
ListViewSettings,
|
||||||
|
TreeViewSettings,
|
||||||
|
} from 'frappe/model/types';
|
||||||
|
import { QueryFilter } from 'utils/db/types';
|
||||||
|
|
||||||
|
export default class Account extends Doc {
|
||||||
|
async beforeInsert() {
|
||||||
|
if (this.accountType || !this.parentAccount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const account = await frappe.db.get(
|
||||||
|
'Account',
|
||||||
|
this.parentAccount as string
|
||||||
|
);
|
||||||
|
this.accountType = account.accountType as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static listSettings: ListViewSettings = {
|
||||||
|
columns: ['name', 'parentAccount', 'rootType'],
|
||||||
|
};
|
||||||
|
|
||||||
|
static treeSettings: TreeViewSettings = {
|
||||||
|
parentField: 'parentAccount',
|
||||||
|
async getRootLabel(): Promise<string> {
|
||||||
|
const accountingSettings = await frappe.doc.getSingle(
|
||||||
|
'AccountingSettings'
|
||||||
|
);
|
||||||
|
return accountingSettings.companyName as string;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static filters: FiltersMap = {
|
||||||
|
parentAccount: (doc: Doc) => {
|
||||||
|
const filter: QueryFilter = {
|
||||||
|
isGroup: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (doc.rootType) {
|
||||||
|
filter.rootType = doc.rootType as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import { ListViewSettings } from 'frappe/model/types';
|
||||||
|
|
||||||
|
export class AccountingLedgerEntry extends Doc {
|
||||||
|
static listSettings: ListViewSettings = {
|
||||||
|
columns: ['account', 'party', 'debit', 'credit', 'balance'],
|
||||||
|
};
|
||||||
|
}
|
20
models/baseModels/AccountingSettings/AccountingSettings.ts
Normal file
20
models/baseModels/AccountingSettings/AccountingSettings.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import { FiltersMap, ListsMap } from 'frappe/model/types';
|
||||||
|
import countryInfo from '../../../fixtures/countryInfo.json';
|
||||||
|
|
||||||
|
export class AccountingSettings extends Doc {
|
||||||
|
static filters: FiltersMap = {
|
||||||
|
writeOffAccount: () => ({
|
||||||
|
isGroup: false,
|
||||||
|
rootType: 'Expense',
|
||||||
|
}),
|
||||||
|
roundOffAccount: () => ({
|
||||||
|
isGroup: false,
|
||||||
|
rootType: 'Expense',
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
static lists: ListsMap = {
|
||||||
|
country: () => Object.keys(countryInfo),
|
||||||
|
};
|
||||||
|
}
|
35
models/baseModels/JournalEntryAccount/JournalEntryAccount.ts
Normal file
35
models/baseModels/JournalEntryAccount/JournalEntryAccount.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import frappe from 'frappe';
|
||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import { FiltersMap, FormulaMap } from 'frappe/model/types';
|
||||||
|
import Money from 'pesa/dist/types/src/money';
|
||||||
|
|
||||||
|
export class JournalEntryAccount extends Doc {
|
||||||
|
getAutoDebitCredit(type: 'debit' | 'credit') {
|
||||||
|
const otherType = type === 'debit' ? 'credit' : 'debit';
|
||||||
|
|
||||||
|
const otherTypeValue = this.get(otherType) as Money;
|
||||||
|
if (!otherTypeValue.isZero()) {
|
||||||
|
return frappe.pesa(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalType = this.parentdoc!.getSum('accounts', type, false) as Money;
|
||||||
|
const totalOtherType = this.parentdoc!.getSum(
|
||||||
|
'accounts',
|
||||||
|
otherType,
|
||||||
|
false
|
||||||
|
) as Money;
|
||||||
|
|
||||||
|
if (totalType.lt(totalOtherType)) {
|
||||||
|
return totalOtherType.sub(totalType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formulas: FormulaMap = {
|
||||||
|
debit: async () => this.getAutoDebitCredit('debit'),
|
||||||
|
credit: async () => this.getAutoDebitCredit('credit'),
|
||||||
|
};
|
||||||
|
|
||||||
|
static filters: FiltersMap = {
|
||||||
|
account: () => ({ isGroup: false }),
|
||||||
|
};
|
||||||
|
}
|
28
models/baseModels/PaymentFor/PaymentFor.ts
Normal file
28
models/baseModels/PaymentFor/PaymentFor.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import frappe from 'frappe';
|
||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import { FiltersMap, FormulaMap } from 'frappe/model/types';
|
||||||
|
import Money from 'pesa/dist/types/src/money';
|
||||||
|
|
||||||
|
export class PaymentFor extends Doc {
|
||||||
|
formulas: FormulaMap = {
|
||||||
|
amount: async () => {
|
||||||
|
const outstandingAmount = this.parentdoc!.getFrom(
|
||||||
|
this.referenceType as string,
|
||||||
|
this.referenceName as string,
|
||||||
|
'outstandingAmount'
|
||||||
|
) as Money;
|
||||||
|
|
||||||
|
if (outstandingAmount) {
|
||||||
|
return outstandingAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frappe.pesa(0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static filters: FiltersMap = {
|
||||||
|
referenceName: () => ({
|
||||||
|
outstandingAmount: ['>', 0],
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
95
models/baseModels/SetupWizard/SetupWizard.ts
Normal file
95
models/baseModels/SetupWizard/SetupWizard.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import frappe from 'frappe';
|
||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import { FormulaMap, ListsMap } from 'frappe/model/types';
|
||||||
|
import { DateTime } from 'luxon';
|
||||||
|
import countryInfo from '../../../fixtures/countryInfo.json';
|
||||||
|
|
||||||
|
export function getCOAList() {
|
||||||
|
return [
|
||||||
|
{ name: frappe.t`Standard Chart of Accounts`, countryCode: '' },
|
||||||
|
|
||||||
|
{ countryCode: 'ae', name: 'U.A.E - Chart of Accounts' },
|
||||||
|
{
|
||||||
|
countryCode: 'ca',
|
||||||
|
name: 'Canada - Plan comptable pour les provinces francophones',
|
||||||
|
},
|
||||||
|
{ countryCode: 'gt', name: 'Guatemala - Cuentas' },
|
||||||
|
{ countryCode: 'hu', name: 'Hungary - Chart of Accounts' },
|
||||||
|
{ countryCode: 'id', name: 'Indonesia - Chart of Accounts' },
|
||||||
|
{ countryCode: 'in', name: 'India - Chart of Accounts' },
|
||||||
|
{ countryCode: 'mx', name: 'Mexico - Plan de Cuentas' },
|
||||||
|
{ countryCode: 'ni', name: 'Nicaragua - Catalogo de Cuentas' },
|
||||||
|
{ countryCode: 'nl', name: 'Netherlands - Grootboekschema' },
|
||||||
|
{ countryCode: 'sg', name: 'Singapore - Chart of Accounts' },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SetupWizard extends Doc {
|
||||||
|
formulas: FormulaMap = {
|
||||||
|
fiscalYearStart: async () => {
|
||||||
|
if (!this.country) return;
|
||||||
|
|
||||||
|
const today = DateTime.local();
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const fyStart = countryInfo[this.country].fiscal_year_start as
|
||||||
|
| string
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
if (fyStart) {
|
||||||
|
return DateTime.fromFormat(fyStart, 'MM-dd')
|
||||||
|
.plus({ year: [1, 2, 3].includes(today.month) ? -1 : 0 })
|
||||||
|
.toISODate();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fiscalYearEnd: async () => {
|
||||||
|
if (!this.country) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const today = DateTime.local();
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const fyEnd = countryInfo[this.country].fiscal_year_end as
|
||||||
|
| string
|
||||||
|
| undefined;
|
||||||
|
if (fyEnd) {
|
||||||
|
return DateTime.fromFormat(fyEnd, 'MM-dd')
|
||||||
|
.plus({ year: [1, 2, 3].includes(today.month) ? 0 : 1 })
|
||||||
|
.toISODate();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
currency: async () => {
|
||||||
|
if (!this.country) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
return countryInfo[this.country].currency;
|
||||||
|
},
|
||||||
|
chartOfAccounts: async () => {
|
||||||
|
const country = this.get('country') as string | undefined;
|
||||||
|
if (country === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const code = (countryInfo[country] as undefined | { code: string })?.code;
|
||||||
|
if (code === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const coaList = getCOAList();
|
||||||
|
const coa = coaList.find(({ countryCode }) => countryCode === code);
|
||||||
|
|
||||||
|
if (coa === undefined) {
|
||||||
|
return coaList[0].name;
|
||||||
|
}
|
||||||
|
return coa.name;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static lists: ListsMap = {
|
||||||
|
country: () => Object.keys(countryInfo),
|
||||||
|
chartOfAccounts: () => getCOAList().map(({ name }) => name),
|
||||||
|
};
|
||||||
|
}
|
13
models/baseModels/TaxSummary/TaxSummary.ts
Normal file
13
models/baseModels/TaxSummary/TaxSummary.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Doc from 'frappe/model/doc';
|
||||||
|
import { FormulaMap } from 'frappe/model/types';
|
||||||
|
import Money from 'pesa/dist/types/src/money';
|
||||||
|
|
||||||
|
export class TaxSummary extends Doc {
|
||||||
|
formulas: FormulaMap = {
|
||||||
|
baseAmount: async () => {
|
||||||
|
const amount = this.amount as Money;
|
||||||
|
const exchangeRate = (this.parentdoc?.exchangeRate ?? 1) as number;
|
||||||
|
return amount.mul(exchangeRate);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -1,95 +0,0 @@
|
|||||||
import frappe, { t } from 'frappe';
|
|
||||||
import Account from './AccountDocument';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Account',
|
|
||||||
label: t`Account`,
|
|
||||||
doctype: 'DocType',
|
|
||||||
documentClass: Account,
|
|
||||||
isSingle: 0,
|
|
||||||
isTree: 1,
|
|
||||||
keywordFields: ['name', 'rootType', 'accountType'],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'name',
|
|
||||||
label: t`Account Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'rootType',
|
|
||||||
label: t`Root Type`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
placeholder: t`Root Type`,
|
|
||||||
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'],
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'parentAccount',
|
|
||||||
label: t`Parent Account`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
getFilters: (query, doc) => {
|
|
||||||
const filter = {
|
|
||||||
isGroup: 1,
|
|
||||||
};
|
|
||||||
doc.rootType ? (filter.rootType = doc.rootType) : '';
|
|
||||||
return filter;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'accountType',
|
|
||||||
label: t`Account Type`,
|
|
||||||
placeholder: t`Account Type`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: [
|
|
||||||
'Accumulated Depreciation',
|
|
||||||
'Bank',
|
|
||||||
'Cash',
|
|
||||||
'Chargeable',
|
|
||||||
'Cost of Goods Sold',
|
|
||||||
'Depreciation',
|
|
||||||
'Equity',
|
|
||||||
'Expense Account',
|
|
||||||
'Expenses Included In Valuation',
|
|
||||||
'Fixed Asset',
|
|
||||||
'Income Account',
|
|
||||||
'Payable',
|
|
||||||
'Receivable',
|
|
||||||
'Round Off',
|
|
||||||
'Stock',
|
|
||||||
'Stock Adjustment',
|
|
||||||
'Stock Received But Not Billed',
|
|
||||||
'Tax',
|
|
||||||
'Temporary',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'balance',
|
|
||||||
label: t`Balance`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
readOnly: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'isGroup',
|
|
||||||
label: t`Is Group`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
quickEditFields: [
|
|
||||||
'name',
|
|
||||||
'rootType',
|
|
||||||
'parentAccount',
|
|
||||||
'accountType',
|
|
||||||
'isGroup',
|
|
||||||
],
|
|
||||||
|
|
||||||
treeSettings: {
|
|
||||||
parentField: 'parentAccount',
|
|
||||||
async getRootLabel() {
|
|
||||||
let accountingSettings = await frappe.getSingle('AccountingSettings');
|
|
||||||
return accountingSettings.companyName;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,11 +0,0 @@
|
|||||||
import frappe from 'frappe';
|
|
||||||
import Document from 'frappe/model/document';
|
|
||||||
|
|
||||||
export default class Account extends Document {
|
|
||||||
async validate() {
|
|
||||||
if (!this.accountType && this.parentAccount) {
|
|
||||||
const account = frappe.db.get('Account', this.parentAccount);
|
|
||||||
this.accountType = account.accountType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
doctype: 'Account',
|
|
||||||
title: t`Account`,
|
|
||||||
columns: ['name', 'parentAccount', 'rootType'],
|
|
||||||
};
|
|
@ -1,85 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'AccountingLedgerEntry',
|
|
||||||
label: t`Ledger Entry`,
|
|
||||||
naming: 'autoincrement',
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 0,
|
|
||||||
isChild: 0,
|
|
||||||
keywordFields: ['account', 'party', 'referenceName'],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'date',
|
|
||||||
label: t`Date`,
|
|
||||||
fieldtype: 'Date',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'account',
|
|
||||||
label: t`Account`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'description',
|
|
||||||
label: t`Description`,
|
|
||||||
fieldtype: 'Text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'party',
|
|
||||||
label: t`Party`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Party',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'debit',
|
|
||||||
label: t`Debit`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'credit',
|
|
||||||
label: t`Credit`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'againstAccount',
|
|
||||||
label: t`Against Account`,
|
|
||||||
fieldtype: 'Text',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'referenceType',
|
|
||||||
label: t`Ref. Type`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'referenceName',
|
|
||||||
label: t`Ref. Name`,
|
|
||||||
fieldtype: 'DynamicLink',
|
|
||||||
references: 'referenceType',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'balance',
|
|
||||||
label: t`Balance`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'reverted',
|
|
||||||
label: t`Reverted`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
default: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
quickEditFields: [
|
|
||||||
'date',
|
|
||||||
'account',
|
|
||||||
'description',
|
|
||||||
'party',
|
|
||||||
'debit',
|
|
||||||
'credit',
|
|
||||||
'againstAccount',
|
|
||||||
'referenceType',
|
|
||||||
'referenceName',
|
|
||||||
'balance',
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
doctype: 'AccountingLedgerEntry',
|
|
||||||
title: t`Accounting Ledger Entries`,
|
|
||||||
columns: ['account', 'party', 'debit', 'credit', 'balance'],
|
|
||||||
};
|
|
@ -1,129 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
import countryInfo from '~/fixtures/countryInfo.json';
|
|
||||||
|
|
||||||
const countryList = Object.keys(countryInfo).sort();
|
|
||||||
export default {
|
|
||||||
name: 'AccountingSettings',
|
|
||||||
label: t`Accounting Settings`,
|
|
||||||
naming: 'name', // {random|autoincrement}
|
|
||||||
isSingle: 1,
|
|
||||||
isChild: 0,
|
|
||||||
isSubmittable: 0,
|
|
||||||
settings: null,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
label: t`Company Name`,
|
|
||||||
fieldname: 'companyName',
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: t`Write Off Account`,
|
|
||||||
fieldname: 'writeOffAccount',
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
default: 'Write Off',
|
|
||||||
getFilters() {
|
|
||||||
return {
|
|
||||||
isGroup: 0,
|
|
||||||
rootType: 'Expense',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: t`Round Off Account`,
|
|
||||||
fieldname: 'roundOffAccount',
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
default: 'Rounded Off',
|
|
||||||
getFilters() {
|
|
||||||
return {
|
|
||||||
isGroup: 0,
|
|
||||||
rootType: 'Expense',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'country',
|
|
||||||
label: t`Country`,
|
|
||||||
fieldtype: 'AutoComplete',
|
|
||||||
placeholder: t`Select Country`,
|
|
||||||
readOnly: 1,
|
|
||||||
required: 1,
|
|
||||||
getList: () => countryList,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'currency',
|
|
||||||
label: t`Currency`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
readOnly: 1,
|
|
||||||
required: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'fullname',
|
|
||||||
label: t`Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'email',
|
|
||||||
label: t`Email`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
validate: {
|
|
||||||
type: 'email',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'bankName',
|
|
||||||
label: t`Bank Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'fiscalYearStart',
|
|
||||||
label: t`Fiscal Year Start Date`,
|
|
||||||
fieldtype: 'Date',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'fiscalYearEnd',
|
|
||||||
label: t`Fiscal Year End Date`,
|
|
||||||
fieldtype: 'Date',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'setupComplete',
|
|
||||||
label: t`Setup Complete`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
default: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'gstin',
|
|
||||||
label: t`GSTIN`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`27AAAAA0000A1Z5`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
quickEditFields: [
|
|
||||||
'fullname',
|
|
||||||
'email',
|
|
||||||
'companyName',
|
|
||||||
'country',
|
|
||||||
'currency',
|
|
||||||
'fiscalYearStart',
|
|
||||||
'fiscalYearEnd',
|
|
||||||
'gstin',
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,18 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Color',
|
|
||||||
doctype: 'DocType',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'name',
|
|
||||||
fieldtype: 'Data',
|
|
||||||
label: t`Color`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'hexvalue',
|
|
||||||
fieldtype: 'Data',
|
|
||||||
label: t`Hex Value`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,27 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'CompanySettings',
|
|
||||||
label: t`Company Settings`,
|
|
||||||
naming: 'autoincrement',
|
|
||||||
isSingle: true,
|
|
||||||
isChild: false,
|
|
||||||
keywordFields: ['companyName'],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'companyName',
|
|
||||||
label: t`Company Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'companyAddress',
|
|
||||||
label: t`Company Address`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
target: 'Address',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,78 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Contact',
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 0,
|
|
||||||
naming: 'autoincrement',
|
|
||||||
pageSettings: {
|
|
||||||
hideTitle: true,
|
|
||||||
},
|
|
||||||
titleField: 'fullName',
|
|
||||||
keywordFields: ['fullName'],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'fullName',
|
|
||||||
label: t`Full Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'emailAddress',
|
|
||||||
label: t`Email Address`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'userId',
|
|
||||||
label: t`User ID`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'User',
|
|
||||||
hidden: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'status',
|
|
||||||
label: t`Status`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: ['Passive', 'Open', 'Replied'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'gender',
|
|
||||||
label: t`Gender`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: ['Male', 'Female', 'Gender'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'mobileNumber',
|
|
||||||
label: t`Mobile Number`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'phone',
|
|
||||||
label: t`Phone`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
events: {
|
|
||||||
validate: (doc) => {},
|
|
||||||
},
|
|
||||||
|
|
||||||
listSettings: {
|
|
||||||
getFields(list) {
|
|
||||||
return ['fullName'];
|
|
||||||
},
|
|
||||||
getRowHTML(list, data) {
|
|
||||||
return `<div class="col-11">${list.getNameHTML(data)}</div>`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
layout: [
|
|
||||||
// section 1
|
|
||||||
{
|
|
||||||
columns: [
|
|
||||||
{ fields: ['fullName', 'emailAddress', 'userId', 'status'] },
|
|
||||||
{ fields: ['postalCode', 'gender', 'phone', 'mobileNumber'] },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,38 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Currency',
|
|
||||||
label: t`Currency`,
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 0,
|
|
||||||
keywordFields: ['name', 'symbol'],
|
|
||||||
quickEditFields: ['name', 'symbol'],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'name',
|
|
||||||
label: t`Currency Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'fraction',
|
|
||||||
label: t`Fraction`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'fractionUnits',
|
|
||||||
label: t`Fraction Units`,
|
|
||||||
fieldtype: 'Int',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t`Smallest Currency Fraction Value`,
|
|
||||||
fieldname: 'smallestValue',
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t`Symbol`,
|
|
||||||
fieldname: 'symbol',
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,67 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'GetStarted',
|
|
||||||
isSingle: 1,
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'onboardingComplete',
|
|
||||||
label: t`Onboarding Complete`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'companySetup',
|
|
||||||
label: t`Company Setup`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'systemSetup',
|
|
||||||
label: t`System Setup`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'invoiceSetup',
|
|
||||||
label: t`Invoice Setup`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'itemCreated',
|
|
||||||
label: t`Item Created`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'customerCreated',
|
|
||||||
label: t`Customer Created`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'supplierCreated',
|
|
||||||
label: t`Supplier Created`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'invoiceCreated',
|
|
||||||
label: t`Invoice Created`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'billCreated',
|
|
||||||
label: t`Bill Created`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'chartOfAccountsReviewed',
|
|
||||||
label: t`Chart Of Accounts Reviewed`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'openingBalanceChecked',
|
|
||||||
label: t`Opening Balances`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'taxesAdded',
|
|
||||||
label: t`Add Taxes`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,45 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'JournalEntryAccount',
|
|
||||||
isChild: 1,
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'account',
|
|
||||||
label: t`Account`,
|
|
||||||
placeholder: t`Account`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
required: 1,
|
|
||||||
groupBy: 'rootType',
|
|
||||||
getFilters: () => ({ isGroup: 0 }),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'debit',
|
|
||||||
label: t`Debit`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
formula: autoDebitCredit('debit'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'credit',
|
|
||||||
label: t`Credit`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
formula: autoDebitCredit('credit'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
tableFields: ['account', 'debit', 'credit'],
|
|
||||||
};
|
|
||||||
|
|
||||||
function autoDebitCredit(type) {
|
|
||||||
let otherType = type === 'debit' ? 'credit' : 'debit';
|
|
||||||
|
|
||||||
return (row, doc) => {
|
|
||||||
if (!row[otherType].isZero()) return frappe.pesa(0);
|
|
||||||
|
|
||||||
let totalType = doc.getSum('accounts', type, false);
|
|
||||||
let totalOtherType = doc.getSum('accounts', otherType, false);
|
|
||||||
|
|
||||||
if (totalType.lt(totalOtherType)) {
|
|
||||||
return totalOtherType.sub(totalType);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'JournalEntrySettings',
|
|
||||||
label: t`Journal Entry Setting`,
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 1,
|
|
||||||
isChild: 0,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [],
|
|
||||||
};
|
|
@ -1,54 +0,0 @@
|
|||||||
import frappe, { t } from 'frappe';
|
|
||||||
|
|
||||||
const referenceTypeMap = {
|
|
||||||
SalesInvoice: t`Invoice`,
|
|
||||||
PurchaseInvoice: t`Bill`,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'PaymentFor',
|
|
||||||
label: t`Payment For`,
|
|
||||||
isSingle: 0,
|
|
||||||
isChild: 1,
|
|
||||||
keywordFields: [],
|
|
||||||
tableFields: ['referenceType', 'referenceName', 'amount'],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'referenceType',
|
|
||||||
label: t`Reference Type`,
|
|
||||||
placeholder: t`Type`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: Object.keys(referenceTypeMap),
|
|
||||||
map: referenceTypeMap,
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'referenceName',
|
|
||||||
label: t`Reference Name`,
|
|
||||||
fieldtype: 'DynamicLink',
|
|
||||||
references: 'referenceType',
|
|
||||||
placeholder: t`Name`,
|
|
||||||
getFilters() {
|
|
||||||
return {
|
|
||||||
outstandingAmount: ['>', 0],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'amount',
|
|
||||||
label: t`Allocated Amount`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
formula: (row, doc) => {
|
|
||||||
return (
|
|
||||||
doc.getFrom(
|
|
||||||
row.referenceType,
|
|
||||||
row.referenceName,
|
|
||||||
'outstandingAmount'
|
|
||||||
) || frappe.pesa(0)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'PaymentSettings',
|
|
||||||
label: t`Payment Settings`,
|
|
||||||
isSingle: 1,
|
|
||||||
isChild: 0,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [],
|
|
||||||
};
|
|
@ -1,105 +0,0 @@
|
|||||||
import theme from '@/theme';
|
|
||||||
import { t } from 'frappe';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'PrintSettings',
|
|
||||||
label: t`Print Settings`,
|
|
||||||
isSingle: 1,
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'logo',
|
|
||||||
label: t`Logo`,
|
|
||||||
fieldtype: 'AttachImage',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'companyName',
|
|
||||||
label: t`Company Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'email',
|
|
||||||
label: t`Email`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`john@doe.com`,
|
|
||||||
validate: {
|
|
||||||
type: 'email',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'displayLogo',
|
|
||||||
label: t`Display Logo in Invoice`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'phone',
|
|
||||||
label: t`Phone`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`9888900000`,
|
|
||||||
validate: {
|
|
||||||
type: 'phone',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'address',
|
|
||||||
label: t`Address`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Address',
|
|
||||||
placeholder: t`Click to create`,
|
|
||||||
inline: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'template',
|
|
||||||
label: t`Template`,
|
|
||||||
placeholder: t`Template`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: ['Basic', 'Minimal', 'Business'],
|
|
||||||
default: 'Basic',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'color',
|
|
||||||
label: t`Color`,
|
|
||||||
placeholder: t`Select Color`,
|
|
||||||
fieldtype: 'Color',
|
|
||||||
colors: [
|
|
||||||
'red',
|
|
||||||
'orange',
|
|
||||||
'yellow',
|
|
||||||
'green',
|
|
||||||
'teal',
|
|
||||||
'blue',
|
|
||||||
'indigo',
|
|
||||||
'purple',
|
|
||||||
'pink',
|
|
||||||
]
|
|
||||||
.map((color) => {
|
|
||||||
let label = color[0].toUpperCase() + color.slice(1);
|
|
||||||
return {
|
|
||||||
label,
|
|
||||||
value: theme.colors[color]['500'],
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.concat({
|
|
||||||
label: t`Black`,
|
|
||||||
value: theme.colors['black'],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'font',
|
|
||||||
label: t`Font`,
|
|
||||||
placeholder: t`Font`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: ['Inter', 'Times New Roman', 'Arial', 'Courier'],
|
|
||||||
default: 'Inter',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
quickEditFields: [
|
|
||||||
'logo',
|
|
||||||
'displayLogo',
|
|
||||||
'template',
|
|
||||||
'color',
|
|
||||||
'font',
|
|
||||||
'email',
|
|
||||||
'phone',
|
|
||||||
'address',
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'PurchaseInvoiceSettings',
|
|
||||||
label: t`Bills Settings`,
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 1,
|
|
||||||
isChild: 0,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [],
|
|
||||||
};
|
|
@ -1,37 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'SalesInvoiceSettings',
|
|
||||||
label: t`SalesInvoice Settings`,
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 1,
|
|
||||||
isChild: 0,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'template',
|
|
||||||
label: t`Template`,
|
|
||||||
placeholder: t`Template`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: ['Basic I', 'Basic II', 'Modern'],
|
|
||||||
required: 1,
|
|
||||||
default: 'Basic I',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'font',
|
|
||||||
label: t`Font`,
|
|
||||||
placeholder: t`Font`,
|
|
||||||
fieldtype: 'Select',
|
|
||||||
options: ['Montserrat', 'Open Sans', 'Oxygen', 'Merriweather'],
|
|
||||||
required: 1,
|
|
||||||
default: 'Montserrat',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'themeColor',
|
|
||||||
label: t`Theme Color`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
default: '#000000',
|
|
||||||
hidden: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,150 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
import { DateTime } from 'luxon';
|
|
||||||
import countryList from '~/fixtures/countryInfo.json';
|
|
||||||
import { getCOAList } from '../../../src/utils';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'SetupWizard',
|
|
||||||
label: t`Setup Wizard`,
|
|
||||||
naming: 'name',
|
|
||||||
isSingle: 1,
|
|
||||||
isChild: 0,
|
|
||||||
isSubmittable: 0,
|
|
||||||
settings: null,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'companyLogo',
|
|
||||||
label: t`Company Logo`,
|
|
||||||
fieldtype: 'AttachImage',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'country',
|
|
||||||
label: t`Country`,
|
|
||||||
fieldtype: 'AutoComplete',
|
|
||||||
placeholder: t`Select Country`,
|
|
||||||
required: 1,
|
|
||||||
getList: () => Object.keys(countryList).sort(),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'fullname',
|
|
||||||
label: t`Your Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`John Doe`,
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'email',
|
|
||||||
label: t`Email`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`john@doe.com`,
|
|
||||||
required: 1,
|
|
||||||
validate: {
|
|
||||||
type: 'email',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'companyName',
|
|
||||||
label: t`Company Name`,
|
|
||||||
placeholder: t`Company Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'bankName',
|
|
||||||
label: t`Bank Name`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`Prime Bank`,
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'fiscalYearStart',
|
|
||||||
label: t`Fiscal Year Start Date`,
|
|
||||||
placeholder: t`Fiscal Year Start Date`,
|
|
||||||
fieldtype: 'Date',
|
|
||||||
formulaDependsOn: ['country'],
|
|
||||||
formula: (doc) => {
|
|
||||||
if (!doc.country) return;
|
|
||||||
let today = DateTime.local();
|
|
||||||
let fyStart = countryList[doc.country].fiscal_year_start;
|
|
||||||
if (fyStart) {
|
|
||||||
return DateTime.fromFormat(fyStart, 'MM-dd')
|
|
||||||
.plus({ year: [1, 2, 3].includes(today.month) ? -1 : 0 })
|
|
||||||
.toISODate();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
fieldname: 'fiscalYearEnd',
|
|
||||||
label: t`Fiscal Year End Date`,
|
|
||||||
placeholder: t`Fiscal Year End Date`,
|
|
||||||
fieldtype: 'Date',
|
|
||||||
formulaDependsOn: ['country'],
|
|
||||||
formula: (doc) => {
|
|
||||||
if (!doc.country) return;
|
|
||||||
let today = DateTime.local();
|
|
||||||
let fyEnd = countryList[doc.country].fiscal_year_end;
|
|
||||||
if (fyEnd) {
|
|
||||||
return DateTime.fromFormat(fyEnd, 'MM-dd')
|
|
||||||
.plus({ year: [1, 2, 3].includes(today.month) ? 0 : 1 })
|
|
||||||
.toISODate();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'currency',
|
|
||||||
label: t`Currency`,
|
|
||||||
fieldtype: 'Data',
|
|
||||||
placeholder: t`Currency`,
|
|
||||||
formulaDependsOn: ['country'],
|
|
||||||
formula: (doc) => {
|
|
||||||
if (!doc.country) return;
|
|
||||||
return countryList[doc.country].currency;
|
|
||||||
},
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'completed',
|
|
||||||
label: t`Completed`,
|
|
||||||
fieldtype: 'Check',
|
|
||||||
readonly: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'chartOfAccounts',
|
|
||||||
label: t`Chart of Accounts`,
|
|
||||||
fieldtype: 'AutoComplete',
|
|
||||||
placeholder: t`Select CoA`,
|
|
||||||
formulaDependsOn: ['country'],
|
|
||||||
formula: async (doc) => {
|
|
||||||
if (!doc.country) return;
|
|
||||||
|
|
||||||
const { code } = countryList[doc.country];
|
|
||||||
const coaList = getCOAList();
|
|
||||||
const coa = coaList.find(({ countryCode }) => countryCode === code);
|
|
||||||
|
|
||||||
if (coa === undefined) {
|
|
||||||
return coaList[0].name;
|
|
||||||
}
|
|
||||||
return coa.name;
|
|
||||||
},
|
|
||||||
getList: () => getCOAList().map(({ name }) => name),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
quickEditFields: [
|
|
||||||
'fullname',
|
|
||||||
'bankName',
|
|
||||||
'country',
|
|
||||||
'currency',
|
|
||||||
'chartOfAccounts',
|
|
||||||
'fiscalYearStart',
|
|
||||||
'fiscalYearEnd',
|
|
||||||
],
|
|
||||||
};
|
|
@ -1,26 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'TaxDetail',
|
|
||||||
label: t`Tax Detail`,
|
|
||||||
doctype: 'DocType',
|
|
||||||
isSingle: 0,
|
|
||||||
isChild: 1,
|
|
||||||
keywordFields: [],
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'account',
|
|
||||||
label: t`Tax Account`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'rate',
|
|
||||||
label: t`Rate`,
|
|
||||||
fieldtype: 'Float',
|
|
||||||
required: 1,
|
|
||||||
placeholder: t`0%`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
tableFields: ['account', 'rate'],
|
|
||||||
};
|
|
@ -1,34 +0,0 @@
|
|||||||
import { t } from 'frappe';
|
|
||||||
export default {
|
|
||||||
name: 'TaxSummary',
|
|
||||||
doctype: 'DocType',
|
|
||||||
isChild: 1,
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldname: 'account',
|
|
||||||
label: t`Tax Account`,
|
|
||||||
fieldtype: 'Link',
|
|
||||||
target: 'Account',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'rate',
|
|
||||||
label: t`Rate`,
|
|
||||||
fieldtype: 'Float',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'amount',
|
|
||||||
label: t`Amount`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
required: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'baseAmount',
|
|
||||||
label: t`Amount (Company Currency)`,
|
|
||||||
fieldtype: 'Currency',
|
|
||||||
formula: (row, doc) => row.amount.mul(doc.exchangeRate),
|
|
||||||
readOnly: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@ -6,7 +6,7 @@
|
|||||||
* match on both ends.
|
* match on both ends.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { SchemaMap } from "schemas/types";
|
import { SchemaMap } from 'schemas/types';
|
||||||
|
|
||||||
type UnknownMap = Record<string, unknown>;
|
type UnknownMap = Record<string, unknown>;
|
||||||
export abstract class DatabaseBase {
|
export abstract class DatabaseBase {
|
||||||
@ -62,8 +62,10 @@ export interface GetAllOptions {
|
|||||||
order?: 'asc' | 'desc';
|
order?: 'asc' | 'desc';
|
||||||
}
|
}
|
||||||
|
|
||||||
export type QueryFilter = Record<string, string | string[]>;
|
export type QueryFilter = Record<
|
||||||
|
string,
|
||||||
|
boolean | string | (string | number)[]
|
||||||
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseDemuxBase is an abstract class that ensures that the function signatures
|
* DatabaseDemuxBase is an abstract class that ensures that the function signatures
|
||||||
@ -73,13 +75,19 @@ export type QueryFilter = Record<string, string | string[]>;
|
|||||||
* and bypassing all the API and IPC calls.
|
* and bypassing all the API and IPC calls.
|
||||||
*/
|
*/
|
||||||
export abstract class DatabaseDemuxBase {
|
export abstract class DatabaseDemuxBase {
|
||||||
abstract getSchemaMap(): Promise<SchemaMap> | SchemaMap
|
abstract getSchemaMap(): Promise<SchemaMap> | SchemaMap;
|
||||||
|
|
||||||
abstract createNewDatabase(dbPath: string, countryCode?: string): Promise<void>
|
abstract createNewDatabase(
|
||||||
|
dbPath: string,
|
||||||
|
countryCode?: string
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
abstract connectToDatabase(dbPath: string, countryCode?: string): Promise<void>
|
abstract connectToDatabase(
|
||||||
|
dbPath: string,
|
||||||
|
countryCode?: string
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
abstract call(method: DatabaseMethod, ...args: unknown[]): Promise<unknown>
|
abstract call(method: DatabaseMethod, ...args: unknown[]): Promise<unknown>;
|
||||||
|
|
||||||
abstract callBespoke(method: string, ...args: unknown[]): Promise<unknown>
|
abstract callBespoke(method: string, ...args: unknown[]): Promise<unknown>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user