import { GraphQLObjectType, GraphQLString, GraphQLInputObjectType, GraphQLBoolean, GraphQLInt, GraphQLList, GraphQLFloat, GraphQLNonNull, } from 'graphql'; import { omit } from 'lodash'; import { createJobTpl, updateJobTpl, archiveJobTpl, restoreJobTpl, updateJobTplStage, removeTplFromStage, } from './jobTplRepository'; import { IJobTpl, ISelectJobTpl, IJobTplStage, IRemoveJobTpl, IJobTplInput, } from '../model/jobTpl'; import { authorized } from '../auth'; interface InputJobTpl { input: IJobTpl; } interface InputJobTplSelect { input: ISelectJobTpl; } interface InputJobTplStageSelect { input: IJobTplStage; } interface IInputRemoveJobTpl { input: IRemoveJobTpl; } const jobTplDescription = { id: 'An id of the job template', unit: 'A unit', name: 'A name of the job template', description: 'A description of the job template', jobPriceType: 'A type of job price', customScriptName: 'A custom scritp name', status: 'A status of job template', price: 'A price of job template', stageId: 'Connected stage id', sortOrder: 'A sort order of the job template in stage context (if stage is provided)', parentId: 'Connected stage id in this context', hoursPerUom: 'Hours per unit of measure', }; const jobTplStageDescription = { id: 'An id of the job template stage relation', jobTplId: 'An id of the job template', stageId: 'An id of the stage', sortOrder: 'A sort order of job template stage relation', }; export const jobTplType = new GraphQLObjectType({ name: 'JobTplType', description: 'Job Template Type', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.id, }, unit: { type: GraphQLString, description: jobTplDescription.unit, }, name: { type: GraphQLString, description: jobTplDescription.name, }, description: { type: GraphQLString, description: jobTplDescription.description, }, jobPriceType: { type: GraphQLString, description: jobTplDescription.jobPriceType, }, customScriptName: { type: GraphQLString, description: jobTplDescription.customScriptName, }, status: { type: GraphQLString, description: jobTplDescription.status, }, price: { type: GraphQLFloat, description: jobTplDescription.price, }, sortOrder: { type: GraphQLFloat, description: jobTplDescription.sortOrder, }, hoursPerUom: { type: GraphQLFloat, description: jobTplDescription.hoursPerUom, }, }), }); export const createJobTplInputType = new GraphQLInputObjectType({ name: 'CreateJobTplInputType', description: 'Use this type to create job template type', fields: () => ({ name: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.name, }, unit: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.unit, }, description: { type: GraphQLString, description: jobTplDescription.description, }, jobPriceType: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.jobPriceType, }, customScriptName: { type: GraphQLString, description: jobTplDescription.customScriptName, }, price: { type: new GraphQLNonNull(GraphQLFloat), description: jobTplDescription.price, }, sortOrder: { type: GraphQLFloat, description: jobTplDescription.sortOrder, }, stageId: { type: GraphQLInt, description: jobTplDescription.stageId, }, hoursPerUom: { type: GraphQLFloat, description: jobTplDescription.hoursPerUom, }, }), }); export const selectorJobTpl = new GraphQLInputObjectType({ name: 'JobTplSelectorType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.id, }, }), }); export const removeJobTplInputType = new GraphQLInputObjectType({ name: 'RemoveJobTplInputType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.id, }, parentId: { type: new GraphQLNonNull(GraphQLInt), description: jobTplDescription.parentId, }, }), }); export const jobTplStageType = new GraphQLObjectType({ name: 'JobTplStageType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: jobTplStageDescription.id, }, jobTplId: { type: new GraphQLNonNull(GraphQLString), description: jobTplStageDescription.jobTplId, }, stageId: { type: new GraphQLNonNull(GraphQLInt), description: jobTplStageDescription.stageId, }, sortOrder: { type: new GraphQLNonNull(GraphQLFloat), description: jobTplStageDescription.sortOrder, }, }), }); export const jobTplStageInputType = new GraphQLInputObjectType({ name: 'JobTplStageInputType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: jobTplStageDescription.id, }, jobTplId: { type: new GraphQLNonNull(GraphQLString), description: jobTplStageDescription.jobTplId, }, stageId: { type: new GraphQLNonNull(GraphQLInt), description: jobTplStageDescription.stageId, }, sortOrder: { type: new GraphQLNonNull(GraphQLFloat), description: jobTplStageDescription.sortOrder, }, }), }); // Job Template -> Material Link const inputMaterialLink = new GraphQLInputObjectType({ name: 'MaterialLinkReturnType', fields: () => ({ consumption: { type: GraphQLFloat, }, materialId: { type: new GraphQLNonNull(GraphQLString), }, default: { type: GraphQLBoolean, }, }), }); const updateInputMaterialLink = new GraphQLInputObjectType({ name: 'UpdateMaterialLinkReturnType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLInt), }, consumption: { type: GraphQLFloat, }, default: { type: GraphQLBoolean, }, }), }); // -- Job Template -> Material Link -- // Job Template -> Material Type Link const inputMaterialTypeLink = new GraphQLInputObjectType({ name: 'MaterialTypeLinkInputType', fields: () => ({ consumption: { type: new GraphQLNonNull(GraphQLFloat), }, materialTypeId: { type: new GraphQLNonNull(GraphQLString), }, materials: { type: new GraphQLList(inputMaterialLink), }, }), }); const updateInputMaterialTypeLink = new GraphQLInputObjectType({ name: 'UpdateMaterialTypeLinkInputType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLInt), }, consumption: { type: new GraphQLNonNull(GraphQLFloat), }, materials: { type: new GraphQLList(updateInputMaterialLink), }, }), }); const deleteMaterialTypeLink = new GraphQLInputObjectType({ name: 'DeleteMaterialTypeLinkInputType', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLInt), }, }), }); // -- Job Template -> Material Type Link -- const changedMaterialTypesInputType = new GraphQLInputObjectType({ name: 'ChangedMaterialTypesInputType', fields: () => ({ created: { type: new GraphQLList(inputMaterialTypeLink), }, updated: { type: new GraphQLList(updateInputMaterialTypeLink), }, deleted: { type: new GraphQLList(deleteMaterialTypeLink), }, }), }); export const updateJobTplInputType = new GraphQLInputObjectType({ name: 'UpdateJobTplInputType', description: 'Use this type to update job template type', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: jobTplDescription.id, }, unit: { type: GraphQLString, description: jobTplDescription.unit, }, materialTypes: { type: changedMaterialTypesInputType, }, name: { type: GraphQLString, description: jobTplDescription.name, }, description: { type: GraphQLString, description: jobTplDescription.description, }, jobPriceType: { type: GraphQLString, description: jobTplDescription.jobPriceType, }, customScriptName: { type: GraphQLString, description: jobTplDescription.customScriptName, }, price: { type: GraphQLFloat, description: jobTplDescription.price, }, sortOrder: { type: GraphQLFloat, description: jobTplDescription.sortOrder, }, hoursPerUom: { type: GraphQLFloat, description: jobTplDescription.hoursPerUom, }, }), }); export default { createJobTpl: { description: 'Creates new job template', type: jobTplType, args: { input: { type: new GraphQLNonNull(createJobTplInputType) }, }, resolve: authorized( ['AM', 'CE'], (_: any, inputJobTpl: InputJobTpl) => { const input = inputJobTpl.input; return createJobTpl(input); }, ), }, archiveJobTpl: { description: 'Archives job template', type: GraphQLBoolean, args: { input: { type: new GraphQLNonNull(selectorJobTpl) }, }, resolve: authorized( ['AM', 'CE'], (_: any, inputJobTpl: InputJobTplSelect) => { const input = inputJobTpl.input; return archiveJobTpl(input.id); }, ), }, updateJobTplStage: { description: 'Updates connection of the job template and the stage', type: jobTplStageType, args: { input: { type: new GraphQLNonNull(jobTplStageInputType) }, }, resolve: authorized( ['AM', 'CE'], (_: any, inputJobTpl: InputJobTplStageSelect) => { const input = inputJobTpl.input; return updateJobTplStage(input); }, ), }, removeJobTplFromStage: { description: 'Removes job template from stage', type: GraphQLBoolean, args: { input: { type: new GraphQLNonNull(removeJobTplInputType) }, }, resolve: authorized( ['AM', 'CE'], (_: any, inputJobTpl: IInputRemoveJobTpl) => { const input = inputJobTpl.input; return removeTplFromStage(input); }, ), }, restoreJobTpl: { description: 'Restores job template', type: GraphQLBoolean, args: { input: { type: new GraphQLNonNull(selectorJobTpl) }, }, resolve: authorized( ['AM', 'CE'], (_: any, inputJobTpl: InputJobTplSelect) => { const input = inputJobTpl.input; return restoreJobTpl(input.id); }, ), }, updateJobTpl: { description: 'Updates job template', type: jobTplType, args: { input: { type: new GraphQLNonNull(updateJobTplInputType) }, }, resolve: authorized( ['AM', 'CE'], (_: any, inputJobTpl: InputJobTpl) => { const input = inputJobTpl.input; return updateJobTpl(input.id, input); }, ), }, };