using AutoMapper; using Marco.Pms.Model.Dtos.Collection; using Marco.Pms.Model.Dtos.PurchaseInvoice; using Marco.Pms.Model.Utilities; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Helpers; using Microsoft.AspNetCore.JsonPatch; using Microsoft.AspNetCore.Mvc; namespace Marco.Pms.Services.Controllers { [Route("api/[controller]")] [ApiController] public class PurchaseInvoiceController : ControllerBase { private readonly UserHelper _userHelper; private readonly IPurchaseInvoiceService _purchaseInvoiceService; private readonly ISignalRService _signalR; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly Guid tenantId; public PurchaseInvoiceController(UserHelper userHelper, IPurchaseInvoiceService purchaseInvoiceService, ISignalRService signalR, IServiceScopeFactory serviceScopeFactory) { _userHelper = userHelper; _purchaseInvoiceService = purchaseInvoiceService; tenantId = _userHelper.GetTenantId(); _signalR = signalR; _serviceScopeFactory = serviceScopeFactory; } #region =================================================================== Purchase Invoice Functions =================================================================== /// /// Retrieves a list of purchase invoices based on search string, filter, activity status, page size, and page number. /// /// Optional search string to filter invoices by. /// Optional filter to apply to the invoices. /// Optional flag to filter invoices by activity status. /// The number of invoices to display per page. /// The requested page number (1-based). /// Token to propagate notification that operations should be canceled. /// A HTTP 200 OK response with a list of purchase invoices or an appropriate HTTP error code. [HttpGet("list")] public async Task GetPurchaseInvoiceList([FromQuery] string? searchString, [FromQuery] string? filter, CancellationToken cancellationToken, [FromQuery] bool isActive = true, [FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1) { // Get the currently logged-in employee var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); // Retrieve the purchase invoice list using the service var response = await _purchaseInvoiceService.GetPurchaseInvoiceListAsync(searchString, filter, isActive, pageSize, pageNumber, loggedInEmployee, tenantId, cancellationToken); // Return the response with the appropriate HTTP status code return StatusCode(response.StatusCode, response); } [HttpGet("details/{id}")] public async Task GetPurchaseInvoiceDetails(Guid id, CancellationToken cancellationToken) { // Get the currently logged-in employee var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); // Retrieve the purchase invoice details using the service var response = await _purchaseInvoiceService.GetPurchaseInvoiceDetailsAsync(id, loggedInEmployee, tenantId, cancellationToken); // Return the response with the appropriate HTTP status code return StatusCode(response.StatusCode, response); } /// /// Creates a purchase invoice. /// /// The purchase invoice model. /// The cancellation token. /// The HTTP response for the creation of the purchase invoice. [HttpPost("create")] public async Task CreatePurchaseInvoice([FromBody] PurchaseInvoiceDto model, CancellationToken ct) { // Get the currently logged-in employee var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); // Create a purchase invoice using the purchase invoice service var response = await _purchaseInvoiceService.CreatePurchaseInvoiceAsync(model, loggedInEmployee, tenantId, ct); // If the creation is successful, send a notification to the SignalR service if (response.Success) { var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Purchase_Invoice", Response = response.Data }; await _signalR.SendNotificationAsync(notification); } // Return the HTTP response return StatusCode(response.StatusCode, response); } [HttpPatch("edit/{id}")] public async Task EditPurchaseInvoice(Guid id, [FromBody] JsonPatchDocument patchDoc, CancellationToken ct) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var existingPurchaseInvoice = await _purchaseInvoiceService.GetPurchaseInvoiceByIdAsync(id, tenantId, ct); if (existingPurchaseInvoice == null) return NotFound(ApiResponse.ErrorResponse("Invalid purchase invoice ID", "Invalid purchase invoice ID", 404)); using var scope = _serviceScopeFactory.CreateScope(); var mapper = scope.ServiceProvider.GetRequiredService(); var modelToPatch = mapper.Map(existingPurchaseInvoice); // Apply the JSON Patch document to the DTO and check model state validity patchDoc.ApplyTo(modelToPatch, ModelState); if (!ModelState.IsValid) { return BadRequest(ApiResponse.ErrorResponse("Validation failed", "Provided patch document values are invalid", 400)); } var response = await _purchaseInvoiceService.UpdatePurchaseInvoiceAsync(id, existingPurchaseInvoice, modelToPatch, loggedInEmployee, tenantId, ct); return StatusCode(response.StatusCode, response); } [HttpDelete("delete/{id}")] public async Task DeletePurchaseInvoice(Guid id, CancellationToken ct, [FromQuery] bool isActive = false) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var response = await _purchaseInvoiceService.DeletePurchaseInvoiceAsync(id, isActive, loggedInEmployee, tenantId, ct); if (response.Success) { var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Purchase_Invoice", Response = response.Data }; await _signalR.SendNotificationAsync(notification); } return StatusCode(response.StatusCode, response); } #endregion #region =================================================================== Delivery Challan Functions =================================================================== [HttpGet("delivery-challan/list/{purchaseInvoiceId}")] public async Task GetDeliveryChallans(Guid purchaseInvoiceId, CancellationToken cancellationToken) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var response = await _purchaseInvoiceService.GetDeliveryChallansAsync(purchaseInvoiceId, loggedInEmployee, tenantId, cancellationToken); return StatusCode(response.StatusCode, response); } /// /// Adds a delivery challan. /// /// The delivery challan model. /// The cancellation token. /// The HTTP response for adding the delivery challan. [HttpPost("delivery-challan/create")] public async Task AddDeliveryChallan([FromBody] DeliveryChallanDto model, CancellationToken ct) { // Get the currently logged-in employee var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); // Add the delivery challan using the purchase invoice service var response = await _purchaseInvoiceService.AddDeliveryChallanAsync(model, loggedInEmployee, tenantId, ct); // If the addition is successful, send a notification to the SignalR service if (response.Success) { var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Delivery_Challan", Response = response.Data }; await _signalR.SendNotificationAsync(notification); } // Return the HTTP response return StatusCode(response.StatusCode, response); } #endregion #region =================================================================== Purchase Invoice History Functions =================================================================== [HttpGet("payment-history/list/{purchaseInvoiceId}")] public async Task GetPurchaseInvoiceHistoryList(Guid purchaseInvoiceId, CancellationToken cancellationToken) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var response = await _purchaseInvoiceService.GetPurchaseInvoiceHistoryListAsync(purchaseInvoiceId, loggedInEmployee, tenantId, cancellationToken); return StatusCode(response.StatusCode, response); } [HttpPost("add/payment")] public async Task AddPurchaseInvoicePayment([FromBody] ReceivedInvoicePaymentDto model, CancellationToken ct) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var response = await _purchaseInvoiceService.AddPurchaseInvoicePaymentAsync(model, loggedInEmployee, tenantId, ct); if (response.Success) { var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Purchase_Invoice_Payment", Response = response.Data }; await _signalR.SendNotificationAsync(notification); } // Return the HTTP response return StatusCode(response.StatusCode, response); } #endregion } }