const {body, validationResult} = require('express-validator') const v_m = require('../validation_messages') const validationMessages = { fa: { method: 'روش محاسبه را انتخاب کنید', method_not_supported: 'روش انتخاب شده پشتیبانی نشده است', gratingType: 'نوع گریتینک را انتخاب کنید', gratingType_not_supported: 'نوع گریتینگ پشتیبانی نشده است', loadType: 'نوع فشار را وارد کنید', class: 'کلاس را انتخاب کنید', pointedLoad: 'مقدار بار متمرکز را وارد کنید', distributedLoad: 'مقدار بار گسترده را وارد کنید', bearingBarThickness: 'ضخامت تسمه باربر را وارد کنید', bearingBarPitch: 'گام تسمه باربر را انتخاب کنید', bearingBarPitch_not_ok: 'مقدار گام تسمه باربر صحیح نیست', crossBarPitch: 'گام تسمه رابط را تنخاب کنید', crossBarPitch_not_ok: 'مقدار گام تسمه رابط صحیح نیست', bearingBarHeight: 'ارتفاع تسمه باربر را انتخاب کنید', bearingBarHeight_not_ok: 'مقدار ارتفاع تسمه باربر صحیح نیست', clearSpan: 'مقدار دهنه را وارد کنید', sigma_ok: 'تنش مجاز', sigma_out_of_range: 'تنش خارج از حد مجاز', deflection_ok: 'خیز مجاز', deflection_out_of_range: 'خیز خارج از حد مجاز' }, en: { method: 'Choose calculation method', method_not_supported: 'Chosen calculation method not supported', gratingType: 'Select the type of grating', gratingType_not_supported: 'Grating type not supported', loadType: 'Enter load type', class: 'Select class', pointedLoad: 'Enter the amount of pointed load', distributedLoad: 'Enter the amount of distributed load', bearingBarThickness: 'Enter bearing bar thickness', bearingBarPitch: 'Select bearing bar pitch', bearingBarPitch_not_ok: 'Bearing bar pitch value is incorrect', crossBarPitch: 'Select cross bar pitch', crossBarPitch_not_ok: 'Cross bar pitch value is incorrect', bearingBarHeight: 'Select bearing bar height', bearingBarHeight_not_ok: 'Bearing bar height is incorrect', clearSpan: 'Enter clear span', sigma_ok: 'Tension OK', sigma_out_of_range: 'Tension Out Of Range', deflection_ok: 'Deflection OK', deflection_out_of_range: 'Deflection Out Of Range' } } const values = { // ArakRail products bearingBarPitch_forge: [30, 35, 41, 50], bearingBarPitch_pressured: [11, 22, 33, 44, 50, 55], // defined in formula crossBarPitch_forge: [38, 50, 76, 100], crossBarPitch_pressured: [11, 22, 33, 44, 50, 55, 66, 77, 88, 100], // defined in formula bearingBarHeight: [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] } function relativeBearingBarHeight(gratingType, crossBarPitch) { // defined in formula bearingBarHeight = values.bearingBarHeight const CBPitch = Number(crossBarPitch) if (gratingType === 'forge') { if (CBPitch === 38) return bearingBarHeight.filter(item => item <= 80) else return bearingBarHeight.filter(item => item <= 60) } else if (gratingType === 'pressured') { if ( CBPitch === 11 || CBPitch === 22 || CBPitch === 55 || CBPitch === 77 || CBPitch === 88 ) return bearingBarHeight.filter(item => item <= 60) else if ( CBPitch === 33 || CBPitch === 44 || CBPitch === 50 || CBPitch === 66 || CBPitch === 100 ) return bearingBarHeight } } module.exports.calculate = [ [ body('method') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].method }) .bail() .custom((value, {req}) => { if (value === 'custom' || value === 'classified') return true else return Promise.reject(validationMessages[req.body.locale].method_not_supported) }), body('gratingType') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].gratingType }) .bail() .custom((value, {req}) => { if (value === 'forge' || value === 'pressured') return true else return Promise.reject(validationMessages[req.body.locale].gratingType_not_supported) }), body('loadType') .custom((value, {req}) => { if (req.body.method === 'custom') { if (value === 'pointedLoad' || value === 'distributedLoad') return true else return Promise.reject(validationMessages[req.body.locale].loadType) } else return true }), body('vehicleClass') .custom((value, {req}) => { if (req.body.method === 'classified') { const classes = ['class1', 'class2', 'class3', 'class4', 'FL1', 'FL2', 'FL3', 'FL4', 'FL5', 'FL6'] if (classes.includes(value)) return true else return Promise.reject(validationMessages[req.body.locale].class) } else return true }), body('pointedLoadValue') .custom((value, {req}) => { if (req.body.method === 'custom') { if (req.body.loadType === 'pointedLoad' && !value) return Promise.reject(validationMessages[req.body.locale].pointedLoad) else return true } else return true }) .bail() .if((value, {req}) => req.body.method === 'custom' && req.body.loadType === 'pointedLoad') .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }), body('distributedLoadValue') .custom((value, {req}) => { if (req.body.method === 'custom') { if (req.body.loadType === 'distributedLoad' && !value) return Promise.reject(validationMessages[req.body.locale].distributedLoad) else return true } else return true }) .bail() .if((value, {req}) => req.body.method === 'custom' && req.body.loadType === 'distributedLoad') .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }), body('bearingBarThickness') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].bearingBarThickness }) .bail() .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }), body('bearingBarPitch') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].bearingBarPitch }) .bail() .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }) .bail() .custom((value, {req}) => { if (req.body.gratingType === 'forge') { if (values.bearingBarPitch_forge.includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].bearingBarPitch_not_ok) } else { if (values.bearingBarPitch_pressured.includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].bearingBarPitch_not_ok) } }), body('crossBarPitch') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].crossBarPitch }) .bail() .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }) .bail() .custom((value, {req}) => { if (req.body.gratingType === 'forge') { if (values.crossBarPitch_forge.includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) } else { if (values.crossBarPitch_pressured.includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) } }), body('bearingBarHeight') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].bearingBarHeight }) .bail() .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }) .bail() .custom((value, {req}) => { if (relativeBearingBarHeight(req.body.gratingType, req.body.crossBarPitch).includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].bearingBarHeight_not_ok) }), body('clearSpan') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].clearSpan }) .bail() .isNumeric().withMessage((value, {req}) => { return v_m[req.body.locale].format.number }) ], (req, res) => { const errors = validationResult(req) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) let method = req.body.method let gratingType = req.body.gratingType let loadType = req.body.loadType let vehicleClass = req.body.vehicleClass let bearingBarHeight = req.body.bearingBarHeight let bearingBarThickness = req.body.bearingBarThickness let bearingBarPitch = req.body.bearingBarPitch let crossBarPitch = req.body.crossBarPitch let clearSpan = req.body.clearSpan let locale = req.body.locale ///////// classified vehicles const vehiclesClasses = { 'class1': { distributedLoad: 6 }, 'class2': { pointedLoad: 10, c4: 200, d4: 200 }, 'class3': { pointedLoad: 30, c4: 200, d4: 400 }, 'class4': { pointedLoad: 90, c4: 250, d4: 600 }, 'FL1': { pointedLoad: 26, c4: 130, d4: 130 }, 'FL2': { pointedLoad: 40, c4: 150, d4: 175 }, 'FL3': { pointedLoad: 63, c4: 200, d4: 200 }, 'FL4': { pointedLoad: 90, c4: 200, d4: 300 }, 'FL5': { pointedLoad: 140, c4: 200, d4: 375 }, 'FL6': { pointedLoad: 170, c4: 200, d4: 450 }, } ///////// pointed load function pointedLoad() { // static variables const forge = gratingType === 'forge' const custom = method === 'custom' // computing m | c4 | d4 | pointedLoadValue function m_pressured(bearingBarHeight, crossBarPitch) { const CBPitch = Number(crossBarPitch) const BBHeight = Number(bearingBarHeight) if (BBHeight === 20) { if (CBPitch === 11) return 4.00 if (CBPitch === 22) return 4.00 if (CBPitch === 33) return 3.33 if (CBPitch === 44) return 2.50 if (CBPitch === 50) return 2.22 if (CBPitch === 55) return 2.00 if (CBPitch === 66) return 1.68 if (CBPitch === 77) return 1.43 if (CBPitch === 88) return 1.25 if (CBPitch === 100) return 1.11 } else if (BBHeight === 25) { if (CBPitch === 11) return 3.85 if (CBPitch === 22) return 3.85 if (CBPitch === 33) return 3.25 if (CBPitch === 44) return 2.45 if (CBPitch === 50) return 2.17 if (CBPitch === 55) return 1.95 if (CBPitch === 66) return 1.62 if (CBPitch === 77) return 1.40 if (CBPitch === 88) return 1.21 if (CBPitch === 100) return 1.08 } else if (BBHeight === 30) { if (CBPitch === 11) return 3.80 if (CBPitch === 22) return 3.77 if (CBPitch === 33) return 3.17 if (CBPitch === 44) return 2.40 if (CBPitch === 50) return 2.15 if (CBPitch === 55) return 1.90 if (CBPitch === 66) return 1.58 if (CBPitch === 77) return 1.35 if (CBPitch === 88) return 1.19 if (CBPitch === 100) return 1.06 } else if (BBHeight === 35) { if (CBPitch === 11) return 3.75 if (CBPitch === 22) return 3.75 if (CBPitch === 33) return 3.08 if (CBPitch === 44) return 2.32 if (CBPitch === 50) return 2.05 if (CBPitch === 55) return 1.86 if (CBPitch === 66) return 1.54 if (CBPitch === 77) return 1.33 if (CBPitch === 88) return 1.17 if (CBPitch === 100) return 1.02 } else if (BBHeight === 40) { if (CBPitch === 11) return 3.70 if (CBPitch === 22) return 3.65 if (CBPitch === 33) return 3.00 if (CBPitch === 44) return 2.25 if (CBPitch === 50) return 2.00 if (CBPitch === 55) return 1.80 if (CBPitch === 66) return 1.52 if (CBPitch === 77) return 1.28 if (CBPitch === 88) return 1.12 if (CBPitch === 100) return 1.01 } else if (BBHeight === 45) { if (CBPitch === 11) return 3.65 if (CBPitch === 22) return 3.50 if (CBPitch === 33) return 2.92 if (CBPitch === 44) return 2.18 if (CBPitch === 50) return 1.95 if (CBPitch === 55) return 1.75 if (CBPitch === 66) return 1.46 if (CBPitch === 77) return 1.25 if (CBPitch === 88) return 1.09 if (CBPitch === 100) return 0.97 } else if (BBHeight === 50) { if (CBPitch === 11) return 3.45 if (CBPitch === 22) return 3.41 if (CBPitch === 33) return 2.83 if (CBPitch === 44) return 2.10 if (CBPitch === 50) return 1.88 if (CBPitch === 55) return 1.69 if (CBPitch === 66) return 1.42 if (CBPitch === 77) return 1.22 if (CBPitch === 88) return 1.06 if (CBPitch === 100) return 0.94 } else if (BBHeight === 55) { if (CBPitch === 11) return 3.28 if (CBPitch === 22) return 3.26 if (CBPitch === 33) return 2.75 if (CBPitch === 44) return 2.08 if (CBPitch === 50) return 1.84 if (CBPitch === 55) return 1.66 if (CBPitch === 66) return 1.39 if (CBPitch === 77) return 1.18 if (CBPitch === 88) return 1.04 if (CBPitch === 100) return 0.92 } else if (BBHeight === 60) { if (CBPitch === 11) return 3.20 if (CBPitch === 22) return 3.18 if (CBPitch === 33) return 2.67 if (CBPitch === 44) return 1.98 if (CBPitch === 50) return 1.76 if (CBPitch === 55) return 1.59 if (CBPitch === 66) return 1.35 if (CBPitch === 77) return 1.14 if (CBPitch === 88) return 0.99 if (CBPitch === 100) return 0.89 } else if (BBHeight === 65) { if (CBPitch === 33) return 2.58 if (CBPitch === 44) return 1.93 if (CBPitch === 50) return 1.71 if (CBPitch === 66) return 1.30 if (CBPitch === 100) return 0.86 } else if (BBHeight === 70) { if (CBPitch === 33) return 2.50 if (CBPitch === 44) return 1.88 if (CBPitch === 50) return 1.66 if (CBPitch === 66) return 1.25 if (CBPitch === 100) return 0.83 } else if (BBHeight === 75) { if (CBPitch === 33) return 2.42 if (CBPitch === 44) return 1.82 if (CBPitch === 50) return 1.62 if (CBPitch === 66) return 1.20 if (CBPitch === 100) return 0.81 } else if (BBHeight === 80) { if (CBPitch === 33) return 2.33 if (CBPitch === 44) return 1.75 if (CBPitch === 50) return 1.58 if (CBPitch === 66) return 1.15 if (CBPitch === 100) return 0.78 } else if (BBHeight === 85) { if (CBPitch === 33) return 2.25 if (CBPitch === 44) return 1.71 if (CBPitch === 50) return 1.52 if (CBPitch === 66) return 1.13 if (CBPitch === 100) return 0.75 } else if (BBHeight === 90) { if (CBPitch === 33) return 2.17 if (CBPitch === 44) return 1.67 if (CBPitch === 50) return 1.45 if (CBPitch === 66) return 1.11 if (CBPitch === 100) return 0.72 } else if (BBHeight === 95) { if (CBPitch === 33) return 2.08 if (CBPitch === 44) return 1.59 if (CBPitch === 50) return 1.39 if (CBPitch === 66) return 1.05 if (CBPitch === 100) return 0.69 } else if (BBHeight === 100) { if (CBPitch === 33) return 2.00 if (CBPitch === 44) return 1.50 if (CBPitch === 50) return 1.33 if (CBPitch === 66) return 0.99 if (CBPitch === 100) return 0.66 } } function m_forge(bearingBarHeight, crossBarPitch) { const CBPitch = Number(crossBarPitch) const BBHeight = Number(bearingBarHeight) if (BBHeight === 20) { if (CBPitch === 38) return 2.25 if (CBPitch === 50) return 1.35 if (CBPitch === 76) return 0.81 if (CBPitch === 100) return 0.52 } else if (BBHeight === 25) { if (CBPitch === 38) return 2.19 if (CBPitch === 50) return 1.28 if (CBPitch === 76) return 0.77 if (CBPitch === 100) return 0.52 } else if (BBHeight === 30) { if (CBPitch === 38) return 2.13 if (CBPitch === 50) return 1.25 if (CBPitch === 76) return 0.75 if (CBPitch === 100) return 0.48 } else if (BBHeight === 35) { if (CBPitch === 38) return 2.06 if (CBPitch === 50) return 1.20 if (CBPitch === 76) return 0.71 if (CBPitch === 100) return 0.47 } else if (BBHeight === 40) { if (CBPitch === 38) return 2.00 if (CBPitch === 50) return 1.17 if (CBPitch === 76) return 0.67 if (CBPitch === 100) return 0.45 } else if (BBHeight === 45) { if (CBPitch === 38) return 1.94 if (CBPitch === 50) return 1.11 if (CBPitch === 76) return 0.65 if (CBPitch === 100) return 0.43 } else if (BBHeight === 50) { if (CBPitch === 38) return 1.88 if (CBPitch === 50) return 1.05 if (CBPitch === 76) return 0.62 if (CBPitch === 100) return 0.40 } else if (BBHeight === 55) { if (CBPitch === 38) return 1.81 if (CBPitch === 50) return 1.03 if (CBPitch === 76) return 0.61 if (CBPitch === 100) return 0.38 } else if (BBHeight === 60) { if (CBPitch === 38) return 1.75 if (CBPitch === 50) return 1.00 if (CBPitch === 76) return 0.59 if (CBPitch === 100) return 0.36 } else if (BBHeight === 65) { if (CBPitch === 38) return 1.69 } else if (BBHeight === 70) { if (CBPitch === 38) return 1.63 } else if (BBHeight === 75) { if (CBPitch === 38) return 1.56 } else if (BBHeight === 80) { if (CBPitch === 38) return 1.50 } } let m = () => { if (forge) return m_forge(bearingBarHeight, crossBarPitch) else return m_pressured(bearingBarHeight, crossBarPitch) } const c4 = () => { if (custom) return 200 else return vehiclesClasses[vehicleClass].c4 } const d4 = () => { if (custom) return 200 else return vehiclesClasses[vehicleClass].d4 } const pointedLoadValue = () => { if (custom) return req.body.pointedLoadValue else return vehiclesClasses[vehicleClass].pointedLoad } /////////////////////////////////////////////////////////////// computed variables const MaxM = (((pointedLoadValue() * 1000) * (clearSpan - (d4() / 2))) / 4) * 1.5 const n = (c4() / bearingBarPitch) + m() const W = () => { const temp = (((bearingBarThickness * Math.pow(bearingBarHeight, 2)) / 6) * n) return forge ? temp : (temp * 0.9) } const sigma = MaxM / W() const L = () => { const temp = (((bearingBarThickness * (Math.pow(bearingBarHeight, 3))) / 12) * n) return forge ? temp : (temp * 0.9) } const D = ((pointedLoadValue() * 1000) / (384 * 210000 * L())) * ((8 * Math.pow(clearSpan, 3)) - (4 * clearSpan * Math.pow(d4(), 2)) + (Math.pow(d4(), 3))) // console.log('m =' + m()) // console.log('c4 =' + c4()) // console.log('d4 =' + d4()) // console.log('pointedLoadValue =' + pointedLoadValue()) // console.log('MaxM =' + MaxM) // console.log('n =' + n) // console.log('W =' + W()) // console.log('sigma =' + sigma) // console.log('L =' + L()) // console.log('D =' + D) //////////////////////////////////////////////////////////////// calculate result const result = { sigma: null, sigmaStatus: null, deflection: null, deflectionStatus: null } if (sigma < 235) { result.sigma = validationMessages[locale].sigma_ok result.sigmaStatus = true } else { result.sigma = validationMessages[locale].sigma_out_of_range result.sigmaStatus = false } if (D < (clearSpan / 200)) { result.deflection = validationMessages[locale].deflection_ok result.deflectionStatus = true } else { result.deflection = validationMessages[locale].deflection_out_of_range result.deflectionStatus = false } return result } ///////// distributed load function distributedLoad() { // static variables const forge = gratingType === 'forge' const custom = method === 'custom' // computing distributedLoadValue const distributedLoadValue = () => { if (custom) return req.body.distributedLoadValue else return vehiclesClasses[vehicleClass].distributedLoad } ////////////////////////////////////////////////////////////////// computed variables const MaxM = (((distributedLoadValue() * 10) * bearingBarPitch * Math.pow(clearSpan, 2)) / 80000) * 1.5 const W = () => { const temp = (bearingBarThickness * Math.pow(bearingBarHeight, 2)) / 6 return forge ? temp : (temp * 0.9) } const sigma = MaxM / W() const L = () => { const temp = (bearingBarThickness * Math.pow(bearingBarHeight, 3)) / 12 return forge ? temp : (temp * 0.9) } const D = (5 * distributedLoadValue() * bearingBarPitch * Math.pow(clearSpan, 4)) / (384 * 21000 * L() * Math.pow(10, 4)) ////////////////////////////////////////////////////////////////// calculate result const result = { sigma: null, sigmaStatus: null, deflection: null, deflectionStatus: null } if (sigma < 235) { result.sigma = validationMessages[locale].sigma_ok result.sigmaStatus = true } else { result.sigma = validationMessages[locale].sigma_out_of_range result.sigmaStatus = false } if (D < (clearSpan / 200)) { result.deflection = validationMessages[locale].deflection_ok result.deflectionStatus = true } else { result.deflection = validationMessages[locale].deflection_out_of_range result.deflectionStatus = false } return result } ////////////////////////////////////////////// calculate if (method === 'custom') { if (loadType === 'pointedLoad') return res.json(pointedLoad()) else return res.json(distributedLoad()) } else if (method === 'classified') { if (vehicleClass === 'class1') return res.json(distributedLoad()) else return res.json(pointedLoad()) } else return res.json({message: 'unsupported entry'}) } ] module.exports.getRelativeValues = [ [ body('gratingType') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].gratingType }) .bail() .custom((value, {req}) => { if (value === 'forge' || value === 'pressured') return true else Promise.reject(validationMessages[req.body.locale].gratingType_not_supported) }), body('crossBarPitch') .notEmpty().withMessage((value, {req}) => { return validationMessages[req.body.locale].crossBarPitch }) .bail() .custom((value, {req}) => { if (req.body.gratingType === 'forge') { if (values.crossBarPitch_forge.includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) } else { if (values.crossBarPitch_pressured.includes(Number(value))) return true else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) } }) ], (req, res) => { const errors = validationResult(req) if (!errors.isEmpty()) return res.status(422).json(errors.mapped()) return res.json(relativeBearingBarHeight(req.body.gratingType, req.body.crossBarPitch)) } ] module.exports.getValues = [ (req, res) => { return res.json(values) } ]