From b985fb850924dc0ccd9141f340f64afb6fab9a6c Mon Sep 17 00:00:00 2001 From: zhuotianyuan Date: Mon, 22 Dec 2025 11:17:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=97=B6=E6=9C=AA=E9=99=90=E5=88=B6=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=8C=83=E5=9B=B4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dto/statistics.dto.ts | 4 + src/enums/base.enum.ts | 1 + src/service/order.service.ts | 11 +- src/service/statistics.service.ts | 395 +++++++++++++++++++++++++++++- 4 files changed, 406 insertions(+), 5 deletions(-) diff --git a/src/dto/statistics.dto.ts b/src/dto/statistics.dto.ts index 31e10a8..b6cf9dc 100644 --- a/src/dto/statistics.dto.ts +++ b/src/dto/statistics.dto.ts @@ -33,4 +33,8 @@ export class OrderStatisticsParams { @ApiProperty({ enum: ['all', 'zyn', 'yoone', 'zolt'], default: 'all' }) @Rule(RuleType.string().valid('all', 'zyn', 'yoone', 'zolt')) brand: string; + + @ApiProperty({ enum: ['day', 'week', 'month'], default: 'day' }) + @Rule(RuleType.string().valid('day', 'week', 'month')) + grouping: string; } diff --git a/src/enums/base.enum.ts b/src/enums/base.enum.ts index 0dbe924..085a582 100644 --- a/src/enums/base.enum.ts +++ b/src/enums/base.enum.ts @@ -42,6 +42,7 @@ export enum OrderStatus { REFUNDED = 'refunded', // 已退款 FAILED = 'failed', // 失败订单 DRAFT = 'draft', // 草稿 + AUTO_DRAFT = 'auto-draft', // 自动草稿 // TRASH = 'trash', // refund 也就是退款相关的状态 RETURN_REQUESTED = 'return-requested', // 已申请退款 diff --git a/src/service/order.service.ts b/src/service/order.service.ts index ed6fd02..1d03d70 100644 --- a/src/service/order.service.ts +++ b/src/service/order.service.ts @@ -162,18 +162,25 @@ export class OrderService { ...orderData } = order; console.log('同步进单个订单', order) + if (order.status === OrderStatus.AUTO_DRAFT) { + return; + } const existingOrder = await this.orderModel.findOne({ where: { externalOrderId: order.id, siteId: siteId }, }); + // 更新状态 await this.autoUpdateOrderStatus(siteId, order); - const externalOrderId = order.id; + if (existingOrder) { + await this.orderModel.update({ id: existingOrder.id }, { orderStatus: this.mapOrderStatus(order.status) }); + } + const externalOrderId = order.id; if ( existingOrder && existingOrder.orderStatus !== ErpOrderStatus.COMPLETED && orderData.status === OrderStatus.COMPLETED ) { - this.updateStock(existingOrder); + this.updateStock(existingOrder); return; } if (existingOrder && !existingOrder.is_editable && !forceUpdate) { diff --git a/src/service/statistics.service.ts b/src/service/statistics.service.ts index b7ce60d..949c040 100644 --- a/src/service/statistics.service.ts +++ b/src/service/statistics.service.ts @@ -15,12 +15,14 @@ export class StatisticsService { orderItemRepository: Repository; async getOrderStatistics(params: OrderStatisticsParams) { - const { startDate, endDate, siteId } = params; + const { startDate, endDate, siteId ,grouping} = params; // const keywords = keyword ? keyword.split(' ').filter(Boolean) : []; const start = dayjs(startDate).format('YYYY-MM-DD'); const end = dayjs(endDate).add(1, 'd').format('YYYY-MM-DD'); - let sql = ` - WITH first_order AS ( + + let sql = ''; + if (!grouping || grouping === 'day') { + sql = `WITH first_order AS ( SELECT customer_email, MIN(date_paid) AS first_purchase_date FROM \`order\` GROUP BY customer_email @@ -214,6 +216,393 @@ export class StatisticsService { dt.can_total_orders ORDER BY d.order_date DESC; `; + }else if (grouping === 'week') { + sql = `WITH first_order AS ( + SELECT customer_email, MIN(date_paid) AS first_purchase_date + FROM \`order\` + GROUP BY customer_email + ), + weekly_orders AS ( + SELECT + o.id AS order_id, + DATE_FORMAT(o.date_paid, '%Y-%u') AS order_date, + o.customer_email, + o.total, + o.source_type, + o.utm_source, + o.siteId, + CASE + WHEN o.date_paid = f.first_purchase_date THEN 'first_purchase' + ELSE 'repeat_purchase' + END AS purchase_type, + CASE + WHEN o.source_type = 'utm' AND o.utm_source = 'google' THEN 'cpc' + ELSE 'non_cpc' + END AS order_type, + MAX(CASE WHEN oi.name LIKE '%zyn%' THEN 'zyn' ELSE 'non_zyn' END) AS zyn_type, + MAX(CASE WHEN oi.name LIKE '%yoone%' THEN 'yoone' ELSE 'non_yoone' END) AS yoone_type, + MAX(CASE WHEN oi.name LIKE '%zex%' THEN 'zex' ELSE 'non_zex' END) AS zex_type + FROM \`order\` o + LEFT JOIN first_order f ON o.customer_email = f.customer_email + LEFT JOIN order_item oi ON o.id = oi.orderId + WHERE o.date_paid IS NOT NULL + AND o.date_paid >= '${start}' AND o.date_paid < '${end}' + AND o.status IN ('processing','completed') + GROUP BY o.id, o.date_paid, o.customer_email, o.total, o.source_type, o.siteId, o.utm_source + ), + order_sales_summary AS ( + SELECT + orderId, + SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity, + SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity, + SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity + FROM order_sale + GROUP BY orderId + ), + order_items_summary AS ( + SELECT + orderId, + SUM(CASE WHEN name LIKE '%zyn%' THEN total + total_tax ELSE 0 END) AS zyn_amount, + SUM(CASE WHEN name LIKE '%yoone%' THEN total + total_tax ELSE 0 END) AS yoone_amount, + SUM(CASE WHEN name LIKE '%zex%' THEN total + total_tax ELSE 0 END) AS zex_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_G_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name NOT LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_S_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN total + total_tax ELSE 0 END) AS yoone_3_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN total + total_tax ELSE 0 END) AS yoone_6_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN total + total_tax ELSE 0 END) AS yoone_9_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN total + total_tax ELSE 0 END) AS yoone_12_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN total + total_tax ELSE 0 END) AS yoone_15_amount + FROM order_item + GROUP BY orderId + ), + weekly_totals AS ( + SELECT order_date, SUM(total) AS total_amount, + SUM(CASE WHEN siteId = 1 THEN total ELSE 0 END) AS togo_total_amount, + SUM(CASE WHEN siteId = 2 THEN total ELSE 0 END) AS can_total_amount, + COUNT(DISTINCT order_id) AS total_orders, + COUNT(DISTINCT CASE WHEN siteId = 1 THEN order_id END) AS togo_total_orders, + COUNT(DISTINCT CASE WHEN siteId = 2 THEN order_id END) AS can_total_orders, + SUM(CASE WHEN purchase_type = 'first_purchase' THEN total ELSE 0 END) AS first_purchase_total, + SUM(CASE WHEN purchase_type = 'repeat_purchase' THEN total ELSE 0 END) AS repeat_purchase_total, + SUM(CASE WHEN order_type = 'cpc' THEN total ELSE 0 END) AS cpc_total, + SUM(CASE WHEN order_type = 'non_cpc' THEN total ELSE 0 END) AS non_cpc_total, + SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'cpc' THEN total ELSE 0 END) AS zyn_total, + SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zyn_total, + SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'cpc' THEN total ELSE 0 END) AS yoone_total, + SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_yoone_total, + SUM(CASE WHEN zex_type = 'zex' AND order_type = 'cpc' THEN total ELSE 0 END) AS zex_total, + SUM(CASE WHEN zex_type = 'zex' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zex_total, + SUM(CASE WHEN source_type = 'typein' THEN total ELSE 0 END) AS direct_total, + SUM(CASE WHEN source_type = 'organic' THEN total ELSE 0 END) AS organic_total + FROM weekly_orders + GROUP BY order_date + ) + SELECT + wt.order_date, + COUNT(DISTINCT CASE WHEN wo.purchase_type = 'first_purchase' THEN wo.order_id END) AS first_purchase_orders, + COUNT(DISTINCT CASE WHEN wo.purchase_type = 'repeat_purchase' THEN wo.order_id END) AS repeat_purchase_orders, + COUNT(DISTINCT CASE WHEN wo.order_type = 'cpc' THEN wo.order_id END) AS cpc_orders, + COUNT(DISTINCT CASE WHEN wo.order_type = 'cpc' AND wo.siteId = 1 THEN wo.order_id END) AS togo_cpc_orders, + COUNT(DISTINCT CASE WHEN wo.order_type = 'cpc' AND wo.siteId = 2 THEN wo.order_id END) AS can_cpc_orders, + COUNT(DISTINCT CASE WHEN wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_cpc_orders, + COUNT(DISTINCT CASE WHEN wo.order_type = 'non_cpc' AND wo.siteId = 1 THEN wo.order_id END) AS non_togo_cpc_orders, + COUNT(DISTINCT CASE WHEN wo.order_type = 'non_cpc' AND wo.siteId = 2 THEN wo.order_id END) AS non_can_cpc_orders, + COUNT(DISTINCT CASE WHEN wo.zyn_type = 'zyn' AND wo.order_type = 'cpc' THEN wo.order_id END) AS zyn_orders, + COUNT(DISTINCT CASE WHEN wo.zyn_type = 'zyn' AND wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_zyn_orders, + COUNT(DISTINCT CASE WHEN wo.yoone_type = 'yoone' AND wo.order_type = 'cpc' THEN wo.order_id END) AS yoone_orders, + COUNT(DISTINCT CASE WHEN wo.yoone_type = 'yoone' AND wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_yoone_orders, + COUNT(DISTINCT CASE WHEN wo.zex_type = 'zex' AND wo.order_type = 'cpc' THEN wo.order_id END) AS zex_orders, + COUNT(DISTINCT CASE WHEN wo.zex_type = 'zex' AND wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_zex_orders, + COUNT(DISTINCT CASE WHEN wo.source_type = 'typein' THEN wo.order_id END) AS direct_orders, + COUNT(DISTINCT CASE WHEN wo.source_type = 'organic' THEN wo.order_id END) AS organic_orders, + wt.total_orders, + wt.togo_total_orders, + wt.can_total_orders, + wt.total_amount, + wt.togo_total_amount, + wt.can_total_amount, + wt.first_purchase_total, + wt.repeat_purchase_total, + wt.cpc_total, + wt.non_cpc_total, + wt.zyn_total, + wt.non_zyn_total, + wt.yoone_total, + wt.non_yoone_total, + wt.zex_total, + wt.non_zex_total, + wt.direct_total, + wt.organic_total, + COALESCE(SUM(os.zyn_quantity), 0) AS zyn_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.zyn_quantity ELSE 0 END) AS cpc_zyn_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.zyn_quantity ELSE 0 END) AS non_cpc_zyn_quantity, + COALESCE(SUM(os.yoone_quantity), 0) AS yoone_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_quantity ELSE 0 END) AS cpc_yoone_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_quantity ELSE 0 END) AS non_cpc_yoone_quantity, + COALESCE(SUM(os.yoone_G_quantity), 0) AS yoone_G_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_G_quantity ELSE 0 END) AS cpc_yoone_G_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_G_quantity ELSE 0 END) AS non_cpc_yoone_G_quantity, + COALESCE(SUM(os.yoone_S_quantity), 0) AS yoone_S_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_S_quantity ELSE 0 END) AS cpc_yoone_S_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_S_quantity ELSE 0 END) AS non_cpc_yoone_S_quantity, + COALESCE(SUM(os.yoone_3_quantity), 0) AS yoone_3_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_3_quantity ELSE 0 END) AS cpc_yoone_3_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_3_quantity ELSE 0 END) AS non_cpc_yoone_3_quantity, + COALESCE(SUM(os.yoone_6_quantity), 0) AS yoone_6_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_6_quantity ELSE 0 END) AS cpc_yoone_6_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_6_quantity ELSE 0 END) AS non_cpc_yoone_6_quantity, + COALESCE(SUM(os.yoone_9_quantity), 0) AS yoone_9_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_9_quantity ELSE 0 END) AS cpc_yoone_9_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_9_quantity ELSE 0 END) AS non_cpc_yoone_9_quantity, + COALESCE(SUM(os.yoone_12_quantity), 0) AS yoone_12_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_12_quantity ELSE 0 END) AS cpc_yoone_12_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_12_quantity ELSE 0 END) AS non_cpc_yoone_12_quantity, + COALESCE(SUM(os.yoone_15_quantity), 0) AS yoone_15_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_15_quantity ELSE 0 END) AS cpc_yoone_15_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_15_quantity ELSE 0 END) AS non_cpc_yoone_15_quantity, + COALESCE(SUM(os.zex_quantity), 0) AS zex_quantity, + SUM(CASE WHEN wo.order_type = 'cpc' THEN os.zex_quantity ELSE 0 END) AS cpc_zex_quantity, + SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.zex_quantity ELSE 0 END) AS non_cpc_zex_quantity, + COALESCE(SUM(oi.zyn_amount), 0) AS zyn_amount, + COALESCE(SUM(oi.yoone_amount), 0) AS yoone_amount, + COALESCE(SUM(oi.zex_amount), 0) AS zex_amount, + COALESCE(SUM(oi.yoone_G_amount), 0) AS yoone_G_amount, + COALESCE(SUM(oi.yoone_S_amount), 0) AS yoone_S_amount, + COALESCE(SUM(oi.yoone_3_amount), 0) AS yoone_3_amount, + COALESCE(SUM(oi.yoone_6_amount), 0) AS yoone_6_amount, + COALESCE(SUM(oi.yoone_9_amount), 0) AS yoone_9_amount, + COALESCE(SUM(oi.yoone_12_amount), 0) AS yoone_12_amount, + COALESCE(SUM(oi.yoone_15_amount), 0) AS yoone_15_amount, + ROUND(COALESCE(wt.total_amount / wt.total_orders, 0), 2) AS avg_total_amount, + ROUND(COALESCE(wt.togo_total_amount / wt.togo_total_orders, 0), 2) AS avg_togo_total_amount, + ROUND(COALESCE(wt.can_total_amount / wt.can_total_orders, 0), 2) AS avg_can_total_amount + FROM weekly_orders wo + LEFT JOIN weekly_totals wt ON wo.order_date = wt.order_date + LEFT JOIN order_sales_summary os ON wo.order_id = os.orderId + LEFT JOIN order_items_summary oi ON wo.order_id = oi.orderId + GROUP BY + wt.order_date, + wt.total_amount, + wt.togo_total_amount, + wt.can_total_amount, + wt.first_purchase_total, + wt.repeat_purchase_total, + wt.cpc_total, + wt.non_cpc_total, + wt.zyn_total, + wt.non_zyn_total, + wt.yoone_total, + wt.non_yoone_total, + wt.zex_total, + wt.non_zex_total, + wt.direct_total, + wt.organic_total, + wt.total_orders, + wt.togo_total_orders, + wt.can_total_orders + ORDER BY wt.order_date DESC; + `; + }else if (grouping === 'month') { + sql = `WITH first_order AS ( + SELECT customer_email, MIN(date_paid) AS first_purchase_date + FROM \`order\` + GROUP BY customer_email + ), + monthly_orders AS ( + SELECT + o.id AS order_id, + DATE_FORMAT(o.date_paid, '%Y-%m') AS order_date, + o.customer_email, + o.total, + o.source_type, + o.utm_source, + o.siteId, + CASE + WHEN o.date_paid = f.first_purchase_date THEN 'first_purchase' + ELSE 'repeat_purchase' + END AS purchase_type, + CASE + WHEN o.source_type = 'utm' AND o.utm_source = 'google' THEN 'cpc' + ELSE 'non_cpc' + END AS order_type, + MAX(CASE WHEN oi.name LIKE '%zyn%' THEN 'zyn' ELSE 'non_zyn' END) AS zyn_type, + MAX(CASE WHEN oi.name LIKE '%yoone%' THEN 'yoone' ELSE 'non_yoone' END) AS yoone_type, + MAX(CASE WHEN oi.name LIKE '%zex%' THEN 'zex' ELSE 'non_zex' END) AS zex_type + FROM \`order\` o + LEFT JOIN first_order f ON o.customer_email = f.customer_email + LEFT JOIN order_item oi ON o.id = oi.orderId + WHERE o.date_paid IS NOT NULL + AND o.date_paid >= '${start}' AND o.date_paid < '${end}' + AND o.status IN ('processing','completed') + GROUP BY o.id, o.date_paid, o.customer_email, o.total, o.source_type, o.siteId, o.utm_source + ), + order_sales_summary AS ( + SELECT + orderId, + SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity, + SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity, + SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity + FROM order_sale + GROUP BY orderId + ), + order_items_summary AS ( + SELECT + orderId, + SUM(CASE WHEN name LIKE '%zyn%' THEN total + total_tax ELSE 0 END) AS zyn_amount, + SUM(CASE WHEN name LIKE '%yoone%' THEN total + total_tax ELSE 0 END) AS yoone_amount, + SUM(CASE WHEN name LIKE '%zex%' THEN total + total_tax ELSE 0 END) AS zex_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_G_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name NOT LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_S_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN total + total_tax ELSE 0 END) AS yoone_3_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN total + total_tax ELSE 0 END) AS yoone_6_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN total + total_tax ELSE 0 END) AS yoone_9_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN total + total_tax ELSE 0 END) AS yoone_12_amount, + SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN total + total_tax ELSE 0 END) AS yoone_15_amount + FROM order_item + GROUP BY orderId + ), + monthly_totals AS ( + SELECT order_date, SUM(total) AS total_amount, + SUM(CASE WHEN siteId = 1 THEN total ELSE 0 END) AS togo_total_amount, + SUM(CASE WHEN siteId = 2 THEN total ELSE 0 END) AS can_total_amount, + COUNT(DISTINCT order_id) AS total_orders, + COUNT(DISTINCT CASE WHEN siteId = 1 THEN order_id END) AS togo_total_orders, + COUNT(DISTINCT CASE WHEN siteId = 2 THEN order_id END) AS can_total_orders, + SUM(CASE WHEN purchase_type = 'first_purchase' THEN total ELSE 0 END) AS first_purchase_total, + SUM(CASE WHEN purchase_type = 'repeat_purchase' THEN total ELSE 0 END) AS repeat_purchase_total, + SUM(CASE WHEN order_type = 'cpc' THEN total ELSE 0 END) AS cpc_total, + SUM(CASE WHEN order_type = 'non_cpc' THEN total ELSE 0 END) AS non_cpc_total, + SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'cpc' THEN total ELSE 0 END) AS zyn_total, + SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zyn_total, + SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'cpc' THEN total ELSE 0 END) AS yoone_total, + SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_yoone_total, + SUM(CASE WHEN zex_type = 'zex' AND order_type = 'cpc' THEN total ELSE 0 END) AS zex_total, + SUM(CASE WHEN zex_type = 'zex' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zex_total, + SUM(CASE WHEN source_type = 'typein' THEN total ELSE 0 END) AS direct_total, + SUM(CASE WHEN source_type = 'organic' THEN total ELSE 0 END) AS organic_total + FROM monthly_orders + GROUP BY order_date + ) + SELECT + mt.order_date, + COUNT(DISTINCT CASE WHEN mo.purchase_type = 'first_purchase' THEN mo.order_id END) AS first_purchase_orders, + COUNT(DISTINCT CASE WHEN mo.purchase_type = 'repeat_purchase' THEN mo.order_id END) AS repeat_purchase_orders, + COUNT(DISTINCT CASE WHEN mo.order_type = 'cpc' THEN mo.order_id END) AS cpc_orders, + COUNT(DISTINCT CASE WHEN mo.order_type = 'cpc' AND mo.siteId = 1 THEN mo.order_id END) AS togo_cpc_orders, + COUNT(DISTINCT CASE WHEN mo.order_type = 'cpc' AND mo.siteId = 2 THEN mo.order_id END) AS can_cpc_orders, + COUNT(DISTINCT CASE WHEN mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_cpc_orders, + COUNT(DISTINCT CASE WHEN mo.order_type = 'non_cpc' AND mo.siteId = 1 THEN mo.order_id END) AS non_togo_cpc_orders, + COUNT(DISTINCT CASE WHEN mo.order_type = 'non_cpc' AND mo.siteId = 2 THEN mo.order_id END) AS non_can_cpc_orders, + COUNT(DISTINCT CASE WHEN mo.zyn_type = 'zyn' AND mo.order_type = 'cpc' THEN mo.order_id END) AS zyn_orders, + COUNT(DISTINCT CASE WHEN mo.zyn_type = 'zyn' AND mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_zyn_orders, + COUNT(DISTINCT CASE WHEN mo.yoone_type = 'yoone' AND mo.order_type = 'cpc' THEN mo.order_id END) AS yoone_orders, + COUNT(DISTINCT CASE WHEN mo.yoone_type = 'yoone' AND mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_yoone_orders, + COUNT(DISTINCT CASE WHEN mo.zex_type = 'zex' AND mo.order_type = 'cpc' THEN mo.order_id END) AS zex_orders, + COUNT(DISTINCT CASE WHEN mo.zex_type = 'zex' AND mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_zex_orders, + COUNT(DISTINCT CASE WHEN mo.source_type = 'typein' THEN mo.order_id END) AS direct_orders, + COUNT(DISTINCT CASE WHEN mo.source_type = 'organic' THEN mo.order_id END) AS organic_orders, + mt.total_orders, + mt.togo_total_orders, + mt.can_total_orders, + mt.total_amount, + mt.togo_total_amount, + mt.can_total_amount, + mt.first_purchase_total, + mt.repeat_purchase_total, + mt.cpc_total, + mt.non_cpc_total, + mt.zyn_total, + mt.non_zyn_total, + mt.yoone_total, + mt.non_yoone_total, + mt.zex_total, + mt.non_zex_total, + mt.direct_total, + mt.organic_total, + COALESCE(SUM(os.zyn_quantity), 0) AS zyn_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.zyn_quantity ELSE 0 END) AS cpc_zyn_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.zyn_quantity ELSE 0 END) AS non_cpc_zyn_quantity, + COALESCE(SUM(os.yoone_quantity), 0) AS yoone_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_quantity ELSE 0 END) AS cpc_yoone_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_quantity ELSE 0 END) AS non_cpc_yoone_quantity, + COALESCE(SUM(os.yoone_G_quantity), 0) AS yoone_G_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_G_quantity ELSE 0 END) AS cpc_yoone_G_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_G_quantity ELSE 0 END) AS non_cpc_yoone_G_quantity, + COALESCE(SUM(os.yoone_S_quantity), 0) AS yoone_S_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_S_quantity ELSE 0 END) AS cpc_yoone_S_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_S_quantity ELSE 0 END) AS non_cpc_yoone_S_quantity, + COALESCE(SUM(os.yoone_3_quantity), 0) AS yoone_3_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_3_quantity ELSE 0 END) AS cpc_yoone_3_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_3_quantity ELSE 0 END) AS non_cpc_yoone_3_quantity, + COALESCE(SUM(os.yoone_6_quantity), 0) AS yoone_6_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_6_quantity ELSE 0 END) AS cpc_yoone_6_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_6_quantity ELSE 0 END) AS non_cpc_yoone_6_quantity, + COALESCE(SUM(os.yoone_9_quantity), 0) AS yoone_9_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_9_quantity ELSE 0 END) AS cpc_yoone_9_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_9_quantity ELSE 0 END) AS non_cpc_yoone_9_quantity, + COALESCE(SUM(os.yoone_12_quantity), 0) AS yoone_12_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_12_quantity ELSE 0 END) AS cpc_yoone_12_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_12_quantity ELSE 0 END) AS non_cpc_yoone_12_quantity, + COALESCE(SUM(os.yoone_15_quantity), 0) AS yoone_15_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_15_quantity ELSE 0 END) AS cpc_yoone_15_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_15_quantity ELSE 0 END) AS non_cpc_yoone_15_quantity, + COALESCE(SUM(os.zex_quantity), 0) AS zex_quantity, + SUM(CASE WHEN mo.order_type = 'cpc' THEN os.zex_quantity ELSE 0 END) AS cpc_zex_quantity, + SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.zex_quantity ELSE 0 END) AS non_cpc_zex_quantity, + COALESCE(SUM(oi.zyn_amount), 0) AS zyn_amount, + COALESCE(SUM(oi.yoone_amount), 0) AS yoone_amount, + COALESCE(SUM(oi.zex_amount), 0) AS zex_amount, + COALESCE(SUM(oi.yoone_G_amount), 0) AS yoone_G_amount, + COALESCE(SUM(oi.yoone_S_amount), 0) AS yoone_S_amount, + COALESCE(SUM(oi.yoone_3_amount), 0) AS yoone_3_amount, + COALESCE(SUM(oi.yoone_6_amount), 0) AS yoone_6_amount, + COALESCE(SUM(oi.yoone_9_amount), 0) AS yoone_9_amount, + COALESCE(SUM(oi.yoone_12_amount), 0) AS yoone_12_amount, + COALESCE(SUM(oi.yoone_15_amount), 0) AS yoone_15_amount, + ROUND(COALESCE(mt.total_amount / mt.total_orders, 0), 2) AS avg_total_amount, + ROUND(COALESCE(mt.togo_total_amount / mt.togo_total_orders, 0), 2) AS avg_togo_total_amount, + ROUND(COALESCE(mt.can_total_amount / mt.can_total_orders, 0), 2) AS avg_can_total_amount + FROM monthly_orders mo + LEFT JOIN monthly_totals mt ON mo.order_date = mt.order_date + LEFT JOIN order_sales_summary os ON mo.order_id = os.orderId + LEFT JOIN order_items_summary oi ON mo.order_id = oi.orderId + GROUP BY + mt.order_date, + mt.total_amount, + mt.togo_total_amount, + mt.can_total_amount, + mt.first_purchase_total, + mt.repeat_purchase_total, + mt.cpc_total, + mt.non_cpc_total, + mt.zyn_total, + mt.non_zyn_total, + mt.yoone_total, + mt.non_yoone_total, + mt.zex_total, + mt.non_zex_total, + mt.direct_total, + mt.organic_total, + mt.total_orders, + mt.togo_total_orders, + mt.can_total_orders + ORDER BY mt.order_date DESC; + `;} + return this.orderRepository.query(sql); } // async getOrderStatistics(params: OrderStatisticsParams) {