const R = require('ramda');
class SlotsRule {
run(result, configs, params) {
const { slots } = this.makeSlots(params);
// add slots to result and slots_config to debugs
return slots;
}
// Create slots and format each bucket to pass through rules
makeSlots(params) {
let slots_config = this.splitHoursIntoSlots(params);
return {
...slots_config,
slots: R.map(hour => this._formatSlot(hour), slots_config.queue)
};
}
// Split quantity of hours in slots taking in count
// max. hours for each prof per service type
splitHoursIntoSlots(params) {
// TODO:
// Take `service_type` in count to retrieve:
// - min hours per service
// - max hours per service
// - max hours per tasker
return R.pipe(
(_ => this._totalSlots(_, params)),
(_ => this._makeDivisions(_, params)),
(_ => this._initializeSlots(_, params)),
(_ => this._spreadRemainder(_, params)),
(_ => this._serializeSlots(_, params))
)(params)
}
_formatSlot(hours) {
return {
hours,
};
}
// Adds total_hours and total_slots to accumulator
_totalSlots(_acc, params) {
const MAX_TASKER_HOUR = 9.0;
return {
total_hours: parseFloat(params.hours),
total_slots: Math.ceil(params.hours / MAX_TASKER_HOUR)
};
}
// Adds rounded quotient as slot's base hour
// and remainder to be spread over slots
_makeDivisions(acc, _params) {
return {
...acc,
rounded_quotient: Math.floor(acc.total_hours / acc.total_slots),
remainder: acc.total_hours % acc.total_slots,
}
}
// Adds an array with total slots filled with base hours
_initializeSlots(acc, _params) {
return {
...acc,
queue: new Array(acc.total_slots).fill(acc.rounded_quotient)
}
}
// Spreads remainder over slots step by step
// Today step is 0.5 'cause it is the time interval between prices declared in sheets
_spreadRemainder(acc, _params) {
for (let n = 0, step = 0.5; acc.remainder - ((n + 1) * step) >= 0; n++) {
acc.queue[n % acc.total_slots] += step;
};
return acc;
}
_serializeSlots(acc, params) {
const {
rounded_quotient: slot_base_hours,
} = acc;
return {
slot_base_hours,
...R.omit(['rounded_quotient'], acc),
};
}
}
(new SlotsRule()).run({}, {}, {
hours: '19',
})