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 | }
|
---|