agmission/Development/server/helpers/subscription_util.js

155 lines
4.7 KiB
JavaScript

'use strict';
const ObjectId = require('mongodb').ObjectId,
Job = require('../model/job'),
utils = require('./utils'),
env = require('../helpers/env'),
{ SubType } = require('../model/subscription'),
{ Errors, TrialTypes } = require('./constants'),
{ AppError, AppMembershipError, AppParamError } = require('./app_error'),
assert = require('assert'),
moment = require('moment');
const stripe = require('stripe')(env.STRIPE_SEC_KEY, {
apiVersion: env.STRIPE_API_VERSION,
appInfo: { // For sample support and debugging, not required for production:
name: 'AG-NAV AgMission Stripe Intergration',
version: '2.10.13',
url: 'https://agmission.agnav.com'
}
})
function _createFilterObj(uid, fromTS, toTS) {
const filterOps = { byPuid: uid, markedDelete: { $ne: true } }
if (fromTS || toTS) filterOps.createdAt = {};
if (fromTS) filterOps.createdAt.$gte = new Date(fromTS * 1e3);
if (toTS) filterOps.createdAt.$lte = new Date(toTS * 1e3);
return filterOps;
}
async function calcTotalAreaByUser(uid, fromTS, toTS) {
if (!uid || !ObjectId.isValid(uid)) return 0;
const filterOps = _createFilterObj(uid, fromTS, toTS);
const pipeline = [
{
$match: filterOps
},
{
$group: {
"_id": "null",
"ttSprayAreas": { $sum: "$ttSprArea" }
}
},
{
$project: {
'_id': false,
ttSprayAreas: { $round: ["$ttSprayAreas", 2] }
}
}];
const res = await Job.aggregate(pipeline);
return res && res.length ? res[0].ttSprayAreas : 0;
}
async function getJobUsageByTime(byPuid, fromTS, toTS) {
if (!ObjectId.isValid(byPuid)) return null;
const filterOps = _createFilterObj(byPuid, fromTS, toTS);
const pipeline = [
{ $match: filterOps },
{
$lookup: {
from: 'applications',
localField: '_id',
foreignField: 'jobId',
as: 'jobs_apps'
}
},
{ $unwind: { path: '$jobs_apps', preserveNullAndEmptyArrays: true } },
{
$group: {
'_id': {
'_id': '$_id',
'createdAt': '$createdAt',
},
ttSprArea: { $first: "$ttSprArea" },
totalSprayed: { $sum: '$jobs_apps.totalSprayed' },
updateDate: { $max: '$jobs_apps.updateDate' }
}
},
// { $match: { totalSprayed: { $gt: 0 } } },
{
$replaceRoot: { newRoot: { $mergeObjects: ['$$ROOT', '$_id'] } }
},
{
$project: {
_id: false,
jobId: '$_id',
ttSprArea: 1,
totalSprayed: { $round: ['$totalSprayed', 2] },
updateDate: 1,
createdAt: 1
}
}
];
const res = await Job.aggregate(pipeline);
return res;
}
function getPkgSubfromUserInfo(userInfo) {
if (!userInfo || !userInfo.membership || utils.isEmptyArray(userInfo.membership.subscriptions)) AppMembershipError.throw();
let pkgSub = userInfo.membership.subscriptions.filter(sub => sub.type === SubType.PACKAGE);
if (!utils.isEmptyArray(pkgSub)) {
pkgSub = pkgSub[0];
}
else {
AppMembershipError.throw(Errors.PKG_SUBSCRIPTION_NOT_FOUND);
}
return pkgSub;
}
function getSubMetaField(pkgSub, metaField) {
return pkgSub && !utils.isEmptyArray(pkgSub.items) && (pkgSub.items[0].metadata && pkgSub.items[0].metadata[metaField]);
}
function validateTrial(trials, errorCode = Errors.INVALID_PARAM) {
if (!trials) return;
if (TrialTypes.BY_DATE === trials.type && trials.byDate) {
const byDateMoment = moment.utc(trials.byDate);
assert(byDateMoment.isValid(), AppError.create(Errors.INVALID_PARAM));
assert(moment.utc(byDateMoment).diff(moment.utc(), "days") > 1, AppError.create(errorCode));
} else if (TrialTypes.DAYS === trials.type && trials.trialDays > 0) {
const endTrialDate = (trials.startDate ? moment.utc(trials.startDate) : moment.utc()).add(trials.trialDays, "days");
assert(endTrialDate.diff(moment.utc(), "days") > 1, AppError.create(errorCode));
}
}
function timeToQueryRange(byTime, fieldName) {
let qRange;
if (!byTime || !fieldName) return qRange;
const m = byTime.match(/^(\d{1,3})(?<time>[m|d]{1})|\d{4}$/is);
if (m && m.length > 2) {
let startUTC;
if (m.groups && m.groups['time']) {
startUTC = moment().utc();
qRange = `${fieldName}<=${startUTC.unix()}`;
const daysOrMonths = m[1] > 0 ? m[1] : 3;
qRange = `${fieldName}>=${startUTC.subtract(daysOrMonths, m.groups['time'].toLowerCase() == 'd' ? 'days' : 'months').unix()} AND ` + qRange;
} else {
startUTC = moment(m[0]).utc();
qRange = `${fieldName}>=${startUTC.startOf('year').unix()} AND ${fieldName}<=${startUTC.endOf('year').unix()}`;
}
}
return qRange;
}
module.exports = {
stripe, getPkgSubfromUserInfo, getSubMetaField, calcTotalAreaByUser, getJobUsageByTime, validateTrial, timeToQueryRange
}