diff --git a/Marco.Pms.Model/ViewModels/Inventory/ProductCategoryDetailsVM.cs b/Marco.Pms.Model/ViewModels/Inventory/ProductCategoryDetailsVM.cs index bfc78da..782fffb 100644 --- a/Marco.Pms.Model/ViewModels/Inventory/ProductCategoryDetailsVM.cs +++ b/Marco.Pms.Model/ViewModels/Inventory/ProductCategoryDetailsVM.cs @@ -6,6 +6,6 @@ public string? Name { get; set; } public string? Description { get; set; } public bool IsActive { get; set; } - public List? ItemGroups { get; set; } + public List? Products { get; set; } } } diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index 7a52af3..5d2b3de 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -616,7 +616,10 @@ namespace Marco.Pms.Services.Controllers .SelectMany(id => featureMenus[id]) .OrderBy(r => r.Name) .ToList(); - + if (tenantId == superTenantId) + { + response.Add(new MasterMenuVM { Id = 14, Name = "Product Category" }); + } _logger.LogInfo("MasterMenu count for TenantId {TenantId}: {Count}", tenantId, response.Count); return Ok(ApiResponse.SuccessResponse(response, "Successfully fetched the master table list", 200)); } diff --git a/Marco.Pms.Services/Controllers/InventoryController.cs b/Marco.Pms.Services/Controllers/InventoryController.cs new file mode 100644 index 0000000..669f833 --- /dev/null +++ b/Marco.Pms.Services/Controllers/InventoryController.cs @@ -0,0 +1,48 @@ +using Marco.Pms.Model.Dtos.Inventory; +using Marco.Pms.Services.Service.ServiceInterfaces; +using MarcoBMS.Services.Helpers; +using MarcoBMS.Services.Service; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Marco.Pms.Services.Controllers +{ + [Authorize] + [Route("api/[controller]")] + [ApiController] + public class InventoryController : ControllerBase + { + private readonly IInventoryService _inventoryService; + private readonly UserHelper _userHelper; + private readonly ILoggingService _logger; + private readonly Guid tenantId; + public InventoryController(IInventoryService inventoryService, UserHelper userHelper, ILoggingService logger) + { + _inventoryService = inventoryService; + _userHelper = userHelper; + _logger = logger; + tenantId = userHelper.GetTenantId(); + } + + #region =================================================================== Items APIs =================================================================== + [HttpGet("item/list")] + [HttpGet("item/details/{id}")] + [HttpPost("item/create")] + public async Task CreateItem([FromBody] ItemDto model) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _inventoryService.CreateItemAsync(model, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + + } + [HttpPut("item/edit/{id}")] + [HttpDelete("item/delete/{id}")] + public async Task SuspendItem(Guid id, [FromQuery] bool isActive = false) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _inventoryService.SuspendItemAsync(id, isActive, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + #endregion + } +} diff --git a/Marco.Pms.Services/Controllers/MasterController.cs b/Marco.Pms.Services/Controllers/MasterController.cs index cefea78..58e6239 100644 --- a/Marco.Pms.Services/Controllers/MasterController.cs +++ b/Marco.Pms.Services/Controllers/MasterController.cs @@ -38,6 +38,30 @@ namespace Marco.Pms.Services.Controllers tenantId = userHelper.GetTenantId(); } + #region =================================================================== Country APIs =================================================================== + + [HttpGet("countries/list")] + public async Task GetCountries([FromQuery] string? searchString) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.GetCountriesAsync(searchString, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + #endregion + + #region =================================================================== States APIs =================================================================== + + [HttpGet("states/list")] + public async Task GetStates([FromQuery] string? searchString) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.GetStatesAsync(searchString, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + #endregion + #region =================================================================== Organization Type APIs =================================================================== [HttpGet("organization-type/list")] @@ -1066,6 +1090,50 @@ namespace Marco.Pms.Services.Controllers #endregion + #region =================================================================== Product Category APIs =================================================================== + + [HttpGet("product-category/list")] + public async Task GetProductCategoryMasterList([FromQuery] bool isActive = true) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.GetProductCategoryMasterListAsync(isActive, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + [HttpGet("product-category/details/{id}")] + public async Task GetProductCategoryMasterDetails(Guid id) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.GetProductCategoryMasterDetailsAsync(id, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + [HttpPost("product-category/create")] + public async Task CreateProductCategoryMaster([FromBody] ProductCategoryDto model) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.CreateProductCategoryMasterAsync(model, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + [HttpPut("product-category/edit/{id}")] + public async Task UpdateProductCategoryMaster(Guid id, [FromBody] ProductCategoryDto model) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.UpdateProductCategoryMasterAsync(id, model, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + [HttpDelete("product-category/delete/{id}")] + public async Task DeleteProductCategoryMaster(Guid id, [FromQuery] bool isActive = false) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.DeleteProductCategoryMasterAsync(id, isActive, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + #endregion + #region =================================================================== Payment Adjustment Head APIs =================================================================== [HttpGet("payment-adjustment-head/list")] public async Task GetpaymentAdjustmentHeadsList([FromQuery] bool isActive = true) diff --git a/Marco.Pms.Services/Service/InventoryService.cs b/Marco.Pms.Services/Service/InventoryService.cs new file mode 100644 index 0000000..f983f92 --- /dev/null +++ b/Marco.Pms.Services/Service/InventoryService.cs @@ -0,0 +1,21 @@ +using Marco.Pms.Model.Dtos.Inventory; +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Utilities; +using Marco.Pms.Services.Service.ServiceInterfaces; + +namespace Marco.Pms.Services.Service +{ + public class InventoryService : IInventoryService + { + #region =================================================================== Items APIs =================================================================== + public async Task> CreateItemAsync(ItemDto model, Employee loggedInEmployee, Guid tenantId) + { + return ApiResponse.SuccessResponse(new { }, "", 200); + } + public async Task> SuspendItemAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId) + { + return ApiResponse.SuccessResponse(new { }, "", 200); + } + #endregion + } +} diff --git a/Marco.Pms.Services/Service/MasterService.cs b/Marco.Pms.Services/Service/MasterService.cs index abb99f6..ad191fa 100644 --- a/Marco.Pms.Services/Service/MasterService.cs +++ b/Marco.Pms.Services/Service/MasterService.cs @@ -55,6 +55,72 @@ namespace Marco.Pms.Services.Service _updateLogHelper = updateLogHelper ?? throw new ArgumentNullException(nameof(updateLogHelper)); } + #region =================================================================== Country APIs =================================================================== + + public async Task> GetCountriesAsync(string? searchString, Employee loggedInEmployee, Guid tenantId) + { + _logger.LogDebug("GetCountriesAsync called"); + + try + { + // Step 1: Fetch countries + var countryQuery = _context.CountryMasters.Where(c => !string.IsNullOrWhiteSpace(c.Name)); + if (!string.IsNullOrWhiteSpace(searchString)) + { + countryQuery = countryQuery.Where(c => c.Name.Contains(searchString) || c.CountryCode.Contains(searchString) || c.CurrencyCode.Contains(searchString)); + } + var countries = await countryQuery.OrderBy(c => c.Name).ToListAsync(); + + _logger.LogInfo("Fetched {Count} countries records", countries.Count); + + return ApiResponse.SuccessResponse(countries, $"{countries.Count} record(s) of countries fetched successfully", 200); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error fetching countries"); + return ApiResponse.ErrorResponse("An error occurred while fetching countries", ex.Message, 500); + } + } + + #endregion + + #region =================================================================== States APIs =================================================================== + + public async Task> GetStatesAsync(string? searchString, Employee loggedInEmployee, Guid tenantId) + { + _logger.LogDebug("GetStatesAsync called"); + + try + { + // Step 1: Fetch states + var stateQuery = _context.StateMasters.Include(s => s.Country).Where(s => !string.IsNullOrWhiteSpace(s.Name)); + if (!string.IsNullOrWhiteSpace(searchString)) + { + stateQuery = stateQuery.Where(s => s.Name.Contains(searchString) || s.StateCode.Contains(searchString)); + } + var states = await stateQuery.OrderBy(c => c.Name).ToListAsync(); + + var response = states.Select(s => new + { + Id = s.Id, + Name = s.Name, + StateCode = s.StateCode, + CountryName = s.Country?.Name + }).ToList(); + + _logger.LogInfo("Fetched {Count} states records", response.Count); + + return ApiResponse.SuccessResponse(response, $"{response.Count} record(s) of states fetched successfully", 200); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error fetching states"); + return ApiResponse.ErrorResponse("An error occurred while fetching states", ex.Message, 500); + } + } + + #endregion + #region =================================================================== Organization Type APIs =================================================================== public async Task> GetOrganizationTypesAsync(Employee loggedInEmployee, Guid tenantId) @@ -63,12 +129,12 @@ namespace Marco.Pms.Services.Service try { - // Step 1: Fetch global services - var services = await _context.OrgTypeMasters.OrderBy(ot => ot.Name).ToListAsync(); + // Step 1: Fetch organization types + var organizationTypes = await _context.OrgTypeMasters.OrderBy(ot => ot.Name).ToListAsync(); - _logger.LogInfo("Fetched {Count} organization type records for tenantId: {TenantId}", services.Count, tenantId); + _logger.LogInfo("Fetched {Count} organization type records for tenantId: {TenantId}", organizationTypes.Count, tenantId); - return ApiResponse.SuccessResponse(services, $"{services.Count} record(s) of organization type fetched successfully", 200); + return ApiResponse.SuccessResponse(organizationTypes, $"{organizationTypes.Count} record(s) of organization type fetched successfully", 200); } catch (Exception ex) { @@ -3579,6 +3645,318 @@ namespace Marco.Pms.Services.Service #endregion + #region =================================================================== Product Category APIs =================================================================== + + /// + /// Retrieves the list of Product Category Master records for a tenant based on active status. + /// + /// Indicates whether to fetch active or inactive records. + /// Context of the employee performing the operation. + /// The tenant's unique identifier. + /// ApiResponse containing the product category list or error details. + public async Task> GetProductCategoryMasterListAsync(bool isActive, Employee loggedInEmployee, Guid tenantId) + { + // Log the details of the incoming request for audit and diagnostics + _logger.LogInfo( + "GetProductCategoryMasterListAsync triggered for tenant {TenantId}, isActive: {IsActive}, by employee {EmployeeId} at {UtcNow}", + tenantId, isActive, loggedInEmployee.Id, DateTime.UtcNow); + + try + { + // Fetch product categories filtered by tenant and status + var productCategoryList = await _context.ProductCategoryMasters + .AsNoTracking() + .Where(pc => pc.IsActive == isActive) + .OrderBy(pc => pc.Name) + .ToListAsync(); + + // Map the entity list to the view model + var responseVm = _mapper.Map>(productCategoryList); + + // Log the result count and context for traceability + _logger.LogInfo("{Count} Product Category records fetched for tenant {TenantId} by employee {EmployeeId}", + responseVm.Count, tenantId, loggedInEmployee.Id); + + // Return standardized successful API response + return ApiResponse.SuccessResponse(responseVm, $"{responseVm.Count} Product Category Master records fetched successfully.", 200); + } + catch (DbUpdateException dbEx) + { + // Log database errors at Error level with context + _logger.LogError(dbEx, "Database error while fetching Product Category Master list for tenant {TenantId} by employee {EmployeeId}: {Error}", + tenantId, loggedInEmployee.Id, dbEx.Message); + + // Return error response with user-friendly message + return ApiResponse.ErrorResponse("A database error occurred while fetching Product Category Master records. Please try again or contact support.", ExceptionMapper(dbEx), 500); + } + catch (Exception ex) + { + // Log unexpected errors at Error level with details for diagnostics + _logger.LogError(ex, "Unhandled exception while fetching Product Category Master list for tenant {TenantId} by employee {EmployeeId}: {Error}", + tenantId, loggedInEmployee.Id, ex.Message); + + // Generic failure response for unexpected errors + return ApiResponse.ErrorResponse( + "An internal error occurred while fetching Product Category Master records.", + ExceptionMapper(ex), + 500 + ); + } + } + + /// + /// Retrieves Product Category Master details including its associated Product Groups for the provided tenant and category Id. + /// Ensures robust error handling and structured logging for traceability. + /// + /// Product Category Master Id + /// Employee requesting the data (used for logging context) + /// Tenant Id for multi-tenancy support + /// ApiResponse containing details or error information + public async Task> GetProductCategoryMasterDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId) + { + _logger.LogInfo("Starting retrieval of Product Category Master details: {ProductCategoryId} for tenant: {TenantId} by employee: {EmployeeId}", + id, tenantId, loggedInEmployee.Id); + + try + { + // Fetch Product Category Master for given Id and tenant + var productCategory = await _context.ProductCategoryMasters + .AsNoTracking() + .FirstOrDefaultAsync(pc => pc.Id == id); + + if (productCategory == null) + { + _logger.LogWarning("Product Category Master {ProductCategoryId} not found for tenant {TenantId}", + id, tenantId); + + return ApiResponse.ErrorResponse("Product Category Master not found", $"Product Category Master with Id {id} does not exist for tenant.", 404); + } + + // Fetch all groups associated with this category + var products = await _context.Products + .AsNoTracking() + .Where(p => p.ProductCategoryId == id && p.TenantId == tenantId) + .ToListAsync(); + + // Map entities to ViewModels + var response = new ProductCategoryDetailsVM + { + Id = productCategory.Id, + Name = productCategory.Name, + Description = productCategory.Description, + IsActive = productCategory.IsActive, + Products = _mapper.Map>(products) + }; + + _logger.LogInfo("Product Category Master details fetched successfully for {ProductCategoryId} by employee {EmployeeId}", + id, loggedInEmployee.Id); + + return ApiResponse.SuccessResponse(response, "Product Category Master details fetched successfully.", 200); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Database update exception while fetching Product Category Master {ProductCategoryId} by employee {EmployeeId}", + id, loggedInEmployee.Id); + + return ApiResponse.ErrorResponse("Database error occurred", ExceptionMapper(dbEx), 500); + } + catch (Exception ex) + { + _logger.LogError(ex, "Unhandled exception while fetching Product Category Master {ProductCategoryId} by employee {EmployeeId}", + id, loggedInEmployee.Id); + + return ApiResponse.ErrorResponse("Internal server error occurred", ExceptionMapper(ex), 500); + } + } + + /// + /// Creates a new Product Category Master for the given tenant after validating permissions and uniqueness. + /// Provides structured logging, robust error handling, and clear user feedback. + /// + /// DTO containing Product Category details + /// Employee performing the operation (used for logging and permission checks) + /// Tenant identifier for multi-tenancy support + /// ApiResponse containing the newly created category or error details + public async Task> CreateProductCategoryMasterAsync(ProductCategoryDto model, Employee loggedInEmployee, Guid tenantId) + { + // Generate a trace ID for distributed tracing/log correlation + var traceId = Guid.NewGuid(); + _logger.LogInfo("Initiating Product Category Master creation by employee {EmployeeId} for tenant {TenantId}, TraceId: {TraceId}", + loggedInEmployee.Id, tenantId, traceId); + + try + { + // Check if the employee has permission to manage master records + var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id); + if (!hasManagePermission) + { + _logger.LogWarning("Access DENIED for employee {EmployeeId} managing PRODUCT CATEGORY MASTER, TraceId: {TraceId}", + loggedInEmployee.Id, traceId); + + return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to manage masters.", 403); + } + + // Ensure the category name is unique per tenant + var productCategoryExists = await _context.ProductCategoryMasters + .AnyAsync(pc => pc.Name == model.Name); + + if (productCategoryExists) + { + _logger.LogWarning("Duplicate Product Category Master creation attempted: {Name} for tenant {TenantId}, TraceId: {TraceId}", + model.Name, tenantId, traceId); + + return ApiResponse.ErrorResponse( + "Product Category Master with the same name already exists.", $"An Product Category Master named '{model.Name}' already exists within this tenant.", 409); + } + + // Map DTO to entity and set additional required fields + var productCategory = _mapper.Map(model); + productCategory.IsActive = true; + + // Add and persist the new category + _context.ProductCategoryMasters.Add(productCategory); + await _context.SaveChangesAsync(); + + var response = _mapper.Map(productCategory); + + _logger.LogInfo("Product Category Master '{CategoryName}' created (Id: {CategoryId}) by employee {EmployeeId} in tenant {TenantId}", + productCategory.Name, productCategory.Id, loggedInEmployee.Id, tenantId); + + return ApiResponse.SuccessResponse(response, "Product Category Master created successfully.", 201); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Database exception while creating Product Category Master by employee {EmployeeId}", + loggedInEmployee.Id); + + return ApiResponse.ErrorResponse("Database error occurred while saving Product Category Master.", ExceptionMapper(dbEx), 500); + } + catch (Exception ex) + { + _logger.LogError(ex, "Unhandled exception during Product Category Master creation by employee {EmployeeId}", + loggedInEmployee.Id); + + return ApiResponse.ErrorResponse("Internal server error occurred while creating Product Category Master.", ExceptionMapper(ex), 500); + } + } + public async Task> UpdateProductCategoryMasterAsync(Guid id, ProductCategoryDto model, Employee loggedInEmployee, Guid tenantId) + { + try + { + var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id); + if (!hasManagePermission) + { + _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing PRODUCT CATEGORY MASTER.", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); + } + + var productCategoryExists = await _context.ProductCategoryMasters.AnyAsync(pc => pc.Id != id && pc.Name == model.Name); + if (productCategoryExists) + { + _logger.LogWarning("Product Category Master of name {Name} already existed in database", model.Name); + return ApiResponse.ErrorResponse("Product Category Master of same name already exists", "Product Category Master of same name already exists", 409); + } + + if (model.Id.HasValue && model.Id == id) + { + _logger.LogWarning("User provided invalid information while updating Product Category Master"); + return ApiResponse.ErrorResponse("Invalid information", "User provided invalid information", 400); + } + + var existingProductCategory = await _context.ProductCategoryMasters.FirstOrDefaultAsync(pc => pc.Id == id); + if (existingProductCategory == null) + { + _logger.LogWarning("Product Category Master {ProductCategoryMastersId} not found in database for tenant {TenantId}", id, tenantId); + return ApiResponse.ErrorResponse("Product Category Master not found", "Product Category Master not found in database for current tenant", 404); + } + + var existingEntityBson = _updateLogHelper.EntityToBsonDocument(existingProductCategory); + + _mapper.Map(model, existingProductCategory); + await _context.SaveChangesAsync(); + + var response = _mapper.Map(existingProductCategory); + + await _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject + { + EntityId = existingProductCategory.Id.ToString(), + UpdatedById = loggedInEmployee.Id.ToString(), + OldObject = existingEntityBson, + UpdatedAt = DateTime.UtcNow + }, "ProductCategoryMasterModificationLog"); + + return ApiResponse.SuccessResponse(response, "Successfully updated the Product Category Master", 200); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Database Exception occured while updating Product Category Master by employee {EmployeeId}", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500); + } + catch (Exception ex) + { + _logger.LogError(ex, "Exception occured while updating Product Category Master by employee {EmployeeId}", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); + } + } + public async Task> DeleteProductCategoryMasterAsync(Guid id, bool active, Employee loggedInEmployee, Guid tenantId) + { + var message = active ? "restoring" : "deleting"; + try + { + var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id); + if (!hasManagePermission) + { + _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing PRODUCT CATEGORY MASTER.", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); + } + + var existingProductCategory = await _context.ProductCategoryMasters.FirstOrDefaultAsync(pc => pc.Id == id); + if (existingProductCategory == null) + { + _logger.LogWarning("Product Category Master {ProductCategoryId} not found in database for tenant {TenantId} while {Message} Product Category Master", id, tenantId, message); + return ApiResponse.ErrorResponse("Product Category Master not found", "Product Category Master not found in database for current tenant", 404); + } + + var productsExists = await _context.Products.AnyAsync(p => p.ProductCategoryId == id && p.TenantId == tenantId); + if (productsExists) + { + message = active ? "restore" : "delete"; + _logger.LogWarning("Employee {EmployeeId} tries to {Message} Product Category Master but mapping to Products founded", loggedInEmployee.Id, message); + return ApiResponse.ErrorResponse($"Product Category Master mapping to Products founded can not be {message}d", $"Product Category Master mapping to Products founded can not be {message}d", 400); + } + + var existingEntityBson = _updateLogHelper.EntityToBsonDocument(existingProductCategory); + + existingProductCategory.IsActive = active; + + await _context.SaveChangesAsync(); + + var response = _mapper.Map(existingProductCategory); + + await _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject + { + EntityId = existingProductCategory.Id.ToString(), + UpdatedById = loggedInEmployee.Id.ToString(), + OldObject = existingEntityBson, + UpdatedAt = DateTime.UtcNow + }, "ProductCategoryMasterModificationLog"); + + message = active ? "restored" : "deleted"; + return ApiResponse.SuccessResponse(response, $"Successfully {message} Product Category Master", 200); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Database Exception occured while {Message} Product Category Master by employee {EmployeeId}", message, loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500); + } + catch (Exception ex) + { + _logger.LogError(ex, "Exception occured while {Message} Product Category Master by employee {EmployeeId}", message, loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); + } + } + #endregion + #region =================================================================== Helper Function =================================================================== private static object ExceptionMapper(Exception ex) { diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IInventoryService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IInventoryService.cs new file mode 100644 index 0000000..0285bbc --- /dev/null +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IInventoryService.cs @@ -0,0 +1,14 @@ +using Marco.Pms.Model.Dtos.Inventory; +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Utilities; + +namespace Marco.Pms.Services.Service.ServiceInterfaces +{ + public interface IInventoryService + { + #region =================================================================== Items APIs =================================================================== + Task> CreateItemAsync(ItemDto model, Employee loggedInEmployee, Guid tenantId); + Task> SuspendItemAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId); + #endregion + } +} diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs index b53d150..77aa279 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs @@ -10,8 +10,17 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces { public interface IMasterService { - #region =================================================================== Organization Type APIs =================================================================== + #region =================================================================== Country APIs =================================================================== + Task> GetCountriesAsync(string? searchString, Employee loggedInEmployee, Guid tenantId); + #endregion + + #region =================================================================== States APIs =================================================================== + Task> GetStatesAsync(string? searchString, Employee loggedInEmployee, Guid tenantId); + + #endregion + + #region =================================================================== Organization Type APIs =================================================================== Task> GetOrganizationTypesAsync(Employee loggedInEmployee, Guid tenantId); #endregion @@ -124,6 +133,14 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces Task> DeletePurchaseOrderStatusAsync(Guid id, bool active, Employee loggedInEmployee, Guid tenantId); #endregion + #region =================================================================== Product Category APIs =================================================================== + Task> GetProductCategoryMasterListAsync(bool isActive, Employee loggedInEmployee, Guid tenantId); + Task> GetProductCategoryMasterDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId); + Task> CreateProductCategoryMasterAsync(ProductCategoryDto model, Employee loggedInEmployee, Guid tenantId); + Task> UpdateProductCategoryMasterAsync(Guid id, ProductCategoryDto model, Employee loggedInEmployee, Guid tenantId); + Task> DeleteProductCategoryMasterAsync(Guid id, bool active, Employee loggedInEmployee, Guid tenantId); + #endregion + #region =================================================================== Payment Adjustment Head APIs =================================================================== Task> GetPaymentAdjustmentHeadListAsync(bool isActive, Employee loggedInEmployee, Guid tenantId); Task> CreatePaymentAdjustmentHeadAsync(PaymentAdjustmentHeadDto model, Employee loggedInEmployee, Guid tenantId);