62 lines
2.5 KiB
JavaScript
62 lines
2.5 KiB
JavaScript
/**
|
||
* @file smsProblemSummary.js
|
||
* @description Складывает неудачные отправки SMS в одну понятную причину.
|
||
*
|
||
* В таблице видно только «SMS не отправлено», а причина в логе — код сервиса.
|
||
* Здесь считаем: сколько сообщений, сколько заказов, за какой период и что
|
||
* именно случилось чаще всего (например, что на счёте закончились средства).
|
||
*/
|
||
import { getSmsFailureReason } from "./orderGroupViews";
|
||
|
||
/**
|
||
* @param {Array} rows строки sms_campaign_log со статусами ошибок
|
||
* @param {Array<string>} visibleIds id заказов, которые сейчас видны в таблице
|
||
* @returns {null|{reason, messages, groups, affectedInTable, hasFundsReason, firstAt, lastAt}}
|
||
*/
|
||
export const summarizeSmsFailures = (rows = [], visibleIds = []) => {
|
||
const list = Array.isArray(rows) ? rows.filter(Boolean) : [];
|
||
if (!list.length) return null;
|
||
|
||
const reasons = new Map();
|
||
const lastByGroup = new Map();
|
||
let firstAt = null;
|
||
let lastAt = null;
|
||
|
||
for (const row of list) {
|
||
const reason = getSmsFailureReason(row) || "причина не указана";
|
||
reasons.set(reason, (reasons.get(reason) || 0) + 1);
|
||
|
||
if (row.order_group_id && !lastByGroup.has(row.order_group_id)) {
|
||
lastByGroup.set(row.order_group_id, row);
|
||
}
|
||
if (row.created_at) {
|
||
if (!firstAt || row.created_at < firstAt) firstAt = row.created_at;
|
||
if (!lastAt || row.created_at > lastAt) lastAt = row.created_at;
|
||
}
|
||
}
|
||
|
||
const [reason, topMessages] = [...reasons.entries()].sort((a, b) => b[1] - a[1])[0];
|
||
const visible = new Set(visibleIds);
|
||
|
||
return {
|
||
reason,
|
||
messages: list.length,
|
||
topMessages,
|
||
groups: lastByGroup.size,
|
||
affectedInTable: [...lastByGroup.keys()].filter((id) => visible.has(id)).length,
|
||
hasVisibleRows: visible.size > 0,
|
||
hasFundsReason: /закончились средства/.test(reason),
|
||
firstAt,
|
||
lastAt,
|
||
};
|
||
};
|
||
|
||
/** «сообщение / сообщения / сообщений», «заказ / заказа / заказов». */
|
||
export const plural = (n, one, few, many) => {
|
||
const mod10 = n % 10;
|
||
const mod100 = n % 100;
|
||
if (mod10 === 1 && mod100 !== 11) return one;
|
||
if (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)) return few;
|
||
return many;
|
||
};
|