[17d6948] | 1 | using System.Data;
|
---|
| 2 | using Dapper;
|
---|
| 3 | using Microsoft.AspNetCore.Mvc;
|
---|
| 4 | using Microsoft.EntityFrameworkCore;
|
---|
| 5 | using Npgsql;
|
---|
| 6 | using WineTrackerWebApi.Helpers;
|
---|
| 7 | using WineTrackerWebApi.Models.Address;
|
---|
| 8 | using WineTrackerWebApi.Models.Customer;
|
---|
| 9 | using WineTrackerWebApi.Models.ErrorHandle;
|
---|
| 10 |
|
---|
| 11 | namespace WineTrackerWebApi.Controllers
|
---|
| 12 | {
|
---|
| 13 | [Route("api/[controller]")]
|
---|
| 14 | [ApiController]
|
---|
| 15 | public class CustomerController : ControllerBase
|
---|
| 16 | {
|
---|
| 17 | private readonly string _connectionString;
|
---|
| 18 |
|
---|
| 19 | public CustomerController(IConfiguration configuration)
|
---|
| 20 | {
|
---|
| 21 | _connectionString = configuration.GetConnectionString("DefaultConnection");
|
---|
| 22 | }
|
---|
| 23 |
|
---|
| 24 | // GET: api/Customer
|
---|
| 25 | [HttpGet]
|
---|
| 26 | public async Task<ActionResult<IEnumerable<CustomerDetails>>> GetCustomer()
|
---|
| 27 | {
|
---|
| 28 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 29 | {
|
---|
| 30 | const string query = $@"
|
---|
| 31 | select
|
---|
| 32 | c.customer_Id as CustomerId,
|
---|
| 33 | c.customer_name as CustomerName,
|
---|
| 34 | ct.customer_type_name as CustomerTypeName,
|
---|
| 35 | c.customer_email as CustomerEmail,
|
---|
| 36 | c.customer_phone_number as CustomerPhoneNumber,
|
---|
| 37 | a.address_Id as AddressId,
|
---|
| 38 | concat(a.street,' ', a.building_number, ', ', a.city, ' ', a.postcode) as CustomerAddress
|
---|
| 39 | from customer c
|
---|
| 40 | join address a on c.address_id = a.address_id
|
---|
| 41 | join customer_type ct on c.customer_type_id = ct.customer_type_id";
|
---|
| 42 | var customers = await db.QueryAsync<CustomerDetails>(query);
|
---|
| 43 | return Ok(customers);
|
---|
| 44 | }
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | // GET: api/Customer/5
|
---|
| 48 | [HttpGet("{id}")]
|
---|
| 49 | public async Task<ActionResult<Customer>> GetCustomer(int id)
|
---|
| 50 | {
|
---|
| 51 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 52 | {
|
---|
| 53 | var parameters = new { id = id };
|
---|
| 54 |
|
---|
| 55 | string query = $@"
|
---|
| 56 | select
|
---|
| 57 | c.customer_Id as CustomerId,
|
---|
| 58 | c.customer_name as CustomerName,
|
---|
| 59 | c.customer_type_id as CustomerTypeId,
|
---|
| 60 | c.customer_email as CustomerEmail,
|
---|
| 61 | c.customer_phone_number as CustomerPhoneNumber,
|
---|
| 62 | a.address_Id as AddressId,
|
---|
| 63 | a.street as Street,
|
---|
| 64 | a.building_number as BuildingNumber,
|
---|
| 65 | a.city as City,
|
---|
| 66 | a.postcode as PostCode
|
---|
| 67 | from customer c
|
---|
| 68 | join address a on c.address_id = a.address_id
|
---|
| 69 | where c.customer_id = @id";
|
---|
| 70 |
|
---|
| 71 | var result = await db.QueryFirstAsync<dynamic>(query, parameters);
|
---|
| 72 |
|
---|
| 73 | var customer = new Customer
|
---|
| 74 | {
|
---|
| 75 | CustomerId = result.customerid,
|
---|
| 76 | CustomerName = result.customername,
|
---|
| 77 | CustomerTypeId = result.customertypeid,
|
---|
| 78 | CustomerEmail = result.customeremail,
|
---|
| 79 | CustomerPhoneNumber = result.customerphonenumber,
|
---|
| 80 | Address = new Address
|
---|
| 81 | {
|
---|
| 82 | AddressId = result.addressid,
|
---|
| 83 | Street = result.street,
|
---|
| 84 | BuildingNumber = result.buildingnumber,
|
---|
| 85 | City = result.city,
|
---|
| 86 | PostCode = result.postcode
|
---|
| 87 | }
|
---|
| 88 | };
|
---|
| 89 |
|
---|
| 90 | return Ok(customer);
|
---|
| 91 | }
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | // PUT: api/Customer/5
|
---|
| 95 | // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
---|
| 96 | [HttpPut]
|
---|
| 97 | public async Task<IActionResult> PutCustomer([FromBody] Customer customer)
|
---|
| 98 | {
|
---|
| 99 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 100 | {
|
---|
| 101 | try
|
---|
| 102 | {
|
---|
| 103 | db.Open();
|
---|
| 104 | using (var transaction = db.BeginTransaction()) // Start a transaction
|
---|
| 105 | {
|
---|
| 106 | var parameters = new
|
---|
| 107 | {
|
---|
| 108 | CustomerId = customer.CustomerId,
|
---|
| 109 | CustomerName = customer.CustomerName.Trim(),
|
---|
| 110 | CustomerTypeId = customer.CustomerTypeId,
|
---|
| 111 | CustomerEmail = customer.CustomerEmail.Trim(),
|
---|
| 112 | CustomerPhoneNumber = customer.CustomerPhoneNumber.Trim(),
|
---|
| 113 | Street = customer.Address.Street.Trim(),
|
---|
| 114 | BuildingNumber = customer.Address.BuildingNumber,
|
---|
| 115 | City = customer.Address.City.Trim(),
|
---|
| 116 | Postcode = customer.Address.PostCode.Trim(),
|
---|
| 117 | AddressId = customer.Address.AddressId
|
---|
| 118 | };
|
---|
| 119 |
|
---|
| 120 | await ModelValidation.DoesEntityExistByName((NpgsqlConnection)db, (NpgsqlTransaction)transaction, "Customer", parameters.CustomerName, entityId: parameters.CustomerTypeId);
|
---|
| 121 |
|
---|
| 122 | string updateCustomer = $@"
|
---|
| 123 | update customer
|
---|
| 124 | set
|
---|
| 125 | customer_name = @CustomerName,
|
---|
| 126 | customer_type_id = @CustomerTypeId,
|
---|
| 127 | customer_email = @CustomerEmail,
|
---|
| 128 | customer_phone_number = @CustomerPhoneNumber
|
---|
| 129 | where customer_Id = @CustomerId";
|
---|
| 130 |
|
---|
| 131 | var updatedCustomerRows = await db.ExecuteAsync(updateCustomer, parameters, transaction: transaction);
|
---|
| 132 |
|
---|
| 133 | string updateAddress = $@"
|
---|
| 134 | update Address
|
---|
| 135 | set
|
---|
| 136 | Street = @Street,
|
---|
| 137 | Building_Number = @BuildingNumber,
|
---|
| 138 | City = @City,
|
---|
| 139 | PostCode = @Postcode
|
---|
| 140 | where Address_Id = @AddressId";
|
---|
| 141 |
|
---|
| 142 | var updatedAddressRows = await db.ExecuteAsync(updateAddress, parameters, transaction: transaction);
|
---|
| 143 |
|
---|
| 144 | transaction.Commit();
|
---|
| 145 |
|
---|
| 146 | return Ok();
|
---|
| 147 | }
|
---|
| 148 | }
|
---|
| 149 | catch (Exception ex)
|
---|
| 150 | {
|
---|
| 151 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 152 | }
|
---|
| 153 | }
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | // POST: api/Customer
|
---|
| 157 | // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
---|
| 158 | [HttpPost]
|
---|
| 159 | public async Task<IActionResult> PostCustomer([FromBody] Customer customer)
|
---|
| 160 | {
|
---|
| 161 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 162 | {
|
---|
| 163 | try
|
---|
| 164 | {
|
---|
| 165 | db.Open();
|
---|
| 166 | using (var transaction = db.BeginTransaction()) // Start a transaction
|
---|
| 167 | {
|
---|
| 168 | var parameters = new
|
---|
| 169 | {
|
---|
| 170 | CustomerName = customer.CustomerName.Trim(),
|
---|
| 171 | CustomerTypeId = customer.CustomerTypeId,
|
---|
| 172 | CustomerEmail = customer.CustomerEmail.Trim(),
|
---|
| 173 | CustomerPhoneNumber = customer.CustomerPhoneNumber.Trim(),
|
---|
| 174 | Street = customer.Address.Street.Trim(),
|
---|
| 175 | BuildingNumber = customer.Address.BuildingNumber,
|
---|
| 176 | City = customer.Address.City.Trim(),
|
---|
| 177 | Postcode = customer.Address.PostCode.Trim(),
|
---|
| 178 | };
|
---|
| 179 |
|
---|
| 180 | await ModelValidation.DoesEntityExistByName((NpgsqlConnection)db, (NpgsqlTransaction)transaction, "Customer", parameters.CustomerName);
|
---|
| 181 |
|
---|
| 182 | string addAddress = @"INSERT INTO public.Address (Street, Building_Number, City, PostCode) VALUES (@Street, @BuildingNumber, @City, @Postcode) RETURNING Address_Id;";
|
---|
| 183 | var addressId = await db.ExecuteScalarAsync<int>(addAddress, parameters, transaction: transaction);
|
---|
| 184 |
|
---|
| 185 | string addCustomer = $@"
|
---|
| 186 | INSERT INTO public.Customer (Customer_Name, Customer_Email, Customer_Phone_Number, Customer_Type_Id, Address_Id)
|
---|
| 187 | VALUES (@CustomerName, @CustomerEmail, @CustomerPhoneNumber, @CustomerTypeId, {addressId});";
|
---|
| 188 |
|
---|
| 189 | var addressAddedRows = await db.ExecuteAsync(addCustomer, parameters, transaction: transaction);
|
---|
| 190 |
|
---|
| 191 | transaction.Commit();
|
---|
| 192 |
|
---|
| 193 | return Ok();
|
---|
| 194 | }
|
---|
| 195 | }
|
---|
| 196 | catch (Exception ex)
|
---|
| 197 | {
|
---|
| 198 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 199 | }
|
---|
| 200 | }
|
---|
| 201 | }
|
---|
| 202 |
|
---|
| 203 | // DELETE: api/Customer/5
|
---|
| 204 | [HttpDelete("{customerId}/{addressId}")]
|
---|
| 205 | public async Task<IActionResult> DeleteCustomer(int customerId, int addressId)
|
---|
| 206 | {
|
---|
| 207 | try
|
---|
| 208 | {
|
---|
| 209 | //Check if there is a shipment load linked to the customer we are trying to delete, if so return a message and dont let the user delete the customer.
|
---|
| 210 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 211 | {
|
---|
| 212 | db.Open();
|
---|
| 213 | using (var transaction = db.BeginTransaction()) // Start a transaction
|
---|
| 214 | {
|
---|
| 215 | var parameters = new { customerId = customerId, addressId = addressId };
|
---|
| 216 |
|
---|
| 217 | string customerLinkToShipmentLoadQuery = $@"
|
---|
| 218 | select count(*)
|
---|
| 219 | from shipment_load sl
|
---|
| 220 | where customer_id = @customerId";
|
---|
| 221 |
|
---|
| 222 | var isCustomerLinkedToShipmentLoad = await db.QueryFirstAsync<int>(customerLinkToShipmentLoadQuery, parameters, transaction: transaction);
|
---|
| 223 |
|
---|
| 224 | if (isCustomerLinkedToShipmentLoad > 0)
|
---|
| 225 | return BadRequest(new ErrorHandler { Name = "Customer Cannot Be Deleted", Description = "Customer cannot be deleted because it is linked to a shipment load" });
|
---|
| 226 |
|
---|
| 227 | string deleteCustomer = $@"delete from customer where customer_id = @customerId";
|
---|
| 228 | string deleteAddress = $@"delete from address where address_Id = @addressId";
|
---|
| 229 |
|
---|
| 230 | int customerDeletedRows = await db.ExecuteAsync(deleteCustomer, parameters, transaction: transaction);
|
---|
| 231 | int addressDeletedRows = await db.ExecuteAsync(deleteAddress, parameters, transaction: transaction);
|
---|
| 232 |
|
---|
| 233 | transaction.Commit();
|
---|
| 234 | return Ok();
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
| 237 | }
|
---|
| 238 | catch (Exception ex)
|
---|
| 239 | {
|
---|
| 240 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 241 | }
|
---|
| 242 | }
|
---|
| 243 | }
|
---|
| 244 | }
|
---|