mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
161 lines
4.6 KiB
TypeScript
161 lines
4.6 KiB
TypeScript
import { cloneDeep } from 'lodash';
|
|
import { getListFromMap, getMapFromList } from './helpers';
|
|
import regionalSchemas from './regional';
|
|
import { appSchemas, coreSchemas, metaSchemas } from './schemas';
|
|
import { Schema, SchemaMap, SchemaStub, SchemaStubMap } from './types';
|
|
|
|
export function getSchemas(countryCode: string = '-'): SchemaMap {
|
|
const builtCoreSchemas = getCoreSchemas();
|
|
const builtAppSchemas = getAppSchemas(countryCode);
|
|
|
|
let schemaMap = Object.assign({}, builtAppSchemas, builtCoreSchemas);
|
|
schemaMap = addMetaFields(schemaMap);
|
|
return schemaMap;
|
|
}
|
|
|
|
function addMetaFields(schemaMap: SchemaMap): SchemaMap {
|
|
const metaSchemaMap = getMapFromList(metaSchemas);
|
|
|
|
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) {
|
|
schema.fields = [...schema.fields, ...submittableTree.fields];
|
|
} else if (schema.isTree) {
|
|
schema.fields = [...schema.fields, ...tree.fields];
|
|
} else if (schema.isSubmittable) {
|
|
schema.fields = [...schema.fields, ...submittable.fields];
|
|
} else if (schema.isChild) {
|
|
schema.fields = [...schema.fields, ...child.fields];
|
|
} else {
|
|
schema.fields = [...schema.fields, ...base.fields];
|
|
}
|
|
}
|
|
|
|
return schemaMap;
|
|
}
|
|
|
|
function getCoreSchemas(): SchemaMap {
|
|
const rawSchemaMap = getMapFromList(coreSchemas);
|
|
const coreSchemaMap = getAbstractCombinedSchemas(rawSchemaMap);
|
|
return cleanSchemas(coreSchemaMap);
|
|
}
|
|
|
|
function getAppSchemas(countryCode: string): SchemaMap {
|
|
const combinedSchemas = getRegionalCombinedSchemas(countryCode);
|
|
const schemaMap = getAbstractCombinedSchemas(combinedSchemas);
|
|
return cleanSchemas(schemaMap);
|
|
}
|
|
|
|
function cleanSchemas(schemaMap: SchemaMap): SchemaMap {
|
|
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;
|
|
}
|
|
|
|
function getAbstractCombinedSchemas(schemas: SchemaStubMap): SchemaMap {
|
|
const abstractSchemaNames: string[] = Object.keys(schemas).filter(
|
|
(n) => schemas[n].isAbstract
|
|
);
|
|
|
|
const extendingSchemaNames: string[] = Object.keys(schemas).filter((n) =>
|
|
abstractSchemaNames.includes(schemas[n].extends)
|
|
);
|
|
|
|
const completeSchemas: Schema[] = Object.keys(schemas)
|
|
.filter(
|
|
(n) =>
|
|
!abstractSchemaNames.includes(n) && !extendingSchemaNames.includes(n)
|
|
)
|
|
.map((n) => schemas[n] as Schema);
|
|
|
|
const schemaMap = getMapFromList(completeSchemas) as SchemaMap;
|
|
|
|
for (const name of extendingSchemaNames) {
|
|
const extendingSchema = schemas[name] as Schema;
|
|
const abstractSchema = schemas[extendingSchema.extends] as SchemaStub;
|
|
|
|
schemaMap[name] = getCombined(extendingSchema, abstractSchema) as Schema;
|
|
}
|
|
|
|
for (const name in abstractSchemaNames) {
|
|
delete schemaMap[name];
|
|
}
|
|
|
|
return schemaMap;
|
|
}
|
|
|
|
function getRegionalCombinedSchemas(countryCode: string): SchemaStubMap {
|
|
const regionalSchemaMap = getRegionalSchema(countryCode);
|
|
const appSchemaMap = getMapFromList(appSchemas);
|
|
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;
|
|
}
|
|
|
|
function getRegionalSchema(countryCode: string): SchemaStubMap {
|
|
const countrySchemas = regionalSchemas[countryCode] as
|
|
| SchemaStub[]
|
|
| undefined;
|
|
if (countrySchemas === undefined) {
|
|
return {};
|
|
}
|
|
|
|
return getMapFromList(countrySchemas);
|
|
}
|