国庆放假表把 10 月 8 日当成休息,超时和成交跟进当天不计时。按国务院安排改为当天上班,并补上 9 月 20 日调休。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-09 00:00:58 +08:00
co-authored by Cursor
parent 5e2a3e29aa
commit 2aab38da99
2 changed files with 25 additions and 13 deletions
+3 -1
View File
@@ -46,6 +46,7 @@ _HOLIDAYS = frozenset(
date(2026, 9, 25), date(2026, 9, 25),
date(2026, 9, 26), date(2026, 9, 26),
date(2026, 9, 27), date(2026, 9, 27),
# 国庆只休到 10 月 7 日。10 月 8 日周四正常上班,不能算假期。
date(2026, 10, 1), date(2026, 10, 1),
date(2026, 10, 2), date(2026, 10, 2),
date(2026, 10, 3), date(2026, 10, 3),
@@ -53,7 +54,6 @@ _HOLIDAYS = frozenset(
date(2026, 10, 5), date(2026, 10, 5),
date(2026, 10, 6), date(2026, 10, 6),
date(2026, 10, 7), date(2026, 10, 7),
date(2026, 10, 8),
# 2027 元旦预留 # 2027 元旦预留
date(2027, 1, 1), date(2027, 1, 1),
date(2027, 1, 2), date(2027, 1, 2),
@@ -68,6 +68,8 @@ _MAKEUP_WORKDAYS = frozenset(
date(2026, 2, 14), date(2026, 2, 14),
date(2026, 2, 28), date(2026, 2, 28),
date(2026, 5, 9), date(2026, 5, 9),
# 国庆调休:9 月 20 日周日、10 月 10 日周六上班。
date(2026, 9, 20),
date(2026, 10, 10), date(2026, 10, 10),
} }
) )
+22 -12
View File
@@ -11,6 +11,7 @@ from zoneinfo import ZoneInfo
from agent.policy.deal_followup import ( from agent.policy.deal_followup import (
SHANGHAI, SHANGHAI,
air_route_keys, air_route_keys,
is_workday,
leader_matches, leader_matches,
next_followup_at, next_followup_at,
shift_workdays, shift_workdays,
@@ -20,33 +21,42 @@ from agent.policy.deal_followup import (
class TestWorkdays(unittest.TestCase): class TestWorkdays(unittest.TestCase):
def test_skip_weekend(self) -> None: def test_skip_weekend(self) -> None:
# 2026-09-18 周五,顺延 3 个工作日 → 21、22、23,第四个工作日 24 # 普通周末仍跳过。2026-11-13 周五 → 16、17、18 三个工作日,第四个是 19 日。
self.assertEqual(shift_workdays(date(2026, 9, 18), 3), date(2026, 9, 23)) self.assertEqual(shift_workdays(date(2026, 11, 13), 3), date(2026, 11, 18))
self.assertEqual(shift_workdays(date(2026, 9, 18), 4), date(2026, 9, 24)) self.assertEqual(shift_workdays(date(2026, 11, 13), 4), date(2026, 11, 19))
def test_sept20_makeup_pulls_followup_forward(self) -> None:
# 2026-09-18 周五。9 月 20 日周日调休上班,第四个工作日是 23 日,不是 24 日。
self.assertEqual(shift_workdays(date(2026, 9, 18), 4), date(2026, 9, 23))
def test_skip_national_day(self) -> None: def test_skip_national_day(self) -> None:
# 2026-09-30 周三,国庆休 → 第四个工作日落到节后 # 2026-09-30 周三。10 月 1–7 日放假,8 日上班,10 日周六调休。
# 节后第 1 个工作日 8 日,第 4 个是 12 日周一。
fourth = shift_workdays(date(2026, 9, 30), 4) fourth = shift_workdays(date(2026, 9, 30), 4)
self.assertGreaterEqual(fourth, date(2026, 10, 9)) self.assertEqual(fourth, date(2026, 10, 12))
self.assertNotEqual(fourth.weekday(), 5)
self.assertNotEqual(fourth.weekday(), 6) def test_oct8_works_and_sept20_is_makeup(self) -> None:
# 国办发明电〔2025〕7号:10 月 8 日正常上班,9 月 20 日周日调休上班。
self.assertTrue(is_workday(date(2026, 10, 8)))
self.assertTrue(is_workday(date(2026, 9, 20)))
self.assertFalse(is_workday(date(2026, 10, 7)))
def test_next_followup_is_9am(self) -> None: def test_next_followup_is_9am(self) -> None:
when = next_followup_at(datetime(2026, 9, 18, 15, 30, tzinfo=SHANGHAI)) when = next_followup_at(datetime(2026, 9, 18, 15, 30, tzinfo=SHANGHAI))
self.assertEqual(when.hour, 9) self.assertEqual(when.hour, 9)
self.assertEqual(when.minute, 0) self.assertEqual(when.minute, 0)
self.assertEqual(when.tzinfo, SHANGHAI) self.assertEqual(when.tzinfo, SHANGHAI)
self.assertEqual(when.date(), date(2026, 9, 24)) self.assertEqual(when.date(), date(2026, 9, 23))
def test_skip_weekend_keep_weekday_night(self) -> None: def test_skip_weekend_keep_weekday_night(self) -> None:
start = datetime(2026, 9, 18, 17, 0, tzinfo=SHANGHAI) # 周五 start = datetime(2026, 11, 13, 17, 0, tzinfo=SHANGHAI) # 周五
now = datetime(2026, 9, 21, 17, 0, tzinfo=SHANGHAI) # 周一 now = datetime(2026, 11, 16, 17, 0, tzinfo=SHANGHAI) # 周一
# 周五 17–24 = 7h,周末不算,周一 0–17 = 17h # 周五 17–24 = 7h,周末不算,周一 0–17 = 17h
self.assertAlmostEqual(workday_elapsed_hours(start, now), 24.0, places=4) self.assertAlmostEqual(workday_elapsed_hours(start, now), 24.0, places=4)
def test_rest_day_start_counts_from_next_workday(self) -> None: def test_rest_day_start_counts_from_next_workday(self) -> None:
start = datetime(2026, 9, 19, 10, 0, tzinfo=SHANGHAI) # 周六 start = datetime(2026, 11, 14, 10, 0, tzinfo=SHANGHAI) # 周六
now = datetime(2026, 9, 21, 10, 0, tzinfo=SHANGHAI) # 周一 now = datetime(2026, 11, 16, 10, 0, tzinfo=SHANGHAI) # 周一
self.assertAlmostEqual(workday_elapsed_hours(start, now), 10.0, places=4) self.assertAlmostEqual(workday_elapsed_hours(start, now), 10.0, places=4)
def test_fractional_quarter_hour(self) -> None: def test_fractional_quarter_hour(self) -> None: