Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- let username = '',
- password = '';
- let archiver = require('archiver'),
- btoa = require('btoa'),
- fs = require('fs'),
- os = require('os'),
- handlebars = require('handlebars'),
- request = require('request'),
- _ = require('lodash'),
- moment = require('moment'),
- wkhtmltopdf = require('wkhtmltopdf'),
- rimraf = require('rimraf'),
- clientProperties,
- serverProperties;
- moment.locale('ru');
- handlebars.registerHelper('format', (date, format) => moment(date).format(format));
- handlebars.registerHelper('condition', (condition, v1, v2) => condition ? v1 : v2);
- handlebars.registerHelper('shift', (employee, date, model, isImpersonal, options) => {
- let shift;
- if (isImpersonal) {
- shift = _.find(model.shifts, e => {
- return e.positionIndex === employee.positionIndex && moment(e.startDate).isSame(date, 'day');
- });
- } else {
- shift = _.find(model.shifts, e => {
- return e.employeePositionId === employee.id && moment(e.startDate).isSame(date, 'day');
- });
- }
- if(shift) {
- this.shift = shift;
- return options.fn(this);
- }
- });
- handlebars.registerHelper('comment', (date, comments) => {
- let comment = _.find(comments, e => moment(e.date).isSame(date, 'day'));
- if(comment) {
- return comment.text;
- }
- });
- handlebars.registerHelper('shifts', (employee, date, type, model, isImpersonal, options) => {
- let typesArray, prop = isImpersonal ? 'positionIndex' : 'employeePositionId';
- switch (type) {
- case 'OPEN':
- typesArray = ['OPEN', 'OUTSIDE_OPEN', 'FULL_DAY', 'FULL_DAY_OUTSIDE'];
- break;
- case 'CLOSE':
- typesArray = ['CLOSE', 'OUTSIDE_CLOSE', 'FULL_DAY', 'FULL_DAY_OUTSIDE'];
- break;
- }
- this.shifts = _.filter(model.shifts, e => {
- return ((employee && _.isNumber(employee[isImpersonal ? prop : 'id'])) ? e[prop] === employee[isImpersonal ? prop : 'id'] : true) &&
- (typesArray ? _.some(typesArray, type => {return type === e.type;}) : true) &&
- (date ? moment(e.startDate).isSame(date, 'day') : true);
- });
- return options.fn(this);
- });
- handlebars.registerHelper('scheduleRequest', (employeeId, date, scheduleRequests, options) => {
- let scheduleRequest = _.find(scheduleRequests, e => {
- return (e.employeeId === employeeId && e.status === 'APPROVED' && e.type !== 'PARTIAL_ABSENCE' && e.type !== 'SHIFT' &&
- moment(date).isBetween(e.startDate, e.endDate, 'day', '[]'));
- });
- if(scheduleRequest) {
- this.scheduleRequest = scheduleRequest;
- return options.fn(this);
- }
- });
- handlebars.registerHelper('shiftClass', type => {
- switch (type) {
- case 'OPEN':
- return 'mdl-color--green-300';
- case 'MIDDLE':
- return 'mdl-color--amber-200';
- case 'CLOSE':
- return 'mdl-color--teal-200';
- case 'FULL_DAY':
- return 'mdl-color--purple-200';
- case 'FULL_DAY_OUTSIDE':
- return 'mdl-color--purple-400';
- case 'OUTSIDE_OPEN':
- return 'mdl-color--green-500';
- case 'OUTSIDE_CLOSE':
- return 'mdl-color--teal-400';
- case 'OUTSIDE':
- return 'mdl-color--blue-grey-400';
- }
- });
- handlebars.registerHelper('daysOff', (shifts, monthArray) => _.size(monthArray) - _.size(shifts));
- handlebars.registerHelper('size', array => _.size(array));
- handlebars.registerHelper('workload', shifts => {
- let sum = 0;
- _.forEach(shifts, shift => {
- sum += (hoursBetween(shift.startDate, shift.endDate) - 1);
- });
- return sum;
- });
- handlebars.registerHelper('timeRange', (startDate, endDate, lunch) => {
- let date = moment().startOf('day').add(endDate - startDate - lunch * 60000);
- return date.format(date.minutes() > 0 ? 'H:mm' : 'H');
- });
- function link(template, valuesObject = {}) {
- let link;
- if (!template) {
- return '';
- }
- link = template
- .replace(/{\?(.)+}/g, '')
- .replace(/{([A-Za-z0-9])+}/g, str => {
- return valuesObject[str.slice(1, str.length - 1)]
- });
- return link;
- }
- function getMonthArray(date = new Date) {
- let array = [];
- for (let c = 1, day; c <= moment(date).daysInMonth(); c++) {
- day = moment(date).date(c).startOf('day').toDate();
- array.push({
- date : day,
- active: (day.getDay() !== 0 && day.getDay() !== 6)
- });
- }
- return array;
- }
- function hoursBetween(startDate, endDate) {
- return Math.round( (moment(endDate).valueOf() - moment(startDate).valueOf()) / (1000 * 60 * 60 ) );
- }
- function tryParseJSON (jsonString){
- try {
- return JSON.parse(jsonString);
- }
- catch (e) {
- console.error("Not a valid JSON")
- }
- return false;
- }
- // params:
- // org-unit-ids
- // position-type-ids
- // date
- // zip
- // locale
- // impersonal
- // chief-id
- exports.render = (req, res, next, properties) => {
- req.setTimeout(6*60*60*1000);
- let orgUnitIds = _.uniq(_.split(_.get(req, 'query[\'org-unit-ids\']'), ',')),
- positionTypeIds = _.uniq(_.split(_.get(req, 'query[\'position-type-ids\']'), ',')),
- date = moment(_.get(req, 'query.date')),
- isZip = _.get(req, 'query.zip') === 'true',
- showMinutes = _.get(req, 'query.minutes') === 'true',
- isImpersonal = _.get(req, 'query.impersonal') === 'true',
- from = date.clone().startOf('month').format('YYYY-MM-DD'),
- to = date.clone().endOf('month').format('YYYY-MM-DD'),
- locale = _.get(req, 'query.locale'),
- chiefId = _.get(req, 'query.chief-id'),
- orgUnits = [],
- isLocalhost = req.headers.host.split(':')[0] === 'localhost',
- jar = request.jar(),
- isClose = false,
- scheduleRequests,
- scheduleRequestTypes;
- if (!orgUnitIds || !date) {
- res.send('ERROR');
- return;
- }
- clientProperties = require(properties.client);
- serverProperties = require(properties.server);
- locale && moment.locale(locale);
- !isLocalhost && jar.setCookie(request.cookie(req.headers.cookie), clientProperties.api.host);
- request.get({
- url : clientProperties.api.host + ':' + clientProperties.api.port + clientProperties.api.path + clientProperties.api.version,
- headers: isLocalhost ? {'Authorization': 'Basic ' + btoa(username + ':' + password)} : null,
- jar : isLocalhost ? null : jar
- }, function (error, response, body) {
- if (error) {
- console.log(error);
- res.send('Can not be authenticated');
- return;
- }
- let data = tryParseJSON(body);
- if (response.statusCode === 401) {
- res.send(_.get(data, '[0].message'));
- return;
- }
- if (response.statusCode !== 200) {
- res.send('Unacceptable status code');
- return;
- }
- let links = _.get(data, '_links'),
- length = orgUnitIds.length;
- if (!links) {
- res.send('Can not get links');
- return;
- }
- isLocalhost && jar.setCookie(request.cookie(_.get(response.headers, 'set-cookie[0]')), clientProperties.api.host);
- req.on('close', () => {
- isClose = true;
- });
- function renderPdf() {
- switch (os.type()) {
- case 'Linux':
- wkhtmltopdf.command = serverProperties.binPath + '/wkhtmltopdf/linux/wkhtmltopdf';
- break;
- case 'Darwin':
- wkhtmltopdf.command = serverProperties.binPath + '/wkhtmltopdf/macosx/wkhtmltopdf';
- break;
- case 'Windows_NT':
- wkhtmltopdf.command = serverProperties.binPath + '/wkhtmltopdf/windows/wkhtmltopdf.exe';
- break;
- }
- _.forEach(orgUnits, orgUnit => {
- orgUnit.pages = _.chunk(orgUnit[isImpersonal ? 'positionTypes' : 'employeePositions'], orgUnit.comments ? 9 : 12);
- });
- let orgUnit_ = [];
- _.forEach(orgUnits, orgUnit => {
- _.size(orgUnit.employeePositions) > 0 && orgUnit_.push(orgUnit);
- });
- orgUnits = orgUnit_;
- let template = fs.readFileSync(__dirname + '/template.html', 'utf8'),
- options = {
- orientation: 'landscape',
- 'B' : 0,
- 'L' : 0,
- 'R' : 0,
- 'T' : 0,
- zoom : serverProperties.zoomFactor
- },
- // zoom: os.type() === 'Linux' ? 0.5 : 0.75
- scope = {
- monthArray : getMonthArray(date),
- date : _.upperFirst(date.format('MMMM YYYY')),
- scheduleRequests: scheduleRequests,
- isImpersonal : isImpersonal,
- base : clientProperties.client.host + ':' + clientProperties.client.port,
- };
- if (isZip) {
- res.setHeader('content-type', 'application/zip');
- let archive = archiver('zip', {
- zlib: {level: 0}
- });
- let dirName = serverProperties.tmpPath + '/' +_.random(1e10, 1e15);
- fs.mkdirSync(dirName);
- let limit_ = serverProperties.processesLimit;
- function a(i) {
- if (orgUnits.length !== i + 1) return;
- // console.log('a')
- _.forEach(orgUnits, (orgUnit, i) => {
- archive.file(dirName + '/' + i + '.pdf', {name: orgUnit.orgUnit.name + '.pdf'});
- });
- archive.finalize();
- archive.pipe(res);
- archive.on('end', () => {
- rimraf(dirName, () => {});
- });
- }
- function f(i) {
- if (isClose) {
- setTimeout(() => rimraf(dirName, () => {}), 10000);
- return;
- }
- // console.log('f ' + i)
- if (orgUnits.length >= i + 1) {
- scope.orgUnits = [orgUnits[i]];
- options.output = dirName + '/' + i + '.pdf';
- if (--limit_ === 0) {
- wkhtmltopdf(handlebars.compile(template)(scope), _.clone(options), () => {
- f(i + 1);
- a(i)
- });
- limit_ = serverProperties.processesLimit;
- } else {
- wkhtmltopdf(handlebars.compile(template)(scope), _.clone(options), () => a(i));
- f(i + 1);
- }
- }
- }
- f(0);
- } else {
- res.setHeader('content-type', 'application/pdf');
- scope.orgUnits = orgUnits;
- let fileName = serverProperties.tmpPath + '/' + _.random(1e10, 1e15) + '.pdf';
- options.output = fileName;
- wkhtmltopdf(handlebars.compile(template)(scope), options, () => {
- fs.createReadStream(fileName).pipe(res);
- setTimeout(() => fs.unlinkSync(fileName), 100);
- });
- }
- }
- function after() {
- if (isClose) return;
- _.forEach(orgUnitIds, orgUnitId => {
- let model = {
- orgUnit : null,
- employeePositions : null,
- positionTypes : null,
- chief : null,
- comments : null,
- shifts : null,
- roster : null,
- pages : null,
- productionCalendarInfo: null,
- isScheduleTemplateUsed: null
- };
- request.get({
- url: _.get(links, 'orgUnits.href') + '/' + orgUnitId,
- jar: jar
- }, (error, response, orgUnit) => {
- if (error || response.statusCode !== 200) {
- --length === 0 && renderPdf();
- return;
- }
- model.orgUnit = tryParseJSON(orgUnit);
- let resources = 0;
- function after() {
- if (isClose) return;
- // console.log('ou ' + (length - 1))
- orgUnits.push(model);
- --length === 0 && renderPdf();
- }
- !isImpersonal && (chiefId ? true : _.get(model.orgUnit, '_links.chief-position.href')) && ++resources &&
- request.get({
- url: chiefId ? (_.get(links, 'positions.href') + '/' + chiefId) : _.get(model.orgUnit, '_links.chief-position.href'),
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- let position = tryParseJSON(body);
- if (_.get(position, '_links.employee.href')) {
- request.get({
- url: _.get(position, '_links.employee.href'),
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- model.chief = tryParseJSON(body);
- --resources === 0 && after();
- });
- } else {
- --resources === 0 && after();
- }
- });
- ++resources &&
- request.get({
- url: link(_.get(model.orgUnit, '_links.productionCalendar.href')) + '?' + 'date=' + from,
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- request.get({
- url: link(_.get(tryParseJSON(body), '_links.productionCalendarInfo.href')),
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- model.productionCalendarInfo = tryParseJSON(body);
- model.productionCalendarInfo.monthWorkDayCount = _.get(model.productionCalendarInfo, `monthWorkDayCount[${date.month()}]`);
- model.productionCalendarInfo.monthOffDayCount = _.get(model.productionCalendarInfo, `monthOffDayCount[${date.month()}]`);
- model.productionCalendarInfo.monthHourCount = _.get(model.productionCalendarInfo, `monthHourCount[${date.month()}]`);
- --resources === 0 && after();
- });
- });
- ++resources &&
- request.get({
- url: link(_.get(links, 'comments.href'), {organizationUnitId: orgUnitId}) + '?' + 'from=' + from + '&' + 'to=' + to + '&' + 'size=' + 1e5,
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- model.comments = _.get(tryParseJSON(body), '_embedded.comments');
- --resources === 0 && after();
- });
- !isImpersonal && ++resources &&
- request.get({
- url: _.get(model.orgUnit, '_links.employeePositions.href') + '?' + 'from=' + from + '&' + 'to=' + to + '&' + 'size=' + 1e5 + '&' + 'include-chief=true',
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- model.employeePositions = _.filter(_.get(tryParseJSON(body), '_embedded.employeePositions'), e => {
- if (_.get(positionTypeIds, '[0]') !== '') {
- return _.some(positionTypeIds, id => id === _.last(_.split(_.get(e, '_embedded.position._links.positionType.href'), '/')));
- }
- return true;
- });
- --resources === 0 && after();
- });
- ++resources && request.get({
- url: link(_.get(model.orgUnit, '_links.rosters.href') + '?' + 'from=' + from + '&' + 'to=' + to),
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- let rosters = _.get(tryParseJSON(body), '_embedded.rosters');
- model.roster = _.find(rosters, {'active': true});
- model.isScheduleTemplateUsed = _.get(model, 'roster.scheduleTemplateUsed');
- if (model.roster) {
- resources--;
- isImpersonal && ++resources &&
- request.get({
- url: link(_.get(model.roster, '_links.positionTypes.href')) + '?' + 'from=' + from + '&' + 'to=' + to,
- jar: jar
- }, function (error, response, body) {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- model.positionTypes = _.unionBy([], _.get(tryParseJSON(body), '_embedded.positionTypes'), 'positionIndex');
- --resources === 0 && after();
- });
- ++resources &&
- request.get({
- url: link(_.get(model.roster, '_links.shifts.href')) + '?' + 'from=' + from + '&' + 'to=' + to,
- jar: jar
- }, function (error, response, body) {
- if (error || response.statusCode !== 200) {
- --resources === 0 && after();
- return;
- }
- model.shifts = _.get(tryParseJSON(body), '_embedded.shifts');
- model.shifts && _.forEach(model.shifts, e => {
- e.startDate = moment(_.get(e, 'dateTimeInterval.startDateTime'));
- e.endDate = moment(_.get(e, 'dateTimeInterval.endDateTime'));
- e.haveMinutes = e.startDate.minutes() > 0 || e.endDate.minutes();
- delete e.dateTimeInterval;
- });
- --resources === 0 && after();
- });
- } else {
- --resources === 0 && after();
- }
- });
- });
- });
- }
- isImpersonal ? after() : request.get({
- url : _.get(links, 'scheduleRequestTypes.href'),
- headers: {
- 'Accept': 'application/json'
- },
- jar : jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- res.send('Can not get scheduleRequestTypes');
- return;
- }
- scheduleRequestTypes = tryParseJSON(body);
- request.get({
- url: link(_.get(links, 'scheduleRequests.href')) + '?' + 'from=' + from + '&' + 'to=' + to + '&' + 'size=' + 1e5 + '&' + 'org-unit-ids=' + orgUnitIds.join(','),
- jar: jar
- }, (error, response, body) => {
- if (error || response.statusCode !== 200) {
- res.send('Can not get scheduleRequests');
- return;
- }
- scheduleRequests = _.get(tryParseJSON(body), '_embedded.scheduleRequests');
- _.forEach(scheduleRequests, e => {
- e.startDate = moment(_.get(e, 'dateTimeInterval.startDateTime'));
- e.endDate = moment(_.get(e, 'dateTimeInterval.endDateTime'));
- e.text = _.get(_.find(scheduleRequestTypes, ['value', e.type]), 'extended.shortName');
- delete e.dateTimeInterval;
- });
- after();
- });
- });
- });
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement