import BuyerUnits from '/common/db/buyerUnit';
import IncomingRequests from '/common/db/request';
import resultRows from '/modules/reports/server/resultRows';
import {Meteor} from 'meteor/meteor';
import {check, Match} from 'meteor/check';
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.tcWork.buyer'(options) {
check(options, Object);
check(options.relationship, Match.Maybe(String));
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: '', 'requests-closed': [], 'requests-closedAlt': [], 'requests-open': [],
'inception-enquired': {groups: [], ids: []},
'inception-suggested': {groups: [], ids: []},
'shortlisting-shortlisted': {groups: [], ids: []},
'visit-pending': {groups: [], ids: []},
'visit-scheduled': {groups: [], ids: []},
'visit-completed-enq': {groups: [], ids: []},
'visit-completed-sug': {groups: [], ids: []},
'visit-completed': {groups: [], ids: []},
'decision-pending-enq': {groups: [], ids: []},
'decision-pending-sug': {groups: [], ids: []},
'decision-pending': {groups: [], ids: []},
'decision-visitReject-enq': {groups: [], ids: []},
'decision-visitReject-sug': {groups: [], ids: []},
'decision-visitReject': {groups: [], ids: []},
'decision-interested-enq': {groups: [], ids: []},
'decision-interested-sug': {groups: [], ids: []},
'decision-interested': {groups: [], ids: []},
};
var total = jp(js(baseRow)); total.name = ' Total Count';
// prepare the baseObject
var baseObject = resultRows(options, baseRow);
let dateQuery;
if (options.from && options.to) {
dateQuery = {$gte: new ServerDate(new Date(options.from).setHours(0, 0, 0, 0)), $lt: new ServerDate(new Date(options.to).setHours(24, 0, 0, 0))};
// cDateQuery = {$gte: new ServerDate(new Date(options.from).setHours(-6, 0, 0, 0)), $lt: new ServerDate(new Date(options.to).setHours(18, 0, 0, 0))};
}
var fillData = function(units) {
for (let i = 0; i < units.length; i ++) {
let assignedTo = units[i]._id.assignedTo;
let st = units[i]._id.process + '-' + units[i]._id.status;
if (units[i].subjects) {
baseObject[assignedTo][st] = units[i].subjects;
total[st] = total[st].concat(units[i].subjects);
}
else {
baseObject[assignedTo][st].groups = units[i].groups;
baseObject[assignedTo][st].ids = units[i].ids;
total[st].groups = total[st].groups.concat(units[i].groups);
total[st].ids = total[st].ids.concat(units[i].ids);
}
}
};
let users = {};
Meteor.users.find({_id: {$in: options.assignedTo}}, {fields: {'status.inactive': 1}}).fetch().map(function(u) { users[u._id] = u; });
// total requests created
total['requests-created'] = IncomingRequests.find({createdAt: dateQuery}).count();
// assigned requests
let requests = IncomingRequests.aggregate([
{$match: {createdAt: dateQuery, 'assignedTo.userId': {$in: options.assignedTo}, 'status.duplicateOf': null}},
{$project: {'assignedTo.userId': 1, 'status': {$cond: {if: {$eq: ['$status.open', true]}, then: 'open', else: 'closed'}}}},
{$group: {_id: {assignedTo: '$assignedTo.userId', process: 'requests', status: '$status'}, subjects: {$addToSet: '$_id'}}},
]);
fillData(requests);
requests = IncomingRequests.aggregate([
{$match: {'status.open': false, 'status.updatedAt': dateQuery, 'assignedTo.userId': {$in: options.assignedTo}, 'status.duplicateOf': null}},
{$project: {'assignedTo.userId': 1}},
{$group: {_id: {assignedTo: '$assignedTo.userId', process: 'requests', status: 'closedAlt'}, subjects: {$addToSet: '$_id'}}},
]);
fillData(requests);
// suggested units
let query = {removed: false, 'processDetails.0.updatedBy': {$in: options.assignedTo}};
if (dateQuery) query['processDetails.0.updatedAt'] = dateQuery;
let units = BuyerUnits.aggregate([
{$match: query},
{$project: {processDetails: 1, 'group.id': 1}},
{$unwind: '$processDetails'},
{$match: {'processDetails.process': 'inception'}},
{$group: {_id: {assignedTo: '$processDetails.updatedBy', process: '$processDetails.process', status: '$processDetails.status'}, ids: {$addToSet: '$_id'}, groups: {$addToSet: '$group.id'}}},
]);
fillData(units);
let unitIds = [];
units.map(function(it) {
unitIds = [...unitIds, ...it.ids];
});
// shortlisted
units = BuyerUnits.aggregate([
{$match: {_id: {$in: unitIds}}},
{$project: {processDetails: 1, 'group.id': 1}},
{$unwind: '$processDetails'},
{$match: {'processDetails.history.assignedTo': {$in: options.assignedTo}, 'processDetails.process': 'shortlisting', 'processDetails.stage': 'done'}},
{$unwind: '$processDetails.history'},
{$match: {'processDetails.history.assignedTo': {$in: options.assignedTo}, 'processDetails.process': 'shortlisting', 'processDetails.history.status': 'shortlisted'}},
{$group: {_id: {assignedTo: '$processDetails.history.assignedTo', process: '$processDetails.process', status: '$processDetails.history.status'}, groups: {$addToSet: '$group.id'}, ids: {$addToSet: '$_id'}}},
]);
fillData(units);
// visit pending
units = BuyerUnits.aggregate([
{$match: {_id: {$in: unitIds}}},
{$project: {processDetails: 1, 'group.id': 1}},
{$unwind: '$processDetails'},
{$match: {'processDetails.process': 'visit', 'processDetails.stage': 'pending'}},
{$unwind: '$processDetails.history'},
{$group: {_id: '$_id', assignedTo: {$last: '$processDetails.history.assignedTo'}, groupId: {$last: '$group.id'}}},
{$match: {'assignedTo': {$in: options.assignedTo}}},
{$group: {_id: {assignedTo: '$assignedTo', process: 'visit', status: 'pending'}, groups: {$addToSet: '$groupId'}, ids: {$addToSet: '$_id'}}},
]);
fillData(units);
// visit scheduled
units = BuyerUnits.aggregate([
{$match: {'processDetails.history.createdAt': dateQuery, 'processDetails.2.process': 'visit', 'processDetails.history.createdBy': {$in: options.assignedTo}, removed: false}},
{$project: {processDetails: 1, 'group.id': 1}},
{$unwind: '$processDetails'},
{$match: {'processDetails.history.createdBy': {$in: options.assignedTo}, 'processDetails.history.createdAt': dateQuery, 'processDetails.process': 'visit'}},
{$unwind: '$processDetails.history'},
{$match: {'processDetails.history.createdBy': {$in: options.assignedTo}, 'processDetails.history.status': {$in: ['scheduled', 'rescheduled']}, 'processDetails.history.createdAt': dateQuery}},
{$group: {_id: {assignedTo: '$processDetails.history.createdBy', process: '$processDetails.process', status: 'scheduled'}, groups: {$addToSet: '$group.id'}, ids: {$addToSet: '$_id'}}},
]);
fillData(units);
// visit completed
units = BuyerUnits.aggregate([
{$match: {'processDetails.history.createdAt': dateQuery, 'processDetails.2.process': 'visit', 'processDetails.history.createdBy': {$in: options.assignedTo}, removed: false}},
{$project: {processDetails: 1, 'group.id': 1, inception: {$arrayElemAt: [ '$processDetails', 0]}}},
{$unwind: '$processDetails'},
{$match: {'processDetails.history.assignedTo': {$in: options.assignedTo}, 'processDetails.history.createdAt': dateQuery, 'processDetails.process': 'visit'}},
{$unwind: '$processDetails.history'},
{$match: {'processDetails.history.assignedTo': {$in: options.assignedTo}, 'processDetails.history.status': 'completed', 'processDetails.history.createdAt': dateQuery}},
{$project: {
processDetails: 1,
status: {$concat: [
'$processDetails.history.status',
'-',
{$cond: [{$eq: ['$inception.status', 'enquired']}, 'enq', 'sug']},
]},
group: 1,
}},
{$group: {_id: {
assignedTo: '$processDetails.history.assignedTo',
process: '$processDetails.process',
status: '$status',
}, ids: {$addToSet: '$_id'}, groups: {$addToSet: '$group.id'}}},
]);
fillData(units);
unitIds = [];
units.map(function(it) {
unitIds = [...unitIds, ...it.ids];
});
// decision
units = BuyerUnits.aggregate([
{$match: {_id: {$in: unitIds}}},
{$project: {processDetails: 1, 'group.id': 1, inception: {$arrayElemAt: [ '$processDetails', 0]}}},
{$unwind: '$processDetails'},
{$match: {'processDetails.process': 'decision'}},
{$unwind: '$processDetails.history'},
{$group: {
_id: '$_id',
status: {$first: '$processDetails.status'},
stage: {$first: '$processDetails.stage'},
assignedTo: {$first: '$processDetails.history.assignedTo'},
groupId: {$first: '$group.id'},
inception: {$first: '$inception'},
}},
{$match: {'assignedTo': {$in: options.assignedTo}}},
{$project: {
assignedTo: 1,
groupId: 1,
status: {$concat: [
{$cond: {if: {$eq: ['$stage', 'pending']}, then: 'pending', else: '$status'}},
'-',
{$cond: [{$eq: ['$inception.status', 'enquired']}, 'enq', 'sug']},
]},
}},
{$group: {_id: {
assignedTo: '$assignedTo',
process: 'decision',
status: '$status',
}, ids: {$addToSet: '$_id'}, groups: {$addToSet: '$groupId'}}},
]);
fillData(units);
// // decision done
// units = BuyerUnits.aggregate([
// {$match: {removed: false, 'cancellation.flag': false, 'processDetails.process': 'negotiation', 'processDetails.stage': 'pending', 'assignedTo.userId': {$in: options.assignedTo}}},
// {$project: {processDetails: 1, 'group.id': 1}},
// {$unwind: '$processDetails'},
// {$match: {'processDetails.process': 'negotiation', 'processDetails.stage': 'pending'}},
// {$unwind: '$processDetails.history'},
// {$match: {'assignedTo': {$in: options.assignedTo}, 'processDetails.history.status': {$in: ['visitReject', 'interested']}, 'processDetails.history.createdAt': dateQuery}},
// {$group: {_id: {assignedTo: '$processDetails.history.assignedTo', process: '$processDetails.process', status: '$processDetails.history.status'}, groups: {$addToSet: '$group.id'}, ids: {$addToSet: '$_id'}}},
// ]);
// fillData(units);
// prepare resultData
var resultData = [];
for (let i in baseObject) {
if (Object.prototype.hasOwnProperty.call(baseObject, i)) {
['visit-completed', 'decision-pending', 'decision-visitReject', 'decision-interested'].map(st => {
baseObject[i][st].ids = [...new Set([...baseObject[i][`${st}-enq`].ids, ...baseObject[i][`${st}-sug`].ids])];
baseObject[i][st].groups = [...new Set([...baseObject[i][`${st}-enq`].groups, ...baseObject[i][`${st}-sug`].groups])];
total[st].groups = total[st].groups.concat(baseObject[i][st].groups);
total[st].ids = total[st].ids.concat(baseObject[i][st].ids);
});
resultData.push({userId: i, inactive: (users[i]?.status || {}).inactive, ...baseObject[i]});
}
}
resultData.push({userId: null, ...total});
return resultData;
},
});