· 6 years ago · Oct 13, 2019, 03:18 PM
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using SmartParkingApp;
6
7namespace ParkingApp
8{
9 class ParkingManager
10 {
11 /* BASIC PART */
12 private List<ParkingSession> _activeParkingSessions = new List<ParkingSession>();
13
14 private List<ParkingSession> _completedParkingSessions = new List<ParkingSession>();
15
16 private List<User> _users = new List<User>();
17
18
19 public List<Tariff> tariffs = new List<Tariff>{
20 new Tariff(15, 0),
21 new Tariff(60, 50),
22 new Tariff(120, 100),
23 new Tariff(180, 140),
24 new Tariff(240, 180),
25 new Tariff(600, 350)
26 };
27
28 public int capacity = 10;
29
30 public int freeleaveperiod = 15;
31
32 public int ticketNumber = 1;
33
34 public ParkingSession getSessionByTicket(int ticketNumber, List<ParkingSession> sessionList)
35 {
36 foreach (var s in sessionList)
37 {
38 if (s.TicketNumber == ticketNumber)
39 return s;
40 }
41 return null;
42 }
43 public ParkingSession EnterParking(string carPlateNumber)
44 {
45 /* Check that there is a free parking place (by comparing the parking capacity
46 * with the number of active parking sessions). If there are no free places, return null
47 *
48 * Also check that there are no existing active sessions with the same car plate number,
49 * if such session exists, also return null
50 *
51 * Otherwise:
52 * Create a new Parking session, fill the following properties:
53 * EntryDt = current date time
54 * CarPlateNumber = carPlateNumber (from parameter)
55 * TicketNumber = unused parking ticket number = generate this programmatically
56 *
57 * Add the newly created session to the list of active sessions
58 *
59 * Advanced task:
60 * Link the new parking session to an existing user by car plate number (if such user exists)
61 */
62
63 ParkingSession currentSession;
64 if (_activeParkingSessions.Count < capacity)
65 {
66 foreach (ParkingSession session in _activeParkingSessions)
67 {
68 if (carPlateNumber == session.CarPlateNumber)
69 {
70 return null;
71 }
72 }
73 currentSession = new ParkingSession(DateTime.Now, carPlateNumber, ticketNumber++);
74 _activeParkingSessions.Add(currentSession);
75 loadToFile();
76 return currentSession;
77 }
78 else {
79 return null;
80 }
81 }
82
83 public bool TryLeaveParkingWithTicket(int ticketNumber, out ParkingSession session)
84 {
85 /*
86 * Check that the car leaves parking within the free leave period
87 * from the PaymentDt (or if there was no payment made, from the EntryDt)
88 * 1. If yes:
89 * 1.1 Complete the parking session by setting the ExitDt property
90 * 1.2 Move the session from the list of active sessions to the list of past sessions *
91 * 1.3 return true and the completed parking session object in the out parameter
92 *
93 * 2. Otherwise, return false, session = null
94 */
95 TimeSpan? interval;
96 session = getSessionByTicket(ticketNumber, _activeParkingSessions);
97 //session = _activeParkingSessions.FirstOrDefault(x => x.TicketNumber == ticketNumber);
98 int sessionId = _activeParkingSessions.IndexOf(session);
99 if (session != null)
100 {
101 if (session.PaymentDt != null)
102 {
103 interval = DateTime.Now - session.PaymentDt;
104 }
105 else
106 {
107 interval = DateTime.Now - session.EntryDt;
108 }
109 if (interval.Value.TotalMinutes <= freeleaveperiod)
110 {
111 _activeParkingSessions.RemoveAt(sessionId);
112 session.ExitDt = DateTime.Now;
113 _completedParkingSessions.Add(session);
114 loadToFile();
115 return true;
116 }
117 else
118 {
119 session = null;
120 return false;
121 }
122 }
123 else
124 {
125 session = null;
126 return false;
127 }
128
129 }
130
131 public decimal GetRemainingCost(int ticketNumber)
132 {
133 /* Return the amount to be paid for the parking
134 * If a payment had already been made but additional charge was then given
135 * because of a late exit, this method should return the amount
136 * that is yet to be paid (not the total charge)
137 */
138 TimeSpan? interval;
139 var session = getSessionByTicket(ticketNumber, _activeParkingSessions);
140 //var session = _activeParkingSessions.FirstOrDefault(x => x.TicketNumber == ticketNumber);
141 if (session != null)
142 {
143 if (session.PaymentDt != null)
144 {
145 interval = DateTime.Now - session.PaymentDt;
146 }
147 else
148 {
149 interval = DateTime.Now - session.EntryDt;
150 }
151 decimal time = Convert.ToDecimal(interval.Value.TotalMinutes);
152 foreach (Tariff elem in tariffs)
153 {
154 if (time - elem.Minutes < 0 || time > Convert.ToDecimal(tariffs[5].Minutes))
155 {
156 return elem.Rate;
157 }
158 }
159 return 0;
160 }
161 else
162 {
163 return 0;
164 }
165 }
166
167 public void PayForParking(int ticketNumber, decimal amount)
168 {
169 /*
170 * Save the payment details in the corresponding parking session
171 * Set PaymentDt to current date and time
172 *
173 * For simplicity we won't make any additional validation here and always
174 * assume that the parking charge is paid in full
175 */
176 //var session = _activeParkingSessions.FirstOrDefault(x => x.TicketNumber == ticketNumber);
177 var session = getSessionByTicket(ticketNumber, _activeParkingSessions);
178 session.TotalPayment += amount;
179 session.PaymentDt = DateTime.Now;
180 loadToFile();
181 }
182
183 public void loadToFile()
184 {
185 using (StreamWriter sw = new StreamWriter("Information.txt", false))
186 {
187 sw.WriteLine($"PARKING CAPACITY: {capacity}");
188 sw.WriteLine($"AVALIABLE: {capacity - _activeParkingSessions.Count}");
189 sw.WriteLine("SESSIONS");
190 sw.WriteLine($"Active:");
191 foreach (ParkingSession session in _activeParkingSessions)
192 {
193 sw.WriteLine($"EntryDt: {session.EntryDt}, CarPlateNumber: {session.CarPlateNumber}, TicketNumber: {session.TicketNumber}");
194 }
195 sw.WriteLine($"Completed");
196 foreach (ParkingSession session in _completedParkingSessions)
197 {
198 sw.WriteLine($"EntryDt: {session.EntryDt}, PaymentDt: {session.PaymentDt}, ExitDt: {session.ExitDt}," +
199 $"TotalPayment: {session.TotalPayment}, CarPlateNumber: {session.CarPlateNumber}, TicketNumber: {session.TicketNumber}");
200 }
201 sw.WriteLine("TARIFFS");
202 foreach (Tariff tariff in tariffs)
203 {
204 sw.WriteLine($"Minutes: {tariff.Minutes}, Rate: {tariff.Rate}");
205 }
206 }
207 }
208
209 /* ADDITIONAL TASK 2 */
210 public bool TryLeaveParkingByCarPlateNumber(string carPlateNumber, out ParkingSession session)
211 {
212 /* There are 3 scenarios for this method:
213
214 1. The user has not made any payments but leaves the parking within the free leave period
215 from EntryDt:
216 1.1 Complete the parking session by setting the ExitDt property
217 1.2 Move the session from the list of active sessions to the list of past sessions *
218 1.3 return true and the completed parking session object in the out parameter
219
220 2. The user has already paid for the parking session (session.PaymentDt != null):
221 Check that the current time is within the free leave period from session.PaymentDt
222 2.1. If yes, complete the session in the same way as in the previous scenario
223 2.2. If no, return false, session = null
224
225 3. The user has not paid for the parking session:
226 3a) If the session has a connected user (see advanced task from the EnterParking method):
227 ExitDt = PaymentDt = current date time;
228 TotalPayment according to the tariff table:
229
230 IMPORTANT: before calculating the parking charge, subtract FreeLeavePeriod
231 from the total number of minutes passed since entry
232 i.e. if the registered visitor enters the parking at 10:05
233 and attempts to leave at 10:25, no charge should be made, otherwise it would be unfair
234 to loyal customers, because an ordinary printed ticket could be inserted in the payment
235 kiosk at 10:15 (no charge) and another 15 free minutes would be given (up to 10:30)
236
237 return the completed session in the out parameter and true in the main return value
238
239 3b) If there is no connected user, set session = null, return false (the visitor
240 has to insert the parking ticket and pay at the kiosk)
241 */
242 throw new NotImplementedException();
243 }
244 }
245}