import logging from azbankgateways import ( bankfactories, models as bank_models, default_settings as settings, ) from .models import OrderModel from account.models import PushSubscription import ghasedak_sms from product.models import ProductImageModel from celery import shared_task @shared_task def udpate_bank_status(): factory = bankfactories.BankFactory() bank_models.Bank.objects.update_expire_records() for item in bank_models.Bank.objects.filter_return_from_bank(): bank = factory.create( bank_type=item.bank_type, identifier=item.bank_choose_identifier ) bank.verify(item.tracking_code) bank_record = bank_models.Bank.objects.get(tracking_code=item.tracking_code) if bank_record.is_success: bank_record.order.cart.clear_cart() bank_record.order.is_paid = True bank_record.order.save() logging.debug("This record is verify now.", extra={"pk": bank_record.pk}) else: order = bank_record.order order.rollback_stock() return 'update bank record is done' @shared_task def send_change_status_notif(instance_pk, new_status): instance = OrderModel.objects.get(pk=instance_pk) user_subs = PushSubscription.objects.filter(user=instance.user) for user_sub in user_subs: try: user_sub.send_notif(f'سفارش شما به {new_status} تغییر کرد', f'سفارش شما به {new_status} تغییر کرد', ProductImageModel.objects.all().first().image.url) except: print('log later send notif error') @shared_task def send_change_status_sms(instance_pk, new_status): instance = OrderModel.objects.get(pk=instance_pk) sms_api = ghasedak_sms.Ghasedak(api_key="8f7396f1e3c39e3a4621009c558d955336eea6d21cf257dd74ae262d6f22a458XdoDjH6egJsiZsy8") response = sms_api.send_single_sms( ghasedak_sms.SendSingleSmsInput( message=f'سفارش شما به {new_status} تغییر کرد', receptor=instance.user.phone, line_number='30005006004095', client_reference_id=str(instance.user.pk) ) ) if response['statusCode'] == 200: return 'done log later' else: return f'error: {response}' @shared_task def generate_daily_shop_reports(): """Generate daily shop reports for the previous day. This task aggregates ShopOrderModel entries from yesterday and creates/updates ShopDailyReport records for each shop. Scheduled to run daily at midnight. """ from django.utils import timezone from datetime import timedelta from django.db.models import Sum from .models import ShopOrderModel, ShopDailyReport target_date = (timezone.now() - timedelta(days=1)).date() logging.info(f'Generating shop reports for {target_date}') shop_orders = ShopOrderModel.objects.filter(created_at__date=target_date) if not shop_orders.exists(): logging.warning(f'No shop orders found for {target_date}') return f'No shop orders for {target_date}' shops = shop_orders.values('shop').distinct() reports_created = 0 reports_updated = 0 for s in shops: shop_id = s['shop'] aggr = shop_orders.filter(shop_id=shop_id).aggregate( total_sales=Sum('subtotal'), total_commission=Sum('commission_amount'), total_payable=Sum('payable_amount') ) total_sales = aggr['total_sales'] or 0 total_commission = aggr['total_commission'] or 0 total_payable = aggr['total_payable'] or 0 report, created = ShopDailyReport.objects.update_or_create( shop_id=shop_id, date=target_date, defaults={ 'total_sales': total_sales, 'total_commission': total_commission, 'total_payable': total_payable, } ) if created: reports_created += 1 else: reports_updated += 1 logging.info(f"Shop {shop_id}: sales={total_sales}, commission={total_commission}, payable={total_payable}") result = f'Generated reports for {target_date}: {reports_created} created, {reports_updated} updated' logging.info(result) return result @shared_task def send_shop_order_invoice_telegram_task(shop_order_id, chat_id, bot_token): """Send shop order invoice PDF to Telegram chat. Args: shop_order_id: ID of the ShopOrderModel chat_id: Telegram chat ID to send invoice to bot_token: Telegram bot token for authentication Returns: Success or error message """ import asyncio import io from telegram import Bot from telegram.error import TelegramError from .invoice_generator import generate_shop_order_invoice from .models import ShopOrderModel try: # Get the shop order shop_order = ShopOrderModel.objects.get(pk=shop_order_id) # Generate invoice PDF pdf_buffer = generate_shop_order_invoice(shop_order_id) # Reset buffer position pdf_buffer.seek(0) # Send via Telegram async def send_invoice(): bot = Bot(token=bot_token) await bot.send_document( chat_id=chat_id, document=pdf_buffer, filename=f'invoice_shop_order_{shop_order_id}.pdf', caption=f'فاکتور سفارش #{shop_order_id}\n{shop_order.shop.shop_name}' ) # Run async function asyncio.run(send_invoice()) logging.info(f'Successfully sent shop order invoice {shop_order_id} to Telegram chat {chat_id}') return f'Invoice sent successfully to chat {chat_id}' except ShopOrderModel.DoesNotExist: error_msg = f'ShopOrderModel with id {shop_order_id} does not exist' logging.error(error_msg) return error_msg except TelegramError as e: error_msg = f'Telegram error sending invoice {shop_order_id}: {str(e)}' logging.error(error_msg) return error_msg except Exception as e: error_msg = f'Error sending invoice {shop_order_id} to Telegram: {str(e)}' logging.error(error_msg) return error_msg