From 9c1d4d347b51a145c6d6a4fda2a7ed938e356dba Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Tue, 17 Feb 2026 19:49:55 -0500 Subject: [PATCH 01/13] More Setup --- .../Controllers/CustomerController.cs | 184 +++++++++--------- MBDEVproAPI.API/GlobalUsings.cs | 3 + MBDEVproAPI.API/Program.cs | 5 +- MBDEVproAPI.BLL/GlobalUsings.cs | 4 +- MBDEVproAPI.BLL/Interfaces/IBaseService.cs | 9 + .../Interfaces/ICustomerService.cs | 2 +- MBDEVproAPI.BLL/Services/.gitkeep | 10 - MBDEVproAPI.BLL/Services/CustomerService.cs | 3 +- MBDEVproAPI.Common/Models/CustomerModel.cs | 2 +- MBDEVproAPI.DataModel/Entities/.gitkeep | 10 - MBDEVproAPI.DataModel/Entities/Customer.cs | 113 +++++++++++ MBDEVproAPI.DataModel/GlobalUsings.cs | 2 +- 12 files changed, 228 insertions(+), 119 deletions(-) create mode 100644 MBDEVproAPI.BLL/Interfaces/IBaseService.cs delete mode 100644 MBDEVproAPI.BLL/Services/.gitkeep delete mode 100644 MBDEVproAPI.DataModel/Entities/.gitkeep create mode 100644 MBDEVproAPI.DataModel/Entities/Customer.cs diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index e2cf31c..d079a8e 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -2,99 +2,105 @@ namespace MBDEVproAPI.API.Controllers { - [Route("api/[controller]")] - [ApiController] - public class CustomerController : ControllerBase + public class CustomerController : BaseController { - private readonly MBDEVproAPIDbContext _context; - public CustomerController(MBDEVproAPIDbContext context) - { - _context = context; - } - - // GET: api/Customer - [HttpGet] - public async Task>> GetCustomers() - { - return await _context.Customers.ToListAsync(); - } - - // GET: api/Customer/5 - [HttpGet("{id}")] - public async Task> GetCustomer(int id) - { - var customer = await _context.Customers.FindAsync(id); - - if (customer == null) - { - return NotFound(); - } - - return customer; - } - - // PUT: api/Customer/5 - // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 - [HttpPut("{id}")] - 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(); - } + #region variables and constructors + /*private readonly MBDEVproAPIDbContext _context*/ + private ICustomerService _customerService; - private bool CustomerExists(int id) + public CustomerController(ICustomerService customerService) { - return _context.Customers.Any(e => e.CustomerID == id); + _customerService = customerService; } + #endregion + + + + + + //// GET: api/Customer + //[HttpGet] + //public async Task>> GetCustomers() + //{ + // return await _context.Customers.ToListAsync(); + //} + + //// GET: api/Customer/5 + //[HttpGet("{id}")] + //public async Task> GetCustomer(int id) + //{ + // var customer = await _context.Customers.FindAsync(id); + + // if (customer == null) + // { + // return NotFound(); + // } + + // return customer; + //} + + //// PUT: api/Customer/5 + //// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 + //[HttpPut("{id}")] + //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); + //} } } diff --git a/MBDEVproAPI.API/GlobalUsings.cs b/MBDEVproAPI.API/GlobalUsings.cs index 482b018..13274d6 100644 --- a/MBDEVproAPI.API/GlobalUsings.cs +++ b/MBDEVproAPI.API/GlobalUsings.cs @@ -4,6 +4,9 @@ //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.Repository.Interfaces; //global using MBDEVproAPI.Repository.Repositories; global using Microsoft.AspNetCore.Authorization; diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index 7828818..871d399 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -1,4 +1,4 @@ -using MBDEVproAPI.DataModel; + var builder = WebApplication.CreateBuilder(args); @@ -6,7 +6,8 @@ builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); -//builder.Services.AddTransient(); +//IServiceCollection serviceCollection = builder.Services.AddTransient(); +builder.Services.AddTransient(); //builder.Services.AddScoped(); diff --git a/MBDEVproAPI.BLL/GlobalUsings.cs b/MBDEVproAPI.BLL/GlobalUsings.cs index bf01b9e..84d18eb 100644 --- a/MBDEVproAPI.BLL/GlobalUsings.cs +++ b/MBDEVproAPI.BLL/GlobalUsings.cs @@ -4,11 +4,9 @@ global using System.Linq; global using System.Reflection; global using System.Transactions; -//global using MBDEVproAPI.BLL.Interfaces; global using MBDEVproAPI.Common.Models; global using MBDEVproAPI.Common.ViewModels; -//global using MBDEVproAPI.Common.ViewModels.Shared; -//global using MBDEVproAPI.Repository.Interfaces; +global using MBDEVproAPI.BLL.Interfaces; global using Microsoft.AspNetCore.Http; global using Microsoft.Extensions.Caching.Memory; global using Microsoft.Extensions.Configuration; diff --git a/MBDEVproAPI.BLL/Interfaces/IBaseService.cs b/MBDEVproAPI.BLL/Interfaces/IBaseService.cs new file mode 100644 index 0000000..81c7477 --- /dev/null +++ b/MBDEVproAPI.BLL/Interfaces/IBaseService.cs @@ -0,0 +1,9 @@ + +namespace MBDEVproAPI.BLL.Interfaces +{ + public interface IBaseService + { + + + } +} diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index 8782c89..4ee6a3e 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -2,7 +2,7 @@ namespace MBDEVproAPI.BLL.Interfaces { - internal interface ICustomerService + public interface ICustomerService : IBaseService { } } diff --git a/MBDEVproAPI.BLL/Services/.gitkeep b/MBDEVproAPI.BLL/Services/.gitkeep deleted file mode 100644 index 83f9acf..0000000 --- a/MBDEVproAPI.BLL/Services/.gitkeep +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace MBDEVproAPI.BLL.Services -{ - class _ - { - } -} diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index c846008..8055f78 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -1,8 +1,7 @@  - namespace MBDEVproAPI.BLL.Services { - internal class CustomerService + public class CustomerService : ICustomerService { } } diff --git a/MBDEVproAPI.Common/Models/CustomerModel.cs b/MBDEVproAPI.Common/Models/CustomerModel.cs index df3459e..427adc9 100644 --- a/MBDEVproAPI.Common/Models/CustomerModel.cs +++ b/MBDEVproAPI.Common/Models/CustomerModel.cs @@ -1,7 +1,7 @@  namespace MBDEVproAPI.Common.Models { - public class Customer : BaseModel + public class CustomerModel : BaseModel { [Key] diff --git a/MBDEVproAPI.DataModel/Entities/.gitkeep b/MBDEVproAPI.DataModel/Entities/.gitkeep deleted file mode 100644 index 7646948..0000000 --- a/MBDEVproAPI.DataModel/Entities/.gitkeep +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace MBDEVproAPI.DataModel.Entities -{ - class _ - { - } -} diff --git a/MBDEVproAPI.DataModel/Entities/Customer.cs b/MBDEVproAPI.DataModel/Entities/Customer.cs new file mode 100644 index 0000000..8009ccb --- /dev/null +++ b/MBDEVproAPI.DataModel/Entities/Customer.cs @@ -0,0 +1,113 @@ + + +namespace MBDEVproAPI.DataModel.Entities +{ + /// + /// Customer Entity + /// + [Table("Customers")] + public partial class Customer /*: TrackHistoryTableAndTrigger*/ + { + public Customer() + { + + } + + [Key] + [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] + public int CustomerID { get; set; } + + //[Required] + //[Display(Name = "User name")] + //public string Username { get; set; } + + //[Required] + //[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + //[DataType(DataType.Password)] + //[Display(Name = "Password")] + //public string Password { get; set; } + + //[DataType(DataType.Password)] + //[Display(Name = "Confirm password")] + //[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] + //public string ConfirmPassword { get; set; } + + + [StringLength(50)] + [DataType(DataType.Text)] + public string? Company { get; set; } + + [Required] + [StringLength(25)] + [DataType(DataType.Text)] + public string FirstName { get; set; } = String.Empty; + + [Required] + [StringLength(25)] + [DataType(DataType.Text)] + public string LastName { get; set; } = String.Empty; + + [Required] + [StringLength(75)] + [DataType(DataType.EmailAddress)] + public string Email { get; set; } = String.Empty; + + [StringLength(50)] + [DataType(DataType.Text)] + public string? Title { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? BPhone { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? HPhone { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? MPhone { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? Fax { get; set; } + + [Required] + [StringLength(75)] + [DataType(DataType.Text)] + public string Address { get; set; } = String.Empty; + + [StringLength(75)] + [DataType(DataType.Text)] + public string City { get; set; } = String.Empty; + + [StringLength(75)] + [DataType(DataType.Text)] + public string State { get; set; } = String.Empty; + + [StringLength(15)] + [DataType(DataType.Text)] + public string ZIPCode { get; set; } = String.Empty; + + [StringLength(30)] + [DataType(DataType.Text)] + public string Country { get; set; } = String.Empty; + + [StringLength(75)] + [DataType(DataType.Text)] + public string? WebPage { get; set; } + + [StringLength(4010)] + [DataType(DataType.MultilineText)] + public string? Notes { get; set; } + + [StringLength(75)] + [DataType(DataType.Text)] + public string? Photo { get; set; } + + [StringLength(300)] + [DataType(DataType.Text)] + public string? Map { get; set; } + + } +} diff --git a/MBDEVproAPI.DataModel/GlobalUsings.cs b/MBDEVproAPI.DataModel/GlobalUsings.cs index 395301d..a42f47f 100644 --- a/MBDEVproAPI.DataModel/GlobalUsings.cs +++ b/MBDEVproAPI.DataModel/GlobalUsings.cs @@ -4,7 +4,7 @@ global using System.Linq; global using MBDEVproAPI.Common; global using MBDEVproAPI.Common.Models; -//global using MBDEVproAPI.DataModel.Entities; +global using MBDEVproAPI.DataModel.Entities; global using Microsoft.AspNetCore.Http; global using Microsoft.EntityFrameworkCore; global using Microsoft.Extensions.Configuration; From 906188144fd84ca46bb87edb9b9995624e359352 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Wed, 18 Feb 2026 19:43:01 -0500 Subject: [PATCH 02/13] Services and Repositories --- MBDEVproAPI.API/GlobalUsings.cs | 4 +- MBDEVproAPI.API/Program.cs | 1 + MBDEVproAPI.BLL/Interfaces/.gitkeep | 10 --- .../Interfaces/ICustomerService.cs | 14 ++++ MBDEVproAPI.BLL/Services/CustomerService.cs | 64 +++++++++++++++++++ MBDEVproAPI.Repository/GlobalUsings.cs | 4 +- MBDEVproAPI.Repository/Interfaces/.gitkeep | 10 --- .../Interfaces/IBaseRepository.cs | 39 +++++++++++ .../Interfaces/ICustomerRepository.cs | 11 ++++ MBDEVproAPI.Repository/Repositories/.gitkeep | 10 --- .../Repositories/BaseRepository.cs | 8 +++ .../Repositories/CustomerRepository.cs | 62 ++++++++++++++++++ 12 files changed, 203 insertions(+), 34 deletions(-) delete mode 100644 MBDEVproAPI.BLL/Interfaces/.gitkeep delete mode 100644 MBDEVproAPI.Repository/Interfaces/.gitkeep create mode 100644 MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs create mode 100644 MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs delete mode 100644 MBDEVproAPI.Repository/Repositories/.gitkeep create mode 100644 MBDEVproAPI.Repository/Repositories/BaseRepository.cs create mode 100644 MBDEVproAPI.Repository/Repositories/CustomerRepository.cs diff --git a/MBDEVproAPI.API/GlobalUsings.cs b/MBDEVproAPI.API/GlobalUsings.cs index 13274d6..5bd5db4 100644 --- a/MBDEVproAPI.API/GlobalUsings.cs +++ b/MBDEVproAPI.API/GlobalUsings.cs @@ -7,8 +7,8 @@ global using MBDEVproAPI.BLL.Interfaces; global using MBDEVproAPI.BLL.Services; global using MBDEVproAPI.DataModel; -//global using MBDEVproAPI.Repository.Interfaces; -//global using MBDEVproAPI.Repository.Repositories; +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; diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index 871d399..f7961ad 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -8,6 +8,7 @@ //IServiceCollection serviceCollection = builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); //builder.Services.AddScoped(); diff --git a/MBDEVproAPI.BLL/Interfaces/.gitkeep b/MBDEVproAPI.BLL/Interfaces/.gitkeep deleted file mode 100644 index 16e72ee..0000000 --- a/MBDEVproAPI.BLL/Interfaces/.gitkeep +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace MBDEVproAPI.BLL.Interfaces -{ - class _ - { - } -} diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index 4ee6a3e..1786f49 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -1,8 +1,22 @@  +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + namespace MBDEVproAPI.BLL.Interfaces { public interface ICustomerService : IBaseService { + + IEnumerable GetAllCustomers(); + + CustomerModel GetCustomer(int id); + + SaveViewModel CreateCustomer(CustomerModel model); + + SaveViewModel EditCustomer(int id, CustomerModel model); + + SaveViewModel DeleteCustomer(int id); + } } diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 8055f78..2d42bfe 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -1,7 +1,71 @@  +using MBDEVproAPI.DataModel; +using Microsoft.AspNetCore.Http.HttpResults; + namespace MBDEVproAPI.BLL.Services { public class CustomerService : ICustomerService { + + private readonly MBDEVproAPIDbContext _databaseContext; + + public CustomerService(MBDEVproAPIDbContext databaseContext) + { + _databaseContext = databaseContext; + } + + /// + /// GET ALL: Customers + /// + /// + public IEnumerable GetAllCustomers() + { + throw new NotImplementedException(); + } + + /// + /// GET: Customer + /// "CustomerControllerGetCustomer": "Customer/GetCustomer" + /// + /// + /// + public CustomerModel GetCustomer(int id) + { + throw new NotImplementedException(); + } + + /// + /// CREATE: Customer + /// "CustomerControllerCreateCustomer": "Customer/CreateCustomer" + /// + /// + /// + public SaveViewModel CreateCustomer(CustomerModel model) + { + throw new NotImplementedException(); + } + + /// + /// EDIT: Customer + /// "CustomerControllerEditCustomer": "Customer/EditCustomer" + /// + /// + /// + public SaveViewModel EditCustomer(int id, CustomerModel model) + { + throw new NotImplementedException(); + } + + /// + /// DELETE: Customer + /// "CustomerControllerDeleteCustomer": "Customer/DeleteCustomer" + /// + /// + /// + public SaveViewModel DeleteCustomer(int id) + { + throw new NotImplementedException(); + } + } } diff --git a/MBDEVproAPI.Repository/GlobalUsings.cs b/MBDEVproAPI.Repository/GlobalUsings.cs index 1bc8b37..d474cef 100644 --- a/MBDEVproAPI.Repository/GlobalUsings.cs +++ b/MBDEVproAPI.Repository/GlobalUsings.cs @@ -2,8 +2,8 @@ global using System.Collections.Generic; global using System.Data; global using System.Linq; -//global using MBDEVproAPI.DataModel.Entities; -//global using MBDEVproAPI.Repository.Interfaces; +global using MBDEVproAPI.DataModel.Entities; +global using MBDEVproAPI.Repository.Interfaces; global using Microsoft.Extensions.Configuration; global using Serilog; global using Serilog.Formatting.Json; diff --git a/MBDEVproAPI.Repository/Interfaces/.gitkeep b/MBDEVproAPI.Repository/Interfaces/.gitkeep deleted file mode 100644 index 155a176..0000000 --- a/MBDEVproAPI.Repository/Interfaces/.gitkeep +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace MBDEVproAPI.Repository.Interfaces -{ - class _ - { - } -} diff --git a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs new file mode 100644 index 0000000..4321e67 --- /dev/null +++ b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs @@ -0,0 +1,39 @@ + +namespace MBDEVproAPI.Repository.Interfaces +{ + public interface IBaseRepository + { + + /// + /// + /// + /// + void Add(T obj); + + /// + /// + /// + /// + void Remove(int id, T obj); + + /// + /// + /// + /// + /// + T GetByID(int? id); + + /// + /// + /// + /// + /// + IEnumerable GetAll(int id); + + /// + /// + /// + void SaveChanges(); + + } +} diff --git a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs new file mode 100644 index 0000000..45eb3fc --- /dev/null +++ b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs @@ -0,0 +1,11 @@ +using MBDEVproAPI.Common.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace MBDEVproAPI.Repository.Interfaces +{ + public interface ICustomerRepository : IBaseRepository + { + } +} diff --git a/MBDEVproAPI.Repository/Repositories/.gitkeep b/MBDEVproAPI.Repository/Repositories/.gitkeep deleted file mode 100644 index 2f22f53..0000000 --- a/MBDEVproAPI.Repository/Repositories/.gitkeep +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace MBDEVproAPI.Repository.Repositories -{ - class _ - { - } -} diff --git a/MBDEVproAPI.Repository/Repositories/BaseRepository.cs b/MBDEVproAPI.Repository/Repositories/BaseRepository.cs new file mode 100644 index 0000000..257d5af --- /dev/null +++ b/MBDEVproAPI.Repository/Repositories/BaseRepository.cs @@ -0,0 +1,8 @@ + +namespace MBDEVproAPI.Repository.Repositories +{ + public abstract class BaseRepository + { + + } +} diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs new file mode 100644 index 0000000..bcb7f63 --- /dev/null +++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs @@ -0,0 +1,62 @@ + +using MBDEVproAPI.Common.Models; +using MBDEVproAPI.DataModel; +using Microsoft.EntityFrameworkCore; + +namespace MBDEVproAPI.Repository.Repositories +{ + public class CustomerRepository : BaseRepository, ICustomerRepository + { + + #region Private variables & constructors + + /// + /// Context + /// + private readonly MBDEVproAPIDbContext _context; + + /// + /// Default contructor + /// + /// + public CustomerRepository(MBDEVproAPIDbContext context) + { + _context = context; + } + + #endregion + + + + + + + + + + public void Add(CustomerModel obj) + { + throw new NotImplementedException(); + } + + public IEnumerable GetAll(int id) + { + throw new NotImplementedException(); + } + + public CustomerModel GetByID(int? id) + { + throw new NotImplementedException(); + } + + public void Remove(int id, CustomerModel obj) + { + throw new NotImplementedException(); + } + + public void SaveChanges() + { + throw new NotImplementedException(); + } + } +} From 71d719b6970b5b77404bfd914ef34b459721c18b Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Fri, 20 Feb 2026 17:31:38 -0500 Subject: [PATCH 03/13] Some simple stuff --- .../Controllers/CustomerController.cs | 59 +++++++++++++++++++ MBDEVproAPI.BLL/GlobalUsings.cs | 3 + .../Interfaces/ICustomerService.cs | 2 +- MBDEVproAPI.BLL/Mapper/Mapper.cs | 56 ++++++++++++++++++ MBDEVproAPI.BLL/Services/CustomerService.cs | 34 +++++++++-- .../Interfaces/IBaseRepository.cs | 4 +- .../Repositories/CustomerRepository.cs | 31 ++++++++-- 7 files changed, 177 insertions(+), 12 deletions(-) create mode 100644 MBDEVproAPI.BLL/Mapper/Mapper.cs diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index d079a8e..4100330 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -1,5 +1,8 @@  +using MBDEVproAPI.DataModel.Entities; +using System.Collections; + namespace MBDEVproAPI.API.Controllers { public class CustomerController : BaseController @@ -17,6 +20,62 @@ public CustomerController(ICustomerService customerService) + #region Get All Customers + //[HttpGet] + //public IEnumerable GetAllGetAllCustomers() + //{ + // if (id == 0) + // { + // Log.Error("Customer API: GetAllGetAllCustomers; ()"); + // } + // return (IEnumerable)Ok(_customerService.GetAllCustomers); + //} + #endregion + + // GET: api/GetAllGetAllCustomers + //[HttpGet] + //public async Task>> GetAllGetAllCustomers() + //{ + // var customers = await _customerService.GetAllCustomers(); + + // if (customers == null) + // { + // return NotFound(); + // } + + // return customers; + //} + + + //EXAMPLE + #region Get All Customers + [HttpGet("{id}")] + public IEnumerable GetAllCustomers() + { + return (IEnumerable)Ok(_customerService.GetAllCustomers()); + } + #endregion + + + + + + + + //// GET: api/Customer/5 + //[HttpGet("{id}")] + //public async Task> GetCustomer(int id) + //{ + // var customer = await _context.Customers.FindAsync(id); + + // if (customer == null) + // { + // return NotFound(); + // } + + // return customer; + //} + //// GET: api/Customer diff --git a/MBDEVproAPI.BLL/GlobalUsings.cs b/MBDEVproAPI.BLL/GlobalUsings.cs index 84d18eb..4276e93 100644 --- a/MBDEVproAPI.BLL/GlobalUsings.cs +++ b/MBDEVproAPI.BLL/GlobalUsings.cs @@ -12,3 +12,6 @@ global using Microsoft.Extensions.Configuration; global using Serilog; global using Serilog.Formatting.Json; +global using MBDEVproAPI.DataModel; +global using MBDEVproAPI.DataModel.Entities; +global using Microsoft.AspNetCore.Http.HttpResults; diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index 1786f49..c8cbfb2 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -9,7 +9,7 @@ public interface ICustomerService : IBaseService { IEnumerable GetAllCustomers(); - + CustomerModel GetCustomer(int id); SaveViewModel CreateCustomer(CustomerModel model); diff --git a/MBDEVproAPI.BLL/Mapper/Mapper.cs b/MBDEVproAPI.BLL/Mapper/Mapper.cs new file mode 100644 index 0000000..f4c4571 --- /dev/null +++ b/MBDEVproAPI.BLL/Mapper/Mapper.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MBDEVproAPI.BLL.Mapper +{ + + internal class Mapper + { + + /// + /// + /// + /// + /// + /// + /// + /// + internal static DestinationObject MapObject(object sourceObject, + DestinationObject destinationObject, + bool isPropertyTypeNeedsMatch = true) where DestinationObject : class + { + //Boundary Condition + if (sourceObject == null || destinationObject == null) + { + return destinationObject; + } + + PropertyInfo[] destinationPropList = destinationObject.GetType().GetProperties(); + + PropertyInfo[] sourcePropList = sourceObject.GetType().GetProperties(); + + foreach (PropertyInfo destinationPropInfo in destinationPropList) + { + foreach (PropertyInfo sourcePropInfo in sourcePropList) + { + if (sourcePropInfo.Name == destinationPropInfo.Name + && !sourcePropInfo.GetGetMethod().IsVirtual + && !destinationPropInfo.GetGetMethod().IsVirtual + && (!isPropertyTypeNeedsMatch || sourcePropInfo.PropertyType == destinationPropInfo.PropertyType) + ) + { + destinationPropInfo.SetValue(destinationObject, sourcePropInfo.GetValue(sourceObject, null), null); + break; + } + } + } + return destinationObject; + } + + + + } + + +} diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 2d42bfe..230ce4a 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -1,6 +1,7 @@  -using MBDEVproAPI.DataModel; -using Microsoft.AspNetCore.Http.HttpResults; + + +using MBDEVproAPI.Repository.Interfaces; namespace MBDEVproAPI.BLL.Services { @@ -8,20 +9,44 @@ public class CustomerService : ICustomerService { private readonly MBDEVproAPIDbContext _databaseContext; + private readonly ICustomerService _customerService; + private readonly ICustomerRepository _customerRepository; - public CustomerService(MBDEVproAPIDbContext databaseContext) + public CustomerService(MBDEVproAPIDbContext databaseContext, ICustomerService customerService, ICustomerRepository customerRepository ) { _databaseContext = databaseContext; + _customerService = customerService; + _customerRepository = customerRepository; } + + #region Get all Customers /// /// GET ALL: Customers /// /// public IEnumerable GetAllCustomers() { - throw new NotImplementedException(); + var customers = _customerRepository.GetAll().ToList(); + + if (customers == null) + + { + Log.Error("Customers API: CustomerService(GetAllCustomers); (customers == null"); + return null; + } + else + { + return customers; + } } + #endregion + + + + + + /// /// GET: Customer @@ -67,5 +92,6 @@ public SaveViewModel DeleteCustomer(int id) throw new NotImplementedException(); } + } } diff --git a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs index 4321e67..230d136 100644 --- a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs +++ b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs @@ -26,9 +26,9 @@ public interface IBaseRepository /// /// /// - /// + /// /// - IEnumerable GetAll(int id); + IEnumerable GetAll(); /// /// diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs index bcb7f63..390023d 100644 --- a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs +++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs @@ -31,7 +31,31 @@ public CustomerRepository(MBDEVproAPIDbContext context) - + public IEnumerable GetAll() + { + return _context.Customers.Select(x => new CustomerModel + { + CustomerID = x.CustomerID, + Company = x.Company, + FirstName = x.FirstName, + LastName = x.LastName, + Email = x.Email, + Title = x.Title, + BPhone = x.BPhone, + HPhone = x.HPhone, + MPhone = x.MPhone, + Fax = x.Fax, + Address = x.Address, + City = x.City, + State = x.State, + ZIPCode = x.ZIPCode, + Country = x.Country, + WebPage = x.WebPage, + Notes = x.Notes, + Photo = x.Photo, + Map = x.Map + }).ToList(); + } public void Add(CustomerModel obj) @@ -39,10 +63,7 @@ public void Add(CustomerModel obj) throw new NotImplementedException(); } - public IEnumerable GetAll(int id) - { - throw new NotImplementedException(); - } + public CustomerModel GetByID(int? id) { From 22e232ad7805c6fe648b4af2106397a511b54f7a Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Fri, 20 Feb 2026 18:18:17 -0500 Subject: [PATCH 04/13] Unit Tests --- MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj | 25 ++++++++++++++++++++++ MBDEVproAPI.Tests/UnitTest1.cs | 11 ++++++++++ MBDEVproAPI.slnx | 1 + 3 files changed, 37 insertions(+) create mode 100644 MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj create mode 100644 MBDEVproAPI.Tests/UnitTest1.cs diff --git a/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj b/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj new file mode 100644 index 0000000..b6e61fc --- /dev/null +++ b/MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj @@ -0,0 +1,25 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MBDEVproAPI.Tests/UnitTest1.cs b/MBDEVproAPI.Tests/UnitTest1.cs new file mode 100644 index 0000000..dc26341 --- /dev/null +++ b/MBDEVproAPI.Tests/UnitTest1.cs @@ -0,0 +1,11 @@ +namespace MBDEVproAPI.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + + } + } +} diff --git a/MBDEVproAPI.slnx b/MBDEVproAPI.slnx index d8ff2b4..3b2c33e 100644 --- a/MBDEVproAPI.slnx +++ b/MBDEVproAPI.slnx @@ -4,4 +4,5 @@ + From b14f50b40432c47d9fd53897703b2ddbbefbe915 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Sun, 22 Feb 2026 17:12:12 -0500 Subject: [PATCH 05/13] Setting up endpoints --- MBDEVproAPI.API/Controllers/BaseController.cs | 4 +- .../Controllers/CustomerController.cs | 58 +++++----- MBDEVproAPI.API/MBDEVproAPI.API.http | 5 + MBDEVproAPI.API/Program.cs | 7 +- .../Properties/launchSettings.json | 31 ++++-- .../Interfaces/ICustomerService.cs | 2 +- MBDEVproAPI.BLL/Services/CustomerService.cs | 16 +-- MBDEVproAPI.Common/Models/CustomerModel.cs | 26 ++--- .../ViewModels/CustomerViewModel.cs | 102 +++++++++++++++++- MBDEVproAPI.DataModel/Entities/Customer.cs | 8 +- .../Entities/TrackHistoryTableAndTrigger.cs | 29 +++++ .../MBDEVproAPI.DataModel.csproj | 4 + ...20260222220338_CustomersTable.Designer.cs} | 15 ++- ...it.cs => 20260222220338_CustomersTable.cs} | 11 +- .../MBDEVproAPIDbContextModelSnapshot.cs | 11 +- .../Interfaces/IBaseRepository.cs | 10 +- .../Interfaces/ICustomerRepository.cs | 4 +- .../MBDEVproAPI.Repository.csproj | 1 + .../Repositories/CustomerRepository.cs | 56 +++++----- MBDEVproAPI.slnx | 4 +- 20 files changed, 290 insertions(+), 114 deletions(-) create mode 100644 MBDEVproAPI.DataModel/Entities/TrackHistoryTableAndTrigger.cs rename MBDEVproAPI.DataModel/Migrations/{20260216012226_CustomerTableInit.Designer.cs => 20260222220338_CustomersTable.Designer.cs} (91%) rename MBDEVproAPI.DataModel/Migrations/{20260216012226_CustomerTableInit.cs => 20260222220338_CustomersTable.cs} (91%) diff --git a/MBDEVproAPI.API/Controllers/BaseController.cs b/MBDEVproAPI.API/Controllers/BaseController.cs index 066fa5d..aded9fb 100644 --- a/MBDEVproAPI.API/Controllers/BaseController.cs +++ b/MBDEVproAPI.API/Controllers/BaseController.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Mvc; - -namespace MBDEVproAPI.API.Controllers +namespace MBDEVproAPI.API.Controllers { [ApiController, AllowAnonymous, Route("api/[controller]/[action]")] diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index 4100330..c49d2d9 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -1,15 +1,14 @@  - -using MBDEVproAPI.DataModel.Entities; -using System.Collections; - namespace MBDEVproAPI.API.Controllers { + + //[ApiController] + //[Route("[controller]")] public class CustomerController : BaseController { #region variables and constructors - /*private readonly MBDEVproAPIDbContext _context*/ + private ICustomerService _customerService; public CustomerController(ICustomerService customerService) @@ -20,17 +19,28 @@ public CustomerController(ICustomerService customerService) - #region Get All Customers - //[HttpGet] - //public IEnumerable GetAllGetAllCustomers() - //{ - // if (id == 0) - // { - // Log.Error("Customer API: GetAllGetAllCustomers; ()"); - // } - // return (IEnumerable)Ok(_customerService.GetAllCustomers); - //} - #endregion + #region GET: all customers + /// + /// GET: returns all Citation Types for a Project + /// "CustomerControllerGetAllCustomers": "Customer/GetAllCustomers", + /// + /// + [HttpGet] + public ActionResult GetAllCustomers(int BusinessID) + { + try + { + var customers = _customerService.GetAllCustomers(BusinessID); + // can check null here. + return Ok(customers); + } + catch (Exception ex) + { + return BadRequest("Customer API error: " + ex.Message + " | " + ex.InnerException); + } + } + + // GET: api/GetAllGetAllCustomers //[HttpGet] @@ -47,13 +57,14 @@ public CustomerController(ICustomerService customerService) //} - //EXAMPLE - #region Get All Customers - [HttpGet("{id}")] - public IEnumerable GetAllCustomers() - { - return (IEnumerable)Ok(_customerService.GetAllCustomers()); - } + ////EXAMPLE + //#region Get All Customers + //[HttpGet("{id}")] + //public IEnumerable GetAllCustomers() + //{ + // return (IEnumerable)Ok(_customerService.GetAllCustomers()); + //} + //#endregion #endregion @@ -61,7 +72,6 @@ public IEnumerable GetAllCustomers() - //// GET: api/Customer/5 //[HttpGet("{id}")] //public async Task> GetCustomer(int id) diff --git a/MBDEVproAPI.API/MBDEVproAPI.API.http b/MBDEVproAPI.API/MBDEVproAPI.API.http index 0c11d52..a9ab544 100644 --- a/MBDEVproAPI.API/MBDEVproAPI.API.http +++ b/MBDEVproAPI.API/MBDEVproAPI.API.http @@ -4,3 +4,8 @@ GET {{MBDEVproAPI.API_HostAddress}}/weatherforecast/ Accept: application/json ### + +### + +GET {{MBDEVproAPI.API_HostAddress}}/Customer +Accept: application/json \ No newline at end of file diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index f7961ad..c960662 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -6,10 +6,13 @@ builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); -//IServiceCollection serviceCollection = builder.Services.AddTransient(); +// SERVICES builder.Services.AddTransient(); + + +// REPOSITORIES builder.Services.AddTransient(); -//builder.Services.AddScoped(); + diff --git a/MBDEVproAPI.API/Properties/launchSettings.json b/MBDEVproAPI.API/Properties/launchSettings.json index 95446b4..859c2db 100644 --- a/MBDEVproAPI.API/Properties/launchSettings.json +++ b/MBDEVproAPI.API/Properties/launchSettings.json @@ -1,23 +1,36 @@ -{ - "$schema": "https://json.schemastore.org/launchsettings.json", +{ "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "http://localhost:5126", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5126" }, "https": { "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "https://localhost:7092;http://localhost:5126", + "applicationUrl": "https://localhost:7092;http://localhost:5126" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:65421/", + "sslPort": 44399 + } } -} +} \ No newline at end of file diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index c8cbfb2..fb76a97 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -8,7 +8,7 @@ namespace MBDEVproAPI.BLL.Interfaces public interface ICustomerService : IBaseService { - IEnumerable GetAllCustomers(); + CustomerModel GetAllCustomers(int BusinessID); CustomerModel GetCustomer(int id); diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 230ce4a..cc31059 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -8,36 +8,38 @@ namespace MBDEVproAPI.BLL.Services public class CustomerService : ICustomerService { + #region variables & constructors private readonly MBDEVproAPIDbContext _databaseContext; - private readonly ICustomerService _customerService; private readonly ICustomerRepository _customerRepository; - public CustomerService(MBDEVproAPIDbContext databaseContext, ICustomerService customerService, ICustomerRepository customerRepository ) + public CustomerService(MBDEVproAPIDbContext databaseContext, ICustomerRepository customerRepository ) { _databaseContext = databaseContext; - _customerService = customerService; _customerRepository = customerRepository; } + #endregion #region Get all Customers /// /// GET ALL: Customers /// + /// /// - public IEnumerable GetAllCustomers() + public CustomerModel GetAllCustomers(int BusinessID) { - var customers = _customerRepository.GetAll().ToList(); + var customers = _customerRepository.GetAll(BusinessID).ToList(); if (customers == null) { Log.Error("Customers API: CustomerService(GetAllCustomers); (customers == null"); - return null; + return null; // return empty model? } else { - return customers; + //return customers; + return null; } } #endregion diff --git a/MBDEVproAPI.Common/Models/CustomerModel.cs b/MBDEVproAPI.Common/Models/CustomerModel.cs index 427adc9..3183f57 100644 --- a/MBDEVproAPI.Common/Models/CustomerModel.cs +++ b/MBDEVproAPI.Common/Models/CustomerModel.cs @@ -9,21 +9,23 @@ public class CustomerModel : BaseModel public int CustomerID { get; set; } - //[Required] - //[Display(Name = "User name")] - //public string Username { get; set; } + //[Required] + //[Display(Name = "User name")] + //public string Username { get; set; } - //[Required] - //[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - //[DataType(DataType.Password)] - //[Display(Name = "Password")] - //public string Password { get; set; } + //[Required] + //[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + //[DataType(DataType.Password)] + //[Display(Name = "Password")] + //public string Password { get; set; } - //[DataType(DataType.Password)] - //[Display(Name = "Confirm password")] - //[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - //public string ConfirmPassword { get; set; } + //[DataType(DataType.Password)] + //[Display(Name = "Confirm password")] + //[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] + //public string ConfirmPassword { get; set; } + [Required] + public int BusinessID { get; set; } [StringLength(50)] [DataType(DataType.Text)] diff --git a/MBDEVproAPI.Common/ViewModels/CustomerViewModel.cs b/MBDEVproAPI.Common/ViewModels/CustomerViewModel.cs index 5d8709a..0666685 100644 --- a/MBDEVproAPI.Common/ViewModels/CustomerViewModel.cs +++ b/MBDEVproAPI.Common/ViewModels/CustomerViewModel.cs @@ -4,12 +4,108 @@ public class CustomerViewModel { public CustomerViewModel() { - //CustomerStatesList = new List(); - //CustomerSCountryList = new List(); - + CustomerList = new List(); } + // *** LISTS *** + public IEnumerable CustomerList { get; set; } + + [Required] + public int CustomerID { get; set; } + + //[Required] + //[Display(Name = "User name")] + //public string Username { get; set; } + + //[Required] + //[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + //[DataType(DataType.Password)] + //[Display(Name = "Password")] + //public string Password { get; set; } + + //[DataType(DataType.Password)] + //[Display(Name = "Confirm password")] + //[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] + //public string ConfirmPassword { get; set; } + + [Required] + public int BusinessID { get; set; } + + [StringLength(50)] + [DataType(DataType.Text)] + public string? Company { get; set; } + + [Required] + [StringLength(25)] + [DataType(DataType.Text)] + public string FirstName { get; set; } = String.Empty; + + [Required] + [StringLength(25)] + [DataType(DataType.Text)] + public string LastName { get; set; } = String.Empty; + + [Required] + [StringLength(75)] + [DataType(DataType.EmailAddress)] + public string Email { get; set; } = String.Empty; + + [StringLength(50)] + [DataType(DataType.Text)] + public string? Title { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? BPhone { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? HPhone { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? MPhone { get; set; } + + [StringLength(25)] + [DataType(DataType.Text)] + public string? Fax { get; set; } + + [Required] + [StringLength(75)] + [DataType(DataType.Text)] + public string Address { get; set; } = String.Empty; + + [StringLength(75)] + [DataType(DataType.Text)] + public string City { get; set; } = String.Empty; + + [StringLength(75)] + [DataType(DataType.Text)] + public string State { get; set; } = String.Empty; + + [StringLength(15)] + [DataType(DataType.Text)] + public string ZIPCode { get; set; } = String.Empty; + + [StringLength(30)] + [DataType(DataType.Text)] + public string Country { get; set; } = String.Empty; + + [StringLength(75)] + [DataType(DataType.Text)] + public string? WebPage { get; set; } + + [StringLength(4010)] + [DataType(DataType.MultilineText)] + public string? Notes { get; set; } + + [StringLength(75)] + [DataType(DataType.Text)] + public string? Photo { get; set; } + [StringLength(300)] + [DataType(DataType.Text)] + public string? Map { get; set; } diff --git a/MBDEVproAPI.DataModel/Entities/Customer.cs b/MBDEVproAPI.DataModel/Entities/Customer.cs index 8009ccb..d8788f7 100644 --- a/MBDEVproAPI.DataModel/Entities/Customer.cs +++ b/MBDEVproAPI.DataModel/Entities/Customer.cs @@ -6,12 +6,8 @@ namespace MBDEVproAPI.DataModel.Entities /// Customer Entity /// [Table("Customers")] - public partial class Customer /*: TrackHistoryTableAndTrigger*/ + public partial class Customer : TrackHistoryTableAndTrigger { - public Customer() - { - - } [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] @@ -32,6 +28,8 @@ public Customer() //[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] //public string ConfirmPassword { get; set; } + [Required] + public int BusinessID { get; set; } [StringLength(50)] [DataType(DataType.Text)] diff --git a/MBDEVproAPI.DataModel/Entities/TrackHistoryTableAndTrigger.cs b/MBDEVproAPI.DataModel/Entities/TrackHistoryTableAndTrigger.cs new file mode 100644 index 0000000..7019493 --- /dev/null +++ b/MBDEVproAPI.DataModel/Entities/TrackHistoryTableAndTrigger.cs @@ -0,0 +1,29 @@ +namespace MBDEVproAPI.DataModel.Entities +{ + public class TrackHistoryTableAndTrigger + { + /// + /// Created By for entities + /// + [StringLength(50), Required] + public string CreatedBy { get; set; } + + /// + /// Created Date for entities + /// + [Required] + public DateTime CreatedDate { get; set; } + + /// + /// Modified By for entities + /// + [StringLength(50), Required] + public string ModifiedBy { get; set; } + + /// + /// Modified Date for entities + /// + [Required] + public DateTime ModifiedDate { get; set; } + } +} diff --git a/MBDEVproAPI.DataModel/MBDEVproAPI.DataModel.csproj b/MBDEVproAPI.DataModel/MBDEVproAPI.DataModel.csproj index b2b5ffa..399a629 100644 --- a/MBDEVproAPI.DataModel/MBDEVproAPI.DataModel.csproj +++ b/MBDEVproAPI.DataModel/MBDEVproAPI.DataModel.csproj @@ -34,5 +34,9 @@ + + + + diff --git a/MBDEVproAPI.DataModel/Migrations/20260216012226_CustomerTableInit.Designer.cs b/MBDEVproAPI.DataModel/Migrations/20260222220338_CustomersTable.Designer.cs similarity index 91% rename from MBDEVproAPI.DataModel/Migrations/20260216012226_CustomerTableInit.Designer.cs rename to MBDEVproAPI.DataModel/Migrations/20260222220338_CustomersTable.Designer.cs index c1d7657..ecfa286 100644 --- a/MBDEVproAPI.DataModel/Migrations/20260216012226_CustomerTableInit.Designer.cs +++ b/MBDEVproAPI.DataModel/Migrations/20260222220338_CustomersTable.Designer.cs @@ -12,8 +12,8 @@ namespace MBDEVproAPI.DataModel.Migrations { [DbContext(typeof(MBDEVproAPIDbContext))] - [Migration("20260216012226_CustomerTableInit")] - partial class CustomerTableInit + [Migration("20260222220338_CustomersTable")] + partial class CustomersTable { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -25,7 +25,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - modelBuilder.Entity("MBDEVproAPI.Common.Models.Customer", b => + modelBuilder.Entity("MBDEVproAPI.DataModel.Entities.Customer", b => { b.Property("CustomerID") .ValueGeneratedOnAdd() @@ -42,6 +42,9 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasMaxLength(25) .HasColumnType("nvarchar(25)"); + b.Property("BusinessID") + .HasColumnType("int"); + b.Property("City") .IsRequired() .HasMaxLength(75) @@ -57,10 +60,11 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(30)"); b.Property("CreatedBy") + .IsRequired() .HasMaxLength(50) .HasColumnType("nvarchar(50)"); - b.Property("CreatedDate") + b.Property("CreatedDate") .HasColumnType("datetime2"); b.Property("Email") @@ -95,10 +99,11 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(300)"); b.Property("ModifiedBy") + .IsRequired() .HasMaxLength(50) .HasColumnType("nvarchar(50)"); - b.Property("ModifiedDate") + b.Property("ModifiedDate") .HasColumnType("datetime2"); b.Property("Notes") diff --git a/MBDEVproAPI.DataModel/Migrations/20260216012226_CustomerTableInit.cs b/MBDEVproAPI.DataModel/Migrations/20260222220338_CustomersTable.cs similarity index 91% rename from MBDEVproAPI.DataModel/Migrations/20260216012226_CustomerTableInit.cs rename to MBDEVproAPI.DataModel/Migrations/20260222220338_CustomersTable.cs index 8107da2..fb510f0 100644 --- a/MBDEVproAPI.DataModel/Migrations/20260216012226_CustomerTableInit.cs +++ b/MBDEVproAPI.DataModel/Migrations/20260222220338_CustomersTable.cs @@ -6,7 +6,7 @@ namespace MBDEVproAPI.DataModel.Migrations { /// - public partial class CustomerTableInit : Migration + public partial class CustomersTable : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) @@ -17,6 +17,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { CustomerID = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), + BusinessID = table.Column(type: "int", nullable: false), Company = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), FirstName = table.Column(type: "nvarchar(25)", maxLength: 25, nullable: false), LastName = table.Column(type: "nvarchar(25)", maxLength: 25, nullable: false), @@ -35,10 +36,10 @@ protected override void Up(MigrationBuilder migrationBuilder) Notes = table.Column(type: "nvarchar(max)", maxLength: 4010, nullable: true), Photo = table.Column(type: "nvarchar(75)", maxLength: 75, nullable: true), Map = table.Column(type: "nvarchar(300)", maxLength: 300, nullable: true), - CreatedBy = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), - CreatedDate = table.Column(type: "datetime2", nullable: true), - ModifiedBy = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), - ModifiedDate = table.Column(type: "datetime2", nullable: true) + CreatedBy = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + CreatedDate = table.Column(type: "datetime2", nullable: false), + ModifiedBy = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + ModifiedDate = table.Column(type: "datetime2", nullable: false) }, constraints: table => { diff --git a/MBDEVproAPI.DataModel/Migrations/MBDEVproAPIDbContextModelSnapshot.cs b/MBDEVproAPI.DataModel/Migrations/MBDEVproAPIDbContextModelSnapshot.cs index b658163..a1554fb 100644 --- a/MBDEVproAPI.DataModel/Migrations/MBDEVproAPIDbContextModelSnapshot.cs +++ b/MBDEVproAPI.DataModel/Migrations/MBDEVproAPIDbContextModelSnapshot.cs @@ -22,7 +22,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - modelBuilder.Entity("MBDEVproAPI.Common.Models.Customer", b => + modelBuilder.Entity("MBDEVproAPI.DataModel.Entities.Customer", b => { b.Property("CustomerID") .ValueGeneratedOnAdd() @@ -39,6 +39,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(25) .HasColumnType("nvarchar(25)"); + b.Property("BusinessID") + .HasColumnType("int"); + b.Property("City") .IsRequired() .HasMaxLength(75) @@ -54,10 +57,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(30)"); b.Property("CreatedBy") + .IsRequired() .HasMaxLength(50) .HasColumnType("nvarchar(50)"); - b.Property("CreatedDate") + b.Property("CreatedDate") .HasColumnType("datetime2"); b.Property("Email") @@ -92,10 +96,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(300)"); b.Property("ModifiedBy") + .IsRequired() .HasMaxLength(50) .HasColumnType("nvarchar(50)"); - b.Property("ModifiedDate") + b.Property("ModifiedDate") .HasColumnType("datetime2"); b.Property("Notes") diff --git a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs index 230d136..c71309e 100644 --- a/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs +++ b/MBDEVproAPI.Repository/Interfaces/IBaseRepository.cs @@ -13,22 +13,24 @@ public interface IBaseRepository /// /// /// + /// /// - void Remove(int id, T obj); + void Remove(int BusinessID, T obj); /// /// /// + /// /// /// - T GetByID(int? id); + T GetByID(int BusinessID, int? id); /// /// /// - /// + /// /// - IEnumerable GetAll(); + IEnumerable GetAll(int BusinessID); /// /// diff --git a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs index 45eb3fc..b2cd950 100644 --- a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs +++ b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs @@ -5,7 +5,9 @@ namespace MBDEVproAPI.Repository.Interfaces { - public interface ICustomerRepository : IBaseRepository + public interface ICustomerRepository : IBaseRepository { + + } } diff --git a/MBDEVproAPI.Repository/MBDEVproAPI.Repository.csproj b/MBDEVproAPI.Repository/MBDEVproAPI.Repository.csproj index bf71976..080d955 100644 --- a/MBDEVproAPI.Repository/MBDEVproAPI.Repository.csproj +++ b/MBDEVproAPI.Repository/MBDEVproAPI.Repository.csproj @@ -24,6 +24,7 @@ + diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs index 390023d..f00c896 100644 --- a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs +++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs @@ -23,54 +23,48 @@ public CustomerRepository(MBDEVproAPIDbContext context) { _context = context; } + #endregion + + + + + + + + + #region CustomerViewModel + + #endregion + #region CustomerModel + + #endregion - public IEnumerable GetAll() - { - return _context.Customers.Select(x => new CustomerModel - { - CustomerID = x.CustomerID, - Company = x.Company, - FirstName = x.FirstName, - LastName = x.LastName, - Email = x.Email, - Title = x.Title, - BPhone = x.BPhone, - HPhone = x.HPhone, - MPhone = x.MPhone, - Fax = x.Fax, - Address = x.Address, - City = x.City, - State = x.State, - ZIPCode = x.ZIPCode, - Country = x.Country, - WebPage = x.WebPage, - Notes = x.Notes, - Photo = x.Photo, - Map = x.Map - }).ToList(); - } + #region Customer - public void Add(CustomerModel obj) + public void Add(Customer obj) { throw new NotImplementedException(); } + public IEnumerable GetAll(int BusinessID) + { + throw new NotImplementedException(); + } - - public CustomerModel GetByID(int? id) + public Customer GetByID(int BusinessID, int? id) { throw new NotImplementedException(); } - public void Remove(int id, CustomerModel obj) + public void Remove(int BusinessID, Customer obj) { throw new NotImplementedException(); } @@ -79,5 +73,9 @@ public void SaveChanges() { throw new NotImplementedException(); } + #endregion + + + } } diff --git a/MBDEVproAPI.slnx b/MBDEVproAPI.slnx index 3b2c33e..2839849 100644 --- a/MBDEVproAPI.slnx +++ b/MBDEVproAPI.slnx @@ -4,5 +4,7 @@ - + + + From d54bcc37911c7f6e6dff0c41b38dc5459fa52103 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Mon, 23 Feb 2026 20:21:31 -0500 Subject: [PATCH 06/13] Updated Repository --- .../Controllers/CustomerController.cs | 121 ++++++------ MBDEVproAPI.API/GlobalUsings.cs | 2 + MBDEVproAPI.API/MBDEVproAPI.API.http | 5 +- MBDEVproAPI.API/Program.cs | 65 ++++++- MBDEVproAPI.API/appsettings.Development.json | 51 ++++- MBDEVproAPI.API/serilogSettings.json | 37 ++++ MBDEVproAPI.BLL/GlobalUsings.cs | 13 +- .../Interfaces/ICustomerService.cs | 4 +- MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj | 2 + MBDEVproAPI.BLL/Mapper/Mapper.cs | 6 +- MBDEVproAPI.BLL/Services/CustomerService.cs | 179 ++++++++++++++++-- MBDEVproAPI.Repository/GlobalUsings.cs | 3 + .../Interfaces/ICustomerRepository.cs | 9 +- .../Repositories/CustomerRepository.cs | 68 ++++++- 14 files changed, 453 insertions(+), 112 deletions(-) create mode 100644 MBDEVproAPI.API/serilogSettings.json diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index c49d2d9..fc7c6c6 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -1,10 +1,10 @@ - -namespace MBDEVproAPI.API.Controllers +namespace MBDEVproAPI.API.Controllers { //[ApiController] //[Route("[controller]")] - public class CustomerController : BaseController + [ApiController, AllowAnonymous, Route("api/[controller]/[action]")] + public class CustomerController : ControllerBase //: BaseController { #region variables and constructors @@ -18,20 +18,56 @@ public CustomerController(ICustomerService customerService) #endregion + #region + #endregion + + + #region CustomerViewModel + ///// + ///// GET: Gets all customers for a business. + ///// https://localhost:7092/api/Customer/GetAllCustomers/52466 + ///// "CustomerControllerGetAllCustomers": "Customer/GetAllCustomers", + ///// + ///// + ///// + //[Route("GetAllCustomers")] + //[HttpGet("{BusinessID}")] + //public ActionResult GetAllCustomers(int BusinessID) + //{ + // BusinessID = 52466; // temp hard code for testing, can remove later. + // try + // { + // var customers = _customerService.GetAllCustomers(BusinessID); + // // can check null here and model is valid. + // return Ok(customers); + // } + // catch (Exception ex) + // { + // return BadRequest("Customer API error: " + ex.Message + " | " + ex.InnerException); + // } + //} - #region GET: all customers /// - /// GET: returns all Citation Types for a Project - /// "CustomerControllerGetAllCustomers": "Customer/GetAllCustomers", + /// GET: Gets all customers for a business. + /// https://localhost:7092/api/Customer/GetAllCustomersAsync/52466 + /// "CustomerControllerGetAllCustomersAsync": "Customer/GetAllCustomersAsync", /// + /// /// - [HttpGet] - public ActionResult GetAllCustomers(int BusinessID) + //[Route("GetAllCustomersAsync")] + [HttpGet("{BusinessID}")] + public async Task> GetAllCustomersAsync(int BusinessID) { + BusinessID = 52466; // temp hard code for testing, can remove later. try { - var customers = _customerService.GetAllCustomers(BusinessID); - // can check null here. + var customers = await _customerService.GetAllCustomersAsync(BusinessID); + + if (customers == null) + { + return NotFound(); + } + return Ok(customers); } catch (Exception ex) @@ -39,44 +75,17 @@ public ActionResult GetAllCustomers(int BusinessID) return BadRequest("Customer API error: " + ex.Message + " | " + ex.InnerException); } } - - - - // GET: api/GetAllGetAllCustomers - //[HttpGet] - //public async Task>> GetAllGetAllCustomers() - //{ - // var customers = await _customerService.GetAllCustomers(); - - // if (customers == null) - // { - // return NotFound(); - // } - - // return customers; - //} - - - ////EXAMPLE - //#region Get All Customers - //[HttpGet("{id}")] - //public IEnumerable GetAllCustomers() - //{ - // return (IEnumerable)Ok(_customerService.GetAllCustomers()); - //} - //#endregion #endregion - - + #region Get Customer //// GET: api/Customer/5 - //[HttpGet("{id}")] - //public async Task> GetCustomer(int id) + //[HttpGet("{CustomerID}")] + //public async Task> GetCustomerAsync(int CustomerID) //{ - // var customer = await _context.Customers.FindAsync(id); + // var customer = await _context.Customers.FindAsync(CustomerID); // if (customer == null) // { @@ -85,30 +94,9 @@ public ActionResult GetAllCustomers(int BusinessID) // return customer; //} + #endregion - - //// GET: api/Customer - //[HttpGet] - //public async Task>> GetCustomers() - //{ - // return await _context.Customers.ToListAsync(); - //} - - //// GET: api/Customer/5 - //[HttpGet("{id}")] - //public async Task> GetCustomer(int id) - //{ - // var customer = await _context.Customers.FindAsync(id); - - // if (customer == null) - // { - // return NotFound(); - // } - - // return customer; - //} - //// PUT: api/Customer/5 //// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 //[HttpPut("{id}")] @@ -171,5 +159,12 @@ public ActionResult GetAllCustomers(int BusinessID) //{ // return _context.Customers.Any(e => e.CustomerID == id); //} + } + } + + + + + diff --git a/MBDEVproAPI.API/GlobalUsings.cs b/MBDEVproAPI.API/GlobalUsings.cs index 5bd5db4..7bebb5a 100644 --- a/MBDEVproAPI.API/GlobalUsings.cs +++ b/MBDEVproAPI.API/GlobalUsings.cs @@ -22,3 +22,5 @@ //global using Microsoft.OpenApi.Models; global using Serilog; global using Serilog.Formatting.Json; +global using Microsoft.OpenApi; + diff --git a/MBDEVproAPI.API/MBDEVproAPI.API.http b/MBDEVproAPI.API/MBDEVproAPI.API.http index a9ab544..da58885 100644 --- a/MBDEVproAPI.API/MBDEVproAPI.API.http +++ b/MBDEVproAPI.API/MBDEVproAPI.API.http @@ -5,7 +5,10 @@ Accept: application/json ### +GET {{MBDEVproAPI.API_HostAddress}}/customer +Accept: application/json + ### -GET {{MBDEVproAPI.API_HostAddress}}/Customer +GET {{MBDEVproAPI.API_HostAddress}}/Getall Accept: application/json \ No newline at end of file diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index c960662..9c6a7f6 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -1,33 +1,86 @@ - var builder = WebApplication.CreateBuilder(args); -//Register services directly in Program.cs +//DATABASE CONNECTION builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // SERVICES builder.Services.AddTransient(); - // REPOSITORIES builder.Services.AddTransient(); - - - builder.Services.AddControllers(); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); + +// Register the Swagger generator; custom details +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new OpenApiInfo + { + Version = "v1", + Title = "MBDEVproAPI v1 | .NET CORE 10", + Description = "manages business customers", + TermsOfService = new Uri("https://images3.alphacoders.com/967/thumb-1920-96797.jpg"), + Contact = new OpenApiContact + { + Name = "MBDEVproAPI Administrator", + Email = "MBDEVproAPIAdministrator@encom.com", + Url = new Uri("https://m.media-amazon.com/images/I/71rVfyrUzPL._SL1101_.jpg"), + }, + License = new OpenApiLicense + { + Name = "No license", + Url = new Uri("https://example.com/license"), + } + }); +}); + + + var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.MapOpenApi(); + Log.Information("MBDEVproAPI: (Development Environment)"); + app.UseDeveloperExceptionPage(); +} + +if (app.Environment.EnvironmentName == "Test") +{ + Log.Information("MBDEVproAPI: Test Environment)"); } +if (app.Environment.EnvironmentName == "Uat") +{ + Log.Information("MBDEVproAPI: Uat Environment)"); +} + +if (app.Environment.EnvironmentName == "Production") +{ + 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 + }); +} + + + + //Middleware app.UseHttpsRedirection(); diff --git a/MBDEVproAPI.API/appsettings.Development.json b/MBDEVproAPI.API/appsettings.Development.json index 3453499..720c196 100644 --- a/MBDEVproAPI.API/appsettings.Development.json +++ b/MBDEVproAPI.API/appsettings.Development.json @@ -4,10 +4,57 @@ // Use Secrets if passwords and so on... "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", + //"IsUserExist": "Account/IsUserExist" + + }, + + "DefaultProjectSettings": { + "ProjectName": "MBDEVproAPI", + "Description": "MBDEVproAPI version .NET CORE 10", + "DefaultFinishInspectionsStatus": "COMPLETED", + "SessionTimeout": "900000", + "ApplicationURL": "https://www.google.com", + "JSReport_TimeOutValue": "200000000", + "LogInExpireTimeSpan": "40" + }, + "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" } + }, + "UserLogin": { + "AppShortName": "MBDEVproAPI", + "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" + } + } + + ] } -} +} \ No newline at end of file diff --git a/MBDEVproAPI.API/serilogSettings.json b/MBDEVproAPI.API/serilogSettings.json new file mode 100644 index 0000000..1436674 --- /dev/null +++ b/MBDEVproAPI.API/serilogSettings.json @@ -0,0 +1,37 @@ +{ + "AllowedHosts": "*", + "Serilog": { + "Using": [ "Serilog.Exceptions" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "System": "Warning" + } + }, + "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId", "WithExceptionDetails" ], + "WriteTo": [ + { "Name": "Console" }, + { + "Name": "File", + "Args": { + "path": "X:\\Logs\\MBDEVpro\\CustomerAPI\\Log.txt", + "outputTemplate": "{Timestamp:G} {Message}{NewLine:1}{Exception:1}" + } + }, + { + "Name": "File", + "Args": { + "path": "X:\\Logs\\MBDEVpro\\CustomerAPI\\log.json", + "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog" + } + }, + { + "Name": "Seq", + "Args": { + "serverUrl": "http://localhost:8081" + } + } + ] + } +} diff --git a/MBDEVproAPI.BLL/GlobalUsings.cs b/MBDEVproAPI.BLL/GlobalUsings.cs index 4276e93..34e3816 100644 --- a/MBDEVproAPI.BLL/GlobalUsings.cs +++ b/MBDEVproAPI.BLL/GlobalUsings.cs @@ -4,14 +4,19 @@ global using System.Linq; global using System.Reflection; global using System.Transactions; -global using MBDEVproAPI.Common.Models; -global using MBDEVproAPI.Common.ViewModels; -global using MBDEVproAPI.BLL.Interfaces; +global using Microsoft.AspNetCore.Http.HttpResults; global using Microsoft.AspNetCore.Http; global using Microsoft.Extensions.Caching.Memory; global using Microsoft.Extensions.Configuration; global using Serilog; global using Serilog.Formatting.Json; +global using System.Threading.Tasks; +global using Microsoft.AspNetCore.Mvc; +global using MBDEVproAPI.Common.Models; +global using MBDEVproAPI.Common.ViewModels; +global using MBDEVproAPI.Repository; +global using MBDEVproAPI.BLL.Interfaces; +global using MBDEVproAPI.BLL.Services; global using MBDEVproAPI.DataModel; global using MBDEVproAPI.DataModel.Entities; -global using Microsoft.AspNetCore.Http.HttpResults; +global using MBDEVproAPI.Repository.Interfaces; diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index fb76a97..fb61d0b 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -8,7 +8,9 @@ namespace MBDEVproAPI.BLL.Interfaces public interface ICustomerService : IBaseService { - CustomerModel GetAllCustomers(int BusinessID); + CustomerViewModel GetAllCustomers(int BusinessID); + + Task GetAllCustomersAsync(int BusinessID); CustomerModel GetCustomer(int id); diff --git a/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj index 9545335..1cb3782 100644 --- a/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj +++ b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj @@ -7,6 +7,8 @@ + + diff --git a/MBDEVproAPI.BLL/Mapper/Mapper.cs b/MBDEVproAPI.BLL/Mapper/Mapper.cs index f4c4571..3462c91 100644 --- a/MBDEVproAPI.BLL/Mapper/Mapper.cs +++ b/MBDEVproAPI.BLL/Mapper/Mapper.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; + -namespace MBDEVproAPI.BLL.Mapper +namespace MBDEVproAPI.BLL { internal class Mapper diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index cc31059..39cf22f 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -1,53 +1,175 @@ - +namespace MBDEVproAPI.BLL.Services { -using MBDEVproAPI.Repository.Interfaces; - -namespace MBDEVproAPI.BLL.Services -{ public class CustomerService : ICustomerService { #region variables & constructors - private readonly MBDEVproAPIDbContext _databaseContext; + private readonly MBDEVproAPIDbContext _context; + + //private IHttpContextAccessor _contextAccessor; + + /// + /// Base Repository + /// private readonly ICustomerRepository _customerRepository; - public CustomerService(MBDEVproAPIDbContext databaseContext, ICustomerRepository customerRepository ) + ///// + ///// memory cache + ///// + //private IMemoryCache _memoryCache; + + ///// + ///// configuration + ///// + //public IConfiguration _configuration { get; } + + + + + public CustomerService(MBDEVproAPIDbContext context, ICustomerRepository customerRepository) { - _databaseContext = databaseContext; + _context = context; _customerRepository = customerRepository; } #endregion - #region Get all Customers + #region CustomerViewModel /// - /// GET ALL: Customers + /// GET: Customers /// /// /// - public CustomerModel GetAllCustomers(int BusinessID) + public CustomerViewModel GetAllCustomers(int BusinessID) { - var customers = _customerRepository.GetAll(BusinessID).ToList(); - - if (customers == null) + try + { + if (BusinessID == 0) + { + Log.Error("Customer API: CustomerService(GetAllCustomers); (BusinessID == 0)"); + return null; + } + else + { + CustomerViewModel model = new CustomerViewModel(); + model.CustomerList = _customerRepository.GetAllCustomers(BusinessID).Select(O => Mapper.MapObject(O, new CustomerModel())).ToList(); + //model.BusinessID = BusinessID; + if (model == null) + { + Log.Error("Customer API: CustomerService(GetAllCustomers); (model == null)"); + return null; + } + else + { + return model; + } + } + } + catch (Exception ex) + { + Log.Error("Customer API: CustomerService(GetAllCustomers); (" + ex + ")" + " (" + ex.InnerException + ")"); + return null; + } + } + /// + /// GET: Customers async + /// + /// + /// + public async Task GetAllCustomersAsync(int BusinessID) + { + try { - Log.Error("Customers API: CustomerService(GetAllCustomers); (customers == null"); - return null; // return empty model? + if (BusinessID == 0) + { + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (BusinessID == 0)"); + return null; + } + else + { + CustomerViewModel model = new CustomerViewModel(); + var customers = await _customerRepository.GetAllCustomersAsync(BusinessID); + + if (customers == null) + { + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (customers == null)"); + return null; + } + + model.CustomerList = customers.Select(o => Mapper.MapObject(o, new CustomerModel())).ToList(); + return model; + } } - else + catch (Exception ex) { - //return customers; + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); return null; } } - #endregion + //public IncidentViewModel GetIncidentsByProjectID(int ProjectID) + //{ + // IncidentViewModel model = new IncidentViewModel(); + // try + // { + // if (ProjectID == 0) + // { + // Log.Error("Incidents API: IncidentService(GetIncidentsByProjectID); (ProjectID == 0)"); + // return model; + // } + // else + // { + // model = Mapper.MapObject(_incidentRepository.GetIncidentsByProjectID(ProjectID), new IncidentViewModel()); + + // if (model == null) + // { + // Log.Error("Incidents API: IncidentService(GetIncidentsByProjectID); (model == null)"); + // return model; + // } + // else + // { + // // INCIDENTS + // model.IncidentList = (List)GetIncidents(ProjectID); + // return model; + // } + // } + // } + // catch (Exception ex) + // { + // Log.Error("Incidents API: IncidentService(GetIncidentsByProjectID); (" + ex + ")" + " (" + ex.InnerException + ")"); + // return model; + // } + // finally + // { + + // } + //} + + + + + //BusinessID = 52466; // temp hard coded for testing; need to get from token or pass in as parameter + // var customers = _customerRepository.GetAll(BusinessID).ToList(); + + // if (customers == null) + + // { + // Log.Error("Customers API: CustomerService(GetAllCustomers); (customers == null"); + // return null; // return empty model? + // } + // else + // { + // return customers.ToList(); + // } + //} + #endregion + /// @@ -95,5 +217,24 @@ public SaveViewModel DeleteCustomer(int id) } + } + } + + + + + + + + + + + + + + + + + diff --git a/MBDEVproAPI.Repository/GlobalUsings.cs b/MBDEVproAPI.Repository/GlobalUsings.cs index d474cef..46caab7 100644 --- a/MBDEVproAPI.Repository/GlobalUsings.cs +++ b/MBDEVproAPI.Repository/GlobalUsings.cs @@ -7,3 +7,6 @@ global using Microsoft.Extensions.Configuration; global using Serilog; global using Serilog.Formatting.Json; +global using MBDEVproAPI.Common.Models; +global using MBDEVproAPI.Common.ViewModels; +global using System.Text; diff --git a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs index b2cd950..d4730a6 100644 --- a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs +++ b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs @@ -1,13 +1,14 @@ -using MBDEVproAPI.Common.Models; -using System; -using System.Collections.Generic; -using System.Text; + namespace MBDEVproAPI.Repository.Interfaces { public interface ICustomerRepository : IBaseRepository { + Task> GetAllAysnc(int BusinessID); + Task> GetAllCustomersAsync(int BusinessID); + + IEnumerable GetAllCustomers(int BusinessID); } } diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs index f00c896..8b77581 100644 --- a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs +++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs @@ -1,6 +1,8 @@  using MBDEVproAPI.Common.Models; +using MBDEVproAPI.Common.ViewModels; using MBDEVproAPI.DataModel; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace MBDEVproAPI.Repository.Repositories @@ -32,38 +34,86 @@ public CustomerRepository(MBDEVproAPIDbContext context) - #region CustomerViewModel - + #region async methods + public async Task> GetAllAysnc(int BusinessID) + { + var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync(); + return customers; + } + public async Task> GetAllCustomersAsync(int BusinessID) + { + var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync(); + return customers; + } #endregion - #region CustomerModel + #region regular methods #endregion #region Customer - - public void Add(Customer obj) + public IEnumerable GetAll(int BusinessID) { - throw new NotImplementedException(); + var customers = _context.Customers.Where(O => O.BusinessID == BusinessID).ToList(); + + return customers; } - public IEnumerable GetAll(int BusinessID) + public IEnumerable GetAllCustomers(int BusinessID) { - throw new NotImplementedException(); + var customers = _context.Customers.Where(O => O.BusinessID == BusinessID).ToList(); + + return customers; } + + ///// + ///// Get a single record by ID + ///// + ///// + ///// + ///// public Customer GetByID(int BusinessID, int? id) + { + 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; + } + } + + + public void Add(Customer obj) { throw new NotImplementedException(); } + ///// + ///// + ///// + ///// + ///// + ///// + //public CitationType GetByID(int ProjectID, int? CitationTypeID) + //{ + // return _context.CitationType + // .Where(O => O.ProjectID == ProjectID && O.CitationTypeID == CitationTypeID).FirstOrDefault(); + //} + + + public void Remove(int BusinessID, Customer obj) { throw new NotImplementedException(); @@ -73,6 +123,8 @@ public void SaveChanges() { throw new NotImplementedException(); } + + #endregion From 1f99f96a6fd245ff13a9a2d31eb936c00cefce25 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Tue, 24 Feb 2026 19:35:57 -0500 Subject: [PATCH 07/13] another update --- MBDEVproAPI.API/Controllers/BaseController.cs | 1 + .../Controllers/CustomerController.cs | 78 +++++------ MBDEVproAPI.API/GlobalUsings.cs | 1 + MBDEVproAPI.API/MBDEVproAPI.API.http | 11 +- MBDEVproAPI.API/Program.cs | 13 +- .../Interfaces/ICustomerService.cs | 8 +- MBDEVproAPI.BLL/Services/CustomerService.cs | 122 +++++++++++------- .../Interfaces/ICustomerRepository.cs | 4 +- .../Repositories/CustomerRepository.cs | 53 ++++---- 9 files changed, 160 insertions(+), 131 deletions(-) diff --git a/MBDEVproAPI.API/Controllers/BaseController.cs b/MBDEVproAPI.API/Controllers/BaseController.cs index aded9fb..ba87c06 100644 --- a/MBDEVproAPI.API/Controllers/BaseController.cs +++ b/MBDEVproAPI.API/Controllers/BaseController.cs @@ -2,6 +2,7 @@ { [ApiController, AllowAnonymous, Route("api/[controller]/[action]")] + public class BaseController : Controller { diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index fc7c6c6..6733c3a 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -1,10 +1,8 @@ -namespace MBDEVproAPI.API.Controllers -{ + - //[ApiController] - //[Route("[controller]")] - [ApiController, AllowAnonymous, Route("api/[controller]/[action]")] - public class CustomerController : ControllerBase //: BaseController +namespace MBDEVproAPI.API.Controllers +{ + public class CustomerController : BaseController { #region variables and constructors @@ -23,40 +21,17 @@ public CustomerController(ICustomerService customerService) #region CustomerViewModel - ///// - ///// GET: Gets all customers for a business. - ///// https://localhost:7092/api/Customer/GetAllCustomers/52466 - ///// "CustomerControllerGetAllCustomers": "Customer/GetAllCustomers", - ///// - ///// - ///// - //[Route("GetAllCustomers")] - //[HttpGet("{BusinessID}")] - //public ActionResult GetAllCustomers(int BusinessID) - //{ - // BusinessID = 52466; // temp hard code for testing, can remove later. - // try - // { - // var customers = _customerService.GetAllCustomers(BusinessID); - // // can check null here and model is valid. - // return Ok(customers); - // } - // catch (Exception ex) - // { - // return BadRequest("Customer API error: " + ex.Message + " | " + ex.InnerException); - // } - //} - /// /// GET: Gets all customers for a business. - /// https://localhost:7092/api/Customer/GetAllCustomersAsync/52466 - /// "CustomerControllerGetAllCustomersAsync": "Customer/GetAllCustomersAsync", + /// TEST URL: https://localhost:7092/api/Customer/GetAllCustomers/52466 | https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466 + /// "CustomerControllerGetAllCustomers": "Customer/GetAllCustomers", /// /// /// - //[Route("GetAllCustomersAsync")] - [HttpGet("{BusinessID}")] - public async Task> GetAllCustomersAsync(int BusinessID) + //[Route("GetAllCustomers")] + //[HttpGet("{BusinessID}")] + [HttpGet] + public async Task> GetAllCustomersAsync(int BusinessID) { BusinessID = 52466; // temp hard code for testing, can remove later. try @@ -80,26 +55,35 @@ public async Task> GetAllCustomersAsync(int Busi #region Get Customer - - //// GET: api/Customer/5 + /// + /// GET: 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", + /// + /// + /// + //[Route("GetCustomer")] //[HttpGet("{CustomerID}")] - //public async Task> GetCustomerAsync(int CustomerID) - //{ - // var customer = await _context.Customers.FindAsync(CustomerID); + [HttpGet] + public async Task> GetCustomerAsync(int CustomerID) + { + var customer = await _customerService.GetCustomerAsync(CustomerID); - // if (customer == null) - // { - // return NotFound(); - // } + if (customer == null) + { + return NotFound(); + } - // return customer; - //} + return customer; + } #endregion - //// PUT: api/Customer/5 + //// 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) diff --git a/MBDEVproAPI.API/GlobalUsings.cs b/MBDEVproAPI.API/GlobalUsings.cs index 7bebb5a..1fb1a1e 100644 --- a/MBDEVproAPI.API/GlobalUsings.cs +++ b/MBDEVproAPI.API/GlobalUsings.cs @@ -7,6 +7,7 @@ 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; diff --git a/MBDEVproAPI.API/MBDEVproAPI.API.http b/MBDEVproAPI.API/MBDEVproAPI.API.http index da58885..cc413c5 100644 --- a/MBDEVproAPI.API/MBDEVproAPI.API.http +++ b/MBDEVproAPI.API/MBDEVproAPI.API.http @@ -1,14 +1,17 @@ -@MBDEVproAPI.API_HostAddress = http://localhost:5126 +@MBDEVproAPI.API_HostAddress = http://localhost:7092 GET {{MBDEVproAPI.API_HostAddress}}/weatherforecast/ Accept: application/json ### -GET {{MBDEVproAPI.API_HostAddress}}/customer +GET {{MBDEVproAPI.API_HostAddress}}/api/Customer/GetAllCustomers?BusinessID=52466 Accept: application/json +// https://localhost:7092/api/Customer/GetAllCustomers/52466 +// https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466 ### -GET {{MBDEVproAPI.API_HostAddress}}/Getall -Accept: application/json \ No newline at end of file +GET {{MBDEVproAPI.API_HostAddress}}/api/Customer/GetCustomer/3 +Accept: application/json +// https://localhost:7092/api/Customer/GetCustomer?CustomerID=3 \ No newline at end of file diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index 9c6a7f6..605712f 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -1,4 +1,6 @@ +using Scalar.AspNetCore; + var builder = WebApplication.CreateBuilder(args); //DATABASE CONNECTION @@ -46,7 +48,9 @@ // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { - app.MapOpenApi(); + app.MapOpenApi(); // Expose the OpenAPI JSON endpoint + app.MapScalarApiReference(); // Map the Scalar UI endpoint + Log.Information("MBDEVproAPI: (Development Environment)"); app.UseDeveloperExceptionPage(); } @@ -78,6 +82,13 @@ }); } +app.MapScalarApiReference(options => +{ + options.Title = "MBDEVproAPI v1 .NET CORE 10"; + options.WithTheme(ScalarTheme.Moon); // Use a specific theme + options.ForceDarkMode(); // Force dark mode +}); + diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index fb61d0b..4767f1a 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -8,11 +8,15 @@ namespace MBDEVproAPI.BLL.Interfaces public interface ICustomerService : IBaseService { - CustomerViewModel GetAllCustomers(int BusinessID); + //CustomerViewModel GetAllCustomers(int BusinessID); Task GetAllCustomersAsync(int BusinessID); - CustomerModel GetCustomer(int id); + + Task GetCustomerAsync(int CustomerID); + + + //CustomerModel GetCustomer(int id); SaveViewModel CreateCustomer(CustomerModel model); diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 39cf22f..3e3af84 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -36,83 +36,117 @@ public CustomerService(MBDEVproAPIDbContext context, ICustomerRepository custome #region CustomerViewModel + ///// + ///// GET: Customers + ///// + ///// + ///// + //public CustomerViewModel GetAllCustomers(int BusinessID) + //{ + // try + // { + // if (BusinessID == 0) + // { + // Log.Error("Customer API: CustomerService(GetAllCustomers); (BusinessID == 0)"); + // return null; + // } + // else + // { + // CustomerViewModel model = new CustomerViewModel(); + // model.CustomerList = _customerRepository.GetAllCustomers(BusinessID).Select(O => Mapper.MapObject(O, new CustomerModel())).ToList(); + // //model.BusinessID = BusinessID; + // if (model == null) + // { + // Log.Error("Customer API: CustomerService(GetAllCustomers); (model == null)"); + // return null; + // } + // else + // { + // return model; + // } + // } + // } + // catch (Exception ex) + // { + // Log.Error("Customer API: CustomerService(GetAllCustomers); (" + ex + ")" + " (" + ex.InnerException + ")"); + // return null; + // } + //} + + /// - /// GET: Customers + /// GET: Get All Customers Async /// /// /// - public CustomerViewModel GetAllCustomers(int BusinessID) + public async Task GetAllCustomersAsync(int BusinessID) { try { if (BusinessID == 0) { - Log.Error("Customer API: CustomerService(GetAllCustomers); (BusinessID == 0)"); - return null; + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (BusinessID == 0)"); + return new CustomerViewModel(); } else { CustomerViewModel model = new CustomerViewModel(); - model.CustomerList = _customerRepository.GetAllCustomers(BusinessID).Select(O => Mapper.MapObject(O, new CustomerModel())).ToList(); - //model.BusinessID = BusinessID; - if (model == null) - { - Log.Error("Customer API: CustomerService(GetAllCustomers); (model == null)"); - return null; - } - else + var customers = await _customerRepository.GetAllCustomersAsync(BusinessID); + + if (customers == null) { - return model; + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (customers == null)"); + return new CustomerViewModel(); } + + model.CustomerList = customers.Select(o => Mapper.MapObject(o, new CustomerModel())).ToList(); + return model; } } catch (Exception ex) { - Log.Error("Customer API: CustomerService(GetAllCustomers); (" + ex + ")" + " (" + ex.InnerException + ")"); - return null; + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); + return new CustomerViewModel(); } } + + //GetCustomerAsync /// - /// GET: Customers async + /// GET: Get Customer by ID Async /// - /// + /// /// - public async Task GetAllCustomersAsync(int BusinessID) + + public async Task GetCustomerAsync(int CustomerID) // can jsut do Customer here instead of CustomerModel { try { - if (BusinessID == 0) + if (CustomerID == 0) { - Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (BusinessID == 0)"); - return null; + Log.Error("Customer API: CustomerService(GetCustomerAsync); (CustomerID == 0)"); + return new Customer(); } else { - CustomerViewModel model = new CustomerViewModel(); - var customers = await _customerRepository.GetAllCustomersAsync(BusinessID); - - if (customers == null) + var customer = await _customerRepository.GetCustomerAsync(CustomerID); + if (customer == null) { - Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (customers == null)"); - return null; + Log.Error("Customer API: CustomerService(GetCustomerAsync); (customer == null)"); + return new Customer(); } - - model.CustomerList = customers.Select(o => Mapper.MapObject(o, new CustomerModel())).ToList(); - return model; + return customer; } } catch (Exception ex) { - Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); - return null; + Log.Error("Customer API: CustomerService(GetCustomerAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); + return new Customer(); } } - - //public IncidentViewModel GetIncidentsByProjectID(int ProjectID) //{ // IncidentViewModel model = new IncidentViewModel(); @@ -172,16 +206,16 @@ public async Task GetAllCustomersAsync(int BusinessID) - /// - /// GET: Customer - /// "CustomerControllerGetCustomer": "Customer/GetCustomer" - /// - /// - /// - public CustomerModel GetCustomer(int id) - { - throw new NotImplementedException(); - } + ///// + ///// GET: Customer + ///// "CustomerControllerGetCustomer": "Customer/GetCustomer" + ///// + ///// + ///// + //public CustomerModel GetCustomer(int id) + //{ + // throw new NotImplementedException(); + //} /// /// CREATE: Customer diff --git a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs index d4730a6..d05e87e 100644 --- a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs +++ b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs @@ -5,10 +5,8 @@ namespace MBDEVproAPI.Repository.Interfaces public interface ICustomerRepository : IBaseRepository { - Task> GetAllAysnc(int BusinessID); - Task> GetAllCustomersAsync(int BusinessID); - IEnumerable GetAllCustomers(int BusinessID); + Task GetCustomerAsync(int CustomerID); } } diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs index 8b77581..7e14af1 100644 --- a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs +++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs @@ -34,46 +34,53 @@ public CustomerRepository(MBDEVproAPIDbContext context) - #region async methods - public async Task> GetAllAysnc(int BusinessID) + #region Get All Customers Async + /// + /// GET: Get All Customers Async + /// + /// + /// + public async Task> GetAllCustomersAsync(int BusinessID) { var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync(); - return customers; } + #endregion - public async Task> GetAllCustomersAsync(int BusinessID) + + #region Get Customer by CustomerID Async + public async Task GetCustomerAsync(int CustomerID) { - var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync(); - return customers; + var customer = await _context.Customers.Where(O => O.CustomerID == CustomerID).FirstOrDefaultAsync(); + if (customer == null) + { + Log.Error("Customer API: CustomerRepository(GetCustomerAsync); (customer == null)"); + return new Customer(); + } + else + { + return customer; + } } #endregion - #region regular methods - #endregion - #region Customer - public IEnumerable GetAll(int BusinessID) - { - var customers = _context.Customers.Where(O => O.BusinessID == BusinessID).ToList(); - return customers; - } - public IEnumerable GetAllCustomers(int BusinessID) + #region other + public IEnumerable GetAll(int BusinessID) { var customers = _context.Customers.Where(O => O.BusinessID == BusinessID).ToList(); return customers; } - ///// ///// Get a single record by ID ///// @@ -100,20 +107,6 @@ public void Add(Customer obj) throw new NotImplementedException(); } - ///// - ///// - ///// - ///// - ///// - ///// - //public CitationType GetByID(int ProjectID, int? CitationTypeID) - //{ - // return _context.CitationType - // .Where(O => O.ProjectID == ProjectID && O.CitationTypeID == CitationTypeID).FirstOrDefault(); - //} - - - public void Remove(int BusinessID, Customer obj) { throw new NotImplementedException(); From 752a8b94fcc988583b7734b3778d7f7474b45a97 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Wed, 25 Feb 2026 20:51:21 -0500 Subject: [PATCH 08/13] More endpoints --- .../Controllers/CustomerController.cs | 75 ++++- .../Interfaces/ICustomerService.cs | 8 +- MBDEVproAPI.BLL/Services/CustomerService.cs | 274 ++++++++++++------ .../Interfaces/ICustomerRepository.cs | 4 + .../Repositories/CustomerRepository.cs | 27 +- 5 files changed, 280 insertions(+), 108 deletions(-) diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index 6733c3a..be036be 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -20,23 +20,23 @@ public CustomerController(ICustomerService customerService) #endregion - #region CustomerViewModel + #region Get All Customers | CustomerViewModel /// - /// GET: Gets all customers for a business. + /// GET: 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 - /// "CustomerControllerGetAllCustomers": "Customer/GetAllCustomers", + /// "CustomerControllerGetAllCustomersVMAsync": "Customer/GetAllCustomersVMAsync", /// /// /// //[Route("GetAllCustomers")] //[HttpGet("{BusinessID}")] [HttpGet] - public async Task> GetAllCustomersAsync(int BusinessID) + public async Task> GetAllCustomersVMAsync(int BusinessID) { BusinessID = 52466; // temp hard code for testing, can remove later. try { - var customers = await _customerService.GetAllCustomersAsync(BusinessID); + var customers = await _customerService.GetAllCustomersVMAsync(BusinessID); if (customers == null) { @@ -53,8 +53,37 @@ public async Task> GetAllCustomersAsync(int Busi #endregion + #region Get All Customers | CustomerModel + /// + /// GET: Gets all customers for a business. + /// TEST URL: https://localhost:7092/api/Customer/GetAllCustomers?BusinessID=52466 + /// "CustomerControllerGetAllCustomersAsync": "Customer/GetAllCustomersAsync", + /// + /// + /// + [HttpGet] + public async Task> GetAllCustomersAsync(int BusinessID) + { + BusinessID = 52466; // temp hard code for testing, can remove later. + try + { + var customers = await _customerService.GetAllCustomersAsync(BusinessID); + if (customers == null) + { + return NotFound(); + } + return Ok(customers); + } + catch (Exception ex) + { + return BadRequest("Customer API error: " + ex.Message + " | " + ex.InnerException); + } + } + #endregion + + - #region Get Customer + #region Get Customer | Customer /// /// GET: Gets a customer for a business. /// TEST URL: https://localhost:7092/api/Customer/GetCustomer/3 | https://localhost:7092/api/Customer/GetCustomer?CustomerID=3 @@ -79,6 +108,39 @@ public async Task> GetCustomerAsync(int CustomerID) #endregion + + #region 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)); + } + #endregion + + + + #region Add Customer | Customer + /// + /// Create a new customer for a business. + /// + /// + /// + [HttpPost] + public async Task CreateCustomerAsync([FromBody] CustomerModel model) + { + return Ok(_customerService.CreateCustomerAsync(model)); + //return Ok("UNDER CONTRUCTION | CreateCustomerAsync([FromBody] Customer model)"); + } + #endregion + + + + //// PUT - CREATE: api/Customer/5 //// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 //[HttpPut("{id}")] @@ -123,6 +185,7 @@ public async Task> GetCustomerAsync(int CustomerID) // return CreatedAtAction("GetCustomer", new { id = customer.CustomerID }, customer); //} + //// DELETE: api/Customer/5 //[HttpDelete("{id}")] //public async Task DeleteCustomer(int id) diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index 4767f1a..b64b4a4 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -8,15 +8,17 @@ namespace MBDEVproAPI.BLL.Interfaces public interface ICustomerService : IBaseService { - //CustomerViewModel GetAllCustomers(int BusinessID); + Task GetAllCustomersVMAsync(int BusinessID); - Task GetAllCustomersAsync(int BusinessID); + Task> GetAllCustomersAsync(int BusinessID); Task GetCustomerAsync(int CustomerID); + Task CreateCustomerVMAsync(CustomerViewModel vm); + + Task CreateCustomerAsync(CustomerModel model); - //CustomerModel GetCustomer(int id); SaveViewModel CreateCustomer(CustomerModel model); diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 3e3af84..93c4c29 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -35,51 +35,13 @@ public CustomerService(MBDEVproAPIDbContext context, ICustomerRepository custome #endregion - #region CustomerViewModel - ///// - ///// GET: Customers - ///// - ///// - ///// - //public CustomerViewModel GetAllCustomers(int BusinessID) - //{ - // try - // { - // if (BusinessID == 0) - // { - // Log.Error("Customer API: CustomerService(GetAllCustomers); (BusinessID == 0)"); - // return null; - // } - // else - // { - // CustomerViewModel model = new CustomerViewModel(); - // model.CustomerList = _customerRepository.GetAllCustomers(BusinessID).Select(O => Mapper.MapObject(O, new CustomerModel())).ToList(); - // //model.BusinessID = BusinessID; - // if (model == null) - // { - // Log.Error("Customer API: CustomerService(GetAllCustomers); (model == null)"); - // return null; - // } - // else - // { - // return model; - // } - // } - // } - // catch (Exception ex) - // { - // Log.Error("Customer API: CustomerService(GetAllCustomers); (" + ex + ")" + " (" + ex.InnerException + ")"); - // return null; - // } - //} - - + #region Get All Customers | CustomerViewModel /// - /// GET: Get All Customers Async + /// GET: Gets all customers for a business in a VM for web UI. /// /// /// - public async Task GetAllCustomersAsync(int BusinessID) + public async Task GetAllCustomersVMAsync(int BusinessID) { try { @@ -91,14 +53,12 @@ public async Task GetAllCustomersAsync(int BusinessID) else { CustomerViewModel model = new CustomerViewModel(); - var customers = await _customerRepository.GetAllCustomersAsync(BusinessID); - + var customers = await _customerRepository.GetAllCustomersVMAsync(BusinessID); if (customers == null) { Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (customers == null)"); return new CustomerViewModel(); } - model.CustomerList = customers.Select(o => Mapper.MapObject(o, new CustomerModel())).ToList(); return model; } @@ -109,15 +69,74 @@ public async Task GetAllCustomersAsync(int BusinessID) return new CustomerViewModel(); } } + #endregion + #region Get All Customers | CustomerModel + public async Task> GetAllCustomersAsync(int BusinessID) + { + try + { + if (BusinessID == 0) + { + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (BusinessID == 0)"); + return new List(); + } + else + { + // Await the repository task first, then project the results. + var customers = await _customerRepository.GetAllCustomersAsync(BusinessID); + if (customers == null) + { + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (entities == null)"); + return new List(); + } + var entities = customers.Select(o => Mapper.MapObject(o, new CustomerModel())).ToList(); + return entities; + } + } + catch (Exception ex) + { + Log.Error("Customer API: CustomerService(GetAllCustomersAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); + return new List(); + } + } + #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 /// - /// GET: Get Customer by ID Async + /// GET: Gets a customer for a business. /// /// /// - + public async Task GetCustomerAsync(int CustomerID) // can jsut do Customer here instead of CustomerModel { try @@ -144,64 +163,115 @@ public async Task GetAllCustomersAsync(int BusinessID) return new Customer(); } } + #endregion - //public IncidentViewModel GetIncidentsByProjectID(int ProjectID) - //{ - // IncidentViewModel model = new IncidentViewModel(); - // try - // { - // if (ProjectID == 0) - // { - // Log.Error("Incidents API: IncidentService(GetIncidentsByProjectID); (ProjectID == 0)"); - // return model; - // } - // else - // { - // model = Mapper.MapObject(_incidentRepository.GetIncidentsByProjectID(ProjectID), new IncidentViewModel()); - - // if (model == null) - // { - // Log.Error("Incidents API: IncidentService(GetIncidentsByProjectID); (model == null)"); - // return model; - // } - // else - // { - // // INCIDENTS - // model.IncidentList = (List)GetIncidents(ProjectID); - // return model; - // } - // } - // } - // catch (Exception ex) - // { - // Log.Error("Incidents API: IncidentService(GetIncidentsByProjectID); (" + ex + ")" + " (" + ex.InnerException + ")"); - // return model; - // } - // finally - // { - // } - //} + #region Add Customer | CustomerViewModel + /// + /// Create a new customer for a business from client web application using a CustomerViewModel. + /// + /// + /// + [HttpPost] + public async Task CreateCustomerVMAsync(CustomerViewModel vm) + { + try + { + if (vm == null || vm.CustomerID != 0 || vm.BusinessID == 0)// we could check each condition here and log which is the issue. + { + Log.Error("Customer API: CustomerService(CreateCustomerVMAsync); (vm == null || vm.CustomerID != 0 || vm.BusinessID == 0"); + return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Create the Customer." }; + } + else + { + var entity = new DataModel.Entities.Customer(); + if (entity == null) + { + Log.Error("Customer API: CustomerService(CreateCustomerVMAsync); (entity == null)"); + return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Create the Customer." }; + } + else + { + int? refID; + using (TransactionScope scope = new TransactionScope()) + { + Mapper.MapObject(vm, entity); + _customerRepository.Add(entity); + _customerRepository.SaveChanges(); + refID = entity.CustomerID; + scope.Complete(); + } + return new SaveViewModel(refID); + } + } + } + catch (Exception ex) + { + Log.Error("Customer API: CustomerService(CreateCustomerVMAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); + return new SaveViewModel(ex.Message); + } + finally + { + } + } + #endregion - //BusinessID = 52466; // temp hard coded for testing; need to get from token or pass in as parameter - // var customers = _customerRepository.GetAll(BusinessID).ToList(); + #region Add Customer | Customer + /// + /// CREATE: Customer + /// "CustomerControllerCreateCustomerAsync": "Customer/CreateCustomerAsync" + /// + /// + /// + public async Task CreateCustomerAsync(CustomerModel model) + { + try + { + if (model == null || model.CustomerID != 0 || model.BusinessID == 0)// we could check each condition here and log which is the issue. + { + Log.Error("Customer API: CustomerService(CreateCustomerAsync); (model == null || model.CustomerID != 0 || model.BusinessID == 0"); + return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Create the Customer." }; + } + else + { + var entity = new DataModel.Entities.Customer(); + if (entity == null) + { + Log.Error("Customer API: CustomerService(CreateCustomerAsync); (entity == null)"); + return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Create the Customer." }; + } + else + { + int? refID; + using (TransactionScope scope = new TransactionScope()) + { + Mapper.MapObject(model, entity); + _customerRepository.Add(entity); + _customerRepository.SaveChanges(); + refID = entity.CustomerID; + scope.Complete(); + } + return new SaveViewModel(refID); + } + } + } + catch (Exception ex) + { + Log.Error("Customer API: CustomerService(CreateCustomerAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); + return new SaveViewModel(ex.Message); + } + finally + { + + } - // if (customers == null) - // { - // Log.Error("Customers API: CustomerService(GetAllCustomers); (customers == null"); - // return null; // return empty model? - // } - // else - // { - // return customers.ToList(); - // } - //} + } #endregion @@ -268,6 +338,22 @@ public SaveViewModel DeleteCustomer(int id) + + + + + + + + + + + + + + + + diff --git a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs index d05e87e..13f9d7a 100644 --- a/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs +++ b/MBDEVproAPI.Repository/Interfaces/ICustomerRepository.cs @@ -5,8 +5,12 @@ namespace MBDEVproAPI.Repository.Interfaces public interface ICustomerRepository : IBaseRepository { + Task> GetAllCustomersVMAsync(int BusinessID); + Task> GetAllCustomersAsync(int BusinessID); Task GetCustomerAsync(int CustomerID); + + Task AddAsync(Customer customer); } } diff --git a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs index 7e14af1..1ba6559 100644 --- a/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs +++ b/MBDEVproAPI.Repository/Repositories/CustomerRepository.cs @@ -34,12 +34,21 @@ public CustomerRepository(MBDEVproAPIDbContext context) - #region Get All Customers Async + #region Get All Customers | CustomerViewModel /// /// GET: Get All Customers Async /// /// /// + 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 public async Task> GetAllCustomersAsync(int BusinessID) { var customers = await _context.Customers.Where(O => O.BusinessID == BusinessID).ToListAsync(); @@ -48,7 +57,7 @@ public async Task> GetAllCustomersAsync(int BusinessID) #endregion - #region Get Customer by CustomerID Async + #region Get All Customers | Customer public async Task GetCustomerAsync(int CustomerID) { var customer = await _context.Customers.Where(O => O.CustomerID == CustomerID).FirstOrDefaultAsync(); @@ -66,7 +75,13 @@ public async Task GetCustomerAsync(int CustomerID) - + #region Add Customer Async + public async Task AddAsync(Customer customer) + { + await _context.Customers.AddAsync(customer); + await _context.SaveChangesAsync(); // Non-blocking save + } + #endregion @@ -104,7 +119,7 @@ public Customer GetByID(int BusinessID, int? id) public void Add(Customer obj) { - throw new NotImplementedException(); + _context.Customers.Add(obj); } public void Remove(int BusinessID, Customer obj) @@ -114,9 +129,11 @@ public void Remove(int BusinessID, Customer obj) public void SaveChanges() { - throw new NotImplementedException(); + _context.SaveChanges(); } + + #endregion From e230d1eb9ab41a7dfed396975294dfa17f670d30 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Sun, 1 Mar 2026 17:58:48 -0500 Subject: [PATCH 09/13] More updates --- .../Controllers/CustomerController.cs | 119 ++++---- MBDEVproAPI.API/Program.cs | 2 +- MBDEVproAPI.BLL/GlobalUsings.cs | 1 + .../Interfaces/ICustomerService.cs | 26 +- MBDEVproAPI.BLL/Services/CustomerService.cs | 257 +++++++++++++----- .../Interfaces/IBaseRepository.cs | 2 +- .../Interfaces/ICustomerRepository.cs | 29 +- .../Repositories/CustomerRepository.cs | 84 +++--- 8 files changed, 348 insertions(+), 172 deletions(-) diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index be036be..7792e26 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,9 +105,10 @@ public async Task> GetCustomerAsync(int CustomerID) - #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. /// /// /// @@ -120,13 +117,10 @@ public async Task CreateCustomerVMAsync([FromBody] CustomerViewMo { return Ok(_customerService.CreateCustomerVMAsync(vm)); } - #endregion - - #region Add Customer | Customer /// - /// Create a new customer for a business. + /// Add Customer | CustomerModel | Create a new customer for a business. /// /// /// @@ -141,50 +135,69 @@ 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}")] + #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", + /// + /// + /// CustomerViewModel + [HttpPost] + public async Task EditCustomerVMAsync([FromBody] CustomerViewModel vm) + { + // if model is valid, then update, else return bad request with model state errors. + return Ok(_customerService.EditCustomerVMAsync(vm)); + //return Ok("UNDER CONTRUCTION | EditCustomer(int id, [FromBody] Customer model)"); + } - //[HttpPost] - //public async Task PutCustomer(int id, Customer customer) - //{ - // if (id != customer.CustomerID) - // { - // return BadRequest(); - // } - // _context.Entry(customer).State = EntityState.Modified; + /// + /// EDIT: Customer | CustomerModel | edit a customer for a business. + /// "CustomerControllerEditCustomer": "Customer/EditCustomer" + /// + /// + /// + [HttpPost] + public async Task EditCustomer(int id, [FromBody] CustomerModel model) + { + // if model is valid, then update, else return bad request with model state errors. + return Ok(_customerService.EditCustomer(model)); + } - // try - // { - // await _context.SaveChangesAsync(); - // } - // catch (DbUpdateConcurrencyException) - // { - // if (!CustomerExists(id)) - // { - // return NotFound(); - // } - // else - // { - // throw; - // } - // } + // CustomerModel to just return a CustomerModel instead of a SaveViewModel with the RefID. We could do this for the VM as well. + #endregion - // 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); - //} + #region Delete Customer + /// + /// DELET: Customer | CustomerModel | Delete a customer for a business. + /// "CustomerControllerDeleteCustomer": "Customer/DeleteCustomer" + /// + /// + /// + [HttpDelete("{id:int}")] + public async Task DeleteCustomer(int id) + { + return Ok(_customerService.DeleteCustomer(id)); + } + #endregion + + //#region DELETE: Citation Type + ///// + ///// DELETE: Citation Type + ///// "CitationTypeControllerDeleteCitationType": "CitationType/DeleteCitationType" + ///// + ///// + ///// + //[HttpDelete("{CitationTypeID:int}")] + //public IActionResult DeleteCitationType(int CitationTypeID) + //{ + // return Ok(_citationTypeService.DeleteCitationType(CitationTypeID)); + //} + //#endregion //// DELETE: api/Customer/5 //[HttpDelete("{id}")] diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index 605712f..ea158c6 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -41,7 +41,7 @@ }); }); - +//ADD: API security and authentication (OAuth2, OpenID Connect, JWT) var app = builder.Build(); 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..470b8d2 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 DeleteCustomerVM(int CustomerID); + SaveViewModel DeleteCustomer(int CustomerID); + #endregion } } diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 93c4c29..40d1692 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,189 @@ public SaveViewModel CreateCustomer(CustomerModel model) { throw new NotImplementedException(); } + #endregion + + + #region Edit Customer /// - /// 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." }; + } + 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 | 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." }; + } + 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; + 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 DeleteCustomerVM(int CustomerID) + { + try + { + int? refID = null; + if (CustomerID == 0) + { + Log.Error("Customer API: CustomerService(DeleteCustomerVM); (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(DeleteCustomerVM); (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(EditCustomer) CustomerModel; (" + ex + ")" + " (" + ex.InnerException + ")"); + return new SaveViewModel(ex.Message); + } + finally + { + } + return new SaveViewModel("Customer API: CustomerService(DeleteCustomer); (SaveViewModel) Not Yet Implemented."); + } + + /// + /// DELETE: Customer | CustomerModel | delete a customer for a business and return a SaveViewModel with the RefID of the deleted customer. + /// "CustomerControllerDeleteCustomerVM": "Customer/DeleteCustomerVM" + /// + /// + /// SaveViewModel + public CustomerModel DeleteCustomer(int CustomerID) { throw new NotImplementedException(); + // return new SaveViewModel("Customer API: CustomerService(DeleteCustomer); (SaveViewModel) Not Yet Implemented."); } + SaveViewModel ICustomerService.DeleteCustomer(int CustomerID) + { + throw new NotImplementedException(); + } + #endregion + + + + + + + + #region Other + #endregion } } 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 - - } } From ef1ec9803ebafa8b938df1e6e227e8c25954d630 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Wed, 4 Mar 2026 16:55:53 -0500 Subject: [PATCH 10/13] updates --- .../Controllers/CustomerController.cs | 73 ++++++------------- .../Interfaces/ICustomerService.cs | 4 +- MBDEVproAPI.BLL/Services/CustomerService.cs | 58 ++++++++++----- 3 files changed, 61 insertions(+), 74 deletions(-) diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index 7792e26..5f56de9 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -106,7 +106,7 @@ public async Task> GetCustomerAsync(int CustomerID) - #region Add Customer + #region Create Customer /// /// Add Customer | CustomerViewModel | Create a new customer for a business from client web application using a CustomerViewModel. /// @@ -115,19 +115,22 @@ public async Task> GetCustomerAsync(int CustomerID) [HttpPost] public async Task CreateCustomerVMAsync([FromBody] CustomerViewModel vm) { - return Ok(_customerService.CreateCustomerVMAsync(vm)); + var result = await _customerService.CreateCustomerVMAsync(vm); + return Ok(result); } /// /// 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 @@ -142,27 +145,30 @@ public async Task CreateCustomerAsync([FromBody] CustomerModel mo /// "CustomerControllerEditCustomerVMAsync": "Customer/EditCustomerVMAsync", /// /// - /// CustomerViewModel + /// SaveViewModel [HttpPost] public async Task EditCustomerVMAsync([FromBody] CustomerViewModel vm) { // if model is valid, then update, else return bad request with model state errors. - return Ok(_customerService.EditCustomerVMAsync(vm)); + 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(int id, [FromBody] CustomerModel model) + public async Task EditCustomer([FromBody] CustomerModel model) { // if model is valid, then update, else return bad request with model state errors. - return Ok(_customerService.EditCustomer(model)); + 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. @@ -172,56 +178,19 @@ public async Task EditCustomer(int id, [FromBody] CustomerModel m #region Delete Customer /// - /// DELET: Customer | CustomerModel | Delete a customer for a business. - /// "CustomerControllerDeleteCustomer": "Customer/DeleteCustomer" + /// DELETE: Customer | SaveViewModel | delete a customer for a business and return a SaveViewModel with the RefID of the deleted customer. + /// "CustomerControllerDeleteCustomerVMAsync": "Customer/DeleteCustomerVMAsync" /// /// - /// - [HttpDelete("{id:int}")] - public async Task DeleteCustomer(int id) + /// SaveViewModel + [HttpDelete("{CustomerID:int}")] + public async Task DeleteCustomerVMAsync(int CustomerID) { - return Ok(_customerService.DeleteCustomer(id)); - } + var result = await _customerService.DeleteCustomerVMAsync(CustomerID); + return result; + } #endregion - - - //#region DELETE: Citation Type - ///// - ///// DELETE: Citation Type - ///// "CitationTypeControllerDeleteCitationType": "CitationType/DeleteCitationType" - ///// - ///// - ///// - //[HttpDelete("{CitationTypeID:int}")] - //public IActionResult DeleteCitationType(int CitationTypeID) - //{ - // return Ok(_citationTypeService.DeleteCitationType(CitationTypeID)); - //} - //#endregion - - //// 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); - //} - } - } diff --git a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs index 470b8d2..f8a90a1 100644 --- a/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs +++ b/MBDEVproAPI.BLL/Interfaces/ICustomerService.cs @@ -43,8 +43,8 @@ public interface ICustomerService : IBaseService #region Delete Customer - Task DeleteCustomerVM(int CustomerID); - SaveViewModel DeleteCustomer(int CustomerID); + Task DeleteCustomerVMAsync(int CustomerID); + Task DeleteCustomer(int CustomerID); #endregion } } diff --git a/MBDEVproAPI.BLL/Services/CustomerService.cs b/MBDEVproAPI.BLL/Services/CustomerService.cs index 40d1692..74028ca 100644 --- a/MBDEVproAPI.BLL/Services/CustomerService.cs +++ b/MBDEVproAPI.BLL/Services/CustomerService.cs @@ -289,7 +289,7 @@ public async Task EditCustomerVMAsync(CustomerViewModel vm) if (entity == null) { Log.Error("Customer API: CustomerService(EditCustomerVMAsync); (entity == null)"); - return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer." }; + return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer. (entity == null)" }; } else { @@ -328,7 +328,7 @@ public async Task EditCustomer(CustomerModel model) 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." }; + return new SaveViewModel { IsSaved = false, ErrorMessage = "Please provide details to Edit the Customer. Null Values" }; } else { @@ -341,11 +341,12 @@ public async Task EditCustomer(CustomerModel model) else { int? refID; + refID = entity.CustomerID; using (TransactionScope scope = new TransactionScope()) { Mapper.MapObject(model, entity); _customerRepository.SaveChanges(); - refID = entity.CustomerID; + //refID = entity.CustomerID; scope.Complete(); } return new SaveViewModel(refID); @@ -374,14 +375,14 @@ public async Task EditCustomer(CustomerModel model) /// /// /// SaveViewModel - public async Task DeleteCustomerVM(int CustomerID) + public async Task DeleteCustomerVMAsync(int CustomerID) { try { int? refID = null; if (CustomerID == 0) { - Log.Error("Customer API: CustomerService(DeleteCustomerVM); (CustomerID == 0)"); + Log.Error("Customer API: CustomerService(DeleteCustomerVMAsync); (CustomerID == 0)"); return new SaveViewModel("Please provide details to delete the Customer."); } else @@ -390,7 +391,7 @@ public async Task DeleteCustomerVM(int CustomerID) if (entity == null) { - Log.Error("Customer API: CustomerService(DeleteCustomerVM); (entity == null)"); + Log.Error("Customer API: CustomerService(DeleteCustomerVMAsync); (entity == null)"); return new SaveViewModel("Please provide details to delete the Customer."); } else @@ -408,30 +409,47 @@ public async Task DeleteCustomerVM(int CustomerID) } catch (Exception ex) { - Log.Error("Customer API: CustomerService(EditCustomer) CustomerModel; (" + ex + ")" + " (" + ex.InnerException + ")"); - return new SaveViewModel(ex.Message); + Log.Error("Customer API: CustomerService(DeleteCustomerVMAsync); (" + ex + ")" + " (" + ex.InnerException + ")"); + return new SaveViewModel("Customer API: CustomerService(DeleteCustomerVMAsync); (" + ex + ")" + " (" + ex.InnerException + ") Message: " + ex.Message); } finally { } - return new SaveViewModel("Customer API: CustomerService(DeleteCustomer); (SaveViewModel) Not Yet Implemented."); } /// - /// DELETE: Customer | CustomerModel | delete a customer for a business and return a SaveViewModel with the RefID of the deleted customer. - /// "CustomerControllerDeleteCustomerVM": "Customer/DeleteCustomerVM" + /// DELETE: Customer | CustomerModel | delete a customer for a business. + /// "CustomerControllerDeleteCustomer": "Customer/DeleteCustomer" /// /// /// SaveViewModel - public CustomerModel DeleteCustomer(int CustomerID) - { - throw new NotImplementedException(); - // return new SaveViewModel("Customer API: CustomerService(DeleteCustomer); (SaveViewModel) Not Yet Implemented."); - } - - SaveViewModel ICustomerService.DeleteCustomer(int CustomerID) - { - throw new NotImplementedException(); + 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 From 2ee6ac824c068766854669142cb48c8d957f248f Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Fri, 13 Mar 2026 20:23:36 -0400 Subject: [PATCH 11/13] another publish --- MBDEVproAPI.API/GlobalUsings.cs | 3 +- MBDEVproAPI.API/MBDEVproAPI.API.csproj | 6 +- MBDEVproAPI.API/Program.cs | 54 +++++++++++++---- MBDEVproAPI.API/appsettings.Development.json | 63 +++++++++++--------- MBDEVproAPI.API/appsettings.json | 4 ++ MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj | 2 + 6 files changed, 90 insertions(+), 42 deletions(-) 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..75ed335 100644 --- a/MBDEVproAPI.API/MBDEVproAPI.API.csproj +++ b/MBDEVproAPI.API/MBDEVproAPI.API.csproj @@ -15,7 +15,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -23,7 +23,9 @@ - + + + diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index ea158c6..55a50a9 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 => @@ -45,11 +50,13 @@ 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 Log.Information("MBDEVproAPI: (Development Environment)"); app.UseDeveloperExceptionPage(); @@ -72,16 +79,25 @@ 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.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 + //}); } + + +//DEMO so can test with swagger and scalar UI, can remove later +app.MapOpenApi(); // Expose the OpenAPI JSON endpoint +app.MapScalarApiReference(); // Map the Scalar UI endpoint + +Log.Information("MBDEVproAPI: (Development Environment)"); +//app.UseDeveloperExceptionPage(); // For local only, can change later for testing and production environments, can also add custom error handling middleware for production environment. + app.MapScalarApiReference(options => { options.Title = "MBDEVproAPI v1 .NET CORE 10"; @@ -90,11 +106,25 @@ }); +//DEMO so can test with swagger and scalar UI, can remove later +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.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.BLL/MBDEVproAPI.BLL.csproj b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj index 1cb3782..407cd5d 100644 --- a/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj +++ b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj @@ -16,6 +16,8 @@ + + From 5977cbab103896212d8192e6cd358221020a9790 Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Sat, 30 May 2026 19:29:01 -0400 Subject: [PATCH 12/13] Add description for MBDEVproAPI Added a brief description of the API's architecture and design pattern. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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. From 616cfaaecefd29c8c8954849efbe973e8ad17f8c Mon Sep 17 00:00:00 2001 From: Mike Belcher Date: Tue, 16 Jun 2026 16:50:40 -0400 Subject: [PATCH 13/13] Test_Initial --- .../Controllers/CustomerController.cs | 4 +- MBDEVproAPI.API/MBDEVproAPI.API.csproj | 16 +- MBDEVproAPI.API/Program.cs | 62 ++++---- MBDEVproAPI.API/dotnet-tools.json | 13 ++ MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj | 2 +- MBDEVproAPI.Repository/Class1.cs | 7 - MBDEVproAPI.Tests/CustomerTests.cs | 147 ++++++++++++++++++ MBDEVproAPI.Tests/GlobalUsings.cs | 27 ++++ MBDEVproAPI.Tests/MBDEVproAPI.Tests.csproj | 16 +- MBDEVproAPI.Tests/UnitTest1.cs | 11 -- 10 files changed, 236 insertions(+), 69 deletions(-) create mode 100644 MBDEVproAPI.API/dotnet-tools.json delete mode 100644 MBDEVproAPI.Repository/Class1.cs create mode 100644 MBDEVproAPI.Tests/CustomerTests.cs create mode 100644 MBDEVproAPI.Tests/GlobalUsings.cs delete mode 100644 MBDEVproAPI.Tests/UnitTest1.cs diff --git a/MBDEVproAPI.API/Controllers/CustomerController.cs b/MBDEVproAPI.API/Controllers/CustomerController.cs index 5f56de9..df85ccd 100644 --- a/MBDEVproAPI.API/Controllers/CustomerController.cs +++ b/MBDEVproAPI.API/Controllers/CustomerController.cs @@ -184,10 +184,10 @@ public async Task EditCustomer([FromBody] CustomerModel model) /// /// SaveViewModel [HttpDelete("{CustomerID:int}")] - public async Task DeleteCustomerVMAsync(int CustomerID) + 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 result; + return Ok(result); } #endregion } diff --git a/MBDEVproAPI.API/MBDEVproAPI.API.csproj b/MBDEVproAPI.API/MBDEVproAPI.API.csproj index 75ed335..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 - + @@ -25,8 +25,8 @@ - - + + diff --git a/MBDEVproAPI.API/Program.cs b/MBDEVproAPI.API/Program.cs index 55a50a9..c9b8cd6 100644 --- a/MBDEVproAPI.API/Program.cs +++ b/MBDEVproAPI.API/Program.cs @@ -52,16 +52,31 @@ 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(); + 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)"); @@ -77,44 +92,19 @@ 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 - //}); -} - - - -//DEMO so can test with swagger and scalar UI, can remove later -app.MapOpenApi(); // Expose the OpenAPI JSON endpoint -app.MapScalarApiReference(); // Map the Scalar UI endpoint +//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.UseDeveloperExceptionPage(); // For local only, can change later for testing and production environments, can also add custom error handling middleware for production environment. - -app.MapScalarApiReference(options => -{ - options.Title = "MBDEVproAPI v1 .NET CORE 10"; - options.WithTheme(ScalarTheme.Moon); // Use a specific theme - options.ForceDarkMode(); // Force dark mode -}); - - -//DEMO so can test with swagger and scalar UI, can remove later -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.UseSerilogRequestLogging(); // Add Serilog request logging middleware 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/MBDEVproAPI.BLL.csproj b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj index 407cd5d..de74504 100644 --- a/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj +++ b/MBDEVproAPI.BLL/MBDEVproAPI.BLL.csproj @@ -7,7 +7,7 @@ - + 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.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() - { - - } - } -}