189 lines
7.5 KiB
C#
189 lines
7.5 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using LittleShop.Data;
|
|
using LittleShop.DTOs;
|
|
using LittleShop.Enums;
|
|
using LittleShop.Models;
|
|
|
|
namespace LittleShop.Services;
|
|
|
|
public class TeleBotMessagingService : ITeleBotMessagingService
|
|
{
|
|
private readonly LittleShopContext _context;
|
|
private readonly ICustomerMessageService _customerMessageService;
|
|
private readonly ILogger<TeleBotMessagingService> _logger;
|
|
|
|
public TeleBotMessagingService(
|
|
LittleShopContext context,
|
|
ICustomerMessageService customerMessageService,
|
|
ILogger<TeleBotMessagingService> logger)
|
|
{
|
|
_context = context;
|
|
_customerMessageService = customerMessageService;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<bool> SendOrderStatusUpdateAsync(Guid orderId, OrderStatus newStatus)
|
|
{
|
|
return newStatus switch
|
|
{
|
|
OrderStatus.PaymentReceived => await SendPaymentConfirmedAsync(orderId),
|
|
OrderStatus.Accepted => await SendOrderAcceptedAsync(orderId),
|
|
OrderStatus.Packing => await SendOrderPackingAsync(orderId),
|
|
OrderStatus.Dispatched => await SendOrderDispatchedAsync(orderId),
|
|
OrderStatus.Delivered => await SendOrderDeliveredAsync(orderId),
|
|
OrderStatus.OnHold => await SendOrderOnHoldAsync(orderId),
|
|
_ => false
|
|
};
|
|
}
|
|
|
|
public async Task<bool> SendPaymentConfirmedAsync(Guid orderId)
|
|
{
|
|
var order = await GetOrderWithCustomerAsync(orderId);
|
|
if (order?.Customer == null) return false;
|
|
|
|
var message = $"💰 *Payment Confirmed!*\n\n" +
|
|
$"Your order #{orderId.ToString()[..8]} has been paid successfully. " +
|
|
$"We'll start processing it shortly.\n\n" +
|
|
$"📦 Total: £{order.TotalAmount:F2}\n" +
|
|
$"⏱️ Expected processing: Within 24 hours";
|
|
|
|
return await QueueMessageAsync(order.Customer.Id, orderId, MessageType.OrderUpdate, "Payment Confirmed", message);
|
|
}
|
|
|
|
public async Task<bool> SendOrderAcceptedAsync(Guid orderId)
|
|
{
|
|
var order = await GetOrderWithCustomerAsync(orderId);
|
|
if (order?.Customer == null) return false;
|
|
|
|
var message = $"✅ *Order Accepted!*\n\n" +
|
|
$"Great news! Your order #{orderId.ToString()[..8]} has been accepted " +
|
|
$"and is being prepared for packing.\n\n" +
|
|
$"⏱️ Expected packing: Within 24 hours\n" +
|
|
$"🚚 We'll notify you when it's dispatched";
|
|
|
|
return await QueueMessageAsync(order.Customer.Id, orderId, MessageType.OrderUpdate, "Order Accepted", message);
|
|
}
|
|
|
|
public async Task<bool> SendOrderPackingAsync(Guid orderId)
|
|
{
|
|
var order = await GetOrderWithCustomerAsync(orderId);
|
|
if (order?.Customer == null) return false;
|
|
|
|
var message = $"📦 *Being Packed!*\n\n" +
|
|
$"Your order #{orderId.ToString()[..8]} is currently being packed with care.\n\n" +
|
|
$"🚚 We'll send tracking details once dispatched.\n" +
|
|
$"⏱️ Expected dispatch: Later today";
|
|
|
|
return await QueueMessageAsync(order.Customer.Id, orderId, MessageType.OrderUpdate, "Order Packing", message);
|
|
}
|
|
|
|
public async Task<bool> SendOrderDispatchedAsync(Guid orderId, string? trackingNumber = null)
|
|
{
|
|
var order = await GetOrderWithCustomerAsync(orderId);
|
|
if (order?.Customer == null) return false;
|
|
|
|
var trackingInfo = !string.IsNullOrEmpty(trackingNumber)
|
|
? $"📍 Tracking: `{trackingNumber}`\n"
|
|
: "";
|
|
|
|
var message = $"🚚 *Order Dispatched!*\n\n" +
|
|
$"Your order #{orderId.ToString()[..8]} is on its way!\n\n" +
|
|
$"{trackingInfo}" +
|
|
$"⏱️ Estimated delivery: 1-3 working days\n" +
|
|
$"📍 Track your package for real-time updates";
|
|
|
|
return await QueueMessageAsync(order.Customer.Id, orderId, MessageType.ShippingInfo, "Order Dispatched", message);
|
|
}
|
|
|
|
public async Task<bool> SendOrderDeliveredAsync(Guid orderId)
|
|
{
|
|
var order = await GetOrderWithCustomerAsync(orderId);
|
|
if (order?.Customer == null) return false;
|
|
|
|
var message = $"🎉 *Order Delivered!*\n\n" +
|
|
$"Your order #{orderId.ToString()[..8]} has been delivered successfully!\n\n" +
|
|
$"⭐ Please consider leaving a review using the /review command.\n" +
|
|
$"🛒 Thank you for choosing us for your order!";
|
|
|
|
return await QueueMessageAsync(order.Customer.Id, orderId, MessageType.OrderUpdate, "Order Delivered", message);
|
|
}
|
|
|
|
public async Task<bool> SendOrderOnHoldAsync(Guid orderId, string? reason = null)
|
|
{
|
|
var order = await GetOrderWithCustomerAsync(orderId);
|
|
if (order?.Customer == null) return false;
|
|
|
|
var reasonText = !string.IsNullOrEmpty(reason)
|
|
? $"\n\n📝 Reason: {reason}"
|
|
: "";
|
|
|
|
var message = $"⏸️ *Order On Hold*\n\n" +
|
|
$"Your order #{orderId.ToString()[..8]} has been temporarily put on hold.{reasonText}\n\n" +
|
|
$"💬 Please contact support if you have any questions.\n" +
|
|
$"⏱️ We'll resolve this as quickly as possible";
|
|
|
|
return await QueueMessageAsync(order.Customer.Id, orderId, MessageType.OrderUpdate, "Order On Hold", message);
|
|
}
|
|
|
|
public async Task<bool> SendTestMessageAsync(Guid customerId, string message)
|
|
{
|
|
var customer = await _context.Customers.FindAsync(customerId);
|
|
if (customer == null) return false;
|
|
|
|
var testMessage = $"🧪 *Test Message*\n\n{message}";
|
|
return await QueueMessageAsync(customerId, null, MessageType.CustomerService, "Test Message", testMessage);
|
|
}
|
|
|
|
public async Task<bool> IsAvailableAsync()
|
|
{
|
|
// TeleBot is always "available" since it polls for messages from the database queue
|
|
// No need to check HTTP endpoint availability
|
|
return true;
|
|
}
|
|
|
|
private async Task<Order?> GetOrderWithCustomerAsync(Guid orderId)
|
|
{
|
|
return await _context.Orders
|
|
.Include(o => o.Customer)
|
|
.FirstOrDefaultAsync(o => o.Id == orderId);
|
|
}
|
|
|
|
private async Task<bool> QueueMessageAsync(Guid customerId, Guid? orderId, MessageType type, string subject, string content)
|
|
{
|
|
try
|
|
{
|
|
var createMessageDto = new CreateCustomerMessageDto
|
|
{
|
|
CustomerId = customerId,
|
|
OrderId = orderId,
|
|
Type = type,
|
|
Subject = subject,
|
|
Content = content,
|
|
Priority = 5, // Normal priority
|
|
IsUrgent = false
|
|
};
|
|
|
|
var result = await _customerMessageService.CreateMessageAsync(createMessageDto);
|
|
|
|
if (result != null)
|
|
{
|
|
_logger.LogInformation("Queued message {MessageId} for customer {CustomerId} - {Subject}",
|
|
result.Id, customerId, subject);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
_logger.LogWarning("Failed to queue message for customer {CustomerId} - {Subject}",
|
|
customerId, subject);
|
|
return false;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error queuing message for customer {CustomerId} - {Subject}",
|
|
customerId, subject);
|
|
return false;
|
|
}
|
|
}
|
|
} |