No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

absensi_history_screen.dart 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:google_fonts/google_fonts.dart';
  4. import 'package:hris_selfservice_mobile/constants.dart';
  5. import 'package:intl/intl.dart';
  6. import 'package:progress_dialog_null_safe/progress_dialog_null_safe.dart';
  7. import 'dart:developer' as logDev;
  8. import '../AjukanCuti/backgroundHistory.dart';
  9. import 'RequestHttp/historyAbsensi_post.dart';
  10. class HistoryAbsensi extends StatefulWidget {
  11. const HistoryAbsensi({Key? key}) : super(key: key);
  12. @override
  13. State<HistoryAbsensi> createState() => _HistoryAbsensi();
  14. }
  15. class _HistoryAbsensi extends State<HistoryAbsensi> {
  16. late List <String> id_List;
  17. late List <String> employee_name_List;
  18. late List <String> check_in_List;
  19. late List <String> check_out_List;
  20. late List <String> worked_hours_List;
  21. late List <String> dayDate_List;
  22. late List <String> date_List;
  23. late List <String> month_List;
  24. //late List <String> workingHours_List;
  25. late List <String> showCheckIn_List;
  26. late List <String> showCheckOut_List;
  27. int HistoryLength = 0;
  28. //List Visibility Double Date
  29. late List <bool> visibilityDate2;
  30. @override
  31. initState() {
  32. super.initState();
  33. id_List = [""];
  34. employee_name_List = [""];
  35. check_in_List = [""];
  36. check_out_List = [""];
  37. worked_hours_List = [""];
  38. dayDate_List = [""];
  39. date_List = [""];
  40. month_List = [""];
  41. //workingHours_List = [""];
  42. showCheckIn_List = [""];
  43. showCheckOut_List = [""];
  44. visibilityDate2 = [false];
  45. WidgetsBinding.instance.addPostFrameCallback((_) async {
  46. getHistoryData();
  47. });
  48. }
  49. getHistoryData() async {
  50. ProgressDialog loading = ProgressDialog(context);
  51. loading = ProgressDialog(context,
  52. type: ProgressDialogType.normal, isDismissible: false, showLogs: true);
  53. loading.style(
  54. message: 'Please Wait .....',
  55. borderRadius: 3,
  56. backgroundColor: Colors.white,
  57. progressWidget: CircularProgressIndicator(),
  58. elevation: 10.0,
  59. padding: EdgeInsets.all(10),
  60. insetAnimCurve: Curves.easeInOut,
  61. progress: 0.0,
  62. maxProgress: 100.0,
  63. progressTextStyle: TextStyle(
  64. color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400),
  65. messageTextStyle: TextStyle(
  66. color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600));
  67. loading.show();
  68. HistoryAbsensi_Post.connectToAPI().then((valueResult) async {
  69. Map<String, dynamic> object = jsonDecode(valueResult);
  70. if (object.containsKey("result").toString() == "true") {
  71. String result = object['result'].toString();
  72. if (result.contains("failed")) {
  73. loading.hide();
  74. alertDialogFailedRetrievedData(context);
  75. } else {
  76. List <dynamic> historyAbsensi = object['result'];
  77. loading.hide();
  78. setState(() {
  79. for (int i = 0; i < historyAbsensi.length; i++){
  80. String id = historyAbsensi[i]['id'].toString();
  81. String employee_name = historyAbsensi[i]['employee_name'].toString();
  82. String check_in = historyAbsensi[i]['check_in'].toString();
  83. String check_out = historyAbsensi[i]['check_out'].toString();
  84. String worked_hours = historyAbsensi[i]['worked_hours'].toString();
  85. double hours = double.parse(worked_hours);
  86. if (check_in != "false"){
  87. String date = DateFormat('dd').format(DateTime.parse(check_in));
  88. String month = DateFormat('MMM').format(DateTime.parse(check_in));
  89. //Convert UTC to Local Time - Check In Time
  90. DateTime checkInTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(check_in, true);
  91. String checkInTimeLocal = checkInTime.toLocal().toString();
  92. String showCheckInTime = checkInTimeLocal.substring(11, 19);
  93. //logDev.log(showCheckInTime.substring(0,5), name: "SHOW CHECK IN TIME");
  94. date_List.add(date + "|00");
  95. month_List.add(month + "|000");
  96. showCheckIn_List.add(showCheckInTime.substring(0,5));
  97. //visibilityDate2[i+1] = false;
  98. }
  99. if (check_out != "false"){
  100. //Convert UTC to Local Time - Check Out Time
  101. DateTime checkOutTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(check_out, true);
  102. String dayDateOut = DateFormat('EEEE').format(DateTime.parse(check_out));
  103. String dateOut = DateFormat('dd').format(DateTime.parse(check_out));
  104. String checkOutTimeLocal = checkOutTime.toLocal().toString();
  105. String showCheckOutTime = checkOutTimeLocal.substring(11, 19);
  106. //logDev.log(showCheckOutTime, name: "SHOW CHECK OUT TIME");
  107. showCheckOut_List.add(showCheckOutTime.substring(0,5));
  108. //visibilityDate2[i+1] = true;
  109. if (check_in.substring(0, 10) == check_out.substring(0,10)){
  110. //Get Day Check In
  111. String dayDateIn = DateFormat('EEEE').format(DateTime.parse(check_in));
  112. String dateIn = DateFormat('dd').format(DateTime.parse(check_in));
  113. String monthIn = DateFormat('MMM').format(DateTime.parse(check_in));
  114. //dayDate_List.add(dayDate.substring(0,3));
  115. dayDate_List.add(dayDateIn.substring(0,3) + "|000");
  116. date_List[i+1] = dateIn + "|00";
  117. month_List[i+1] = monthIn + "|000";
  118. visibilityDate2[i+1] = false;
  119. } else if (check_in.substring(0, 10) != check_out.substring(0,10)){
  120. //Get Day Check In & Check Out
  121. String dayDateIn = DateFormat('EEEE').format(DateTime.parse(check_in));
  122. String dayDateOut = DateFormat('EEEE').format(DateTime.parse(check_out));
  123. String dateIn = DateFormat('dd').format(DateTime.parse(check_in));
  124. String monthIn = DateFormat('MMM').format(DateTime.parse(check_in));
  125. String dateOut = DateFormat('dd').format(DateTime.parse(check_out));
  126. String monthOut = DateFormat('MMM').format(DateTime.parse(check_out));
  127. logDev.log(dateIn + "\n" + monthIn + "\n" + dateOut + "\n" + monthOut, name: "ABSENSI IN OUT TIDAK SAMA");
  128. dayDate_List.add(dayDateIn.substring(0,3) + "|" + dayDateOut.substring(0,3));
  129. date_List[i+1] = dateIn + "|" + dateOut;
  130. month_List[i+1] = monthIn + "|" + monthOut;
  131. visibilityDate2[i+1] = true;
  132. logDev.log(dayDate_List.toString() + "\n" + date_List.toString() + "\n" + month_List.toString(), name: "LIST ABSENSI IN OUT TIDAK SAMA");
  133. }
  134. }
  135. if (check_in == "false"){
  136. String show_check_in = "-";
  137. showCheckIn_List.add(show_check_in);
  138. }
  139. if (check_out == "false"){
  140. String show_check_out = "-";
  141. //String workingHours = "-";
  142. //workingHours_List.add(workingHours);
  143. showCheckOut_List.add(show_check_out);
  144. String dayDate = DateFormat('EEEE').format(DateTime.parse(check_in));
  145. dayDate_List.add(dayDate.substring(0,3) + "|000");
  146. }
  147. if (check_in != "false" && check_out != "false"){
  148. DateFormat format = DateFormat("HH:mm");
  149. DateTime cIn = format.parse(check_in.substring(11,16));
  150. DateTime cOut = format.parse(check_out.substring(11,16));
  151. //workingHours_List.add("${cOut.difference(cIn)}".substring(0,4));
  152. }
  153. id_List.add(id);
  154. employee_name_List.add(employee_name);
  155. check_in_List.add(check_in);
  156. check_out_List.add(check_out);
  157. worked_hours_List.add(hours.toStringAsFixed(3));
  158. }
  159. id_List.removeAt(0);
  160. employee_name_List.removeAt(0);
  161. check_in_List.removeAt(0);
  162. check_out_List.removeAt(0);
  163. worked_hours_List.removeAt(0);
  164. dayDate_List.removeAt(0);
  165. date_List.removeAt(0);
  166. month_List.removeAt(0);
  167. //workingHours_List.removeAt(0);
  168. showCheckIn_List.removeAt(0);
  169. showCheckOut_List.removeAt(0);
  170. visibilityDate2.removeAt(0);
  171. HistoryLength = historyAbsensi.length;
  172. });
  173. }
  174. } else {
  175. alertDialogFailedRetrievedData(context);
  176. }
  177. });
  178. loading.hide();
  179. }
  180. @override
  181. Widget build(BuildContext context) {
  182. var size = MediaQuery.of(context).size;
  183. return Scaffold(
  184. body: Stack(
  185. children: [
  186. Column(
  187. children: <Widget>[
  188. Stack(
  189. children: [
  190. WavyHeader(),
  191. Container(
  192. margin: EdgeInsets.only(
  193. top: (size.height / 6) - 20),
  194. padding: EdgeInsets.fromLTRB(0, 5, 25, 5),
  195. child: Row(
  196. mainAxisAlignment: MainAxisAlignment.end,
  197. crossAxisAlignment: CrossAxisAlignment.end,
  198. children: [
  199. Text(
  200. 'Attendance History\t\t',
  201. maxLines: 1,
  202. style: GoogleFonts.luckiestGuy(
  203. fontSize: 28,
  204. color: Color(0xFF4858A7),
  205. //fontWeight: FontWeight.bold,
  206. fontStyle: FontStyle.italic,
  207. ),
  208. ),
  209. Image.asset(
  210. 'assets/images/ic_history.png',
  211. width: 40,
  212. height: 40,
  213. ),
  214. ],
  215. )
  216. ),
  217. ],
  218. ),
  219. ],
  220. ),
  221. Container(
  222. margin: EdgeInsets.only(top: (MediaQuery.of(context).size.height / 6) + 40,
  223. left: 5, right: 5, bottom: 10),
  224. child: ListView.builder(
  225. scrollDirection: Axis.vertical,
  226. shrinkWrap: true,
  227. itemCount: HistoryLength,
  228. itemBuilder: (context, int i) {
  229. return Container(
  230. margin: EdgeInsets.fromLTRB(5, 5, 5, 5),
  231. child: InkWell(
  232. child: Card(
  233. elevation: 8,
  234. child: Container(
  235. padding: EdgeInsets.all(10),
  236. child: Row(
  237. children: [
  238. Expanded(
  239. flex: 3,
  240. child:
  241. Container(
  242. alignment: Alignment.center,
  243. padding: EdgeInsets.all(5),
  244. decoration: BoxDecoration(
  245. border: Border.all(color: Colors.black),
  246. borderRadius: BorderRadius.all(Radius.circular(3)),
  247. ),
  248. child: Column(
  249. mainAxisAlignment: MainAxisAlignment.center,
  250. children: [
  251. Row(
  252. children: [
  253. Text(dayDate_List[i].substring(0,3), style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  254. Visibility(
  255. visible: visibilityDate2[i],
  256. child: Text("\t|\t", style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  257. ),
  258. Visibility(
  259. visible: visibilityDate2[i],
  260. child: Text(dayDate_List[i].substring(4,7), style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  261. )
  262. ],
  263. ),
  264. Row(
  265. children: [
  266. Text(date_List[i].substring(0,2), style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  267. Visibility(
  268. visible: visibilityDate2[i],
  269. child: Text("\t|\t", style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  270. ),
  271. Visibility(
  272. visible: visibilityDate2[i],
  273. child: Text(date_List[i].substring(3,5), style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  274. ),
  275. ],
  276. ),
  277. Row(
  278. children: [
  279. Text(month_List[i].substring(0,3), style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  280. Visibility(
  281. visible: visibilityDate2[i],
  282. child: Text("\t|\t", style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  283. ),
  284. Visibility(
  285. visible: visibilityDate2[i],
  286. child: Text(month_List[i].substring(4,7), style: GoogleFonts.fredokaOne(fontSize: 15, color: Colors.blueGrey)),
  287. )
  288. ],
  289. ),
  290. ],
  291. )
  292. ,
  293. )
  294. ),
  295. Expanded(
  296. flex: 2,
  297. child: Column(
  298. children: [
  299. Text("Check In", style: GoogleFonts.fredokaOne(fontSize: 16),textAlign: TextAlign.center),
  300. Text(showCheckIn_List[i], style: GoogleFonts.barlowSemiCondensed(fontSize: 16),textAlign: TextAlign.center),
  301. ],
  302. ),
  303. ),
  304. Expanded(
  305. flex: 2,
  306. child: Column(
  307. children: [
  308. Text("Check Out", style: GoogleFonts.fredokaOne(fontSize: 16),textAlign: TextAlign.center),
  309. Text(showCheckOut_List[i], style: GoogleFonts.barlowSemiCondensed(fontSize: 16),textAlign: TextAlign.center),
  310. ],
  311. ),
  312. ),
  313. Expanded(
  314. flex: 2,
  315. child: Column(
  316. children: [
  317. Text("Working\nHours", style: GoogleFonts.fredokaOne(fontSize: 16), textAlign: TextAlign.center),
  318. Text(worked_hours_List[i], style: GoogleFonts.barlowSemiCondensed(fontSize: 16),textAlign: TextAlign.center),
  319. ],
  320. ),
  321. ),
  322. ],
  323. ),
  324. ),
  325. ),
  326. onTap: (){
  327. setState(() {
  328. //visible[i] = !visible[i];
  329. });
  330. },
  331. ),
  332. );
  333. },
  334. ),
  335. )
  336. ]),
  337. );
  338. }
  339. }
  340. alertDialogFailedRetrievedData(BuildContext context) {
  341. Widget okButton = TextButton(
  342. child: Text("Refresh"),
  343. onPressed: () {
  344. Navigator.of(context, rootNavigator: true).pop();
  345. Navigator.pushReplacement(
  346. context, MaterialPageRoute(builder: (context) => HistoryAbsensi()));
  347. },
  348. );
  349. Widget noButton = TextButton(
  350. child: Text("Back"),
  351. onPressed: () {
  352. Navigator.of(context, rootNavigator: true).pop();
  353. Navigator.pop(context);
  354. },
  355. );
  356. // set up the AlertDialog
  357. AlertDialog alert = AlertDialog(
  358. title: Text(appName),
  359. content: Text("Failed to Retrieve Data"),
  360. actions: [
  361. noButton,
  362. okButton,
  363. ],
  364. );
  365. // show the dialog
  366. showDialog(
  367. context: context,
  368. barrierDismissible: false,
  369. builder: (BuildContext context) {
  370. return alert;
  371. },
  372. );
  373. }
  374. alertDialogFailedResponse(BuildContext context){
  375. Widget okButton = TextButton(
  376. child: Text("Refresh"),
  377. onPressed: () {
  378. Navigator.of(context, rootNavigator: true).pop();
  379. Navigator.pushReplacement(context, MaterialPageRoute(
  380. builder: (context) => HistoryAbsensi()));
  381. },
  382. );
  383. Widget noButton = TextButton(
  384. child: Text("Back"),
  385. onPressed: () {
  386. Navigator.of(context, rootNavigator: true).pop();
  387. Navigator.pop(context);
  388. },
  389. );
  390. // set up the AlertDialog
  391. AlertDialog alert = AlertDialog(
  392. title: Text(appName),
  393. content: Text("Server Response Error"),
  394. actions: [
  395. noButton,
  396. okButton,
  397. ],
  398. );
  399. // show the dialog
  400. showDialog(
  401. context: context,
  402. barrierDismissible: false,
  403. builder: (BuildContext context) {
  404. return alert;
  405. },
  406. );
  407. }