data.dart 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:archive/archive_io.dart';
  4. import 'package:jiffy/jiffy.dart';
  5. import 'package:myshelf/models/dtinterval.dart';
  6. import 'package:supabase/supabase.dart';
  7. final Map<String, String> tables = {
  8. "secondprgtype.txt": "aclegs_csv",
  9. "ExportPGRGPNmois.txt": "pnlegs_csv",
  10. "exportPGRGPN.txt": "pnlegs_csv",
  11. "exportlicence.txt": "licences_csv",
  12. };
  13. final Map<String, List<String>> headers = {
  14. "secondprgtype.txt": [
  15. "leg_no",
  16. "fn_carrier",
  17. "fn_number",
  18. "fn_suffix",
  19. "day_of_origin",
  20. "ac_owner",
  21. "ac_subtype",
  22. "ac_version",
  23. "ac_registration",
  24. "dep_ap_actual",
  25. "dep_ap_sched",
  26. "dep_dt_est",
  27. "dep_sched_dt",
  28. "arr_ap_actual",
  29. "arr_ap_sched",
  30. "arr_dt_est",
  31. "arr_sched_dt",
  32. "slot_time_actual",
  33. "leg_type",
  34. "status",
  35. "employer_cockpit",
  36. "employer_cabin",
  37. "cycles",
  38. "delay_code_01",
  39. "delay_code_02",
  40. "delay_code_03",
  41. "delay_code_04",
  42. "delay_time_01",
  43. "delay_time_02",
  44. "delay_time_03",
  45. "delay_time_04",
  46. "subdelay_code_01",
  47. "subdelay_code_02",
  48. "subdelay_code_03",
  49. "subdelay_code_04",
  50. "pax_booked_c",
  51. "pax_booked_y",
  52. "pax_booked_trs_c",
  53. "pax_booked_trs_y",
  54. "pad_booked_c",
  55. "pad_booked_y",
  56. "offblock_dt_a",
  57. "airborne_dt_a",
  58. "landing_dt_a",
  59. "onblock_dt_a",
  60. "offblock_dt_f",
  61. "airborne_dt_f",
  62. "landing_dt_f",
  63. "onblock_dt_f",
  64. "offblock_dt_m",
  65. "airborne_dt_m",
  66. "landing_dt_m",
  67. "onblock_dt_m",
  68. "eet",
  69. ],
  70. "exportPGRGPN.txt": [
  71. "date",
  72. "tlc",
  73. "actype",
  74. "al",
  75. "fnum",
  76. "ddep",
  77. "hdep",
  78. "ddes",
  79. "hdes",
  80. "dep",
  81. "des",
  82. "label",
  83. "type",
  84. ],
  85. "ExportPGRGPNmois.txt": [
  86. "date",
  87. "tlc",
  88. "actype",
  89. "al",
  90. "fnum",
  91. "ddep",
  92. "hdep",
  93. "ddes",
  94. "hdes",
  95. "dep",
  96. "des",
  97. "label",
  98. "type",
  99. ],
  100. "exportlicence.txt": [
  101. "tlc",
  102. "fname",
  103. "mname",
  104. "lname",
  105. "expire",
  106. "ac",
  107. "college",
  108. "base",
  109. ],
  110. };
  111. final Map<String, String> scopes = {
  112. "secondprgtype.txt": "day_of_origin",
  113. "exportPGRGPN.txt": "date",
  114. "ExportPGRGPNmois.txt": "date",
  115. "exportlicence.txt": "tlc",
  116. };
  117. List<Map<String, String?>> createListOfMaps(
  118. List<String> headers, List<List<dynamic>> data) {
  119. // Initialize an empty list to hold the maps
  120. List<Map<String, String?>> result = [];
  121. // Iterate over each row of data
  122. for (var row in data) {
  123. // Create a map for the current row
  124. Map<String, String?> map = {};
  125. // Populate the map with header-value pairs
  126. for (int i = 0; i < headers.length; i++) {
  127. if (i < row.length) {
  128. // Convert each value to String? and handle null values
  129. map[headers[i]] = row[i]
  130. ?.toString(); // Use toString() to ensure it's a String or null
  131. } else {
  132. // If there's no corresponding data, set it as null
  133. map[headers[i]] = null;
  134. }
  135. }
  136. // Add the map to the result list
  137. result.add(map);
  138. }
  139. return result;
  140. }
  141. List<List<String?>> csv2list(String text,
  142. {bool nulling = true, bool quotes = true, bool trim = true}) {
  143. List<List<String?>> out = [];
  144. final lines = text.split("\n");
  145. for (var line in lines) {
  146. final cols = line.split(",").map((String? e) {
  147. if (e != null && quotes) {
  148. e = e.replaceAll('"', "");
  149. }
  150. if (e != null && trim) {
  151. e = e.trim();
  152. }
  153. if (nulling) {
  154. e = (e == "") ? null : e;
  155. }
  156. return e;
  157. }).toList();
  158. // print("${out.length}: $cols");
  159. if (cols.isNotEmpty && cols.length > 1) out.add(cols);
  160. }
  161. return out;
  162. }
  163. class Qualif {
  164. String? tlc;
  165. String? lname;
  166. String? mname;
  167. String? fname;
  168. String? date;
  169. String? ac;
  170. String? college;
  171. String? base;
  172. Qualif({
  173. this.tlc,
  174. this.lname,
  175. this.mname,
  176. this.fname,
  177. this.date,
  178. this.ac,
  179. this.college,
  180. this.base,
  181. });
  182. Qualif copyWith({
  183. String? tlc,
  184. String? lname,
  185. String? mname,
  186. String? fname,
  187. String? date,
  188. String? ac,
  189. String? college,
  190. String? base,
  191. }) {
  192. return Qualif(
  193. tlc: tlc ?? this.tlc,
  194. lname: lname ?? this.lname,
  195. mname: mname ?? this.mname,
  196. fname: fname ?? this.fname,
  197. date: date ?? this.date,
  198. ac: ac ?? this.ac,
  199. college: college ?? this.college,
  200. base: base ?? this.base,
  201. );
  202. }
  203. Map<String, dynamic> toMap() {
  204. return <String, dynamic>{
  205. 'tlc': tlc,
  206. 'lname': lname,
  207. 'mname': mname,
  208. 'fname': fname,
  209. 'date': date,
  210. 'ac': ac,
  211. 'college': college,
  212. 'base': base,
  213. };
  214. }
  215. factory Qualif.fromList(List datalist) {
  216. return Qualif(
  217. tlc: datalist[0],
  218. lname: datalist[1],
  219. mname: datalist[2],
  220. fname: datalist[3],
  221. date: datalist[4],
  222. ac: datalist[5],
  223. college: datalist[6],
  224. base: datalist[7]);
  225. }
  226. factory Qualif.fromMap(Map<String, dynamic> map) {
  227. return Qualif(
  228. tlc: map['tlc'] != null ? map['tlc'] as String : null,
  229. lname: map['lname'] != null ? map['lname'] as String : null,
  230. mname: map['mname'] != null ? map['mname'] as String : null,
  231. fname: map['fname'] != null ? map['fname'] as String : null,
  232. date: map['date'] != null ? map['date'] as String : null,
  233. ac: map['ac'] != null ? map['ac'] as String : null,
  234. college: map['college'] != null ? map['college'] as String : null,
  235. base: map['base'] != null ? map['base'] as String : null,
  236. );
  237. }
  238. String toJson() => json.encode(toMap());
  239. factory Qualif.fromJson(String source) =>
  240. Qualif.fromMap(json.decode(source) as Map<String, dynamic>);
  241. @override
  242. String toString() {
  243. return 'Qualif(tlc: $tlc, lname: $lname, mname: $mname, fname: $fname, date: $date, ac: $ac, college: $college, base: $base)';
  244. }
  245. @override
  246. bool operator ==(covariant Qualif other) {
  247. if (identical(this, other)) return true;
  248. return other.tlc == tlc &&
  249. other.lname == lname &&
  250. other.mname == mname &&
  251. other.fname == fname &&
  252. other.date == date &&
  253. other.ac == ac &&
  254. other.college == college &&
  255. other.base == base;
  256. }
  257. @override
  258. int get hashCode {
  259. return tlc.hashCode ^
  260. lname.hashCode ^
  261. mname.hashCode ^
  262. fname.hashCode ^
  263. date.hashCode ^
  264. ac.hashCode ^
  265. college.hashCode ^
  266. base.hashCode;
  267. }
  268. }
  269. class Pnleg {
  270. String? date;
  271. Jiffy? get jdate => date != null
  272. ? Jiffy.parse(date ?? "01/01/1970", pattern: "dd/MM/yyyy", isUtc: true)
  273. : null;
  274. String? tlc;
  275. String? actype;
  276. String? al;
  277. String? fnum;
  278. String? depdate;
  279. String? deptime;
  280. String? arrdate;
  281. String? arrtime;
  282. String? dep;
  283. String? arr;
  284. String? label;
  285. String? type;
  286. Jiffy? get jdep =>
  287. deptime != null ? "$depdate $deptime".parseddmmyyyyhhmm() : null;
  288. Jiffy? get jarr =>
  289. arrtime != null ? "$arrdate $arrtime".parseddmmyyyyhhmm() : null;
  290. String get dutytype {
  291. if (type == "L") {
  292. return "flight";
  293. } else if ((type == "G")) {
  294. return "dhlimo";
  295. } else if ((type == "F") || ((dep ?? "") != "" && (arr ?? "") != "")) {
  296. return "dhflight";
  297. } else if ((label?.startsWith("SBY") ?? false) || (label == "R0")) {
  298. return "standby";
  299. } else if ((!["OFF", "CM", "CA", "PP"].contains(label)) &&
  300. (jarr != null &&
  301. jdep != null &&
  302. DTInterval(jdep!, jarr!).duration.inHours < 18)) {
  303. return "ground";
  304. } else {
  305. return "day";
  306. }
  307. }
  308. Pnleg({
  309. this.date,
  310. this.tlc,
  311. this.actype,
  312. this.al,
  313. this.fnum,
  314. this.depdate,
  315. this.deptime,
  316. this.arrdate,
  317. this.arrtime,
  318. this.dep,
  319. this.arr,
  320. this.label,
  321. this.type,
  322. });
  323. Pnleg copyWith({
  324. String? date,
  325. String? tlc,
  326. String? actype,
  327. String? al,
  328. String? fnum,
  329. String? depdate,
  330. String? deptime,
  331. String? arrdate,
  332. String? arrtime,
  333. String? dep,
  334. String? arr,
  335. String? label,
  336. String? type,
  337. }) {
  338. return Pnleg(
  339. date: date ?? this.date,
  340. tlc: tlc ?? this.tlc,
  341. actype: actype ?? this.actype,
  342. al: al ?? this.al,
  343. fnum: fnum ?? this.fnum,
  344. depdate: depdate ?? this.depdate,
  345. deptime: deptime ?? this.deptime,
  346. arrdate: arrdate ?? this.arrdate,
  347. arrtime: arrtime ?? this.arrtime,
  348. dep: dep ?? this.dep,
  349. arr: arr ?? this.arr,
  350. label: label ?? this.label,
  351. type: type ?? this.type,
  352. );
  353. }
  354. Map<String, dynamic> toMap() {
  355. return <String, dynamic>{
  356. 'date': date,
  357. 'tlc': tlc,
  358. 'actype': actype,
  359. 'al': al,
  360. 'fnum': fnum,
  361. 'depdate': depdate,
  362. 'deptime': deptime,
  363. 'arrdate': arrdate,
  364. 'arrtime': arrtime,
  365. 'dep': dep,
  366. 'arr': arr,
  367. 'label': label,
  368. 'type': type,
  369. };
  370. }
  371. factory Pnleg.fromList(List datalist) {
  372. return Pnleg(
  373. date: datalist[0],
  374. tlc: datalist[1],
  375. actype: datalist[2],
  376. al: datalist[3],
  377. fnum: datalist[4],
  378. depdate: datalist[5],
  379. deptime: datalist[6],
  380. arrdate: datalist[7],
  381. arrtime: datalist[8],
  382. dep: datalist[9],
  383. arr: datalist[10],
  384. label: datalist[11],
  385. type: datalist[12]);
  386. }
  387. factory Pnleg.fromMap(Map<String, dynamic> map) {
  388. return Pnleg(
  389. date: map['date'] != null ? map['date'] as String : null,
  390. tlc: map['tlc'] != null ? map['tlc'] as String : null,
  391. actype: map['actype'] != null ? map['actype'] as String : null,
  392. al: map['al'] != null ? map['al'] as String : null,
  393. fnum: map['fnum'] != null ? map['fnum'] as String : null,
  394. depdate: map['depdate'] != null ? map['depdate'] as String : null,
  395. deptime: map['deptime'] != null ? map['deptime'] as String : null,
  396. arrdate: map['arrdate'] != null ? map['arrdate'] as String : null,
  397. arrtime: map['arrtime'] != null ? map['arrtime'] as String : null,
  398. dep: map['dep'] != null ? map['dep'] as String : null,
  399. arr: map['arr'] != null ? map['arr'] as String : null,
  400. label: map['label'] != null ? map['label'] as String : null,
  401. type: map['type'] != null ? map['type'] as String : null,
  402. );
  403. }
  404. String toJson() => json.encode(toMap());
  405. factory Pnleg.fromJson(String source) =>
  406. Pnleg.fromMap(json.decode(source) as Map<String, dynamic>);
  407. @override
  408. String toString() {
  409. return 'Pnleg(date: $date, tlc: $tlc, actype: $actype, al: $al, fnum: $fnum, depdate: $depdate, deptime: $deptime, arrdate: $arrdate, arrtime: $arrtime, dep: $dep, arr: $arr, label: $label, type: $type)';
  410. }
  411. @override
  412. bool operator ==(covariant Pnleg other) {
  413. if (identical(this, other)) return true;
  414. return other.date == date &&
  415. other.tlc == tlc &&
  416. other.actype == actype &&
  417. other.al == al &&
  418. other.fnum == fnum &&
  419. other.depdate == depdate &&
  420. other.deptime == deptime &&
  421. other.arrdate == arrdate &&
  422. other.arrtime == arrtime &&
  423. other.dep == dep &&
  424. other.arr == arr &&
  425. other.label == label &&
  426. other.type == type;
  427. }
  428. @override
  429. int get hashCode {
  430. return date.hashCode ^
  431. tlc.hashCode ^
  432. actype.hashCode ^
  433. al.hashCode ^
  434. fnum.hashCode ^
  435. depdate.hashCode ^
  436. deptime.hashCode ^
  437. arrdate.hashCode ^
  438. arrtime.hashCode ^
  439. dep.hashCode ^
  440. arr.hashCode ^
  441. label.hashCode ^
  442. type.hashCode;
  443. }
  444. }
  445. //enum flt_status { sched, delayed, taxiout, enroute, landed, arrived }
  446. class Acleg {
  447. String? LEG_NO;
  448. String? FN_CARRIER;
  449. String? FN_NUMBER;
  450. String? FN_SUFFIX;
  451. String? DAY_OF_ORIGIN;
  452. String? AC_OWNER;
  453. String? AC_SUBTYPE;
  454. String? AC_VERSION;
  455. String? AC_REGISTRATION;
  456. String? DEP_AP_ACTUAL;
  457. String? DEP_AP_SCHED;
  458. String? DEP_DT_EST;
  459. Jiffy? get jdepest =>
  460. (DEP_DT_EST == null) ? null : DEP_DT_EST!.parseyyyymmddhhmm();
  461. String? DEP_SCHED_DT;
  462. Jiffy? get jdepsched =>
  463. (DEP_SCHED_DT == null) ? null : DEP_SCHED_DT!.parseyyyymmddhhmm();
  464. String? ARR_AP_ACTUAL;
  465. String? ARR_AP_SCHED;
  466. String? ARR_DT_EST;
  467. Jiffy? get jarrest =>
  468. (ARR_DT_EST == null) ? null : ARR_DT_EST!.parseyyyymmddhhmm();
  469. String? ARR_SCHED_DT;
  470. Jiffy? get jarrsched =>
  471. (ARR_SCHED_DT == null) ? null : ARR_SCHED_DT!.parseyyyymmddhhmm();
  472. String? SLOT_TIME_ACTUAL;
  473. Jiffy? get slot =>
  474. (SLOT_TIME_ACTUAL == null) ? null : SLOT_TIME_ACTUAL!.parseyyyymmddhhmm();
  475. String? LEG_TYPE;
  476. String? STATUS;
  477. String? EMPLOYER_COCKPIT;
  478. String? EMPLOYER_CABIN;
  479. String? CYCLES;
  480. String? DELAY_CODE_01;
  481. String? DELAY_CODE_02;
  482. String? DELAY_CODE_03;
  483. String? DELAY_CODE_04;
  484. String? DELAY_TIME_01;
  485. String? DELAY_TIME_02;
  486. String? DELAY_TIME_03;
  487. String? DELAY_TIME_04;
  488. String? SUBDELAY_CODE_01;
  489. String? SUBDELAY_CODE_02;
  490. String? SUBDELAY_CODE_03;
  491. String? SUBDELAY_CODE_04;
  492. List<List> get dla => [
  493. [
  494. SUBDELAY_CODE_01 ?? DELAY_CODE_01,
  495. DELAY_TIME_01 == null
  496. ? null
  497. : Duration(minutes: int.parse(DELAY_TIME_01!))
  498. ],
  499. [
  500. SUBDELAY_CODE_02 ?? DELAY_CODE_02,
  501. DELAY_TIME_02 == null
  502. ? null
  503. : Duration(minutes: int.parse(DELAY_TIME_02!))
  504. ],
  505. [
  506. SUBDELAY_CODE_03 ?? DELAY_CODE_03,
  507. DELAY_TIME_03 == null
  508. ? null
  509. : Duration(minutes: int.parse(DELAY_TIME_03!))
  510. ],
  511. [
  512. SUBDELAY_CODE_04 ?? DELAY_CODE_04,
  513. DELAY_TIME_04 == null
  514. ? null
  515. : Duration(minutes: int.parse(DELAY_TIME_04!))
  516. ],
  517. ].where((e) => e.every((f) => f != null)).toList();
  518. List<String> get delaycode => [
  519. DELAY_CODE_01,
  520. DELAY_CODE_02,
  521. DELAY_CODE_03,
  522. DELAY_CODE_04
  523. ].nonNulls.toList();
  524. List<String> get delaysubcode => [
  525. SUBDELAY_CODE_01,
  526. SUBDELAY_CODE_02,
  527. SUBDELAY_CODE_03,
  528. SUBDELAY_CODE_04
  529. ].nonNulls.toList();
  530. List<Duration?> get delaytime => [
  531. DELAY_TIME_01 == null
  532. ? null
  533. : Duration(minutes: int.parse(DELAY_TIME_01!)),
  534. DELAY_TIME_02 == null
  535. ? null
  536. : Duration(minutes: int.parse(DELAY_TIME_02!)),
  537. DELAY_TIME_03 == null
  538. ? null
  539. : Duration(minutes: int.parse(DELAY_TIME_03!)),
  540. DELAY_TIME_04 == null
  541. ? null
  542. : Duration(minutes: int.parse(DELAY_TIME_04!))
  543. ].nonNulls.toList();
  544. String? PAX_BOOKED_C;
  545. String? PAX_BOOKED_Y;
  546. String? get pax_booked => (PAX_BOOKED_C != null || PAX_BOOKED_Y != null)
  547. ? "${(AC_VERSION != null && AC_VERSION!.contains("C")) ? "C${PAX_BOOKED_C ?? 0}." : ""}Y${PAX_BOOKED_Y ?? 0}"
  548. : null;
  549. String? PAX_BOOKED_TRS_C;
  550. String? PAX_BOOKED_TRS_Y;
  551. String? get pax_trs => (PAX_BOOKED_TRS_C != null || PAX_BOOKED_TRS_Y != null)
  552. ? "C${PAX_BOOKED_TRS_C ?? 0}/Y${PAX_BOOKED_TRS_Y ?? 0}"
  553. : null;
  554. String? PAD_BOOKED_C;
  555. String? PAD_BOOKED_Y;
  556. String? get pad_booked => (PAD_BOOKED_C != null || PAD_BOOKED_Y != null)
  557. ? "C${PAD_BOOKED_C ?? 0}/Y${PAD_BOOKED_Y ?? 0}"
  558. : null;
  559. String? OFFBLOCK_DT_A;
  560. String? AIRBORNE_DT_A;
  561. String? LANDING_DT_A;
  562. String? ONBLOCK_DT_A;
  563. List<Jiffy?> get blocks_a => [
  564. (OFFBLOCK_DT_A ?? "").parseyyyymmddhhmm(),
  565. (AIRBORNE_DT_A ?? "").parseyyyymmddhhmm(),
  566. (LANDING_DT_A ?? "").parseyyyymmddhhmm(),
  567. (ONBLOCK_DT_A ?? "").parseyyyymmddhhmm()
  568. ];
  569. String get flt_status {
  570. if (blocks[3] != null) {
  571. return "Arrived";
  572. } else if (blocks[2] != null) {
  573. return "Landed";
  574. } else if (blocks[1] != null) {
  575. return "Inflight";
  576. } else if (blocks[0] != null) {
  577. return "Taxiout";
  578. } else if (jdepest != null &&
  579. jarrsched != null &&
  580. jdepest!.isAfter(jdepsched!)) {
  581. return "Delayed";
  582. } else {
  583. return "Sched";
  584. }
  585. }
  586. String? OFFBLOCK_DT_F;
  587. String? AIRBORNE_DT_F;
  588. String? LANDING_DT_F;
  589. String? ONBLOCK_DT_F;
  590. List<Jiffy?> get blocks_f => [
  591. (OFFBLOCK_DT_F ?? "").parseyyyymmddhhmm(),
  592. (AIRBORNE_DT_F ?? "").parseyyyymmddhhmm(),
  593. (LANDING_DT_F ?? "").parseyyyymmddhhmm(),
  594. (ONBLOCK_DT_F ?? "").parseyyyymmddhhmm()
  595. ];
  596. String? OFFBLOCK_DT_M;
  597. String? AIRBORNE_DT_M;
  598. String? LANDING_DT_M;
  599. String? ONBLOCK_DT_M;
  600. List<Jiffy?> get blocks_m => [
  601. (OFFBLOCK_DT_M ?? "").parseyyyymmddhhmm(),
  602. (AIRBORNE_DT_M ?? "").parseyyyymmddhhmm(),
  603. (LANDING_DT_M ?? "").parseyyyymmddhhmm(),
  604. (ONBLOCK_DT_M ?? "").parseyyyymmddhhmm()
  605. ];
  606. List<Jiffy?> get blocks => [
  607. blocks_m[0] ?? blocks_a[0] ?? blocks_f[0],
  608. blocks_m[1] ?? blocks_a[1] ?? blocks_f[1],
  609. blocks_m[2] ?? blocks_a[2] ?? blocks_f[2],
  610. blocks_m[3] ?? blocks_a[3] ?? blocks_f[3]
  611. ];
  612. Jiffy? get jdep => blocks[0] ?? jdepest ?? jdepsched;
  613. Jiffy? get jarr =>
  614. blocks[3] ??
  615. blocks[2]?.add(minutes: 5) ??
  616. (eet == null ? null : blocks[1]?.addDuration(eet!).add(minutes: 8)) ??
  617. (eet == null
  618. ? null
  619. : blocks[0]?.add(minutes: 5).addDuration(eet!).add(minutes: 8)) ??
  620. (eet == null
  621. ? null
  622. : jdep?.addDuration(eet!).add(minutes: 8).add(minutes: 5)) ??
  623. jarrest ??
  624. jarrsched;
  625. String? EET;
  626. Duration? get eet => EET == null ? null : Duration(minutes: int.parse(EET!));
  627. Acleg({
  628. this.LEG_NO,
  629. this.FN_CARRIER,
  630. this.FN_NUMBER,
  631. this.FN_SUFFIX,
  632. this.DAY_OF_ORIGIN,
  633. this.AC_OWNER,
  634. this.AC_SUBTYPE,
  635. this.AC_VERSION,
  636. this.AC_REGISTRATION,
  637. this.DEP_AP_ACTUAL,
  638. this.DEP_AP_SCHED,
  639. this.DEP_DT_EST,
  640. this.DEP_SCHED_DT,
  641. this.ARR_AP_ACTUAL,
  642. this.ARR_AP_SCHED,
  643. this.ARR_DT_EST,
  644. this.ARR_SCHED_DT,
  645. this.SLOT_TIME_ACTUAL,
  646. this.LEG_TYPE,
  647. this.STATUS,
  648. this.EMPLOYER_COCKPIT,
  649. this.EMPLOYER_CABIN,
  650. this.CYCLES,
  651. this.DELAY_CODE_01,
  652. this.DELAY_CODE_02,
  653. this.DELAY_CODE_03,
  654. this.DELAY_CODE_04,
  655. this.DELAY_TIME_01,
  656. this.DELAY_TIME_02,
  657. this.DELAY_TIME_03,
  658. this.DELAY_TIME_04,
  659. this.SUBDELAY_CODE_01,
  660. this.SUBDELAY_CODE_02,
  661. this.SUBDELAY_CODE_03,
  662. this.SUBDELAY_CODE_04,
  663. this.PAX_BOOKED_C,
  664. this.PAX_BOOKED_Y,
  665. this.PAX_BOOKED_TRS_C,
  666. this.PAX_BOOKED_TRS_Y,
  667. this.PAD_BOOKED_C,
  668. this.PAD_BOOKED_Y,
  669. this.OFFBLOCK_DT_A,
  670. this.AIRBORNE_DT_A,
  671. this.LANDING_DT_A,
  672. this.ONBLOCK_DT_A,
  673. this.OFFBLOCK_DT_F,
  674. this.AIRBORNE_DT_F,
  675. this.LANDING_DT_F,
  676. this.ONBLOCK_DT_F,
  677. this.OFFBLOCK_DT_M,
  678. this.AIRBORNE_DT_M,
  679. this.LANDING_DT_M,
  680. this.ONBLOCK_DT_M,
  681. this.EET,
  682. });
  683. Acleg copyWith({
  684. String? LEG_NO,
  685. String? FN_CARRIER,
  686. String? FN_NUMBER,
  687. String? FN_SUFFIX,
  688. String? DAY_OF_ORIGIN,
  689. String? AC_OWNER,
  690. String? AC_SUBTYPE,
  691. String? AC_VERSION,
  692. String? AC_REGISTRATION,
  693. String? DEP_AP_ACTUAL,
  694. String? DEP_AP_SCHED,
  695. String? DEP_DT_EST,
  696. String? DEP_SCHED_DT,
  697. String? ARR_AP_ACTUAL,
  698. String? ARR_AP_SCHED,
  699. String? ARR_DT_EST,
  700. String? ARR_SCHED_DT,
  701. String? SLOT_TIME_ACTUAL,
  702. String? LEG_TYPE,
  703. String? STATUS,
  704. String? EMPLOYER_COCKPIT,
  705. String? EMPLOYER_CABIN,
  706. String? CYCLES,
  707. String? DELAY_CODE_01,
  708. String? DELAY_CODE_02,
  709. String? DELAY_CODE_03,
  710. String? DELAY_CODE_04,
  711. String? DELAY_TIME_01,
  712. String? DELAY_TIME_02,
  713. String? DELAY_TIME_03,
  714. String? DELAY_TIME_04,
  715. String? SUBDELAY_CODE_01,
  716. String? SUBDELAY_CODE_02,
  717. String? SUBDELAY_CODE_03,
  718. String? SUBDELAY_CODE_04,
  719. String? PAX_BOOKED_C,
  720. String? PAX_BOOKED_Y,
  721. String? PAX_BOOKED_TRS_C,
  722. String? PAX_BOOKED_TRS_Y,
  723. String? PAD_BOOKED_C,
  724. String? PAD_BOOKED_Y,
  725. String? OFFBLOCK_DT_A,
  726. String? AIRBORNE_DT_A,
  727. String? LANDING_DT_A,
  728. String? ONBLOCK_DT_A,
  729. String? OFFBLOCK_DT_F,
  730. String? AIRBORNE_DT_F,
  731. String? LANDING_DT_F,
  732. String? ONBLOCK_DT_F,
  733. String? OFFBLOCK_DT_M,
  734. String? AIRBORNE_DT_M,
  735. String? LANDING_DT_M,
  736. String? ONBLOCK_DT_M,
  737. String? EET,
  738. }) {
  739. return Acleg(
  740. LEG_NO: LEG_NO ?? this.LEG_NO,
  741. FN_CARRIER: FN_CARRIER ?? this.FN_CARRIER,
  742. FN_NUMBER: FN_NUMBER ?? this.FN_NUMBER,
  743. FN_SUFFIX: FN_SUFFIX ?? this.FN_SUFFIX,
  744. DAY_OF_ORIGIN: DAY_OF_ORIGIN ?? this.DAY_OF_ORIGIN,
  745. AC_OWNER: AC_OWNER ?? this.AC_OWNER,
  746. AC_SUBTYPE: AC_SUBTYPE ?? this.AC_SUBTYPE,
  747. AC_VERSION: AC_VERSION ?? this.AC_VERSION,
  748. AC_REGISTRATION: AC_REGISTRATION ?? this.AC_REGISTRATION,
  749. DEP_AP_ACTUAL: DEP_AP_ACTUAL ?? this.DEP_AP_ACTUAL,
  750. DEP_AP_SCHED: DEP_AP_SCHED ?? this.DEP_AP_SCHED,
  751. DEP_DT_EST: DEP_DT_EST ?? this.DEP_DT_EST,
  752. DEP_SCHED_DT: DEP_SCHED_DT ?? this.DEP_SCHED_DT,
  753. ARR_AP_ACTUAL: ARR_AP_ACTUAL ?? this.ARR_AP_ACTUAL,
  754. ARR_AP_SCHED: ARR_AP_SCHED ?? this.ARR_AP_SCHED,
  755. ARR_DT_EST: ARR_DT_EST ?? this.ARR_DT_EST,
  756. ARR_SCHED_DT: ARR_SCHED_DT ?? this.ARR_SCHED_DT,
  757. SLOT_TIME_ACTUAL: SLOT_TIME_ACTUAL ?? this.SLOT_TIME_ACTUAL,
  758. LEG_TYPE: LEG_TYPE ?? this.LEG_TYPE,
  759. STATUS: STATUS ?? this.STATUS,
  760. EMPLOYER_COCKPIT: EMPLOYER_COCKPIT ?? this.EMPLOYER_COCKPIT,
  761. EMPLOYER_CABIN: EMPLOYER_CABIN ?? this.EMPLOYER_CABIN,
  762. CYCLES: CYCLES ?? this.CYCLES,
  763. DELAY_CODE_01: DELAY_CODE_01 ?? this.DELAY_CODE_01,
  764. DELAY_CODE_02: DELAY_CODE_02 ?? this.DELAY_CODE_02,
  765. DELAY_CODE_03: DELAY_CODE_03 ?? this.DELAY_CODE_03,
  766. DELAY_CODE_04: DELAY_CODE_04 ?? this.DELAY_CODE_04,
  767. DELAY_TIME_01: DELAY_TIME_01 ?? this.DELAY_TIME_01,
  768. DELAY_TIME_02: DELAY_TIME_02 ?? this.DELAY_TIME_02,
  769. DELAY_TIME_03: DELAY_TIME_03 ?? this.DELAY_TIME_03,
  770. DELAY_TIME_04: DELAY_TIME_04 ?? this.DELAY_TIME_04,
  771. SUBDELAY_CODE_01: SUBDELAY_CODE_01 ?? this.SUBDELAY_CODE_01,
  772. SUBDELAY_CODE_02: SUBDELAY_CODE_02 ?? this.SUBDELAY_CODE_02,
  773. SUBDELAY_CODE_03: SUBDELAY_CODE_03 ?? this.SUBDELAY_CODE_03,
  774. SUBDELAY_CODE_04: SUBDELAY_CODE_04 ?? this.SUBDELAY_CODE_04,
  775. PAX_BOOKED_C: PAX_BOOKED_C ?? this.PAX_BOOKED_C,
  776. PAX_BOOKED_Y: PAX_BOOKED_Y ?? this.PAX_BOOKED_Y,
  777. PAX_BOOKED_TRS_C: PAX_BOOKED_TRS_C ?? this.PAX_BOOKED_TRS_C,
  778. PAX_BOOKED_TRS_Y: PAX_BOOKED_TRS_Y ?? this.PAX_BOOKED_TRS_Y,
  779. PAD_BOOKED_C: PAD_BOOKED_C ?? this.PAD_BOOKED_C,
  780. PAD_BOOKED_Y: PAD_BOOKED_Y ?? this.PAD_BOOKED_Y,
  781. OFFBLOCK_DT_A: OFFBLOCK_DT_A ?? this.OFFBLOCK_DT_A,
  782. AIRBORNE_DT_A: AIRBORNE_DT_A ?? this.AIRBORNE_DT_A,
  783. LANDING_DT_A: LANDING_DT_A ?? this.LANDING_DT_A,
  784. ONBLOCK_DT_A: ONBLOCK_DT_A ?? this.ONBLOCK_DT_A,
  785. OFFBLOCK_DT_F: OFFBLOCK_DT_F ?? this.OFFBLOCK_DT_F,
  786. AIRBORNE_DT_F: AIRBORNE_DT_F ?? this.AIRBORNE_DT_F,
  787. LANDING_DT_F: LANDING_DT_F ?? this.LANDING_DT_F,
  788. ONBLOCK_DT_F: ONBLOCK_DT_F ?? this.ONBLOCK_DT_F,
  789. OFFBLOCK_DT_M: OFFBLOCK_DT_M ?? this.OFFBLOCK_DT_M,
  790. AIRBORNE_DT_M: AIRBORNE_DT_M ?? this.AIRBORNE_DT_M,
  791. LANDING_DT_M: LANDING_DT_M ?? this.LANDING_DT_M,
  792. ONBLOCK_DT_M: ONBLOCK_DT_M ?? this.ONBLOCK_DT_M,
  793. EET: EET ?? this.EET,
  794. );
  795. }
  796. Map<String, dynamic> toMap() {
  797. return <String, dynamic>{
  798. 'LEG_NO': LEG_NO,
  799. 'FN_CARRIER': FN_CARRIER,
  800. 'FN_NUMBER': FN_NUMBER,
  801. 'FN_SUFFIX': FN_SUFFIX,
  802. 'DAY_OF_ORIGIN': DAY_OF_ORIGIN,
  803. 'AC_OWNER': AC_OWNER,
  804. 'AC_SUBTYPE': AC_SUBTYPE,
  805. 'AC_VERSION': AC_VERSION,
  806. 'AC_REGISTRATION': AC_REGISTRATION,
  807. 'DEP_AP_ACTUAL': DEP_AP_ACTUAL,
  808. 'DEP_AP_SCHED': DEP_AP_SCHED,
  809. 'DEP_DT_EST': DEP_DT_EST,
  810. 'DEP_SCHED_DT': DEP_SCHED_DT,
  811. 'ARR_AP_ACTUAL': ARR_AP_ACTUAL,
  812. 'ARR_AP_SCHED': ARR_AP_SCHED,
  813. 'ARR_DT_EST': ARR_DT_EST,
  814. 'ARR_SCHED_DT': ARR_SCHED_DT,
  815. 'SLOT_TIME_ACTUAL': SLOT_TIME_ACTUAL,
  816. 'LEG_TYPE': LEG_TYPE,
  817. 'STATUS': STATUS,
  818. 'EMPLOYER_COCKPIT': EMPLOYER_COCKPIT,
  819. 'EMPLOYER_CABIN': EMPLOYER_CABIN,
  820. 'CYCLES': CYCLES,
  821. 'DELAY_CODE_01': DELAY_CODE_01,
  822. 'DELAY_CODE_02': DELAY_CODE_02,
  823. 'DELAY_CODE_03': DELAY_CODE_03,
  824. 'DELAY_CODE_04': DELAY_CODE_04,
  825. 'DELAY_TIME_01': DELAY_TIME_01,
  826. 'DELAY_TIME_02': DELAY_TIME_02,
  827. 'DELAY_TIME_03': DELAY_TIME_03,
  828. 'DELAY_TIME_04': DELAY_TIME_04,
  829. 'SUBDELAY_CODE_01': SUBDELAY_CODE_01,
  830. 'SUBDELAY_CODE_02': SUBDELAY_CODE_02,
  831. 'SUBDELAY_CODE_03': SUBDELAY_CODE_03,
  832. 'SUBDELAY_CODE_04': SUBDELAY_CODE_04,
  833. 'PAX_BOOKED_C': PAX_BOOKED_C,
  834. 'PAX_BOOKED_Y': PAX_BOOKED_Y,
  835. 'PAX_BOOKED_TRS_C': PAX_BOOKED_TRS_C,
  836. 'PAX_BOOKED_TRS_Y': PAX_BOOKED_TRS_Y,
  837. 'PAD_BOOKED_C': PAD_BOOKED_C,
  838. 'PAD_BOOKED_Y': PAD_BOOKED_Y,
  839. 'OFFBLOCK_DT_A': OFFBLOCK_DT_A,
  840. 'AIRBORNE_DT_A': AIRBORNE_DT_A,
  841. 'LANDING_DT_A': LANDING_DT_A,
  842. 'ONBLOCK_DT_A': ONBLOCK_DT_A,
  843. 'OFFBLOCK_DT_F': OFFBLOCK_DT_F,
  844. 'AIRBORNE_DT_F': AIRBORNE_DT_F,
  845. 'LANDING_DT_F': LANDING_DT_F,
  846. 'ONBLOCK_DT_F': ONBLOCK_DT_F,
  847. 'OFFBLOCK_DT_M': OFFBLOCK_DT_M,
  848. 'AIRBORNE_DT_M': AIRBORNE_DT_M,
  849. 'LANDING_DT_M': LANDING_DT_M,
  850. 'ONBLOCK_DT_M': ONBLOCK_DT_M,
  851. 'EET': EET,
  852. };
  853. }
  854. factory Acleg.fromList(List datalist) {
  855. //print(datalist);
  856. if (datalist.length >= 54) {
  857. return Acleg(
  858. LEG_NO: datalist[0],
  859. FN_CARRIER: datalist[1],
  860. FN_NUMBER: datalist[2],
  861. FN_SUFFIX: datalist[3],
  862. DAY_OF_ORIGIN: datalist[4],
  863. AC_OWNER: datalist[5],
  864. AC_SUBTYPE: datalist[6],
  865. AC_VERSION: datalist[7],
  866. AC_REGISTRATION: datalist[8],
  867. DEP_AP_ACTUAL: datalist[9],
  868. DEP_AP_SCHED: datalist[10],
  869. DEP_DT_EST: datalist[11],
  870. DEP_SCHED_DT: datalist[12],
  871. ARR_AP_ACTUAL: datalist[13],
  872. ARR_AP_SCHED: datalist[14],
  873. ARR_DT_EST: datalist[15],
  874. ARR_SCHED_DT: datalist[16],
  875. SLOT_TIME_ACTUAL: datalist[17],
  876. LEG_TYPE: datalist[18],
  877. STATUS: datalist[19],
  878. EMPLOYER_COCKPIT: datalist[20],
  879. EMPLOYER_CABIN: datalist[21],
  880. CYCLES: datalist[22],
  881. DELAY_CODE_01: datalist[23],
  882. DELAY_CODE_02: datalist[24],
  883. DELAY_CODE_03: datalist[25],
  884. DELAY_CODE_04: datalist[26],
  885. DELAY_TIME_01: datalist[27],
  886. DELAY_TIME_02: datalist[28],
  887. DELAY_TIME_03: datalist[29],
  888. DELAY_TIME_04: datalist[30],
  889. SUBDELAY_CODE_01: datalist[31],
  890. SUBDELAY_CODE_02: datalist[32],
  891. SUBDELAY_CODE_03: datalist[33],
  892. SUBDELAY_CODE_04: datalist[34],
  893. PAX_BOOKED_C: datalist[35],
  894. PAX_BOOKED_Y: datalist[36],
  895. PAX_BOOKED_TRS_C: datalist[37],
  896. PAX_BOOKED_TRS_Y: datalist[38],
  897. PAD_BOOKED_C: datalist[39],
  898. PAD_BOOKED_Y: datalist[40],
  899. OFFBLOCK_DT_A: datalist[41],
  900. AIRBORNE_DT_A: datalist[42],
  901. LANDING_DT_A: datalist[43],
  902. ONBLOCK_DT_A: datalist[44],
  903. OFFBLOCK_DT_F: datalist[45],
  904. AIRBORNE_DT_F: datalist[46],
  905. LANDING_DT_F: datalist[47],
  906. ONBLOCK_DT_F: datalist[48],
  907. OFFBLOCK_DT_M: datalist[49],
  908. AIRBORNE_DT_M: datalist[50],
  909. LANDING_DT_M: datalist[51],
  910. ONBLOCK_DT_M: datalist[52],
  911. EET: datalist[53]);
  912. } else {
  913. return Acleg();
  914. }
  915. }
  916. factory Acleg.fromMap(Map<String, dynamic> map) {
  917. return Acleg(
  918. LEG_NO: map['LEG_NO'] != null ? map['LEG_NO'] as String : null,
  919. FN_CARRIER:
  920. map['FN_CARRIER'] != null ? map['FN_CARRIER'] as String : null,
  921. FN_NUMBER: map['FN_NUMBER'] != null ? map['FN_NUMBER'] as String : null,
  922. FN_SUFFIX: map['FN_SUFFIX'] != null ? map['FN_SUFFIX'] as String : null,
  923. DAY_OF_ORIGIN:
  924. map['DAY_OF_ORIGIN'] != null ? map['DAY_OF_ORIGIN'] as String : null,
  925. AC_OWNER: map['AC_OWNER'] != null ? map['AC_OWNER'] as String : null,
  926. AC_SUBTYPE:
  927. map['AC_SUBTYPE'] != null ? map['AC_SUBTYPE'] as String : null,
  928. AC_VERSION:
  929. map['AC_VERSION'] != null ? map['AC_VERSION'] as String : null,
  930. AC_REGISTRATION: map['AC_REGISTRATION'] != null
  931. ? map['AC_REGISTRATION'] as String
  932. : null,
  933. DEP_AP_ACTUAL:
  934. map['DEP_AP_ACTUAL'] != null ? map['DEP_AP_ACTUAL'] as String : null,
  935. DEP_AP_SCHED:
  936. map['DEP_AP_SCHED'] != null ? map['DEP_AP_SCHED'] as String : null,
  937. DEP_DT_EST:
  938. map['DEP_DT_EST'] != null ? map['DEP_DT_EST'] as String : null,
  939. DEP_SCHED_DT:
  940. map['DEP_SCHED_DT'] != null ? map['DEP_SCHED_DT'] as String : null,
  941. ARR_AP_ACTUAL:
  942. map['ARR_AP_ACTUAL'] != null ? map['ARR_AP_ACTUAL'] as String : null,
  943. ARR_AP_SCHED:
  944. map['ARR_AP_SCHED'] != null ? map['ARR_AP_SCHED'] as String : null,
  945. ARR_DT_EST:
  946. map['ARR_DT_EST'] != null ? map['ARR_DT_EST'] as String : null,
  947. ARR_SCHED_DT:
  948. map['ARR_SCHED_DT'] != null ? map['ARR_SCHED_DT'] as String : null,
  949. SLOT_TIME_ACTUAL: map['SLOT_TIME_ACTUAL'] != null
  950. ? map['SLOT_TIME_ACTUAL'] as String
  951. : null,
  952. LEG_TYPE: map['LEG_TYPE'] != null ? map['LEG_TYPE'] as String : null,
  953. EMPLOYER_COCKPIT: map['EMPLOYER_COCKPIT'] != null
  954. ? map['EMPLOYER_COCKPIT'] as String
  955. : null,
  956. EMPLOYER_CABIN: map['EMPLOYER_CABIN'] != null
  957. ? map['EMPLOYER_CABIN'] as String
  958. : null,
  959. // CYCLES: map['CYCLES'] != null ? map['CYCLES'] as String : null,
  960. DELAY_CODE_01:
  961. map['DELAY_CODE_01'] != null ? map['DELAY_CODE_01'] as String : null,
  962. DELAY_CODE_02:
  963. map['DELAY_CODE_02'] != null ? map['DELAY_CODE_02'] as String : null,
  964. DELAY_CODE_03:
  965. map['DELAY_CODE_03'] != null ? map['DELAY_CODE_03'] as String : null,
  966. DELAY_CODE_04:
  967. map['DELAY_CODE_04'] != null ? map['DELAY_CODE_04'] as String : null,
  968. DELAY_TIME_01:
  969. map['DELAY_TIME_01'] != null ? map['DELAY_TIME_01'] as String : null,
  970. DELAY_TIME_02:
  971. map['DELAY_TIME_02'] != null ? map['DELAY_TIME_02'] as String : null,
  972. DELAY_TIME_03:
  973. map['DELAY_TIME_03'] != null ? map['DELAY_TIME_03'] as String : null,
  974. DELAY_TIME_04:
  975. map['DELAY_TIME_04'] != null ? map['DELAY_TIME_04'] as String : null,
  976. SUBDELAY_CODE_01: map['SUBDELAY_CODE_01'] != null
  977. ? map['SUBDELAY_CODE_01'] as String
  978. : null,
  979. SUBDELAY_CODE_02: map['SUBDELAY_CODE_02'] != null
  980. ? map['SUBDELAY_CODE_02'] as String
  981. : null,
  982. SUBDELAY_CODE_03: map['SUBDELAY_CODE_03'] != null
  983. ? map['SUBDELAY_CODE_03'] as String
  984. : null,
  985. SUBDELAY_CODE_04: map['SUBDELAY_CODE_04'] != null
  986. ? map['SUBDELAY_CODE_04'] as String
  987. : null,
  988. PAX_BOOKED_C:
  989. map['PAX_BOOKED_C'] != null ? map['PAX_BOOKED_C'] as String : null,
  990. PAX_BOOKED_Y:
  991. map['PAX_BOOKED_Y'] != null ? map['PAX_BOOKED_Y'] as String : null,
  992. PAX_BOOKED_TRS_C: map['PAX_BOOKED_TRS_C'] != null
  993. ? map['PAX_BOOKED_TRS_C'] as String
  994. : null,
  995. PAX_BOOKED_TRS_Y: map['PAX_BOOKED_TRS_Y'] != null
  996. ? map['PAX_BOOKED_TRS_Y'] as String
  997. : null,
  998. PAD_BOOKED_C:
  999. map['PAD_BOOKED_C'] != null ? map['PAD_BOOKED_C'] as String : null,
  1000. PAD_BOOKED_Y:
  1001. map['PAD_BOOKED_Y'] != null ? map['PAD_BOOKED_Y'] as String : null,
  1002. OFFBLOCK_DT_A:
  1003. map['OFFBLOCK_DT_A'] != null ? map['OFFBLOCK_DT_A'] as String : null,
  1004. AIRBORNE_DT_A:
  1005. map['AIRBORNE_DT_A'] != null ? map['AIRBORNE_DT_A'] as String : null,
  1006. LANDING_DT_A:
  1007. map['LANDING_DT_A'] != null ? map['LANDING_DT_A'] as String : null,
  1008. ONBLOCK_DT_A:
  1009. map['ONBLOCK_DT_A'] != null ? map['ONBLOCK_DT_A'] as String : null,
  1010. OFFBLOCK_DT_F:
  1011. map['OFFBLOCK_DT_F'] != null ? map['OFFBLOCK_DT_F'] as String : null,
  1012. AIRBORNE_DT_F:
  1013. map['AIRBORNE_DT_F'] != null ? map['AIRBORNE_DT_F'] as String : null,
  1014. LANDING_DT_F:
  1015. map['LANDING_DT_F'] != null ? map['LANDING_DT_F'] as String : null,
  1016. ONBLOCK_DT_F:
  1017. map['ONBLOCK_DT_F'] != null ? map['ONBLOCK_DT_F'] as String : null,
  1018. OFFBLOCK_DT_M:
  1019. map['OFFBLOCK_DT_M'] != null ? map['OFFBLOCK_DT_M'] as String : null,
  1020. AIRBORNE_DT_M:
  1021. map['AIRBORNE_DT_M'] != null ? map['AIRBORNE_DT_M'] as String : null,
  1022. LANDING_DT_M:
  1023. map['LANDING_DT_M'] != null ? map['LANDING_DT_M'] as String : null,
  1024. ONBLOCK_DT_M:
  1025. map['ONBLOCK_DT_M'] != null ? map['ONBLOCK_DT_M'] as String : null,
  1026. EET: map['EET'] != null ? map['EET'] as String : null,
  1027. );
  1028. }
  1029. String toJson() => json.encode(toMap());
  1030. factory Acleg.fromJson(String source) =>
  1031. Acleg.fromMap(json.decode(source) as Map<String, dynamic>);
  1032. @override
  1033. String toString() {
  1034. return 'Acleg(LEG_NO: $LEG_NO, FN_CARRIER: $FN_CARRIER, FN_NUMBER: $FN_NUMBER, FN_SUFFIX: $FN_SUFFIX, DAY_OF_ORIGIN: $DAY_OF_ORIGIN, AC_OWNER: $AC_OWNER, AC_SUBTYPE: $AC_SUBTYPE, AC_VERSION: $AC_VERSION, AC_REGISTRATION: $AC_REGISTRATION, DEP_AP_ACTUAL: $DEP_AP_ACTUAL, DEP_AP_SCHED: $DEP_AP_SCHED, DEP_DT_EST: $DEP_DT_EST, DEP_SCHED_DT: $DEP_SCHED_DT, ARR_AP_ACTUAL: $ARR_AP_ACTUAL, ARR_AP_SCHED: $ARR_AP_SCHED, ARR_DT_EST: $ARR_DT_EST, ARR_SCHED_DT: $ARR_SCHED_DT, SLOT_TIME_ACTUAL: $SLOT_TIME_ACTUAL, LEG_TYPE: $LEG_TYPE, EMPLOYER_COCKPIT: $EMPLOYER_COCKPIT, EMPLOYER_CABIN: $EMPLOYER_CABIN, CYCLES: $CYCLES, DELAY_CODE_01: $DELAY_CODE_01, DELAY_CODE_02: $DELAY_CODE_02, DELAY_CODE_03: $DELAY_CODE_03, DELAY_CODE_04: $DELAY_CODE_04, DELAY_TIME_01: $DELAY_TIME_01, DELAY_TIME_02: $DELAY_TIME_02, DELAY_TIME_03: $DELAY_TIME_03, DELAY_TIME_04: $DELAY_TIME_04, SUBDELAY_CODE_01: $SUBDELAY_CODE_01, SUBDELAY_CODE_02: $SUBDELAY_CODE_02, SUBDELAY_CODE_03: $SUBDELAY_CODE_03, SUBDELAY_CODE_04: $SUBDELAY_CODE_04, PAX_BOOKED_C: $PAX_BOOKED_C, PAX_BOOKED_Y: $PAX_BOOKED_Y, PAX_BOOKED_TRS_C: $PAX_BOOKED_TRS_C, PAX_BOOKED_TRS_Y: $PAX_BOOKED_TRS_Y, PAD_BOOKED_C: $PAD_BOOKED_C, PAD_BOOKED_Y: $PAD_BOOKED_Y, OFFBLOCK_DT_A: $OFFBLOCK_DT_A, AIRBORNE_DT_A: $AIRBORNE_DT_A, LANDING_DT_A: $LANDING_DT_A, ONBLOCK_DT_A: $ONBLOCK_DT_A, OFFBLOCK_DT_F: $OFFBLOCK_DT_F, AIRBORNE_DT_F: $AIRBORNE_DT_F, LANDING_DT_F: $LANDING_DT_F, ONBLOCK_DT_F: $ONBLOCK_DT_F, OFFBLOCK_DT_M: $OFFBLOCK_DT_M, AIRBORNE_DT_M: $AIRBORNE_DT_M, LANDING_DT_M: $LANDING_DT_M, ONBLOCK_DT_M: $ONBLOCK_DT_M, EET: $EET)';
  1035. }
  1036. @override
  1037. bool operator ==(covariant Acleg other) {
  1038. if (identical(this, other)) return true;
  1039. return other.LEG_NO == LEG_NO &&
  1040. other.FN_CARRIER == FN_CARRIER &&
  1041. other.FN_NUMBER == FN_NUMBER &&
  1042. other.FN_SUFFIX == FN_SUFFIX &&
  1043. other.DAY_OF_ORIGIN == DAY_OF_ORIGIN &&
  1044. other.AC_OWNER == AC_OWNER &&
  1045. other.AC_SUBTYPE == AC_SUBTYPE &&
  1046. other.AC_VERSION == AC_VERSION &&
  1047. other.AC_REGISTRATION == AC_REGISTRATION &&
  1048. other.DEP_AP_ACTUAL == DEP_AP_ACTUAL &&
  1049. other.DEP_AP_SCHED == DEP_AP_SCHED &&
  1050. other.DEP_DT_EST == DEP_DT_EST &&
  1051. other.DEP_SCHED_DT == DEP_SCHED_DT &&
  1052. other.ARR_AP_ACTUAL == ARR_AP_ACTUAL &&
  1053. other.ARR_AP_SCHED == ARR_AP_SCHED &&
  1054. other.ARR_DT_EST == ARR_DT_EST &&
  1055. other.ARR_SCHED_DT == ARR_SCHED_DT &&
  1056. other.SLOT_TIME_ACTUAL == SLOT_TIME_ACTUAL &&
  1057. other.LEG_TYPE == LEG_TYPE &&
  1058. other.EMPLOYER_COCKPIT == EMPLOYER_COCKPIT &&
  1059. other.EMPLOYER_CABIN == EMPLOYER_CABIN &&
  1060. other.CYCLES == CYCLES &&
  1061. other.DELAY_CODE_01 == DELAY_CODE_01 &&
  1062. other.DELAY_CODE_02 == DELAY_CODE_02 &&
  1063. other.DELAY_CODE_03 == DELAY_CODE_03 &&
  1064. other.DELAY_CODE_04 == DELAY_CODE_04 &&
  1065. other.DELAY_TIME_01 == DELAY_TIME_01 &&
  1066. other.DELAY_TIME_02 == DELAY_TIME_02 &&
  1067. other.DELAY_TIME_03 == DELAY_TIME_03 &&
  1068. other.DELAY_TIME_04 == DELAY_TIME_04 &&
  1069. other.SUBDELAY_CODE_01 == SUBDELAY_CODE_01 &&
  1070. other.SUBDELAY_CODE_02 == SUBDELAY_CODE_02 &&
  1071. other.SUBDELAY_CODE_03 == SUBDELAY_CODE_03 &&
  1072. other.SUBDELAY_CODE_04 == SUBDELAY_CODE_04 &&
  1073. other.PAX_BOOKED_C == PAX_BOOKED_C &&
  1074. other.PAX_BOOKED_Y == PAX_BOOKED_Y &&
  1075. other.PAX_BOOKED_TRS_C == PAX_BOOKED_TRS_C &&
  1076. other.PAX_BOOKED_TRS_Y == PAX_BOOKED_TRS_Y &&
  1077. other.PAD_BOOKED_C == PAD_BOOKED_C &&
  1078. other.PAD_BOOKED_Y == PAD_BOOKED_Y &&
  1079. other.OFFBLOCK_DT_A == OFFBLOCK_DT_A &&
  1080. other.AIRBORNE_DT_A == AIRBORNE_DT_A &&
  1081. other.LANDING_DT_A == LANDING_DT_A &&
  1082. other.ONBLOCK_DT_A == ONBLOCK_DT_A &&
  1083. other.OFFBLOCK_DT_F == OFFBLOCK_DT_F &&
  1084. other.AIRBORNE_DT_F == AIRBORNE_DT_F &&
  1085. other.LANDING_DT_F == LANDING_DT_F &&
  1086. other.ONBLOCK_DT_F == ONBLOCK_DT_F &&
  1087. other.OFFBLOCK_DT_M == OFFBLOCK_DT_M &&
  1088. other.AIRBORNE_DT_M == AIRBORNE_DT_M &&
  1089. other.LANDING_DT_M == LANDING_DT_M &&
  1090. other.ONBLOCK_DT_M == ONBLOCK_DT_M &&
  1091. other.EET == EET;
  1092. }
  1093. @override
  1094. int get hashCode {
  1095. return LEG_NO.hashCode ^
  1096. FN_CARRIER.hashCode ^
  1097. FN_NUMBER.hashCode ^
  1098. FN_SUFFIX.hashCode ^
  1099. DAY_OF_ORIGIN.hashCode ^
  1100. AC_OWNER.hashCode ^
  1101. AC_SUBTYPE.hashCode ^
  1102. AC_VERSION.hashCode ^
  1103. AC_REGISTRATION.hashCode ^
  1104. DEP_AP_ACTUAL.hashCode ^
  1105. DEP_AP_SCHED.hashCode ^
  1106. DEP_DT_EST.hashCode ^
  1107. DEP_SCHED_DT.hashCode ^
  1108. ARR_AP_ACTUAL.hashCode ^
  1109. ARR_AP_SCHED.hashCode ^
  1110. ARR_DT_EST.hashCode ^
  1111. ARR_SCHED_DT.hashCode ^
  1112. SLOT_TIME_ACTUAL.hashCode ^
  1113. LEG_TYPE.hashCode ^
  1114. EMPLOYER_COCKPIT.hashCode ^
  1115. EMPLOYER_CABIN.hashCode ^
  1116. CYCLES.hashCode ^
  1117. DELAY_CODE_01.hashCode ^
  1118. DELAY_CODE_02.hashCode ^
  1119. DELAY_CODE_03.hashCode ^
  1120. DELAY_CODE_04.hashCode ^
  1121. DELAY_TIME_01.hashCode ^
  1122. DELAY_TIME_02.hashCode ^
  1123. DELAY_TIME_03.hashCode ^
  1124. DELAY_TIME_04.hashCode ^
  1125. SUBDELAY_CODE_01.hashCode ^
  1126. SUBDELAY_CODE_02.hashCode ^
  1127. SUBDELAY_CODE_03.hashCode ^
  1128. SUBDELAY_CODE_04.hashCode ^
  1129. PAX_BOOKED_C.hashCode ^
  1130. PAX_BOOKED_Y.hashCode ^
  1131. PAX_BOOKED_TRS_C.hashCode ^
  1132. PAX_BOOKED_TRS_Y.hashCode ^
  1133. PAD_BOOKED_C.hashCode ^
  1134. PAD_BOOKED_Y.hashCode ^
  1135. OFFBLOCK_DT_A.hashCode ^
  1136. AIRBORNE_DT_A.hashCode ^
  1137. LANDING_DT_A.hashCode ^
  1138. ONBLOCK_DT_A.hashCode ^
  1139. OFFBLOCK_DT_F.hashCode ^
  1140. AIRBORNE_DT_F.hashCode ^
  1141. LANDING_DT_F.hashCode ^
  1142. ONBLOCK_DT_F.hashCode ^
  1143. OFFBLOCK_DT_M.hashCode ^
  1144. AIRBORNE_DT_M.hashCode ^
  1145. LANDING_DT_M.hashCode ^
  1146. ONBLOCK_DT_M.hashCode ^
  1147. EET.hashCode;
  1148. }
  1149. }
  1150. extension StringExtensions on String {
  1151. String capitalize() {
  1152. if (isEmpty) {
  1153. return this;
  1154. } else {
  1155. return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
  1156. }
  1157. }
  1158. String capitalizeword() {
  1159. return split(' ').map((word) => word.capitalize()).join(' ');
  1160. }
  1161. Jiffy? parseddmmyyyyhhmm() => length >= 15
  1162. ? Jiffy.parse(
  1163. "${substring(6, 10)}-${substring(3, 5)}-${substring(0, 2)} ${substring(11, 13)}:${substring(13, 15)}",
  1164. pattern: 'yyyy-MM-dd HH:mm',
  1165. isUtc: true)
  1166. : null;
  1167. Jiffy? parseyyyymmddhhmm() => length >= 16
  1168. ? Jiffy.parse(this,
  1169. pattern: 'yyyy-MM-dd HH:mm:ss',
  1170. // "${substring(6, 10)}-${substring(3, 5)}-${substring(0, 2)} ${substring(11, 13)}${substring(13, 16)}",
  1171. // pattern: 'yyyy-MM-dd HH:mm',
  1172. isUtc: true)
  1173. : null;
  1174. }
  1175. class FilesAsData {
  1176. String? filename;
  1177. String? updatedAt;
  1178. String data;
  1179. FilesAsData({
  1180. this.filename,
  1181. this.updatedAt,
  1182. required this.data,
  1183. });
  1184. }
  1185. const maxItemsToSelect = 200;
  1186. const maxItemsToInsert = 500;
  1187. const maxItemsToRemove = 500;
  1188. processCsvData(File tempfile, SupabaseClient supabase) async {
  1189. List<FilesAsData> csvData = [];
  1190. final filename = tempfile.path.split('/').last;
  1191. final bytes = await tempfile.readAsBytes();
  1192. // Check if file is a zip archive
  1193. String? csvcontent;
  1194. if (filename.toLowerCase().endsWith('.zip')) {
  1195. final archive = ZipDecoder().decodeBytes(bytes);
  1196. for (final file in archive) {
  1197. if (!file.isFile) continue;
  1198. csvcontent = utf8.decode(file.content as List<int>);
  1199. csvData.add(FilesAsData(filename: file.name, data: csvcontent));
  1200. }
  1201. } else {
  1202. // For non-zip files, store in extracted folder
  1203. csvcontent = utf8.decode(bytes);
  1204. csvData.add(FilesAsData(filename: filename, data: csvcontent));
  1205. }
  1206. for (final FilesAsData data in csvData) {
  1207. //inserting data
  1208. if (tables.keys.contains(data.filename)) {
  1209. final mapsToInsert =
  1210. createListOfMaps(headers[data.filename] ?? [], csv2list(data.data));
  1211. final scopeName = scopes[data.filename!]!;
  1212. final scopeInNew = mapsToInsert
  1213. .fold(<String>{}, (t, e) => t..add(e[scopeName] ?? "")).toList();
  1214. // print("Loading old data scope: ${scopeInNew.length}");
  1215. List<Map<String, dynamic>> old = [];
  1216. for (var e in splitList(scopeInNew, headerToNb(scopeInNew))) {
  1217. final res = await supabase
  1218. .from(tables[data.filename]!)
  1219. .select()
  1220. .inFilter(scopeName, e)
  1221. .limit(100000);
  1222. old.addAll(res);
  1223. // print("Loaded old data scope: ${e.length}");
  1224. }
  1225. // Replace with your actual table name
  1226. final oldComparable = old
  1227. .map((e) => filterMapByKeys(e, headers[data.filename] ?? []))
  1228. .toList();
  1229. List<int> indexToRemove = [];
  1230. List<int> indexToMaintain = [];
  1231. // print("Deleting old data scope: ${mapsToInsert.length}");
  1232. for (int i = 0; i < oldComparable.length; i++) {
  1233. final item = oldComparable[i];
  1234. final index = findIndex(mapsToInsert, item);
  1235. if (index != -1) {
  1236. indexToMaintain.add(i);
  1237. mapsToInsert.removeAt(index);
  1238. } else {
  1239. indexToRemove.add(i);
  1240. }
  1241. }
  1242. // print(
  1243. // " indexToRemove: ${indexToRemove.length} , indexToMaintain: ${indexToMaintain.length}");
  1244. // print("delete from db");
  1245. // print("delete from db ${indexToRemove.length}");
  1246. for (var e in splitList(indexToRemove.map((e) => old[e]['id']).toList(),
  1247. headerToNb(indexToRemove.map((e) => old[e]['id']).toList()))) {
  1248. await supabase
  1249. .from(tables[data.filename]!) // Replace with your actual table name
  1250. .delete()
  1251. .inFilter('id', e);
  1252. // print("Deleted old data scope: ${e.length}");
  1253. }
  1254. // splitList(indexToRemove.map((e) => old[e]['id']).toList(), 200).forEach(
  1255. // (e) async => await supabase
  1256. // .from(
  1257. // tables[data.filename]!) // Replace with your actual table name
  1258. // .delete()
  1259. // .inFilter('id', e));
  1260. // print("insert in db");
  1261. await supabase
  1262. .from(tables[data.filename]!) // Replace with your actual table name
  1263. .insert(mapsToInsert);
  1264. // print("insert in db ${mapsToInsert.length}");
  1265. // for (var e in splitList(mapsToInsert, headerToNb(mapsToInsert))) {
  1266. // await supabase
  1267. // .from(tables[data.filename]!) // Replace with your actual table name
  1268. // .insert(e);
  1269. // print("Inserted old data scope: ${e.length}");
  1270. // }
  1271. // splitList(mapsToInsert, 200).forEach((e) async => await supabase
  1272. // .from(tables[data.filename]!) // Replace with your actual table name
  1273. // .insert(e));
  1274. // print("end");
  1275. // print(createListOfMaps(headers[data.filename] ?? [], csv2list(data.data)));
  1276. } else {
  1277. print("filename: ${data.filename} unknown, not inserted.");
  1278. }
  1279. }
  1280. }
  1281. bool mapEquals(Map<String, dynamic> map1, Map<String, dynamic> map2) {
  1282. //if (map1.length != map2.length) return false;
  1283. for (var key in map1.keys) {
  1284. if (map1[key] != map2[key]) return false;
  1285. }
  1286. return true;
  1287. }
  1288. int findIndex(List<dynamic> list, dynamic element) {
  1289. for (int i = 0; i < list.length; i++) {
  1290. if (mapEquals(list[i], element)) {
  1291. return i;
  1292. }
  1293. }
  1294. return -1; // Return -1 if the element is not found
  1295. }
  1296. Map<String, dynamic> filterMapByKeys(
  1297. Map<String, dynamic> originalMap, List<String> keysToInclude) {
  1298. // Create a new map to hold the filtered results
  1299. Map<String, dynamic> filteredMap = {};
  1300. // Iterate through the list of keys to include
  1301. for (String key in keysToInclude) {
  1302. // Check if the key exists in the original map
  1303. if (originalMap.containsKey(key)) {
  1304. filteredMap[key] = originalMap[key]; // Add to the new map
  1305. }
  1306. }
  1307. return filteredMap;
  1308. }
  1309. List<List<T>> splitList<T>(List<T> originalList, int maxSize) {
  1310. List<List<T>> sublists = [];
  1311. for (int i = 0; i < originalList.length; i += maxSize) {
  1312. // Create a sublist for the current chunk
  1313. List<T> sublist = originalList.sublist(
  1314. i,
  1315. (i + maxSize > originalList.length) ? originalList.length : i + maxSize,
  1316. );
  1317. sublists.add(sublist);
  1318. }
  1319. return sublists;
  1320. }
  1321. int headerToNb(List list) {
  1322. //header max of 16k
  1323. final maxheader = 4 * 1024 * 8;
  1324. if (list.isEmpty) {
  1325. return list.length;
  1326. }
  1327. final length1 = (list.toString().length / list.length).ceil() * 8;
  1328. final lengthurl = 200 * 8;
  1329. final res = ((maxheader - lengthurl) / length1).floor();
  1330. //print("header2nb: $res");
  1331. return res;
  1332. }