supersam/src/services/smsProblemSummary.js

62 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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;
};