UNPKG

@fabrix/spool-cart

Version:

Spool - eCommerce Spool for Fabrix

1,057 lines 58.6 kB
"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 + '.' :