diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs
index be036be..df85ccd 100644
--- a/MBDEVproAPI.API/Controllers/CustomerController.cs
+++ b/MBDEVproAPI.API/Controllers/CustomerController.cs
@@ -1,6 +1,4 @@
-
-
-namespace MBDEVproAPI.API.Controllers
+namespace MBDEVproAPI.API.Controllers
{
public class CustomerController : BaseController
{
@@ -20,9 +18,9 @@ public CustomerController(ICustomerService customerService)
#endregion
- #region Get All Customers | CustomerViewModel
+ #region Get All Customers
///
- /// GET: Gets all customers for a business in a VM for web UI.
+ /// GET: Get All Customers | CustomerViewModel | Gets all customers for a business in a VM for web UI.
/// TEST URL: https://localhost:7092/api/Customer/GetAllCustomers/52466 | https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466
/// "CustomerControllerGetAllCustomersVMAsync": "Customer/GetAllCustomersVMAsync",
///
@@ -50,12 +48,10 @@ public async Task> GetAllCustomersVMAsync(int Bu
return BadRequest("Customer API error: " + ex.Message + " | " + ex.InnerException);
}
}
- #endregion
- #region Get All Customers | CustomerModel
///
- /// GET: Gets all customers for a business.
+ /// GET: Get All Customers | CustomerModel | Gets all customers for a business.
/// TEST URL: https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466
/// "CustomerControllerGetAllCustomersAsync": "Customer/GetAllCustomersAsync",
///
@@ -83,9 +79,9 @@ public async Task> GetAllCustomersAsync(int Business
- #region Get Customer | Customer
+ #region Get Customer
///
- /// GET: Gets a customer for a business.
+ /// GET: Get Customer | Customer | Gets a customer for a business.
/// TEST URL: https://localhost:7092/api/Customer/GetCustomer/3 | https://localhost:7092/api/Customer/GetCustomer?CustomerID=3
/// "CustomerControllerGetCustomer": "Customer/GetCustomer",
///
@@ -109,31 +105,32 @@ public async Task> GetCustomerAsync(int CustomerID)
- #region Add Customer | CustomerViewModel
+
+ #region Create Customer
///
- /// Create a new customer for a business from client web application using a CustomerViewModel.
+ /// Add Customer | CustomerViewModel | Create a new customer for a business from client web application using a CustomerViewModel.
///
///
///
[HttpPost]
public async Task CreateCustomerVMAsync([FromBody] CustomerViewModel vm)
{
- return Ok(_customerService.CreateCustomerVMAsync(vm));
+ var result = await _customerService.CreateCustomerVMAsync(vm);
+ return Ok(result);
}
- #endregion
-
- #region Add Customer | Customer
///
- /// Create a new customer for a business.
+ /// Add Customer | CustomerModel | Create a new customer for a business.
+ /// TEST URL: https://localhost:7092/api/Customer/CreateCustomer
///
///
///
[HttpPost]
public async Task CreateCustomerAsync([FromBody] CustomerModel model)
{
- return Ok(_customerService.CreateCustomerAsync(model));
+ var result = await _customerService.CreateCustomerAsync(model);
+ return Ok(result);
//return Ok("UNDER CONTRUCTION | CreateCustomerAsync([FromBody] Customer model)");
}
#endregion
@@ -141,74 +138,59 @@ public async Task CreateCustomerAsync([FromBody] CustomerModel mo
- //// PUT - CREATE: api/Customer/5
- //// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
- //[HttpPut("{id}")]
-
- //[HttpPost]
- //public async Task PutCustomer(int id, Customer customer)
- //{
- // if (id != customer.CustomerID)
- // {
- // return BadRequest();
- // }
-
- // _context.Entry(customer).State = EntityState.Modified;
-
- // try
- // {
- // await _context.SaveChangesAsync();
- // }
- // catch (DbUpdateConcurrencyException)
- // {
- // if (!CustomerExists(id))
- // {
- // return NotFound();
- // }
- // else
- // {
- // throw;
- // }
- // }
-
- // return NoContent();
- //}
-
- //// POST: api/Customer
- //// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
- //[HttpPost]
- //public async Task> PostCustomer(Customer customer)
- //{
- // _context.Customers.Add(customer);
- // await _context.SaveChangesAsync();
-
- // return CreatedAtAction("GetCustomer", new { id = customer.CustomerID }, customer);
- //}
-
-
- //// DELETE: api/Customer/5
- //[HttpDelete("{id}")]
- //public async Task DeleteCustomer(int id)
- //{
- // var customer = await _context.Customers.FindAsync(id);
- // if (customer == null)
- // {
- // return NotFound();
- // }
-
- // _context.Customers.Remove(customer);
- // await _context.SaveChangesAsync();
-
- // return NoContent();
- //}
-
- //private bool CustomerExists(int id)
- //{
- // return _context.Customers.Any(e => e.CustomerID == id);
- //}
+ #region Edit Customer
+ ///
+ /// EDIT: Edit a Customer | CustomerViewModel | edit a customer for a business in a VM for web UI.
+ /// TEST URL: |
+ /// "CustomerControllerEditCustomerVMAsync": "Customer/EditCustomerVMAsync",
+ ///
+ ///
+ /// SaveViewModel
+ [HttpPost]
+ public async Task EditCustomerVMAsync([FromBody] CustomerViewModel vm)
+ {
+ // if model is valid, then update, else return bad request with model state errors.
+ var result = await _customerService.EditCustomerVMAsync(vm);
+ return Ok(result);
+ //return Ok("UNDER CONTRUCTION | EditCustomer(int id, [FromBody] Customer model)");
+ }
+
+
+ ///
+ /// EDIT: Customer | CustomerModel | edit a customer for a business.
+ /// TEST URL: https://localhost:7092/api/Customer/EditCustomer?id=5
+ /// "CustomerControllerEditCustomer": "Customer/EditCustomer"
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task EditCustomer([FromBody] CustomerModel model)
+ {
+ // if model is valid, then update, else return bad request with model state errors.
+ var result = await _customerService.EditCustomer(model);
+ return Ok(result);
+ }
+
+ // CustomerModel to just return a CustomerModel instead of a SaveViewModel with the RefID. We could do this for the VM as well.
+ #endregion
- }
+
+ #region Delete Customer
+ ///
+ /// DELETE: Customer | SaveViewModel | delete a customer for a business and return a SaveViewModel with the RefID of the deleted customer.
+ /// "CustomerControllerDeleteCustomerVMAsync": "Customer/DeleteCustomerVMAsync"
+ ///
+ ///
+ /// SaveViewModel
+ [HttpDelete("{CustomerID:int}")]
+ public async Task DeleteCustomerVMAsync(int CustomerID)// LOOK AT ALL THESE IN CONTROLLER COMPAARED TO LICENSE API, WE JUST USE ACTION RESULT HERE AND RETURN THE MODEL THAT IS IN THE SERVICE.
+ {
+ var result = await _customerService.DeleteCustomerVMAsync(CustomerID);
+ return Ok(result);
+ }
+ #endregion
+ }
}
diff --git a/MBDEVproAPI.API/GlobalUsings.cs b/MBDEVproAPI.API/GlobalUsings.cs
index 1fb1a1e..ea436fa 100644
--- a/MBDEVproAPI.API/GlobalUsings.cs
+++ b/MBDEVproAPI.API/GlobalUsings.cs
@@ -23,5 +23,6 @@
//global using Microsoft.OpenApi.Models;
global using Serilog;
global using Serilog.Formatting.Json;
-global using Microsoft.OpenApi;
+global using Microsoft.OpenApi;
+global using Scalar.AspNetCore;
diff --git a/MBDEVproAPI.API/MBDEVproAPI.API.csproj b/MBDEVproAPI.API/MBDEVproAPI.API.csproj
index f2b34cb..ab80dc1 100644
--- a/MBDEVproAPI.API/MBDEVproAPI.API.csproj
+++ b/MBDEVproAPI.API/MBDEVproAPI.API.csproj
@@ -7,15 +7,15 @@
-
-
-
-
-
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
@@ -23,8 +23,10 @@
-
-
+
+
+
+
diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs
index 605712f..c9b8cd6 100644
--- a/MBDEVproAPI.API/Program.cs
+++ b/MBDEVproAPI.API/Program.cs
@@ -1,7 +1,12 @@
+var builder = WebApplication.CreateBuilder(args);
+var logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(builder.Configuration)
+ .Enrich.FromLogContext()
+ .CreateLogger();
+builder.Host.UseSerilog(logger);
+
-using Scalar.AspNetCore;
-var builder = WebApplication.CreateBuilder(args);
//DATABASE CONNECTION
builder.Services.AddDbContext(options =>
@@ -41,20 +46,37 @@
});
});
-
+//ADD: API security and authentication (OAuth2, OpenID Connect, JWT)
var app = builder.Build();
+app.UseSerilogRequestLogging();
+
+
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
- app.MapOpenApi(); // Expose the OpenAPI JSON endpoint
- app.MapScalarApiReference(); // Map the Scalar UI endpoint
+ //app.MapOpenApi(); // Expose the OpenAPI JSON endpoint
+ //app.MapScalarApiReference(); // Map the Scalar UI endpoint
+
+ app.MapOpenApi();
+ app.MapScalarApiReference();
+ //app.MapScalarApiReference(options =>
+ //{
+ // options.Title = "MBDEVproAPI v1 .NET CORE 10";
+ // options.WithTheme(ScalarTheme.Moon); // Use a specific theme
+ // options.ForceDarkMode(); // Force dark mode
+ //});
+
+ // Automatically redirect to Scalar documentation
+ //app.MapGet("/", () => Results.Redirect("/scalar"));
Log.Information("MBDEVproAPI: (Development Environment)");
app.UseDeveloperExceptionPage();
}
+
+
if (app.Environment.EnvironmentName == "Test")
{
Log.Information("MBDEVproAPI: Test Environment)");
@@ -70,31 +92,29 @@
Log.Information("MBDEVproAPI: Production Environment)");
}
-if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName == "Test")
-{
- app.UseSwagger();
- app.UseSwaggerUI(c =>
- {
- //c.SwaggerEndpoint("/MBDEVproAPI/swagger/v1/swagger.json", "MBDEVproAPI v1 .NET CORE 10");
- c.SwaggerEndpoint("../swagger/v1/swagger.json", "MBDEVproAPI v1 .NET CORE 10");
- // ENDPOINTS: https://localhost:7092/swagger/index.html
- // JSON: https://localhost:7092/swagger/v1/swagger.json
- });
-}
-
-app.MapScalarApiReference(options =>
-{
- options.Title = "MBDEVproAPI v1 .NET CORE 10";
- options.WithTheme(ScalarTheme.Moon); // Use a specific theme
- options.ForceDarkMode(); // Force dark mode
-});
+//if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName == "Test")
+//{
+// //app.UseSwagger();
+// //app.UseSwaggerUI(c =>
+// //{
+// // //c.SwaggerEndpoint("/MBDEVproAPI/swagger/v1/swagger.json", "MBDEVproAPI v1 .NET CORE 10");
+// // c.SwaggerEndpoint("../swagger/v1/swagger.json", "MBDEVproAPI v1 .NET CORE 10");
+// // // ENDPOINTS: https://localhost:7092/swagger/index.html
+// // // JSON: https://localhost:7092/swagger/v1/swagger.json
+// //});
+//}
+Log.Information("MBDEVproAPI: (Development Environment)");
+app.UseSerilogRequestLogging(); // Add Serilog request logging middleware
+app.UseDeveloperExceptionPage(); // For local only, can change later for testing and production environments, can also add custom error handling middleware for production environment.
//Middleware
app.UseHttpsRedirection();
+app.UseStaticFiles();
+
app.UseAuthorization();
app.MapControllers();
diff --git a/MBDEVproAPI.API/appsettings.Development.json b/MBDEVproAPI.API/appsettings.Development.json
index 720c196..186a07e 100644
--- a/MBDEVproAPI.API/appsettings.Development.json
+++ b/MBDEVproAPI.API/appsettings.Development.json
@@ -1,14 +1,12 @@
{
"ConnectionStrings": {
- //"DefaultConnection": "Server=ComputerPro7.local;Database=MBDEVproDB;Trusted_Connection=True;MultipleActiveResultSets=true",
- // Use Secrets if passwords and so on...
- "DefaultConnection": "Server=COMPUTERPRO7\\MSSQLSERVER2025;Initial Catalog=MBDEVproDB;Integrated Security=True;Encrypt=False;Trust Server Certificate=True"
+ "DefaultConnection": "Server=COMPUTERPRO7\\MSSQLSERVER2025;Initial Catalog=MBDEVproDB;Integrated Security=True;Encrypt=False;Trust Server Certificate=True"
},
"APISettings": {
//"APIUrl": "https://localhost:7092/api/Customer/",
//"AuthenticateUrl": "Account/Login",
- //"ProjectID": "0",
+ //"BusinessID": "0",
//"IsUserExist": "Account/IsUserExist"
},
@@ -16,7 +14,7 @@
"DefaultProjectSettings": {
"ProjectName": "MBDEVproAPI",
"Description": "MBDEVproAPI version .NET CORE 10",
- "DefaultFinishInspectionsStatus": "COMPLETED",
+ "SomeKey": "xcxc",
"SessionTimeout": "900000",
"ApplicationURL": "https://www.google.com",
"JSReport_TimeOutValue": "200000000",
@@ -35,26 +33,37 @@
"BaseUri": "https://localhost:7092/api/Customer/",
"ValidateTokenUri": "Auth/ValidateAppAccessToken"
},
- "AllowedHosts": "*",
- "Serilog": {
- "Using": [ "Serilog.Exceptions" ],
- "MinimumLevel": {
- "Default": "Debug",
- "Override": {
- "Microsoft": "Warning",
- "System": "Warning"
- }
- },
- "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId", "WithExceptionDetails" ],
- "WriteTo": [
- {
- "Name": "ApplicationInsights",
- "Args": {
- "connectionString": "InstrumentationKey=xxxxx;IngestionEndpoint=https://MBDEVproAPI.applicationinsights.azure.com/;LiveEndpoint=https://MBDEVproAPI.livediagnostics.monitor.azure.com/;ApplicationId=xxxxx",
- "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
+ "HttpsRedirection": {
+ "Enabled": true,
+ "SSLPort": 443
+ },
+ "AllowedHosts": "*",
+ "Serilog": {
+ "Using": [ "Serilog.Exceptions" ],
+ "MinimumLevel": {
+ "Default": "Debug",
+ "Override": {
+ "Microsoft": "Warning",
+ "System": "Warning"
}
- }
-
- ]
- }
-}
\ No newline at end of file
+ },
+ "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId", "WithExceptionDetails" ],
+ "WriteTo": [
+ { "Name": "Console" },
+ {
+ "Name": "File",
+ "Args": {
+ "path": "X:\\Logs\\MBDEVpro\\MBDEVproAPI\\Development\\log.txt",
+ "outputTemplate": "{Timestamp:G} {Message}{NewLine:1}{Exception:1}"
+ }
+ },
+ {
+ "Name": "File",
+ "Args": {
+ "path": "X:\\Logs\\MBDEVpro\\MBDEVproAPI\\Development\\log.json",
+ "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
+ }
+ }
+ ]
+ }
+ }
\ No newline at end of file
diff --git a/MBDEVproAPI.API/appsettings.json b/MBDEVproAPI.API/appsettings.json
index 10f68b8..8c3ffb4 100644
--- a/MBDEVproAPI.API/appsettings.json
+++ b/MBDEVproAPI.API/appsettings.json
@@ -5,5 +5,9 @@
"Microsoft.AspNetCore": "Warning"
}
},
+ "HttpsRedirection": {
+ "Enabled": true,
+ "SSLPort": 443
+ },
"AllowedHosts": "*"
}
diff --git a/MBDEVproAPI.API/dotnet-tools.json b/MBDEVproAPI.API/dotnet-tools.json
new file mode 100644
index 0000000..b6f4c2f
--- /dev/null
+++ b/MBDEVproAPI.API/dotnet-tools.json
@@ -0,0 +1,13 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-ef": {
+ "version": "10.0.5",
+ "commands": [
+ "dotnet-ef"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/MBDEVproAPI.BLL/GlobalUsings.cs b/MBDEVproAPI.BLL/GlobalUsings.cs
index 34e3816..b00585a 100644
--- a/MBDEVproAPI.BLL/GlobalUsings.cs
+++ b/MBDEVproAPI.BLL/GlobalUsings.cs
@@ -20,3 +20,4 @@
global using MBDEVproAPI.DataModel;
global using MBDEVproAPI.DataModel.Entities;
global using MBDEVproAPI.Repository.Interfaces;
+global using MBDEVproAPI.Repository.Repositories;
diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs
index b64b4a4..f8a90a1 100644
--- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs
+++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs
@@ -8,23 +8,43 @@ namespace MBDEVproAPI.BLL.Interfaces
public interface ICustomerService : IBaseService
{
+
+ #region
+ #endregion
+
+
+
+ #region Get All Customers
Task GetAllCustomersVMAsync(int BusinessID);
Task> GetAllCustomersAsync(int BusinessID);
+ #endregion
+ #region Get Customer
Task GetCustomerAsync(int CustomerID);
+ #endregion
+
+ #region Add Customer
Task CreateCustomerVMAsync(CustomerViewModel vm);
Task CreateCustomerAsync(CustomerModel model);
+
+ SaveViewModel CreateCustomer(CustomerModel model);
+ #endregion
- SaveViewModel CreateCustomer(CustomerModel model);
+ #region Edit Customer
+ Task EditCustomerVMAsync(CustomerViewModel vm);
- SaveViewModel EditCustomer(int id, CustomerModel model);
+ Task EditCustomer(CustomerModel model);
+ #endregion
- SaveViewModel DeleteCustomer(int id);
+ #region Delete Customer
+ Task DeleteCustomerVMAsync(int CustomerID);
+ Task DeleteCustomer(int CustomerID);
+ #endregion
}
}
diff --git a/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj
index 1cb3782..de74504 100644
--- a/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj
+++ b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj
@@ -7,7 +7,7 @@
-
+
@@ -16,6 +16,8 @@
+
+
diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs
index 93c4c29..74028ca 100644
--- a/MBDEVproAPI.BLL/Services/CustomerService.cs
+++ b/MBDEVproAPI.BLL/Services/CustomerService.cs
@@ -35,9 +35,17 @@ public CustomerService(MBDEVproAPIDbContext context, ICustomerRepository custome
#endregion
- #region Get All Customers | CustomerViewModel
+
+ #region
+ #endregion
+
+
+
+ #region Get All Customers
///
- /// GET: Gets all customers for a business in a VM for web UI.
+ /// GET: Get All Customers | CustomerViewModel | Gets all customers for a business in a VM for web UI.
+ /// TEST URL: https://localhost:7092/api/Customer/GetAllCustomers/52466 | https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466
+ /// "CustomerControllerGetAllCustomersVMAsync": "Customer/GetAllCustomersVMAsync",
///
///
///
@@ -69,10 +77,14 @@ public async Task GetAllCustomersVMAsync(int BusinessID)
return new CustomerViewModel();
}
}
- #endregion
-
- #region Get All Customers | CustomerModel
+ ///
+ /// GET: Get All Customers | CustomerModel | Gets all customers for a business.
+ /// TEST URL: https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466
+ /// "CustomerControllerGetAllCustomersAsync": "Customer/GetAllCustomersAsync",
+ ///
+ ///
+ ///
public async Task> GetAllCustomersAsync(int BusinessID)
{
try
@@ -104,35 +116,11 @@ public async Task> GetAllCustomersAsync(int BusinessI
#endregion
- //public IEnumerable GetAll()
- //{
- // try
- // {
- // var entities = _projectRepository.GetAll().Select(O => Mapper.MapObject(O, new ProjectModel())).ToList();
- // if (entities == null)
- // {
- // throw new Exception("Licensing API: ProjectService(GetAll); (entities == null");
- // }
- // else
- // {
- // return entities;
- // }
- // }
- // catch (Exception ex)
- // {
- // ex.Data.Add("ErrorMessage", "Licensing API: ProjectService(GetAll)");
- // throw;
- // }
- //}
-
-
-
-
-
- #region Get Customer | Customer
- //GetCustomerAsync
+ #region Get Customer
///
- /// GET: Gets a customer for a business.
+ /// GET: Get Customer | Customer | Gets a customer for a business.
+ /// TEST URL: https://localhost:7092/api/Customer/GetCustomer/3 | https://localhost:7092/api/Customer/GetCustomer?CustomerID=3
+ /// "CustomerControllerGetCustomer": "Customer/GetCustomer",
///
///
///
@@ -167,12 +155,9 @@ public async Task> GetAllCustomersAsync(int BusinessI
-
-
-
- #region Add Customer | CustomerViewModel
+ #region Add Customer
///
- /// Create a new customer for a business from client web application using a CustomerViewModel.
+ /// Add Customer | CustomerViewModel | Create a new customer for a business from client web application using a CustomerViewModel.
///
///
///
@@ -218,13 +203,9 @@ public async Task CreateCustomerVMAsync(CustomerViewModel vm)
{
}
}
- #endregion
-
- #region Add Customer | Customer
///
- /// CREATE: Customer
- /// "CustomerControllerCreateCustomerAsync": "Customer/CreateCustomerAsync"
+ /// Add Customer | CustomerModel | Create a new customer for a business.
///
///
///
@@ -239,7 +220,7 @@ public async Task CreateCustomerAsync(CustomerModel model)
}
else
{
- var entity = new DataModel.Entities.Customer();
+ var entity = new DataModel.Entities.Customer();
if (entity == null)
{
Log.Error("Customer API: CustomerService(CreateCustomerAsync); (entity == null)");
@@ -269,23 +250,7 @@ public async Task CreateCustomerAsync(CustomerModel model)
{
}
-
-
}
- #endregion
-
-
-
- /////
- ///// GET: Customer
- ///// "CustomerControllerGetCustomer": "Customer/GetCustomer"
- /////
- /////
- /////
- //public CustomerModel GetCustomer(int id)
- //{
- // throw new NotImplementedException();
- //}
///
/// CREATE: Customer
@@ -297,31 +262,207 @@ public SaveViewModel CreateCustomer(CustomerModel model)
{
throw new NotImplementedException();
}
+ #endregion
+
+
+
+ #region Edit Customer
+ ///
+ /// EDIT: Edit a Customer | CustomerViewModel | edit a customer for a business in a VM for web UI.
+ /// TEST URL: |
+ /// "CustomerControllerEditCustomerVMAsync": "Customer/EditCustomerVMAsync",
+ ///
+ ///
+ /// SaveViewModel
+ public async Task EditCustomerVMAsync(CustomerViewModel vm)
+ {
+ try
+ {
+ if (vm == null || vm.CustomerID == 0 || vm.BusinessID == 0)
+ {
+ Log.Error("Customer API: CustomerService(EditCustomerVMAsync); (vm == null || vm.CustomerID == 0 || vm.BusinessID == 0)");
+ return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer." };
+ }
+ else
+ {
+ var entity = await _customerRepository.GetCustomerAsync(vm.CustomerID);
+ if (entity == null)
+ {
+ Log.Error("Customer API: CustomerService(EditCustomerVMAsync); (entity == null)");
+ return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer. (entity == null)" };
+ }
+ else
+ {
+ int? refID;
+ using (TransactionScope scope = new TransactionScope())
+ {
+ Mapper.MapObject(vm, entity);
+ _customerRepository.SaveChanges();
+ refID = entity.CustomerID;
+ scope.Complete();
+ }
+ return new SaveViewModel(refID);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Customer API: CustomerService(EditCustomerVMAsync); (" + ex + ")" + " (" + ex.InnerException + ")");
+ return new SaveViewModel(ex.Message);
+ }
+ finally
+ {
+ }
+ }
///
- /// EDIT: Customer
+ /// EDIT: Customer | CustomerModel | edit a customer for a business.
/// "CustomerControllerEditCustomer": "Customer/EditCustomer"
///
///
///
- public SaveViewModel EditCustomer(int id, CustomerModel model)
+ public async Task EditCustomer(CustomerModel model)
{
- throw new NotImplementedException();
+ try
+ {
+ if (model == null || model.CustomerID == 0 || model.BusinessID == 0)
+ {
+ Log.Error("Customer API: CustomerService(EditCustomer) CustomerModel; (model == null || model.CustomerID == 0 || model.BusinessID == 0)");
+ return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer. Null Values" };
+ }
+ else
+ {
+ var entity = await _customerRepository.GetCustomerAsync(model.CustomerID);
+ if (entity == null)
+ {
+ Log.Error("Customer API: CustomerService(EditCustomer) CustomerModel; (entity == null)");
+ return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer." };
+ }
+ else
+ {
+ int? refID;
+ refID = entity.CustomerID;
+ using (TransactionScope scope = new TransactionScope())
+ {
+ Mapper.MapObject(model, entity);
+ _customerRepository.SaveChanges();
+ //refID = entity.CustomerID;
+ scope.Complete();
+ }
+ return new SaveViewModel(refID);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Customer API: CustomerService(EditCustomer) CustomerModel; (" + ex + ")" + " (" + ex.InnerException + ")");
+ return new SaveViewModel(ex.Message);
+ }
+ finally
+ {
+ }
}
+ // CustomerModel to just return a CustomerModel instead of a SaveViewModel with the RefID. We could do this for the VM as well.
+ #endregion
+
+
+
+ #region Delete Customer
///
- /// DELETE: Customer
- /// "CustomerControllerDeleteCustomer": "Customer/DeleteCustomer"
+ /// DELETE: Customer | SaveViewModel | delete a customer for a business and return a SaveViewModel with the RefID of the deleted customer.
+ /// "CustomerControllerDeleteCustomerVM": "Customer/DeleteCustomerVM"
///
///
- ///
- public SaveViewModel DeleteCustomer(int id)
+ /// SaveViewModel
+ public async Task DeleteCustomerVMAsync(int CustomerID)
{
- throw new NotImplementedException();
+ try
+ {
+ int? refID = null;
+ if (CustomerID == 0)
+ {
+ Log.Error("Customer API: CustomerService(DeleteCustomerVMAsync); (CustomerID == 0)");
+ return new SaveViewModel("Please provide details to delete the Customer.");
+ }
+ else
+ {
+ var entity = await _customerRepository.GetCustomerAsync(CustomerID);
+
+ if (entity == null)
+ {
+ Log.Error("Customer API: CustomerService(DeleteCustomerVMAsync); (entity == null)");
+ return new SaveViewModel("Please provide details to delete the Customer.");
+ }
+ else
+ {
+ using (TransactionScope scope = new TransactionScope())
+ {
+ _customerRepository.Remove(entity);
+ _customerRepository.SaveChanges();
+ scope.Complete();
+ refID = entity.CustomerID;
+ }
+ return new SaveViewModel(refID);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Customer API: CustomerService(DeleteCustomerVMAsync); (" + ex + ")" + " (" + ex.InnerException + ")");
+ return new SaveViewModel("Customer API: CustomerService(DeleteCustomerVMAsync); (" + ex + ")" + " (" + ex.InnerException + ") Message: " + ex.Message);
+ }
+ finally
+ {
+ }
}
+ ///
+ /// DELETE: Customer | CustomerModel | delete a customer for a business.
+ /// "CustomerControllerDeleteCustomer": "Customer/DeleteCustomer"
+ ///
+ ///
+ /// SaveViewModel
+ public async Task DeleteCustomer(int CustomerID)
+ { // More to do here
+ if (CustomerID == 0)
+ {
+ Log.Error("Customer API: CustomerService(DeleteCustomer); (CustomerID == 0)");
+ return new CustomerModel();
+ }
+ else {
+ var entity = await _customerRepository.GetCustomerAsync(CustomerID);
+ if (entity == null)
+ {
+ Log.Error("Customer API: CustomerService(DeleteCustomer); (entity == null)");
+ return new CustomerModel();
+ }
+ else
+ {
+ int? refID = null;
+ using (TransactionScope scope = new TransactionScope())
+ {
+ _customerRepository.Remove(entity);
+ _customerRepository.SaveChanges();
+ scope.Complete();
+ refID = entity.CustomerID;
+ }
+ return Mapper.MapObject(entity, new CustomerModel());
+ }
+ }
+ }
+ #endregion
+
+
+
+
+
+
+
+ #region Other
+ #endregion
}
}
diff --git a/MBDEVproAPI.Repository/Class1.cs b/MBDEVproAPI.Repository/Class1.cs
deleted file mode 100644
index ddcf26a..0000000
--- a/MBDEVproAPI.Repository/Class1.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace MBDEVproAPI.Repository
-{
- public class Class1
- {
-
- }
-}
diff --git a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs
index c71309e..5113e2d 100644
--- a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs
+++ b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs
@@ -15,7 +15,7 @@ public interface IBaseRepository
///
///
///
- void Remove(int BusinessID, T obj);
+ void Remove(T obj);
///
///
diff --git a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs
index 13f9d7a..659c22b 100644
--- a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs
+++ b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs
@@ -5,12 +5,39 @@ namespace MBDEVproAPI.Repository.Interfaces
public interface ICustomerRepository : IBaseRepository
{
+ #region
+ #endregion
+
+
+
+ #region Get All Customers
Task> GetAllCustomersVMAsync(int BusinessID);
Task> GetAllCustomersAsync(int BusinessID);
+ #endregion
+
+
+ #region Get Customer
Task GetCustomerAsync(int CustomerID);
+ #endregion
+
+
+
+ #region Add Customer
+ #endregion
+
+
+
+ #region Edit Customer
+ #endregion
+
+
+
+ #region Delete Customer
+ public void DeleteCustomerVM(Customer obj);
+
+ #endregion
- Task AddAsync(Customer customer);
}
}
diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs
index 1ba6559..34cca35 100644
--- a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs
+++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs
@@ -29,26 +29,27 @@ public CustomerRepository(MBDEVproAPIDbContext context)
+ #region
+ #endregion
-
-
- #region Get All Customers | CustomerViewModel
+ #region Get All Customers
///
- /// GET: Get All Customers Async
+ /// GET: Get All Customers | CustomerViewModel | Gets all customers for a business in a VM for web UI.
///
///
- ///
+ /// customers
public async Task> GetAllCustomersVMAsync(int BusinessID)
{
var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync();
return customers;
}
- #endregion
-
- #region Get All Customers | CustomerModel
+ /// GET: Get All Customers | CustomerModel | Gets all customers for a business.
+ ///
+ ///
+ /// customer
public async Task> GetAllCustomersAsync(int BusinessID)
{
var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync();
@@ -57,7 +58,13 @@ public async Task> GetAllCustomersAsync(int BusinessID)
#endregion
- #region Get All Customers | Customer
+
+ #region Get Customer
+ ///
+ /// GET: Get Customer | Customer | Gets a customer for a business.
+ ///
+ ///
+ ///
public async Task GetCustomerAsync(int CustomerID)
{
var customer = await _context.Customers.Where(O => O.CustomerID == CustomerID).FirstOrDefaultAsync();
@@ -75,69 +82,54 @@ public async Task GetCustomerAsync(int CustomerID)
- #region Add Customer Async
- public async Task AddAsync(Customer customer)
+ #region Add Customer
+ public void Add(Customer obj)
{
- await _context.Customers.AddAsync(customer);
- await _context.SaveChangesAsync(); // Non-blocking save
+ _context.Customers.Add(obj);
}
#endregion
+ #region Edit Customer
+ #endregion
- #region other
- public IEnumerable GetAll(int BusinessID)
+ #region Delete Customer
+ //Task DeleteCustomerVM(int CustomerID);
+ public void DeleteCustomerVM(Customer obj)
{
- var customers = _context.Customers.Where(O => O.BusinessID == BusinessID).ToList();
-
- return customers;
+ _context.Customers.Remove(obj);
}
- /////
- ///// Get a single record by ID
- /////
- /////
- /////
- /////
- public Customer GetByID(int BusinessID, int? id)
+ public void Remove(Customer obj)
{
- var customer = _context.Customers.Where(O => O.BusinessID == BusinessID && O.CustomerID == id).FirstOrDefault();
-
- if (customer == null)
- {
- throw new Exception("Customer not found");
- }
- else
- {
- return customer;
- }
+ _context.Customers.Remove(obj);
}
+ #endregion
- public void Add(Customer obj)
+ #region Save Customer
+ public void SaveChanges()
{
- _context.Customers.Add(obj);
+ _context.SaveChanges();
}
+ #endregion
+
- public void Remove(int BusinessID, Customer obj)
+
+ #region Other
+ public Customer GetByID(int BusinessID, int? id)
{
throw new NotImplementedException();
}
- public void SaveChanges()
+ public IEnumerable GetAll(int BusinessID)
{
- _context.SaveChanges();
+ throw new NotImplementedException();
}
-
-
-
-
#endregion
-
-
}
}
diff --git a/MBDEVproAPI.Tests/CustomerTests.cs b/MBDEVproAPI.Tests/CustomerTests.cs
new file mode 100644
index 0000000..fce719d
--- /dev/null
+++ b/MBDEVproAPI.Tests/CustomerTests.cs
@@ -0,0 +1,147 @@
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
+
+namespace MBDEVproAPI.Tests
+{
+ public class CustomerTests
+ {
+
+ #region Variables and Constructors
+
+ private ICustomerService _customerService;
+
+ #endregion
+
+ public CustomerTests(ICustomerService customerService) {
+
+ _customerService = customerService;
+
+ }
+
+
+ //using MBDEVproAPI.DataModel.Entities;
+ private static readonly List _customerListEntity = new()
+ { new Customer { CustomerID = 1, BusinessID = 52466, Company = "cheeseburger", FirstName = "Jeff", LastName = "Smith", Email = "Jeff@Smith.com", Address = "123 Test St" }
+ };
+
+
+ //using MBDEVproAPI.Common.Models;
+ private static readonly List _customerListModel = new()
+ { new CustomerModel { CustomerID = 1, BusinessID = 52466, Company = "cheeseburger", FirstName = "Jeff", LastName = "Smith", Email = "Jeff@Smith.com", Address = "123 Test St" }
+ };
+
+
+ #region commented out code
+ //public int CustomerID { get; set; }
+ //public int BusinessID { get; set; }
+
+ //public string? Company { get; set; }
+ //public string FirstName { get; set; } = String.Empty;
+ //public string LastName { get; set; } = String.Empty;
+
+ //public string Email { get; set; } = String.Empty;
+
+ //public string? Title { get; set; }
+ //public string? BPhone { get; set; }
+ //public string? HPhone { get; set; }
+ //public string? MPhone { get; set; }
+ //public string? Fax { get; set; }
+
+ //public string Address { get; set; } = String.Empty;
+ //public string City { get; set; } = String.Empty;
+ //public string State { get; set; } = String.Empty;
+ //public string ZIPCode { get; set; } = String.Empty;
+ //public string Country { get; set; } = String.Empty;
+
+ //public string? WebPage { get; set; }
+ //public string? Notes { get; set; }
+ //public string? Photo { get; set; }
+ //public string? Map { get; set; }
+
+ //public CustomerTests()
+ //{
+ // var mock = new Mock();
+ // mock.Setup(s => s.GetCustomerAsync(It.IsAny()))
+ // .ReturnsAsync((int id) => _customerListEntity.FirstOrDefault(c => c.CustomerID == id) ?? new Customer());
+ // mock.Setup(s => s.GetAllCustomersVMAsync(It.IsAny()))
+ // .ReturnsAsync((int businessId) => new CustomerViewModel { CustomerList = _customerListEntity.Select(x => Mapper.MapObject(x, new CustomerModel())).ToList() });
+ // _customerService = mock.Object;
+ //}
+
+
+ //public class CustomerTests
+ //{
+ // private ICustomerService _customerService;
+
+ // public CustomerTests()
+ // {
+ // _customerService = new TestCustomerService();
+ // }
+
+ // private static readonly List _customerListEntity = new()
+ // {
+ // new Customer { CustomerID = 1, BusinessID = 52466, Company = "cheeseburger", FirstName = "Jeff", LastName = "Smith", Email = "Jeff@Smith.com", Address = "123 Test St" }
+ // };
+
+ // // Simple test-only implementation
+ // private class TestCustomerService : ICustomerService
+ // {
+ // public Task GetCustomerAsync(int CustomerID)
+ // {
+ // var c = _customerListEntity.FirstOrDefault(x => x.CustomerID == CustomerID);
+ // return Task.FromResult(c ?? new Customer());
+ // }
+
+ // public Task GetAllCustomersVMAsync(int BusinessID)
+ // {
+ // var vm = new CustomerViewModel { CustomerList = _customerListEntity.Select(x => Mapper.MapObject(x, new CustomerModel())).ToList() };
+ // return Task.FromResult(vm);
+ // }
+
+ // // Implement other members of ICustomerService as no-op or throw NotImplementedException
+ // // ...
+ // }
+
+ // // tests follow...
+ //}
+ #endregion
+
+
+
+ #region Tests
+
+ [Fact]
+ public async Task GetCustomerAsync()
+ {
+ var customer = await _customerService.GetCustomerAsync(3);
+ Assert.NotNull(customer);
+ }
+
+ [Theory]
+ [InlineData(1)]
+ [InlineData(2)]
+ [InlineData(3)]
+ [InlineData(4)]
+ [InlineData(5)]
+ public async Task GetCustomerAsyncID(int id)
+ {
+ var customer = await _customerService.GetCustomerAsync(id);
+ Assert.NotNull(customer);
+ }
+
+
+ [Theory]
+ [InlineData(52466)]
+ public async Task GetAllCustomersVMAsyncTest(int id)
+ {
+ var customers = await _customerService.GetAllCustomersVMAsync(id);
+ Assert.NotNull(customers);
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/MBDEVproAPI.Tests/GlobalUsings.cs b/MBDEVproAPI.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..7f3ce43
--- /dev/null
+++ b/MBDEVproAPI.Tests/GlobalUsings.cs
@@ -0,0 +1,27 @@
+global using System;
+global using System.Collections.Generic;
+//global using MBDEVproAPI.BLL.Interfaces;
+//global using MBDEVproAPI.BLL.Services;
+global using MBDEVproAPI.Common.Models;
+global using MBDEVproAPI.Common.ViewModels;
+global using MBDEVproAPI.BLL.Interfaces;
+global using MBDEVproAPI.BLL.Services;
+global using MBDEVproAPI.DataModel;
+global using MBDEVproAPI.DataModel.Entities;
+global using MBDEVproAPI.Repository.Interfaces;
+global using MBDEVproAPI.Repository.Repositories;
+global using Microsoft.AspNetCore.Authorization;
+global using Microsoft.AspNetCore.Builder;
+global using Microsoft.AspNetCore.Hosting;
+global using Microsoft.AspNetCore.Http;
+global using Microsoft.AspNetCore.Mvc;
+global using Microsoft.AspNetCore.Mvc.Filters;
+global using Microsoft.EntityFrameworkCore;
+global using Microsoft.Extensions.Configuration;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.Extensions.Hosting;
+//global using Microsoft.OpenApi.Models;
+global using Serilog;
+global using Serilog.Formatting.Json;
+global using Microsoft.OpenApi;
+global using Scalar.AspNetCore;
\ No newline at end of file
diff --git a/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj b/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj
index b6e61fc..cec5f9c 100644
--- a/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj
+++ b/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj
@@ -8,10 +8,18 @@
-
-
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
diff --git a/MBDEVproAPI.Tests/UnitTest1.cs b/MBDEVproAPI.Tests/UnitTest1.cs
deleted file mode 100644
index dc26341..0000000
--- a/MBDEVproAPI.Tests/UnitTest1.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace MBDEVproAPI.Tests
-{
- public class UnitTest1
- {
- [Fact]
- public void Test1()
- {
-
- }
- }
-}
diff --git a/README.md b/README.md
index 4cde91b..4505254 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
-# MBDEVproAPI
\ No newline at end of file
+# MBDEVproAPI
+A .NET CORE 10 web api using N-Tier Architecture and the Repository Pattern.