2
0
mirror of https://github.com/frappe/books.git synced 2024-11-09 23:30:56 +00:00
books/schemas/index.ts

167 lines
4.7 KiB
TypeScript
Raw Normal View History

2022-03-23 14:46:19 +00:00
import { cloneDeep } from 'lodash';
import { getListFromMap, getMapFromList } from './helpers';
2022-03-23 16:40:36 +00:00
import regionalSchemas from './regional';
import { appSchemas, coreSchemas, metaSchemas } from './schemas';
2022-03-23 14:46:19 +00:00
import { Schema, SchemaMap, SchemaStub, SchemaStubMap } from './types';
export function getSchemas(countryCode: string = '-'): SchemaMap {
const builtCoreSchemas = getCoreSchemas();
const builtAppSchemas = getAppSchemas(countryCode);
2022-03-23 16:40:36 +00:00
let schemaMap = Object.assign({}, builtAppSchemas, builtCoreSchemas);
schemaMap = addMetaFields(schemaMap);
return schemaMap;
}
2022-03-25 10:12:39 +00:00
export function addMetaFields(schemaMap: SchemaMap): SchemaMap {
const metaSchemaMap = getMapFromList(metaSchemas, 'name');
2022-03-23 16:40:36 +00:00
const base = metaSchemaMap.base;
const tree = getCombined(metaSchemaMap.tree, base);
const child = metaSchemaMap.child;
const submittable = getCombined(metaSchemaMap.submittable, base);
const submittableTree = getCombined(tree, metaSchemaMap.submittable);
for (const name in schemaMap) {
const schema = schemaMap[name];
if (schema.isSingle) {
continue;
}
if (schema.isTree && schema.isSubmittable) {
2022-03-25 10:12:39 +00:00
schema.fields = [...schema.fields, ...submittableTree.fields!];
2022-03-23 16:40:36 +00:00
} else if (schema.isTree) {
2022-03-25 10:12:39 +00:00
schema.fields = [...schema.fields, ...tree.fields!];
2022-03-23 16:40:36 +00:00
} else if (schema.isSubmittable) {
2022-03-25 10:12:39 +00:00
schema.fields = [...schema.fields, ...submittable.fields!];
2022-03-23 16:40:36 +00:00
} else if (schema.isChild) {
2022-03-25 10:12:39 +00:00
schema.fields = [...schema.fields, ...child.fields!];
2022-03-23 16:40:36 +00:00
} else {
2022-03-25 10:12:39 +00:00
schema.fields = [...schema.fields, ...base.fields!];
2022-03-23 16:40:36 +00:00
}
}
return schemaMap;
2022-03-23 14:46:19 +00:00
}
function getCoreSchemas(): SchemaMap {
2022-03-25 10:12:39 +00:00
const rawSchemaMap = getMapFromList(coreSchemas, 'name');
2022-03-23 14:46:19 +00:00
const coreSchemaMap = getAbstractCombinedSchemas(rawSchemaMap);
return cleanSchemas(coreSchemaMap);
}
function getAppSchemas(countryCode: string): SchemaMap {
2022-03-25 10:12:39 +00:00
const appSchemaMap = getMapFromList(appSchemas, 'name');
const regionalSchemaMap = getRegionalSchemaMap(countryCode);
const combinedSchemas = getRegionalCombinedSchemas(
appSchemaMap,
regionalSchemaMap
);
2022-03-23 14:46:19 +00:00
const schemaMap = getAbstractCombinedSchemas(combinedSchemas);
return cleanSchemas(schemaMap);
}
2022-03-25 10:12:39 +00:00
export function cleanSchemas(schemaMap: SchemaMap): SchemaMap {
2022-03-23 14:46:19 +00:00
for (const name in schemaMap) {
const schema = schemaMap[name];
if (schema.isAbstract && !schema.extends) {
delete schemaMap[name];
continue;
}
delete schema.extends;
delete schema.isAbstract;
}
return schemaMap;
}
function getCombined(
extendingSchema: SchemaStub,
abstractSchema: SchemaStub
): SchemaStub {
abstractSchema = cloneDeep(abstractSchema);
extendingSchema = cloneDeep(extendingSchema);
const abstractFields = getMapFromList(
abstractSchema.fields ?? [],
'fieldname'
);
const extendingFields = getMapFromList(
extendingSchema.fields ?? [],
'fieldname'
);
const combined = Object.assign(abstractSchema, extendingSchema);
for (const fieldname in extendingFields) {
abstractFields[fieldname] = extendingFields[fieldname];
}
combined.fields = getListFromMap(abstractFields);
return combined;
}
2022-03-25 10:12:39 +00:00
export function getAbstractCombinedSchemas(schemas: SchemaStubMap): SchemaMap {
2022-03-23 14:46:19 +00:00
const abstractSchemaNames: string[] = Object.keys(schemas).filter(
(n) => schemas[n].isAbstract
);
const extendingSchemaNames: string[] = Object.keys(schemas).filter((n) =>
2022-03-25 10:12:39 +00:00
abstractSchemaNames.includes(schemas[n].extends ?? '')
2022-03-23 14:46:19 +00:00
);
const completeSchemas: Schema[] = Object.keys(schemas)
.filter(
(n) =>
!abstractSchemaNames.includes(n) && !extendingSchemaNames.includes(n)
)
.map((n) => schemas[n] as Schema);
2022-03-25 10:12:39 +00:00
const schemaMap = getMapFromList(completeSchemas, 'name') as SchemaMap;
2022-03-23 14:46:19 +00:00
for (const name of extendingSchemaNames) {
const extendingSchema = schemas[name] as Schema;
2022-03-25 10:12:39 +00:00
const abstractSchema = schemas[extendingSchema.extends!] as SchemaStub;
2022-03-23 14:46:19 +00:00
schemaMap[name] = getCombined(extendingSchema, abstractSchema) as Schema;
}
for (const name in abstractSchemaNames) {
delete schemaMap[name];
}
return schemaMap;
}
2022-03-25 10:12:39 +00:00
export function getRegionalCombinedSchemas(
appSchemaMap: SchemaStubMap,
regionalSchemaMap: SchemaStubMap
): SchemaStubMap {
2022-03-23 14:46:19 +00:00
const combined = { ...appSchemaMap };
for (const name in regionalSchemaMap) {
const regionalSchema = regionalSchemaMap[name];
if (!combined.hasOwnProperty(name)) {
combined[name] = regionalSchema;
continue;
}
combined[name] = getCombined(regionalSchema, combined[name]);
}
return combined;
}
2022-03-25 10:12:39 +00:00
function getRegionalSchemaMap(countryCode: string): SchemaStubMap {
2022-03-23 16:40:36 +00:00
const countrySchemas = regionalSchemas[countryCode] as
| SchemaStub[]
| undefined;
if (countrySchemas === undefined) {
2022-03-23 14:46:19 +00:00
return {};
}
2022-03-25 10:12:39 +00:00
return getMapFromList(countrySchemas, 'name');
2022-03-23 14:46:19 +00:00
}