File size: 2,525 Bytes
b6154b2
 
 
2552437
b6154b2
2552437
b6154b2
 
 
2552437
 
b6154b2
 
 
 
 
2552437
b6154b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2552437
b6154b2
 
2552437
 
 
 
b6154b2
2552437
 
 
 
 
 
 
 
 
b6154b2
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from __future__ import annotations

import asyncio
from datetime import timedelta

from sqlalchemy import select
from sqlalchemy.ext.asyncio import async_sessionmaker

from ..config import settings
from ..models import ReminderDelivery
from .datetime_utils import now_in_config_timezone
from .inventory import get_expiring_products, list_active_users
from .telegram import send_message


def seconds_until_next_run() -> float:
    now = now_in_config_timezone()
    target = now.replace(hour=settings.reminder_hour, minute=settings.reminder_minute, second=0, microsecond=0)
    if target <= now:
        target = target + timedelta(days=1)
    return (target - now).total_seconds()


def render_reminder(records: list[dict]) -> str:
    if not records:
        return f"Recordatorio diario: no hay productos por vencer en los proximos {settings.expiry_warning_days} dias."
    lines = [
        f"- {item['producto']}: vence {item['fechaCaducidad']}, stock {item['stockActual']} {item['unidad']}"
        for item in records
    ]
    return "Recordatorio diario de vencimientos:\n" + "\n".join(lines)


async def run_daily_reminders(session_factory: async_sessionmaker) -> None:
    async with session_factory() as session:
        users = await list_active_users(session)
        if not users:
            return
        records = await get_expiring_products(session, settings.expiry_warning_days)
        message = render_reminder(records)
        reminder_date = now_in_config_timezone().date().isoformat()
        for user in users:
            try:
                delivery_id = f"{user.chat_id}:{reminder_date}"
                exists = await session.get(ReminderDelivery, delivery_id)
                if exists is not None:
                    continue
                await send_message(user.chat_id, message)
                session.add(
                    ReminderDelivery(
                        delivery_id=delivery_id,
                        chat_id=str(user.chat_id),
                        reminder_date=reminder_date,
                        created_at=now_in_config_timezone().replace(microsecond=0).isoformat(),
                    )
                )
                await session.commit()
            except Exception as exc:
                print(f"No se pudo enviar recordatorio a {user.chat_id}: {exc}")


async def reminder_loop(session_factory: async_sessionmaker) -> None:
    while True:
        await asyncio.sleep(seconds_until_next_run())
        await run_daily_reminders(session_factory)