74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""报销模块日期范围工具(从 bx-backend 迁移)。"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
|
|
def current_month_bounds(now: datetime | None = None) -> tuple[datetime, datetime]:
|
|
"""当前自然月 [month_start, next_month_start)。"""
|
|
if now is None:
|
|
now = datetime.now()
|
|
month_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
|
if now.month == 12:
|
|
month_end = datetime(now.year + 1, 1, 1)
|
|
else:
|
|
month_end = datetime(now.year, now.month + 1, 1)
|
|
return month_start, month_end
|
|
|
|
|
|
def parse_create_time_day_bounds(apply_date: str | None) -> tuple[datetime, datetime] | None:
|
|
if not apply_date or not str(apply_date).strip():
|
|
return None
|
|
try:
|
|
day_start = datetime.strptime(str(apply_date).strip(), "%Y-%m-%d")
|
|
return day_start, day_start + timedelta(days=1)
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def _parse_day_start(date_str: str | None) -> datetime | None:
|
|
if not date_str or not str(date_str).strip():
|
|
return None
|
|
try:
|
|
return datetime.strptime(str(date_str).strip(), "%Y-%m-%d")
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def resolve_create_time_bounds(
|
|
apply_date: str | None = None,
|
|
apply_date_from: str | None = None,
|
|
apply_date_to: str | None = None,
|
|
) -> tuple[datetime | None, datetime | None]:
|
|
"""解析申请时间筛选边界,返回 (含起, 不含止)。"""
|
|
if apply_date_from or apply_date_to:
|
|
start = _parse_day_start(apply_date_from)
|
|
end = None
|
|
day_end = _parse_day_start(apply_date_to)
|
|
if day_end is not None:
|
|
end = day_end + timedelta(days=1)
|
|
return start, end
|
|
bounds = parse_create_time_day_bounds(apply_date)
|
|
if bounds:
|
|
return bounds[0], bounds[1]
|
|
return None, None
|
|
|
|
|
|
def append_create_time_filters(
|
|
filters: list,
|
|
model,
|
|
*,
|
|
apply_date: str | None = None,
|
|
apply_date_from: str | None = None,
|
|
apply_date_to: str | None = None,
|
|
) -> None:
|
|
start, end = resolve_create_time_bounds(
|
|
apply_date=apply_date,
|
|
apply_date_from=apply_date_from,
|
|
apply_date_to=apply_date_to,
|
|
)
|
|
if start is not None:
|
|
filters.append(model.create_time >= start)
|
|
if end is not None:
|
|
filters.append(model.create_time < end)
|