GSI - Employe Self Service Mobile
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.

515 lines
25 KiB

2 months ago
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:file_picker/file_picker.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:fluttertoast/fluttertoast.dart';
  7. import 'package:google_fonts/google_fonts.dart';
  8. import 'package:employee_selfservice_mobile/Screens/Menu/SuratTugas/RequestHttp/pengajuanST_post.dart';
  9. import 'package:intl/intl.dart';
  10. import 'package:progress_dialog_null_safe/progress_dialog_null_safe.dart';
  11. import 'dart:developer' as logDev;
  12. import '../SlipGaji/background.dart';
  13. List<String> fileAttach = [""];
  14. TextEditingController keperluanTeksController = TextEditingController();
  15. TextEditingController tujuanTeksController = TextEditingController();
  16. TextEditingController uangMukaTeksController = TextEditingController();
  17. TextEditingController ticketFromTeksController = TextEditingController();
  18. TextEditingController ticketToTeksController = TextEditingController();
  19. TextEditingController ticketPriceTeksController = TextEditingController();
  20. class DeklarasiST_Screen extends StatefulWidget {
  21. const DeklarasiST_Screen({Key? key}) : super(key: key);
  22. @override
  23. State<DeklarasiST_Screen> createState() => _DeklarasiST_Screen_State();
  24. }
  25. class _DeklarasiST_Screen_State extends State<DeklarasiST_Screen> {
  26. String _fileText = "";
  27. String _totalFile= "";
  28. bool visibleDateST = false;
  29. bool visibleDateDeparture = false;
  30. bool visibleDateReturn = false;
  31. bool visibleDateTicket = false;
  32. DateTime dateFrom = DateTime.now();
  33. late String formattedDateST = "";
  34. late String formattedDateDeparture = "";
  35. late String formattedDateReturn = "";
  36. late String formattedDateTicket = "";
  37. late String kendaraan;
  38. var selectedTicketType;
  39. initState(){
  40. keperluanTeksController.clear();
  41. tujuanTeksController.clear();
  42. uangMukaTeksController.clear();
  43. super.initState();
  44. }
  45. @override
  46. Widget build(BuildContext context) {
  47. var size = MediaQuery.of(context).size;
  48. return Scaffold(
  49. body: SingleChildScrollView(
  50. child: Column(
  51. children: <Widget>[
  52. Stack(
  53. children: [
  54. WavyHeader(),
  55. Container(
  56. margin: EdgeInsets.only(top: MediaQuery.of(context).size.height/6 - 20),
  57. padding: EdgeInsets.fromLTRB(20, 5, 25, 5),
  58. child: Row(
  59. mainAxisAlignment: MainAxisAlignment.end,
  60. crossAxisAlignment: CrossAxisAlignment.end,
  61. children: [
  62. Text(
  63. 'Declaration of\nAssignment Letter\t\t',
  64. maxLines: 2,
  65. style: GoogleFonts.luckiestGuy(
  66. fontSize: 28,
  67. color: Color(0xFF4858A7),
  68. fontStyle: FontStyle.italic,
  69. ),
  70. ),
  71. Image.asset('assets/images/submit_st.png',
  72. width: 40,
  73. height: 40,
  74. ),
  75. ],
  76. )),
  77. SafeArea(
  78. child: Container(
  79. width: MediaQuery.of(context).size.width,
  80. margin: EdgeInsets.only(
  81. top: MediaQuery.of(context).size.height / 5, left: 10, right: 10, bottom: 10
  82. ),
  83. child: Column(
  84. children: [
  85. Container(
  86. child: Card(
  87. elevation: 10,
  88. child: Container(
  89. decoration: BoxDecoration(
  90. color: Color(0XFFFAF7EE),
  91. borderRadius: BorderRadius.circular(10)),
  92. child: Column(
  93. children: [
  94. Container(
  95. margin: EdgeInsets.only(
  96. left: 10, right: 10, top: 15, bottom: 10),
  97. child: Text('Declaration of Assignment Letter', style:
  98. GoogleFonts.josefinSans(fontSize: 19, fontWeight: FontWeight.bold, decoration: TextDecoration.underline,
  99. decorationStyle: TextDecorationStyle.dashed),),
  100. ),
  101. Container(
  102. margin: EdgeInsets.only(
  103. left: 10, right: 10, top: 10, bottom: 10),
  104. child: Column(
  105. children: [
  106. Align(
  107. alignment: Alignment.centerLeft,
  108. child: Text(
  109. 'Total Amount',
  110. style: GoogleFonts.inconsolata(
  111. fontSize: 16, fontWeight: FontWeight.bold),
  112. )),
  113. Container(
  114. margin: EdgeInsets.only(top: 7),
  115. decoration: BoxDecoration(
  116. color: Colors.white,
  117. borderRadius:
  118. BorderRadius.circular(5)),
  119. child: Padding(
  120. padding: EdgeInsets.only(
  121. left: 10,
  122. right: 10,
  123. top: 5,
  124. bottom: 5),
  125. child: TextFormField(
  126. keyboardType:
  127. TextInputType.multiline,
  128. maxLines: 1,
  129. textInputAction:
  130. TextInputAction.next,
  131. controller: keperluanTeksController,
  132. decoration: InputDecoration(
  133. border:
  134. InputBorder.none,
  135. hintText: "ex. 2500750")),
  136. )
  137. )
  138. ],
  139. ),
  140. ),
  141. Container(
  142. margin: EdgeInsets.only(
  143. left: 10, right: 10, top: 10, bottom: 10),
  144. child: Column(
  145. children: [
  146. Align(
  147. alignment: Alignment.centerLeft,
  148. child: Text(
  149. 'Description',
  150. style: GoogleFonts.inconsolata(
  151. fontSize: 16, fontWeight: FontWeight.bold),
  152. )),
  153. Container(
  154. margin: EdgeInsets.only(top: 7),
  155. decoration: BoxDecoration(
  156. color: Colors.white,
  157. borderRadius:
  158. BorderRadius.circular(5)),
  159. child: Padding(
  160. padding: EdgeInsets.only(
  161. left: 10,
  162. right: 10,
  163. top: 5,
  164. bottom: 5),
  165. child: TextFormField(
  166. keyboardType:
  167. TextInputType.multiline,
  168. maxLines: null,
  169. textInputAction:
  170. TextInputAction.next,
  171. controller: tujuanTeksController,
  172. decoration: InputDecoration(
  173. border:
  174. InputBorder.none,
  175. hintText: "description")),
  176. )
  177. )
  178. ],
  179. ),
  180. ),
  181. Container(
  182. margin: EdgeInsets.only(
  183. left: 10, right: 10, top: 10),
  184. child: Column(
  185. children: [
  186. Align(
  187. alignment: Alignment.centerLeft,
  188. child: Text(
  189. 'Attachment',
  190. style: GoogleFonts.inconsolata(
  191. fontSize: 16, fontWeight: FontWeight.bold),
  192. ),
  193. ),
  194. ElevatedButton(
  195. onPressed: () {
  196. _pickMultipleFiles();
  197. },
  198. /*style: ElevatedButton.styleFrom(
  199. backgroundColor:
  200. CupertinoColors
  201. .systemGrey2),*/
  202. child: Container(
  203. width: double.infinity,
  204. child: Text("Choose File",
  205. style: TextStyle(
  206. color: Colors.white,
  207. fontSize: 16,
  208. fontWeight:
  209. FontWeight.w400)),
  210. ),
  211. ),
  212. Container(
  213. alignment:
  214. Alignment.centerLeft,
  215. margin: EdgeInsets.only(
  216. left: 15,
  217. right: 15,
  218. bottom: 10),
  219. child: Text(_totalFile + _fileText,
  220. overflow:
  221. TextOverflow.ellipsis,
  222. /*maxLines: 7,*/
  223. style: TextStyle(
  224. color: Colors.black54),
  225. ),
  226. ),
  227. ],
  228. ),
  229. ),
  230. InkWell(
  231. child: Container(
  232. margin: EdgeInsets.only(left: 10, right: 10, bottom: 15),
  233. padding: EdgeInsets.fromLTRB(
  234. 10, 10, 10, 10),
  235. width: double.infinity,
  236. decoration: BoxDecoration(
  237. borderRadius:
  238. BorderRadius.circular(5),
  239. gradient: LinearGradient(colors: [
  240. Color(0xFFFF9945),
  241. Color(0xFFFc6076)
  242. ])),
  243. child: Text('Submit',
  244. textAlign: TextAlign.center,
  245. style: TextStyle(
  246. color: Colors.white,
  247. fontSize: 17,
  248. fontWeight: FontWeight.w500)),
  249. ),
  250. onTap: () {
  251. ProgressDialog loading = ProgressDialog(context);
  252. loading = ProgressDialog(context,
  253. type: ProgressDialogType.normal, isDismissible: false, showLogs: true);
  254. loading.style(
  255. message: 'Please Wait .....',
  256. borderRadius: 3,
  257. backgroundColor: Colors.white,
  258. progressWidget: CircularProgressIndicator(),
  259. elevation: 10.0,
  260. padding: EdgeInsets.all(10),
  261. insetAnimCurve: Curves.easeInOut,
  262. progress: 0.0,
  263. maxProgress: 100.0,
  264. progressTextStyle: TextStyle(
  265. color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400),
  266. messageTextStyle: TextStyle(
  267. color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600));
  268. //await loading.show();
  269. /*if (!validateFormCuti(context)){
  270. return;
  271. } else if (validateFormCuti(context)){
  272. await loading.show();
  273. PengajuanCuti_Post.connectToAPI(idCuti, formattedDateFrom,
  274. formattedDateTo, deskripsiTeksController.text.toString(), fileAttach)
  275. .then((valueResult) async {
  276. Map<String, dynamic> object = json.decode(valueResult);
  277. logDev.log(fileAttach.toString(), name: "Attachment File Upload");
  278. if (object.containsKey("result").toString() == "true") {
  279. *//*String employee = object['result']['employee'].toString();
  280. String tipe = object['result']['tipe'].toString();
  281. String from = object['result']['from'].toString();
  282. String to = object['result']['to'].toString();
  283. String deskripsi = object['result']['deskripsi'].toString();
  284. String attachment = object['result']['attachment'].toString();*//*
  285. await loading.hide();
  286. deskripsiTeksController.clear();
  287. Widget okButton = TextButton(
  288. child: Text("OK"),
  289. onPressed: () {
  290. Navigator.of(context, rootNavigator: true).pop();
  291. Navigator.pushReplacement(context, MaterialPageRoute(
  292. builder: (context) => AjukanCutiScreen()));
  293. },
  294. );
  295. // set up the AlertDialog
  296. AlertDialog alert = AlertDialog(
  297. title: Text("Employee Self Service"),
  298. content: Text("Success Submit Time Off"),
  299. actions: [
  300. okButton,
  301. ],
  302. );
  303. // show the dialog
  304. showDialog(
  305. context: context,
  306. builder: (BuildContext context) {
  307. return alert;
  308. },
  309. );
  310. *//* deskripsiTeksController.clear();
  311. formattedDateFrom = "";
  312. formattedDateTo = "";
  313. visibleDateFrom = false;
  314. visibleDateFrom = false;*//*
  315. } else if (object.containsKey("error").toString() == "true") {
  316. String errorMessage = object['error']['data']['message']
  317. .toString();
  318. await loading.hide();
  319. Widget okButton = TextButton(
  320. child: Text("OK"),
  321. onPressed: () {
  322. Navigator.of(context, rootNavigator: true).pop();
  323. },
  324. );
  325. // set up the AlertDialog
  326. AlertDialog alert = AlertDialog(
  327. title: Text("Employee Self Service"),
  328. content: Text(errorMessage),
  329. actions: [
  330. okButton,
  331. ],
  332. );
  333. // show the dialog
  334. showDialog(
  335. context: context,
  336. builder: (BuildContext context) {
  337. return alert;
  338. },
  339. );
  340. }
  341. });
  342. }*/
  343. },
  344. )
  345. ],
  346. ),
  347. ),
  348. ),
  349. ),
  350. ],
  351. ),
  352. ),
  353. ),
  354. ],
  355. ),
  356. ],
  357. )),
  358. );
  359. }
  360. void _pickMultipleFiles() async {
  361. FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true);
  362. if (_fileText != ""){
  363. _fileText = "";
  364. }
  365. if (result != null) {
  366. List<File> files = result.paths.map((path) => File(path!)).toList();
  367. for (int i = 0; i< files.length; i++){
  368. String fileName = files[i].path.split('/').last;
  369. _fileText = _fileText + "\n" + fileName;
  370. List<int> fileInBytes = files[i].readAsBytesSync();
  371. String toBase64 = base64Encode(fileInBytes);
  372. fileAttach.add(toBase64);
  373. }
  374. fileAttach.removeAt(0);
  375. logDev.log(fileAttach.length.toString(), name: "Length File Attach");
  376. logDev.log(files.toString(), name: "Files Picked");
  377. setState(() {
  378. _fileText;
  379. _totalFile = "Total File : " + files.length.toString();
  380. });
  381. } else {
  382. // User canceled the picker
  383. }
  384. }
  385. bool validateFormPengajuanST (BuildContext context) {
  386. bool result = true;
  387. if (formattedDateST == "") {
  388. Fluttertoast.showToast(
  389. msg: "Assignment Letter Date\nNot Selected",
  390. toastLength: Toast.LENGTH_SHORT,
  391. gravity: ToastGravity.CENTER,
  392. timeInSecForIosWeb: 1,
  393. textColor: Colors.white,
  394. fontSize: 16.0);
  395. result = false;
  396. } else if (keperluanTeksController.text.toString().isEmpty) {
  397. Fluttertoast.showToast(
  398. msg: "Description of Needs Required!",
  399. toastLength: Toast.LENGTH_SHORT,
  400. gravity: ToastGravity.CENTER,
  401. timeInSecForIosWeb: 1,
  402. textColor: Colors.white,
  403. fontSize: 16.0);
  404. result = false;
  405. }
  406. return result;
  407. }
  408. }
  409. alertDialogFailedRetrievedData(BuildContext context){
  410. Widget okButton = TextButton(
  411. child: Text("Refresh"),
  412. onPressed: () {
  413. /*Navigator.of(context, rootNavigator: true).pop();
  414. Navigator.pushReplacement(context, MaterialPageRoute(
  415. builder: (context) => AjukanCutiScreen()));*/
  416. },
  417. );
  418. Widget noButton = TextButton(
  419. child: Text("Back"),
  420. onPressed: () {
  421. Navigator.of(context, rootNavigator: true).pop();
  422. Navigator.pop(context);
  423. },
  424. );
  425. // set up the AlertDialog
  426. AlertDialog alert = AlertDialog(
  427. title: Text("Employee Self Service"),
  428. content: Text("Failed to Retrieve Data"),
  429. actions: [
  430. noButton,
  431. okButton,
  432. ],
  433. );
  434. // show the dialog
  435. showDialog(
  436. context: context,
  437. builder: (BuildContext context) {
  438. return alert;
  439. },
  440. );
  441. }
  442. alertDialogFailedResponse(BuildContext context){
  443. Widget okButton = TextButton(
  444. child: Text("Refresh"),
  445. onPressed: () {
  446. /* Navigator.of(context, rootNavigator: true).pop();
  447. Navigator.pushReplacement(context, MaterialPageRoute(
  448. builder: (context) => AjukanCutiScreen()));*/
  449. },
  450. );
  451. Widget noButton = TextButton(
  452. child: Text("Back"),
  453. onPressed: () {
  454. Navigator.of(context, rootNavigator: true).pop();
  455. Navigator.pop(context);
  456. },
  457. );
  458. // set up the AlertDialog
  459. AlertDialog alert = AlertDialog(
  460. title: Text("Employee Self Service"),
  461. content: Text("Server Response Error"),
  462. actions: [
  463. noButton,
  464. okButton,
  465. ],
  466. );
  467. // show the dialog
  468. showDialog(
  469. context: context,
  470. builder: (BuildContext context) {
  471. return alert;
  472. },
  473. );
  474. }
  475. List<String> ticketType = [
  476. "airplane",
  477. "train"
  478. ];