agmission/Development/server/controllers/customer.js

151 lines
5.0 KiB
JavaScript

'use strict';
const Customer = require('../model/customer'),
cache = require('../helpers/mem_cache'),
ObjectId = require('mongodb').ObjectId,
utils = require('../helpers/utils'),
{ UserTypes, TrialTypes } = require('../helpers/constants'),
{ AppParamError } = require('../helpers/app_error'),
{ validateTrial } = require('../helpers/subscription_util'),
moment = require('moment'),
debug = require('debug')('agm:controllers-customer');
async function getCustomers_get(req, res) {
const customers = await Customer.aggregate(
[
{ $match: { kind: UserTypes.APP, markedDelete: { $ne: true } } },
{
$lookup: {
from: 'jobs',
localField: '_id',
foreignField: 'byPuid',
as: 'cust_jobs'
}
},
{ $unwind: { path: '$cust_jobs', preserveNullAndEmptyArrays: true } },
{
$group: {
'_id': {
'_id': '$_id',
'name': '$name',
'contact': '$contact',
'email': '$email',
'active': '$active',
'billable': '$billable',
'premium': '$premium',
'createdAt': '$createdAt',
'username': '$username'
},
'totalJobs': {
$sum: { $cond: [{ $gte: ['$cust_jobs', null] }, 1, 0] }
}
}
},
{
$replaceRoot: { newRoot: { $mergeObjects: ['$$ROOT', '$_id'] } }
},
]).allowDiskUse(true);
res.json(customers);
}
async function createCustomer_post(req, res) {
const _customer = req.body;
if (!_customer || !_customer.username || !_customer.password) AppParamError.throw();
if (_customer.membership && _customer.membership.trials) {
validateTrial(_customer.membership.trials);
}
delete _customer._id;
const newCustomer = new Customer(Customer.toUser(_customer));
const theUser = await newCustomer.createOne();
res.json(theUser);
}
async function getCustomer_get(req, res) {
const cId = req.params.customer_id;
if (!ObjectId.isValid(cId)) AppParamError.throw();
const customer = await Customer.findOne({ _id: ObjectId(cId) }, null, { lean: true }).populate({ path: 'Country', select: 'code name -_id' });
res.json(customer);
}
async function updateCustomer_put(req, res) {
const _customer = req.body;
if (!_customer || !utils.isObjectId(_customer._id)) AppParamError.throw();
if (utils.isBlank(_customer.username) && !utils.isBlank(_customer.password))
_customer.password = undefined;
if (!_customer.hasOwnProperty('active'))
_customer.active = true;
let customer = await Customer.findOne({ _id: ObjectId(_customer._id) });
if (customer) {
if (!utils.isEmptyObj(_customer.membership)) {
if (!utils.isEmptyObj(_customer.membership.trials)) {
const custTrials = customer.membership && customer.membership.trials;
const curMoment = moment.utc();
if (custTrials && custTrials.lasStartDate && custTrials.lastEndDate) {
if (curMoment.isBetween(moment.utc(custTrials.lastStartDate), moment.utc(custTrials.lastEndDate))) {
// Ignore updating trials if the customer is being in the middle of trial period
delete _customer.membership.trials;
}
}
// For days trial, if startDate not mentioned (and it is not in the trial period), infer and set the trial startDate from today UTC
if (_customer.membership.trials.type === TrialTypes.DAYS && !_customer.membership.trials.startDate) {
_customer.membership.trials.startDate = curMoment.toDate();
}
validateTrial(_customer.membership.trials);
} else {
delete _customer.membership.trials;
}
// Never try to update any subscriptions, customer must follow the sub. change process or changed made in Stripe dashboard only.
delete _customer.membership.subscription;
}
customer = await Customer.findOneAndUpdate({ _id: ObjectId(_customer._id) }, _customer, { runValidators: true, new: true, lean: true });
// Update related cached user info if the applicator premium changed
// TODO: Later, may be improving this logic using hash or independant cached when needed.
const uiList = cache.filterByKind(customer._id.toHexString());
let uiValue;
for (let i = 0; i < uiList.length; i++) {
uiValue = uiList[i];
if (uiValue) {
if (customer.premium !== uiValue[1]['premium'])
uiValue[1].premium = customer.premium;
}
}
}
res.json(customer);
}
async function deleteCustomer(req, res) {
const _id = req.params.customer_id;
if (!utils.isObjectId(_id)) AppParamError.throw();
const customer = await Customer.findById(ObjectId(_id));
if (customer)
await customer.removeFull();
// Remove all related logged user sessions
const uiList = cache.filterByKind(_id);
if (uiList) {
for (const u of uiList)
cache.delete(u[0]);
}
cache.delete(_id);
res.json({ message: 'deleted' });
}
module.exports = {
getCustomers_get, createCustomer_post, getCustomer_get, updateCustomer_put, deleteCustomer
}