diff --git a/scripts/sms_first_campaign.py b/scripts/sms_first_campaign.py index 129e473..f495ace 100644 --- a/scripts/sms_first_campaign.py +++ b/scripts/sms_first_campaign.py @@ -184,6 +184,7 @@ def get_groups_to_send(conn): AND og.delivery_link IS NOT NULL AND og.delivery_link != '' AND COALESCE(og.notification_status, '') = 'link_ready' + AND sms_allowed_for_city(og.town, 'first_sms') -- Нет активной SMS в логе (sent/checking) за последние max_check_duration минут AND NOT EXISTS ( SELECT 1 FROM sms_campaign_log scl diff --git a/scripts/sms_paid_storage_campaign.py b/scripts/sms_paid_storage_campaign.py index 4abb2e9..c5df2e8 100644 --- a/scripts/sms_paid_storage_campaign.py +++ b/scripts/sms_paid_storage_campaign.py @@ -185,6 +185,7 @@ def get_groups_to_send(conn): AND COALESCE(og.notification_status, '') NOT IN ('paid_storage_sending', 'paid_storage_sent') AND og.delivery_link IS NOT NULL AND og.delivery_link != '' + AND sms_allowed_for_city(og.town, 'paid_storage') AND NOT EXISTS ( SELECT 1 FROM sms_campaign_log scl WHERE scl.order_group_id = og.id diff --git a/scripts/sms_second_campaign.py b/scripts/sms_second_campaign.py index 5d61ef3..e746318 100644 --- a/scripts/sms_second_campaign.py +++ b/scripts/sms_second_campaign.py @@ -206,6 +206,7 @@ def get_groups_to_send(conn): AND COALESCE(og.notification_status, '') = 'first_sms_sent' AND og.second_sms_sent_at IS NULL AND (og.next_notification_check_at IS NULL OR og.next_notification_check_at <= NOW()) + AND sms_allowed_for_city(og.town, 'second_sms') -- Нет активной второй SMS в логе AND NOT EXISTS ( SELECT 1 FROM sms_campaign_log scl diff --git a/src/components/admin/SmsCampaignPanel.jsx b/src/components/admin/SmsCampaignPanel.jsx index 8f0a1b8..e2ea79e 100644 --- a/src/components/admin/SmsCampaignPanel.jsx +++ b/src/components/admin/SmsCampaignPanel.jsx @@ -9,6 +9,7 @@ import { Panel } from "../UI/Panel"; import { Badge } from "../UI/Badge"; import { supabase } from "../../supabaseClient"; import { SmsCampaignStats } from "./SmsCampaignStats"; +import { SmsCityRulesPanel } from "./SmsCityRulesPanel"; // ── Campaigns ─────────────────────────────────────────────────────────────── const CAMPAIGNS = [ @@ -121,6 +122,7 @@ export const SmsCampaignPanel = () => { const [checkingIds, setCheckingIds] = useState(new Set()); const [autoRefresh, setAutoRefresh] = useState(true); const [togglingCampaign, setTogglingCampaign] = useState(null); + const [showCityRules, setShowCityRules] = useState(false); const refreshTimer = useRef(null); const handleOpenGroup = useCallback((groupId) => { @@ -405,6 +407,25 @@ export const SmsCampaignPanel = () => { })} + {/* ── City rules button ──────────────────────────────────────────── */} +
+ Управление отправкой SMS по городам и кампаниям. Выключенное правило = SMS не отправляется. +
++ Пустые даты = правило действует постоянно. Указав даты, можно временно отключить SMS на период. +
+ +Загрузка...
+ ) : rules.length === 0 ? ( ++ Правил пока нет. SMS отправляются во все города. +
++ Нажмите «+ Правило» чтобы отключить SMS для конкретного города. +
+