feat(filters): два отдельных фильтра «Статус SMS» и «Статус автодозвона» вместо «Прозвонить»
This commit is contained in:
parent
587e12f562
commit
04f78f7367
|
|
@ -299,7 +299,7 @@ const isFilterActive = (filters) => {
|
|||
if (filters.deliveryStatus && filters.deliveryStatus !== "all") return true;
|
||||
if (filters.deliveryHalfDay && filters.deliveryHalfDay !== "all") return true;
|
||||
if (filters.smsStatus && filters.smsStatus !== "all") return true;
|
||||
if (filters.callStatus && filters.callStatus !== "all") return true;
|
||||
if (filters.autocallStatus && filters.autocallStatus !== "all") return true;
|
||||
if (filters.dateFrom) return true;
|
||||
if (filters.dateTo) return true;
|
||||
return false;
|
||||
|
|
@ -405,7 +405,7 @@ export const LogisticsReadinessBoard = ({ orderGroups = [], totalGroups: totalGr
|
|||
// Reset to page 1 when filters change
|
||||
React.useEffect(() => {
|
||||
setPage(1);
|
||||
}, [filters.query, filters.displayStatus, filters.city, filters.deliveryStatus, filters.deliveryHalfDay, filters.smsStatus, filters.callStatus, filters.dateFrom, filters.dateTo]);
|
||||
}, [filters.query, filters.displayStatus, filters.city, filters.deliveryStatus, filters.deliveryHalfDay, filters.smsStatus, filters.autocallStatus, filters.dateFrom, filters.dateTo]);
|
||||
|
||||
const totalGroups = rankedGroups.length;
|
||||
const totalPages = Math.max(1, Math.ceil(totalGroups / PAGE_SIZE));
|
||||
|
|
|
|||
|
|
@ -121,17 +121,23 @@ export const OrderFilters = ({ filters, setFilters, statusOptions = [], cities =
|
|||
{ value: "pickup", label: "Самовывоз" },
|
||||
];
|
||||
|
||||
const smsProblemOptions = [
|
||||
{ value: "all", label: "Проблемы SMS" },
|
||||
{ value: "problem_not_sent", label: "SMS не отправлено" },
|
||||
{ value: "problem_not_delivered", label: "SMS не доставлено" },
|
||||
const smsStatusOptions = [
|
||||
{ value: "all", label: "Статус SMS" },
|
||||
{ value: "not_sent", label: "SMS: не отправлено" },
|
||||
{ value: "sent", label: "SMS: отправлено" },
|
||||
{ value: "delivered", label: "SMS: доставлено" },
|
||||
{ value: "error", label: "SMS: ошибка" },
|
||||
];
|
||||
|
||||
const callStatusOptions = [
|
||||
{ value: "all", label: "Прозвонить" },
|
||||
{ value: "need_call", label: "Нужно прозвонить" },
|
||||
{ value: "sms_problem", label: "Проблема с SMS" },
|
||||
{ value: "autocall_problem", label: "Проблема с автодозвоном" },
|
||||
const autocallStatusOptions = [
|
||||
{ value: "all", label: "Статус автодозвона" },
|
||||
{ value: "not_called", label: "Автодозвон: не звонили" },
|
||||
{ value: "confirmed", label: "Автодозвон: согласовано" },
|
||||
{ value: "no_answer", label: "Автодозвон: не дозвонились" },
|
||||
{ value: "no_input", label: "Автодозвон: не нажал в меню" },
|
||||
{ value: "manual", label: "Автодозвон: требует ручного управления" },
|
||||
{ value: "opt_out", label: "Автодозвон: отказ от звонков" },
|
||||
{ value: "excluded", label: "Автодозвон: не звоним (исключение)" },
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
@ -235,16 +241,16 @@ export const OrderFilters = ({ filters, setFilters, statusOptions = [], cities =
|
|||
|
||||
<DropdownSelect
|
||||
value={filters.smsStatus || "all"}
|
||||
options={smsProblemOptions}
|
||||
options={smsStatusOptions}
|
||||
onChange={(v) => updateFilter("smsStatus", v)}
|
||||
placeholder="Проблемы SMS"
|
||||
placeholder="Статус SMS"
|
||||
/>
|
||||
|
||||
<DropdownSelect
|
||||
value={filters.callStatus || "all"}
|
||||
options={callStatusOptions}
|
||||
onChange={(v) => updateFilter("callStatus", v)}
|
||||
placeholder="Прозвонить"
|
||||
value={filters.autocallStatus || "all"}
|
||||
options={autocallStatusOptions}
|
||||
onChange={(v) => updateFilter("autocallStatus", v)}
|
||||
placeholder="Статус автодозвона"
|
||||
/>
|
||||
|
||||
{typeof onToggleHideCompleted === "function" && (
|
||||
|
|
|
|||
|
|
@ -245,22 +245,38 @@ export const parseGroupDate = (value) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* SMS delivery problem tone used for both table highlighting and filtering.
|
||||
* Returns "ok" | "not_sent" | "not_delivered".
|
||||
* SMS status used for both table highlighting and filtering.
|
||||
* Returns "not_sent" | "sent" | "delivered" | "error".
|
||||
*/
|
||||
export const getSmsProblemTone = (group) => {
|
||||
if (!group) return "ok";
|
||||
export const getSmsStatus = (group) => {
|
||||
if (!group) return "not_sent";
|
||||
const firstSms = group.firstSmsSentAt || group.first_sms_sent_at;
|
||||
const secondSms = group.secondSmsSentAt || group.second_sms_sent_at;
|
||||
const lastError = group.lastSmsError;
|
||||
// Sent an SMS (1st or 2nd) and it has a recorded delivery error → problem with delivery.
|
||||
if ((firstSms || secondSms) && lastError) return "not_delivered";
|
||||
// Sent an SMS (1st or 2nd) and it has a recorded delivery error → error.
|
||||
if ((firstSms || secondSms) && lastError) return "error";
|
||||
// SMS should be expected but not sent at all yet.
|
||||
if (!firstSms && !secondSms) return "not_sent";
|
||||
// Sent but no error recorded — assume delivered / in progress.
|
||||
return "delivered";
|
||||
};
|
||||
|
||||
// Для обратной совместимости
|
||||
export const getSmsProblemTone = (group) => {
|
||||
const s = getSmsStatus(group);
|
||||
if (s === "error") return "not_delivered";
|
||||
if (s === "not_sent") return "not_sent";
|
||||
return "ok";
|
||||
};
|
||||
|
||||
// ─── Статус SMS: человеческие значения для фильтра ─────────────────
|
||||
export const SMS_STATUS_META = {
|
||||
not_sent: { label: "Не отправлено", tone: "neutral" },
|
||||
sent: { label: "Отправлено", tone: "info" },
|
||||
delivered: { label: "Доставлено", tone: "accent" },
|
||||
error: { label: "Ошибка", tone: "danger" },
|
||||
};
|
||||
|
||||
// ─── Автодозвон: единый человеческий статус (по аналогии со статусом SMS) ──
|
||||
// Принимает массив autocall_log (отсортированный по created_at desc) или null.
|
||||
export const AUTOCALL_STATUS_META = {
|
||||
|
|
@ -294,7 +310,7 @@ export const filterOrderGroups = (groups, filters = {}) => {
|
|||
const dateTo = normalizeDate(filters.dateTo);
|
||||
const deliveryHalfDay = normalizeDate(filters.deliveryHalfDay || filters.timeSlot || "all");
|
||||
const smsStatus = filters.smsStatus || "all";
|
||||
const callStatus = filters.callStatus || "all";
|
||||
const autocallStatus = filters.autocallStatus || "all";
|
||||
|
||||
const isWithinDateRange = (group) => {
|
||||
const deliveryDate = parseGroupDate(getDeliveryDate(group));
|
||||
|
|
@ -387,23 +403,20 @@ export const filterOrderGroups = (groups, filters = {}) => {
|
|||
}
|
||||
|
||||
if (smsStatus !== "all") {
|
||||
const tone = getSmsProblemTone(group);
|
||||
if (smsStatus === "problem_not_sent" && tone !== "not_sent") return false;
|
||||
if (smsStatus === "problem_not_delivered" && tone !== "not_delivered") return false;
|
||||
const status = getSmsStatus(group);
|
||||
if (smsStatus === "not_sent" && status !== "not_sent") return false;
|
||||
if (smsStatus === "sent" && status !== "sent") return false;
|
||||
if (smsStatus === "delivered" && status !== "delivered") return false;
|
||||
if (smsStatus === "error" && status !== "error") return false;
|
||||
}
|
||||
|
||||
// Фильтр «прозвонить»: SMS + автодозвон
|
||||
if (callStatus !== "all") {
|
||||
const smsTone = getSmsProblemTone(group);
|
||||
const autocallStatus = group.autocall_status || group.autocallStatus || resolveAutocallStatus([], {
|
||||
// Фильтр «Статус автодозвона»
|
||||
if (autocallStatus !== "all") {
|
||||
const acStatus = group.autocall_status || group.autocallStatus || resolveAutocallStatus([], {
|
||||
optOut: group.autocall_opt_out,
|
||||
exclusionReason: group.autocall_exclusion_reason,
|
||||
});
|
||||
const smsNotDone = smsTone === "not_sent" || smsTone === "not_delivered";
|
||||
const callNotDone = ["not_called", "no_answer", "no_input", "manual"].includes(autocallStatus);
|
||||
if (callStatus === "need_call" && !(smsNotDone || callNotDone)) return false;
|
||||
if (callStatus === "sms_problem" && !smsNotDone) return false;
|
||||
if (callStatus === "autocall_problem" && !callNotDone) return false;
|
||||
if (acStatus !== autocallStatus) return false;
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue