portal/modules/reports/server/work/seller/verifier/methods.js

import {Meteor} from 'meteor/meteor';
import Units from '/common/db/unit';

Meteor.methods({
	/**
	 * @param {Object} options assignedToQueryject containing from (Date), to (Date)  and assignedTo (Array of ids) fields.
	 * @summary
	 * 1. Find all required telecallers
	 * 2. Find all rawUnits assigned to those telecallers and loop on them
	 * 3. if cancelled, count as cancelled, else {
	 * 			count statuses
	 * 			count callLaters
	 * 		}
	 * 4. if (callLater)
	 * @returns {Object} reactive-table-data
	 */
	async 'reports.work.verifier'(options) {
		const {check} = require('meteor/check');
		check(options, Object);
		options.from = options.date?.[0] ? new Date(options.date[0]) : null;
		options.to = options.date?.[1] ? new Date(options.date[1]) : null;
		delete options.date;

		var baseRow = {name: '', 'verification-confirmed': [], 'verification-pending': [], 'verification-given': [], 'verification-completed': [], 'verification-failed': [], 'upload-pending': [], 'upload-photosAwaited': [], 'upload-dataUploaded': [], 'upload-approved': [], 'unitCancelled': [], 'morning': [], 'evening': []};
		var total = jp(js(baseRow)); total.name = ' Total Count';
		// prepare the baseObject
		// also set options.assignedTo
		const {default: resultRows} = require('/modules/reports/server/resultRows');
		var baseObject = resultRows(options, baseRow);

		let dateQuery;
		if (options.from && options.to) dateQuery = {$gte: new ServerDate(options.from.setHours(0, 0, 0, 0)), $lt: new ServerDate(options.to.setHours(24, 0, 0, 0))};
		else return [];

		var fillData = function(units, status) {
			for (let i = 0; i < units.length; i ++) {
				let assignedTo = units[i]._id.assignedTo;
				let st = status || (units[i]._id.process + '-' + units[i]._id.status);
				let timings = '';
				const {default: incentivesBeyondNormalHoursThresholds} = require('/common/info/incentive/beyondNormalHoursThresholds');
				const {default: dateFormat} = require('/common/utils/date/toStr');
				if (units[i]._id.appointmentDate) {
					let aHour = parseInt(dateFormat(units[i]._id.appointmentDate, 'HH'), 10);
					let uHour = parseInt(dateFormat(units[i]._id.updatedAt, 'HH'), 10);
					if (dateFormat(units[i]._id.appointmentDate, 'MMM-DD-YYYY') === dateFormat(units[i]._id.updatedAt, 'MMM-DD-YYYY')) {
						if (uHour < incentivesBeyondNormalHoursThresholds.morning1 && aHour < incentivesBeyondNormalHoursThresholds.morning1) timings = 'morning';
						if (uHour > incentivesBeyondNormalHoursThresholds.evening1 && aHour > incentivesBeyondNormalHoursThresholds.evening1) timings = 'evening';
					}
				}
				if (!baseObject[assignedTo]) continue;
				baseObject[assignedTo][st] = baseObject[assignedTo][st]?.concat(units[i].subjects);
				if (st === 'verification-completed') {
					baseObject[assignedTo]['verification-given'] = baseObject[assignedTo]['verification-given']?.concat(units[i].subjects);
					total['verification-given'] = total['verification-given']?.concat(units[i].subjects);
				}
				if (timings) {
					baseObject[assignedTo][timings] = baseObject[assignedTo][timings].concat(units[i].subjects);
					total[timings] = total[timings]?.concat(units[i].subjects);
				}
				total[st] = total[st]?.concat(units[i].subjects);
			}
		};

		let users = {};
		Meteor.users.find({_id: {$in: options.assignedTo}}, {fields: {'status.inactive': 1}}).fetch().map(function(u) { users[u._id] = u; });
		let units;

		// verfication pending
		units = Units.aggregate([
			// $ne does not work for processDetail.2.status
			{$match: {removed: false, 'cancellation.flag': false, 'processDetails.2.status': {$ne: 'cancelled'}, 'processDetails.2.stage': 'pending', 'processDetails.history.visitExec': {$in: options.assignedTo}, 'processDetails.history.appointmentDate': dateQuery}},
			{$project: {processDetails: 1}},
			{$unwind: '$processDetails'},
			{$match: {'processDetails.process': 'verification', 'processDetails.status': {$ne: 'cancelled'}, 'processDetails.history.visitExec': {$in: options.assignedTo}, 'processDetails.history.appointmentDate': dateQuery}},
			{$unwind: '$processDetails.history'},
			{$group: {_id: '$_id', visitExec: {$last: '$processDetails.history.visitExec'}, appointmentDate: {$last: '$processDetails.history.appointmentDate'}}},
			{$match: {visitExec: {$in: options.assignedTo}, appointmentDate: dateQuery}},
			{$group: {_id: {assignedTo: '$visitExec', process: 'verification', status: 'pending'}, subjects: {$addToSet: '$_id'}}},
		]);
		fillData(units);

		// verification confirmed
		units = Units.aggregate([
			{$match: {removed: false, 'cancellation.flag': false, 'processDetails.2.visitExec': {$in: options.assignedTo}, 'processDetails.2.appointmentDate': dateQuery}},
			{$project: {processDetails: 1}},
			{$unwind: '$processDetails'},
			{$match: {'processDetails.process': 'verification'}},
			{$group: {_id: {appointmentDate: '$processDetails.appointmentDate', updatedAt: '$processDetails.updatedAt', assignedTo: '$processDetails.visitExec', process: 'verification', status: {$cond: {if: {$eq: ['$processDetails.status', 'completed']}, then: 'completed', else: 'given'}}}, subjects: {$addToSet: '$_id'}}},
		]);
		fillData(units);

		//failed
		units = Units.aggregate([
			{$match: {removed: false, 'cancellation.flag': false, 'processDetails.2.visitExec': {$in: options.assignedTo}, 'processDetails.2.appointmentDate': dateQuery}},
			{$project: {processDetails: 1}},
			{$unwind: '$processDetails'},
			{$match: {'processDetails.status': 'failed'}},
			{$group: {_id: {appointmentDate: '$processDetails.appointmentDate', updatedAt: '$processDetails.updatedAt', assignedTo: '$processDetails.visitExec', process: 'verification', status: 'failed'}, subjects: {$addToSet: '$_id'}}},
		]);
		fillData(units);

		// upload completed
		units = Units.aggregate([
			{$match: {removed: false, 'cancellation.flag': false, 'processDetails.3.stage': 'done', 'processDetails.2.visitExec': {$in: options.assignedTo}, 'processDetails.2.appointmentDate': dateQuery}},
			{$project: {processDetails: 1}},
			{$unwind: '$processDetails'},
			{$match: {'processDetails.process': {$in: ['verification', 'upload']}}},
			{$group: {_id: '$_id', visitExec: {$first: '$processDetails.visitExec'}, uploadStatus: {$last: '$processDetails.status'}}},
			{$group: {_id: {assignedTo: '$visitExec', process: 'upload', status: '$uploadStatus'}, subjects: {$addToSet: '$_id'}}},
		]);
		fillData(units);

		// upload pending
		units = Units.aggregate([
			{$match: {removed: false, 'cancellation.flag': false, 'processDetails.3.stage': 'pending', 'processDetails.2.stage': 'done', 'processDetails.2.visitExec': {$in: options.assignedTo}}},
			{$project: {processDetails: 1}},
			{$unwind: '$processDetails'},
			{$match: {'processDetails.process': {$in: ['verification', 'upload']}}},
			{$group: {_id: '$_id', visitExec: {$first: '$processDetails.visitExec'}, uploadStatus: {$last: '$processDetails.status'}}},
			{$group: {_id: {assignedTo: '$visitExec', process: 'upload', status: '$uploadStatus'}, subjects: {$addToSet: '$_id'}}},
		]);
		fillData(units);

		// // builder dataUploaded
		// let sellerProjects = SellerProjects.aggregate([
		// 	{$match: {removed: false, 'cancellation.flag': false, 'processDetails.3.process': 'upload', 'processDetails.3.status': 'dataUploaded', 'processDetails.2.visitExec': {$in: options.assignedTo}, 'processDetails.2.appointmentDate': dateQuery}},
		// 	{$project: {processDetails: 1}},
		// 	{$unwind: '$processDetails'},
		// 	{$match: {'processDetails.process': {$in: ['upload']}}},
		// 	{$group: {_id: '$_id', visitExec: {$first: '$processDetails.visitExec'}, uploadStatus: {$last: '$processDetails.status'}}},
		// 	{$group: {_id: {assignedTo: '$visitExec', process: 'upload', status: '$uploadStatus'}, subjects: {$addToSet: '$_id'}}},
		// ]);
		// fillData(sellerProjects);

		// for (var i = 0; i < options.assignedTo.length; i++) {
		// 	let assignedTo = options.assignedTo[i];
		// 	if (!unitIds[assignedTo]) continue;
		// 	// pending
		// 	baseObject[assignedTo]["upload-pending"] = Units.find({_id: {$in: unitIds[assignedTo]}, "processDetails.2.visitExec": assignedTo, "processDetails.3.stage": "pending"}).fetch().map((it) => it._id);
		// 	total["upload-pending"] = total["upload-pending"].concat(baseObject[assignedTo]["upload-pending"]);
		//
		// 	// uploaded
		// 	units = Units.aggregate([
		// 		{$match: {removed: false, duplicateOf: null, "cancellation.flag": false, "processDetails.history.createdAt": dateQuery, "processDetails.2.visitExec": assignedTo, "processDetails.3.stage": "done"}},
		// 		{$project: {processDetails: 1}},
		// 		{$unwind: "$processDetails"},
		// 		{$match: {"processDetails.history.createdAt": dateQuery, "processDetails.process": "upload"}},
		// 		{$unwind: "$processDetails.history"},
		// 		{$match: {"processDetails.history.status": "dataUploaded", "processDetails.history.createdAt": dateQuery}},
		// 		{$group: {_id: {assignedTo: assignedTo, process: "$processDetails.process", status: "$processDetails.history.status"}, subjects: {$addToSet: "$_id"}}},
		// 	]);
		// 	fillData(units);
		//
		// 	// visit done but upload incomplete
		// 	units = Units.aggregate([
		// 		{$match: {removed: false, duplicateOf: null, "cancellation.flag": false, "processDetails.history.createdAt": dateQuery, "processDetails.2.visitExec": assignedTo, "processDetails.2.stage": "done", "processDetails.3.incomplete": true}},
		// 		{$project: {processDetails: 1}},
		// 		{$unwind: "$processDetails"},
		// 		{$match: {"processDetails.history.createdAt": dateQuery, "processDetails.process": "upload"}},
		// 		{$unwind: "$processDetails.history"},
		// 		{$match: {"processDetails.history.status": "dataUploaded", "processDetails.history.createdAt": dateQuery}},
		// 		{$group: {_id: {assignedTo: assignedTo, process: "upload", status: "incomplete"}, subjects: {$addToSet: "$_id"}}},
		// 	]);
		// 	fillData(units);
		// }

		// prepare resultData
		let resultData = [];
		for (let i in baseObject) {
			if (Object.prototype.hasOwnProperty.call(baseObject, i)) {
				resultData.push({userId: i, inactive: (users[i].status || {}).inactive, ...baseObject[i]});
			}
		}

		// verification scheduled
		total['verification-scheduled'] = ((Units.aggregate([
			// irrespective of unit cancelled
			{$match: {removed: false, 'processDetails.2.status': {$in: ['scheduled', 'rescheduled']}, 'processDetails.history.appointmentDate': dateQuery}},
			{$project: {processDetails: 1}},
			{$unwind: '$processDetails'},
			{$match: {'processDetails.process': 'verification', 'processDetails.history.appointmentDate': dateQuery}},
			{$unwind: '$processDetails.history'},
			{$match: {'processDetails.history.status': {$in: ['scheduled', 'rescheduled']}, 'processDetails.history.appointmentDate': dateQuery}},
			{$group: {_id: null, subjects: {$addToSet: '$_id'}}},
		]) || [])[0] || {}).subjects;
		resultData.push({userId: null, ...total});
		return resultData;
	},
});