mirror of
https://github.com/frappe/books.git
synced 2024-12-22 10:58:59 +00:00
316f052c53
- add support for default value in fields
156 lines
3.9 KiB
TypeScript
156 lines
3.9 KiB
TypeScript
import { DocValue } from 'fyo/core/types';
|
|
import { Doc } from 'fyo/model/doc';
|
|
import type {
|
|
FormulaMap,
|
|
HiddenMap,
|
|
ListsMap,
|
|
RequiredMap,
|
|
ValidationMap,
|
|
} from 'fyo/model/types';
|
|
import { ValueError } from 'fyo/utils/errors';
|
|
import { camelCase } from 'lodash';
|
|
import { ModelNameEnum } from 'models/types';
|
|
import type { FieldType } from 'schemas/types';
|
|
import { FieldTypeEnum } from 'schemas/types';
|
|
import type { CustomForm } from './CustomForm';
|
|
|
|
export class CustomField extends Doc {
|
|
parentdoc?: CustomForm;
|
|
|
|
label?: string;
|
|
fieldname?: string;
|
|
fieldtype?: FieldType;
|
|
isRequired?: boolean;
|
|
section?: string;
|
|
tab?: string;
|
|
options?: string;
|
|
target?: string;
|
|
references?: string;
|
|
|
|
get parentSchema() {
|
|
return this.parentdoc?.parentSchema ?? null;
|
|
}
|
|
|
|
get parentFields() {
|
|
return this.parentdoc?.parentFields;
|
|
}
|
|
|
|
formulas: FormulaMap = {
|
|
fieldname: {
|
|
formula: () => {
|
|
if (!this.label?.length) {
|
|
return;
|
|
}
|
|
|
|
return camelCase(this.label);
|
|
},
|
|
dependsOn: ['label'],
|
|
},
|
|
};
|
|
|
|
hidden: HiddenMap = {
|
|
options: () =>
|
|
this.fieldtype !== 'Select' &&
|
|
this.fieldtype !== 'AutoComplete' &&
|
|
this.fieldtype !== 'Color',
|
|
target: () => this.fieldtype !== 'Link' && this.fieldtype !== 'Table',
|
|
references: () => this.fieldtype !== 'DynamicLink',
|
|
};
|
|
|
|
validations: ValidationMap = {
|
|
label: (value) => {
|
|
if (typeof value !== 'string') {
|
|
return;
|
|
}
|
|
|
|
const fieldname = camelCase(value);
|
|
(this.validations.fieldname as (value: DocValue) => void)(fieldname);
|
|
},
|
|
fieldname: (value) => {
|
|
if (typeof value !== 'string') {
|
|
return;
|
|
}
|
|
|
|
const field = this.parentFields?.[value];
|
|
if (field && !field.isCustom) {
|
|
throw new ValueError(
|
|
this.fyo.t`Fieldname ${value} already exists for ${this.parentdoc!
|
|
.name!}`
|
|
);
|
|
}
|
|
|
|
const cf = this.parentdoc?.customFields?.find(
|
|
(cf) => cf.fieldname === value
|
|
);
|
|
if (cf) {
|
|
throw new ValueError(
|
|
this.fyo.t`Fieldname ${value} already used for Custom Field ${
|
|
(cf.idx ?? 0) + 1
|
|
}`
|
|
);
|
|
}
|
|
},
|
|
};
|
|
|
|
static lists: ListsMap = {
|
|
target: (doc) => {
|
|
const schemaMap = doc?.fyo.schemaMap ?? {};
|
|
return Object.values(schemaMap)
|
|
.filter(
|
|
(s) =>
|
|
!s?.isSingle &&
|
|
![
|
|
ModelNameEnum.PatchRun,
|
|
ModelNameEnum.SingleValue,
|
|
ModelNameEnum.CustomField,
|
|
ModelNameEnum.CustomForm,
|
|
ModelNameEnum.SetupWizard,
|
|
].includes(s?.name as ModelNameEnum)
|
|
)
|
|
.map((s) => ({
|
|
label: s?.label ?? '',
|
|
value: s?.name ?? '',
|
|
}));
|
|
},
|
|
references: (doc) => {
|
|
if (!(doc instanceof CustomField)) {
|
|
return [];
|
|
}
|
|
|
|
const referenceType: string[] = [
|
|
FieldTypeEnum.AutoComplete,
|
|
FieldTypeEnum.Data,
|
|
FieldTypeEnum.Text,
|
|
FieldTypeEnum.Select,
|
|
];
|
|
|
|
const customFields =
|
|
doc.parentdoc?.customFields
|
|
?.filter(
|
|
(cf) =>
|
|
cf.fieldname &&
|
|
cf.label &&
|
|
referenceType.includes(cf.fieldtype ?? '')
|
|
)
|
|
?.map((cf) => ({ value: cf.fieldname!, label: cf.label! })) ?? [];
|
|
|
|
const schemaFields =
|
|
doc.parentSchema?.fields
|
|
.filter(
|
|
(f) => f.fieldname && f.label && referenceType.includes(f.fieldtype)
|
|
)
|
|
.map((f) => ({ value: f.fieldname, label: f.label })) ?? [];
|
|
|
|
return [customFields, schemaFields].flat();
|
|
},
|
|
};
|
|
|
|
required: RequiredMap = {
|
|
options: () =>
|
|
this.fieldtype === 'Select' || this.fieldtype === 'AutoComplete',
|
|
target: () => this.fieldtype === 'Link' || this.fieldtype === 'Table',
|
|
references: () => this.fieldtype === 'DynamicLink',
|
|
default: () => !!this.isRequired,
|
|
};
|
|
}
|