using FluentValidation; using Microsoft.AspNetCore.Mvc; using Meezi.API.Models.Printing; using Meezi.Core.Authorization; using Meezi.Core.Entities; using Meezi.Core.Interfaces; using Meezi.Infrastructure.Data; using Meezi.Shared; using Microsoft.EntityFrameworkCore; namespace Meezi.API.Controllers; [Route("api/cafes/{cafeId}/branches/{branchId}/print-settings")] public class BranchPrintSettingsController : CafeApiControllerBase { private readonly AppDbContext _db; private readonly IValidator _validator; public BranchPrintSettingsController( AppDbContext db, IValidator validator) { _db = db; _validator = validator; } [HttpGet] public async Task Get( string cafeId, string branchId, ITenantContext tenant, CancellationToken ct) { if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied; var branch = await _db.Branches .AsNoTracking() .FirstOrDefaultAsync(b => b.Id == branchId && b.CafeId == cafeId, ct); if (branch is null) return NotFound(new ApiResponse(false, null, new ApiError("BRANCH_NOT_FOUND", "Branch not found."))); return Ok(new ApiResponse(true, ToDto(branch))); } [HttpPatch] public async Task Patch( string cafeId, string branchId, [FromBody] PatchBranchPrintSettingsRequest request, ITenantContext tenant, CancellationToken ct) { if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied; if (EnsurePermission(tenant, Permission.ManagePrintSettings) is { } permDenied) return permDenied; var validation = await _validator.ValidateAsync(request, ct); if (!validation.IsValid) return BadRequest(ValidationError(validation)); var branch = await _db.Branches.FirstOrDefaultAsync(b => b.Id == branchId && b.CafeId == cafeId, ct); if (branch is null) return NotFound(new ApiResponse(false, null, new ApiError("BRANCH_NOT_FOUND", "Branch not found."))); if (request.ReceiptPrinterIp is not null) branch.ReceiptPrinterIp = string.IsNullOrWhiteSpace(request.ReceiptPrinterIp) ? null : request.ReceiptPrinterIp.Trim(); if (request.ReceiptPrinterPort.HasValue) branch.ReceiptPrinterPort = request.ReceiptPrinterPort.Value; if (request.KitchenPrinterIp is not null) branch.KitchenPrinterIp = string.IsNullOrWhiteSpace(request.KitchenPrinterIp) ? null : request.KitchenPrinterIp.Trim(); if (request.KitchenPrinterPort.HasValue) branch.KitchenPrinterPort = request.KitchenPrinterPort.Value; if (request.PaperWidthMm.HasValue) branch.PaperWidthMm = request.PaperWidthMm.Value is 58 or 80 ? request.PaperWidthMm.Value : 80; if (request.AutoCutEnabled.HasValue) branch.AutoCutEnabled = request.AutoCutEnabled.Value; if (request.ReceiptHeader is not null) branch.ReceiptHeader = string.IsNullOrWhiteSpace(request.ReceiptHeader) ? null : request.ReceiptHeader.Trim(); if (request.ReceiptFooter is not null) branch.ReceiptFooter = string.IsNullOrWhiteSpace(request.ReceiptFooter) ? null : request.ReceiptFooter.Trim(); if (request.WifiPassword is not null) branch.WifiPassword = string.IsNullOrWhiteSpace(request.WifiPassword) ? null : request.WifiPassword.Trim(); if (request.PosDeviceIp is not null) branch.PosDeviceIp = string.IsNullOrWhiteSpace(request.PosDeviceIp) ? null : request.PosDeviceIp.Trim(); if (request.PosDevicePort.HasValue) branch.PosDevicePort = request.PosDevicePort.Value; if (request.ReceiptPrintDeviceId is not null) branch.ReceiptPrintDeviceId = string.IsNullOrWhiteSpace(request.ReceiptPrintDeviceId) ? null : request.ReceiptPrintDeviceId; if (request.KitchenPrintDeviceId is not null) branch.KitchenPrintDeviceId = string.IsNullOrWhiteSpace(request.KitchenPrintDeviceId) ? null : request.KitchenPrintDeviceId; branch.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(ct); return Ok(new ApiResponse(true, ToDto(branch))); } private static BranchPrintSettingsDto ToDto(Branch b) => new( b.Id, b.ReceiptPrinterIp, b.ReceiptPrinterPort, b.KitchenPrinterIp, b.KitchenPrinterPort, b.PaperWidthMm is 58 or 80 ? b.PaperWidthMm : 80, b.AutoCutEnabled, b.ReceiptHeader, b.ReceiptFooter, b.WifiPassword, b.PosDeviceIp, b.PosDevicePort, b.ReceiptPrintDeviceId, b.KitchenPrintDeviceId); }