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