UNPKG

@rsc-labs/medusa-store-analytics

Version:
313 lines (312 loc) 13.8 kB
"use strict"; /* * Copyright 2024 RSC-Labs, https://rsoftcon.com/ * * MIT License * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); const medusa_1 = require("@medusajs/medusa"); const medusa_2 = require("@medusajs/medusa"); const dateTransformations_1 = require("./utils/dateTransformations"); const typeorm_1 = require("typeorm"); class OrdersAnalyticsService extends medusa_1.TransactionBaseService { constructor(container) { super(container); this.orderService = container.orderService; } async getOrdersHistory(orderStatuses, from, to, dateRangeFromCompareTo, dateRangeToCompareTo) { const orderStatusesAsStrings = Object.values(orderStatuses); if (orderStatusesAsStrings.length) { if (dateRangeFromCompareTo && from && to && dateRangeToCompareTo) { const resolution = (0, dateTransformations_1.calculateResolution)(from); const query = this.activeManager_.getRepository(medusa_2.Order) .createQueryBuilder('order') .select(` CASE WHEN order.created_at < :from AND order.created_at >= :dateRangeFromCompareTo THEN 'previous' ELSE 'current' END AS type, date_trunc('${resolution}', order.created_at) AS date `) .setParameters({ from, dateRangeFromCompareTo }) .addSelect('COUNT(order.id)', 'orderCount') .where(`created_at >= :dateRangeFromCompareTo`, { dateRangeFromCompareTo }) .andWhere(`status IN(:...orderStatusesAsStrings)`, { orderStatusesAsStrings }); const orders = await query .groupBy('type, date') .orderBy('date, type', 'ASC') .getRawMany(); const finalOrders = orders.reduce((acc, entry) => { const type = entry.type; const date = entry.date; const orderCount = entry.orderCount; if (!acc[type]) { acc[type] = []; } acc[type].push({ date, orderCount }); return acc; }, {}); return { dateRangeFrom: from.getTime(), dateRangeTo: to.getTime(), dateRangeFromCompareTo: dateRangeFromCompareTo.getTime(), dateRangeToCompareTo: dateRangeToCompareTo.getTime(), current: finalOrders.current ? finalOrders.current : [], previous: finalOrders.previous ? finalOrders.previous : [], }; } let startQueryFrom; if (!dateRangeFromCompareTo) { if (from) { startQueryFrom = from; } else { // All time const lastOrder = await this.activeManager_.getRepository(medusa_2.Order).find({ skip: 0, take: 1, order: { created_at: "ASC" }, where: { status: (0, typeorm_1.In)(orderStatusesAsStrings) } }); if (lastOrder.length > 0) { startQueryFrom = lastOrder[0].created_at; } } } else { startQueryFrom = dateRangeFromCompareTo; } if (startQueryFrom) { const resolution = (0, dateTransformations_1.calculateResolution)(startQueryFrom); const query = this.activeManager_.getRepository(medusa_2.Order) .createQueryBuilder('order') .select(`date_trunc('${resolution}', order.created_at)`, 'date') .addSelect('COUNT(order.id)', 'orderCount') .where(`created_at >= :startQueryFrom`, { startQueryFrom }) .andWhere(`status IN(:...orderStatusesAsStrings)`, { orderStatusesAsStrings }); const orders = await query .groupBy('date') .orderBy('date', 'ASC') .getRawMany(); return { dateRangeFrom: startQueryFrom.getTime(), dateRangeTo: to ? to.getTime() : new Date(Date.now()).getTime(), dateRangeFromCompareTo: undefined, dateRangeToCompareTo: undefined, current: orders, previous: [] }; } } return { dateRangeFrom: undefined, dateRangeTo: undefined, dateRangeFromCompareTo: undefined, dateRangeToCompareTo: undefined, current: [], previous: [] }; } async getOrdersCount(orderStatuses, from, to, dateRangeFromCompareTo, dateRangeToCompareTo) { let startQueryFrom; const orderStatusesAsStrings = Object.values(orderStatuses); if (orderStatusesAsStrings.length) { if (!dateRangeFromCompareTo) { if (from) { startQueryFrom = from; } else { // All time const lastOrder = await this.activeManager_.getRepository(medusa_2.Order).find({ skip: 0, take: 1, order: { created_at: "ASC" }, where: { status: (0, typeorm_1.In)(orderStatusesAsStrings) } }); if (lastOrder.length > 0) { startQueryFrom = lastOrder[0].created_at; } } } else { startQueryFrom = dateRangeFromCompareTo; } const orders = await this.orderService.listAndCount({ created_at: startQueryFrom ? { gte: startQueryFrom } : undefined, status: (0, typeorm_1.In)(orderStatusesAsStrings) }, { select: [ "id", "created_at", "updated_at" ], order: { created_at: "DESC" }, }); if (dateRangeFromCompareTo && from && to && dateRangeToCompareTo) { const previousOrders = orders[0].filter(order => order.created_at < from); const currentOrders = orders[0].filter(order => order.created_at >= from); return { dateRangeFrom: from.getTime(), dateRangeTo: to.getTime(), dateRangeFromCompareTo: dateRangeFromCompareTo.getTime(), dateRangeToCompareTo: dateRangeToCompareTo.getTime(), current: currentOrders.length, previous: previousOrders.length }; } if (startQueryFrom) { return { dateRangeFrom: startQueryFrom.getTime(), dateRangeTo: to ? to.getTime() : new Date(Date.now()).getTime(), dateRangeFromCompareTo: undefined, dateRangeToCompareTo: undefined, current: orders[1], previous: 0 }; } } return { dateRangeFrom: undefined, dateRangeTo: undefined, dateRangeFromCompareTo: undefined, dateRangeToCompareTo: undefined, current: 0, previous: 0 }; } async getPaymentProviderPopularity(from, to, dateRangeFromCompareTo, dateRangeToCompareTo) { function calculateSumAndPercentageOfResults(results) { const orderMap = new Map(); let allSum = 0; results.forEach(result => { const { orderCount, paymentProviderId } = result; if (orderMap.has(paymentProviderId)) { const sum = parseInt(orderMap.get(paymentProviderId)) + parseInt(orderCount); orderMap.set(paymentProviderId, sum.toFixed()); } else { orderMap.set(paymentProviderId, orderCount); } }); const newArray = []; orderMap.forEach((value) => { allSum += parseInt(value); }); orderMap.forEach((value, key) => { newArray.push({ orderCount: value, percentage: (parseInt(value) * 100 / allSum).toFixed(2), paymentProviderId: key }); }); return newArray; } if (dateRangeFromCompareTo && from && to && dateRangeToCompareTo) { const resolution = (0, dateTransformations_1.calculateResolution)(from); const query = this.activeManager_ .getRepository(medusa_2.Order) .createQueryBuilder('order') .select(` CASE WHEN order.created_at < :from AND order.created_at >= :dateRangeFromCompareTo THEN 'previous' ELSE 'current' END AS type`) .addSelect(`date_trunc('${resolution}', order.created_at)`, 'date') .addSelect('COUNT(order.id)', 'orderCount') .leftJoinAndSelect('order.payments', 'payments') .where('order.created_at >= :dateRangeFromCompareTo', { dateRangeFromCompareTo }); const ordersCountWithPayments = await query .groupBy('date, type, payments.id') .orderBy('date', 'ASC') .setParameters({ from, dateRangeFromCompareTo }) .getRawMany(); const finalOrders = ordersCountWithPayments.reduce((acc, entry) => { const type = entry.type; const orderCount = entry.orderCount; const paymentProviderId = entry.payments_provider_id; if (!acc[type]) { acc[type] = []; } acc[type].push({ orderCount, paymentProviderId, }); return acc; }, {}); const finalOrdersCurrentGrouped = calculateSumAndPercentageOfResults(finalOrders.current ? finalOrders.current : []); const finalOrdersPreviousGrouped = calculateSumAndPercentageOfResults(finalOrders.previous ? finalOrders.previous : []); return { dateRangeFrom: from.getTime(), dateRangeTo: to.getTime(), dateRangeFromCompareTo: dateRangeFromCompareTo.getTime(), dateRangeToCompareTo: dateRangeToCompareTo.getTime(), current: finalOrdersCurrentGrouped ? finalOrdersCurrentGrouped : [], previous: finalOrdersPreviousGrouped ? finalOrdersPreviousGrouped : [], }; } let startQueryFrom; if (!dateRangeFromCompareTo) { if (from) { startQueryFrom = from; } else { // All time const lastOrder = await this.activeManager_.getRepository(medusa_2.Order).find({ skip: 0, take: 1, order: { created_at: "ASC" }, }); if (lastOrder.length > 0) { startQueryFrom = lastOrder[0].created_at; } } } else { startQueryFrom = dateRangeFromCompareTo; } if (startQueryFrom) { const resolution = (0, dateTransformations_1.calculateResolution)(startQueryFrom); const query = this.activeManager_ .getRepository(medusa_2.Order) .createQueryBuilder('order') .select(`date_trunc('${resolution}', order.created_at)`, 'date') .addSelect('COUNT(order.id)', 'orderCount') .leftJoinAndSelect('order.payments', 'payments') .where('order.created_at >= :startQueryFrom', { startQueryFrom }); const ordersCountWithPayments = await query .groupBy('date, payments.id') .orderBy('date', 'ASC') .getRawMany(); const initialOrders = ordersCountWithPayments.map(order => { return { orderCount: order.orderCount, paymentProviderId: order.payments_provider_id, }; }); const finalOrdersGrouped = calculateSumAndPercentageOfResults(initialOrders ? initialOrders : []); return { dateRangeFrom: startQueryFrom.getTime(), dateRangeTo: to ? to.getTime() : new Date(Date.now()).getTime(), dateRangeFromCompareTo: undefined, dateRangeToCompareTo: undefined, current: finalOrdersGrouped, previous: [] }; } return { dateRangeFrom: undefined, dateRangeTo: undefined, dateRangeFromCompareTo: undefined, dateRangeToCompareTo: undefined, current: [], previous: [] }; } } exports.default = OrdersAnalyticsService;