[17d6948] | 1 | using Microsoft.AspNetCore.Mvc;
|
---|
| 2 | using Microsoft.EntityFrameworkCore;
|
---|
| 3 | using Npgsql;
|
---|
| 4 | using System.Data;
|
---|
| 5 | using Dapper;
|
---|
| 6 | using WineTrackerWebApi.Models.Shipment;
|
---|
| 7 | using WineTrackerWebApi.Models.Wine;
|
---|
| 8 | using WineTrackerWebApi.Models.Customer;
|
---|
| 9 | using WineTrackerWebApi.Models.Vehicle;
|
---|
| 10 | using WineTrackerWebApi.Models.Employee;
|
---|
| 11 | using WineTrackerWebApi.Models.ErrorHandle;
|
---|
| 12 | using WineTrackerWebApi.Helpers;
|
---|
| 13 |
|
---|
| 14 | namespace WineTrackerWebApi.Controllers
|
---|
| 15 | {
|
---|
| 16 | [Route("api/[controller]")]
|
---|
| 17 | [ApiController]
|
---|
| 18 | public class ShipmentController : ControllerBase
|
---|
| 19 | {
|
---|
| 20 | private readonly string _connectionString;
|
---|
| 21 | public ShipmentController(IConfiguration configuration)
|
---|
| 22 | {
|
---|
| 23 | _connectionString = configuration.GetConnectionString("DefaultConnection");
|
---|
| 24 | }
|
---|
| 25 |
|
---|
| 26 | // GET: api/Shipment
|
---|
| 27 | [HttpGet]
|
---|
| 28 | public async Task<ActionResult<IEnumerable<Shipment>>> GetShipment(string shipmentDate ="", string employeeNameSurname = "", string registration="")
|
---|
| 29 | {
|
---|
| 30 | var parameters = new {
|
---|
| 31 | ShipmentDate = !string.IsNullOrEmpty(shipmentDate) ? DateTime.Parse(shipmentDate) : DateTime.MinValue,
|
---|
| 32 | employeeNameSurname = employeeNameSurname.Trim().ToLower(),
|
---|
| 33 | Registration = registration.Trim().ToLower() };
|
---|
| 34 |
|
---|
| 35 | List<string> whereConditons = new List<string>();
|
---|
| 36 | if(!string.IsNullOrEmpty(shipmentDate)) whereConditons.Add("s.shipment_date = @ShipmentDate");
|
---|
| 37 | if(!string.IsNullOrEmpty(employeeNameSurname)) whereConditons.Add("LOWER(CONCAT(e.employee_name, ' ', e.employee_surname)) Like '%' || @employeeNameSurname || '%'");
|
---|
| 38 | if(!string.IsNullOrEmpty(registration)) whereConditons.Add("LOWER(v.registration) = @Registration");
|
---|
| 39 |
|
---|
| 40 | string whereClause = whereConditons.Count > 0 ? "where " + string.Join(" and ", whereConditons) : "";
|
---|
| 41 |
|
---|
| 42 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 43 | {
|
---|
| 44 | string query = $@"
|
---|
| 45 | select
|
---|
| 46 | s.shipment_id as ShipmentId,
|
---|
| 47 | s.payment_id as PaymentId,
|
---|
| 48 | p.payment_status as PaymentStatus,
|
---|
| 49 | TO_CHAR(s.shipment_date, 'DD-MM-YYYY') as ShipmentDate,
|
---|
| 50 | (
|
---|
| 51 | SELECT STRING_AGG(DISTINCT c.customer_name, ', ')
|
---|
| 52 | FROM shipment_load sl
|
---|
| 53 | JOIN customer c ON sl.customer_id = c.customer_id
|
---|
| 54 | WHERE sl.shipment_id = s.shipment_id
|
---|
| 55 | ) as Customers,
|
---|
| 56 | CONCAT(e.employee_name, ' ', e.employee_surname) AS EmployeeFullName,
|
---|
| 57 | CONCAT(vd.make, ' ', vd.model, ' (', v.registration, ')') AS VehicleInfo
|
---|
| 58 | FROM shipment s
|
---|
| 59 | JOIN employee e ON s.employee_id = e.employee_id
|
---|
| 60 | JOIN vehicle v ON s.vehicle_id = v.vehicle_id
|
---|
| 61 | join vehicle_details vd on vd.vehicle_details_id = v.vehicle_details_id
|
---|
| 62 | join payment p on s.payment_id = p.payment_id
|
---|
| 63 | {whereClause}
|
---|
| 64 | ORDER BY s.shipment_date desc";
|
---|
| 65 | var shipments = await db.QueryAsync<Shipment>(query, parameters);
|
---|
| 66 | return Ok(shipments);
|
---|
| 67 | }
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | [HttpGet("getCreateShipmentInfo")]
|
---|
| 71 | public async Task<ActionResult<IEnumerable<Shipment>>> GetCreateShipmentInfo()
|
---|
| 72 | {
|
---|
| 73 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 74 | {
|
---|
| 75 | const string getEmployees = $@"
|
---|
| 76 | select
|
---|
| 77 | e.employee_id as Id,
|
---|
| 78 | CONCAT(e.employee_name, ' ', e.employee_surname) AS Name
|
---|
| 79 | from employee e";
|
---|
| 80 | var employeeList = await db.QueryAsync<EmployeeListElement>(getEmployees);
|
---|
| 81 |
|
---|
| 82 | const string getCustomers = $@"
|
---|
| 83 | select
|
---|
| 84 | c.customer_id as Id,
|
---|
| 85 | CONCAT(c.customer_name , ' (', a.city , ' ', a.street ,' ',a.building_number, ' ', a.postcode, ')') AS Name,
|
---|
| 86 | CONCAT(a.city ,' ', a.street ,' ',a.building_number,' ', a.postcode) AS Address
|
---|
| 87 | from customer c
|
---|
| 88 | join address a on c.address_id = a.address_id";
|
---|
| 89 | var customerList = await db.QueryAsync<CustomerListElement>(getCustomers);
|
---|
| 90 |
|
---|
| 91 | string getWines = $@"
|
---|
| 92 | select
|
---|
| 93 | w.wine_id as Id,
|
---|
| 94 | CONCAT(w.wine_name , ' (', wt.wine_type_name,', ', wt.wine_type_region,')') AS Name,
|
---|
| 95 | w.base_price as BasePrice
|
---|
| 96 | from wine w
|
---|
| 97 | join wine_type wt on w.wine_type_id = wt.wine_type_id";
|
---|
| 98 | var wineList = await db.QueryAsync<WineListElement>(getWines);
|
---|
| 99 |
|
---|
| 100 | string getVehicles = $@"
|
---|
| 101 | select
|
---|
| 102 | v.vehicle_id as Id,
|
---|
| 103 | CONCAT(vd.make, ' ', vd.model, ' (', v.registration, ')') AS Name,
|
---|
| 104 | edv.employee_id as EmployeeId,
|
---|
| 105 | vd.capacity as Capacity
|
---|
| 106 | from employee_drives_vehicle edv
|
---|
| 107 | join vehicle v on edv.vehicle_id = v.vehicle_id
|
---|
| 108 | join vehicle_details vd on v.vehicle_details_id = vd.vehicle_details_id";
|
---|
| 109 | var vehicleList = await db.QueryAsync<VehicleListElement>(getVehicles);
|
---|
| 110 |
|
---|
| 111 | return Ok(new{ employeeList, customerList, wineList, vehicleList });
|
---|
| 112 | }
|
---|
| 113 | }
|
---|
| 114 |
|
---|
| 115 | [HttpPost]
|
---|
| 116 | public async Task<IActionResult> CreateShipment([FromBody]AddShipment shipment)
|
---|
| 117 | {
|
---|
| 118 | try
|
---|
| 119 | {
|
---|
| 120 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 121 | {
|
---|
| 122 |
|
---|
| 123 | db.Open();
|
---|
| 124 | using (var transaction = db.BeginTransaction()) // Start a transaction
|
---|
| 125 | {
|
---|
| 126 | var parameters = new
|
---|
| 127 | {
|
---|
| 128 | VehicleId = int.Parse(shipment.VehicleId),
|
---|
| 129 | ShipmentDate= DateTime.Parse(shipment.ShipmentDate),
|
---|
| 130 | EmployeeId = int.Parse(shipment.EmployeeId)
|
---|
| 131 | };
|
---|
| 132 |
|
---|
| 133 | await ModelValidation.IsVehicleAlreadyBooked((NpgsqlConnection)db, (NpgsqlTransaction)transaction, parameters.VehicleId, parameters.ShipmentDate);
|
---|
| 134 |
|
---|
| 135 | string addPayment = @"INSERT INTO public.Payment (Payment_Status) VALUES (0) RETURNING Payment_Id;";
|
---|
| 136 | var paymentId = await db.ExecuteScalarAsync<int>(addPayment, transaction: transaction);
|
---|
| 137 |
|
---|
| 138 | string addShipment = $@"INSERT INTO public.Shipment (Employee_Id, Payment_Id, Vehicle_Id, Shipment_Date) VALUES (@EmployeeId, {paymentId}, @VehicleId, @ShipmentDate) RETURNING Shipment_Id;";
|
---|
| 139 | var shipmentId = await db.ExecuteScalarAsync<int>(addShipment, parameters, transaction: transaction);
|
---|
| 140 |
|
---|
| 141 | //make a regular nested list for each loop to insert the shipment_load rows
|
---|
| 142 | var updateRows = shipment.Customers.SelectMany(s => s.Wines.Select(x => $"({shipmentId}, {int.Parse(s.CustomerId)}, {x.WineId}, {Math.Round((x.AgreedPrice / x.Quantity), 2)}, {x.BasePrice}, {x.Quantity})")).ToList();
|
---|
| 143 | string updateRowsString = string.Join(",", updateRows);
|
---|
| 144 |
|
---|
| 145 | string addShipmentLoad = $@"INSERT INTO public.shipment_load (Shipment_Id, Customer_Id, Wine_Id, Wine_Agreed_Price, Wine_Base_Price, Wine_Quantity) VALUES {updateRowsString};";
|
---|
| 146 | var shipmentLoadId = await db.ExecuteAsync(addShipmentLoad, transaction: transaction);
|
---|
| 147 |
|
---|
| 148 | transaction.Commit();
|
---|
| 149 |
|
---|
| 150 | return Ok();
|
---|
| 151 | }
|
---|
| 152 | }
|
---|
| 153 | }
|
---|
| 154 | catch (Exception ex)
|
---|
| 155 | {
|
---|
| 156 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 157 | }
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | [HttpGet("getBaseShipmentDetails/{shipmentId}")]
|
---|
| 161 | public async Task<ActionResult<ShipmentBaseDetails>> GetBaseShipmentDetails(string shipmentId)
|
---|
| 162 | {
|
---|
| 163 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 164 | {
|
---|
| 165 | string query = $@"
|
---|
| 166 | SELECT
|
---|
| 167 | s.shipment_id AS ShipmentId,
|
---|
| 168 | p.payment_status AS PaymentStatus,
|
---|
| 169 | CONCAT(e.employee_name, ' ', e.employee_surname) AS EmployeeFullName,
|
---|
| 170 | CONCAT(vd.make, ' ', vd.model, ' (', v.registration, ')') AS VehicleInfo,
|
---|
| 171 | TO_CHAR(s.shipment_date, 'DD-MM-YYYY') AS ShipmentDate,
|
---|
| 172 | COUNT(DISTINCT sl.customer_id) AS NumberOfCustomers,
|
---|
| 173 | SUM(sl.wine_quantity) AS WineQuantityShipped,
|
---|
| 174 | SUM(sl.wine_base_price * sl.wine_quantity) AS ShipmentBasePrice,
|
---|
| 175 | SUM(sl.wine_agreed_price * sl.wine_quantity) AS ShipmentAgreedPrice,
|
---|
| 176 | COALESCE(ex.shipment_expenses, 0) AS ShipmentExpenses,
|
---|
| 177 | ROUND(
|
---|
| 178 | (SUM(sl.wine_agreed_price * sl.wine_quantity) -
|
---|
| 179 | SUM(sl.wine_base_price * sl.wine_quantity) -
|
---|
| 180 | COALESCE(ex.shipment_expenses, 0))::NUMERIC
|
---|
| 181 | , 2) AS ShipmentProfit
|
---|
| 182 | FROM shipment s
|
---|
| 183 | JOIN payment p ON s.payment_id = p.payment_id
|
---|
| 184 | JOIN employee e ON s.employee_id = e.employee_id
|
---|
| 185 | JOIN vehicle v ON s.vehicle_id = v.vehicle_id
|
---|
| 186 | join vehicle_details vd on vd.vehicle_details_id = v.vehicle_details_id
|
---|
| 187 | JOIN shipment_load sl ON s.shipment_id = sl.shipment_id
|
---|
| 188 | LEFT JOIN (SELECT shipment_id, SUM(amount) AS shipment_expenses FROM shipment_has_expense_of_expense_type GROUP BY shipment_id) ex ON s.shipment_id = ex.shipment_id
|
---|
| 189 | WHERE s.shipment_id = {int.Parse(shipmentId)}
|
---|
| 190 | GROUP BY
|
---|
| 191 | s.shipment_id,
|
---|
| 192 | p.payment_status,
|
---|
| 193 | e.employee_name,
|
---|
| 194 | e.employee_surname,
|
---|
| 195 | vd.make,
|
---|
| 196 | vd.model,
|
---|
| 197 | v.registration,
|
---|
| 198 | s.shipment_date,
|
---|
| 199 | ex.shipment_expenses;";
|
---|
| 200 |
|
---|
| 201 | var shipmentDetails = await db.QueryFirstAsync<ShipmentBaseDetails>(query);
|
---|
| 202 | return Ok(shipmentDetails);
|
---|
| 203 | }
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 |
|
---|
| 207 | [HttpGet("getCustomerShipmentDetails/{shipmentId}")]
|
---|
| 208 | public async Task<ActionResult<IEnumerable<ShipmentCustomerDetails>>> GetCustomerShipmentDetails(string shipmentId)
|
---|
| 209 | {
|
---|
| 210 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 211 | {
|
---|
| 212 | string query = $@"
|
---|
| 213 | select
|
---|
| 214 | c.customer_name as CustomerName,
|
---|
| 215 | CONCAT(a.city , ', ', a.street, ', ',a.building_number, ', ', a.postcode) AS CustomerAddress,
|
---|
| 216 | w.wine_name as WineName,
|
---|
| 217 | sl.wine_base_price as WineBasePrice,
|
---|
| 218 | sl.wine_agreed_price as WineAgreedPrice,
|
---|
| 219 | sl.wine_quantity as WineQuantity
|
---|
| 220 | from shipment_load sl
|
---|
| 221 | join customer c on sl.customer_id = c.customer_id
|
---|
| 222 | join address a on c.address_id = a.address_id
|
---|
| 223 | join wine w on sl.wine_id = w.wine_id
|
---|
| 224 | where sl.shipment_id = {int.Parse(shipmentId)}";
|
---|
| 225 |
|
---|
| 226 | var shipmentCustomerDetails = await db.QueryAsync<ShipmentCustomerDetails>(query);
|
---|
| 227 | return Ok(shipmentCustomerDetails);
|
---|
| 228 | }
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | // PUT: api/Shipment/PayShipment/5
|
---|
| 232 | // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
---|
| 233 | [HttpPut("PayShipment/{paymentId}")]
|
---|
| 234 | public async Task<IActionResult> PayShipment(int paymentId)
|
---|
| 235 | {
|
---|
| 236 | try
|
---|
| 237 | {
|
---|
| 238 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 239 | {
|
---|
| 240 | var parameters = new { PaymentId = paymentId };
|
---|
| 241 |
|
---|
| 242 | string query = $@"update payment set payment_status = 1 where payment_Id = @PaymentId";
|
---|
| 243 | await db.ExecuteAsync(query, parameters);
|
---|
| 244 |
|
---|
| 245 | return Ok();
|
---|
| 246 | }
|
---|
| 247 | }
|
---|
| 248 | catch (Exception ex)
|
---|
| 249 | {
|
---|
| 250 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 251 | }
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | // PUT: api/Shipment/AddShipmentExpense
|
---|
| 255 | // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
---|
| 256 | [HttpPost("AddShipmentExpense")]
|
---|
| 257 | public async Task<IActionResult> AddShipmentExpense([FromBody] ShipmentExpense shipmentExpense)
|
---|
| 258 | {
|
---|
| 259 | try
|
---|
| 260 | {
|
---|
| 261 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 262 | {
|
---|
| 263 | var parameters = new { ShipmentId = shipmentExpense.ShipmentId, ExpenseTypeId = shipmentExpense.ExpenseTypeId, Amount = shipmentExpense.Amount };
|
---|
| 264 |
|
---|
| 265 | string query = $@"insert into shipment_has_expense_of_expense_type (expense_type_id, shipment_id, amount) values (@ExpenseTypeId, @ShipmentId, @Amount)";
|
---|
| 266 | await db.ExecuteAsync(query, parameters);
|
---|
| 267 |
|
---|
| 268 | return Ok();
|
---|
| 269 | }
|
---|
| 270 | }
|
---|
| 271 | catch (Exception ex)
|
---|
| 272 | {
|
---|
| 273 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 274 | }
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 | // GET: api/Shipment/GetShipmentExpenses/5
|
---|
| 278 | [HttpGet("GetShipmentExpenses/{shipmentId}")]
|
---|
| 279 | public async Task<ActionResult<IEnumerable<ShipmentExpense>>> GetShipmentExpenses(int shipmentId)
|
---|
| 280 | {
|
---|
| 281 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 282 | {
|
---|
| 283 | var parameters = new { ShipmentId = shipmentId };
|
---|
| 284 |
|
---|
| 285 | const string query = $@"
|
---|
| 286 | select
|
---|
| 287 | sheoet.shipment_id as ShipmentId,
|
---|
| 288 | sheoet.expense_type_id as ExpenseTypeId,
|
---|
| 289 | et.expense_type_name as ExpenseTypeName,
|
---|
| 290 | sheoet.amount as Amount
|
---|
| 291 | from shipment_has_expense_of_expense_type sheoet
|
---|
| 292 | join expense_type et on et.expense_type_id = sheoet.expense_type_id
|
---|
| 293 | where sheoet.shipment_id = @ShipmentId
|
---|
| 294 | ";
|
---|
| 295 | var vehicleDetails = await db.QueryAsync<ShipmentExpense>(query, parameters);
|
---|
| 296 | return Ok(vehicleDetails);
|
---|
| 297 | }
|
---|
| 298 | }
|
---|
| 299 |
|
---|
| 300 | // DELETE: api/Shipment/removeShipmentExpense/5
|
---|
| 301 | [HttpDelete("removeShipmentExpense/{shipmentId}/{expenseTypeId}")]
|
---|
| 302 | public async Task<IActionResult> RemoveShipmentExpense(int shipmentId, int expenseTypeId)
|
---|
| 303 | {
|
---|
| 304 | try
|
---|
| 305 | {
|
---|
| 306 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 307 | {
|
---|
| 308 | var parameters = new { ShipmentId = shipmentId, ExpenseTypeId = expenseTypeId };
|
---|
| 309 |
|
---|
| 310 | string query = $@"delete from shipment_has_expense_of_expense_type where shipment_id = @ShipmentId and expense_type_id = @ExpenseTypeId";
|
---|
| 311 | await db.ExecuteAsync(query, parameters);
|
---|
| 312 | return Ok();
|
---|
| 313 | }
|
---|
| 314 | }
|
---|
| 315 | catch (Exception ex)
|
---|
| 316 | {
|
---|
| 317 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 318 | }
|
---|
| 319 | }
|
---|
| 320 |
|
---|
| 321 | // DELETE: api/Shipment/deleteShipment/5
|
---|
| 322 | [HttpDelete("deleteShipment/{shipmentId}/{paymentId}")]
|
---|
| 323 | public async Task<IActionResult> DeleteShipment(int shipmentId, int paymentId)
|
---|
| 324 | {
|
---|
| 325 | try
|
---|
| 326 | {
|
---|
| 327 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 328 | {
|
---|
| 329 | db.Open();
|
---|
| 330 | using (var transaction = db.BeginTransaction()) // Start a transaction
|
---|
| 331 | {
|
---|
| 332 | var parameters = new { ShipmentId = shipmentId, PaymentId = paymentId };
|
---|
| 333 |
|
---|
| 334 | string deleteShipmentExpenses = $@"delete from shipment_has_expense_of_expense_type where shipment_id = @ShipmentId";
|
---|
| 335 | await db.ExecuteAsync(deleteShipmentExpenses, parameters, transaction: transaction);
|
---|
| 336 |
|
---|
| 337 | string deleteShipmentLoads = $@"delete from shipment_load where shipment_id = @ShipmentId";
|
---|
| 338 | await db.ExecuteAsync(deleteShipmentLoads, parameters, transaction: transaction);
|
---|
| 339 |
|
---|
| 340 | string deleteShipment = $@"delete from shipment where shipment_id = @ShipmentId";
|
---|
| 341 | await db.ExecuteAsync(deleteShipment, parameters, transaction: transaction);
|
---|
| 342 |
|
---|
| 343 | string deletePayment = $@"delete from payment where payment_id = @PaymentId";
|
---|
| 344 | await db.ExecuteAsync(deletePayment, parameters, transaction: transaction);
|
---|
| 345 |
|
---|
| 346 | transaction.Commit();
|
---|
| 347 | return Ok();
|
---|
| 348 | }
|
---|
| 349 | }
|
---|
| 350 | }
|
---|
| 351 | catch (Exception ex)
|
---|
| 352 | {
|
---|
| 353 | return BadRequest(new ErrorHandler { Name = "Error", Description = ex.Message });
|
---|
| 354 | }
|
---|
| 355 | }
|
---|
| 356 |
|
---|
| 357 | // GET: api/Shipment/GetEditableShipment/5
|
---|
| 358 | [HttpGet("GetEditableShipment/{shipmentId}")]
|
---|
| 359 | public async Task<ActionResult<IEnumerable<AddShipment>>> GetEditableShipment(int shipmentId)
|
---|
| 360 | {
|
---|
| 361 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 362 | {
|
---|
| 363 | var parameters = new { ShipmentId = shipmentId };
|
---|
| 364 |
|
---|
| 365 | string getShipment = $@"
|
---|
| 366 | select
|
---|
| 367 | shipment_id as ShipmentId,
|
---|
| 368 | TO_CHAR(shipment_date , 'yyyy-MM-dd') as ShipmentDate,
|
---|
| 369 | employee_id as EmployeeId,
|
---|
| 370 | vehicle_id as VehicleId
|
---|
| 371 | from shipment s
|
---|
| 372 | where shipment_id = @ShipmentId";
|
---|
| 373 | var editableShipment = await db.QueryFirstAsync<AddShipment>(getShipment, parameters);
|
---|
| 374 |
|
---|
| 375 | string getCustomersPerShipment = $@"
|
---|
| 376 | select distinct
|
---|
| 377 | c.customer_id as CustomerId
|
---|
| 378 | from shipment_load sl
|
---|
| 379 | join customer c on sl.customer_id = c.customer_id
|
---|
| 380 | where sl.shipment_id = @ShipmentId";
|
---|
| 381 |
|
---|
| 382 | var customersPerShipmentIds = await db.QueryAsync<AddCustomerToShipment>(getCustomersPerShipment, parameters);
|
---|
| 383 |
|
---|
| 384 | var wineParameters = new { CustomerIds = customersPerShipmentIds.Select(x => int.Parse(x.CustomerId)).ToList(), ShipmentId = shipmentId };
|
---|
| 385 |
|
---|
| 386 | string getWinesPerCustomer = $@"
|
---|
| 387 | select
|
---|
| 388 | sl.wine_id as WineId,
|
---|
| 389 | customer_id as CustomerId,
|
---|
| 390 | sl.wine_quantity as Quantity,
|
---|
| 391 | sl.wine_agreed_price * sl.wine_quantity as AgreedPrice,
|
---|
| 392 | sl.wine_base_price as BasePrice
|
---|
| 393 | from shipment_load sl
|
---|
| 394 | WHERE sl.customer_id = ANY(@CustomerIds) and sl.shipment_id = @ShipmentId";
|
---|
| 395 | var winesPerCustomersDynamic = await db.QueryAsync<dynamic>(getWinesPerCustomer, wineParameters);
|
---|
| 396 |
|
---|
| 397 | var customersPerShipmentMapped = winesPerCustomersDynamic.GroupBy(x => (int)x.customerid).Select(x => new AddCustomerToShipment
|
---|
| 398 | {
|
---|
| 399 | CustomerId = x.Key.ToString(),
|
---|
| 400 | Wines = x.Select(y => new AddWineToShipment
|
---|
| 401 | {
|
---|
| 402 | WineId = y.wineid.ToString(),
|
---|
| 403 | Quantity = y.quantity,
|
---|
| 404 | AgreedPrice = (decimal)y.agreedprice,
|
---|
| 405 | BasePrice = (decimal)y.baseprice
|
---|
| 406 | }).ToList()
|
---|
| 407 | }).ToList();
|
---|
| 408 |
|
---|
| 409 | editableShipment.Customers = customersPerShipmentMapped;
|
---|
| 410 |
|
---|
| 411 | return Ok(editableShipment);
|
---|
| 412 | }
|
---|
| 413 | }
|
---|
| 414 |
|
---|
| 415 | [HttpPost("EditShipment")]
|
---|
| 416 | public async Task<ActionResult<bool>> EditShipment([FromBody] AddShipment shipment)
|
---|
| 417 | {
|
---|
| 418 | try
|
---|
| 419 | {
|
---|
| 420 | using (IDbConnection db = new NpgsqlConnection(_connectionString)) // Use NpgsqlConnection for PostgreSQL
|
---|
| 421 | {
|
---|
| 422 | db.Open();
|
---|
| 423 | using (var transaction = db.BeginTransaction()) // Start a transaction
|
---|
| 424 | {
|
---|
| 425 | var parameters = new {
|
---|
| 426 | ShipmentId = int.Parse(shipment.ShipmentId),
|
---|
| 427 | EmployeeId = int.Parse(shipment.EmployeeId),
|
---|
| 428 | VehicleId = int.Parse(shipment.VehicleId),
|
---|
| 429 | ShipmentDate = DateTime.Parse(shipment.ShipmentDate)
|
---|
| 430 | };
|
---|
| 431 |
|
---|
| 432 | await ModelValidation.IsVehicleAlreadyBooked((NpgsqlConnection)db, (NpgsqlTransaction)transaction, parameters.VehicleId, parameters.ShipmentDate, parameters.ShipmentId);
|
---|
| 433 |
|
---|
| 434 | string editShipment = $@"
|
---|
| 435 | update public.Shipment
|
---|
| 436 | set
|
---|
| 437 | Employee_Id = @EmployeeId,
|
---|
| 438 | Vehicle_Id = @VehicleId,
|
---|
| 439 | Shipment_Date = @ShipmentDate
|
---|
| 440 | where shipment_id = @ShipmentId";
|
---|
| 441 |
|
---|
| 442 | await db.ExecuteAsync(editShipment, parameters, transaction: transaction);
|
---|
| 443 |
|
---|
| 444 | string deleteShipmentLoads = $@"delete from shipment_load where shipment_id = @ShipmentId";
|
---|
| 445 | await db.ExecuteAsync(deleteShipmentLoads, parameters, transaction: transaction);
|
---|
| 446 |
|
---|
| 447 | //make a regular nested for each loop to insert the shipment_load rows
|
---|
| 448 | var updateRows = shipment.Customers.SelectMany(s => s.Wines.Select(x => $"({int.Parse(shipment.ShipmentId)}, {int.Parse(s.CustomerId)}, {x.WineId}, {Math.Round((x.AgreedPrice / x.Quantity), 2)}, {x.BasePrice}, {x.Quantity})")).ToList();
|
---|
| 449 | string updateRowsString = string.Join(",", updateRows);
|
---|
| 450 |
|
---|
| 451 | string addShipmentLoad = $@"INSERT INTO public.shipment_load (Shipment_Id, Customer_Id, Wine_Id, Wine_Agreed_Price, Wine_Base_Price, Wine_Quantity) VALUES {updateRowsString};";
|
---|
| 452 | var shipmentLoadId = await db.ExecuteAsync(addShipmentLoad, transaction: transaction);
|
---|
| 453 |
|
---|
| 454 | transaction.Commit();
|
---|
| 455 |
|
---|
| 456 | return Ok(true);
|
---|
| 457 | }
|
---|
| 458 | }
|
---|
| 459 | }
|
---|
| 460 | catch (Exception ex)
|
---|
| 461 | {
|
---|
| 462 | return BadRequest(ex.Message);
|
---|
| 463 | }
|
---|
| 464 | }
|
---|
| 465 | }
|
---|
| 466 | }
|
---|