1 | unit Car;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils, Generics.Collections, Generics.Defaults, DateUtils,
|
---|
7 | PrefixMultiplier;
|
---|
8 |
|
---|
9 | type
|
---|
10 | TRents = class;
|
---|
11 | TCompany = class;
|
---|
12 |
|
---|
13 | TEngineType = (etNone, etPetrol, etDiesel, etElectric, etCng, etLpg);
|
---|
14 |
|
---|
15 | { TCar }
|
---|
16 |
|
---|
17 | TCar = class
|
---|
18 | Name: string;
|
---|
19 | EngineType: TEngineType;
|
---|
20 | Rents: TRents;
|
---|
21 | constructor Create;
|
---|
22 | destructor Destroy; override;
|
---|
23 | function GetConsumption: Double;
|
---|
24 | end;
|
---|
25 |
|
---|
26 | { TCars }
|
---|
27 |
|
---|
28 | TCars = class(TObjectList<TCar>)
|
---|
29 | function AddNew(Name: string): TCar;
|
---|
30 | function SearchByName(Name: string): TCar;
|
---|
31 | function SearchByNameEngine(Name: string; EngineType: TEngineType): TCar;
|
---|
32 | end;
|
---|
33 |
|
---|
34 | { TCarComparer }
|
---|
35 |
|
---|
36 | TCarComparer = class(TInterfacedObject, IComparer<TCar>)
|
---|
37 | function Compare(constref Left, Right: TCar): Integer; overload;
|
---|
38 | end;
|
---|
39 |
|
---|
40 | { TRent }
|
---|
41 |
|
---|
42 | TRent = class
|
---|
43 | Time: TDateTime;
|
---|
44 | Car: TCar;
|
---|
45 | Company: TCompany;
|
---|
46 | Price: Double;
|
---|
47 | PriceWithFuel: Double;
|
---|
48 | Distance: Double;
|
---|
49 | Consumption: Double;
|
---|
50 | Odometer: Integer;
|
---|
51 | procedure Assign(Source: TRent);
|
---|
52 | function GetEmission: Double;
|
---|
53 | function GetFuel: Double;
|
---|
54 | end;
|
---|
55 |
|
---|
56 | { TRents }
|
---|
57 |
|
---|
58 | TRents = class(TObjectList<TRent>)
|
---|
59 | function AddNew: TRent;
|
---|
60 | end;
|
---|
61 |
|
---|
62 | { TCompany }
|
---|
63 |
|
---|
64 | TCompany = class
|
---|
65 | Name: string;
|
---|
66 | Rents: TRents;
|
---|
67 | constructor Create;
|
---|
68 | destructor Destroy; override;
|
---|
69 | function GetPrice: Double;
|
---|
70 | function GetPriceWithFuel: Double;
|
---|
71 | function GetAverageOdometer: Integer;
|
---|
72 | end;
|
---|
73 |
|
---|
74 | { TCompanies }
|
---|
75 |
|
---|
76 | TCompanies = class(TObjectList<TCompany>)
|
---|
77 | function AddNew(Name: string): TCompany;
|
---|
78 | function SearchByName(Name: string): TCompany;
|
---|
79 | end;
|
---|
80 |
|
---|
81 | TLogEvent = procedure (Text: string) of object;
|
---|
82 |
|
---|
83 | { TSummary }
|
---|
84 |
|
---|
85 | TSummary = class
|
---|
86 | private
|
---|
87 | FOnLog: TLogEvent;
|
---|
88 | procedure Log(Text: string);
|
---|
89 | procedure SaveAndFreeCar(var CarName: string; var EngineType: TEngineType;
|
---|
90 | var CompanyName: string; var Distance: Double; var Odometer: Integer;
|
---|
91 | var Price: double; var PriceWithFuel: double; var RentTime: TDateTime;
|
---|
92 | var Consumption: double);
|
---|
93 | public
|
---|
94 | Cars: TCars;
|
---|
95 | Rents: TRents;
|
---|
96 | Companies: TCompanies;
|
---|
97 | constructor Create;
|
---|
98 | destructor Destroy; override;
|
---|
99 | procedure LoadFromFile(FileName: string);
|
---|
100 | function Print: string;
|
---|
101 | property OnLog: TLogEvent read FOnLog write FOnLog;
|
---|
102 | end;
|
---|
103 |
|
---|
104 | { TSummaryYear }
|
---|
105 |
|
---|
106 | TSummaryYear = class
|
---|
107 | Year: Integer;
|
---|
108 | Price: Double;
|
---|
109 | PriceWithFuel: Double;
|
---|
110 | Distance: Double;
|
---|
111 | RentCount: Integer;
|
---|
112 | Companies: TCompanies;
|
---|
113 | constructor Create;
|
---|
114 | destructor Destroy; override;
|
---|
115 | end;
|
---|
116 |
|
---|
117 | { TSummaryYears }
|
---|
118 |
|
---|
119 | TSummaryYears = class(TObjectList<TSummaryYear>)
|
---|
120 | function AddNew(Year: Integer): TSummaryYear;
|
---|
121 | function SearchByYear(Year: Integer): TSummaryYear;
|
---|
122 | end;
|
---|
123 |
|
---|
124 |
|
---|
125 | implementation
|
---|
126 |
|
---|
127 | const
|
---|
128 | EngineTypeText: array[TEngineType] of string = ('Žádný', 'Benzín', 'Diesel', 'Elektrické',
|
---|
129 | 'CNG', 'LPG');
|
---|
130 | EngineTypeUnit: array[TEngineType] of string = ('', 'l', 'l', 'Wh',
|
---|
131 | 'g', 'g');
|
---|
132 | DistanceUnits: array[TEngineType] of Integer = (1, 100, 100, 1, 100, 100);
|
---|
133 |
|
---|
134 | function Explode(Separator: string; Data: string): TStringArray;
|
---|
135 | var
|
---|
136 | Index: Integer;
|
---|
137 | begin
|
---|
138 | Result := Default(TStringArray);
|
---|
139 | repeat
|
---|
140 | Index := Pos(Separator, Data);
|
---|
141 | if Index > 0 then begin
|
---|
142 | SetLength(Result, Length(Result) + 1);
|
---|
143 | Result[High(Result)] := Copy(Data, 1, Index - 1);
|
---|
144 | Delete(Data, 1, Index + Length(Separator) - 1);
|
---|
145 | end else Break;
|
---|
146 | until False;
|
---|
147 | if Data <> '' then begin
|
---|
148 | SetLength(Result, Length(Result) + 1);
|
---|
149 | Result[High(Result)] := Data;
|
---|
150 | end;
|
---|
151 | end;
|
---|
152 |
|
---|
153 | function Trim(const S: string; What: Char): string; overload;
|
---|
154 | var
|
---|
155 | Ofs, Len: Integer;
|
---|
156 | begin
|
---|
157 | Len := Length(S);
|
---|
158 | while (Len > 0) and (S[Len] = What) do
|
---|
159 | Dec(Len);
|
---|
160 | Ofs := 1;
|
---|
161 | while (Ofs <= Len) and (S[Ofs] = What) do
|
---|
162 | Inc(Ofs);
|
---|
163 | Result := Copy(S, Ofs, 1 + Len - Ofs);
|
---|
164 | end;
|
---|
165 |
|
---|
166 | { TSummaryYear }
|
---|
167 |
|
---|
168 | constructor TSummaryYear.Create;
|
---|
169 | begin
|
---|
170 | Companies := TCompanies.Create(False);
|
---|
171 | end;
|
---|
172 |
|
---|
173 | destructor TSummaryYear.Destroy;
|
---|
174 | begin
|
---|
175 | FreeAndNil(Companies);
|
---|
176 | inherited;
|
---|
177 | end;
|
---|
178 |
|
---|
179 | { TSummaryYears }
|
---|
180 |
|
---|
181 | function TSummaryYears.AddNew(Year: Integer): TSummaryYear;
|
---|
182 | begin
|
---|
183 | Result := TSummaryYear.Create;
|
---|
184 | Result.Year := Year;
|
---|
185 | Add(Result);
|
---|
186 | end;
|
---|
187 |
|
---|
188 | function TSummaryYears.SearchByYear(Year: Integer): TSummaryYear;
|
---|
189 | var
|
---|
190 | I: Integer;
|
---|
191 | begin
|
---|
192 | I := 0;
|
---|
193 | while (I < Count) and (Items[I].Year <> Year) do Inc(I);
|
---|
194 | if I < Count then Result := Items[I]
|
---|
195 | else Result := nil;
|
---|
196 | end;
|
---|
197 |
|
---|
198 | { TCompanies }
|
---|
199 |
|
---|
200 | function TCompanies.AddNew(Name: string): TCompany;
|
---|
201 | begin
|
---|
202 | Result := TCompany.Create;
|
---|
203 | Result.Name := Name;
|
---|
204 | Add(Result);
|
---|
205 | end;
|
---|
206 |
|
---|
207 | function TCompanies.SearchByName(Name: string): TCompany;
|
---|
208 | var
|
---|
209 | I: Integer;
|
---|
210 | begin
|
---|
211 | I := 0;
|
---|
212 | while (I < Count) and (Items[I].Name <> Name) do Inc(I);
|
---|
213 | if I < Count then Result := Items[I]
|
---|
214 | else Result := nil;
|
---|
215 | end;
|
---|
216 |
|
---|
217 | { TCompany }
|
---|
218 |
|
---|
219 | constructor TCompany.Create;
|
---|
220 | begin
|
---|
221 | Rents := TRents.Create(False);
|
---|
222 | end;
|
---|
223 |
|
---|
224 | destructor TCompany.Destroy;
|
---|
225 | begin
|
---|
226 | FreeAndNil(Rents);
|
---|
227 | inherited;
|
---|
228 | end;
|
---|
229 |
|
---|
230 | function TCompany.GetPrice: Double;
|
---|
231 | var
|
---|
232 | I: Integer;
|
---|
233 | begin
|
---|
234 | Result := 0;
|
---|
235 | for I := 0 to Rents.Count - 1 do begin
|
---|
236 | Result := Result + Rents[I].Price;
|
---|
237 | end;
|
---|
238 | end;
|
---|
239 |
|
---|
240 | function TCompany.GetPriceWithFuel: Double;
|
---|
241 | var
|
---|
242 | I: Integer;
|
---|
243 | begin
|
---|
244 | Result := 0;
|
---|
245 | for I := 0 to Rents.Count - 1 do begin
|
---|
246 | Result := Result + Rents[I].PriceWithFuel;
|
---|
247 | end;
|
---|
248 | end;
|
---|
249 |
|
---|
250 | function TCompany.GetAverageOdometer: Integer;
|
---|
251 | var
|
---|
252 | I: Integer;
|
---|
253 | Count: Integer;
|
---|
254 | begin
|
---|
255 | Result := 0;
|
---|
256 | Count := 0;
|
---|
257 | for I := 0 to Rents.Count - 1 do
|
---|
258 | if Rents[I].Odometer > 0 then begin
|
---|
259 | Result := Result + Rents[I].Odometer;
|
---|
260 | Inc(Count);
|
---|
261 | end;
|
---|
262 | if Count > 0 then
|
---|
263 | Result := Result div Count;
|
---|
264 | end;
|
---|
265 |
|
---|
266 | { TRent }
|
---|
267 |
|
---|
268 | procedure TRent.Assign(Source: TRent);
|
---|
269 | begin
|
---|
270 | Time := Source.Time;
|
---|
271 | Price := Source.Price;
|
---|
272 | PriceWithFuel := Source.PriceWithFuel;
|
---|
273 | Distance := Source.Distance;
|
---|
274 | Consumption := Source.Consumption;
|
---|
275 | Odometer := Source.Odometer;
|
---|
276 | end;
|
---|
277 |
|
---|
278 | function TRent.GetEmission: Double;
|
---|
279 | begin
|
---|
280 | // https://www.autolexicon.net/cs/articles/vypocet-emisi-co2/
|
---|
281 | case Car.EngineType of
|
---|
282 | etPetrol: Result := GetFuel * 2390;
|
---|
283 | etDiesel: Result := GetFuel * 2640;
|
---|
284 | etLpg: Result := GetFuel * 1660;
|
---|
285 | etCng: Result := GetFuel * 2666;
|
---|
286 | etElectric: Result := GetFuel * 1-17;
|
---|
287 | end;
|
---|
288 | end;
|
---|
289 |
|
---|
290 | function TRent.GetFuel: Double;
|
---|
291 | begin
|
---|
292 | Result := Distance / DistanceUnits[Car.EngineType] * Consumption;
|
---|
293 | end;
|
---|
294 |
|
---|
295 | { TCarComparer }
|
---|
296 |
|
---|
297 | function TCarComparer.Compare(constref Left, Right: TCar): Integer;
|
---|
298 | begin
|
---|
299 | if Left.Name > Right.Name then Result := 1
|
---|
300 | else if Left.Name < Right.Name then Result := -1
|
---|
301 | else Result := 0;
|
---|
302 | end;
|
---|
303 |
|
---|
304 | { TRents }
|
---|
305 |
|
---|
306 | function TRents.AddNew: TRent;
|
---|
307 | begin
|
---|
308 | Result := TRent.Create;
|
---|
309 | Add(Result);
|
---|
310 | end;
|
---|
311 |
|
---|
312 | { TCar }
|
---|
313 |
|
---|
314 | constructor TCar.Create;
|
---|
315 | begin
|
---|
316 | Rents := TRents.Create(False);
|
---|
317 | end;
|
---|
318 |
|
---|
319 | destructor TCar.Destroy;
|
---|
320 | begin
|
---|
321 | FreeAndNil(Rents);
|
---|
322 | inherited;
|
---|
323 | end;
|
---|
324 |
|
---|
325 | function TCar.GetConsumption: Double;
|
---|
326 | var
|
---|
327 | I: Integer;
|
---|
328 | TotalCount: Integer;
|
---|
329 | begin
|
---|
330 | Result := 0;
|
---|
331 | TotalCount := 0;
|
---|
332 | for I := 0 to Rents.Count - 1 do begin
|
---|
333 | if Rents[I].Consumption > 0 then begin
|
---|
334 | Result := Result + Rents[I].Consumption;
|
---|
335 | Inc(TotalCount);
|
---|
336 | end;
|
---|
337 | end;
|
---|
338 | if TotalCount > 0 then Result := Result / TotalCount;
|
---|
339 | end;
|
---|
340 |
|
---|
341 | { TCars }
|
---|
342 |
|
---|
343 | function TCars.AddNew(Name: string): TCar;
|
---|
344 | begin
|
---|
345 | Result := TCar.Create;
|
---|
346 | Result.Name := Name;
|
---|
347 | Add(Result);
|
---|
348 | end;
|
---|
349 |
|
---|
350 | function TCars.SearchByName(Name: string): TCar;
|
---|
351 | var
|
---|
352 | I: Integer;
|
---|
353 | begin
|
---|
354 | I := 0;
|
---|
355 | while (I < Count) and (Items[I].Name <> Name) do Inc(I);
|
---|
356 | if I < Count then Result := Items[I]
|
---|
357 | else Result := nil;
|
---|
358 | end;
|
---|
359 |
|
---|
360 | function TCars.SearchByNameEngine(Name: string; EngineType: TEngineType): TCar;
|
---|
361 | var
|
---|
362 | I: Integer;
|
---|
363 | begin
|
---|
364 | I := 0;
|
---|
365 | while (I < Count) and ((Items[I].Name <> Name) or
|
---|
366 | (Items[I].EngineType <> EngineType)) do Inc(I);
|
---|
367 | if I < Count then Result := Items[I]
|
---|
368 | else Result := nil;
|
---|
369 | end;
|
---|
370 |
|
---|
371 | { TSummary }
|
---|
372 |
|
---|
373 | constructor TSummary.Create;
|
---|
374 | begin
|
---|
375 | Cars := TCars.Create;
|
---|
376 | Rents := TRents.Create;
|
---|
377 | Companies := TCompanies.Create;
|
---|
378 | end;
|
---|
379 |
|
---|
380 | destructor TSummary.Destroy;
|
---|
381 | begin
|
---|
382 | FreeAndNil(Companies);
|
---|
383 | FreeAndNil(Rents);
|
---|
384 | FreeAndNil(Cars);
|
---|
385 | inherited;
|
---|
386 | end;
|
---|
387 |
|
---|
388 | procedure TSummary.LoadFromFile(FileName: string);
|
---|
389 | var
|
---|
390 | I: Integer;
|
---|
391 | Lines: TStringList;
|
---|
392 | Line: string;
|
---|
393 | CarComparer: TCarComparer;
|
---|
394 | ValueDouble: Double;
|
---|
395 | ValueDate: TDateTime;
|
---|
396 | Parts: TStringArray;
|
---|
397 | Part: string;
|
---|
398 | Odometer: Integer;
|
---|
399 | ValueInteger: Integer;
|
---|
400 | InBetween: string;
|
---|
401 | LeftIndex: Integer;
|
---|
402 | RightIndex: Integer;
|
---|
403 | CarName: string;
|
---|
404 | EngineType: TEngineType;
|
---|
405 | CompanyName: string;
|
---|
406 | Distance: double;
|
---|
407 | Price: double;
|
---|
408 | PriceWithFuel: double;
|
---|
409 | RentTime: TDateTime;
|
---|
410 | Consumption: double;
|
---|
411 | const
|
---|
412 | DistanceText = '* Vzdálenost:';
|
---|
413 | DistanceUnit = 'km';
|
---|
414 | PriceText = '* Půjčení:';
|
---|
415 | PriceWithFuelText = '* Půjčení včetně paliva:';
|
---|
416 | PriceWithFuelText2 = '* Půjčení včetně energie:';
|
---|
417 | PriceUnit = 'Kč';
|
---|
418 | ConsumptionText = '* Průměrná spotřeba:';
|
---|
419 | ConsumptionUnit = 'l/100km';
|
---|
420 | ConsumptionUnitElectric = 'Wh/km';
|
---|
421 | ConsumptionUnitCng = 'Kg/100km';
|
---|
422 | CompanyText = '* Půjčovna:';
|
---|
423 | DateText = '* Datum:';
|
---|
424 | BrandText = '* Značka:';
|
---|
425 | TableLineStartText = '| ';
|
---|
426 | TableLineCellSeparator = '||';
|
---|
427 | begin
|
---|
428 | Lines := TStringList.Create;
|
---|
429 | Lines.LoadFromFile(FileName);
|
---|
430 | for I := 0 to Lines.Count - 1 do begin
|
---|
431 | Line := Lines[I];
|
---|
432 | if Pos('==', Line) > 0 then begin
|
---|
433 | SaveAndFreeCar(CarName, EngineType, CompanyName, Distance, Odometer, Price,
|
---|
434 | PriceWithFuel, RentTime, Consumption);
|
---|
435 | CarName := Trim(Line, '=');
|
---|
436 | end else
|
---|
437 | if Line.StartsWith(DistanceText) then begin
|
---|
438 | Line := Copy(Line, Length(DistanceText) + 1, MaxInt);
|
---|
439 | LeftIndex := Pos('(', Line);
|
---|
440 | RightIndex := Pos(')', Line);
|
---|
441 | if (LeftIndex > 0) and (RightIndex > 0) then begin
|
---|
442 | InBetween := Copy(Line, LeftIndex + 1, RightIndex - LeftIndex - 1);
|
---|
443 | if Pos('-', InBetween) > 0 then InBetween := Copy(InBetween, Pos('-', InBetween) + 1, MaxInt);
|
---|
444 | if TryStrToInt(Trim(InBetween), ValueInteger) then
|
---|
445 | Odometer := ValueInteger;
|
---|
446 | Line := Copy(Line, 1, LeftIndex - 1) + Copy(Line, RightIndex + 1, MaxInt);
|
---|
447 | end;
|
---|
448 | if Pos(DistanceUnit, Line) > 0 then
|
---|
449 | Line := Trim(Copy(Line, 1, Pos(DistanceUnit, Line) - 1));
|
---|
450 | if TryStrToFloat(Line, ValueDouble) then begin
|
---|
451 | Distance := ValueDouble;
|
---|
452 | end else begin
|
---|
453 | Log('Špatná vzdálenost ' + Line);
|
---|
454 | end;
|
---|
455 | end else
|
---|
456 | if Line.StartsWith(BrandText) then begin
|
---|
457 | Line := LowerCase(Copy(Line, Length(BrandText) + 1, MaxInt));
|
---|
458 | if Line.Contains('diesel') then EngineType := etDiesel
|
---|
459 | else if Line.Contains('lpg') then EngineType := etLpg
|
---|
460 | else if Line.Contains('kwh') then EngineType := etElectric;
|
---|
461 | end else
|
---|
462 | if Line.StartsWith(PriceText) then begin
|
---|
463 | Line := Copy(Line, Length(PriceText) + 1, MaxInt);
|
---|
464 | if Pos(PriceUnit, Line) > 0 then
|
---|
465 | Line := Trim(Copy(Line, 1, Pos(PriceUnit, Line) - 1));
|
---|
466 | if TryStrToFloat(Line, ValueDouble) then begin
|
---|
467 | Price := ValueDouble;
|
---|
468 | end else begin
|
---|
469 | Log('Špatná cena ' + Line);
|
---|
470 | end
|
---|
471 | end else
|
---|
472 | if Line.StartsWith(PriceWithFuelText) then begin
|
---|
473 | Line := Copy(Line, Length(PriceWithFuelText) + 1, MaxInt);
|
---|
474 | if Pos(PriceUnit, Line) > 0 then
|
---|
475 | Line := Trim(Copy(Line, 1, Pos(PriceUnit, Line) - 1));
|
---|
476 | if TryStrToFloat(Line, ValueDouble) then begin
|
---|
477 | PriceWithFuel := ValueDouble;
|
---|
478 | end else begin
|
---|
479 | Log('Špatná cena včetně paliva ' + Line);
|
---|
480 | end
|
---|
481 | end else
|
---|
482 | if Line.StartsWith(PriceWithFuelText2) then begin
|
---|
483 | Line := Copy(Line, Length(PriceWithFuelText2) + 1, MaxInt);
|
---|
484 | if Pos(PriceUnit, Line) > 0 then
|
---|
485 | Line := Trim(Copy(Line, 1, Pos(PriceUnit, Line) - 1));
|
---|
486 | if TryStrToFloat(Line, ValueDouble) then begin
|
---|
487 | PriceWithFuel := ValueDouble;
|
---|
488 | end else begin
|
---|
489 | Log('Špatný cena včetně energie ' + Line);
|
---|
490 | end
|
---|
491 | end else
|
---|
492 | if Line.StartsWith(DateText) then begin
|
---|
493 | Line := Trim(Copy(Line, Length(DateText) + 1, MaxInt));
|
---|
494 | if TryStrToDate(Line, ValueDate) then begin
|
---|
495 | RentTime := ValueDate;
|
---|
496 | end else begin
|
---|
497 | Log('Špatný datum ' + Line);
|
---|
498 | end;
|
---|
499 | end else
|
---|
500 | if Line.StartsWith(ConsumptionText) then begin
|
---|
501 | Line := Copy(Line, Length(ConsumptionText) + 1, MaxInt);
|
---|
502 | if Pos(ConsumptionUnit, Line) > 0 then begin
|
---|
503 | Line := Trim(Copy(Line, 1, Pos(ConsumptionUnit, Line) - 1));
|
---|
504 | if EngineType = etNone then
|
---|
505 | EngineType := etPetrol;
|
---|
506 | if TryStrToFloat(Line, ValueDouble) then
|
---|
507 | Consumption := ValueDouble;
|
---|
508 | end;
|
---|
509 | if Pos(ConsumptionUnitElectric, Line) > 0 then begin
|
---|
510 | Line := Trim(Copy(Line, 1, Pos(ConsumptionUnitElectric, Line) - 1));
|
---|
511 | if EngineType = etNone then
|
---|
512 | EngineType := etElectric;
|
---|
513 | if TryStrToFloat(Line, ValueDouble) then
|
---|
514 | Consumption := ValueDouble;
|
---|
515 | end;
|
---|
516 | if Pos(ConsumptionUnitCng, Line) > 0 then begin
|
---|
517 | Line := Trim(Copy(Line, 1, Pos(ConsumptionUnitCng, Line) - 1));
|
---|
518 | if EngineType = etNone then
|
---|
519 | EngineType := etCng;
|
---|
520 | if TryStrToFloat(Line, ValueDouble) then
|
---|
521 | Consumption := ValueDouble * 1000;
|
---|
522 | end;
|
---|
523 | end else
|
---|
524 | if Line.StartsWith(CompanyText) then begin
|
---|
525 | CompanyName := Trim(Copy(Line, Length(CompanyText) + 1, MaxInt));
|
---|
526 | end else
|
---|
527 | if Line.StartsWith(TableLineStartText) then begin
|
---|
528 | Parts := Explode(TableLineCellSeparator, Line);
|
---|
529 | if Length(Parts) > 4 then begin
|
---|
530 | Part := Parts[4];
|
---|
531 | Part := Trim(Part);
|
---|
532 | if TryStrToInt(Part, Odometer) and (Odometer = 0) then
|
---|
533 | Odometer := Odometer;
|
---|
534 | end;
|
---|
535 | end else begin
|
---|
536 | // Line := Trim(Line);
|
---|
537 | end;
|
---|
538 | end;
|
---|
539 | SaveAndFreeCar(CarName, EngineType, CompanyName, Distance, Odometer, Price,
|
---|
540 | PriceWithFuel, RentTime, Consumption);
|
---|
541 | Lines.Free;
|
---|
542 | CarComparer := TCarComparer.Create;
|
---|
543 | Cars.Sort(CarComparer);
|
---|
544 | end;
|
---|
545 |
|
---|
546 | function TSummary.Print: string;
|
---|
547 | var
|
---|
548 | I: Integer;
|
---|
549 | TotalDistance: Double;
|
---|
550 | TotalPrice: Double;
|
---|
551 | TotalPriceWithFuel: Double;
|
---|
552 | TotalEmission: Double;
|
---|
553 | TotalFuel: array[TEngineType] of Double;
|
---|
554 | CarName: string;
|
---|
555 | CompanyName: string;
|
---|
556 | E: TEngineType;
|
---|
557 | PrefixMultiplier: TPrefixMultiplier;
|
---|
558 | SummaryYears: TSummaryYears;
|
---|
559 | SummaryYear: TSummaryYear;
|
---|
560 | Year: Integer;
|
---|
561 |
|
---|
562 | procedure AddLine(Text: string = '');
|
---|
563 | begin
|
---|
564 | Result := Result + Text + LineEnding;
|
---|
565 | end;
|
---|
566 |
|
---|
567 | begin
|
---|
568 | PrefixMultiplier := TPrefixMultiplier.Create(nil);
|
---|
569 | SummaryYears := TSummaryYears.Create;
|
---|
570 |
|
---|
571 | TotalDistance := 0;
|
---|
572 | TotalPrice := 0;
|
---|
573 | TotalPriceWithFuel := 0;
|
---|
574 | TotalEmission := 0;
|
---|
575 | for E := Low(TEngineType) to High(TEngineType) do
|
---|
576 | TotalFuel[E] := 0;
|
---|
577 | for I := 0 to Rents.Count - 1 do
|
---|
578 | with TRent(Rents[I]) do begin
|
---|
579 | TotalDistance := TotalDistance + Distance;
|
---|
580 | TotalPrice := TotalPrice + Price;
|
---|
581 | TotalPriceWithFuel := TotalPriceWithFuel + PriceWithFuel;
|
---|
582 | TotalEmission := TotalEmission + GetEmission;
|
---|
583 | TotalFuel[Car.EngineType] := TotalFuel[Car.EngineType] + GetFuel;
|
---|
584 |
|
---|
585 | Year := YearOf(Time);
|
---|
586 | SummaryYear := SummaryYears.SearchByYear(Year);
|
---|
587 | if not Assigned(SummaryYear) then begin
|
---|
588 | SummaryYear := SummaryYears.AddNew(Year);
|
---|
589 | end;
|
---|
590 | SummaryYear.Distance := SummaryYear.Distance + Distance;
|
---|
591 | SummaryYear.Price := SummaryYear.Price + Price;
|
---|
592 | SummaryYear.PriceWithFuel := SummaryYear.PriceWithFuel + PriceWithFuel;
|
---|
593 | Inc(SummaryYear.RentCount);
|
---|
594 | if SummaryYear.Companies.IndexOf(Company) = -1 then
|
---|
595 | SummaryYear.Companies.Add(Company);
|
---|
596 | end;
|
---|
597 |
|
---|
598 | AddLine;
|
---|
599 | AddLine('=Souhrn=');
|
---|
600 | AddLine('* Počet půjčení: ' + IntToStr(Rents.Count));
|
---|
601 | AddLine('* Cena půjčení: ' + FloatToStr(TotalPrice) + ' Kč');
|
---|
602 | AddLine('* Cena půjčení včetně paliva: ' + FloatToStr(TotalPriceWithFuel) + ' Kč');
|
---|
603 | AddLine('* Vzdálenost: ' + FloatToStr(TotalDistance) + ' km');
|
---|
604 | for E := Succ(Low(TEngineType)) to High(TEngineType) do
|
---|
605 | AddLine('* Palivo ' + EngineTypeText[E] + ': ' + PrefixMultiplier.Add(TotalFuel[E], BasePrefixMultipliers, EngineTypeUnit[E]));
|
---|
606 | AddLine('* Emise CO2: ' + FloatToStr(TotalEmission / 1000) + ' Kg');
|
---|
607 |
|
---|
608 | AddLine;
|
---|
609 | AddLine('==Roky==');
|
---|
610 | AddLine('{| class="wikitable sortable"');
|
---|
611 | AddLine('! Rok !! Cena [Kč] !! Cena včetně paliva [Kč] !! Vzdálenost [km] !! Zápůjček !! Půjčoven');
|
---|
612 | AddLine('|-');
|
---|
613 | for I := 0 to SummaryYears.Count - 1 do
|
---|
614 | with TSummaryYear(SummaryYears[I]) do begin
|
---|
615 | AddLine('| ' + IntToStr(Year) + ' || ' + FloatToStr(Price) + ' || ' +
|
---|
616 | FloatToStr(PriceWithFuel) + ' || ' +
|
---|
617 | FloatToStr(Distance) + ' || ' + IntToStr(RentCount) + ' || ' +
|
---|
618 | IntToStr(Companies.Count));
|
---|
619 | if I < SummaryYears.Count - 1 then AddLine('|-');
|
---|
620 | end;
|
---|
621 | AddLine('|}');
|
---|
622 |
|
---|
623 | AddLine;
|
---|
624 | AddLine('==Auta==');
|
---|
625 | AddLine('{| class="wikitable sortable"');
|
---|
626 | AddLine('! Jméno !! Půjčení !! Průměrná spotřeba !! Typ paliva');
|
---|
627 | AddLine('|-');
|
---|
628 | for I := 0 to Cars.Count - 1 do
|
---|
629 | with TCar(Cars[I]) do begin
|
---|
630 | AddLine('| ' + Name + ' || ' + IntToStr(Rents.Count) + ' || ' +
|
---|
631 | FloatToStr(Round(GetConsumption * 100) / 100) + ' || ' + EngineTypeText[EngineType]);
|
---|
632 | if I < Cars.Count - 1 then AddLine('|-');
|
---|
633 | end;
|
---|
634 | AddLine('|}');
|
---|
635 |
|
---|
636 | AddLine;
|
---|
637 | AddLine('==Půjčovny==');
|
---|
638 | AddLine('{| class="wikitable sortable"');
|
---|
639 | AddLine('! Jméno !! Půjčení !! Celkem cena [Kč] !! Celkem cena s palivem [Kč] !! Průměrně odometr [Km]');
|
---|
640 | AddLine('|-');
|
---|
641 | for I := 0 to Companies.Count - 1 do
|
---|
642 | with TCompany(Companies[I]) do begin
|
---|
643 | AddLine('| ' + Name + ' || ' + IntToStr(Rents.Count) + ' || ' +
|
---|
644 | FloatToStr(GetPrice) + ' || ' + FloatToStr(GetPriceWithFuel) + ' || ' +
|
---|
645 | IntToStr(GetAverageOdometer));
|
---|
646 | if I < Companies.Count - 1 then AddLine('|-');
|
---|
647 | end;
|
---|
648 | AddLine('|}');
|
---|
649 |
|
---|
650 | AddLine;
|
---|
651 | AddLine('==Zápůjčky==');
|
---|
652 | AddLine('{| class="wikitable sortable"');
|
---|
653 | AddLine('! Datum !! Auto !! Půjčovna !! Cena celkem [Kč] !! Celkem cena s palivem [Kč] !! Vzdálenost [km] !! Spotřeba !! Typ paliva || Energie');
|
---|
654 | AddLine('|-');
|
---|
655 | for I := 0 to Rents.Count - 1 do
|
---|
656 | with TRent(Rents[I]) do begin
|
---|
657 | if Assigned(Car) then CarName := Car.Name else CarName := '';
|
---|
658 | if Assigned(Company) then CompanyName := Company.Name else CompanyName := '';
|
---|
659 | AddLine('| ' + DateToStr(Time) + ' || ' + CarName + ' || ' +
|
---|
660 | CompanyName + ' || ' + FloatToStr(Price) + ' || ' +
|
---|
661 | FloatToStr(PriceWithFuel) + ' || ' +
|
---|
662 | FloatToStr(Distance) + ' || ' + FloatToStr(Consumption) + ' || ' +
|
---|
663 | EngineTypeText[Car.EngineType] + ' || ' + FloatToStr(GetFuel));
|
---|
664 | if I < Rents.Count - 1 then AddLine('|-');
|
---|
665 | end;
|
---|
666 | AddLine('|}');
|
---|
667 |
|
---|
668 | SummaryYears.Free;
|
---|
669 | PrefixMultiplier.Free;
|
---|
670 | end;
|
---|
671 |
|
---|
672 | procedure TSummary.Log(Text: string);
|
---|
673 | begin
|
---|
674 | if Assigned(FOnLog) then FOnLog(Text);
|
---|
675 | end;
|
---|
676 |
|
---|
677 | procedure TSummary.SaveAndFreeCar(var CarName: string;
|
---|
678 | var EngineType: TEngineType; var CompanyName: string; var Distance: Double;
|
---|
679 | var Odometer: Integer; var Price: double; var PriceWithFuel: double;
|
---|
680 | var RentTime: TDateTime; var Consumption: double);
|
---|
681 | var
|
---|
682 | Car: TCar;
|
---|
683 | Rent: TRent;
|
---|
684 | Company: TCompany;
|
---|
685 | begin
|
---|
686 | if EngineType = etNone then EngineType := etPetrol;
|
---|
687 | if CarName <> '' then begin
|
---|
688 | Car := Cars.SearchByNameEngine(CarName, EngineType);
|
---|
689 | if not Assigned(Car) then begin
|
---|
690 | Car := Cars.AddNew(CarName);
|
---|
691 | Car.EngineType := EngineType;
|
---|
692 | end;
|
---|
693 |
|
---|
694 | Rent := Rents.AddNew;
|
---|
695 | Car.Rents.Add(Rent);
|
---|
696 | Rent.Car := Car;
|
---|
697 | Rent.Odometer := Odometer;
|
---|
698 | Rent.Distance := Distance;
|
---|
699 | Rent.Price := Price;
|
---|
700 | Rent.PriceWithFuel := PriceWithFuel;
|
---|
701 | Rent.Time := RentTime;
|
---|
702 | Rent.Consumption := Consumption;
|
---|
703 |
|
---|
704 | Company := Companies.SearchByName(CompanyName);
|
---|
705 | if not Assigned(Company) then begin
|
---|
706 | Company := Companies.AddNew(CompanyName);
|
---|
707 | end;
|
---|
708 | Company.Rents.Add(Rent);
|
---|
709 | Rent.Company := Company;
|
---|
710 | end;
|
---|
711 |
|
---|
712 | CarName := '';
|
---|
713 | EngineType := etNone;
|
---|
714 | CompanyName := '';
|
---|
715 | Odometer := 0;
|
---|
716 | Distance := 0;
|
---|
717 | Price := 0;
|
---|
718 | PriceWithFuel := 0;
|
---|
719 | RentTime := 0;
|
---|
720 | Consumption := 0;
|
---|
721 | end;
|
---|
722 |
|
---|
723 | end.
|
---|
724 |
|
---|