@fabrix/spool-cart
Version:
Spool - eCommerce Spool for Fabrix
1,057 lines • 58.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const spool_analytics_1 = require("@fabrix/spool-analytics");
const moment = require("moment");
class StoreAnalytic extends spool_analytics_1.Analytic {
run() {
}
MMR(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
renews_on: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
active: true
}
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Subscription.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_due)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Subscription.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}MMR`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
NR(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
status: 'success',
kind: ['sale', 'capture']
}
};
const query2 = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
status: 'success',
kind: 'refund'
}
};
if (shopId) {
query.where.shop_id = shopId;
query2.where.shop_id = shopId;
}
let resSales;
return this.app.models.Transaction.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Transaction.sequelize.literal('SUM(amount)'), 'total'],
[this.app.models.Transaction.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
resSales = count;
return this.app.models.Transaction.findAll(Object.assign({}, query2, { attributes: [
[this.app.models.Transaction.sequelize.literal('SUM(amount)'), 'total'],
[this.app.models.Transaction.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }));
})
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map((c, index) => {
const cTotal = parseInt(c instanceof this.app.models.Transaction.instance
? (c.get('total') || 0)
: (c.total || 0), 10);
const cCount = parseInt(c instanceof this.app.models.Transaction.instance
? (c.get('count') || 0)
: (c.count || 0), 10);
resSales[index] = resSales[index] || [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
const cTotal2 = parseInt(resSales[index] instanceof this.app.models.Transaction.instance
? (resSales[index].get('total') || 0)
: (resSales[index].total || 0), 10);
const cCount2 = parseInt(resSales[index] instanceof this.app.models.Transaction.instance
? (resSales[index].get('count') || 0)
: (resSales[index].count || 0), 10);
const ct = (cCount2 || 0) - (cCount || 0);
const total = (cTotal2 || 0) - (cTotal || 0);
return [ct, total, c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}NR`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
fees(options = {}) {
}
ARPC(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
updated_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
total_spent: {
$gte: 1
}
},
};
let resCustomers;
return this.app.models.Customer.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Customer.sequelize.literal('SUM(total_spent)'), 'total'],
[this.app.models.Customer.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
resCustomers = count;
return this.app.models.Subscription.findAll({
where: {
renews_on: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
}
},
attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
],
group: ['currency']
});
})
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map((c, i) => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const cCount = resCustomers[i] instanceof this.app.models.Customer.instance
? resCustomers[i].get('count') : resCustomers[i].count;
const amount = cTotal / cCount;
return [amount, c.currency];
});
if (data.length === 0) {
data = [[0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}ARPC`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['gross', 'currency'],
data: data
}]);
});
});
});
}
ARR(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
status: 'success',
kind: ['sale', 'capture']
}
};
if (shopId) {
query.where.shop_id = shopId;
}
let resSales;
return this.app.models.Transaction.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Transaction.sequelize.literal('SUM(amount)'), 'total'],
[this.app.models.Transaction.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map((c, index) => {
const cTotal = parseInt(c instanceof this.app.models.Transaction.instance
? (c.get('total') || 0)
: (c.total || 0), 10);
const cCount = parseInt(c instanceof this.app.models.Transaction.instance
? (c.get('count') || 0)
: (c.count || 0), 10);
const ct = (cCount || 0) * 12;
const total = (cTotal || 0) * 12;
return [ct, total, c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}ARR`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
RLTV(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
renews_on: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
active: true
},
};
if (shopId) {
query.where.shop_id = shopId;
}
let resMMR;
return this.app.models.Subscription.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('AVG(total_due)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
resMMR = count;
return this.app.models.Analytic.findOne({
where: {
name: `store.${shopId ? shopId + '.' : ''}churn`
}
});
})
.then(prevChurn => {
prevChurn = prevChurn || {
data: [[1, this.app.config.get('cart.default_currency')]]
};
let data = resMMR.map((c, index) => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const ltv = cTotal / (prevChurn.data[index][0] || 1);
return [ltv, c.currency];
});
if (data.length === 0) {
data = [[0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}RLTV`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['rltv', 'currency'],
data: data
}]);
});
});
});
}
LTV(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
updated_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
total_spent: {
$gte: 1
}
},
};
return this.app.models.Customer.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Customer.sequelize.literal('AVG(total_spent)'), 'total'],
[this.app.models.Customer.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Customer.instance
? c.get('total') || 0
: c.total || 0;
return [parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}LTV`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['ltv', 'currency'],
data: data
}]);
});
});
});
}
churn(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const start2 = moment()
.subtract(2, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
cancelled_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
cancelled: true
},
};
if (shopId) {
query.where.shop_id = shopId;
}
let resCancelled;
return this.app.models.Subscription.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
resCancelled = count;
return this.app.models.Analytic.findOne({
where: {
name: `store.${shopId ? shopId + '.' : ''}activeSubscriptions`,
end: {
$gte: start2.format('YYYY-MM-DD HH:mm:ss')
}
}
});
})
.then(prevChurn => {
prevChurn = prevChurn || {
data: [[0, 0, this.app.config.get('cart.default_currency')]]
};
let data = resCancelled.map((c, index) => {
prevChurn.data[index] = prevChurn.data[index] || [0, 0, c.currency];
const cTotal = resCancelled instanceof this.app.models.Subscription.instance
? resCancelled.get('total') || 0
: resCancelled.total || 0;
const total = (cTotal / prevChurn.data[index][0]) * 100;
return [total, c.currency];
});
if (data.length === 0) {
data = [[0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}churn`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['churn', 'currency'],
data: data
}]);
});
});
});
}
MMRChurn(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const start2 = moment()
.subtract(2, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
cancelled_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
cancelled: true
},
};
if (shopId) {
query.where.shop_id = shopId;
}
let resCancelled;
return this.app.models.Subscription.findAll({
where: {
cancelled_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
cancelled: true
},
attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
],
group: ['currency']
})
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
resCancelled = count;
return this.app.models.Analytic.findOne({
where: {
name: `store.${shopId ? shopId + '.' : ''}MMR`,
end: {
$gte: start2.format('YYYY-MM-DD HH:mm:ss')
}
}
});
})
.then(prevMMR => {
prevMMR = prevMMR || {
data: [[0, 0, this.app.config.get('cart.default_currency')]]
};
let data = resCancelled.map((c, index) => {
prevMMR.data[index] = prevMMR.data[index] || [0, 0, c.currency];
const cTotal = resCancelled instanceof this.app.models.Subscription.instance
? resCancelled.get('total') : resCancelled.total;
const total = (cTotal / prevMMR.data[index][0]) * 100;
return [total, c.currency];
});
if (data.length === 0) {
data = [[0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}MMRChurn`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['churn', 'currency'],
data: data
}]);
});
});
});
}
QR(options = {}) {
}
activeCustomers(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
updated_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
total_spent: {
$gte: 1
}
},
};
return this.app.models.Customer.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Customer.sequelize.literal('SUM(total_spent)'), 'total'],
[this.app.models.Customer.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Customer.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Customer.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}activeCustomers`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
newCustomers(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
}
},
};
return this.app.models.Customer.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Customer.sequelize.literal('SUM(total_spent)'), 'total'],
[this.app.models.Customer.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Customer.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Customer.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}newCustomers`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
reactivatedSubscriptions(options = {}) {
const start1 = moment()
.subtract(1, 'months')
.startOf('hour');
const start2 = moment()
.subtract(2, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
renews_on: {
$gte: start1.format('YYYY-MM-DD HH:mm:ss')
},
active: true
},
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Subscription.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Subscription.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}reactivatedSubscriptions`,
start: start1.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
newSubscriptions(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
}
},
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Subscription.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Subscription.instance
? c.get('count') : c.count;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}newSubscriptions`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
activeSubscriptions(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
renews_on: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
active: true
},
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Subscription.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Subscription.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}activeSubscriptions`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
cancelledSubscriptions(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
cancelled_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
cancelled: true
},
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Subscription.count(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Subscription.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}cancelledSubscriptions`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
upgradedSubscriptions(options = {}) {
}
subscriptionDiscountsRedeemed(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
renews_on: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
}
},
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Subscription.count(Object.assign({}, query, { attributes: [
[this.app.models.Subscription.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Subscription.sequelize.literal('SUM(total_discounts)'), 'total_discounts'],
[this.app.models.Subscription.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, total_discounts: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Subscription.instance
? c.get('total_discounts') || 0
: c.total_discounts || 0;
const cCount = c instanceof this.app.models.Subscription.instance
? c.get('count') || 0
: c.count || 0;
const total = parseInt(cTotal, 10);
return [parseInt(cCount, 10), total, c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}subscriptionDiscountsRedeemed`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
discountsRedeemed(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
financial_status: 'paid'
},
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Order.count(Object.assign({}, query, { attributes: [
[this.app.models.Order.sequelize.literal('SUM(total_price)'), 'total'],
[this.app.models.Order.sequelize.literal('SUM(total_discounts)'), 'total_discounts'],
[this.app.models.Order.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, total_discounts: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Order.instance
? c.get('total_discounts') || 0
: c.total_discounts || 0;
const cCount = c instanceof this.app.models.Order.instance
? c.get('count') || 0
: c.count || 0;
const total = parseInt(cTotal, 10);
return [parseInt(cCount, 10), total, c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' : ''}discountsRedeemed`,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
group_label: 'currency',
labels: ['total', 'gross', 'currency'],
data: data
}]);
});
});
});
}
failedCharges(options = {}) {
const start = moment()
.subtract(1, 'months')
.startOf('hour');
const end = moment(Date.now()).startOf('hour');
return this.app.models.Shop.findAll({
attributes: ['id']
})
.then((shops = []) => {
const ids = shops.map(shop => shop.id);
ids.unshift(null);
return this.app.models.Shop.sequelize.Promise.mapSeries(ids, shopId => {
const query = {
where: {
created_at: {
$gte: start.format('YYYY-MM-DD HH:mm:ss')
},
status: 'failure'
}
};
if (shopId) {
query.where.shop_id = shopId;
}
return this.app.models.Transaction.findAll(Object.assign({}, query, { attributes: [
[this.app.models.Transaction.sequelize.literal('SUM(amount)'), 'total'],
[this.app.models.Transaction.sequelize.literal('COUNT(id)'), 'count'],
'currency'
], group: ['currency'] }))
.then((count = []) => {
if (count.length === 0) {
count = [{ total: 0, count: 0, currency: this.app.config.get('cart.default_currency') }];
}
let data = count.map(c => {
const cTotal = c instanceof this.app.models.Transaction.instance
? c.get('total') || 0
: c.total || 0;
const cCount = c instanceof this.app.models.Transaction.instance
? c.get('count') || 0
: c.count || 0;
return [parseInt(cCount, 10), parseInt(cTotal, 10), c.currency];
});
if (data.length === 0) {
data = [[0, 0, this.app.config.get('cart.default_currency')]];
}
return this.publish([{
name: `store.${shopId ? shopId + '.' :