From ea8912dc2b45e52850ba647fdf40c32c73434d4f Mon Sep 17 00:00:00 2001 From: Mirza Shafique Date: Wed, 15 Dec 2021 16:04:01 +0000 Subject: [PATCH 01/22] Initial commit --- README.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..4dadb64 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# mohem_flutter_app + + + +## Getting started + +To make it easy for you to get started with GitLab, here's a list of recommended next steps. + +Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! + +## Add your files + +- [ ] [Create](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files +- [ ] [Add files using the command line](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: + +``` +cd existing_repo +git remote add origin https://gitlab.com/mirza.shafique/mohem_flutter_app.git +git branch -M main +git push -uf origin main +``` + +## Integrate with your tools + +- [ ] [Set up project integrations](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://gitlab.com/mirza.shafique/mohem_flutter_app/-/settings/integrations) + +## Collaborate with your team + +- [ ] [Invite team members and collaborators](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/members/) +- [ ] [Create a new merge request](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) +- [ ] [Automatically close issues from merge requests](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) +- [ ] [Enable merge request approvals](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) +- [ ] [Automatically merge when pipeline succeeds](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) + +## Test and Deploy + +Use the built-in continuous integration in GitLab. + +- [ ] [Get started with GitLab CI/CD](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/ci/quick_start/index.html) +- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/application_security/sast/) +- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/topics/autodevops/requirements.html) +- [ ] [Use pull-based deployments for improved Kubernetes management](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/clusters/agent/) +- [ ] [Set up protected environments](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/ci/environments/protected_environments.html) + +*** + +# Editing this README + +When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://www.makeareadme.com/) for this template. + +## Suggestions for a good README +Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. + +## Name +Choose a self-explaining name for your project. + +## Description +Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. + +## Badges +On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. + +## Visuals +Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. + +## Installation +Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. + +## Usage +Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. + +## Support +Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. + +## Roadmap +If you have ideas for releases in the future, it is a good idea to list them in the README. + +## Contributing +State if you are open to contributions and what your requirements are for accepting them. + +For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. + +You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. + +## Authors and acknowledgment +Show your appreciation to those who have contributed to the project. + +## License +For open source projects, say how it is licensed. + +## Project status +If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. + From c2ced77bca8ab1ada2e12b2fe7df7b3c1501eceb Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Mon, 24 Jan 2022 14:57:08 +0300 Subject: [PATCH 02/22] shimmer --- lib/ui/landing/dashboard.dart | 193 +++++++++------------------------- pubspec.lock | 17 ++- pubspec.yaml | 1 + 3 files changed, 64 insertions(+), 147 deletions(-) diff --git a/lib/ui/landing/dashboard.dart b/lib/ui/landing/dashboard.dart index 2c8367a..ac427d1 100644 --- a/lib/ui/landing/dashboard.dart +++ b/lib/ui/landing/dashboard.dart @@ -8,7 +8,9 @@ import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/theme/colors.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:shimmer/shimmer.dart'; class Dashboard extends StatefulWidget { Dashboard({Key? key}) : super(key: key); @@ -32,34 +34,14 @@ class _DashboardState extends State { @override Widget build(BuildContext context) { - List names = [ - LocaleKeys.workList.tr(), - LocaleKeys.missingSwipes.tr(), - LocaleKeys.leaveBalance.tr(), - LocaleKeys.ticketBalance.tr() - ]; + List names = [LocaleKeys.workList.tr(), LocaleKeys.missingSwipes.tr(), LocaleKeys.leaveBalance.tr(), LocaleKeys.ticketBalance.tr()]; List namesInt = [118, 02, 18.5, 03]; List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; - List namesT = [ - LocaleKeys.monthlyAttendance.tr(), - LocaleKeys.workFromHome.tr(), - LocaleKeys.ticketRequest.tr(), - LocaleKeys.monthlyAttendance.tr() - ]; - List iconT = [ - "assets/images/monthly_attendance.svg", - "assets/images/work_from_home.svg", - "assets/images/ticket_request.svg", - "assets/images/work_from_home.svg" - ]; + List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; + List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; - List namesD = [ - "Nostalgia Perfume Perfume", - "Al Nafoura", - "AlJadi", - "Nostalgia Perfume" - ]; + List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; return Scaffold( body: Column( @@ -72,8 +54,7 @@ class _DashboardState extends State { CircularAvatar( width: 34, height: 34, - url: - "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", + url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", ), 8.width, SvgPicture.asset("assets/images/side_nav.svg"), @@ -103,9 +84,7 @@ class _DashboardState extends State { top: 0, child: Container( padding: const EdgeInsets.only(left: 5, right: 5), - decoration: BoxDecoration( - color: MyColors.redColor, - borderRadius: BorderRadius.circular(17)), + decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), child: "3".toText12(color: Colors.white), ), ) @@ -121,9 +100,7 @@ class _DashboardState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.goodMorning - .tr() - .toText14(color: MyColors.grey77Color), + LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), "Mahmoud Shrouf".toText24(isBold: true), 16.height, Row( @@ -134,41 +111,27 @@ class _DashboardState extends State { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient( - transform: GradientRotation(.46), - begin: Alignment.topRight, - end: Alignment.bottomRight, - colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), ), child: Stack( alignment: Alignment.center, children: [ - SvgPicture.asset("assets/images/"), + // SvgPicture.asset("assets/images/"), Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.markAttendance - .tr() - .toText14( - color: Colors.white, - isBold: true), + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), 9.height, - "07:55:12".toText14( - color: Colors.white, - isBold: true), - LocaleKeys.timeLeftToday - .tr() - .toText12(color: Colors.white), + "07:55:12".toText14(color: Colors.white, isBold: true), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), 9.height, const ClipRRect( borderRadius: BorderRadius.all( @@ -177,50 +140,33 @@ class _DashboardState extends State { child: LinearProgressIndicator( value: 0.7, minHeight: 8, - valueColor: - const AlwaysStoppedAnimation< - Color>(Colors.white), - backgroundColor: - const Color(0xff196D73), + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), ), ), ], - ).paddingOnly( - top: 12, right: 15, left: 12), + ).paddingOnly(top: 12, right: 15, left: 12), ), Row( children: [ Expanded( child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - LocaleKeys.checkIn - .tr() - .toText12( - color: Colors.white), - "09:00".toText14( - color: Colors.white, - isBold: true), - 4.height - ], + crossAxisAlignment: CrossAxisAlignment.start, + children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], ).paddingOnly(left: 12), ), Container( width: 45, height: 45, - padding: const EdgeInsets.only( - left: 14, right: 14), + padding: const EdgeInsets.only(left: 14, right: 14), decoration: const BoxDecoration( color: Color(0xff259EA4), borderRadius: BorderRadius.only( - bottomRight: - Radius.circular(15), + bottomRight: Radius.circular(15), ), ), - child: SvgPicture.asset( - "assets/images/stop.svg"), + child: SvgPicture.asset("assets/images/stop.svg"), ), ], ), @@ -229,8 +175,7 @@ class _DashboardState extends State { ], ), ).onPress(() { - Navigator.pushNamed( - context, AppRoutes.todayAttendance); + Navigator.pushNamed(context, AppRoutes.todayAttendance); }), ), ), @@ -240,12 +185,7 @@ class _DashboardState extends State { shrinkWrap: true, primary: false, physics: const NeverScrollableScrollPhysics(), - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 2 / 2, - crossAxisSpacing: 9, - mainAxisSpacing: 9), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), padding: EdgeInsets.zero, itemCount: 4, itemBuilder: (BuildContext context, int index) { @@ -255,31 +195,22 @@ class _DashboardState extends State { borderRadius: BorderRadius.circular(10), ), child: Column( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ names[index].toText12(color: Colors.white), Row( children: [ Expanded( - child: namesInt[index] - .toStringAsFixed(1) - .toText16( - color: Colors.white, - isBold: true), + child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), ), - SvgPicture.asset( - "assets/images/arrow_next.svg", - color: Colors.white) + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) ], ) ], - ).paddingOnly( - left: 10, right: 10, bottom: 6, top: 6), + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), ).onPress(() { - Navigator.pushNamed( - context, AppRoutes.workList); + Navigator.pushNamed(context, AppRoutes.workList); }); }, ), @@ -300,9 +231,7 @@ class _DashboardState extends State { ], ), ), - LocaleKeys.viewAllServices - .tr() - .toText12(isUnderLine: true), + LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), ], ), ], @@ -312,8 +241,7 @@ class _DashboardState extends State { child: ListView.separated( shrinkWrap: true, physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only( - left: 21, right: 21, top: 13, bottom: 13), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), scrollDirection: Axis.horizontal, itemBuilder: (cxt, index) { return AspectRatio( @@ -324,8 +252,7 @@ class _DashboardState extends State { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: - const Color(0xff000000).withOpacity(.05), + color: const Color(0xff000000).withOpacity(.05), blurRadius: 26, offset: const Offset(0, -3), ), @@ -340,17 +267,13 @@ class _DashboardState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( - child: - namesT[index].toText11(isBold: true), + child: namesT[index].toText11(isBold: true), ), - SvgPicture.asset( - "assets/images/arrow_next.svg") - .paddingOnly(bottom: 4) + SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) ], ) ], - ).paddingOnly( - left: 10, right: 10, bottom: 10, top: 12), + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), ), ); }, @@ -363,11 +286,8 @@ class _DashboardState extends State { padding: EdgeInsets.only(top: 31), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(50), - topLeft: Radius.circular(50)), - border: - Border.all(color: MyColors.lightGreyEDColor, width: 1), + borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), ), child: Column( mainAxisSize: MainAxisSize.min, @@ -383,29 +303,21 @@ class _DashboardState extends State { LocaleKeys.offers.tr().toText12(), Row( children: [ - LocaleKeys.discounts - .tr() - .toText24(isBold: true), + LocaleKeys.discounts.tr().toText24(isBold: true), 6.width, Container( - padding: const EdgeInsets.only( - left: 8, right: 8), + padding: const EdgeInsets.only(left: 8, right: 8), decoration: BoxDecoration( color: MyColors.yellowColor, - borderRadius: - BorderRadius.circular(10), + borderRadius: BorderRadius.circular(10), ), - child: LocaleKeys.newString - .tr() - .toText10(isBold: true)), + child: LocaleKeys.newString.tr().toText10(isBold: true)), ], ), ], ), ), - LocaleKeys.viewAllOffers - .tr() - .toText12(isUnderLine: true), + LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true), ], ).paddingOnly(left: 21, right: 21), SizedBox( @@ -413,8 +325,7 @@ class _DashboardState extends State { child: ListView.separated( shrinkWrap: true, physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only( - left: 21, right: 21, top: 13), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13), scrollDirection: Axis.horizontal, itemBuilder: (cxt, index) { return SizedBox( @@ -429,9 +340,7 @@ class _DashboardState extends State { borderRadius: const BorderRadius.all( Radius.circular(100), ), - border: Border.all( - color: MyColors.lightGreyEDColor, - width: 1), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), ), child: ClipRRect( borderRadius: const BorderRadius.all( @@ -445,8 +354,8 @@ class _DashboardState extends State { ), 4.height, Expanded( - child: namesD[6 % (index + 1)].toText12( - isCenter: true, maxLine: 2)), + child: namesD[6 % (index + 1)].toText12(isCenter: true, maxLine: 2), + ), ], ), ); diff --git a/pubspec.lock b/pubspec.lock index 56d2f3f..1ae9d08 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -14,7 +14,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: @@ -202,7 +202,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" meta: dependency: transitive description: @@ -392,6 +392,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.3" + shimmer: + dependency: "direct main" + description: + name: shimmer + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" sizer: dependency: "direct main" description: @@ -445,7 +452,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.3" typed_data: dependency: transitive description: @@ -466,7 +473,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index dfbb0eb..868012d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: sizer: ^2.0.15 local_auth: ^1.1.9 fluttertoast: ^8.0.8 + shimmer: ^2.0.0 dev_dependencies: From 02be1cde49aa3713e0eee2465d76c7e6315b204b Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 26 Jan 2022 10:58:58 +0300 Subject: [PATCH 03/22] api structure improvement. --- lib/api/api_client.dart | 27 +- lib/models/generic_response_model.dart | 32 +- lib/models/member_information_list_model.dart | 336 ++++++++++++++++++ lib/models/privilege_list_model.dart | 21 ++ lib/theme/app_theme.dart | 4 +- lib/ui/login/verify_login_screen.dart | 23 +- 6 files changed, 419 insertions(+), 24 deletions(-) create mode 100644 lib/models/member_information_list_model.dart create mode 100644 lib/models/privilege_list_model.dart diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index fc289c0..7de80da 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -25,11 +25,19 @@ class APIError { APIException _throwAPIException(Response response) { switch (response.statusCode) { + case 200: + APIError? apiError; + if (response.body != null && response.body.isNotEmpty) { + var jsonError = jsonDecode(response.body); + print(jsonError); + apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage']); + } + return APIException(APIException.BAD_REQUEST, error: apiError); case 400: APIError? apiError; if (response.body != null && response.body.isNotEmpty) { var jsonError = jsonDecode(response.body); - apiError = APIError(jsonError['errorCode'], jsonError['errorMessage']); + apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage']); } return APIException(APIException.BAD_REQUEST, error: apiError); case 401: @@ -66,13 +74,18 @@ class ApiClient { print("body:$jsonObject"); } var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); - try { + // try { var jsonData = jsonDecode(response.body); - return factoryConstructor(jsonData); - } catch (ex) { - print(ex); - throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); - } + if (jsonData["ErrorMessage"] != null) { + return factoryConstructor(jsonData); + } else { + throw _throwAPIException(response); + } + // } catch (ex) { + // print(response.body); + // print(ex); + // throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); + // } } Future postJsonForResponse(String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 5bfa4fc..b993db8 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,6 +1,8 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'basic_member_information_model.dart'; +import 'member_information_list_model.dart'; +import 'privilege_list_model.dart'; class GenericResponseModel { String? date; @@ -167,10 +169,10 @@ class GenericResponseModel { String? listNewEmployees; String? listRadScreen; String? logInTokenID; - String? memberInformationList; + List? memberInformationList; MemberLoginListModel? memberLoginList; String? mohemmGetBusinessCardEnabledList; - String? mohemmGetFavoriteReplacementsList; + List? mohemmGetFavoriteReplacementsList; String? mohemmGetMobileDeviceInfobyEmpInfoList; String? mohemmGetMobileLoginInfoList; String? mohemmGetPatientIDList; @@ -198,7 +200,7 @@ class GenericResponseModel { String? pSchema; String? pharmacyStockAddPharmacyStockList; String? pharmacyStockGetOnHandList; - String? privilegeList; + List? privilegeList; String? processTransactions; String? registerUserNameList; String? replacementList; @@ -673,7 +675,12 @@ class GenericResponseModel { listNewEmployees = json['List_NewEmployees']; listRadScreen = json['List_RadScreen']; logInTokenID = json['LogInTokenID']; - memberInformationList = json['MemberInformationList']; + if (json['MemberInformationList'] != null) { + memberInformationList = []; + json['MemberInformationList'].forEach((v) { + memberInformationList!.add(MemberInformationListModel.fromJson(v)); + }); + } memberLoginList = json['MemberLoginList'] != null ? MemberLoginListModel.fromJson(json['MemberLoginList']) : null; mohemmGetBusinessCardEnabledList = json['Mohemm_GetBusinessCardEnabledList']; mohemmGetFavoriteReplacementsList = json['Mohemm_GetFavoriteReplacementsList']; @@ -704,7 +711,14 @@ class GenericResponseModel { pSchema = json['P_Schema']; pharmacyStockAddPharmacyStockList = json['PharmacyStock_AddPharmacyStockList']; pharmacyStockGetOnHandList = json['PharmacyStock_GetOnHandList']; - privilegeList = json['Privilege_List']; + + if (json['Privilege_List'] != null) { + privilegeList = []; + json['Privilege_List'].forEach((v) { + privilegeList!.add(PrivilegeListModel.fromJson(v)); + }); + } + processTransactions = json['ProcessTransactions']; registerUserNameList = json['RegisterUserNameList']; replacementList = json['ReplacementList']; @@ -930,7 +944,9 @@ class GenericResponseModel { data['List_NewEmployees'] = this.listNewEmployees; data['List_RadScreen'] = this.listRadScreen; data['LogInTokenID'] = this.logInTokenID; - data['MemberInformationList'] = this.memberInformationList; + if (this.memberInformationList != null) { + data['MemberInformationList'] = this.memberInformationList!.map((v) => v.toJson()).toList(); + } data['MemberLoginList'] = this.memberLoginList; data['Mohemm_GetBusinessCardEnabledList'] = this.mohemmGetBusinessCardEnabledList; data['Mohemm_GetFavoriteReplacementsList'] = this.mohemmGetFavoriteReplacementsList; @@ -961,7 +977,9 @@ class GenericResponseModel { data['P_Schema'] = this.pSchema; data['PharmacyStock_AddPharmacyStockList'] = this.pharmacyStockAddPharmacyStockList; data['PharmacyStock_GetOnHandList'] = this.pharmacyStockGetOnHandList; - data['Privilege_List'] = this.privilegeList; + if (this.privilegeList != null) { + data['Privilege_List'] = this.privilegeList!.map((v) => v.toJson()).toList(); + } data['ProcessTransactions'] = this.processTransactions; data['RegisterUserNameList'] = this.registerUserNameList; data['ReplacementList'] = this.replacementList; diff --git a/lib/models/member_information_list_model.dart b/lib/models/member_information_list_model.dart new file mode 100644 index 0000000..a3bc05f --- /dev/null +++ b/lib/models/member_information_list_model.dart @@ -0,0 +1,336 @@ +class MemberInformationListModel { + String? aCTUALTERMINATIONDATE; + String? aSSIGNMENTENDDATE; + int? aSSIGNMENTID; + String? aSSIGNMENTNUMBER; + String? aSSIGNMENTSTARTDATE; + int? aSSIGNMENTSTATUSTYPEID; + String? aSSIGNMENTTYPE; + int? bUSINESSGROUPID; + String? bUSINESSGROUPNAME; + String? businessCardQR; + String? cURRENTEMPLOYEEFLAG; + String? eMPLOYEEDISPLAYNAME; + String? eMPLOYEEDISPLAYNAMEAr; + String? eMPLOYEEDISPLAYNAMEEn; + String? eMPLOYEEEMAILADDRESS; + String? eMPLOYEEIMAGE; + String? eMPLOYEEMOBILENUMBER; + String? eMPLOYEENAME; + String? eMPLOYEENAMEAr; + String? eMPLOYEENAMEEn; + String? eMPLOYEENUMBER; + String? eMPLOYEEWORKNUMBER; + String? eMPLOYMENTCATEGORY; + String? eMPLOYMENTCATEGORYMEANING; + String? employeeQR; + String? fREQUENCY; + String? fREQUENCYMEANING; + int? fROMROWNUM; + String? gRADEID; + String? gRADENAME; + String? hIREDATE; + int? jOBID; + String? jOBNAME; + String? jOBNAMEAr; + String? jOBNAMEEn; + int? lEDGERID; + int? lOCATIONID; + String? lOCATIONNAME; + String? mANUALTIMECARDFLAG; + String? mANUALTIMECARDMEANING; + String? mobileNumberWithZipCode; + String? nATIONALITYCODE; + String? nATIONALITYMEANING; + String? nATIONALIDENTIFIER; + String? nORMALHOURS; + int? nOOFROWS; + int? oRGANIZATIONID; + String? oRGANIZATIONNAME; + String? pAYROLLCODE; + int? pAYROLLID; + String? pAYROLLNAME; + int? pERSONID; + String? pERSONTYPE; + int? pERSONTYPEID; + String? pERINFORMATIONCATEGORY; + int? pOSITIONID; + String? pOSITIONNAME; + String? pRIMARYFLAG; + int? rOWNUM; + int? sERVICEDAYS; + int? sERVICEMONTHS; + int? sERVICEYEARS; + String? sUPERVISORASSIGNMENTID; + String? sUPERVISORDISPLAYNAME; + String? sUPERVISOREMAILADDRESS; + int? sUPERVISORID; + String? sUPERVISORMOBILENUMBER; + String? sUPERVISORNAME; + String? sUPERVISORNUMBER; + String? sUPERVISORWORKNUMBER; + String? sWIPESEXEMPTEDFLAG; + String? sWIPESEXEMPTEDMEANING; + String? sYSTEMPERSONTYPE; + String? tKEMAILADDRESS; + String? tKEMPLOYEEDISPLAYNAME; + String? tKEMPLOYEENAME; + String? tKEMPLOYEENUMBER; + int? tKPERSONID; + int? tOROWNUM; + String? uNITNUMBER; + String? uSERSTATUS; + + MemberInformationListModel( + {this.aCTUALTERMINATIONDATE, + this.aSSIGNMENTENDDATE, + this.aSSIGNMENTID, + this.aSSIGNMENTNUMBER, + this.aSSIGNMENTSTARTDATE, + this.aSSIGNMENTSTATUSTYPEID, + this.aSSIGNMENTTYPE, + this.bUSINESSGROUPID, + this.bUSINESSGROUPNAME, + this.businessCardQR, + this.cURRENTEMPLOYEEFLAG, + this.eMPLOYEEDISPLAYNAME, + this.eMPLOYEEDISPLAYNAMEAr, + this.eMPLOYEEDISPLAYNAMEEn, + this.eMPLOYEEEMAILADDRESS, + this.eMPLOYEEIMAGE, + this.eMPLOYEEMOBILENUMBER, + this.eMPLOYEENAME, + this.eMPLOYEENAMEAr, + this.eMPLOYEENAMEEn, + this.eMPLOYEENUMBER, + this.eMPLOYEEWORKNUMBER, + this.eMPLOYMENTCATEGORY, + this.eMPLOYMENTCATEGORYMEANING, + this.employeeQR, + this.fREQUENCY, + this.fREQUENCYMEANING, + this.fROMROWNUM, + this.gRADEID, + this.gRADENAME, + this.hIREDATE, + this.jOBID, + this.jOBNAME, + this.jOBNAMEAr, + this.jOBNAMEEn, + this.lEDGERID, + this.lOCATIONID, + this.lOCATIONNAME, + this.mANUALTIMECARDFLAG, + this.mANUALTIMECARDMEANING, + this.mobileNumberWithZipCode, + this.nATIONALITYCODE, + this.nATIONALITYMEANING, + this.nATIONALIDENTIFIER, + this.nORMALHOURS, + this.nOOFROWS, + this.oRGANIZATIONID, + this.oRGANIZATIONNAME, + this.pAYROLLCODE, + this.pAYROLLID, + this.pAYROLLNAME, + this.pERSONID, + this.pERSONTYPE, + this.pERSONTYPEID, + this.pERINFORMATIONCATEGORY, + this.pOSITIONID, + this.pOSITIONNAME, + this.pRIMARYFLAG, + this.rOWNUM, + this.sERVICEDAYS, + this.sERVICEMONTHS, + this.sERVICEYEARS, + this.sUPERVISORASSIGNMENTID, + this.sUPERVISORDISPLAYNAME, + this.sUPERVISOREMAILADDRESS, + this.sUPERVISORID, + this.sUPERVISORMOBILENUMBER, + this.sUPERVISORNAME, + this.sUPERVISORNUMBER, + this.sUPERVISORWORKNUMBER, + this.sWIPESEXEMPTEDFLAG, + this.sWIPESEXEMPTEDMEANING, + this.sYSTEMPERSONTYPE, + this.tKEMAILADDRESS, + this.tKEMPLOYEEDISPLAYNAME, + this.tKEMPLOYEENAME, + this.tKEMPLOYEENUMBER, + this.tKPERSONID, + this.tOROWNUM, + this.uNITNUMBER, + this.uSERSTATUS}); + + MemberInformationListModel.fromJson(Map json) { + aCTUALTERMINATIONDATE = json['ACTUAL_TERMINATION_DATE']; + aSSIGNMENTENDDATE = json['ASSIGNMENT_END_DATE']; + aSSIGNMENTID = json['ASSIGNMENT_ID']; + aSSIGNMENTNUMBER = json['ASSIGNMENT_NUMBER']; + aSSIGNMENTSTARTDATE = json['ASSIGNMENT_START_DATE']; + aSSIGNMENTSTATUSTYPEID = json['ASSIGNMENT_STATUS_TYPE_ID']; + aSSIGNMENTTYPE = json['ASSIGNMENT_TYPE']; + bUSINESSGROUPID = json['BUSINESS_GROUP_ID']; + bUSINESSGROUPNAME = json['BUSINESS_GROUP_NAME']; + businessCardQR = json['BusinessCardQR']; + cURRENTEMPLOYEEFLAG = json['CURRENT_EMPLOYEE_FLAG']; + eMPLOYEEDISPLAYNAME = json['EMPLOYEE_DISPLAY_NAME']; + eMPLOYEEDISPLAYNAMEAr = json['EMPLOYEE_DISPLAY_NAME_Ar']; + eMPLOYEEDISPLAYNAMEEn = json['EMPLOYEE_DISPLAY_NAME_En']; + eMPLOYEEEMAILADDRESS = json['EMPLOYEE_EMAIL_ADDRESS']; + eMPLOYEEIMAGE = json['EMPLOYEE_IMAGE']; + eMPLOYEEMOBILENUMBER = json['EMPLOYEE_MOBILE_NUMBER']; + eMPLOYEENAME = json['EMPLOYEE_NAME']; + eMPLOYEENAMEAr = json['EMPLOYEE_NAME_Ar']; + eMPLOYEENAMEEn = json['EMPLOYEE_NAME_En']; + eMPLOYEENUMBER = json['EMPLOYEE_NUMBER']; + eMPLOYEEWORKNUMBER = json['EMPLOYEE_WORK_NUMBER']; + eMPLOYMENTCATEGORY = json['EMPLOYMENT_CATEGORY']; + eMPLOYMENTCATEGORYMEANING = json['EMPLOYMENT_CATEGORY_MEANING']; + employeeQR = json['EmployeeQR']; + fREQUENCY = json['FREQUENCY']; + fREQUENCYMEANING = json['FREQUENCY_MEANING']; + fROMROWNUM = json['FROM_ROW_NUM']; + gRADEID = json['GRADE_ID']; + gRADENAME = json['GRADE_NAME']; + hIREDATE = json['HIRE_DATE']; + jOBID = json['JOB_ID']; + jOBNAME = json['JOB_NAME']; + jOBNAMEAr = json['JOB_NAME_Ar']; + jOBNAMEEn = json['JOB_NAME_En']; + lEDGERID = json['LEDGER_ID']; + lOCATIONID = json['LOCATION_ID']; + lOCATIONNAME = json['LOCATION_NAME']; + mANUALTIMECARDFLAG = json['MANUAL_TIMECARD_FLAG']; + mANUALTIMECARDMEANING = json['MANUAL_TIMECARD_MEANING']; + mobileNumberWithZipCode = json['MobileNumberWithZipCode']; + nATIONALITYCODE = json['NATIONALITY_CODE']; + nATIONALITYMEANING = json['NATIONALITY_MEANING']; + nATIONALIDENTIFIER = json['NATIONAL_IDENTIFIER']; + nORMALHOURS = json['NORMAL_HOURS']; + nOOFROWS = json['NO_OF_ROWS']; + oRGANIZATIONID = json['ORGANIZATION_ID']; + oRGANIZATIONNAME = json['ORGANIZATION_NAME']; + pAYROLLCODE = json['PAYROLL_CODE']; + pAYROLLID = json['PAYROLL_ID']; + pAYROLLNAME = json['PAYROLL_NAME']; + pERSONID = json['PERSON_ID']; + pERSONTYPE = json['PERSON_TYPE']; + pERSONTYPEID = json['PERSON_TYPE_ID']; + pERINFORMATIONCATEGORY = json['PER_INFORMATION_CATEGORY']; + pOSITIONID = json['POSITION_ID']; + pOSITIONNAME = json['POSITION_NAME']; + pRIMARYFLAG = json['PRIMARY_FLAG']; + rOWNUM = json['ROW_NUM']; + sERVICEDAYS = json['SERVICE_DAYS']; + sERVICEMONTHS = json['SERVICE_MONTHS']; + sERVICEYEARS = json['SERVICE_YEARS']; + sUPERVISORASSIGNMENTID = json['SUPERVISOR_ASSIGNMENT_ID']; + sUPERVISORDISPLAYNAME = json['SUPERVISOR_DISPLAY_NAME']; + sUPERVISOREMAILADDRESS = json['SUPERVISOR_EMAIL_ADDRESS']; + sUPERVISORID = json['SUPERVISOR_ID']; + sUPERVISORMOBILENUMBER = json['SUPERVISOR_MOBILE_NUMBER']; + sUPERVISORNAME = json['SUPERVISOR_NAME']; + sUPERVISORNUMBER = json['SUPERVISOR_NUMBER']; + sUPERVISORWORKNUMBER = json['SUPERVISOR_WORK_NUMBER']; + sWIPESEXEMPTEDFLAG = json['SWIPES_EXEMPTED_FLAG']; + sWIPESEXEMPTEDMEANING = json['SWIPES_EXEMPTED_MEANING']; + sYSTEMPERSONTYPE = json['SYSTEM_PERSON_TYPE']; + tKEMAILADDRESS = json['TK_EMAIL_ADDRESS']; + tKEMPLOYEEDISPLAYNAME = json['TK_EMPLOYEE_DISPLAY_NAME']; + tKEMPLOYEENAME = json['TK_EMPLOYEE_NAME']; + tKEMPLOYEENUMBER = json['TK_EMPLOYEE_NUMBER']; + tKPERSONID = json['TK_PERSON_ID']; + tOROWNUM = json['TO_ROW_NUM']; + uNITNUMBER = json['UNIT_NUMBER']; + uSERSTATUS = json['USER_STATUS']; + } + + Map toJson() { + final Map data = new Map(); + data['ACTUAL_TERMINATION_DATE'] = this.aCTUALTERMINATIONDATE; + data['ASSIGNMENT_END_DATE'] = this.aSSIGNMENTENDDATE; + data['ASSIGNMENT_ID'] = this.aSSIGNMENTID; + data['ASSIGNMENT_NUMBER'] = this.aSSIGNMENTNUMBER; + data['ASSIGNMENT_START_DATE'] = this.aSSIGNMENTSTARTDATE; + data['ASSIGNMENT_STATUS_TYPE_ID'] = this.aSSIGNMENTSTATUSTYPEID; + data['ASSIGNMENT_TYPE'] = this.aSSIGNMENTTYPE; + data['BUSINESS_GROUP_ID'] = this.bUSINESSGROUPID; + data['BUSINESS_GROUP_NAME'] = this.bUSINESSGROUPNAME; + data['BusinessCardQR'] = this.businessCardQR; + data['CURRENT_EMPLOYEE_FLAG'] = this.cURRENTEMPLOYEEFLAG; + data['EMPLOYEE_DISPLAY_NAME'] = this.eMPLOYEEDISPLAYNAME; + data['EMPLOYEE_DISPLAY_NAME_Ar'] = this.eMPLOYEEDISPLAYNAMEAr; + data['EMPLOYEE_DISPLAY_NAME_En'] = this.eMPLOYEEDISPLAYNAMEEn; + data['EMPLOYEE_EMAIL_ADDRESS'] = this.eMPLOYEEEMAILADDRESS; + data['EMPLOYEE_IMAGE'] = this.eMPLOYEEIMAGE; + data['EMPLOYEE_MOBILE_NUMBER'] = this.eMPLOYEEMOBILENUMBER; + data['EMPLOYEE_NAME'] = this.eMPLOYEENAME; + data['EMPLOYEE_NAME_Ar'] = this.eMPLOYEENAMEAr; + data['EMPLOYEE_NAME_En'] = this.eMPLOYEENAMEEn; + data['EMPLOYEE_NUMBER'] = this.eMPLOYEENUMBER; + data['EMPLOYEE_WORK_NUMBER'] = this.eMPLOYEEWORKNUMBER; + data['EMPLOYMENT_CATEGORY'] = this.eMPLOYMENTCATEGORY; + data['EMPLOYMENT_CATEGORY_MEANING'] = this.eMPLOYMENTCATEGORYMEANING; + data['EmployeeQR'] = this.employeeQR; + data['FREQUENCY'] = this.fREQUENCY; + data['FREQUENCY_MEANING'] = this.fREQUENCYMEANING; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['GRADE_ID'] = this.gRADEID; + data['GRADE_NAME'] = this.gRADENAME; + data['HIRE_DATE'] = this.hIREDATE; + data['JOB_ID'] = this.jOBID; + data['JOB_NAME'] = this.jOBNAME; + data['JOB_NAME_Ar'] = this.jOBNAMEAr; + data['JOB_NAME_En'] = this.jOBNAMEEn; + data['LEDGER_ID'] = this.lEDGERID; + data['LOCATION_ID'] = this.lOCATIONID; + data['LOCATION_NAME'] = this.lOCATIONNAME; + data['MANUAL_TIMECARD_FLAG'] = this.mANUALTIMECARDFLAG; + data['MANUAL_TIMECARD_MEANING'] = this.mANUALTIMECARDMEANING; + data['MobileNumberWithZipCode'] = this.mobileNumberWithZipCode; + data['NATIONALITY_CODE'] = this.nATIONALITYCODE; + data['NATIONALITY_MEANING'] = this.nATIONALITYMEANING; + data['NATIONAL_IDENTIFIER'] = this.nATIONALIDENTIFIER; + data['NORMAL_HOURS'] = this.nORMALHOURS; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['ORGANIZATION_ID'] = this.oRGANIZATIONID; + data['ORGANIZATION_NAME'] = this.oRGANIZATIONNAME; + data['PAYROLL_CODE'] = this.pAYROLLCODE; + data['PAYROLL_ID'] = this.pAYROLLID; + data['PAYROLL_NAME'] = this.pAYROLLNAME; + data['PERSON_ID'] = this.pERSONID; + data['PERSON_TYPE'] = this.pERSONTYPE; + data['PERSON_TYPE_ID'] = this.pERSONTYPEID; + data['PER_INFORMATION_CATEGORY'] = this.pERINFORMATIONCATEGORY; + data['POSITION_ID'] = this.pOSITIONID; + data['POSITION_NAME'] = this.pOSITIONNAME; + data['PRIMARY_FLAG'] = this.pRIMARYFLAG; + data['ROW_NUM'] = this.rOWNUM; + data['SERVICE_DAYS'] = this.sERVICEDAYS; + data['SERVICE_MONTHS'] = this.sERVICEMONTHS; + data['SERVICE_YEARS'] = this.sERVICEYEARS; + data['SUPERVISOR_ASSIGNMENT_ID'] = this.sUPERVISORASSIGNMENTID; + data['SUPERVISOR_DISPLAY_NAME'] = this.sUPERVISORDISPLAYNAME; + data['SUPERVISOR_EMAIL_ADDRESS'] = this.sUPERVISOREMAILADDRESS; + data['SUPERVISOR_ID'] = this.sUPERVISORID; + data['SUPERVISOR_MOBILE_NUMBER'] = this.sUPERVISORMOBILENUMBER; + data['SUPERVISOR_NAME'] = this.sUPERVISORNAME; + data['SUPERVISOR_NUMBER'] = this.sUPERVISORNUMBER; + data['SUPERVISOR_WORK_NUMBER'] = this.sUPERVISORWORKNUMBER; + data['SWIPES_EXEMPTED_FLAG'] = this.sWIPESEXEMPTEDFLAG; + data['SWIPES_EXEMPTED_MEANING'] = this.sWIPESEXEMPTEDMEANING; + data['SYSTEM_PERSON_TYPE'] = this.sYSTEMPERSONTYPE; + data['TK_EMAIL_ADDRESS'] = this.tKEMAILADDRESS; + data['TK_EMPLOYEE_DISPLAY_NAME'] = this.tKEMPLOYEEDISPLAYNAME; + data['TK_EMPLOYEE_NAME'] = this.tKEMPLOYEENAME; + data['TK_EMPLOYEE_NUMBER'] = this.tKEMPLOYEENUMBER; + data['TK_PERSON_ID'] = this.tKPERSONID; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['UNIT_NUMBER'] = this.uNITNUMBER; + data['USER_STATUS'] = this.uSERSTATUS; + return data; + } +} \ No newline at end of file diff --git a/lib/models/privilege_list_model.dart b/lib/models/privilege_list_model.dart new file mode 100644 index 0000000..3ef3954 --- /dev/null +++ b/lib/models/privilege_list_model.dart @@ -0,0 +1,21 @@ +class PrivilegeListModel { + int? iD; + String? serviceName; + bool? previlege; + + PrivilegeListModel({this.iD, this.serviceName, this.previlege}); + + PrivilegeListModel.fromJson(Map json) { + iD = json['ID']; + serviceName = json['ServiceName']; + previlege = json['Previlege']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['ServiceName'] = this.serviceName; + data['Previlege'] = this.previlege; + return data; + } +} diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index c28da2f..51987cd 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -15,9 +15,7 @@ class AppTheme { }, ), hintColor: Colors.grey[400], - colorScheme: ColorScheme.fromSwatch( - - ), + colorScheme: ColorScheme.fromSwatch(accentColor: MyColors.backgroundColor), disabledColor: Colors.grey[300], errorColor: const Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: MyColors.backgroundColor, diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index 26b978f..b28ad4d 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -624,21 +624,30 @@ class _VerifyLoginScreenState extends State { // isMoreOption = true; }); } else { + Utils.showLoading(context); BasicMemberInformationModel? memberInformationModel = await LoginApiClient() .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); + Utils.hideLoading(context); OtpDialog( context, _flag, int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), (value) async { - GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); - if (genericResponseModel?.errorMessage != null) { - Utils.showToast(genericResponseModel?.errorMessage ?? ""); - // Navigator.pop(context); + Utils.showLoading(context); + try { + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); + if (genericResponseModel?.errorMessage != null) { + Utils.showToast(genericResponseModel?.errorMessage ?? ""); + // Navigator.pop(context); + } + Utils.hideLoading(context); + Navigator.pop(context); + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, null); } - - Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); - // this.checkActivationCode(value: value); }, () => { Navigator.pop(context), From b5c9b83fdde198dbff50438b6481a6da3f201aab Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 26 Jan 2022 11:53:24 +0300 Subject: [PATCH 04/22] api structure improvement. --- lib/api/api_client.dart | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index 7de80da..dcd184e 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -10,8 +10,8 @@ import 'package:mohem_flutter_app/exceptions/api_exception.dart'; typedef FactoryConstructor = U Function(dynamic); class APIError { - int errorCode; - String errorMessage; + int? errorCode; + String? errorMessage; APIError(this.errorCode, this.errorMessage); @@ -74,18 +74,22 @@ class ApiClient { print("body:$jsonObject"); } var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); - // try { + try { var jsonData = jsonDecode(response.body); - if (jsonData["ErrorMessage"] != null) { + if (jsonData["ErrorMessage"] == null) { return factoryConstructor(jsonData); } else { - throw _throwAPIException(response); + APIError? apiError; + apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorMessage']); + throw APIException(APIException.BAD_REQUEST, error: apiError); } - // } catch (ex) { - // print(response.body); - // print(ex); - // throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); - // } + } catch (ex) { + if (ex is APIException) { + rethrow; + } else { + throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); + } + } } Future postJsonForResponse(String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { From ab25a98a9efa88da930c61ad170e81b8a2668797 Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Sun, 30 Jan 2022 10:29:07 +0300 Subject: [PATCH 05/22] 1.1 --- lib/generated/locale_keys.g.dart | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 lib/generated/locale_keys.g.dart diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart new file mode 100644 index 0000000..24d7171 --- /dev/null +++ b/lib/generated/locale_keys.g.dart @@ -0,0 +1,69 @@ +// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart + +abstract class LocaleKeys { + static const mohemm = 'mohemm'; + static const english = 'english'; + static const arabic = 'arabic'; + static const login = 'login'; + static const pleaseEnterLoginDetails = 'pleaseEnterLoginDetails'; + static const username = 'username'; + static const password = 'password'; + static const welcomeBack = 'welcomeBack'; + static const wouldYouLikeToLoginWithCurrentUsername = 'wouldYouLikeToLoginWithCurrentUsername'; + static const lastLoginDetails = 'lastLoginDetails'; + static const verificationType = 'verificationType'; + static const pleaseVerify = 'pleaseVerify'; + static const verifyThroughFace = 'verifyThroughFace'; + static const verifyThroughFingerprint = 'verifyThroughFingerprint'; + static const verifyThroughSMS = 'verifyThroughSMS'; + static const verifyThroughWhatsapp = 'verifyThroughWhatsapp'; + static const useAnotherAccount = 'useAnotherAccount'; + static const pleaseEnterTheVerificationCodeSentTo = 'pleaseEnterTheVerificationCodeSentTo'; + static const theVerificationCodeWillExpireIn = 'theVerificationCodeWillExpireIn'; + static const goodMorning = 'goodMorning'; + static const markAttendance = 'markAttendance'; + static const timeLeftToday = 'timeLeftToday'; + static const checkIn = 'checkIn'; + static const workList = 'workList'; + static const leaveBalance = 'leaveBalance'; + static const missingSwipes = 'missingSwipes'; + static const ticketBalance = 'ticketBalance'; + static const services = 'services'; + static const viewAllServices = 'viewAllServices'; + static const monthlyAttendance = 'monthlyAttendance'; + static const workFromHome = 'workFromHome'; + static const ticketRequest = 'ticketRequest'; + static const viewAllOffers = 'viewAllOffers'; + static const offers = 'offers'; + static const discounts = 'discounts'; + static const newString = 'newString'; + static const setTheNewPassword = 'setTheNewPassword'; + static const typeYourNewPasswordBelow = 'typeYourNewPasswordBelow'; + static const confirmPassword = 'confirmPassword'; + static const update = 'update'; + static const title = 'title'; + static const home = 'home'; + static const mySalary = 'mySalary'; + static const createRequest = 'createRequest'; + static const forgotPassword = 'forgotPassword'; + static const employeeId = 'employeeId'; + static const loginCodeWillSentToMobileNumber = 'loginCodeWillSentToMobileNumber'; + static const changePassword = 'changePassword'; + static const itemsForSale = 'itemsForSale'; + static const msg = 'msg'; + static const msg_named = 'msg_named'; + static const clickMe = 'clickMe'; + static const human = 'human'; + static const resources = 'resources'; + static const profile_reset_password_label = 'profile.reset_password.label'; + static const profile_reset_password_username = 'profile.reset_password.username'; + static const profile_reset_password_password = 'profile.reset_password.password'; + static const profile_reset_password = 'profile.reset_password'; + static const profile = 'profile'; + static const clicked = 'clicked'; + static const amount = 'amount'; + static const gender_with_arg = 'gender.with_arg'; + static const gender = 'gender'; + static const reset_locale = 'reset_locale'; + +} From baa7182655cccdeddec21f6ff55307b5c19fe29c Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Mon, 31 Jan 2022 10:11:26 +0300 Subject: [PATCH 06/22] Dashboard API's 1.0 --- lib/api/api_client.dart | 3 + lib/api/dashboard_api_client.dart | 69 +++++++ lib/api/login_api_client.dart | 7 + lib/app_state/app_state.dart | 14 +- lib/classes/consts.dart | 3 + .../get_accrual_balances_list_model.dart | 39 ++++ .../get_attendance_tracking_list_model.dart | 55 +++++ .../get_open_missing_swipes_list_model.dart | 24 +++ .../get_open_notifications_list.dart | 23 +++ lib/models/dashboard/itg_forms_model.dart | 189 ++++++++++++++++++ lib/models/generic_response_model.dart | 23 ++- lib/models/post_params_model.dart | 51 ++++- lib/ui/landing/dashboard.dart | 5 +- lib/ui/login/login_screen.dart | 4 +- lib/ui/login/verify_login_screen.dart | 4 +- 15 files changed, 497 insertions(+), 16 deletions(-) create mode 100644 lib/api/dashboard_api_client.dart create mode 100644 lib/models/dashboard/get_accrual_balances_list_model.dart create mode 100644 lib/models/dashboard/get_attendance_tracking_list_model.dart create mode 100644 lib/models/dashboard/get_open_missing_swipes_list_model.dart create mode 100644 lib/models/dashboard/get_open_notifications_list.dart create mode 100644 lib/models/dashboard/itg_forms_model.dart diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index dcd184e..a08ed01 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -75,6 +75,9 @@ class ApiClient { } var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); try { + if (!kReleaseMode) { + print("res: " + response.body); + } var jsonData = jsonDecode(response.body); if (jsonData["ErrorMessage"] == null) { return factoryConstructor(jsonData); diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart new file mode 100644 index 0000000..5b6f961 --- /dev/null +++ b/lib/api/dashboard_api_client.dart @@ -0,0 +1,69 @@ +import 'dart:async'; + +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; +import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; +import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; + +import 'api_client.dart'; + +class DashbaordApiClient { + static final DashbaordApiClient _instance = DashbaordApiClient._internal(); + + DashbaordApiClient._internal(); + + factory DashbaordApiClient() => _instance; + + Future getAttendanceTracking() async { + String url = "${ApiConsts.erpRest}GET_Attendance_Tracking"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getOpenNotifications() async { + String url = "${ApiConsts.erpRest}GET_OPEN_NOTIFICATIONS"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getItgFormsPendingTask() async { + String url = "${ApiConsts.cocRest}ITGFormsPendingTasks"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + ItgFormsModel responseData = ItgFormsModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getAccrualBalances() async { + String url = "${ApiConsts.erpRest}GET_ACCRUAL_BALANCES"; + Map postParams = {"P_EFFECTIVE_DATE": "1/30/2022"}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getOpenMissingSwipes() async { + String url = "${ApiConsts.erpRest}GET_OPEN_MISSING_SWIPES"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } +} diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart index 1811414..fb6bb80 100644 --- a/lib/api/login_api_client.dart +++ b/lib/api/login_api_client.dart @@ -47,7 +47,14 @@ class LoginApiClient { postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); + AppState().setLogged = true; AppState().postParamsObject?.setTokenID = responseData.tokenID; + AppState().postParamsObject?.mobileNumber = responseData.basicMemberInformation!.pMOBILENUMBER; + AppState().postParamsObject?.userName = AppState().getUserName; + AppState().postParamsObject?.pEmailAddress = responseData.basicMemberInformation!.pEMAILADDRESS; + AppState().postParamsObject?.pSessionId = responseData.pSESSIONID; + AppState().postParamsObject?.pUserName = AppState().getUserName; + AppState().postParamsObject?.pSelectedEmployeeNumber = AppState().getUserName; return responseData; }, url, postParams); } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 2af87d8..65d5184 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -8,6 +8,12 @@ class AppState { factory AppState() => _instance; + bool isLogged = false; + + set setLogged(v) => isLogged = v; + + bool? get getIsLogged => isLogged; + String? forgetPasswordTokenID; set setForgetPasswordTokenID(token) => forgetPasswordTokenID = token; @@ -18,15 +24,17 @@ class AppState { PostParamsModel? get postParamsObject => _postParams; - Map get postParamsJson => _postParams?.toJson() ?? {}; + Map get postParamsJson => isLogged ? (_postParams?.toJsonAfterLogin() ?? {}) : (_postParams?.toJson() ?? {}); void setPostParamsModel(PostParamsModel _postParams) { this._postParams = _postParams; } - String? username; + String? _username; + + set setUserName(v) => _username = v; - set setUserName(_username) => username = _username; + String? get getUserName => _username; MemberLoginListModel? _memberLoginList; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index b0453c0..4bad83c 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -6,8 +6,11 @@ class ApiConsts { static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; static String erpRest = baseUrlServices + "ERP.svc/REST/"; static String user = baseUrlServices + "api/User/"; + static String cocRest = baseUrlServices + "COCWS.svc/REST/"; } + + class GlobalConsts { static String isRememberMe = "remember_me"; static String email = "email"; diff --git a/lib/models/dashboard/get_accrual_balances_list_model.dart b/lib/models/dashboard/get_accrual_balances_list_model.dart new file mode 100644 index 0000000..a53133e --- /dev/null +++ b/lib/models/dashboard/get_accrual_balances_list_model.dart @@ -0,0 +1,39 @@ +class GetAccrualBalancesList { + GetAccrualBalancesList({ + this.accrualNetEntitlement, + this.accrualUsedEntitlement, + this.accrualYearlyEntitlement, + this.accuralPlanName, + this.endDate, + this.lastAccrualDate, + this.startDate, + }); + + double? accrualNetEntitlement; + int? accrualUsedEntitlement; + dynamic accrualYearlyEntitlement; + String? accuralPlanName; + String? endDate; + String? lastAccrualDate; + String? startDate; + + factory GetAccrualBalancesList.fromJson(Map json) => GetAccrualBalancesList( + accrualNetEntitlement: json["ACCRUAL_NET_ENTITLEMENT"] == null ? null : json["ACCRUAL_NET_ENTITLEMENT"].toDouble(), + accrualUsedEntitlement: json["ACCRUAL_USED_ENTITLEMENT"] == null ? null : json["ACCRUAL_USED_ENTITLEMENT"], + accrualYearlyEntitlement: json["ACCRUAL_YEARLY_ENTITLEMENT"], + accuralPlanName: json["ACCURAL_PLAN_NAME"] == null ? null : json["ACCURAL_PLAN_NAME"], + endDate: json["END_DATE"] == null ? null : json["END_DATE"], + lastAccrualDate: json["LAST_ACCRUAL_DATE"] == null ? null : json["LAST_ACCRUAL_DATE"], + startDate: json["START_DATE"] == null ? null : json["START_DATE"], + ); + + Map toJson() => { + "ACCRUAL_NET_ENTITLEMENT": accrualNetEntitlement == null ? null : accrualNetEntitlement, + "ACCRUAL_USED_ENTITLEMENT": accrualUsedEntitlement == null ? null : accrualUsedEntitlement, + "ACCRUAL_YEARLY_ENTITLEMENT": accrualYearlyEntitlement, + "ACCURAL_PLAN_NAME": accuralPlanName == null ? null : accuralPlanName, + "END_DATE": endDate == null ? null : endDate, + "LAST_ACCRUAL_DATE": lastAccrualDate == null ? null : lastAccrualDate, + "START_DATE": startDate == null ? null : startDate, + }; +} diff --git a/lib/models/dashboard/get_attendance_tracking_list_model.dart b/lib/models/dashboard/get_attendance_tracking_list_model.dart new file mode 100644 index 0000000..66b9ed8 --- /dev/null +++ b/lib/models/dashboard/get_attendance_tracking_list_model.dart @@ -0,0 +1,55 @@ +class GetAttendanceTrackingList { + GetAttendanceTrackingList({ + this.pBreakHours, + this.pLateInHours, + this.pRemainingHours, + this.pReturnMsg, + this.pReturnStatus, + this.pScheduledHours, + this.pShtName, + this.pSpentHours, + this.pSwipesExemptedFlag, + this.pSwipeIn, + this.pSwipeOut, + }); + + String? pBreakHours; + String? pLateInHours; + String? pRemainingHours; + String? pReturnMsg; + String? pReturnStatus; + String? pScheduledHours; + String? pShtName; + String? pSpentHours; + String? pSwipesExemptedFlag; + dynamic pSwipeIn; + dynamic pSwipeOut; + + factory GetAttendanceTrackingList.fromMap(Map json) => GetAttendanceTrackingList( + pBreakHours: json["P_BREAK_HOURS"] == null ? null : json["P_BREAK_HOURS"], + pLateInHours: json["P_LATE_IN_HOURS"] == null ? null : json["P_LATE_IN_HOURS"], + pRemainingHours: json["P_REMAINING_HOURS"] == null ? null : json["P_REMAINING_HOURS"], + pReturnMsg: json["P_RETURN_MSG"] == null ? null : json["P_RETURN_MSG"], + pReturnStatus: json["P_RETURN_STATUS"] == null ? null : json["P_RETURN_STATUS"], + pScheduledHours: json["P_SCHEDULED_HOURS"] == null ? null : json["P_SCHEDULED_HOURS"], + pShtName: json["P_SHT_NAME"] == null ? null : json["P_SHT_NAME"], + pSpentHours: json["P_SPENT_HOURS"] == null ? null : json["P_SPENT_HOURS"], + pSwipesExemptedFlag: json["P_SWIPES_EXEMPTED_FLAG"] == null ? null : json["P_SWIPES_EXEMPTED_FLAG"], + pSwipeIn: json["P_SWIPE_IN"], + pSwipeOut: json["P_SWIPE_OUT"], + ); + + Map toMap() => { + "P_BREAK_HOURS": pBreakHours == null ? null : pBreakHours, + "P_LATE_IN_HOURS": pLateInHours == null ? null : pLateInHours, + "P_REMAINING_HOURS": pRemainingHours == null ? null : pRemainingHours, + "P_RETURN_MSG": pReturnMsg == null ? null : pReturnMsg, + "P_RETURN_STATUS": pReturnStatus == null ? null : pReturnStatus, + "P_SCHEDULED_HOURS": pScheduledHours == null ? null : pScheduledHours, + "P_SHT_NAME": pShtName == null ? null : pShtName, + "P_SPENT_HOURS": pSpentHours == null ? null : pSpentHours, + "P_SWIPES_EXEMPTED_FLAG": pSwipesExemptedFlag == null ? null : pSwipesExemptedFlag, + "P_SWIPE_IN": pSwipeIn, + "P_SWIPE_OUT": pSwipeOut, + }; +} diff --git a/lib/models/dashboard/get_open_missing_swipes_list_model.dart b/lib/models/dashboard/get_open_missing_swipes_list_model.dart new file mode 100644 index 0000000..86ac6a9 --- /dev/null +++ b/lib/models/dashboard/get_open_missing_swipes_list_model.dart @@ -0,0 +1,24 @@ + +class GetOpenMissingSwipesList { + GetOpenMissingSwipesList({ + this.pOpenMissingSwipes, + this.pReturnMsg, + this.pReturnStatus, + }); + + int? pOpenMissingSwipes; + String? pReturnMsg; + String? pReturnStatus; + + factory GetOpenMissingSwipesList.fromJson(Map json) => GetOpenMissingSwipesList( + pOpenMissingSwipes: json["P_OPEN_MISSING_SWIPES"] == null ? null : json["P_OPEN_MISSING_SWIPES"], + pReturnMsg: json["P_RETURN_MSG"] == null ? null : json["P_RETURN_MSG"], + pReturnStatus: json["P_RETURN_STATUS"] == null ? null : json["P_RETURN_STATUS"], + ); + + Map toJson() => { + "P_OPEN_MISSING_SWIPES": pOpenMissingSwipes == null ? null : pOpenMissingSwipes, + "P_RETURN_MSG": pReturnMsg == null ? null : pReturnMsg, + "P_RETURN_STATUS": pReturnStatus == null ? null : pReturnStatus, + }; +} diff --git a/lib/models/dashboard/get_open_notifications_list.dart b/lib/models/dashboard/get_open_notifications_list.dart new file mode 100644 index 0000000..854b62a --- /dev/null +++ b/lib/models/dashboard/get_open_notifications_list.dart @@ -0,0 +1,23 @@ +class GetOpenNotificationsList { + GetOpenNotificationsList({ + this.itemType, + this.itemTypeDisplayName, + this.openNtfNumber, + }); + + String? itemType; + String? itemTypeDisplayName; + int? openNtfNumber; + + factory GetOpenNotificationsList.fromMap(Map json) => GetOpenNotificationsList( + itemType: json["ITEM_TYPE"] == null ? null : json["ITEM_TYPE"], + itemTypeDisplayName: json["ITEM_TYPE_DISPLAY_NAME"] == null ? null : json["ITEM_TYPE_DISPLAY_NAME"], + openNtfNumber: json["OPEN_NTF_NUMBER"] == null ? null : json["OPEN_NTF_NUMBER"], + ); + + Map toMap() => { + "ITEM_TYPE": itemType == null ? null : itemType, + "ITEM_TYPE_DISPLAY_NAME": itemTypeDisplayName == null ? null : itemTypeDisplayName, + "OPEN_NTF_NUMBER": openNtfNumber == null ? null : openNtfNumber, + }; +} diff --git a/lib/models/dashboard/itg_forms_model.dart b/lib/models/dashboard/itg_forms_model.dart new file mode 100644 index 0000000..c5a0145 --- /dev/null +++ b/lib/models/dashboard/itg_forms_model.dart @@ -0,0 +1,189 @@ +// To parse this JSON data, do +// +// final itgFormsModel = itgFormsModelFromMap(jsonString); + +import 'dart:convert'; + +ItgFormsModel itgFormsModelFromMap(String str) => ItgFormsModel.fromJson(json.decode(str)); + +String itgFormsModelToMap(ItgFormsModel data) => json.encode(data.toMap()); + +class ItgFormsModel { + ItgFormsModel({ + this.date, + this.languageId, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenId, + this.data, + this.dataw, + this.dietType, + this.dietTypeId, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iosLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.itgRequest, + this.itgFormAttachmentsList, + this.message, + this.mohemmItgDepartmentSectionsList, + this.mohemmItgProjectDepartmentsList, + this.mohemmItgResponseItem, + this.mohemmItgSectionTopicsList, + this.mohemmItgTicketDetailsList, + this.mohemmItgTicketTransactionsList, + this.mohemmItgTicketsByEmployeeList, + this.mohemmItgProjectsList, + this.mohemmItgTicketTypesList, + this.referenceNumber, + this.requestType, + this.totalCount, + this.statuseCode, + }); + + dynamic date; + int? languageId; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenId; + dynamic data; + bool? dataw; + int? dietType; + int? dietTypeId; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iosLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + String? successMsg; + dynamic successMsgN; + dynamic vidaUpdatedResponse; + dynamic itgRequest; + dynamic itgFormAttachmentsList; + String? message; + dynamic mohemmItgDepartmentSectionsList; + dynamic mohemmItgProjectDepartmentsList; + dynamic mohemmItgResponseItem; + dynamic mohemmItgSectionTopicsList; + dynamic mohemmItgTicketDetailsList; + dynamic mohemmItgTicketTransactionsList; + dynamic mohemmItgTicketsByEmployeeList; + dynamic mohemmItgProjectsList; + dynamic mohemmItgTicketTypesList; + DateTime? referenceNumber; + dynamic requestType; + int? totalCount; + int? statuseCode; + + factory ItgFormsModel.fromJson(Map json) => ItgFormsModel( + date: json["Date"], + languageId: json["LanguageID"] == null ? null : json["LanguageID"], + serviceName: json["ServiceName"] == null ? null : json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"] == null ? null : json["Dataw"], + dietType: json["DietType"] == null ? null : json["DietType"], + dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorType: json["ErrorType"] == null ? null : json["ErrorType"], + foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"], + mealType: json["MealType"] == null ? null : json["MealType"], + messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + itgRequest: json["ITGRequest"], + itgFormAttachmentsList: json["Itg_FormAttachmentsList"], + message: json["Message"] == null ? null : json["Message"], + mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"], + mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"], + mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"], + mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"], + mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"], + mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"], + mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"], + mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"], + mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"], + referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]), + requestType: json["RequestType"], + totalCount: json["TotalCount"] == null ? null : json["TotalCount"], + statuseCode: json["statuseCode"] == null ? null : json["statuseCode"], + ); + + Map toMap() => { + "Date": date, + "LanguageID": languageId == null ? null : languageId, + "ServiceName": serviceName == null ? null : serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw == null ? null : dataw, + "DietType": dietType == null ? null : dietType, + "DietTypeID": dietTypeId == null ? null : dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorType": errorType == null ? null : errorType, + "FoodCategory": foodCategory == null ? null : foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated == null ? null : isAuthenticated, + "MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus, + "MealType": mealType == null ? null : mealType, + "MessageStatus": messageStatus == null ? null : messageStatus, + "NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg == null ? null : successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "ITGRequest": itgRequest, + "Itg_FormAttachmentsList": itgFormAttachmentsList, + "Message": message == null ? null : message, + "Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList, + "Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList, + "Mohemm_ITG_ResponseItem": mohemmItgResponseItem, + "Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList, + "Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList, + "Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList, + "Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList, + "Mohemm_Itg_ProjectsList": mohemmItgProjectsList, + "Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList, + "ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(), + "RequestType": requestType, + "TotalCount": totalCount == null ? null : totalCount, + "statuseCode": statuseCode == null ? null : statuseCode, + }; +} diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index b993db8..fad6e51 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,6 +1,10 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'basic_member_information_model.dart'; +import 'dashboard/get_accrual_balances_list_model.dart'; +import 'dashboard/get_attendance_tracking_list_model.dart'; +import 'dashboard/get_open_missing_swipes_list_model.dart'; +import 'dashboard/get_open_notifications_list.dart'; import 'member_information_list_model.dart'; import 'privilege_list_model.dart'; @@ -57,13 +61,13 @@ class GenericResponseModel { List? getAbsenceCollectionNotificationBodyList; List? getAbsenceDffStructureList; List? getAbsenceTransactionList; - List? getAccrualBalancesList; + List? getAccrualBalancesList; List? getActionHistoryList; List? getAddressDffStructureList; List? getAddressNotificationBodyList; List? getApprovesList; List? getAttachementList; - List? getAttendanceTrackingList; + GetAttendanceTrackingList? getAttendanceTrackingList; List? getBasicDetColsStructureList; List? getBasicDetDffStructureList; List? getBasicDetNtfBodyList; @@ -105,8 +109,8 @@ class GenericResponseModel { List? getNotificationButtonsList; List? getNotificationReassignModeList; List? getObjectValuesList; - List? getOpenMissingSwipesList; - List? getOpenNotificationsList; + GetOpenMissingSwipesList? getOpenMissingSwipesList; + List? getOpenNotificationsList; List? getOpenNotificationsNumList; List? getOpenPeriodDatesList; List? getOrganizationsSalariesList; @@ -563,13 +567,15 @@ class GenericResponseModel { getAbsenceCollectionNotificationBodyList = json['GetAbsenceCollectionNotificationBodyList']; getAbsenceDffStructureList = json['GetAbsenceDffStructureList']; getAbsenceTransactionList = json['GetAbsenceTransactionList']; - getAccrualBalancesList = json['GetAccrualBalancesList']; + getAccrualBalancesList: + json["GetAccrualBalancesList"] == null ? null : List.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x))); getActionHistoryList = json['GetActionHistoryList']; getAddressDffStructureList = json['GetAddressDffStructureList']; getAddressNotificationBodyList = json['GetAddressNotificationBodyList']; getApprovesList = json['GetApprovesList']; getAttachementList = json['GetAttachementList']; - getAttendanceTrackingList = json['GetAttendanceTrackingList']; + getAttendanceTrackingList: + json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTrackingList.fromMap(json["GetAttendanceTrackingList"]); getBasicDetColsStructureList = json['GetBasicDetColsStructureList']; getBasicDetDffStructureList = json['GetBasicDetDffStructureList']; getBasicDetNtfBodyList = json['GetBasicDetNtfBodyList']; @@ -611,8 +617,9 @@ class GenericResponseModel { getNotificationButtonsList = json['GetNotificationButtonsList']; getNotificationReassignModeList = json['GetNotificationReassignModeList']; getObjectValuesList = json['GetObjectValuesList']; - getOpenMissingSwipesList = json['GetOpenMissingSwipesList']; - getOpenNotificationsList = json['GetOpenNotificationsList']; + getOpenMissingSwipesList: json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); + getOpenNotificationsList: + json["GetOpenNotificationsList"] == null ? null : List.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x))); getOpenNotificationsNumList = json['GetOpenNotificationsNumList']; getOpenPeriodDatesList = json['GetOpenPeriodDatesList']; getOrganizationsSalariesList = json['GetOrganizationsSalariesList']; diff --git a/lib/models/post_params_model.dart b/lib/models/post_params_model.dart index cd6dd72..1ab86f7 100644 --- a/lib/models/post_params_model.dart +++ b/lib/models/post_params_model.dart @@ -5,8 +5,27 @@ class PostParamsModel { String? mobileType; String? logInTokenID; String? tokenID; + String? mobileNumber; + String? pEmailAddress; + String? pUserName; + String? pSelectedEmployeeNumber; + int? pSessionId; + String? userName; - PostParamsModel({this.versionID, this.channel, this.languageID, this.mobileType, this.logInTokenID, this.tokenID}); + PostParamsModel({ + this.versionID, + this.channel, + this.languageID, + this.mobileType, + this.logInTokenID, + this.tokenID, + this.mobileNumber, + this.userName, + this.pEmailAddress, + this.pSessionId, + this.pUserName, + this.pSelectedEmployeeNumber, + }); PostParamsModel.fromJson(Map json) { versionID = json['VersionID']; @@ -28,7 +47,37 @@ class PostParamsModel { return data; } + Map toJsonAfterLogin() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['MobileType'] = this.mobileType; + data['LogInTokenID'] = this.logInTokenID; + data['TokenID'] = this.tokenID; + data['MobileNumber'] = this.mobileNumber; + data['UserName'] = this.userName; + data['P_EMAIL_ADDRESS'] = this.pEmailAddress; + data['P_SESSION_ID'] = this.pSessionId; + data['P_SELECTED_EMPLOYEE_NUMBER'] = this.pSelectedEmployeeNumber; + data['P_USER_NAME'] = this.pUserName; + + return data; + } + set setLogInTokenID(String? token) => logInTokenID = token; set setTokenID(String? token) => tokenID = token; + + set setMobileNumer(String? v) => mobileNumber = v; + + set setUserName(String? v) => userName = v; + + set setPEmailAddress(String? v) => pEmailAddress = v; + + set setPSessionId(int? v) => pSessionId = v; + + set setPUserName(String? v) => pUserName = v; + + set setPSelectedEmployeeNumber(String? v) => pSelectedEmployeeNumber = v; } diff --git a/lib/ui/landing/dashboard.dart b/lib/ui/landing/dashboard.dart index ac427d1..e8c2157 100644 --- a/lib/ui/landing/dashboard.dart +++ b/lib/ui/landing/dashboard.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; @@ -25,6 +26,7 @@ class _DashboardState extends State { @override void initState() { super.initState(); + DashbaordApiClient().getAttendanceTracking(); } @override @@ -42,7 +44,8 @@ class _DashboardState extends State { List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; - + // DashbaordApiClient().getOpenNotifications(); + DashbaordApiClient().getOpenMissingSwipes(); return Scaffold( body: Column( children: [ diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 5f0f266..2353f99 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -49,7 +49,7 @@ class _LoginScreenState extends State { _checkMobileAppVersion = await LoginApiClient().checkMobileAppVersion(); _memberLoginList = await LoginApiClient().memberLogin(username.text, password.text); AppState().setMemberLoginListModel = _memberLoginList; - AppState().username = username.text; + AppState().setUserName = username.text; print(_memberLoginList?.toJson()); Utils.hideLoading(context); Navigator.pushNamed(context, AppRoutes.verifyLogin); @@ -62,6 +62,8 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { + username.text="15153"; + password.text="e123e123e123"; return Scaffold( body: Column( children: [ diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index b28ad4d..ba0eb98 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -626,7 +626,7 @@ class _VerifyLoginScreenState extends State { } else { Utils.showLoading(context); BasicMemberInformationModel? memberInformationModel = await LoginApiClient() - .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); + .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName); Utils.hideLoading(context); OtpDialog( context, @@ -635,7 +635,7 @@ class _VerifyLoginScreenState extends State { (value) async { Utils.showLoading(context); try { - GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); // Navigator.pop(context); From fb8d6c7b20d3c074d6f269c2636bd67a28e9d556 Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Mon, 31 Jan 2022 17:46:43 +0300 Subject: [PATCH 07/22] Dashboard API's 1.1 --- assets/images/play.svg | 3 + assets/images/thumb.svg | 8 + lib/api/api_client.dart | 4 +- lib/api/dashboard_api_client.dart | 5 +- lib/config/routes.dart | 4 +- lib/extensions/widget_extensions.dart | 19 ++ lib/main.dart | 18 +- .../get_attendance_tracking_list_model.dart | 6 +- lib/models/generic_response_model.dart | 12 +- lib/provider/dashboard_provider_model.dart | 39 ++++ .../{dashboard.dart => dashboard_screen.dart} | 182 ++++++++++-------- .../shimmer/dashboard_shimmer_widget.dart | 82 ++++++++ pubspec.lock | 14 ++ pubspec.yaml | 2 + 14 files changed, 308 insertions(+), 90 deletions(-) create mode 100644 assets/images/play.svg create mode 100644 assets/images/thumb.svg create mode 100644 lib/provider/dashboard_provider_model.dart rename lib/ui/landing/{dashboard.dart => dashboard_screen.dart} (64%) create mode 100644 lib/widgets/shimmer/dashboard_shimmer_widget.dart diff --git a/assets/images/play.svg b/assets/images/play.svg new file mode 100644 index 0000000..1608b2e --- /dev/null +++ b/assets/images/play.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/thumb.svg b/assets/images/thumb.svg new file mode 100644 index 0000000..855ba71 --- /dev/null +++ b/assets/images/thumb.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index a08ed01..609aca9 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -7,6 +7,8 @@ import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:mohem_flutter_app/exceptions/api_exception.dart'; +import '../main.dart'; + typedef FactoryConstructor = U Function(dynamic); class APIError { @@ -76,7 +78,7 @@ class ApiClient { var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); try { if (!kReleaseMode) { - print("res: " + response.body); + logger.i("res: " + response.body); } var jsonData = jsonDecode(response.body); if (jsonData["ErrorMessage"] == null) { diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 5b6f961..ad513e9 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -4,6 +4,7 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; +import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; @@ -17,13 +18,13 @@ class DashbaordApiClient { factory DashbaordApiClient() => _instance; - Future getAttendanceTracking() async { + Future getAttendanceTracking() async { String url = "${ApiConsts.erpRest}GET_Attendance_Tracking"; Map postParams = {}; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); - return responseData; + return responseData.getAttendanceTrackingList; }, url, postParams); } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 39a4ebc..8e5a64e 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/ui/landing/dashboard.dart'; +import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart'; import 'package:mohem_flutter_app/ui/login/forgot_password_screen.dart'; import 'package:mohem_flutter_app/ui/login/login_screen.dart'; @@ -28,7 +28,7 @@ class AppRoutes { static final Map routes = { login: (context) => LoginScreen(), verifyLogin: (context) => VerifyLoginScreen(), - dashboard: (context) => Dashboard(), + dashboard: (context) => DashboardScreen(), newPassword: (context) => NewPasswordScreen(), forgotPassword: (context) => ForgotPasswordScreen(), todayAttendance: (context) => TodayAttendanceScreen(), diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 787894d..dc083ce 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import 'package:shimmer/shimmer.dart'; extension WidgetExtensions on Widget { Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); @@ -8,4 +9,22 @@ extension WidgetExtensions on Widget { Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); + + Widget toShimmer() => Shimmer.fromColors( + baseColor: Color(0xffe8eff0), + highlightColor: Colors.white, + child: Container( + child: this, + color: Colors.white, + )); + + Widget animatedSwither() => AnimatedSwitcher( + duration: const Duration(milliseconds: 500), + // transitionBuilder: (Widget child, Animation animation) { + // return ScaleTransition(scale: animation, child: child); + // }, + switchInCurve: Curves.linearToEaseOut, + switchOutCurve: Curves.linearToEaseOut, + child: this, + ); } diff --git a/lib/main.dart b/lib/main.dart index 99cff95..0b05d10 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,11 +6,22 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/config/app_provider.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/theme/app_theme.dart'; +import 'package:provider/provider.dart'; import 'package:sizer/sizer.dart'; +import 'package:logger/logger.dart'; import 'config/routes.dart'; + +var logger = Logger( + filter: null, // Use the default LogFilter (-> only log in debug mode) + printer: PrettyPrinter(), // Use the PrettyPrinter to format and print log + output: null, // U +); + + Future main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); @@ -22,7 +33,12 @@ Future main() async { ], path: 'assets/langs', assetLoader: CodegenLoader(), - child: MyApp(), + child: MultiProvider( + providers: [ + ChangeNotifierProvider(create: (_) => DashboardProviderModel()), + ], + child: MyApp(), + ), ), ); } diff --git a/lib/models/dashboard/get_attendance_tracking_list_model.dart b/lib/models/dashboard/get_attendance_tracking_list_model.dart index 66b9ed8..fb415b0 100644 --- a/lib/models/dashboard/get_attendance_tracking_list_model.dart +++ b/lib/models/dashboard/get_attendance_tracking_list_model.dart @@ -1,5 +1,5 @@ -class GetAttendanceTrackingList { - GetAttendanceTrackingList({ +class GetAttendanceTracking { + GetAttendanceTracking({ this.pBreakHours, this.pLateInHours, this.pRemainingHours, @@ -25,7 +25,7 @@ class GetAttendanceTrackingList { dynamic pSwipeIn; dynamic pSwipeOut; - factory GetAttendanceTrackingList.fromMap(Map json) => GetAttendanceTrackingList( + factory GetAttendanceTracking.fromMap(Map json) => GetAttendanceTracking( pBreakHours: json["P_BREAK_HOURS"] == null ? null : json["P_BREAK_HOURS"], pLateInHours: json["P_LATE_IN_HOURS"] == null ? null : json["P_LATE_IN_HOURS"], pRemainingHours: json["P_REMAINING_HOURS"] == null ? null : json["P_REMAINING_HOURS"], diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index fad6e51..86552a0 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -67,7 +67,7 @@ class GenericResponseModel { List? getAddressNotificationBodyList; List? getApprovesList; List? getAttachementList; - GetAttendanceTrackingList? getAttendanceTrackingList; + GetAttendanceTracking? getAttendanceTrackingList; List? getBasicDetColsStructureList; List? getBasicDetDffStructureList; List? getBasicDetNtfBodyList; @@ -567,15 +567,15 @@ class GenericResponseModel { getAbsenceCollectionNotificationBodyList = json['GetAbsenceCollectionNotificationBodyList']; getAbsenceDffStructureList = json['GetAbsenceDffStructureList']; getAbsenceTransactionList = json['GetAbsenceTransactionList']; - getAccrualBalancesList: + getAccrualBalancesList= json["GetAccrualBalancesList"] == null ? null : List.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x))); getActionHistoryList = json['GetActionHistoryList']; getAddressDffStructureList = json['GetAddressDffStructureList']; getAddressNotificationBodyList = json['GetAddressNotificationBodyList']; getApprovesList = json['GetApprovesList']; getAttachementList = json['GetAttachementList']; - getAttendanceTrackingList: - json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTrackingList.fromMap(json["GetAttendanceTrackingList"]); + getAttendanceTrackingList= + json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]); getBasicDetColsStructureList = json['GetBasicDetColsStructureList']; getBasicDetDffStructureList = json['GetBasicDetDffStructureList']; getBasicDetNtfBodyList = json['GetBasicDetNtfBodyList']; @@ -617,8 +617,8 @@ class GenericResponseModel { getNotificationButtonsList = json['GetNotificationButtonsList']; getNotificationReassignModeList = json['GetNotificationReassignModeList']; getObjectValuesList = json['GetObjectValuesList']; - getOpenMissingSwipesList: json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); - getOpenNotificationsList: + getOpenMissingSwipesList= json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); + getOpenNotificationsList= json["GetOpenNotificationsList"] == null ? null : List.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x))); getOpenNotificationsNumList = json['GetOpenNotificationsNumList']; getOpenPeriodDatesList = json['GetOpenPeriodDatesList']; diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart new file mode 100644 index 0000000..6ccbfc1 --- /dev/null +++ b/lib/provider/dashboard_provider_model.dart @@ -0,0 +1,39 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/main.dart'; +import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; + +/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool +// ignore: prefer_mixin +class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { + bool isAttendanceTrackingLoading = true; + int isTimeRemainingInSeconds = 0; + GetAttendanceTracking? attendanceTracking; + + fetchAttendanceTracking() async { + try { + attendanceTracking = await DashbaordApiClient().getAttendanceTracking(); + isAttendanceTrackingLoading = false; + isTimeRemainingInSeconds = calculateSeconds("00:00:30"); + notifyListeners(); + } catch (ex) { + Utils.handleException(ex, null); + } + } + + int calculateSeconds(String time) { + int hour = int.parse(time.split(":")[0]); + int mints = int.parse(time.split(":")[1]); + int seconds = int.parse(time.split(":")[2]); + return ((hour * 60 * 60) + (mints * 60) + seconds); + } + + update() { + isAttendanceTrackingLoading = !isAttendanceTrackingLoading; + attendanceTracking?.pSwipeIn = "a"; + isTimeRemainingInSeconds = calculateSeconds("00:00:30"); + notifyListeners(); + } +} diff --git a/lib/ui/landing/dashboard.dart b/lib/ui/landing/dashboard_screen.dart similarity index 64% rename from lib/ui/landing/dashboard.dart rename to lib/ui/landing/dashboard_screen.dart index e8c2157..4a4ad94 100644 --- a/lib/ui/landing/dashboard.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -9,26 +10,33 @@ import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/theme/colors.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; import 'package:shimmer/shimmer.dart'; -class Dashboard extends StatefulWidget { - Dashboard({Key? key}) : super(key: key); +class DashboardScreen extends StatefulWidget { + DashboardScreen({Key? key}) : super(key: key); @override - _DashboardState createState() { - return _DashboardState(); + _DashboardScreenState createState() { + return _DashboardScreenState(); } } -class _DashboardState extends State { +class _DashboardScreenState extends State { @override void initState() { super.initState(); - DashbaordApiClient().getAttendanceTracking(); + final data = Provider.of(context, listen: false); + data.fetchAttendanceTracking(); } + int endTime = 0; + @override void dispose() { super.dispose(); @@ -44,8 +52,9 @@ class _DashboardState extends State { List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; - // DashbaordApiClient().getOpenNotifications(); - DashbaordApiClient().getOpenMissingSwipes(); + final data = Provider.of(context); + + endTime=DateTime.now().millisecondsSinceEpoch + Duration(seconds: data.isTimeRemainingInSeconds).inMilliseconds; return Scaffold( body: Column( children: [ @@ -93,7 +102,9 @@ class _DashboardState extends State { ) ], ), - ) + ).onPress(() { + data.update(); + }) ], ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), Expanded( @@ -111,75 +122,96 @@ class _DashboardState extends State { Expanded( child: AspectRatio( aspectRatio: 159 / 159, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Stack( - alignment: Alignment.center, - children: [ - // SvgPicture.asset("assets/images/"), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + child: (data.isAttendanceTrackingLoading + ? GetAttendanceTrackingShimmer() + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Stack( + alignment: Alignment.center, children: [ - LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), - 9.height, - "07:55:12".toText14(color: Colors.white, isBold: true), - LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), - 9.height, - const ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(20), - ), - child: LinearProgressIndicator( - value: 0.7, - minHeight: 8, - valueColor: const AlwaysStoppedAnimation(Colors.white), - backgroundColor: const Color(0xff196D73), - ), - ), - ], - ).paddingOnly(top: 12, right: 15, left: 12), - ), - Row( - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, + if (data.attendanceTracking?.pSwipeIn == null) SvgPicture.asset("assets/images/thumb.svg"), + Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], - ).paddingOnly(left: 12), - ), - Container( - width: 45, - height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), - decoration: const BoxDecoration( - color: Color(0xff259EA4), - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(15), - ), + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CountdownTimer( + endTime: endTime, + onEnd: null, + endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), + textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), + ), + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + if (data.attendanceTracking?.pSwipeIn == null) "01-02-2022".toText12(color: Colors.white), + if (data.attendanceTracking?.pSwipeIn != null) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 9.height, + "07:55:12".toText14(color: Colors.white, isBold: true), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + const ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), + ], + ), + ], + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.checkIn.tr().toText12(color: Colors.white), + (data.attendanceTracking?.pSwipeIn == null ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true), + 4.height + ], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset(data.attendanceTracking?.pSwipeIn == null ? "assets/images/play.svg" : "assets/images/stop.svg"), + ), + ], + ), + ], ), - child: SvgPicture.asset("assets/images/stop.svg"), - ), - ], - ), - ], - ), - ], - ), - ).onPress(() { - Navigator.pushNamed(context, AppRoutes.todayAttendance); - }), + ], + ), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.todayAttendance); + })) + .animatedSwither(), ), ), 9.width, diff --git a/lib/widgets/shimmer/dashboard_shimmer_widget.dart b/lib/widgets/shimmer/dashboard_shimmer_widget.dart new file mode 100644 index 0000000..1c63d71 --- /dev/null +++ b/lib/widgets/shimmer/dashboard_shimmer_widget.dart @@ -0,0 +1,82 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:shimmer/shimmer.dart'; + +class GetAttendanceTrackingShimmer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Stack( + alignment: Alignment.center, + children: [ + // SvgPicture.asset("assets/images/"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true).toShimmer(), + 16.height, + "07:55:12".toText10(color: Colors.white, isBold: true).toShimmer(), + 3.height, + LocaleKeys.timeLeftToday.tr().toText10(color: Colors.white).toShimmer(), + 9.height, + const ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ).toShimmer(), + ], + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white).toShimmer(),], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + // color: Colors.blue, + padding: const EdgeInsets.only(left: 14, right: 14), + ).toShimmer(), + ], + ), + ], + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 1ae9d08..58ce64a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -104,6 +104,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_countdown_timer: + dependency: "direct main" + description: + name: flutter_countdown_timer + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" flutter_lints: dependency: "direct dev" description: @@ -196,6 +203,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.9" + logger: + dependency: "direct main" + description: + name: logger + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 868012d..e7d1182 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,8 @@ dependencies: local_auth: ^1.1.9 fluttertoast: ^8.0.8 shimmer: ^2.0.0 + logger: ^1.1.0 + flutter_countdown_timer: ^4.1.0 dev_dependencies: From b6670289b12de5707e8f4a642835047c7318493c Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Mon, 7 Feb 2022 11:09:15 +0300 Subject: [PATCH 08/22] Dashboard API's 1.2 --- lib/api/dashboard_api_client.dart | 22 ++ lib/api/login_api_client.dart | 1 + lib/extensions/string_extensions.dart | 8 + lib/extensions/widget_extensions.dart | 15 +- lib/main.dart | 6 +- lib/models/dashboard/list_menu.dart | 39 ++ lib/models/dashboard/menu_entries.dart | 60 +++ lib/models/dashboard/menus.dart | 10 + lib/models/generic_response_model.dart | 23 +- lib/provider/dashboard_provider_model.dart | 142 +++++++- lib/ui/landing/dashboard_screen.dart | 341 +++++++----------- lib/ui/landing/widget/menus_widget.dart | 138 +++++++ lib/ui/landing/widget/services_widget.dart | 147 ++++++++ lib/widgets/Updater.dart | 39 ++ .../shimmer/dashboard_shimmer_widget.dart | 109 +++++- 15 files changed, 864 insertions(+), 236 deletions(-) create mode 100644 lib/models/dashboard/list_menu.dart create mode 100644 lib/models/dashboard/menu_entries.dart create mode 100644 lib/models/dashboard/menus.dart create mode 100644 lib/ui/landing/widget/menus_widget.dart create mode 100644 lib/ui/landing/widget/services_widget.dart create mode 100644 lib/widgets/Updater.dart diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index ad513e9..b98a777 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -67,4 +67,26 @@ class DashbaordApiClient { return responseData; }, url, postParams); } + + //Menus List + Future getListMenu() async { + String url = "${ApiConsts.erpRest}GET_MENU"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + //GET_MENU_ENTRIES + Future getGetMenuEntries() async { + String url = "${ApiConsts.erpRest}GET_MENU_ENTRIES"; + Map postParams = {"P_SELECTED_RESP_ID": -999,"P_MENU_TYPE":"E"}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } } diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart index fb6bb80..86b7ace 100644 --- a/lib/api/login_api_client.dart +++ b/lib/api/login_api_client.dart @@ -55,6 +55,7 @@ class LoginApiClient { AppState().postParamsObject?.pSessionId = responseData.pSESSIONID; AppState().postParamsObject?.pUserName = AppState().getUserName; AppState().postParamsObject?.pSelectedEmployeeNumber = AppState().getUserName; + return responseData; }, url, postParams); } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9db4829..5d4f8cd 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -2,6 +2,14 @@ import 'package:flutter/cupertino.dart'; import 'package:intl/intl.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +extension CapExtension on String { + String get toCamelCase => "${this[0].toUpperCase()}${this.substring(1)}"; + String get inCaps => '${this[0].toUpperCase()}${this.substring(1)}'; + String get allInCaps => this.toUpperCase(); + String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : ""; +} + + extension EmailValidator on String { Widget get toWidget => Text(this); diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index dc083ce..130c867 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -10,13 +10,14 @@ extension WidgetExtensions on Widget { Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); - Widget toShimmer() => Shimmer.fromColors( - baseColor: Color(0xffe8eff0), - highlightColor: Colors.white, - child: Container( - child: this, - color: Colors.white, - )); + Widget toShimmer({bool isShow=true}) =>isShow? Shimmer.fromColors( + baseColor: Color(0xffe8eff0), + highlightColor: Colors.white, + child: Container( + child: this, + color: Colors.white, + ), + ):Container(child: this,); Widget animatedSwither() => AnimatedSwitcher( duration: const Duration(milliseconds: 500), diff --git a/lib/main.dart b/lib/main.dart index 0b05d10..1146ff0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,9 +16,9 @@ import 'config/routes.dart'; var logger = Logger( - filter: null, // Use the default LogFilter (-> only log in debug mode) - printer: PrettyPrinter(), // Use the PrettyPrinter to format and print log - output: null, // U + // filter: null, // Use the default LogFilter (-> only log in debug mode) + printer: PrettyPrinter(lineLength: 0), // Use the PrettyPrinter to format and print log + // output: null, // U ); diff --git a/lib/models/dashboard/list_menu.dart b/lib/models/dashboard/list_menu.dart new file mode 100644 index 0000000..ba327c2 --- /dev/null +++ b/lib/models/dashboard/list_menu.dart @@ -0,0 +1,39 @@ +class ListMenu { + ListMenu({ + this.menuId, + this.menuName, + this.menuType, + this.requestGroupId, + this.requestGroupName, + this.respId, + this.subMenuName, + }); + + int? menuId; + String? menuName; + String? menuType; + int? requestGroupId; + String? requestGroupName; + dynamic? respId; + String? subMenuName; + + factory ListMenu.fromJson(Map json) => ListMenu( + menuId: json["MENU_ID"] == null ? null : json["MENU_ID"], + menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"], + menuType: json["MENU_TYPE"] == null ? null : json["MENU_TYPE"], + requestGroupId: json["REQUEST_GROUP_ID"] == null ? null : json["REQUEST_GROUP_ID"], + requestGroupName: json["REQUEST_GROUP_NAME"] == null ? null : json["REQUEST_GROUP_NAME"], + respId: json["RESP_ID"], + subMenuName: json["SUB_MENU_NAME"] == null ? null : json["SUB_MENU_NAME"], + ); + + Map toJson() => { + "MENU_ID": menuId == null ? null : menuId, + "MENU_NAME": menuName == null ? null : menuName, + "MENU_TYPE": menuType == null ? null : menuType, + "REQUEST_GROUP_ID": requestGroupId == null ? null : requestGroupId, + "REQUEST_GROUP_NAME": requestGroupName == null ? null : requestGroupName, + "RESP_ID": respId, + "SUB_MENU_NAME": subMenuName == null ? null : subMenuName, + }; +} diff --git a/lib/models/dashboard/menu_entries.dart b/lib/models/dashboard/menu_entries.dart new file mode 100644 index 0000000..7678ad8 --- /dev/null +++ b/lib/models/dashboard/menu_entries.dart @@ -0,0 +1,60 @@ +class GetMenuEntriesList { + GetMenuEntriesList({ + this.addButton, + this.deleteButton, + this.entrySequence, + this.functionName, + this.icon, + this.lvl, + this.menuEntryType, + this.menuName, + this.parentMenuName, + this.prompt, + this.requestType, + this.updateButton, + }); + + String? addButton; + String? deleteButton; + int? entrySequence; + String? functionName; + String? icon; + int? lvl; + String? menuEntryType; + String? menuName; + String? parentMenuName; + String? prompt; + String? requestType; + String? updateButton; + + factory GetMenuEntriesList.fromJson(Map json) => GetMenuEntriesList( + addButton: json["ADD_BUTTON"] == null ? null : json["ADD_BUTTON"], + deleteButton: json["DELETE_BUTTON"] == null ? null : json["DELETE_BUTTON"], + entrySequence: json["ENTRY_SEQUENCE"] == null ? null : json["ENTRY_SEQUENCE"], + functionName: json["FUNCTION_NAME"] == null ? null : json["FUNCTION_NAME"], + icon: json["ICON"] == null ? null : json["ICON"], + lvl: json["LVL"] == null ? null : json["LVL"], + menuEntryType: json["MENU_ENTRY_TYPE"] == null ? null : json["MENU_ENTRY_TYPE"], + menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"], + parentMenuName: json["PARENT_MENU_NAME"] == null ? null : json["PARENT_MENU_NAME"], + prompt: json["PROMPT"] == null ? null : json["PROMPT"], + requestType: json["REQUEST_TYPE"] == null ? null : json["REQUEST_TYPE"], + updateButton: json["UPDATE_BUTTON"] == null ? null :json["UPDATE_BUTTON"], + ); + + Map toJson() => { + "ADD_BUTTON": addButton == null ? null :addButton, + "DELETE_BUTTON": deleteButton == null ? null : deleteButton, + "ENTRY_SEQUENCE": entrySequence == null ? null : entrySequence, + "FUNCTION_NAME": functionName == null ? null : functionName, + "ICON": icon == null ? null : icon, + "LVL": lvl == null ? null : lvl, + "MENU_ENTRY_TYPE": menuEntryType == null ? null : menuEntryType, + "MENU_NAME": menuName == null ? null : menuName, + "PARENT_MENU_NAME": parentMenuName == null ? null : parentMenuName, + "PROMPT": prompt == null ? null : prompt, + "REQUEST_TYPE": requestType == null ? null : requestType, + "UPDATE_BUTTON": updateButton == null ? null : updateButton, + }; +} + diff --git a/lib/models/dashboard/menus.dart b/lib/models/dashboard/menus.dart new file mode 100644 index 0000000..7b88a33 --- /dev/null +++ b/lib/models/dashboard/menus.dart @@ -0,0 +1,10 @@ +import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; + +class Menus { + GetMenuEntriesList menuEntry; + List menuEntiesList; + + Menus(this.menuEntry, this.menuEntiesList); + + +} diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 86552a0..8ac68bb 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -5,6 +5,8 @@ import 'dashboard/get_accrual_balances_list_model.dart'; import 'dashboard/get_attendance_tracking_list_model.dart'; import 'dashboard/get_open_missing_swipes_list_model.dart'; import 'dashboard/get_open_notifications_list.dart'; +import 'dashboard/list_menu.dart'; +import 'dashboard/menu_entries.dart'; import 'member_information_list_model.dart'; import 'privilege_list_model.dart'; @@ -103,7 +105,7 @@ class GenericResponseModel { List? getItemTypeNotificationsList; List? getItemTypesList; List? getLookupValuesList; - List? getMenuEntriesList; + List? getMenuEntriesList; List? getMoItemHistoryList; List? getMoNotificationBodyList; List? getNotificationButtonsList; @@ -169,7 +171,7 @@ class GenericResponseModel { String? listItemImagesDetails; String? listItemMaster; String? listMedicineDetails; - String? listMenu; + List? listMenu; String? listNewEmployees; String? listRadScreen; String? logInTokenID; @@ -198,7 +200,7 @@ class GenericResponseModel { String? pINFORMATION; int? pMBLID; String? pNUMOFSUBORDINATES; - String? pOPENNTFNUMBER; + int? pOPENNTFNUMBER; String? pQUESTION; int? pSESSIONID; String? pSchema; @@ -567,15 +569,13 @@ class GenericResponseModel { getAbsenceCollectionNotificationBodyList = json['GetAbsenceCollectionNotificationBodyList']; getAbsenceDffStructureList = json['GetAbsenceDffStructureList']; getAbsenceTransactionList = json['GetAbsenceTransactionList']; - getAccrualBalancesList= - json["GetAccrualBalancesList"] == null ? null : List.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x))); + getAccrualBalancesList = json["GetAccrualBalancesList"] == null ? null : List.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x))); getActionHistoryList = json['GetActionHistoryList']; getAddressDffStructureList = json['GetAddressDffStructureList']; getAddressNotificationBodyList = json['GetAddressNotificationBodyList']; getApprovesList = json['GetApprovesList']; getAttachementList = json['GetAttachementList']; - getAttendanceTrackingList= - json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]); + getAttendanceTrackingList = json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]); getBasicDetColsStructureList = json['GetBasicDetColsStructureList']; getBasicDetDffStructureList = json['GetBasicDetDffStructureList']; getBasicDetNtfBodyList = json['GetBasicDetNtfBodyList']; @@ -611,15 +611,14 @@ class GenericResponseModel { getItemTypeNotificationsList = json['GetItemTypeNotificationsList']; getItemTypesList = json['GetItemTypesList']; getLookupValuesList = json['GetLookupValuesList']; - getMenuEntriesList = json['GetMenuEntriesList']; + getMenuEntriesList= json["GetMenuEntriesList"] == null ? null : List.from(json["GetMenuEntriesList"].map((x) => GetMenuEntriesList.fromJson(x))); getMoItemHistoryList = json['GetMoItemHistoryList']; getMoNotificationBodyList = json['GetMoNotificationBodyList']; getNotificationButtonsList = json['GetNotificationButtonsList']; getNotificationReassignModeList = json['GetNotificationReassignModeList']; getObjectValuesList = json['GetObjectValuesList']; - getOpenMissingSwipesList= json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); - getOpenNotificationsList= - json["GetOpenNotificationsList"] == null ? null : List.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x))); + getOpenMissingSwipesList = json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); + getOpenNotificationsList = json["GetOpenNotificationsList"] == null ? null : List.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x))); getOpenNotificationsNumList = json['GetOpenNotificationsNumList']; getOpenPeriodDatesList = json['GetOpenPeriodDatesList']; getOrganizationsSalariesList = json['GetOrganizationsSalariesList']; @@ -678,7 +677,7 @@ class GenericResponseModel { listItemImagesDetails = json['List_ItemImagesDetails']; listItemMaster = json['List_ItemMaster']; listMedicineDetails = json['List_MedicineDetails']; - listMenu = json['List_Menu']; + listMenu = json["List_Menu"] == null ? null : List.from(json["List_Menu"].map((x) => ListMenu.fromJson(x))); listNewEmployees = json['List_NewEmployees']; listRadScreen = json['List_RadScreen']; logInTokenID = json['LogInTokenID']; diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 6ccbfc1..b52448e 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -1,23 +1,54 @@ +import 'dart:convert'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; +import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; +import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; +import 'package:mohem_flutter_app/models/dashboard/menus.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/widgets/Updater.dart'; /// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool // ignore: prefer_mixin class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { + //Attendance Tracking bool isAttendanceTrackingLoading = true; - int isTimeRemainingInSeconds = 0; + int endTime = 0, isTimeRemainingInSeconds = 0; GetAttendanceTracking? attendanceTracking; + //Work List + bool isWorkListLoading = true; + int workListCounter = 0; + + //Misssing Swipe + bool isMissingSwipeLoading = true; + int missingSwipeCounter = 0; + + //Leave and Ticket Balance + bool isLeaveTicketBalanceLoading = true; + double leaveBalance = 0; + double ticketBalance = 0; + + //Menu Entries + bool isServicesMenusLoading = true; + List? homeMenus; + List? getMenuEntriesList; + + //Attendance Tracking API's & Methods fetchAttendanceTracking() async { try { attendanceTracking = await DashbaordApiClient().getAttendanceTracking(); isAttendanceTrackingLoading = false; - isTimeRemainingInSeconds = calculateSeconds("00:00:30"); - notifyListeners(); + isTimeRemainingInSeconds = calculateSeconds("00:00:00"); + endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; + print("isTimeRemainingInSeconds " + isTimeRemainingInSeconds.toString()); + print("endTime " + endTime.toString()); + + // notifyListeners(); } catch (ex) { Utils.handleException(ex, null); } @@ -32,8 +63,111 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { update() { isAttendanceTrackingLoading = !isAttendanceTrackingLoading; + isWorkListLoading = !isWorkListLoading; attendanceTracking?.pSwipeIn = "a"; - isTimeRemainingInSeconds = calculateSeconds("00:00:30"); + isTimeRemainingInSeconds = calculateSeconds("00:10:30"); + endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; + notifyListeners(); } + + //Work List API's & Methods + fetchWorkListCounter() async { + try { + GenericResponseModel? genericResponseModel = await DashbaordApiClient().getOpenNotifications(); + isWorkListLoading = false; + workListCounter = genericResponseModel?.pOPENNTFNUMBER ?? 0; + ItgFormsModel? itgFormsModel = await DashbaordApiClient().getItgFormsPendingTask(); + workListCounter = workListCounter + (itgFormsModel?.totalCount ?? 0); + notifyListeners(); + } catch (ex) { + isWorkListLoading = false; + logger.wtf(ex); + notifyListeners(); + Utils.handleException(ex, null); + } + } + + //Missing Siwpe API's & Methods + fetchMissingSwipe() async { + try { + GenericResponseModel? genericResponseModel = await DashbaordApiClient().getOpenMissingSwipes(); + isMissingSwipeLoading = false; + missingSwipeCounter = genericResponseModel!.getOpenMissingSwipesList!.pOpenMissingSwipes ?? 0; + notifyListeners(); + } catch (ex) { + isMissingSwipeLoading = false; + logger.wtf(ex); + notifyListeners(); + Utils.handleException(ex, null); + } + } + + //Leave and Ticket Balance API's & Methods + fetchLeaveTicketBalance() async { + try { + GenericResponseModel? genericResponseModel = await DashbaordApiClient().getAccrualBalances(); + isLeaveTicketBalanceLoading = false; + leaveBalance = genericResponseModel?.getAccrualBalancesList![0].accrualNetEntitlement ?? 0.0; + ticketBalance = (genericResponseModel?.getAccrualBalancesList![1].accrualNetEntitlement ?? 0.0) + (genericResponseModel?.getAccrualBalancesList![2].accrualNetEntitlement ?? 0.0); + notifyListeners(); + } catch (ex) { + isLeaveTicketBalanceLoading = false; + logger.wtf(ex); + notifyListeners(); + Utils.handleException(ex, null); + } + } + + //List Menu API's & Methods + fetchListMenu() async { + try { + GenericResponseModel? genericResponseModel = await DashbaordApiClient().getListMenu(); + Map map = {}; + print(jsonEncode(genericResponseModel!.listMenu)); + for (int i = 0; i < genericResponseModel!.listMenu!.length; i++) { + print(genericResponseModel!.listMenu![i]!.menuName ?? ""); + map[genericResponseModel!.listMenu![i]!.menuName ?? ""] = i.toString(); + } + logger.i(map); + notifyListeners(); + } catch (ex) { + logger.wtf(ex); + notifyListeners(); + Utils.handleException(ex, null); + } + } + + //Menu Entries API's & Methods + fetchMenuEntries() async { + try { + GenericResponseModel? genericResponseModel = await DashbaordApiClient().getGetMenuEntries(); + getMenuEntriesList = genericResponseModel!.getMenuEntriesList; + homeMenus = parseMenues(getMenuEntriesList ?? []); + isServicesMenusLoading = false; + notifyListeners(); + } catch (ex) { + logger.wtf(ex); + notifyListeners(); + Utils.handleException(ex, null); + } + } + + List parseMenues(List getMenuEntriesList) { + List menus = []; + for (int i = 0; i < getMenuEntriesList.length; i++) { + if (getMenuEntriesList[i].parentMenuName!.isEmpty) { + menus.add(Menus(getMenuEntriesList[i], getMenuEntriesList.where((element) => getMenuEntriesList[i].menuName == element.parentMenuName).toList())); + } + } + + //Verify Menus by printing in log + // for(int i=0;i { + late var data; + @override void initState() { super.initState(); - final data = Provider.of(context, listen: false); + data = Provider.of(context, listen: false); data.fetchAttendanceTracking(); + data.fetchWorkListCounter(); + data.fetchMissingSwipe(); + data.fetchLeaveTicketBalance(); + // data.fetchMenuEntries(); } - int endTime = 0; - @override void dispose() { super.dispose(); @@ -44,17 +56,8 @@ class _DashboardScreenState extends State { @override Widget build(BuildContext context) { - List names = [LocaleKeys.workList.tr(), LocaleKeys.missingSwipes.tr(), LocaleKeys.leaveBalance.tr(), LocaleKeys.ticketBalance.tr()]; - List namesInt = [118, 02, 18.5, 03]; - List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; - - List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; - List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; - List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; - final data = Provider.of(context); - - endTime=DateTime.now().millisecondsSinceEpoch + Duration(seconds: data.isTimeRemainingInSeconds).inMilliseconds; + return Scaffold( body: Column( children: [ @@ -108,214 +111,134 @@ class _DashboardScreenState extends State { ], ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), Expanded( - child: ListView( - padding: EdgeInsets.zero, + child: Column( + // padding: EdgeInsets.zero, + // physics: NeverScrollableScrollPhysics(), children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), - "Mahmoud Shrouf".toText24(isBold: true), - 16.height, - Row( + Expanded( + child: SingleChildScrollView( + child: Column( children: [ - Expanded( - child: AspectRatio( - aspectRatio: 159 / 159, - child: (data.isAttendanceTrackingLoading - ? GetAttendanceTrackingShimmer() - : Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Stack( - alignment: Alignment.center, - children: [ - if (data.attendanceTracking?.pSwipeIn == null) SvgPicture.asset("assets/images/thumb.svg"), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - CountdownTimer( - endTime: endTime, - onEnd: null, - endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), - textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), + "Mahmoud Shrouf".toText24(isBold: true), + 16.height, + Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 159 / 159, + child: Consumer( + builder: (context, model, child) { + return (model.isAttendanceTrackingLoading + ? GetAttendanceTrackingShimmer() + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), ), - LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), - if (data.attendanceTracking?.pSwipeIn == null) "01-02-2022".toText12(color: Colors.white), - if (data.attendanceTracking?.pSwipeIn != null) - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 9.height, - "07:55:12".toText14(color: Colors.white, isBold: true), - LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), - 9.height, - const ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(20), + child: Stack( + alignment: Alignment.center, + children: [ + if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white), + if (model.isTimeRemainingInSeconds != 0) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 9.height, + CountdownTimer( + endTime: model.endTime, + onEnd: null, + endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), + textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), + ), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + const ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), + ], + ), + ], + ).paddingOnly(top: 12, right: 15, left: 12), ), - child: LinearProgressIndicator( - value: 0.7, - minHeight: 8, - valueColor: const AlwaysStoppedAnimation(Colors.white), - backgroundColor: const Color(0xff196D73), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.checkIn.tr().toText12(color: Colors.white), + (model.isTimeRemainingInSeconds == 0 ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true), + 4.height + ], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"), + ), + ], ), - ), - ], - ), - ], - ).paddingOnly(top: 12, right: 15, left: 12), - ), - Row( - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.checkIn.tr().toText12(color: Colors.white), - (data.attendanceTracking?.pSwipeIn == null ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true), - 4.height + ], + ), ], - ).paddingOnly(left: 12), - ), - Container( - width: 45, - height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), - decoration: const BoxDecoration( - color: Color(0xff259EA4), - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(15), - ), ), - child: SvgPicture.asset(data.attendanceTracking?.pSwipeIn == null ? "assets/images/play.svg" : "assets/images/stop.svg"), - ), - ], - ), - ], - ), - ], - ), - ).onPress(() { - Navigator.pushNamed(context, AppRoutes.todayAttendance); - })) - .animatedSwither(), - ), - ), - 9.width, - Expanded( - child: GridView.builder( - shrinkWrap: true, - primary: false, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), - padding: EdgeInsets.zero, - itemCount: 4, - itemBuilder: (BuildContext context, int index) { - return Container( - decoration: BoxDecoration( - color: Color(namesColor[index]), - borderRadius: BorderRadius.circular(10), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.todayAttendance); + })) + .animatedSwither(); + }, + )), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - names[index].toText12(color: Colors.white), - Row( - children: [ - Expanded( - child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), - ), - SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) - ], - ) - ], - ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), - ).onPress(() { - Navigator.pushNamed(context, AppRoutes.workList); - }); - }, - ), - ), - ], - ), - 20.height, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - "Other".tr().toText12(), - LocaleKeys.services.tr().toText24(isBold: true), - ], - ), - ), - LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), - ], - ), - ], - ).paddingOnly(left: 21, right: 21, top: 7), - SizedBox( - height: 105 + 26, - child: ListView.separated( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), - scrollDirection: Axis.horizontal, - itemBuilder: (cxt, index) { - return AspectRatio( - aspectRatio: 105 / 105, - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), + 9.width, + Expanded( + child: MenusWidget(), ), ], ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SvgPicture.asset(iconT[index]), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - child: namesT[index].toText11(isBold: true), - ), - SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) - ], - ) - ], - ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), - ), - ); - }, - separatorBuilder: (cxt, index) => 9.width, - itemCount: 4), + 20.height, + ], + ).paddingOnly(left: 21, right: 21, top: 7), + ServicesWidget(), + 8.height, + ], + ), + ), ), - 8.height, Container( width: double.infinity, padding: EdgeInsets.only(top: 31), diff --git a/lib/ui/landing/widget/menus_widget.dart b/lib/ui/landing/widget/menus_widget.dart new file mode 100644 index 0000000..4d13775 --- /dev/null +++ b/lib/ui/landing/widget/menus_widget.dart @@ -0,0 +1,138 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class MenusWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; + + return Consumer(builder: (context, data, child) { + return GridView( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), + padding: EdgeInsets.zero, + shrinkWrap: true, + primary: false, + physics: const NeverScrollableScrollPhysics(), + children: [ + data.isWorkListLoading + ? MenuShimmer().onPress(() { + data.fetchWorkListCounter(); + }) + : Container( + decoration: BoxDecoration( + color: Color(namesColor[0]), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.workList.tr().toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: data.workListCounter.toString().toText16(color: Colors.white, isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ).onPress(() { + // Navigator.pushNamed(context, AppRoutes.workList); + data.fetchWorkListCounter(); + }), + data.isMissingSwipeLoading + ? MenuShimmer().onPress(() { + data.fetchWorkListCounter(); + }) + : Container( + decoration: BoxDecoration( + color: Color(namesColor[1]), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.missingSwipes.tr().toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: data.missingSwipeCounter.toString().toText16(color: Colors.white, isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.workList); + }), + data.isLeaveTicketBalanceLoading + ? MenuShimmer().onPress(() { + data.fetchWorkListCounter(); + }) + : Container( + decoration: BoxDecoration( + color: Color(namesColor[2]), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.leaveBalance.tr().toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: data.leaveBalance.toString().toText16(color: Colors.white, isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.workList); + }), + data.isLeaveTicketBalanceLoading + ? MenuShimmer().onPress(() { + data.fetchWorkListCounter(); + }) + : Container( + decoration: BoxDecoration( + color: Color(namesColor[3]), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.ticketBalance.tr().toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: data.ticketBalance.toString().toText16(color: Colors.white, isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.workList); + }) + ], + ); + }); + } +} diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart new file mode 100644 index 0000000..f397a4c --- /dev/null +++ b/lib/ui/landing/widget/services_widget.dart @@ -0,0 +1,147 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; +import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class ServicesWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; + List iconT = [ + "assets/images/monthly_attendance.svg", + "assets/images/work_from_home.svg", + "assets/images/ticket_request.svg", + "assets/images/work_from_home.svg", + "assets/images/work_from_home.svg", + "assets/images/work_from_home.svg", + "assets/images/work_from_home.svg", + "assets/images/work_from_home.svg" + ]; + + return Consumer( + builder: (context, data, child) { + return data.isServicesMenusLoading + ? whileLoading() + : ListView.separated( + itemBuilder: (context, parentIndex) { + return Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + firstWord(data.homeMenus![parentIndex].menuEntry.prompt!).toText12(), + lastWord(data.homeMenus![parentIndex].menuEntry.prompt!).toText24(isBold: true), + ], + ), + ), + LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), + ], + ).paddingOnly(left: 21, right: 21), + SizedBox( + height: 105 + 26, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return AspectRatio( + aspectRatio: 105 / 105, + child: data.isServicesMenusLoading + ? ServicesMenuShimmer() + : Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset(iconT[index]), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: data.homeMenus![parentIndex].menuEntiesList.length), + ), + ], + ); + }, + separatorBuilder: (context, index) { + return 12.height; + }, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: data.homeMenus!.length); + }, + ); + } + + String firstWord(String value) { + return value.split(" ").length > 1 ? value.split(" ")[0] : ""; + } + + String lastWord(String value) { + var parts = value.split(" "); + if (parts.length == 1) { + return value; + } else { + int i = value.indexOf(" "); + return value.substring(i + 1).toCamelCase; + } + } + + Widget whileLoading() { + return Column( + children: [ + ServicesHeaderShimmer().paddingOnly(left: 21, right: 21), + SizedBox( + height: 105 + 26, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return AspectRatio( + aspectRatio: 105 / 105, + child: ServicesMenuShimmer(), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: 4), + ), + ], + ); + } +} diff --git a/lib/widgets/Updater.dart b/lib/widgets/Updater.dart new file mode 100644 index 0000000..154173d --- /dev/null +++ b/lib/widgets/Updater.dart @@ -0,0 +1,39 @@ +/* ZiK */ + +import 'dart:async'; +import 'package:flutter/cupertino.dart'; + +typedef ChildProvider = Widget Function(BuildContext context, E? data); + +class Updater extends StatelessWidget{ + final ChildProvider childProvider; + StreamController? sink; + T? initialData; + List _history = []; + + Stream? _stream; + Updater({T? initialData, required this.childProvider}){ + this.sink = StreamController(); + this.initialData = initialData; + _stream = this.sink?.stream; + } + + @override + Widget build(BuildContext context) { + return StreamBuilder( + initialData: this.initialData, + stream: _stream, + builder: (ctx, snapshot){ + return childProvider(context, snapshot.data); + }); + } + + pushData(T? data) { + _history.add(data); + sink?.sink.add(data); + } + + List getDataHistory() => _history; + T? getLatestData() => _history.last; + +} \ No newline at end of file diff --git a/lib/widgets/shimmer/dashboard_shimmer_widget.dart b/lib/widgets/shimmer/dashboard_shimmer_widget.dart index 1c63d71..5b5bd60 100644 --- a/lib/widgets/shimmer/dashboard_shimmer_widget.dart +++ b/lib/widgets/shimmer/dashboard_shimmer_widget.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; @@ -62,7 +63,9 @@ class GetAttendanceTrackingShimmer extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white).toShimmer(),], + children: [ + LocaleKeys.checkIn.tr().toText12(color: Colors.white).toShimmer(), + ], ).paddingOnly(left: 12), ), Container( @@ -80,3 +83,107 @@ class GetAttendanceTrackingShimmer extends StatelessWidget { ); } } + +class MenuShimmer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.workList.tr().toText12(color: Colors.white).toShimmer(), + Row( + children: [ + Expanded( + flex: 3, + child: 123.toString().toText10(color: Colors.white, isBold: true).toShimmer(), + ), + 12.width, + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white).toShimmer() + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ); + } +} + +class ServicesHeaderShimmer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + "Other".tr().toText10().toShimmer(), + 6.height, + LocaleKeys.services.tr().toText12(isBold: true).toShimmer(), + ], + ), + ), + LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true).toShimmer(), + ], + ); + } +} + +class ServicesMenuShimmer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset("assets/images/monthly_attendance.svg").toShimmer(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + "Attendan".toText11(isBold: false).toShimmer(), + 5.height, + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: "Attendance".toText11(isBold: false).toShimmer(), + ), + 6.width, + SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4).toShimmer() + ], + ), + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ); + } +} From 6b9ea200adb5a51e79ef31dd49c4750fc3cd25ca Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 13 Feb 2022 11:44:49 +0300 Subject: [PATCH 09/22] login flow added. --- android/app/build.gradle | 5 +- android/app/google-services.json | 40 + android/app/src/main/AndroidManifest.xml | 3 +- .../com/mohem_flutter_app/MainActivity.kt | 17 +- android/build.gradle | 1 + assets/langs/ar-SA.json | 11 + assets/langs/en-US.json | 11 + lib/api/login_api_client.dart | 37 +- lib/app_state/app_state.dart | 20 + lib/classes/consts.dart | 9 +- lib/classes/utils.dart | 21 + lib/config/routes.dart | 3 + lib/generated/codegen_loader.g.dart | 22 + lib/main.dart | 3 +- lib/models/generic_response_model.dart | 14 +- .../get_mobile_login_info_list_model.dart | 64 ++ lib/models/member_information_list_model.dart | 17 + lib/models/privilege_list_model.dart | 17 + lib/ui/login/forgot_password_screen.dart | 37 +- lib/ui/login/login_screen.dart | 75 +- lib/ui/login/new_password_screen.dart | 184 +++-- lib/ui/login/verify_last_login_screen.dart | 750 ++++++++++++++++++ lib/ui/login/verify_login_screen.dart | 241 +++--- lib/widgets/dialogs/confirm_dialog.dart | 66 ++ lib/widgets/input_widget.dart | 22 +- pubspec.yaml | 2 + 26 files changed, 1504 insertions(+), 188 deletions(-) create mode 100644 android/app/google-services.json create mode 100644 lib/models/get_mobile_login_info_list_model.dart create mode 100644 lib/ui/login/verify_last_login_screen.dart create mode 100644 lib/widgets/dialogs/confirm_dialog.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 4e4b395..596d981 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -23,6 +23,7 @@ if (flutterVersionName == null) { apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +apply plugin: 'com.google.gms.google-services' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { @@ -43,8 +44,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.mohem_flutter_app" - minSdkVersion 16 + applicationId "hmg.cloudSolutions.mohem" + minSdkVersion 21 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..62fbaea --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,40 @@ +{ + "project_info": { + "project_number": "679409052782", + "firebase_url": "https://mohemm-dce93.firebaseio.com", + "project_id": "mohemm-dce93", + "storage_bucket": "mohemm-dce93.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:679409052782:android:dba155ac0859d7fea78a7f", + "android_client_info": { + "package_name": "hmg.cloudSolutions.mohem" + } + }, + "oauth_client": [ + { + "client_id": "679409052782-mtd6d8rjltucnm9uatn6g7et08sm6lbv.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDgWjuSBIKGghWxYg_KGBRIZTi-O_UA8mU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "679409052782-mtd6d8rjltucnm9uatn6g7et08sm6lbv.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 472e794..8d53eaf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,9 @@ + _instance; + Future getMobileLoginInfoNEW(String deviceToken, String deviceType) async { + String url = "${ApiConsts.erpRest}Mohemm_GetMobileLoginInfo_NEW"; + Map postParams = {}; + postParams["DeviceToken"] = deviceToken; + postParams["DeviceType"] = deviceType; + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return (responseData.mohemmGetMobileLoginInfoList?.length ?? 0) > 0 ? responseData.mohemmGetMobileLoginInfoList!.first : null; + }, url, postParams); + } + + Future insertMobileLoginInfoNEW( + String email, int sessionId, String employeeName, int loginType, String mobileNumber, String userName, String deviceToken, String deviceType) async { + String url = "${ApiConsts.erpRest}Mohemm_InsertMobileLoginInfo"; + Map postParams = { + "MobileNumber": mobileNumber, + "P_USER_NAME": userName, + "UserName": userName, + "CompanyID": 1, // todo 'sikander' @discuss umer for companyID + "DeviceToken": deviceToken, + "LoginType": loginType, + "EmployeeName": employeeName, + "P_SESSION_ID": sessionId, + "P_EMAIL_ADDRESS": email + }; + postParams["DeviceToken"] = deviceToken; + postParams["DeviceType"] = deviceType; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + Future checkMobileAppVersion() async { String url = "${ApiConsts.utilitiesRest}CheckMobileAppVersion"; Map postParams = {}; @@ -76,7 +111,7 @@ class LoginApiClient { postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); - AppState().setForgetPasswordTokenID = responseData.tokenID; + AppState().setForgetPasswordTokenID = responseData.forgetPasswordTokenID; return responseData; }, url, postParams); } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 2af87d8..1c7f5b0 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -1,5 +1,8 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; +import 'package:mohem_flutter_app/models/privilege_list_model.dart'; class AppState { static final AppState _instance = AppState._internal(); @@ -24,13 +27,30 @@ class AppState { this._postParams = _postParams; } + bool isArabic(context) => EasyLocalization.of(context)?.locale.languageCode == "ar"; + String? username; + // todo ''sikander' added password for now, later will remove & improve + String? password; set setUserName(_username) => username = _username; + set setUserPassword(_password) => password = _password; MemberLoginListModel? _memberLoginList; MemberLoginListModel? get memberLoginList => _memberLoginList; set setMemberLoginListModel(MemberLoginListModel? _memberLoginList) => this._memberLoginList = _memberLoginList; + + MemberInformationListModel? _memberInformationList; + + MemberInformationListModel? get memberInformationList => _memberInformationList; + + set setMemberInformationListModel(MemberInformationListModel? _memberInformationList) => this._memberInformationList = _memberInformationList; + + List? _privilegeListModel; + + List? get privilegeListModel => _privilegeListModel; + + set setPrivilegeListModel(List? _privilegeListModel) => this._privilegeListModel = _privilegeListModel; } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index b0453c0..8177750 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -8,12 +8,13 @@ class ApiConsts { static String user = baseUrlServices + "api/User/"; } -class GlobalConsts { +class SharedPrefsConsts { static String isRememberMe = "remember_me"; - static String email = "email"; + static String username = "username"; static String password = "password"; - static String bookmark = "bookmark"; - static String fontZoomSize = "font_zoom_size"; + static String privilegeList = "privilegeList"; + static String firebaseToken = "firebaseToken"; + static String memberInformation = "memberInformation"; static String welcomeVideoUrl = "welcomeVideoUrl"; static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo"; } diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index d80fdf5..ae8041f 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -3,7 +3,9 @@ import 'package:fluttertoast/fluttertoast.dart'; // import 'package:fluttertoast/fluttertoast.dart'; import 'package:mohem_flutter_app/exceptions/api_exception.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:mohem_flutter_app/widgets/loading_dialog.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class Utils { static bool _isLoadingVisible = false; @@ -52,6 +54,16 @@ class Utils { _isLoadingVisible = false; } + static Future getStringFromPrefs(String key) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return prefs.getString(key) ?? ""; + } + + static Future saveStringFromPrefs(String key, String value) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return await prefs.setString(key, value); + } + static void handleException(dynamic exception, Function(String)? onErrorMessage) { String errorMessage; if (exception is APIException) { @@ -69,4 +81,13 @@ class Utils { showToast(errorMessage); } } + + static void confirmDialog(cxt, String message) { + showDialog( + context: cxt, + builder: (cxt) => ConfirmDialog( + message: message, + ), + ); + } } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 39a4ebc..f0362d9 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -4,6 +4,7 @@ import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart'; import 'package:mohem_flutter_app/ui/login/forgot_password_screen.dart'; import 'package:mohem_flutter_app/ui/login/login_screen.dart'; import 'package:mohem_flutter_app/ui/login/new_password_screen.dart'; +import 'package:mohem_flutter_app/ui/login/verify_last_login_screen.dart'; import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/missing_swipe_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart'; @@ -14,6 +15,7 @@ class AppRoutes { static const String loginVerifyAccount = "/loginVerifyAccount"; static const String login = "/login"; static const String verifyLogin = "/verifyLogin"; + static const String verifyLastLogin = "/verifyLastLogin"; static const String forgotPassword = "/forgotPassword"; static const String newPassword = "/newPassword"; static const String loginVerification = "/loginVerification"; @@ -28,6 +30,7 @@ class AppRoutes { static final Map routes = { login: (context) => LoginScreen(), verifyLogin: (context) => VerifyLoginScreen(), + verifyLastLogin: (context) => VerifyLastLoginScreen(), dashboard: (context) => Dashboard(), newPassword: (context) => NewPasswordScreen(), forgotPassword: (context) => ForgotPasswordScreen(), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index b43f3bd..3d67def 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -64,7 +64,18 @@ class CodegenLoader extends AssetLoader{ "employeeId": "هوية الموظف", "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", "changePassword": "تغيير كلمة المرور", + "ok": "موافق", + "confirm": "تؤكد", + "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", "itemsForSale": "سلع للبيع", + "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", + "atLeastOneLowercase": "حرف صغير واحد على الأقل", + "atLeastOneUppercase": "حرف كبير واحد على الأقل", + "atLeastOneNumeric": "رقم واحد على الأقل", + "minimum8Characters": "8 أحرف على الأقل", + "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", + "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", + "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", @@ -153,7 +164,18 @@ static const Map en_US = { "employeeId": "Employee ID", "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", "changePassword": "Change Password", + "ok": "OK", + "confirm": "Confirm", + "passwordChangedSuccessfully": "Password changed successfully", "itemsForSale": "Items for Sale", + "doNotUseRecentPassword": "Do not use recent password", + "atLeastOneLowercase": "At least one lowercase", + "atLeastOneUppercase": "At least one uppercase", + "atLeastOneNumeric": "At least one numeric", + "minimum8Characters": "Minimum 8 characters", + "doNotAddRepeatingLetters": "Do not add repeating letters", + "itShouldContainSpecialCharacter": "It should contain special character", + "confirmPasswordMustMatch": "Confirm password must match", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/main.dart b/lib/main.dart index 99cff95..7276ac0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,12 +8,13 @@ import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; import 'package:mohem_flutter_app/theme/app_theme.dart'; import 'package:sizer/sizer.dart'; - +import 'package:firebase_core/firebase_core.dart'; import 'config/routes.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); + await Firebase.initializeApp(); runApp( EasyLocalization( supportedLocales: const [ diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index b993db8..8e60858 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,6 +1,7 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'basic_member_information_model.dart'; +import 'get_mobile_login_info_list_model.dart'; import 'member_information_list_model.dart'; import 'privilege_list_model.dart'; @@ -174,7 +175,7 @@ class GenericResponseModel { String? mohemmGetBusinessCardEnabledList; List? mohemmGetFavoriteReplacementsList; String? mohemmGetMobileDeviceInfobyEmpInfoList; - String? mohemmGetMobileLoginInfoList; + List? mohemmGetMobileLoginInfoList; String? mohemmGetPatientIDList; String? mohemmITGResponseItem; bool? mohemmIsChangeIsActiveBusinessCardEnable; @@ -685,7 +686,12 @@ class GenericResponseModel { mohemmGetBusinessCardEnabledList = json['Mohemm_GetBusinessCardEnabledList']; mohemmGetFavoriteReplacementsList = json['Mohemm_GetFavoriteReplacementsList']; mohemmGetMobileDeviceInfobyEmpInfoList = json['Mohemm_GetMobileDeviceInfobyEmpInfoList']; - mohemmGetMobileLoginInfoList = json['Mohemm_GetMobileLoginInfoList']; + if (json['Mohemm_GetMobileLoginInfoList'] != null) { + mohemmGetMobileLoginInfoList = []; + json['Mohemm_GetMobileLoginInfoList'].forEach((v) { + mohemmGetMobileLoginInfoList!.add(new GetMobileLoginInfoListModel.fromJson(v)); + }); + } mohemmGetPatientIDList = json['Mohemm_GetPatientID_List']; mohemmITGResponseItem = json['Mohemm_ITG_ResponseItem']; mohemmIsChangeIsActiveBusinessCardEnable = json['Mohemm_IsChangeIsActiveBusinessCardEnable']; @@ -951,7 +957,9 @@ class GenericResponseModel { data['Mohemm_GetBusinessCardEnabledList'] = this.mohemmGetBusinessCardEnabledList; data['Mohemm_GetFavoriteReplacementsList'] = this.mohemmGetFavoriteReplacementsList; data['Mohemm_GetMobileDeviceInfobyEmpInfoList'] = this.mohemmGetMobileDeviceInfobyEmpInfoList; - data['Mohemm_GetMobileLoginInfoList'] = this.mohemmGetMobileLoginInfoList; + if (this.mohemmGetMobileLoginInfoList != null) { + data['Mohemm_GetMobileLoginInfoList'] = this.mohemmGetMobileLoginInfoList!.map((v) => v.toJson()).toList(); + } data['Mohemm_GetPatientID_List'] = this.mohemmGetPatientIDList; data['Mohemm_ITG_ResponseItem'] = this.mohemmITGResponseItem; data['Mohemm_IsChangeIsActiveBusinessCardEnable'] = this.mohemmIsChangeIsActiveBusinessCardEnable; diff --git a/lib/models/get_mobile_login_info_list_model.dart b/lib/models/get_mobile_login_info_list_model.dart new file mode 100644 index 0000000..ff419f2 --- /dev/null +++ b/lib/models/get_mobile_login_info_list_model.dart @@ -0,0 +1,64 @@ +class GetMobileLoginInfoListModel { + int? iD; + int? employeeID; + int? channelID; + int? companyID; + String? deviceType; + String? deviceToken; + int? language; + int? gender; + int? loginType; + String? createdOn; + String? editedOn; + String? employeeName; + bool? businessCardPrivilege; + + GetMobileLoginInfoListModel( + {this.iD, + this.employeeID, + this.channelID, + this.companyID, + this.deviceType, + this.deviceToken, + this.language, + this.gender, + this.loginType, + this.createdOn, + this.editedOn, + this.employeeName, + this.businessCardPrivilege}); + + GetMobileLoginInfoListModel.fromJson(Map json) { + iD = json['ID']; + employeeID = json['EmployeeID']; + channelID = json['ChannelID']; + companyID = json['CompanyID']; + deviceType = json['DeviceType']; + deviceToken = json['DeviceToken']; + language = json['Language']; + gender = json['Gender']; + loginType = json['LoginType']; + createdOn = json['CreatedOn']; + editedOn = json['EditedOn']; + employeeName = json['EmployeeName']; + businessCardPrivilege = json['BusinessCardPrivilege']; + } + + Map toJson() { + final Map data = Map(); + data['ID'] = iD; + data['EmployeeID'] = employeeID; + data['ChannelID'] = channelID; + data['CompanyID'] = companyID; + data['DeviceType'] = deviceType; + data['DeviceToken'] = deviceToken; + data['Language'] = language; + data['Gender'] = gender; + data['LoginType'] = loginType; + data['CreatedOn'] = createdOn; + data['EditedOn'] = editedOn; + data['EmployeeName'] = employeeName; + data['BusinessCardPrivilege'] = businessCardPrivilege; + return data; + } +} diff --git a/lib/models/member_information_list_model.dart b/lib/models/member_information_list_model.dart index a3bc05f..da95ed0 100644 --- a/lib/models/member_information_list_model.dart +++ b/lib/models/member_information_list_model.dart @@ -1,3 +1,8 @@ +import 'dart:convert'; + +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + class MemberInformationListModel { String? aCTUALTERMINATIONDATE; String? aSSIGNMENTENDDATE; @@ -333,4 +338,16 @@ class MemberInformationListModel { data['USER_STATUS'] = this.uSERSTATUS; return data; } + + static Future> getFromPrefs() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + List encodedList = prefs.getStringList(SharedPrefsConsts.memberInformation) ?? []; + return encodedList.map((e) => MemberInformationListModel.fromJson(jsonDecode(e))).toList(); + } + + static void saveToPrefs(List list) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + List encodedList = list.map((e) => jsonEncode(e.toJson())).toList(); + await prefs.setStringList(SharedPrefsConsts.memberInformation, encodedList); + } } \ No newline at end of file diff --git a/lib/models/privilege_list_model.dart b/lib/models/privilege_list_model.dart index 3ef3954..ad83500 100644 --- a/lib/models/privilege_list_model.dart +++ b/lib/models/privilege_list_model.dart @@ -1,3 +1,8 @@ +import 'dart:convert'; + +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + class PrivilegeListModel { int? iD; String? serviceName; @@ -18,4 +23,16 @@ class PrivilegeListModel { data['Previlege'] = this.previlege; return data; } + + static Future> getFromPrefs() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + List encodedList = prefs.getStringList(SharedPrefsConsts.privilegeList) ?? []; + return encodedList.map((e) => PrivilegeListModel.fromJson(jsonDecode(e))).toList(); + } + + static void saveToPrefs(List list) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + List encodedList = list.map((e) => jsonEncode(e.toJson())).toList(); + await prefs.setStringList(SharedPrefsConsts.privilegeList, encodedList); + } } diff --git a/lib/ui/login/forgot_password_screen.dart b/lib/ui/login/forgot_password_screen.dart index 89bd66e..17b105f 100644 --- a/lib/ui/login/forgot_password_screen.dart +++ b/lib/ui/login/forgot_password_screen.dart @@ -37,24 +37,30 @@ class _ForgotPasswordScreenState extends State { super.dispose(); } - void performLogin() async { - // Utils.showLoading(context); + void performForgotPassword() async { + if (employeeId.text.isEmpty) { + return; + } + Utils.showLoading(context); try { _basicMemberInformation = await LoginApiClient().getBasicUserInformation("CS", employeeId.text); genericResponseModel = await LoginApiClient().sendPublicActivationCode(_basicMemberInformation?.pMOBILENUMBER, employeeId.text); + Utils.hideLoading(context); OtpDialog( context, 1, int.tryParse(_basicMemberInformation?.pMOBILENUMBER ?? ""), (value) async { + Utils.showLoading(context); GenericResponseModel? genericResponseModel = await LoginApiClient().checkPublicActivationCode(value, employeeId.text); if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); return; } - - Navigator.pushNamed(context, AppRoutes.newPassword); - // this.checkActivationCode(value: value); + Utils.hideLoading(context); + await Navigator.pushNamed(context, AppRoutes.newPassword, arguments: employeeId.text); + Navigator.pop(context); + Navigator.pop(context); }, () => { Navigator.pop(context), @@ -62,8 +68,8 @@ class _ForgotPasswordScreenState extends State { ).displayDialog(context); } catch (ex) { print(ex); + Utils.hideLoading(context); Utils.handleException(ex, null); - // Utils.hideLoading(context); } } @@ -95,7 +101,14 @@ class _ForgotPasswordScreenState extends State { LocaleKeys.forgotPassword.tr().toText24(isBold: true), LocaleKeys.loginCodeWillSentToMobileNumber.tr().toText16(), 16.height, - InputWidget(LocaleKeys.employeeId.tr(), "123456", employeeId), + InputWidget( + LocaleKeys.employeeId.tr(), + "123456", + employeeId, + onChange: (value) { + setState(() {}); + }, + ), ], ), ) @@ -103,9 +116,13 @@ class _ForgotPasswordScreenState extends State { ), ), ), - DefaultButton(LocaleKeys.changePassword.tr(), () async { - //Navigator.pushNamed(context, AppRoutes.verifyLogin); - }) + DefaultButton( + LocaleKeys.changePassword.tr(), + employeeId.text.isEmpty + ? null + : () async { + performForgotPassword(); + }) .insideContainer ], ), diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 5f0f266..d7c91ee 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -1,11 +1,15 @@ +import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/src/public_ext.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; @@ -13,7 +17,10 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; +import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; +import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; @@ -33,9 +40,15 @@ class _LoginScreenState extends State { CheckMobileAppVersionModel? _checkMobileAppVersion; MemberLoginListModel? _memberLoginList; + final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; + + bool _autoLogin = false; + @override void initState() { super.initState(); + checkFirebaseToken(); + //checkPrefs(); } @override @@ -43,6 +56,48 @@ class _LoginScreenState extends State { super.dispose(); } + Future checkPrefs() async { + String username = await Utils.getStringFromPrefs(SharedPrefsConsts.username); + if (username.isNotEmpty) { + String password = await Utils.getStringFromPrefs(SharedPrefsConsts.password); + // String firebaseToken = await Utils.getStringFromPrefs(SharedPrefsConsts.firebaseToken); + // print("firebaseToken:$firebaseToken"); + this.username.text = username; + this.password.text = password; + _autoLogin = true; + } + } + + String? firebaseToken; + + Future checkFirebaseToken() async { + try { + Utils.showLoading(context); + firebaseToken = await _firebaseMessaging.getToken(); + GetMobileLoginInfoListModel? loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + if (loginInfo == null) { + Utils.hideLoading(context); + print("Device token not found"); + return; + } else { + await checkPrefs(); + Utils.hideLoading(context); + performLogin(); + } + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, null); + } + } + + // Future getFirebaseToken() async { + // String? firebaseToken = await _firebaseMessaging.getToken(); + // if (firebaseToken != null) { + // await Utils.saveStringFromPrefs(SharedPrefsConsts.firebaseToken, firebaseToken); + // } + // } + void performLogin() async { Utils.showLoading(context); try { @@ -50,13 +105,23 @@ class _LoginScreenState extends State { _memberLoginList = await LoginApiClient().memberLogin(username.text, password.text); AppState().setMemberLoginListModel = _memberLoginList; AppState().username = username.text; - print(_memberLoginList?.toJson()); + AppState().password = password.text; + if (_autoLogin) { + AppState().setMemberInformationListModel = (await MemberInformationListModel.getFromPrefs()).first; + AppState().setPrivilegeListModel = await PrivilegeListModel.getFromPrefs(); + } Utils.hideLoading(context); - Navigator.pushNamed(context, AppRoutes.verifyLogin); + if (_autoLogin) { + Navigator.pushNamed(context, AppRoutes.verifyLastLogin); + } else { + Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken"); + } } catch (ex) { print(ex); - Utils.handleException(ex, null); Utils.hideLoading(context); + Utils.handleException(ex, (msg) { + Utils.confirmDialog(context, msg); + }); } } @@ -77,7 +142,7 @@ class _LoginScreenState extends State { Expanded(child: SizedBox()), Row( children: [ - LocaleKeys.english.tr().toText14(color: MyColors.textMixColor).onPress(() { + LocaleKeys.english.tr().toText14(color: AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() { context.setLocale(const Locale("en", "US")); }), Container( @@ -86,7 +151,7 @@ class _LoginScreenState extends State { height: 16, margin: const EdgeInsets.only(left: 10, right: 10), ), - LocaleKeys.arabic.tr().toText14().onPress(() { + LocaleKeys.arabic.tr().toText14(color: !AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() { context.setLocale(const Locale("ar", "SA")); }), ], diff --git a/lib/ui/login/new_password_screen.dart b/lib/ui/login/new_password_screen.dart index 3fc37f1..e0a8f94 100644 --- a/lib/ui/login/new_password_screen.dart +++ b/lib/ui/login/new_password_screen.dart @@ -1,7 +1,9 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/login_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; -import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; @@ -22,6 +24,8 @@ class _NewPasswordScreenState extends State { TextEditingController password = TextEditingController(); TextEditingController confirmPassword = TextEditingController(); + String? userName; + @override void initState() { super.initState(); @@ -32,8 +36,26 @@ class _NewPasswordScreenState extends State { super.dispose(); } + void setNewPassword() async { + Utils.showLoading(context); + try { + var genericResponseModel = await LoginApiClient().changePasswordForget(AppState().getForgetPasswordTokenID ?? "", password.text, confirmPassword.text, userName); + Utils.hideLoading(context); + Utils.showToast(LocaleKeys.passwordChangedSuccessfully.tr()); + Navigator.pop(context); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, (msg) { + Utils.confirmDialog(context, msg); + }); + } + } + @override Widget build(BuildContext context) { + userName ??= ModalRoute.of(context)!.settings.arguments as String; + return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, @@ -46,53 +68,125 @@ class _NewPasswordScreenState extends State { children: [ //const SizedBox(height: 23), Expanded( - child: Padding( - padding: const EdgeInsets.all(21.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Row( - // children: [ - // Expanded(child: SizedBox()), - // Row( - // children: [ - // LocaleKeys.english.tr().toText14(color: MyColors.textMixColor).onPress(() {}), - // Container( - // width: 1, - // color: MyColors.darkWhiteColor, - // height: 16, - // margin: const EdgeInsets.only(left: 10, right: 10), - // ), - // LocaleKeys.arabic.tr().toText14().onPress(() {}), - // ], - // ), - // ], - // ), - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - LocaleKeys.setTheNewPassword.tr().toText24(isBold: true), - LocaleKeys.typeYourNewPasswordBelow.tr().toText16(), - 16.height, - InputWidget(LocaleKeys.password.tr(), "**********", password), - 12.height, - InputWidget(LocaleKeys.confirmPassword.tr(), "**********", confirmPassword, isObscureText: true) - ], - ), - ) - ], - ), - ), + child: ListView( + // mainAxisSize: MainAxisSize.min, + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + LocaleKeys.setTheNewPassword.tr().toText24(isBold: true), + LocaleKeys.typeYourNewPasswordBelow.tr().toText16(), + 16.height, + InputWidget( + LocaleKeys.password.tr(), + "**********", + password, + onChange: (value) { + setState(() {}); + }, + ), + 12.height, + InputWidget( + LocaleKeys.confirmPassword.tr(), + "**********", + confirmPassword, + isObscureText: true, + onChange: (value) { + setState(() {}); + }, + ), + 12.height, + passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true), + 8.height, + passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')), + 8.height, + passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')), + 8.height, + passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')), + 8.height, + passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8), + 8.height, + passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)), + 8.height, + passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')), + 8.height, + passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text), + 12.height, + ], + ).paddingAll(21), ), - DefaultButton(LocaleKeys.update.tr(), () async { - - // Navigator.pushNamed(context, AppRoutes.verifyLogin); - }).insideContainer + DefaultButton( + LocaleKeys.update.tr(), + (!isPasswordCompliant(password.text, 8)) + ? null + : () async { + setNewPassword(); + }) + .insideContainer ], ), ); } + + bool checkRegEx(String pattern) { + return RegExp(pattern).hasMatch(password.text); + } + + String recentPassword = ""; + + bool checkRepeatedCharacters(String value) { + if (value.isEmpty) { + return false; + } + for (int i = 0; i < value.length; i++) { + //if(i) + } + + return true; + } + + bool isPasswordCompliant(String? password, int minLength) { + if (password == null || password.isEmpty) { + return false; + } + + bool hasUppercase = password.contains(RegExp(r'[A-Z]')); + bool hasDigits = password.contains(RegExp(r'[0-9]')); + bool hasLowercase = password.contains(RegExp(r'[a-z]')); + bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]')); + bool hasMinLength = password.length >= minLength; + bool isMatched = password == confirmPassword.text; + + return hasDigits && hasUppercase && hasLowercase && hasSpecialCharacters && hasMinLength && isMatched && checkRepeatedChars(password); + } + + bool checkRepeatedChars(String password) { + bool isNonRepeatedLetters = true; + if (password.length > 2) { + for (int i = 0; i < password.length; i++) { + String char = password[i]; + try { + if (char == password[i + 1]) { + isNonRepeatedLetters = false; + break; + } + } catch (ex) {} + } + } + return isNonRepeatedLetters; + } + + Widget passwordConstraintsUI(String description, bool check) { + return Row( + children: [ + 4.width, + SizedBox( + width: 12, + height: 12, + child: Checkbox(fillColor: MaterialStateProperty.all(MyColors.gradiantEndColor), shape: const CircleBorder(), value: check, onChanged: null), + ), + 8.width, + description.toText14() + ], + ); + } } diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart new file mode 100644 index 0000000..0c8554f --- /dev/null +++ b/lib/ui/login/verify_last_login_screen.dart @@ -0,0 +1,750 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:local_auth/auth_strings.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:mohem_flutter_app/api/login_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; + +class VerifyLastLoginScreen extends StatefulWidget { + VerifyLastLoginScreen({Key? key}) : super(key: key); + + @override + _VerifyLastLoginScreenState createState() { + return _VerifyLastLoginScreenState(); + } +} + +class _VerifyLastLoginScreenState extends State { + final LocalAuthentication auth = LocalAuthentication(); + List _availableBioMetricType = []; + + @override + void initState() { + _getAvailableBiometrics(); + // setDefault(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + String empName = AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!; + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], + ), + body: Column( + children: [ + Expanded( + child: ListView( + padding: const EdgeInsets.all(21), + physics: const BouncingScrollPhysics(), + children: [ + //12.height, + if (true) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.welcomeBack.tr().toText12(), + empName.toText24(isBold: true), + 10.height, + LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), + Container( + height: 72, + margin: const EdgeInsets.only(top: 23, bottom: 23), + alignment: Alignment.center, + padding: const EdgeInsets.only(left: 17, right: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: const Color(0xffefefef), + width: 1, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LocaleKeys.lastLoginDetails.tr().toText16(), + // Text( + // user.editedOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) + // : user.createdOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn)) + // : '--', + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + // ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), + Text( + "SMS", + // " " + getType(user.logInType, context), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + ), + ), + Expanded(child: SizedBox()), + // Text( + // user.editedOn != null + // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false) + // : user.createdOn != null + // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false) + // : '--', + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), + // ), + ], + ) + ], + ), + ), + LocaleKeys.pleaseVerify.tr().toText16(), + GridView( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.only(top: 9), + shrinkWrap: true, + children: [ + getButton(3), + getButton(2), + getButton(1), + getButton(4), + ], + ) + ], + ) + // else + // Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + // Image.asset( + // 'assets/images/habib-logo.png', + // height: 90, + // width: 90, + // ), + // SizedBox(height: 23), + // this.onlySMSBox == false + // ? Text( + // TranslationBase.of(context).verifyLoginWith, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + // ) + // : Text( + // TranslationBase.of(context).verifyFingerprint2, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + // ), + // SizedBox(height: 23), + // Text( + // TranslationBase.of(context).pleaseVerify, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + // ), + // GridView( + // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + // physics: NeverScrollableScrollPhysics(), + // padding: EdgeInsets.only(top: 9), + // shrinkWrap: true, + // children: [ + // if (onlySMSBox == false) getButton(3), + // if (onlySMSBox == false) getButton(2), + // getButton(1), + // getButton(4), + // ], + // ), + // ]), + ], + ), + ), + 12.height, + DefaultButton( + LocaleKeys.useAnotherAccount.tr(), + () => { + //Navigator.of(context).pushNamed(LOGIN_TYPE) + }, + ).insideContainer, + ], + ), + ); + } + + Future _getAvailableBiometrics() async { + try { + _availableBioMetricType = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + // AppToast.showErrorToast(message: e.message); + print(e); + } + if (mounted) setState(() {}); + } + + // authenticateUser(int type, {int isActive}) { + // GifLoaderDialogUtils.showMyDialog(context); + // if (type == 2 || type == 3) { + // fingrePrintBefore = type; + // } + // this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; + // + // switch (type) { + // case 1: + // this.loginWithSMS(type); + // break; + // case 2: + // this.loginWithFingurePrintFace(type, isActive); + // break; + // case 3: + // this.loginWithFingurePrintFace(type, isActive); + // break; + // case 4: + // this.loginWithSMS(type); + // break; + // default: + // break; + // } + // sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); + // } +// +// loginWithSMS(type) { +// //if (!el.disabled) { +// if (this.user != null && this.registerd_data == null) { +// this.checkUserAuthentication(type); +// } else { +// if (this.loginTokenID != null) { +// // Future.delayed(Duration(seconds: 1), () { +// this.sendActivationCode(type); +// // }); +// } else { +// this.checkUserAuthentication(type); +// } +// } +// } +// +// checkUserAuthentication(type) { +// showLoader(true); +// var req = getCommonRequest(type: type); +// req.logInTokenID = ""; +// +// var request = CheckPatientAuthenticationReq.fromJson(req.toJson()); +// +// sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); +// authService +// .checkPatientAuthentication(request) +// .then((value) => { +// GifLoaderDialogUtils.hideDialog(context), +// if (value['isSMSSent']) +// { +// sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), +// this.loginTokenID = value['LogInTokenID'], +// sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), +// // Future.delayed(Duration(seconds: 1), () { +// this.sendActivationCode(type) +// // }) +// } +// else +// { +// if (value['IsAuthenticated']) {this.checkActivationCode()} +// } +// }) +// .catchError((err) { +// print(err); +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } +// +// sendActivationCode(type) async { +// var request = this.getCommonRequest(type: type); +// request.sMSSignature = await SMSOTP.getSignature(); +// GifLoaderDialogUtils.showMyDialog(context); +// if (healthId != null) { +// // final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); +// // final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); +// request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); +// request.healthId = healthId; +// request.isHijri = isHijri; +// await this.authService.sendActivationCodeRegister(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result != null && result['isSMSSent'] == true) { +// this.startSMSService(type); +// } +// }).catchError((r) { +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } else { +// request.dob = ""; +// request.healthId = ""; +// request.isHijri = 0; +// await this.authService.sendActivationCode(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result != null && result['isSMSSent'] == true) { +// this.startSMSService(type); +// } +// }).catchError((r) { +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } +// } +// +// var tempType; +// +// startSMSService(type) { +// tempType = type; +// new SMSOTP( +// context, +// type, +// this.mobileNumber, +// (value) { +// this.checkActivationCode(value: value); +// }, +// () => { +// Navigator.pop(context), +// }, +// ).displayDialog(context); +// } +// +// loginWithFingurePrintFace(type, int isActive) async { +// if (isActive == 1 || isActive == 0) { +// const iosStrings = +// const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); +// +// try { +// authenticated = await auth.authenticateWithBiometrics(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); +// } on PlatformException catch (e) { +// GifLoaderDialogUtils.hideDialog(context); +// AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); +// } +// +// if (authenticated == true) { +// // if (user != null && (user.logInType == 2 || user.logInType == 3)) { +// // this.checkActivationCode(); +// // } else { +// +// var request = this.getCommonRequest(type: type); +// this.getMobileInfo(request); +// //} +// } +// } +// } +// +// getMobileInfo(request) { +// // GifLoaderDialogUtils.showMyDialog(context); +// this.authService.getLoginInfo(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result['SMSLoginRequired'] == false) { +// this.loginTokenID = result['LogInTokenID']; +// this.patientOutSA = result['PatientOutSA']; +// // sms for register the biometric +// if (result['isSMSSent']) { +// setState(() { +// isMoreOption = true; +// this.onlySMSBox = true; +// // this.fingrePrintBefore = true; +// }); +// //this.button(); +// } else { +// setDefault(); +// checkActivationCode(); +// } +// } else { +// if (result['IsAuthenticated'] == true) { +// setState(() { +// isMoreOption = true; +// this.onlySMSBox = true; +// // this.fingrePrintBefore = true; +// }); +// } +// } +// }).catchError((err) { +// GifLoaderDialogUtils.hideDialog(context); +// print(err); +// }); +// } +// +// setDefault() async { +// if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); +// +// if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { +// isMoreOption = true; +// this.registerd_data = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); +// } +// +// this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.mobile); +// this.zipCode = this.registerd_data != null +// ? this.registerd_data.zipCode +// : this.user.outSA == true +// ? "971" +// : "966"; +// this.patientOutSA = this.registerd_data != null +// ? this.registerd_data.zipCode == "966" +// ? 0 +// : 1 +// : this.user.outSA; +// if (this.registerd_data != null) { +// this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); +// this.loginType = this.registerd_data.searchType; +// } +// var nhic = await sharedPref.getObject(NHIC_DATA); +// if (nhic != null) { +// final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); +// final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); +// dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); +// +// isHijri = nhic['IsHijri'] ? 1 : 0; +// healthId = nhic['HealthId']; +// } +// this.deviceToken = await sharedPref.getString(PUSH_TOKEN); +// this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null +// ? await sharedPref.getInt(LAST_LOGIN) +// : user != null +// ? user.logInType +// : null; +// +// //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); +// } +// +// getCommonRequest({type}) { +// var request = SendActivationRequest(); +// request.patientMobileNumber = this.mobileNumber; +// request.mobileNo = '0' + this.mobileNumber.toString(); +// request.deviceToken = this.deviceToken; +// request.projectOutSA = this.patientOutSA == true ? true : false; +// request.loginType = this.selectedOption; +// request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; +// request.zipCode = this.zipCode; +// +// request.logInTokenID = this.loginTokenID ?? ""; +// +// if (this.registerd_data != null) { +// request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; +// request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; +// request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; +// +// request.isRegister = this.registerd_data.isRegister; +// } else { +// request.searchType = request.searchType != null ? request.searchType : 2; +// request.patientID = this.user.patientID != null ? this.user.patientID : 0; +// request.nationalID = request.nationalID != null ? request.nationalID : '0'; +// request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; +// request.isRegister = false; +// } +// request.deviceTypeID = request.searchType; +// return request; +// } +// +// // checkActivationCode({value}) async { +// // // Navigator.pop(context); +// // GifLoaderDialogUtils.showMyDialog(context); +// // var request = this.getCommonRequest().toJson(); +// // dynamic res; +// // if (healthId != null) { +// // request['DOB'] = dob; +// // request['HealthId'] = healthId; +// // request['IsHijri'] = isHijri; +// // +// // authService +// // .checkActivationCodeRegister(request, value) +// // .then((result) => { +// // res = result, +// // if (result is Map) +// // { +// // result = CheckActivationCode.fromJson(result), +// // if (this.registerd_data != null && this.registerd_data.isRegister == true) +// // { +// // widget.changePageViewIndex(1), +// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), +// // } +// // } +// // else +// // { +// // // Navigator.of(context).pop(), +// // GifLoaderDialogUtils.hideDialog(context), +// // Future.delayed(Duration(seconds: 1), () { +// // AppToast.showErrorToast(message: result); +// // }), +// // } +// // }) +// // .catchError((err) { +// // print(err); +// // GifLoaderDialogUtils.hideDialog(context); +// // Future.delayed(Duration(seconds: 1), () { +// // AppToast.showErrorToast(message: err); +// // startSMSService(tempType); +// // }); +// // }); +// // } else { +// // authService +// // .checkActivationCode(request, value) +// // .then((result) => { +// // res = result, +// // if (result is Map) +// // { +// // result = CheckActivationCode.fromJson(result), +// // if (this.registerd_data != null && this.registerd_data.isRegister == true) +// // { +// // widget.changePageViewIndex(1), +// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), +// // } +// // else +// // { +// // sharedPref.remove(FAMILY_FILE), +// // result.list.isFamily = false, +// // userData = result.list, +// // sharedPref.setString(BLOOD_TYPE, result.patientBloodType), +// // authenticatedUserObject.user = result.list, +// // projectViewModel.setPrivilege(privilegeList: res), +// // sharedPref.setObject(MAIN_USER, result.list), +// // sharedPref.setObject(USER_PROFILE, result.list), +// // loginTokenID = result.logInTokenID, +// // sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), +// // sharedPref.setString(TOKEN, result.authenticationTokenID), +// // checkIfUserAgreedBefore(result), +// // } +// // } +// // else +// // { +// // // // Navigator.of(context).pop(), +// // // GifLoaderDialogUtils.hideDialog(context), +// // // Future.delayed(Duration(seconds: 1), () { +// // // AppToast.showErrorToast(message: result); +// // // startSMSService(tempType); +// // // }), +// // } +// // }) +// // .catchError((err) { +// // // print(err); +// // // GifLoaderDialogUtils.hideDialog(context); +// // // Future.delayed(Duration(seconds: 1), () { +// // // AppToast.showErrorToast(message: err); +// // // startSMSService(tempType); +// // // }); +// // }); +// // } +// // } +// +// // checkIfUserAgreedBefore(CheckActivationCode result) { +// // if (result.isNeedUserAgreement == true) { +// // //move to agreement page. +// // } else { +// // goToHome(); +// // } +// // } +// +// insertIMEI() { +// authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { +// print(err); +// }); +// } +// +// // getToDoCount() { +// // toDoProvider.setState(0, true, "0"); +// // ClinicListService service = new ClinicListService(); +// // service.getActiveAppointmentNo(context).then((res) { +// // if (res['MessageStatus'] == 1) { +// // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); +// // } else {} +// // }).catchError((err) { +// // print(err); +// // }); +// // } +// +// // goToHome() async { +// // authenticatedUserObject.isLogin = true; +// // appointmentRateViewModel.isLogin = true; +// // projectViewModel.isLogin = true; +// // projectViewModel.user = authenticatedUserObject.user; +// // await authenticatedUserObject.getUser(getUser: true); +// // +// // // getToDoCount(); +// // +// // appointmentRateViewModel +// // .getIsLastAppointmentRatedList() +// // .then((value) => { +// // getToDoCount(), +// // GifLoaderDialogUtils.hideDialog(AppGlobal.context), +// // if (appointmentRateViewModel.isHaveAppointmentNotRate) +// // { +// // Navigator.pushAndRemoveUntil( +// // context, +// // FadePage( +// // page: RateAppointmentDoctor(), +// // ), +// // (r) => false) +// // } +// // else +// // { +// // Navigator.pushAndRemoveUntil( +// // context, +// // FadePage( +// // page: LandingPage(), +// // ), +// // (r) => false) +// // }, +// // insertIMEI() +// // }) +// // .catchError((err) { +// // print(err); +// // }); +// // } +// +// loading(flag) { +// // setState(() { +// // isLoading = flag; +// // }); +// } +// + + Future loginWithFaceIDAndBiometrics() async { + IOSAuthMessages iosStrings = + const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); + bool authenticated = false; + try { + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); + } on PlatformException catch (e) { + print(e); + Utils.hideLoading(context); + Utils.showToast("Please enable your Touch or Face ID"); + } + return authenticated; + } + + Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { + bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 2 && !checkBiometricIsAvailable(BiometricType.fingerprint))); + print("$_title:$isDisable"); + return InkWell( + onTap: isDisable + ? null + : () async { + if (_flag == 0) { + setState(() { + // isMoreOption = true; + }); + } else { + Utils.showLoading(context); + if (_flag == 2 || _flag == 3) { + bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics(); + if (authenticateWithFaceAndTouchID) { + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); + return; + } else { + Utils.hideLoading(context); + return; + } + } + await LoginApiClient().checkMobileAppVersion(); + await LoginApiClient().memberLogin(AppState().username!, AppState().password!); + BasicMemberInformationModel? memberInformationModel = await LoginApiClient() + .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); + Utils.hideLoading(context); + OtpDialog( + context, + _flag, + int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), + (value) async { + Utils.showLoading(context); + try { + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); + if (genericResponseModel?.errorMessage != null) { + Utils.showToast(genericResponseModel?.errorMessage ?? ""); + // Navigator.pop(context); + } + Utils.hideLoading(context); + Navigator.pop(context); + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, null); + } + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); + + // authenticateUser(_flag, isActive: _loginIndex); + } + }, + child: Container( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, + border: Border.all(color: MyColors.lightGreyEFColor, width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + _icon, + height: 38, + width: 38, + color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null, + ), + _title.toText16() + ], + ), + ), + ); + } + + Widget getButton(int flag) { + switch (flag) { + case 4: + return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null); + case 1: + return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null); + case 2: + return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.index); + case 3: + return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index); + default: + return const SizedBox(); + } + } + + bool checkBiometricIsAvailable(BiometricType biometricType) { + bool isAvailable = false; + for (int i = 0; i < _availableBioMetricType.length; i++) { + if (biometricType == _availableBioMetricType[i]) { + isAvailable = true; + break; + } + } + return isAvailable; + } +// +// formatDate(date) { +// return date; +// return DateFormat('MMM dd, yyy, kk:mm').format(date); +// } +// +// showLoader(bool isTrue) { +// setState(() { +// // isLoading = isTrue; +// }); +// } + +} diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index b28ad4d..bf64d8e 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -1,20 +1,25 @@ +import 'dart:io'; + import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; -import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/member_information_list_model.dart'; +import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; class VerifyLoginScreen extends StatefulWidget { @@ -30,6 +35,8 @@ class _VerifyLoginScreenState extends State { final LocalAuthentication auth = LocalAuthentication(); List _availableBioMetricType = []; + String? firebaseToken; + @override void initState() { _getAvailableBiometrics(); @@ -39,6 +46,7 @@ class _VerifyLoginScreenState extends State { @override Widget build(BuildContext context) { + firebaseToken ??= ModalRoute.of(context)!.settings.arguments as String; return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, @@ -46,7 +54,7 @@ class _VerifyLoginScreenState extends State { icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), onPressed: () => Navigator.pop(context), ), - actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], + // actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], ), body: Column( children: [ @@ -61,69 +69,69 @@ class _VerifyLoginScreenState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.welcomeBack.tr().toText12(), - "Mohammad Hussain".toText24(isBold: true), - 10.height, - LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), - Container( - height: 72, - margin: const EdgeInsets.only(top: 23, bottom: 23), - alignment: Alignment.center, - padding: EdgeInsets.only(left: 17, right: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - border: Border.all( - color: Color(0xffefefef), - width: 1, - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - LocaleKeys.lastLoginDetails.tr().toText16(), - // Text( - // user.editedOn != null - // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) - // : user.createdOn != null - // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn)) - // : '--', - // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), - // ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), - Text( - "SMS", - // " " + getType(user.logInType, context), - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - ), - ), - Expanded(child: SizedBox()), - // Text( - // user.editedOn != null - // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false) - // : user.createdOn != null - // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false) - // : '--', - // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), - // ), - ], - ) - ], - ), - ), + // LocaleKeys.welcomeBack.tr().toText12(), + // "Mohammad Hussain".toText24(isBold: true), + // 10.height, + // LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), + // Container( + // height: 72, + // margin: const EdgeInsets.only(top: 23, bottom: 23), + // alignment: Alignment.center, + // padding: EdgeInsets.only(left: 17, right: 12), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(10), + // color: Colors.white, + // border: Border.all( + // color: Color(0xffefefef), + // width: 1, + // ), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // LocaleKeys.lastLoginDetails.tr().toText16(), + // // Text( + // // user.editedOn != null + // // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) + // // : user.createdOn != null + // // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn)) + // // : '--', + // // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + // // ), + // ], + // ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), + // Text( + // "SMS", + // // " " + getType(user.logInType, context), + // style: TextStyle( + // fontSize: 12, + // fontWeight: FontWeight.w600, + // color: Color(0xff2B353E), + // ), + // ), + // Expanded(child: SizedBox()), + // // Text( + // // user.editedOn != null + // // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false) + // // : user.createdOn != null + // // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false) + // // : '--', + // // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), + // // ), + // ], + // ) + // ], + // ), + // ), LocaleKeys.pleaseVerify.tr().toText16(), GridView( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), @@ -612,9 +620,23 @@ class _VerifyLoginScreenState extends State { // // }); // } // + + Future loginWithFaceIDAndBiometrics() async { + IOSAuthMessages iosStrings = + const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); + bool authenticated = false; + try { + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); + } on PlatformException catch (e) { + print(e); + Utils.hideLoading(context); + Utils.showToast("Please enable your Touch or Face ID"); + } + return authenticated; + } + Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 2 && !checkBiometricIsAvailable(BiometricType.fingerprint))); - print("$_title:$isDisable"); return InkWell( onTap: isDisable ? null @@ -624,37 +646,64 @@ class _VerifyLoginScreenState extends State { // isMoreOption = true; }); } else { - Utils.showLoading(context); - BasicMemberInformationModel? memberInformationModel = await LoginApiClient() - .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); - Utils.hideLoading(context); - OtpDialog( - context, - _flag, - int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), - (value) async { - Utils.showLoading(context); - try { - GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); - if (genericResponseModel?.errorMessage != null) { - Utils.showToast(genericResponseModel?.errorMessage ?? ""); - // Navigator.pop(context); - } - Utils.hideLoading(context); - Navigator.pop(context); - Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); - } catch (ex) { - print(ex); - Utils.hideLoading(context); - Utils.handleException(ex, null); + try { + Utils.showLoading(context); + if (_flag == 2 || _flag == 3) { + bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics(); + if (!authenticateWithFaceAndTouchID) { + return; } - }, - () => { - Navigator.pop(context), - }, - ).displayDialog(context); - - // authenticateUser(_flag, isActive: _loginIndex); + } + await LoginApiClient().checkMobileAppVersion(); + await LoginApiClient().memberLogin(AppState().username!, AppState().password!); + BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType( + checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); + Utils.hideLoading(context); + OtpDialog( + context, + _flag, + int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), + (value) async { + Utils.showLoading(context); + try { + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); + GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( + AppState().memberLoginList?.pEMAILADDRESS ?? "", + genericResponseModel?.pSESSIONID ?? 0, + genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "", + _flag, + AppState().memberLoginList?.pMOBILENUMBER ?? "", + AppState().username!, + firebaseToken!, + Platform.isAndroid ? "android" : "ios"); + if (genericResponseModel?.errorMessage != null) { + Utils.showToast(genericResponseModel?.errorMessage ?? ""); + } else { + AppState().setPrivilegeListModel = genericResponseModel!.privilegeList ?? []; + AppState().setMemberInformationListModel = genericResponseModel.memberInformationList?.first; + MemberInformationListModel.saveToPrefs(genericResponseModel.memberInformationList ?? []); + PrivilegeListModel.saveToPrefs(genericResponseModel.privilegeList ?? []); + Utils.saveStringFromPrefs(SharedPrefsConsts.username, AppState().username!); + Utils.saveStringFromPrefs(SharedPrefsConsts.password, AppState().password!); + } + Utils.hideLoading(context); + Navigator.pop(context); + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, null); + } + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, null); + } } }, child: Container( diff --git a/lib/widgets/dialogs/confirm_dialog.dart b/lib/widgets/dialogs/confirm_dialog.dart new file mode 100644 index 0000000..7264a9b --- /dev/null +++ b/lib/widgets/dialogs/confirm_dialog.dart @@ -0,0 +1,66 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; + +class ConfirmDialog extends StatelessWidget { + final String? title; + final String? message; + final String? okTitle; + final VoidCallback? onTap; + + const ConfirmDialog({Key? key, this.title, @required this.message, this.okTitle, this.onTap}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder(), + insetPadding: EdgeInsets.only(left: 21, right: 21), + child: Padding( + padding: EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Text( + title ?? LocaleKeys.confirm.tr(), + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Color(0xff2B353E), height: 35 / 24, letterSpacing: -0.96), + ), + ), + ), + IconButton( + padding: EdgeInsets.zero, + icon: Icon(Icons.close), + color: Color(0xff2B353E), + constraints: BoxConstraints(), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + Text( + message ?? "", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff808080), letterSpacing: -0.48), + ), + SizedBox(height: 28), + DefaultButton( + okTitle ?? LocaleKeys.ok.tr(), + onTap == null ? () => Navigator.pop(context) : onTap, + textColor: Colors.white, + //color: Ap.green, + ), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 8b248e4..7761816 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -12,15 +12,10 @@ class InputWidget extends StatelessWidget { final bool isInputTypeNum; final bool isObscureText; final bool isBackgroundEnable; + final Function(String)? onChange; InputWidget(this.labelText, this.hintText, this.controller, - {this.isObscureText = false, - this.suffixTap, - this.isEnable = true, - this.hasSelection = false, - this.lines = 1, - this.isInputTypeNum = false, - this.isBackgroundEnable = false}); + {this.isObscureText = false, this.suffixTap, this.isEnable = true, this.hasSelection = false, this.lines = 1, this.onChange, this.isInputTypeNum = false, this.isBackgroundEnable = false}); @override Widget build(BuildContext context) { @@ -56,14 +51,12 @@ class InputWidget extends StatelessWidget { TextField( enabled: isEnable, scrollPadding: EdgeInsets.zero, - keyboardType: isInputTypeNum - ? TextInputType.number - : TextInputType.text, + keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text, controller: controller, maxLines: lines, obscuringCharacter: "*", obscureText: isObscureText, - onChanged: (value) => {}, + onChanged: onChange, style: const TextStyle( fontSize: 14, height: 21 / 14, @@ -82,12 +75,7 @@ class InputWidget extends StatelessWidget { letterSpacing: -0.56, ), suffixIconConstraints: const BoxConstraints(minWidth: 50), - suffixIcon: suffixTap == null - ? null - : IconButton( - icon: const Icon(Icons.mic, - color: MyColors.darkTextColor), - onPressed: suffixTap), + suffixIcon: suffixTap == null ? null : IconButton(icon: const Icon(Icons.mic, color: MyColors.darkTextColor), onPressed: suffixTap), contentPadding: EdgeInsets.zero, border: InputBorder.none, focusedBorder: InputBorder.none, diff --git a/pubspec.yaml b/pubspec.yaml index dfbb0eb..611dbf1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,8 @@ dependencies: sizer: ^2.0.15 local_auth: ^1.1.9 fluttertoast: ^8.0.8 + shared_preferences: ^2.0.12 + firebase_messaging: ^11.2.6 dev_dependencies: From 9c40878c4a9e49a4ffbd2852f74d0bad3be7f43a Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 13 Feb 2022 11:47:06 +0300 Subject: [PATCH 10/22] locale commited --- lib/generated/locale_keys.g.dart | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 lib/generated/locale_keys.g.dart diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart new file mode 100644 index 0000000..b5ecc57 --- /dev/null +++ b/lib/generated/locale_keys.g.dart @@ -0,0 +1,80 @@ +// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart + +abstract class LocaleKeys { + static const mohemm = 'mohemm'; + static const english = 'english'; + static const arabic = 'arabic'; + static const login = 'login'; + static const pleaseEnterLoginDetails = 'pleaseEnterLoginDetails'; + static const username = 'username'; + static const password = 'password'; + static const welcomeBack = 'welcomeBack'; + static const wouldYouLikeToLoginWithCurrentUsername = 'wouldYouLikeToLoginWithCurrentUsername'; + static const lastLoginDetails = 'lastLoginDetails'; + static const verificationType = 'verificationType'; + static const pleaseVerify = 'pleaseVerify'; + static const verifyThroughFace = 'verifyThroughFace'; + static const verifyThroughFingerprint = 'verifyThroughFingerprint'; + static const verifyThroughSMS = 'verifyThroughSMS'; + static const verifyThroughWhatsapp = 'verifyThroughWhatsapp'; + static const useAnotherAccount = 'useAnotherAccount'; + static const pleaseEnterTheVerificationCodeSentTo = 'pleaseEnterTheVerificationCodeSentTo'; + static const theVerificationCodeWillExpireIn = 'theVerificationCodeWillExpireIn'; + static const goodMorning = 'goodMorning'; + static const markAttendance = 'markAttendance'; + static const timeLeftToday = 'timeLeftToday'; + static const checkIn = 'checkIn'; + static const workList = 'workList'; + static const leaveBalance = 'leaveBalance'; + static const missingSwipes = 'missingSwipes'; + static const ticketBalance = 'ticketBalance'; + static const services = 'services'; + static const viewAllServices = 'viewAllServices'; + static const monthlyAttendance = 'monthlyAttendance'; + static const workFromHome = 'workFromHome'; + static const ticketRequest = 'ticketRequest'; + static const viewAllOffers = 'viewAllOffers'; + static const offers = 'offers'; + static const discounts = 'discounts'; + static const newString = 'newString'; + static const setTheNewPassword = 'setTheNewPassword'; + static const typeYourNewPasswordBelow = 'typeYourNewPasswordBelow'; + static const confirmPassword = 'confirmPassword'; + static const update = 'update'; + static const title = 'title'; + static const home = 'home'; + static const mySalary = 'mySalary'; + static const createRequest = 'createRequest'; + static const forgotPassword = 'forgotPassword'; + static const employeeId = 'employeeId'; + static const loginCodeWillSentToMobileNumber = 'loginCodeWillSentToMobileNumber'; + static const changePassword = 'changePassword'; + static const ok = 'ok'; + static const confirm = 'confirm'; + static const passwordChangedSuccessfully = 'passwordChangedSuccessfully'; + static const itemsForSale = 'itemsForSale'; + static const doNotUseRecentPassword = 'doNotUseRecentPassword'; + static const atLeastOneLowercase = 'atLeastOneLowercase'; + static const atLeastOneUppercase = 'atLeastOneUppercase'; + static const atLeastOneNumeric = 'atLeastOneNumeric'; + static const minimum8Characters = 'minimum8Characters'; + static const doNotAddRepeatingLetters = 'doNotAddRepeatingLetters'; + static const itShouldContainSpecialCharacter = 'itShouldContainSpecialCharacter'; + static const confirmPasswordMustMatch = 'confirmPasswordMustMatch'; + static const msg = 'msg'; + static const msg_named = 'msg_named'; + static const clickMe = 'clickMe'; + static const human = 'human'; + static const resources = 'resources'; + static const profile_reset_password_label = 'profile.reset_password.label'; + static const profile_reset_password_username = 'profile.reset_password.username'; + static const profile_reset_password_password = 'profile.reset_password.password'; + static const profile_reset_password = 'profile.reset_password'; + static const profile = 'profile'; + static const clicked = 'clicked'; + static const amount = 'amount'; + static const gender_with_arg = 'gender.with_arg'; + static const gender = 'gender'; + static const reset_locale = 'reset_locale'; + +} From 7027299a489ac8666022991b7fd0c90669f50493 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 13 Feb 2022 11:57:49 +0300 Subject: [PATCH 11/22] merge improvements --- lib/ui/login/verify_last_login_screen.dart | 6 +++--- lib/ui/login/verify_login_screen.dart | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 0c8554f..282c7a5 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -653,9 +653,9 @@ class _VerifyLastLoginScreenState extends State { } } await LoginApiClient().checkMobileAppVersion(); - await LoginApiClient().memberLogin(AppState().username!, AppState().password!); + await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!); BasicMemberInformationModel? memberInformationModel = await LoginApiClient() - .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); + .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName); Utils.hideLoading(context); OtpDialog( context, @@ -664,7 +664,7 @@ class _VerifyLastLoginScreenState extends State { (value) async { Utils.showLoading(context); try { - GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); // Navigator.pop(context); diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index bf64d8e..8e9255f 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -655,9 +655,9 @@ class _VerifyLoginScreenState extends State { } } await LoginApiClient().checkMobileAppVersion(); - await LoginApiClient().memberLogin(AppState().username!, AppState().password!); + await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!); BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType( - checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().username); + checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName); Utils.hideLoading(context); OtpDialog( context, @@ -666,14 +666,14 @@ class _VerifyLoginScreenState extends State { (value) async { Utils.showLoading(context); try { - GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().username); + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( AppState().memberLoginList?.pEMAILADDRESS ?? "", genericResponseModel?.pSESSIONID ?? 0, genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "", _flag, AppState().memberLoginList?.pMOBILENUMBER ?? "", - AppState().username!, + AppState().getUserName!, firebaseToken!, Platform.isAndroid ? "android" : "ios"); if (genericResponseModel?.errorMessage != null) { @@ -683,7 +683,7 @@ class _VerifyLoginScreenState extends State { AppState().setMemberInformationListModel = genericResponseModel.memberInformationList?.first; MemberInformationListModel.saveToPrefs(genericResponseModel.memberInformationList ?? []); PrivilegeListModel.saveToPrefs(genericResponseModel.privilegeList ?? []); - Utils.saveStringFromPrefs(SharedPrefsConsts.username, AppState().username!); + Utils.saveStringFromPrefs(SharedPrefsConsts.username, AppState().getUserName!); Utils.saveStringFromPrefs(SharedPrefsConsts.password, AppState().password!); } Utils.hideLoading(context); From c4b7046a90dadafcf0f3d141a17e21eeb1318754 Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Tue, 1 Mar 2022 10:39:16 +0300 Subject: [PATCH 12/22] Dashboard API's 1.3 --- assets/icons/create_req.svg | 7 +++ assets/icons/home.svg | 7 +++ assets/icons/item_for_sale.svg | 3 + assets/icons/work_list.svg | 15 +++++ lib/ui/landing/dashboard_screen.dart | 65 +++++++++++++++++++++- lib/ui/landing/widget/services_widget.dart | 25 +++++---- lib/ui/login/login_screen.dart | 2 +- 7 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 assets/icons/create_req.svg create mode 100644 assets/icons/home.svg create mode 100644 assets/icons/item_for_sale.svg create mode 100644 assets/icons/work_list.svg diff --git a/assets/icons/create_req.svg b/assets/icons/create_req.svg new file mode 100644 index 0000000..a87e809 --- /dev/null +++ b/assets/icons/create_req.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/home.svg b/assets/icons/home.svg new file mode 100644 index 0000000..fb67997 --- /dev/null +++ b/assets/icons/home.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/item_for_sale.svg b/assets/icons/item_for_sale.svg new file mode 100644 index 0000000..0a87567 --- /dev/null +++ b/assets/icons/item_for_sale.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/work_list.svg b/assets/icons/work_list.svg new file mode 100644 index 0000000..a802c53 --- /dev/null +++ b/assets/icons/work_list.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 92ea49d..747ef1c 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -46,7 +46,7 @@ class _DashboardScreenState extends State { data.fetchWorkListCounter(); data.fetchMissingSwipe(); data.fetchLeaveTicketBalance(); - // data.fetchMenuEntries(); + data.fetchMenuEntries(); } @override @@ -329,6 +329,69 @@ class _DashboardScreenState extends State { ) ], ), + bottomNavigationBar: BottomNavigationBar( + items: [ + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.all(4.0), + child: SvgPicture.asset( + "assets/icons/home.svg", + width: 20, + height: 20, + ), + ), + label: 'Home', + ), + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.all(4.0), + child: SvgPicture.asset( + "assets/icons/create_req.svg", + width: 20, + height: 20, + ), + ), + label: 'Create Request', + ), + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.all(4.0), + child: SvgPicture.asset( + "assets/icons/work_list.svg", + width: 20, + height: 20, + ), + ), + label: 'Work List', + ), + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.all(4.0), + child: SvgPicture.asset( + "assets/icons/item_for_sale.svg", + width: 20, + height: 20, + ), + ), + label: 'Items for Sale', + ), + ], + currentIndex: 0, + selectedLabelStyle: TextStyle( + fontSize: 8, + color: Color(0xff989898), + fontWeight: FontWeight.w600, + ), + unselectedLabelStyle: TextStyle( + fontSize: 8, + color: Color(0xff989898), + fontWeight: FontWeight.w600, + ), + type: BottomNavigationBarType.fixed, + selectedItemColor: Colors.black, + backgroundColor: Color(0xffF8F8F8), + onTap: (v) {}, + ), ); } } diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index f397a4c..89a0aa6 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -128,18 +128,19 @@ class ServicesWidget extends StatelessWidget { SizedBox( height: 105 + 26, child: ListView.separated( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), - scrollDirection: Axis.horizontal, - itemBuilder: (cxt, index) { - return AspectRatio( - aspectRatio: 105 / 105, - child: ServicesMenuShimmer(), - ); - }, - separatorBuilder: (cxt, index) => 9.width, - itemCount: 4), + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return AspectRatio( + aspectRatio: 105 / 105, + child: ServicesMenuShimmer(), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: 4, + ), ), ], ); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 2353f99..fe7f118 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -63,7 +63,7 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { username.text="15153"; - password.text="e123e123e123"; + password.text="s12s12s12"; return Scaffold( body: Column( children: [ From 4b5ab2cd7f6fb988b978b78a66daf5c795371e94 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 2 Mar 2022 10:04:46 +0300 Subject: [PATCH 13/22] wokrlist api's added & improvements --- assets/langs/ar-SA.json | 11 +- assets/langs/en-US.json | 7 + lib/api/api_client.dart | 100 +++- lib/api/dashboard_api_client.dart | 10 +- lib/api/login_api_client.dart | 2 +- lib/api/worklist/worklist_api_client.dart | 41 ++ lib/classes/colors.dart | 1 + lib/classes/date_uitl.dart | 444 +++++++++++++++++ lib/extensions/string_extensions.dart | 42 +- lib/extensions/widget_extensions.dart | 22 +- lib/generated/codegen_loader.g.dart | 386 +++++++-------- lib/generated/locale_keys.g.dart | 10 +- lib/main.dart | 38 +- lib/models/dashboard/itg_forms_model.dart | 240 +++++---- lib/models/dashboard/list_menu.dart | 32 +- lib/models/generic_response_model.dart | 20 +- lib/models/worklist_item_type_model.dart | 38 ++ lib/models/worklist_response_model.dart | 137 ++++++ lib/provider/dashboard_provider_model.dart | 36 +- lib/ui/app_bar.dart | 26 - lib/ui/landing/dashboard_screen.dart | 189 ++++--- lib/ui/landing/today_attendance_screen.dart | 4 +- lib/ui/landing/widget/menus_widget.dart | 16 +- lib/ui/login/login_screen.dart | 10 +- lib/ui/login/verify_last_login_screen.dart | 463 +----------------- .../missing_swipe/missing_swipe_screen.dart | 248 +++++++--- lib/ui/work_list/work_list_screen.dart | 342 +++++++++---- lib/widgets/app_bar_widget.dart | 44 ++ 28 files changed, 1828 insertions(+), 1131 deletions(-) create mode 100644 lib/api/worklist/worklist_api_client.dart create mode 100644 lib/classes/date_uitl.dart create mode 100644 lib/models/worklist_item_type_model.dart create mode 100644 lib/models/worklist_response_model.dart delete mode 100644 lib/ui/app_bar.dart create mode 100644 lib/widgets/app_bar_widget.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index f88c890..e8892a8 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -60,11 +60,18 @@ "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", + "sms": "رسالة قصيرة", + "fingerPrint": "بصمة", + "face": "التعرف على الوجه", + "whatsapp": "واتس اب", + "reject": "يرفض", + "approve": "يوافق", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", - "human": "Human", - "resources": "Resources", + "human": "بشري", + "resources": "موارد", + "details": "تفاصيل", "profile": { "reset_password": { "label": "Reset Password", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index a669a4f..f5b9b44 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -60,11 +60,18 @@ "doNotAddRepeatingLetters": "Do not add repeating letters", "itShouldContainSpecialCharacter": "It should contain special character", "confirmPasswordMustMatch": "Confirm password must match", + "sms": "SMS", + "fingerPrint": "Fingerprint", + "face": "Face", + "whatsapp": "Whatsapp", + "reject": "Reject", + "approve": "Approve", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", "human": "Human", "resources": "Resources", + "details": "Details", "profile": { "reset_password": { "label": "Reset Password", diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index 609aca9..17eac0d 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -76,25 +76,25 @@ class ApiClient { print("body:$jsonObject"); } var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); - try { - if (!kReleaseMode) { - logger.i("res: " + response.body); - } - var jsonData = jsonDecode(response.body); - if (jsonData["ErrorMessage"] == null) { - return factoryConstructor(jsonData); - } else { - APIError? apiError; - apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorMessage']); - throw APIException(APIException.BAD_REQUEST, error: apiError); - } - } catch (ex) { - if (ex is APIException) { - rethrow; - } else { - throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); - } + // try { + if (!kReleaseMode) { + logger.i("res: " + response.body); } + var jsonData = jsonDecode(response.body); + if (jsonData["ErrorMessage"] == null) { + return factoryConstructor(jsonData); + } else { + APIError? apiError; + apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorMessage']); + throw APIException(APIException.BAD_REQUEST, error: apiError); + } + // } catch (ex) { + // if (ex is APIException) { + // rethrow; + // } else { + // throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); + // } + // } } Future postJsonForResponse(String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { @@ -162,6 +162,68 @@ class ApiClient { } } + Future getJsonForResponse(String url, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + if (headers == null) { + headers = {'Content-Type': 'application/json'}; + } else { + headers['Content-Type'] = 'application/json'; + } + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes); + } + + Future _getForResponse(String url, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + try { + var _headers = {}; + if (token != null) { + _headers['Authorization'] = 'Bearer $token'; + } + + if (headers != null && headers.isNotEmpty) { + _headers.addAll(headers); + } + + if (queryParameters != null) { + var queryString = new Uri(queryParameters: queryParameters).query; + url = url + '?' + queryString; + } + var response = await _get(Uri.parse(url), headers: _headers).timeout(Duration(seconds: 60)); + + if (response.statusCode >= 200 && response.statusCode < 300) { + return response; + } else { + throw _throwAPIException(response); + } + } on SocketException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } on HttpException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } on TimeoutException catch (e) { + throw APIException(APIException.TIMEOUT, arguments: e); + } on ClientException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } + } + + Future _get(url, {Map? headers}) => _withClient((client) => client.get(url, headers: headers)); + bool _certificateCheck(X509Certificate cert, String host, int port) => true; Future _withClient(Future Function(Client) fn) async { @@ -175,4 +237,4 @@ class ApiClient { } Future _post(url, {Map? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding)); -} + } diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index b98a777..76e2453 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -11,12 +11,12 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'api_client.dart'; -class DashbaordApiClient { - static final DashbaordApiClient _instance = DashbaordApiClient._internal(); +class DashboardApiClient { + static final DashboardApiClient _instance = DashboardApiClient._internal(); - DashbaordApiClient._internal(); + DashboardApiClient._internal(); - factory DashbaordApiClient() => _instance; + factory DashboardApiClient() => _instance; Future getAttendanceTracking() async { String url = "${ApiConsts.erpRest}GET_Attendance_Tracking"; @@ -82,7 +82,7 @@ class DashbaordApiClient { //GET_MENU_ENTRIES Future getGetMenuEntries() async { String url = "${ApiConsts.erpRest}GET_MENU_ENTRIES"; - Map postParams = {"P_SELECTED_RESP_ID": -999,"P_MENU_TYPE":"E"}; + Map postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E"}; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart index f69e317..070fa27 100644 --- a/lib/api/login_api_client.dart +++ b/lib/api/login_api_client.dart @@ -47,6 +47,7 @@ class LoginApiClient { postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + AppState().setLogged = true; return responseData; }, url, postParams); } @@ -82,7 +83,6 @@ class LoginApiClient { postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); - AppState().setLogged = true; AppState().postParamsObject?.setTokenID = responseData.tokenID; AppState().postParamsObject?.mobileNumber = responseData.basicMemberInformation!.pMOBILENUMBER; AppState().postParamsObject?.userName = AppState().getUserName; diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart new file mode 100644 index 0000000..a473ba7 --- /dev/null +++ b/lib/api/worklist/worklist_api_client.dart @@ -0,0 +1,41 @@ +import 'dart:async'; + +import 'package:mohem_flutter_app/api/api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; + +class WorkListApiClient { + static final WorkListApiClient _instance = WorkListApiClient._internal(); + + WorkListApiClient._internal(); + + factory WorkListApiClient() => _instance; + + Future?> getWorkList(int pPageNum, String pItemType) async { + String url = "${ApiConsts.erpRest}GET_WORKLIST"; + Map postParams = { + "P_NOTIFICATION_TYPE": "1", + "P_PAGE_NUM": pPageNum, + "P_PAGE_LIMIT": 50, + "P_ITEM_TYPE": pItemType, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return responseData.getWorkList; + }, url, postParams); + } + + Future GetITGTaskCountRequestType() async { + String url = "${ApiConsts.cocRest}ITGGetTaskCountRequestType"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + ItgFormsModel responseData = ItgFormsModel.fromJson(json); + return responseData; + }, url, postParams); + } +} diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 2e5eaef..0d80b05 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -16,6 +16,7 @@ class MyColors { static const Color grey98Color = Color(0xff989898); static const Color lightGreyEFColor = Color(0xffEFEFEF); static const Color lightGreyEDColor = Color(0xffEDEDED); + static const Color lightGreyE6Color = Color(0xffE6E6E6); static const Color lightGreyEAColor = Color(0xffEAEAEA); static const Color darkWhiteColor = Color(0xffE0E0E0); static const Color redColor = Color(0xffD02127); diff --git a/lib/classes/date_uitl.dart b/lib/classes/date_uitl.dart new file mode 100644 index 0000000..d0f4b1f --- /dev/null +++ b/lib/classes/date_uitl.dart @@ -0,0 +1,444 @@ +import 'package:intl/intl.dart'; + +class DateUtil { + /// convert String To Date function + /// [date] String we want to convert + static DateTime convertStringToDate(String date) { + // /Date(1585774800000+0300)/ + if (date != null) { + const start = "/Date("; + const end = "+0300)"; + final startIndex = date.indexOf(start); + final endIndex = date.indexOf(end, startIndex + start.length); + return DateTime.fromMillisecondsSinceEpoch( + int.parse( + date.substring(startIndex + start.length, endIndex), + ), + ); + } else + return DateTime.now(); + } + + static DateTime convertSimpleStringDateToDate(String date) { + return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date); + } + + static DateTime convertStringToDateNoTimeZone(String date) { + // /Date(1585774800000+0300)/ + if (date != null) { + const start = "/Date("; + const end = ")"; + final startIndex = date.indexOf(start); + final endIndex = date.indexOf(end, startIndex + start.length); + return DateTime.fromMillisecondsSinceEpoch( + int.parse( + date.substring(startIndex + start.length, endIndex), + ), + ); + } else + return DateTime.now(); + } + + static DateTime convertStringToDateTime(String date) { + if (date != null) { + try { + var dateT = date.split('/'); + var year = dateT[2].substring(0, 4); + var dateP = DateTime(int.parse(year), int.parse(dateT[1]), int.parse(dateT[0])); + return dateP; + } catch (e) { + print(e); + } + + return DateTime.now(); + } else + return DateTime.now(); + } + + static String convertDateToString(DateTime date) { + const start = "/Date("; + const end = "+0300)"; + int milliseconds = date.millisecondsSinceEpoch; + + return start + "$milliseconds" + end; + } + + static String convertDateToStringLocation(DateTime date) { + const start = "/Date("; + const end = ")/"; + int milliseconds = date.millisecondsSinceEpoch; + + return start + "$milliseconds" + end; + } + + static String formatDateToDate(DateTime date, bool isArabic) { + return DateFormat('dd MMM yyy', isArabic ? "ar_SA" : "en_US").format(date); + } + + static String formatDateToTime(DateTime date) { + return DateFormat('hh:mm a').format(date); + } + + static String yearMonthDay(DateTime dateTime) { + String dateFormat = '${dateTime.year}-${dateTime.month}-${dateTime.day}'; + return dateFormat; + } + + static String time(DateTime dateTime) { + String dateFormat = '${dateTime.hour}:${dateTime.minute}:00'; + return dateFormat; + } + + static String convertDateMSToJsonDate(utc) { + var dt = new DateTime.fromMicrosecondsSinceEpoch(utc); + + return "/Date(" + (dt.millisecondsSinceEpoch * 1000).toString() + '+0300' + ")/"; + } + + /// check Date + /// [dateString] String we want to convert + static String checkDate(DateTime checkedTime) { + DateTime currentTime = DateTime.now(); + if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month) && (currentTime.day == checkedTime.day)) { + return "Today"; + } else if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month)) { + if ((currentTime.day - checkedTime.day) == 1) { + return "YESTERDAY"; + } else if ((currentTime.day - checkedTime.day) == -1) { + return "Tomorrow"; + } + + if ((currentTime.day - checkedTime.day) <= -2) { + return "Next Week"; + } else { + return "Old Date"; + } + } + return "Old Date"; + } + + static String getDateFormatted(String date) { + DateTime dateObj = DateUtil.convertStringToDate(date); + return DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString(); + } + + static String getISODateFormat(DateTime dateTime) { + // 2020-04-30T00:00:00.000 + return dateTime.toIso8601String(); + } + + /// get month by + /// [month] convert month number in to month name + static getMonth(int month) { + switch (month) { + case 1: + return "January"; + case 2: + return "February"; + case 3: + return "March"; + case 4: + return "April"; + case 5: + return "May"; + case 6: + return "June"; + case 7: + return "July"; + case 8: + return "August"; + case 9: + return "September"; + case 10: + return "October"; + case 11: + return "November"; + case 12: + return "December"; + } + } + + /// get month by + /// [month] convert month number in to month name in Arabic + static getMonthArabic(int month) { + switch (month) { + case 1: + return "يناير"; + case 2: + return " فبراير"; + case 3: + return "مارس"; + case 4: + return "أبريل"; + case 5: + return "مايو"; + case 6: + return "يونيو"; + case 7: + return "يوليو"; + case 8: + return "أغسطس"; + case 9: + return "سبتمبر"; + case 10: + return " اكتوبر"; + case 11: + return " نوفمبر"; + case 12: + return "ديسمبر"; + } + } + + static getMonthByName(String month) { + switch (month.toLowerCase()) { + case 'january': + return 1; + case 'february': + return 2; + case 'march': + return 3; + case 'april': + return 4; + case 'may': + return 5; + case 'june': + return 6; + case 'july': + return 7; + case 'august': + return 8; + case 'september': + return 9; + case 'october': + return 10; + case 'november': + return 11; + case 'december': + return 12; + } + } + + static DateTime getMonthDateTime(String month, yearName) { + DateTime? date; + try { + date = DateTime(int.parse(yearName), getMonthByName(month)); + } catch (e) { + print(e); + } + return date ?? DateTime.now(); + } + + /// get month by + /// [weekDay] convert week day in int to week day name + static getWeekDay(int weekDay) { + switch (weekDay) { + case 1: + return "Monday"; + case 2: + return "Tuesday"; + case 3: + return "Wednesday"; + case 4: + return "Thursday"; + case 5: + return "Friday"; + case 6: + return "Saturday "; + case 7: + return "Sunday"; + } + } + + /// get month by + /// [weekDay] convert week day in int to week day name arabic + static getWeekDayArabic(int weekDay) { + switch (weekDay) { + case 1: + return "الاثنين"; + case 2: + return "الثلاثاء"; + case 3: + return "الاربعاء"; + case 4: + return "الخميس"; + case 5: + return "الجمعه"; + case 6: + return "السبت "; + case 7: + return "الاحد"; + } + } + + static getWeekDayEnglish(int weekDay) { + switch (weekDay) { + case 1: + return "Monday"; + case 2: + return "Tuesday"; + case 3: + return "Wednesday"; + case 4: + return "Thursday"; + case 5: + return "Friday"; + case 6: + return "Saturday "; + case 7: + return "Sunday"; + } + } + + /// get data formatted like Apr 26,2020 + /// [dateTime] convert DateTime to data formatted + static String getMonthDayYearDateFormatted(DateTime dateTime) { + if (dateTime != null) + return getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString(); + else + return ""; + } + + /// get data formatted like Apr 26,2020 + /// [dateTime] convert DateTime to data formatted Arabic + static String getMonthDayYearDateFormattedAr(DateTime dateTime) { + if (dateTime != null) + return getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString(); + else + return ""; + } + + /// get data formatted like Thursday, Apr 26,2020 + /// [dateTime] convert DateTime to date formatted + static String getWeekDayMonthDayYearDateFormatted(DateTime dateTime, String lang) { + // print(dateTime); + // print(dateTime.weekday); + // print(dateTime.weekday.getDayOfWeekEnumValue.value); + if (dateTime != null) + return lang == 'en' + ? getWeekDayEnglish(dateTime.weekday) + ", " + getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString() + : getWeekDayArabic(dateTime.weekday) + ", " + dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); + else + return ""; + } + + static String getMonthDayYearLangDateFormatted(DateTime dateTime, String lang) { + if (dateTime != null) + return lang == 'en' + ? getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString() + : dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); + else + return ""; + } + + /// get data formatted like 26/4/2020 + static String getDayMonthYearLangDateFormatted(DateTime dateTime, String lang) { + if (dateTime != null) + return lang == 'en' + ? dateTime.day.toString() + " " + getMonth(dateTime.month) + " " + dateTime.year.toString() + : dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); + else + return ""; + } + + static String getMonthYearLangDateFormatted(DateTime dateTime, String lang) { + if (dateTime != null) + return lang == 'en' ? getMonth(dateTime.month) + " " + dateTime.year.toString() : getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); + else + return ""; + } + + /// get data formatted like 26/4/2020 + /// [dateTime] convert DateTime to data formatted + static String getDayMonthYearDateFormatted(DateTime dateTime) { + if (dateTime != null) + return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString(); + else + return ""; + } + + /// get data formatted like 26/4/2020 + /// [dateTime] convert DateTime to data formatted + static String getDayMonthDateFormatted(DateTime dateTime) { + if (dateTime != null) + return DateFormat('dd/MM').format(dateTime); + else + return ""; + } + + /// get data formatted like 26/4/2020 + /// [dateTime] convert DateTime to data formatted according to language + static String getDayMonthYearDateFormattedLang(DateTime dateTime, bool isArabic) { + if (dateTime != null) + return DateFormat('dd/MM/yyyy', isArabic ? "ar_SA" : "en_US").format(dateTime); + else + return ""; + } + + /// get data formatted like 10:30 according to lang + static String formatDateToTimeLang(DateTime date, bool isArabic) { + return DateFormat('HH:mm', isArabic ? "ar_SA" : "en_US").format(date); + } + + /// get data formatted like 26/4/2020 10:30 + /// [dateTime] convert DateTime to data formatted + static String getDayMonthYearHourMinuteDateFormatted(DateTime dateTime) { + if (dateTime != null) + return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString() + " " + DateFormat('HH:mm').format(dateTime); + else + return ""; + } + + /// get data formatted like 2020-8-13 09:43:00 + /// [dateTime] convert DateTime to data formatted + static String getYearMonthDayHourMinSecDateFormatted(DateTime dateTime) { + if (dateTime != null) + return dateTime.year.toString() + + "-" + + dateTime.month.toString() + + "-" + + dateTime.day.toString() + + " " + + dateTime.hour.toString() + + ":" + + dateTime.minute.toString() + + ":" + + dateTime.second.toString(); + else + return ""; + } + + static String getFormattedDate(DateTime dateTime, String formattedString) { + return DateFormat(formattedString).format(dateTime); + } + + static convertISODateToJsonDate(String isoDate) { + return "/Date(" + DateFormat('mm-dd-yyy').parse(isoDate).millisecondsSinceEpoch.toString() + ")/"; + } + + // static String getDay(DayOfWeek dayOfWeek) { + // switch (dayOfWeek) { + // case DayOfWeek.Monday: + // return "Monday"; + // break; + // case DayOfWeek.Tuesday: + // return "Tuesday"; + // break; + // case DayOfWeek.Wednesday: + // return "Wednesday"; + // break; + // case DayOfWeek.Thursday: + // return "Thursday"; + // break; + // case DayOfWeek.Friday: + // return "Friday"; + // break; + // case DayOfWeek.Saturday: + // return "Saturday"; + // break; + // case DayOfWeek.Sunday: + // return "Sunday"; + // break; + // } + // return ""; + // } +} diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 5d4f8cd..2db6135 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -1,15 +1,19 @@ +import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/cupertino.dart'; import 'package:intl/intl.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; extension CapExtension on String { String get toCamelCase => "${this[0].toUpperCase()}${this.substring(1)}"; + String get inCaps => '${this[0].toUpperCase()}${this.substring(1)}'; + String get allInCaps => this.toUpperCase(); + String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : ""; } - extension EmailValidator on String { Widget get toWidget => Text(this); @@ -65,9 +69,9 @@ extension EmailValidator on String { style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); - Widget toText24({Color? color, bool isBold = false}) => Text( + Widget toText24({Color? color, bool isBold = false, bool considerHeight = true}) => Text( this, - style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + style: TextStyle(height: considerHeight ? 23 / 24 : null, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); Widget toText32({Color? color, bool isBold = false}) => Text( @@ -75,6 +79,38 @@ extension EmailValidator on String { style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); + Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) { + String upper = ""; + String lower = ""; + String heading = this; + if (heading.isNotEmpty) { + List data = heading.split(" "); + + if (data.length > 1) { + upper = data[0]; + data.removeAt(0); + lower = data.join(" "); + } else { + lower = data[0]; + } + } + if (upperHeading.isNotEmpty) { + upper = upperHeading; + } + if (lowerHeading.isNotEmpty) { + lower = lowerHeading; + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (upper.isNotEmpty) upper.toText12(), + lower.toText24(isBold: true), + ], + ); + } + bool isValidEmail() { return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); } diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 130c867..5169f19 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -5,19 +5,27 @@ import 'package:shimmer/shimmer.dart'; extension WidgetExtensions on Widget { Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); + Widget get expanded => Expanded(child: this); + + Widget get center => Center(child: this); + Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this); Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); - Widget toShimmer({bool isShow=true}) =>isShow? Shimmer.fromColors( - baseColor: Color(0xffe8eff0), - highlightColor: Colors.white, - child: Container( + Widget toShimmer({bool isShow = true}) => isShow + ? Shimmer.fromColors( + baseColor: Color(0xffe8eff0), + highlightColor: Colors.white, + child: Container( + child: this, + color: Colors.white, + ), + ) + : Container( child: this, - color: Colors.white, - ), - ):Container(child: this,); + ); Widget animatedSwither() => AnimatedSwitcher( duration: const Duration(milliseconds: 500), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 3d67def..f4a2a6c 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -6,213 +6,193 @@ import 'dart:ui'; import 'package:easy_localization/easy_localization.dart' show AssetLoader; -class CodegenLoader extends AssetLoader{ +class CodegenLoader extends AssetLoader { const CodegenLoader(); @override - Future> load(String fullPath, Locale locale ) { + Future> load(String fullPath, Locale locale) { return Future.value(mapLocales[locale.toString()]); } - static const Map ar_SA = { - "mohemm": "Mohemm", - "english": "English", - "arabic": "Arabic", - "login": "تسجيل الدخول", - "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", - "username": "اسم المستخدم", - "password": "كلمة المرور", - "welcomeBack": "مرحبا بعودتك", - "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", - "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", - "verificationType": "نوع التحقق:", - "pleaseVerify": "ارجوك تحقق", - "verifyThroughFace": "تحقق من خلال الوجه", - "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", - "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", - "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", - "useAnotherAccount": "استخدم حسابا آخر", - "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", - "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", - "goodMorning": "صباح الخير", - "markAttendance": "علامة الحضور", - "timeLeftToday": "الوقت المتبقي اليوم", - "checkIn": "تحقق في", - "workList": "قائمة العمل", - "leaveBalance": "رصيد الاجازات", - "missingSwipes": "الضربات الشديدة في عداد المفقودين", - "ticketBalance": "رصيد التذكرة", - "other": "آخر", - "services": "خدمات", - "viewAllServices": "عرض جميع الخدمات", - "monthlyAttendance": "الحضور الشهري", - "workFromHome": "العمل من المنزل", - "ticketRequest": "طلب تذكرة", - "viewAllOffers": "مشاهدة جميع العروض", - "offers": "عروض & ", - "discounts": "الخصومات", - "newString": "جديد", - "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", - "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", - "confirmPassword": "تأكيد كلمة المرور", - "update": "تحديث", - "title": "عنوان", - "home": "مسكن", - "mySalary": "راتبي", - "createRequest": "إنشاء طلب", - "forgotPassword": "هل نسيت كلمة السر", - "employeeId": "هوية الموظف", - "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", - "changePassword": "تغيير كلمة المرور", - "ok": "موافق", - "confirm": "تؤكد", - "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", - "itemsForSale": "سلع للبيع", - "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", - "atLeastOneLowercase": "حرف صغير واحد على الأقل", - "atLeastOneUppercase": "حرف كبير واحد على الأقل", - "atLeastOneNumeric": "رقم واحد على الأقل", - "minimum8Characters": "8 أحرف على الأقل", - "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", - "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", - "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "human": "Human", - "resources": "Resources", - "profile": { - "reset_password": { - "label": "Reset Password", - "username": "Username", - "password": "password" - } - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "amount": { - "zero": "Your amount : {} ", - "one": "Your amount : {} ", - "two": "Your amount : {} ", - "few": "Your amount : {} ", - "many": "Your amount : {} ", - "other": "Your amount : {} " - }, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": { - "male": "Hi man ;) {}", - "female": "Hello girl :) {}" - } - }, - "reset_locale": "Reset Language" -}; -static const Map en_US = { - "mohemm": "Mohemm", - "english": "English", - "arabic": "Arabic", - "login": "Login", - "pleaseEnterLoginDetails": "Please enter the detail below to login", - "username": "Username", - "password": "Password", - "welcomeBack": "Welcome back", - "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", - "lastLoginDetails": "Last Login Details:", - "verificationType": "Verification Type:", - "pleaseVerify": "Please Verify", - "verifyThroughFace": "Verify Through Face", - "verifyThroughFingerprint": "Verify Through Fingerprint", - "verifyThroughSMS": "Verify Through SMS", - "verifyThroughWhatsapp": "Verify Through Whatsapp", - "useAnotherAccount": "Use Another Account", - "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", - "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "goodMorning": "Good Morning", - "markAttendance": "Mark Attendance", - "timeLeftToday": "Time Left Today", - "checkIn": "Check In", - "workList": "Work List", - "leaveBalance": "Leave Balance", - "missingSwipes": "Missing Swipes", - "ticketBalance": "Ticket Balance", - "other": "Other", - "services": "Services", - "viewAllServices": "View All Services", - "monthlyAttendance": "Monthly Attendance", - "workFromHome": "Work From Home", - "ticketRequest": "Ticket Request", - "viewAllOffers": "View All Offers", - "offers": "Offers & ", - "discounts": "Discounts", - "newString": "New", - "setTheNewPassword": "Set the new password", - "typeYourNewPasswordBelow": "Type your new password below", - "confirmPassword": "Confirm Password", - "update": "Update", - "title": "Title", - "home": "Home", - "mySalary": "My Salary", - "createRequest": "Create Request", - "forgotPassword": "Forgot Password", - "employeeId": "Employee ID", - "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", - "changePassword": "Change Password", - "ok": "OK", - "confirm": "Confirm", - "passwordChangedSuccessfully": "Password changed successfully", - "itemsForSale": "Items for Sale", - "doNotUseRecentPassword": "Do not use recent password", - "atLeastOneLowercase": "At least one lowercase", - "atLeastOneUppercase": "At least one uppercase", - "atLeastOneNumeric": "At least one numeric", - "minimum8Characters": "Minimum 8 characters", - "doNotAddRepeatingLetters": "Do not add repeating letters", - "itShouldContainSpecialCharacter": "It should contain special character", - "confirmPasswordMustMatch": "Confirm password must match", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "human": "Human", - "resources": "Resources", - "profile": { - "reset_password": { - "label": "Reset Password", - "username": "Username", - "password": "password" - } - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "amount": { - "zero": "Your amount : {} ", - "one": "Your amount : {} ", - "two": "Your amount : {} ", - "few": "Your amount : {} ", - "many": "Your amount : {} ", - "other": "Your amount : {} " - }, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": { - "male": "Hi man ;) {}", - "female": "Hello girl :) {}" - } - }, - "reset_locale": "Reset Language" -}; -static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; + static const Map ar_SA = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "تسجيل الدخول", + "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", + "username": "اسم المستخدم", + "password": "كلمة المرور", + "welcomeBack": "مرحبا بعودتك", + "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", + "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", + "verificationType": "نوع التحقق:", + "pleaseVerify": "ارجوك تحقق", + "verifyThroughFace": "تحقق من خلال الوجه", + "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", + "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", + "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", + "useAnotherAccount": "استخدم حسابا آخر", + "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", + "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", + "goodMorning": "صباح الخير", + "markAttendance": "علامة الحضور", + "timeLeftToday": "الوقت المتبقي اليوم", + "checkIn": "تحقق في", + "workList": "قائمة العمل", + "leaveBalance": "رصيد الاجازات", + "missingSwipes": "الضربات الشديدة في عداد المفقودين", + "ticketBalance": "رصيد التذكرة", + "other": "آخر", + "services": "خدمات", + "viewAllServices": "عرض جميع الخدمات", + "monthlyAttendance": "الحضور الشهري", + "workFromHome": "العمل من المنزل", + "ticketRequest": "طلب تذكرة", + "viewAllOffers": "مشاهدة جميع العروض", + "offers": "عروض & ", + "discounts": "الخصومات", + "newString": "جديد", + "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", + "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "confirmPassword": "تأكيد كلمة المرور", + "update": "تحديث", + "title": "عنوان", + "home": "مسكن", + "mySalary": "راتبي", + "createRequest": "إنشاء طلب", + "forgotPassword": "هل نسيت كلمة السر", + "employeeId": "هوية الموظف", + "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", + "changePassword": "تغيير كلمة المرور", + "ok": "موافق", + "confirm": "تؤكد", + "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", + "itemsForSale": "سلع للبيع", + "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", + "atLeastOneLowercase": "حرف صغير واحد على الأقل", + "atLeastOneUppercase": "حرف كبير واحد على الأقل", + "atLeastOneNumeric": "رقم واحد على الأقل", + "minimum8Characters": "8 أحرف على الأقل", + "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", + "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", + "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", + "sms": "رسالة قصيرة", + "fingerPrint": "بصمة", + "face": "التعرف على الوجه", + "whatsapp": "واتس اب", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "profile": { + "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"} + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "}, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} + }, + "reset_locale": "Reset Language" + }; + static const Map en_US = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "Login", + "pleaseEnterLoginDetails": "Please enter the detail below to login", + "username": "Username", + "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "newString": "New", + "setTheNewPassword": "Set the new password", + "typeYourNewPasswordBelow": "Type your new password below", + "confirmPassword": "Confirm Password", + "update": "Update", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", + "forgotPassword": "Forgot Password", + "employeeId": "Employee ID", + "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", + "changePassword": "Change Password", + "ok": "OK", + "confirm": "Confirm", + "passwordChangedSuccessfully": "Password changed successfully", + "itemsForSale": "Items for Sale", + "doNotUseRecentPassword": "Do not use recent password", + "atLeastOneLowercase": "At least one lowercase", + "atLeastOneUppercase": "At least one uppercase", + "atLeastOneNumeric": "At least one numeric", + "minimum8Characters": "Minimum 8 characters", + "doNotAddRepeatingLetters": "Do not add repeating letters", + "itShouldContainSpecialCharacter": "It should contain special character", + "confirmPasswordMustMatch": "Confirm password must match", + "sms": "SMS", + "fingerPrint": "Fingerprint", + "face": "Face", + "whatsapp": "Whatsapp", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "profile": { + "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"} + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "}, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} + }, + "reset_locale": "Reset Language" + }; + static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index b5ecc57..55e543b 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1,6 +1,6 @@ // DO NOT EDIT. This is code generated via package:easy_localization/generate.dart -abstract class LocaleKeys { +abstract class LocaleKeys { static const mohemm = 'mohemm'; static const english = 'english'; static const arabic = 'arabic'; @@ -61,11 +61,18 @@ abstract class LocaleKeys { static const doNotAddRepeatingLetters = 'doNotAddRepeatingLetters'; static const itShouldContainSpecialCharacter = 'itShouldContainSpecialCharacter'; static const confirmPasswordMustMatch = 'confirmPasswordMustMatch'; + static const sms = 'sms'; + static const fingerPrint = 'fingerPrint'; + static const face = 'face'; + static const whatsapp = 'whatsapp'; static const msg = 'msg'; static const msg_named = 'msg_named'; static const clickMe = 'clickMe'; static const human = 'human'; static const resources = 'resources'; + static const details = 'details'; + static const reject = 'reject'; + static const approve = 'approve'; static const profile_reset_password_label = 'profile.reset_password.label'; static const profile_reset_password_username = 'profile.reset_password.username'; static const profile_reset_password_password = 'profile.reset_password.password'; @@ -76,5 +83,4 @@ abstract class LocaleKeys { static const gender_with_arg = 'gender.with_arg'; static const gender = 'gender'; static const reset_locale = 'reset_locale'; - } diff --git a/lib/main.dart b/lib/main.dart index 49b0e35..20759d9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,18 +14,19 @@ import 'package:firebase_core/firebase_core.dart'; import 'config/routes.dart'; import 'package:logger/logger.dart'; - var logger = Logger( // filter: null, // Use the default LogFilter (-> only log in debug mode) printer: PrettyPrinter(lineLength: 0), // Use the PrettyPrinter to format and print log // output: null, // U ); - Future main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); await Firebase.initializeApp(); + AppState().setPostParamsModel( + PostParamsModel(channel: 31, versionID: 3.2, mobileType: Platform.isAndroid ? "android" : "ios"), + ); runApp( EasyLocalization( supportedLocales: const [ @@ -57,23 +58,22 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return AppProvider( - child: Sizer( - builder: (context, orientation, deviceType) { - AppState().setPostParamsModel( - PostParamsModel(languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, channel: 31, versionID: 3.2, mobileType: Platform.isAndroid ? "android" : "ios"), - ); - return MaterialApp( - theme: AppTheme.getTheme(EasyLocalization.of(context)?.locale.languageCode == "ar"), - debugShowCheckedModeBanner: false, - localizationsDelegates: context.localizationDelegates, - supportedLocales: context.supportedLocales, - locale: context.locale, - initialRoute: AppRoutes.initialRoute, - routes: AppRoutes.routes, - ); - }, - ), + return Sizer( + builder: (context, orientation, deviceType) { + print(AppState().postParamsObject?.toJson()); + var obj = AppState().postParamsObject; + obj?.languageID = EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2; + AppState().setPostParamsModel(obj!); + return MaterialApp( + theme: AppTheme.getTheme(EasyLocalization.of(context)?.locale.languageCode == "ar"), + debugShowCheckedModeBanner: false, + localizationsDelegates: context.localizationDelegates, + supportedLocales: context.supportedLocales, + locale: context.locale, + initialRoute: AppRoutes.initialRoute, + routes: AppRoutes.routes, + ); + }, ); } } diff --git a/lib/models/dashboard/itg_forms_model.dart b/lib/models/dashboard/itg_forms_model.dart index c5a0145..5ed719b 100644 --- a/lib/models/dashboard/itg_forms_model.dart +++ b/lib/models/dashboard/itg_forms_model.dart @@ -93,97 +93,163 @@ class ItgFormsModel { dynamic mohemmItgProjectsList; dynamic mohemmItgTicketTypesList; DateTime? referenceNumber; - dynamic requestType; + List? requestType; int? totalCount; int? statuseCode; factory ItgFormsModel.fromJson(Map json) => ItgFormsModel( - date: json["Date"], - languageId: json["LanguageID"] == null ? null : json["LanguageID"], - serviceName: json["ServiceName"] == null ? null : json["ServiceName"], - time: json["Time"], - androidLink: json["AndroidLink"], - authenticationTokenId: json["AuthenticationTokenID"], - data: json["Data"], - dataw: json["Dataw"] == null ? null : json["Dataw"], - dietType: json["DietType"] == null ? null : json["DietType"], - dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"], - errorCode: json["ErrorCode"], - errorEndUserMessage: json["ErrorEndUserMessage"], - errorEndUserMessageN: json["ErrorEndUserMessageN"], - errorMessage: json["ErrorMessage"], - errorType: json["ErrorType"] == null ? null : json["ErrorType"], - foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"], - iosLink: json["IOSLink"], - isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"], - mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"], - mealType: json["MealType"] == null ? null : json["MealType"], - messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"], - numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"], - patientBlodType: json["PatientBlodType"], - successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"], - successMsgN: json["SuccessMsgN"], - vidaUpdatedResponse: json["VidaUpdatedResponse"], - itgRequest: json["ITGRequest"], - itgFormAttachmentsList: json["Itg_FormAttachmentsList"], - message: json["Message"] == null ? null : json["Message"], - mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"], - mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"], - mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"], - mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"], - mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"], - mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"], - mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"], - mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"], - mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"], - referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]), - requestType: json["RequestType"], - totalCount: json["TotalCount"] == null ? null : json["TotalCount"], - statuseCode: json["statuseCode"] == null ? null : json["statuseCode"], - ); + date: json["Date"], + languageId: json["LanguageID"] == null ? null : json["LanguageID"], + serviceName: json["ServiceName"] == null ? null : json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"] == null ? null : json["Dataw"], + dietType: json["DietType"] == null ? null : json["DietType"], + dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorType: json["ErrorType"] == null ? null : json["ErrorType"], + foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"], + mealType: json["MealType"] == null ? null : json["MealType"], + messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + itgRequest: json["ITGRequest"], + itgFormAttachmentsList: json["Itg_FormAttachmentsList"], + message: json["Message"] == null ? null : json["Message"], + mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"], + mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"], + mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"], + mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"], + mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"], + mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"], + mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"], + mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"], + mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"], + referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]), + requestType: json["RequestType"] == null ? [] : json['RequestType']!.map((v) => RequestType.fromJson(v)).toList(), + totalCount: json["TotalCount"] == null ? null : json["TotalCount"], + statuseCode: json["statuseCode"] == null ? null : json["statuseCode"], + ); Map toMap() => { - "Date": date, - "LanguageID": languageId == null ? null : languageId, - "ServiceName": serviceName == null ? null : serviceName, - "Time": time, - "AndroidLink": androidLink, - "AuthenticationTokenID": authenticationTokenId, - "Data": data, - "Dataw": dataw == null ? null : dataw, - "DietType": dietType == null ? null : dietType, - "DietTypeID": dietTypeId == null ? null : dietTypeId, - "ErrorCode": errorCode, - "ErrorEndUserMessage": errorEndUserMessage, - "ErrorEndUserMessageN": errorEndUserMessageN, - "ErrorMessage": errorMessage, - "ErrorType": errorType == null ? null : errorType, - "FoodCategory": foodCategory == null ? null : foodCategory, - "IOSLink": iosLink, - "IsAuthenticated": isAuthenticated == null ? null : isAuthenticated, - "MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus, - "MealType": mealType == null ? null : mealType, - "MessageStatus": messageStatus == null ? null : messageStatus, - "NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords, - "PatientBlodType": patientBlodType, - "SuccessMsg": successMsg == null ? null : successMsg, - "SuccessMsgN": successMsgN, - "VidaUpdatedResponse": vidaUpdatedResponse, - "ITGRequest": itgRequest, - "Itg_FormAttachmentsList": itgFormAttachmentsList, - "Message": message == null ? null : message, - "Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList, - "Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList, - "Mohemm_ITG_ResponseItem": mohemmItgResponseItem, - "Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList, - "Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList, - "Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList, - "Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList, - "Mohemm_Itg_ProjectsList": mohemmItgProjectsList, - "Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList, - "ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(), - "RequestType": requestType, - "TotalCount": totalCount == null ? null : totalCount, - "statuseCode": statuseCode == null ? null : statuseCode, - }; + "Date": date, + "LanguageID": languageId == null ? null : languageId, + "ServiceName": serviceName == null ? null : serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw == null ? null : dataw, + "DietType": dietType == null ? null : dietType, + "DietTypeID": dietTypeId == null ? null : dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorType": errorType == null ? null : errorType, + "FoodCategory": foodCategory == null ? null : foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated == null ? null : isAuthenticated, + "MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus, + "MealType": mealType == null ? null : mealType, + "MessageStatus": messageStatus == null ? null : messageStatus, + "NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg == null ? null : successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "ITGRequest": itgRequest, + "Itg_FormAttachmentsList": itgFormAttachmentsList, + "Message": message == null ? null : message, + "Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList, + "Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList, + "Mohemm_ITG_ResponseItem": mohemmItgResponseItem, + "Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList, + "Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList, + "Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList, + "Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList, + "Mohemm_Itg_ProjectsList": mohemmItgProjectsList, + "Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList, + "ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(), + "RequestType": requestType == null ? null : requestType!.map((v) => v.toJson()).toList(), + "TotalCount": totalCount == null ? null : totalCount, + "statuseCode": statuseCode == null ? null : statuseCode, + }; +} + +class RequestType { + int? itemCount; + List? requestDetails; + String? requestTypeCode; + String? requestTypeName; + + RequestType({this.itemCount, this.requestDetails, this.requestTypeCode, this.requestTypeName}); + + RequestType.fromJson(Map json) { + itemCount = json['ItemCount']; + if (json['RequestDetails'] != null) { + requestDetails = []; + json['RequestDetails'].forEach((v) { + requestDetails!.add(new RequestDetails.fromJson(v)); + }); + } + requestTypeCode = json['RequestTypeCode']; + requestTypeName = json['RequestTypeName']; + } + + Map toJson() { + final Map data = new Map(); + data['ItemCount'] = this.itemCount; + if (this.requestDetails != null) { + data['RequestDetails'] = this.requestDetails!.map((v) => v.toJson()).toList(); + } + data['RequestTypeCode'] = this.requestTypeCode; + data['RequestTypeName'] = this.requestTypeName; + return data; + } +} + +class RequestDetails { + int? iD; + int? itemID; + String? listID; + String? listName; + String? modifiedDate; + String? title; + String? uRL; + + RequestDetails({this.iD, this.itemID, this.listID, this.listName, this.modifiedDate, this.title, this.uRL}); + + RequestDetails.fromJson(Map json) { + iD = json['ID']; + itemID = json['ItemID']; + listID = json['ListID']; + listName = json['ListName']; + modifiedDate = json['ModifiedDate']; + title = json['Title']; + uRL = json['URL']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['ItemID'] = this.itemID; + data['ListID'] = this.listID; + data['ListName'] = this.listName; + data['ModifiedDate'] = this.modifiedDate; + data['Title'] = this.title; + data['URL'] = this.uRL; + return data; + } } diff --git a/lib/models/dashboard/list_menu.dart b/lib/models/dashboard/list_menu.dart index ba327c2..a55cd79 100644 --- a/lib/models/dashboard/list_menu.dart +++ b/lib/models/dashboard/list_menu.dart @@ -18,22 +18,22 @@ class ListMenu { String? subMenuName; factory ListMenu.fromJson(Map json) => ListMenu( - menuId: json["MENU_ID"] == null ? null : json["MENU_ID"], - menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"], - menuType: json["MENU_TYPE"] == null ? null : json["MENU_TYPE"], - requestGroupId: json["REQUEST_GROUP_ID"] == null ? null : json["REQUEST_GROUP_ID"], - requestGroupName: json["REQUEST_GROUP_NAME"] == null ? null : json["REQUEST_GROUP_NAME"], - respId: json["RESP_ID"], - subMenuName: json["SUB_MENU_NAME"] == null ? null : json["SUB_MENU_NAME"], - ); + menuId: json["MENU_ID"] == null ? null : json["MENU_ID"], + menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"], + menuType: json["MENU_TYPE"] == null ? null : json["MENU_TYPE"], + requestGroupId: json["REQUEST_GROUP_ID"] == null ? null : json["REQUEST_GROUP_ID"], + requestGroupName: json["REQUEST_GROUP_NAME"] == null ? null : json["REQUEST_GROUP_NAME"], + respId: json["RESP_ID"], + subMenuName: json["SUB_MENU_NAME"] == null ? null : json["SUB_MENU_NAME"], + ); Map toJson() => { - "MENU_ID": menuId == null ? null : menuId, - "MENU_NAME": menuName == null ? null : menuName, - "MENU_TYPE": menuType == null ? null : menuType, - "REQUEST_GROUP_ID": requestGroupId == null ? null : requestGroupId, - "REQUEST_GROUP_NAME": requestGroupName == null ? null : requestGroupName, - "RESP_ID": respId, - "SUB_MENU_NAME": subMenuName == null ? null : subMenuName, - }; + "MENU_ID": menuId == null ? null : menuId, + "MENU_NAME": menuName == null ? null : menuName, + "MENU_TYPE": menuType == null ? null : menuType, + "REQUEST_GROUP_ID": requestGroupId == null ? null : requestGroupId, + "REQUEST_GROUP_NAME": requestGroupName == null ? null : requestGroupName, + "RESP_ID": respId, + "SUB_MENU_NAME": subMenuName == null ? null : subMenuName, + }; } diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index a9781d1..0b5c497 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,4 +1,5 @@ import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; import 'basic_member_information_model.dart'; import 'get_mobile_login_info_list_model.dart'; @@ -150,7 +151,7 @@ class GenericResponseModel { List? getVaccinationOnHandList; List? getVaccinationsList; List? getValueSetValuesList; - List? getWorkList; + List? getWorkList; String? hRCertificateTemplate; String? imgURLsList; String? insertApInv; @@ -612,7 +613,7 @@ class GenericResponseModel { getItemTypeNotificationsList = json['GetItemTypeNotificationsList']; getItemTypesList = json['GetItemTypesList']; getLookupValuesList = json['GetLookupValuesList']; - getMenuEntriesList= json["GetMenuEntriesList"] == null ? null : List.from(json["GetMenuEntriesList"].map((x) => GetMenuEntriesList.fromJson(x))); + getMenuEntriesList = json["GetMenuEntriesList"] == null ? null : List.from(json["GetMenuEntriesList"].map((x) => GetMenuEntriesList.fromJson(x))); getMoItemHistoryList = json['GetMoItemHistoryList']; getMoNotificationBodyList = json['GetMoNotificationBodyList']; getNotificationButtonsList = json['GetNotificationButtonsList']; @@ -656,7 +657,14 @@ class GenericResponseModel { getVaccinationOnHandList = json['GetVaccinationOnHandList']; getVaccinationsList = json['GetVaccinationsList']; getValueSetValuesList = json['GetValueSetValuesList']; - getWorkList = json['GetWorkList']; + + if (json['GetWorkList'] != null) { + getWorkList = []; + json['GetWorkList'].forEach((v) { + getWorkList!.add(WorkListResponseModel.fromJson(v)); + }); + } + hRCertificateTemplate = json['HRCertificateTemplate']; imgURLsList = json['ImgURLsList']; insertApInv = json['InsertApInv']; @@ -930,7 +938,11 @@ class GenericResponseModel { data['GetVaccinationOnHandList'] = this.getVaccinationOnHandList; data['GetVaccinationsList'] = this.getVaccinationsList; data['GetValueSetValuesList'] = this.getValueSetValuesList; - data['GetWorkList'] = this.getWorkList; + + if (getWorkList != null) { + data['GetWorkList'] = getWorkList!.map((v) => v.toJson()).toList(); + } + data['HRCertificateTemplate'] = this.hRCertificateTemplate; data['ImgURLsList'] = this.imgURLsList; data['InsertApInv'] = this.insertApInv; diff --git a/lib/models/worklist_item_type_model.dart b/lib/models/worklist_item_type_model.dart new file mode 100644 index 0000000..49346c0 --- /dev/null +++ b/lib/models/worklist_item_type_model.dart @@ -0,0 +1,38 @@ +import 'dart:ui'; + +class WorkListItemTypeModelData { + late int value; + late String name; + late String fullName; + late bool active; + late List color; + late String icon; + late String key; + late bool disable; + + WorkListItemTypeModelData({required this.value, required this.name, required this.fullName, required this.active, required this.color, required this.icon, required this.key, required this.disable}); + + WorkListItemTypeModelData.fromJson(Map json) { + value = json['value']; + name = json['name']; + fullName = json['fullName']; + active = json['active']; + color = json['color']; + icon = json['icon']; + key = json['key']; + disable = json['disable']; + } + + Map toJson() { + final Map data = {}; + data['value'] = value; + data['name'] = name; + data['fullName'] = fullName; + data['active'] = active; + data['color'] = color; + data['icon'] = icon; + data['key'] = key; + data['disable'] = disable; + return data; + } +} diff --git a/lib/models/worklist_response_model.dart b/lib/models/worklist_response_model.dart new file mode 100644 index 0000000..4899d5a --- /dev/null +++ b/lib/models/worklist_response_model.dart @@ -0,0 +1,137 @@ + +class WorkListResponseModel { + String? bEGINDATE; + String? dUEDATE; + String? eNDDATE; + String? fROMROLE; + int? fROMROWNUM; + String? fROMUSER; + String? fUNCTIONNAME; + String? iTEMKEY; + String? iTEMTYPE; + String? iTEMTYPEDISPLAYNAME; + String? lANGUAGE; + String? mAILSTATUS; + String? mOREINFOROLE; + int? nOTIFICATIONID; + String? nOTIFICATIONNAME; + int? nOOFROWS; + String? oRIGINALRECIPIENT; + String? pONUMBER; + int? pRIORITY; + String? pRIORITYF; + String? pRNUMBER; + String? rECIPIENTROLE; + String? rEQUESTNUMBER; + String? rEQUESTTYPE; + String? rESPONDER; + int? rOWNUM; + String? sELECTEDEMPLOYEENUMBER; + String? sTATUS; + String? sUBJECT; + int? tOROWNUM; + String? tOUSER; + + WorkListResponseModel( + {this.bEGINDATE, + this.dUEDATE, + this.eNDDATE, + this.fROMROLE, + this.fROMROWNUM, + this.fROMUSER, + this.fUNCTIONNAME, + this.iTEMKEY, + this.iTEMTYPE, + this.iTEMTYPEDISPLAYNAME, + this.lANGUAGE, + this.mAILSTATUS, + this.mOREINFOROLE, + this.nOTIFICATIONID, + this.nOTIFICATIONNAME, + this.nOOFROWS, + this.oRIGINALRECIPIENT, + this.pONUMBER, + this.pRIORITY, + this.pRIORITYF, + this.pRNUMBER, + this.rECIPIENTROLE, + this.rEQUESTNUMBER, + this.rEQUESTTYPE, + this.rESPONDER, + this.rOWNUM, + this.sELECTEDEMPLOYEENUMBER, + this.sTATUS, + this.sUBJECT, + this.tOROWNUM, + this.tOUSER}); + + WorkListResponseModel.fromJson(Map json) { + bEGINDATE = json['BEGIN_DATE']; + dUEDATE = json['DUE_DATE']; + eNDDATE = json['END_DATE']; + fROMROLE = json['FROM_ROLE']; + fROMROWNUM = json['FROM_ROW_NUM']; + fROMUSER = json['FROM_USER']; + fUNCTIONNAME = json['FUNCTION_NAME']; + iTEMKEY = json['ITEM_KEY']; + iTEMTYPE = json['ITEM_TYPE']; + iTEMTYPEDISPLAYNAME = json['ITEM_TYPE_DISPLAY_NAME']; + lANGUAGE = json['LANGUAGE']; + mAILSTATUS = json['MAIL_STATUS']; + mOREINFOROLE = json['MORE_INFO_ROLE']; + nOTIFICATIONID = json['NOTIFICATION_ID']; + nOTIFICATIONNAME = json['NOTIFICATION_NAME']; + nOOFROWS = json['NO_OF_ROWS']; + oRIGINALRECIPIENT = json['ORIGINAL_RECIPIENT']; + pONUMBER = json['PO_NUMBER']; + pRIORITY = json['PRIORITY']; + pRIORITYF = json['PRIORITY_F']; + pRNUMBER = json['PR_NUMBER']; + rECIPIENTROLE = json['RECIPIENT_ROLE']; + rEQUESTNUMBER = json['REQUEST_NUMBER']; + rEQUESTTYPE = json['REQUEST_TYPE']; + rESPONDER = json['RESPONDER']; + rOWNUM = json['ROW_NUM']; + sELECTEDEMPLOYEENUMBER = json['SELECTED_EMPLOYEE_NUMBER']; + sTATUS = json['STATUS']; + sUBJECT = json['SUBJECT']; + tOROWNUM = json['TO_ROW_NUM']; + tOUSER = json['TO_USER']; + } + + Map toJson() { + final Map data = new Map(); + data['BEGIN_DATE'] = this.bEGINDATE; + data['DUE_DATE'] = this.dUEDATE; + data['END_DATE'] = this.eNDDATE; + data['FROM_ROLE'] = this.fROMROLE; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['FROM_USER'] = this.fROMUSER; + data['FUNCTION_NAME'] = this.fUNCTIONNAME; + data['ITEM_KEY'] = this.iTEMKEY; + data['ITEM_TYPE'] = this.iTEMTYPE; + data['ITEM_TYPE_DISPLAY_NAME'] = this.iTEMTYPEDISPLAYNAME; + data['LANGUAGE'] = this.lANGUAGE; + data['MAIL_STATUS'] = this.mAILSTATUS; + data['MORE_INFO_ROLE'] = this.mOREINFOROLE; + data['NOTIFICATION_ID'] = this.nOTIFICATIONID; + data['NOTIFICATION_NAME'] = this.nOTIFICATIONNAME; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['ORIGINAL_RECIPIENT'] = this.oRIGINALRECIPIENT; + data['PO_NUMBER'] = this.pONUMBER; + data['PRIORITY'] = this.pRIORITY; + data['PRIORITY_F'] = this.pRIORITYF; + data['PR_NUMBER'] = this.pRNUMBER; + data['RECIPIENT_ROLE'] = this.rECIPIENTROLE; + data['REQUEST_NUMBER'] = this.rEQUESTNUMBER; + data['REQUEST_TYPE'] = this.rEQUESTTYPE; + data['RESPONDER'] = this.rESPONDER; + data['ROW_NUM'] = this.rOWNUM; + data['SELECTED_EMPLOYEE_NUMBER'] = this.sELECTEDEMPLOYEENUMBER; + data['STATUS'] = this.sTATUS; + data['SUBJECT'] = this.sUBJECT; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['TO_USER'] = this.tOUSER; + return data; + } +} \ No newline at end of file diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index b52448e..f15e244 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -6,6 +6,7 @@ import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; +import 'package:mohem_flutter_app/models/dashboard/get_open_notifications_list.dart'; import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; import 'package:mohem_flutter_app/models/dashboard/menus.dart'; @@ -39,9 +40,9 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List? getMenuEntriesList; //Attendance Tracking API's & Methods - fetchAttendanceTracking() async { + void fetchAttendanceTracking() async { try { - attendanceTracking = await DashbaordApiClient().getAttendanceTracking(); + attendanceTracking = await DashboardApiClient().getAttendanceTracking(); isAttendanceTrackingLoading = false; isTimeRemainingInSeconds = calculateSeconds("00:00:00"); endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; @@ -67,31 +68,36 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { attendanceTracking?.pSwipeIn = "a"; isTimeRemainingInSeconds = calculateSeconds("00:10:30"); endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; - notifyListeners(); } + ItgFormsModel? itgFormsModel; + List? getOpenNotificationsList; //Work List API's & Methods - fetchWorkListCounter() async { + Future fetchWorkListCounter(context, {bool showLoading = false}) async { try { - GenericResponseModel? genericResponseModel = await DashbaordApiClient().getOpenNotifications(); + if (showLoading) Utils.showLoading(context); + GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenNotifications(); isWorkListLoading = false; + getOpenNotificationsList = genericResponseModel?.getOpenNotificationsList; workListCounter = genericResponseModel?.pOPENNTFNUMBER ?? 0; - ItgFormsModel? itgFormsModel = await DashbaordApiClient().getItgFormsPendingTask(); + itgFormsModel = await DashboardApiClient().getItgFormsPendingTask(); workListCounter = workListCounter + (itgFormsModel?.totalCount ?? 0); + if (showLoading) Utils.hideLoading(context); notifyListeners(); } catch (ex) { isWorkListLoading = false; logger.wtf(ex); + if (showLoading) Utils.hideLoading(context); notifyListeners(); Utils.handleException(ex, null); } } //Missing Siwpe API's & Methods - fetchMissingSwipe() async { + Future fetchMissingSwipe() async { try { - GenericResponseModel? genericResponseModel = await DashbaordApiClient().getOpenMissingSwipes(); + GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenMissingSwipes(); isMissingSwipeLoading = false; missingSwipeCounter = genericResponseModel!.getOpenMissingSwipesList!.pOpenMissingSwipes ?? 0; notifyListeners(); @@ -104,9 +110,9 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } //Leave and Ticket Balance API's & Methods - fetchLeaveTicketBalance() async { + Future fetchLeaveTicketBalance() async { try { - GenericResponseModel? genericResponseModel = await DashbaordApiClient().getAccrualBalances(); + GenericResponseModel? genericResponseModel = await DashboardApiClient().getAccrualBalances(); isLeaveTicketBalanceLoading = false; leaveBalance = genericResponseModel?.getAccrualBalancesList![0].accrualNetEntitlement ?? 0.0; ticketBalance = (genericResponseModel?.getAccrualBalancesList![1].accrualNetEntitlement ?? 0.0) + (genericResponseModel?.getAccrualBalancesList![2].accrualNetEntitlement ?? 0.0); @@ -122,12 +128,12 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { //List Menu API's & Methods fetchListMenu() async { try { - GenericResponseModel? genericResponseModel = await DashbaordApiClient().getListMenu(); + GenericResponseModel? genericResponseModel = await DashboardApiClient().getListMenu(); Map map = {}; print(jsonEncode(genericResponseModel!.listMenu)); - for (int i = 0; i < genericResponseModel!.listMenu!.length; i++) { - print(genericResponseModel!.listMenu![i]!.menuName ?? ""); - map[genericResponseModel!.listMenu![i]!.menuName ?? ""] = i.toString(); + for (int i = 0; i < genericResponseModel.listMenu!.length; i++) { + print(genericResponseModel.listMenu![i].menuName ?? ""); + map[genericResponseModel.listMenu![i].menuName ?? ""] = i.toString(); } logger.i(map); notifyListeners(); @@ -141,7 +147,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { //Menu Entries API's & Methods fetchMenuEntries() async { try { - GenericResponseModel? genericResponseModel = await DashbaordApiClient().getGetMenuEntries(); + GenericResponseModel? genericResponseModel = await DashboardApiClient().getGetMenuEntries(); getMenuEntriesList = genericResponseModel!.getMenuEntriesList; homeMenus = parseMenues(getMenuEntriesList ?? []); isServicesMenusLoading = false; diff --git a/lib/ui/app_bar.dart b/lib/ui/app_bar.dart deleted file mode 100644 index c39e249..0000000 --- a/lib/ui/app_bar.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:easy_localization/src/public_ext.dart'; -import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/classes/colors.dart'; -import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; - -AppBar appBar(BuildContext context, {required String title}) { - return AppBar( - title: title.toText24(color: MyColors.darkTextColor), - centerTitle: false, - automaticallyImplyLeading: false, - backgroundColor: Colors.white, - - actions: [ - IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: Icon( - Icons.close, - color: MyColors.darkIconColor, - ), - ), - ], - ); -} diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 92ea49d..f7260cf 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -1,30 +1,20 @@ -import 'dart:convert'; - import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart'; -import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; -import 'package:mohem_flutter_app/models/dashboard/menus.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; -import 'package:mohem_flutter_app/theme/colors.dart'; import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart'; import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; -import 'package:shimmer/shimmer.dart'; - -import '../../main.dart'; class DashboardScreen extends StatefulWidget { DashboardScreen({Key? key}) : super(key: key); @@ -36,14 +26,14 @@ class DashboardScreen extends StatefulWidget { } class _DashboardScreenState extends State { - late var data; + late DashboardProviderModel data; @override void initState() { super.initState(); data = Provider.of(context, listen: false); data.fetchAttendanceTracking(); - data.fetchWorkListCounter(); + data.fetchWorkListCounter(context); data.fetchMissingSwipe(); data.fetchLeaveTicketBalance(); // data.fetchMenuEntries(); @@ -129,100 +119,101 @@ class _DashboardScreenState extends State { children: [ Expanded( child: AspectRatio( - aspectRatio: 159 / 159, - child: Consumer( - builder: (context, model, child) { - return (model.isAttendanceTrackingLoading - ? GetAttendanceTrackingShimmer() - : Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Stack( - alignment: Alignment.center, - children: [ - if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), - if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white), - if (model.isTimeRemainingInSeconds != 0) - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 9.height, - CountdownTimer( - endTime: model.endTime, - onEnd: null, - endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), - textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), - ), - LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), - 9.height, - const ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(20), - ), - child: LinearProgressIndicator( - value: 0.7, - minHeight: 8, - valueColor: const AlwaysStoppedAnimation(Colors.white), - backgroundColor: const Color(0xff196D73), - ), - ), - ], - ), - ], - ).paddingOnly(top: 12, right: 15, left: 12), - ), - Row( + aspectRatio: 159 / 159, + child: Consumer( + builder: (context, model, child) { + return (model.isAttendanceTrackingLoading + ? GetAttendanceTrackingShimmer() + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Stack( + alignment: Alignment.center, + children: [ + if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white), + if (model.isTimeRemainingInSeconds != 0) + Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.checkIn.tr().toText12(color: Colors.white), - (model.isTimeRemainingInSeconds == 0 ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true), - 4.height + 9.height, + CountdownTimer( + endTime: model.endTime, + onEnd: null, + endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), + textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), + ), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + const ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), ], - ).paddingOnly(left: 12), - ), - Container( - width: 45, - height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), - decoration: const BoxDecoration( - color: Color(0xff259EA4), - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(15), - ), ), - child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"), - ), ], - ), - ], - ), - ], - ), - ).onPress(() { - Navigator.pushNamed(context, AppRoutes.todayAttendance); - })) - .animatedSwither(); - }, - )), + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.checkIn.tr().toText12(color: Colors.white), + (model.isTimeRemainingInSeconds == 0 ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true), + 4.height + ], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"), + ), + ], + ), + ], + ), + ], + ), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.todayAttendance); + })) + .animatedSwither(); + }, + ), + ), ), 9.width, Expanded( diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index ac42dd1..b2ab7aa 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -83,7 +83,7 @@ class _TodayAttendanceScreenState extends State { padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), decoration: BoxDecoration( borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), - gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ MyColors.gradiantEndColor, MyColors.gradiantStartColor, ]), @@ -156,7 +156,7 @@ class _TodayAttendanceScreenState extends State { padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ MyColors.gradiantEndColor, MyColors.gradiantStartColor, ]), diff --git a/lib/ui/landing/widget/menus_widget.dart b/lib/ui/landing/widget/menus_widget.dart index 4d13775..5d73f0a 100644 --- a/lib/ui/landing/widget/menus_widget.dart +++ b/lib/ui/landing/widget/menus_widget.dart @@ -14,7 +14,7 @@ class MenusWidget extends StatelessWidget { Widget build(BuildContext context) { List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; - return Consumer(builder: (context, data, child) { + return Consumer(builder: (cxt, data, child) { return GridView( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), padding: EdgeInsets.zero, @@ -24,7 +24,7 @@ class MenusWidget extends StatelessWidget { children: [ data.isWorkListLoading ? MenuShimmer().onPress(() { - data.fetchWorkListCounter(); + data.fetchWorkListCounter(context, showLoading: true); }) : Container( decoration: BoxDecoration( @@ -46,13 +46,13 @@ class MenusWidget extends StatelessWidget { ) ], ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), - ).onPress(() { - // Navigator.pushNamed(context, AppRoutes.workList); - data.fetchWorkListCounter(); + ).onPress(() async { + //await data.fetchWorkListCounter(context, showLoading: true); + Navigator.pushNamed(context, AppRoutes.workList); }), data.isMissingSwipeLoading ? MenuShimmer().onPress(() { - data.fetchWorkListCounter(); + data.fetchWorkListCounter(context); }) : Container( decoration: BoxDecoration( @@ -79,7 +79,7 @@ class MenusWidget extends StatelessWidget { }), data.isLeaveTicketBalanceLoading ? MenuShimmer().onPress(() { - data.fetchWorkListCounter(); + data.fetchWorkListCounter(context); }) : Container( decoration: BoxDecoration( @@ -106,7 +106,7 @@ class MenusWidget extends StatelessWidget { }), data.isLeaveTicketBalanceLoading ? MenuShimmer().onPress(() { - data.fetchWorkListCounter(); + data.fetchWorkListCounter(context); }) : Container( decoration: BoxDecoration( diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 533e9ee..d98fda8 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -69,12 +69,12 @@ class _LoginScreenState extends State { } String? firebaseToken; - + GetMobileLoginInfoListModel? loginInfo; Future checkFirebaseToken() async { try { Utils.showLoading(context); firebaseToken = await _firebaseMessaging.getToken(); - GetMobileLoginInfoListModel? loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); if (loginInfo == null) { Utils.hideLoading(context); print("Device token not found"); @@ -112,7 +112,7 @@ class _LoginScreenState extends State { } Utils.hideLoading(context); if (_autoLogin) { - Navigator.pushNamed(context, AppRoutes.verifyLastLogin); + Navigator.pushNamed(context, AppRoutes.verifyLastLogin, arguments: loginInfo); } else { Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken"); } @@ -127,8 +127,8 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { - username.text="15153"; - password.text="Riyadh@1234"; + username.text = "15153"; + password.text = "a123a123a123"; return Scaffold( body: Column( children: [ diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 282c7a5..52ec751 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -7,6 +7,7 @@ import 'package:local_auth/local_auth.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; @@ -16,6 +17,7 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; class VerifyLastLoginScreen extends StatefulWidget { @@ -30,6 +32,7 @@ class VerifyLastLoginScreen extends StatefulWidget { class _VerifyLastLoginScreenState extends State { final LocalAuthentication auth = LocalAuthentication(); List _availableBioMetricType = []; + GetMobileLoginInfoListModel? mobileLoginInfoListModel; @override void initState() { @@ -40,6 +43,7 @@ class _VerifyLastLoginScreenState extends State { @override Widget build(BuildContext context) { + mobileLoginInfoListModel ??= ModalRoute.of(context)!.settings.arguments as GetMobileLoginInfoListModel; String empName = AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!; return Scaffold( appBar: AppBar( @@ -64,7 +68,7 @@ class _VerifyLastLoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.welcomeBack.tr().toText12(), - empName.toText24(isBold: true), + mobileLoginInfoListModel!.employeeName!.toText24(isBold: true), 10.height, LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), Container( @@ -88,14 +92,7 @@ class _VerifyLastLoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ LocaleKeys.lastLoginDetails.tr().toText16(), - // Text( - // user.editedOn != null - // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) - // : user.createdOn != null - // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn)) - // : '--', - // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), - // ), + DateUtil.formatDateToDate(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!), false).toText12(), ], ), Row( @@ -103,24 +100,9 @@ class _VerifyLastLoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), - Text( - "SMS", - // " " + getType(user.logInType, context), - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - ), - ), + getVerificationType(mobileLoginInfoListModel!.loginType!).toText12(), Expanded(child: SizedBox()), - // Text( - // user.editedOn != null - // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false) - // : user.createdOn != null - // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false) - // : '--', - // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), - // ), + DateUtil.formatDateToTime(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!)).toText12(), ], ) ], @@ -201,419 +183,18 @@ class _VerifyLastLoginScreenState extends State { if (mounted) setState(() {}); } - // authenticateUser(int type, {int isActive}) { - // GifLoaderDialogUtils.showMyDialog(context); - // if (type == 2 || type == 3) { - // fingrePrintBefore = type; - // } - // this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; - // - // switch (type) { - // case 1: - // this.loginWithSMS(type); - // break; - // case 2: - // this.loginWithFingurePrintFace(type, isActive); - // break; - // case 3: - // this.loginWithFingurePrintFace(type, isActive); - // break; - // case 4: - // this.loginWithSMS(type); - // break; - // default: - // break; - // } - // sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); - // } -// -// loginWithSMS(type) { -// //if (!el.disabled) { -// if (this.user != null && this.registerd_data == null) { -// this.checkUserAuthentication(type); -// } else { -// if (this.loginTokenID != null) { -// // Future.delayed(Duration(seconds: 1), () { -// this.sendActivationCode(type); -// // }); -// } else { -// this.checkUserAuthentication(type); -// } -// } -// } -// -// checkUserAuthentication(type) { -// showLoader(true); -// var req = getCommonRequest(type: type); -// req.logInTokenID = ""; -// -// var request = CheckPatientAuthenticationReq.fromJson(req.toJson()); -// -// sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); -// authService -// .checkPatientAuthentication(request) -// .then((value) => { -// GifLoaderDialogUtils.hideDialog(context), -// if (value['isSMSSent']) -// { -// sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), -// this.loginTokenID = value['LogInTokenID'], -// sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), -// // Future.delayed(Duration(seconds: 1), () { -// this.sendActivationCode(type) -// // }) -// } -// else -// { -// if (value['IsAuthenticated']) {this.checkActivationCode()} -// } -// }) -// .catchError((err) { -// print(err); -// GifLoaderDialogUtils.hideDialog(context); -// }); -// } -// -// sendActivationCode(type) async { -// var request = this.getCommonRequest(type: type); -// request.sMSSignature = await SMSOTP.getSignature(); -// GifLoaderDialogUtils.showMyDialog(context); -// if (healthId != null) { -// // final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); -// // final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); -// request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); -// request.healthId = healthId; -// request.isHijri = isHijri; -// await this.authService.sendActivationCodeRegister(request).then((result) { -// GifLoaderDialogUtils.hideDialog(context); -// if (result != null && result['isSMSSent'] == true) { -// this.startSMSService(type); -// } -// }).catchError((r) { -// GifLoaderDialogUtils.hideDialog(context); -// }); -// } else { -// request.dob = ""; -// request.healthId = ""; -// request.isHijri = 0; -// await this.authService.sendActivationCode(request).then((result) { -// GifLoaderDialogUtils.hideDialog(context); -// if (result != null && result['isSMSSent'] == true) { -// this.startSMSService(type); -// } -// }).catchError((r) { -// GifLoaderDialogUtils.hideDialog(context); -// }); -// } -// } -// -// var tempType; -// -// startSMSService(type) { -// tempType = type; -// new SMSOTP( -// context, -// type, -// this.mobileNumber, -// (value) { -// this.checkActivationCode(value: value); -// }, -// () => { -// Navigator.pop(context), -// }, -// ).displayDialog(context); -// } -// -// loginWithFingurePrintFace(type, int isActive) async { -// if (isActive == 1 || isActive == 0) { -// const iosStrings = -// const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); -// -// try { -// authenticated = await auth.authenticateWithBiometrics(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); -// } on PlatformException catch (e) { -// GifLoaderDialogUtils.hideDialog(context); -// AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); -// } -// -// if (authenticated == true) { -// // if (user != null && (user.logInType == 2 || user.logInType == 3)) { -// // this.checkActivationCode(); -// // } else { -// -// var request = this.getCommonRequest(type: type); -// this.getMobileInfo(request); -// //} -// } -// } -// } -// -// getMobileInfo(request) { -// // GifLoaderDialogUtils.showMyDialog(context); -// this.authService.getLoginInfo(request).then((result) { -// GifLoaderDialogUtils.hideDialog(context); -// if (result['SMSLoginRequired'] == false) { -// this.loginTokenID = result['LogInTokenID']; -// this.patientOutSA = result['PatientOutSA']; -// // sms for register the biometric -// if (result['isSMSSent']) { -// setState(() { -// isMoreOption = true; -// this.onlySMSBox = true; -// // this.fingrePrintBefore = true; -// }); -// //this.button(); -// } else { -// setDefault(); -// checkActivationCode(); -// } -// } else { -// if (result['IsAuthenticated'] == true) { -// setState(() { -// isMoreOption = true; -// this.onlySMSBox = true; -// // this.fingrePrintBefore = true; -// }); -// } -// } -// }).catchError((err) { -// GifLoaderDialogUtils.hideDialog(context); -// print(err); -// }); -// } -// -// setDefault() async { -// if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); -// -// if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { -// isMoreOption = true; -// this.registerd_data = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); -// } -// -// this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.mobile); -// this.zipCode = this.registerd_data != null -// ? this.registerd_data.zipCode -// : this.user.outSA == true -// ? "971" -// : "966"; -// this.patientOutSA = this.registerd_data != null -// ? this.registerd_data.zipCode == "966" -// ? 0 -// : 1 -// : this.user.outSA; -// if (this.registerd_data != null) { -// this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); -// this.loginType = this.registerd_data.searchType; -// } -// var nhic = await sharedPref.getObject(NHIC_DATA); -// if (nhic != null) { -// final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); -// final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); -// dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); -// -// isHijri = nhic['IsHijri'] ? 1 : 0; -// healthId = nhic['HealthId']; -// } -// this.deviceToken = await sharedPref.getString(PUSH_TOKEN); -// this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null -// ? await sharedPref.getInt(LAST_LOGIN) -// : user != null -// ? user.logInType -// : null; -// -// //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); -// } -// -// getCommonRequest({type}) { -// var request = SendActivationRequest(); -// request.patientMobileNumber = this.mobileNumber; -// request.mobileNo = '0' + this.mobileNumber.toString(); -// request.deviceToken = this.deviceToken; -// request.projectOutSA = this.patientOutSA == true ? true : false; -// request.loginType = this.selectedOption; -// request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; -// request.zipCode = this.zipCode; -// -// request.logInTokenID = this.loginTokenID ?? ""; -// -// if (this.registerd_data != null) { -// request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; -// request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; -// request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; -// -// request.isRegister = this.registerd_data.isRegister; -// } else { -// request.searchType = request.searchType != null ? request.searchType : 2; -// request.patientID = this.user.patientID != null ? this.user.patientID : 0; -// request.nationalID = request.nationalID != null ? request.nationalID : '0'; -// request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; -// request.isRegister = false; -// } -// request.deviceTypeID = request.searchType; -// return request; -// } -// -// // checkActivationCode({value}) async { -// // // Navigator.pop(context); -// // GifLoaderDialogUtils.showMyDialog(context); -// // var request = this.getCommonRequest().toJson(); -// // dynamic res; -// // if (healthId != null) { -// // request['DOB'] = dob; -// // request['HealthId'] = healthId; -// // request['IsHijri'] = isHijri; -// // -// // authService -// // .checkActivationCodeRegister(request, value) -// // .then((result) => { -// // res = result, -// // if (result is Map) -// // { -// // result = CheckActivationCode.fromJson(result), -// // if (this.registerd_data != null && this.registerd_data.isRegister == true) -// // { -// // widget.changePageViewIndex(1), -// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), -// // } -// // } -// // else -// // { -// // // Navigator.of(context).pop(), -// // GifLoaderDialogUtils.hideDialog(context), -// // Future.delayed(Duration(seconds: 1), () { -// // AppToast.showErrorToast(message: result); -// // }), -// // } -// // }) -// // .catchError((err) { -// // print(err); -// // GifLoaderDialogUtils.hideDialog(context); -// // Future.delayed(Duration(seconds: 1), () { -// // AppToast.showErrorToast(message: err); -// // startSMSService(tempType); -// // }); -// // }); -// // } else { -// // authService -// // .checkActivationCode(request, value) -// // .then((result) => { -// // res = result, -// // if (result is Map) -// // { -// // result = CheckActivationCode.fromJson(result), -// // if (this.registerd_data != null && this.registerd_data.isRegister == true) -// // { -// // widget.changePageViewIndex(1), -// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), -// // } -// // else -// // { -// // sharedPref.remove(FAMILY_FILE), -// // result.list.isFamily = false, -// // userData = result.list, -// // sharedPref.setString(BLOOD_TYPE, result.patientBloodType), -// // authenticatedUserObject.user = result.list, -// // projectViewModel.setPrivilege(privilegeList: res), -// // sharedPref.setObject(MAIN_USER, result.list), -// // sharedPref.setObject(USER_PROFILE, result.list), -// // loginTokenID = result.logInTokenID, -// // sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), -// // sharedPref.setString(TOKEN, result.authenticationTokenID), -// // checkIfUserAgreedBefore(result), -// // } -// // } -// // else -// // { -// // // // Navigator.of(context).pop(), -// // // GifLoaderDialogUtils.hideDialog(context), -// // // Future.delayed(Duration(seconds: 1), () { -// // // AppToast.showErrorToast(message: result); -// // // startSMSService(tempType); -// // // }), -// // } -// // }) -// // .catchError((err) { -// // // print(err); -// // // GifLoaderDialogUtils.hideDialog(context); -// // // Future.delayed(Duration(seconds: 1), () { -// // // AppToast.showErrorToast(message: err); -// // // startSMSService(tempType); -// // // }); -// // }); -// // } -// // } -// -// // checkIfUserAgreedBefore(CheckActivationCode result) { -// // if (result.isNeedUserAgreement == true) { -// // //move to agreement page. -// // } else { -// // goToHome(); -// // } -// // } -// -// insertIMEI() { -// authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { -// print(err); -// }); -// } -// -// // getToDoCount() { -// // toDoProvider.setState(0, true, "0"); -// // ClinicListService service = new ClinicListService(); -// // service.getActiveAppointmentNo(context).then((res) { -// // if (res['MessageStatus'] == 1) { -// // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); -// // } else {} -// // }).catchError((err) { -// // print(err); -// // }); -// // } -// -// // goToHome() async { -// // authenticatedUserObject.isLogin = true; -// // appointmentRateViewModel.isLogin = true; -// // projectViewModel.isLogin = true; -// // projectViewModel.user = authenticatedUserObject.user; -// // await authenticatedUserObject.getUser(getUser: true); -// // -// // // getToDoCount(); -// // -// // appointmentRateViewModel -// // .getIsLastAppointmentRatedList() -// // .then((value) => { -// // getToDoCount(), -// // GifLoaderDialogUtils.hideDialog(AppGlobal.context), -// // if (appointmentRateViewModel.isHaveAppointmentNotRate) -// // { -// // Navigator.pushAndRemoveUntil( -// // context, -// // FadePage( -// // page: RateAppointmentDoctor(), -// // ), -// // (r) => false) -// // } -// // else -// // { -// // Navigator.pushAndRemoveUntil( -// // context, -// // FadePage( -// // page: LandingPage(), -// // ), -// // (r) => false) -// // }, -// // insertIMEI() -// // }) -// // .catchError((err) { -// // print(err); -// // }); -// // } -// -// loading(flag) { -// // setState(() { -// // isLoading = flag; -// // }); -// } -// + String getVerificationType(int type) { + if (type == 1) { + LocaleKeys.sms.tr(); + } else if (type == 2) { + return LocaleKeys.fingerPrint.tr(); + } else if (type == 3) { + return LocaleKeys.face.tr(); + } else if (type == 4) { + return LocaleKeys.whatsapp.tr(); + } + return ""; + } Future loginWithFaceIDAndBiometrics() async { IOSAuthMessages iosStrings = @@ -654,8 +235,8 @@ class _VerifyLastLoginScreenState extends State { } await LoginApiClient().checkMobileAppVersion(); await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!); - BasicMemberInformationModel? memberInformationModel = await LoginApiClient() - .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName); + BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType( + checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName); Utils.hideLoading(context); OtpDialog( context, diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart index 4af620e..0a27afc 100644 --- a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -1,56 +1,85 @@ +import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; -import 'package:mohem_flutter_app/ui/app_bar.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/actions_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/attachments_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_fragments.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:mohem_flutter_app/extensions/int_extensions.dart'; -class MissingSwipeScreen extends StatelessWidget { +class MissingSwipeScreen extends StatefulWidget { + MissingSwipeScreen({Key? key}) : super(key: key); + + @override + _MissingSwipeScreenState createState() { + return _MissingSwipeScreenState(); + } +} + +class _MissingSwipeScreenState extends State { + int tabIndex = 0; + PageController controller = PageController(); + bool showFabOptions = false; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + @override Widget build(BuildContext context) { - return DefaultTabController( - length: 4, - child: Scaffold( - appBar: appBar(context, title: "Missing Swipe Request"), - body: Container( - width: double.infinity, - height: double.infinity, - child: Column( + return Scaffold( + appBar: AppBarWidget(context, title: LocaleKeys.details.tr()), + backgroundColor: Colors.white, + body: Stack( + children: [ + Column( children: [ Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), - gradient: LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), + padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + gradient: LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), ), - clipBehavior: Clip.antiAlias, - child: TabBar( - indicatorColor: Colors.white, - labelColor: Colors.white, - tabs: [ - Tab( - text: "Request", - ), - Tab( - text: "Actions", - ), - Tab( - text: "Attachments", - ), - Tab( - text: "Info.", - ), + child: Row( + children: [ + myTab("Request", 0), + myTab("Actions", 1), + myTab("Attachments", 2), + myTab("Info.", 3), ], ), ), Expanded( - child: TabBarView( + child: PageView( + controller: controller, + onPageChanged: (pageIndex) { + setState(() { + tabIndex = pageIndex; + }); + }, children: [ RequestFragment(), ActionsFragment(), @@ -60,39 +89,140 @@ class MissingSwipeScreen extends StatelessWidget { ), ), Container( - width: double.infinity, - height: 60, - padding: EdgeInsets.only(left: 21, right: 21), + padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21), + decoration: const BoxDecoration( + color: Colors.white, + border: Border( + top: BorderSide( + color: MyColors.lightGreyEFColor, + width: 1.0, + ), + ), + ), child: Row( children: [ - Expanded( - child: DefaultButton( - "Reject", - () {}, - colors: [ - Color(0xffEB8C90), - Color(0xffDE6C70), - ], - ), - ), - 12.width, - Expanded( - child: DefaultButton( - "Approve", - () {}, - colors: [ - Color(0xff32D892), - Color(0xff1AB170), - ], + DefaultButton( + LocaleKeys.reject.tr(), + () {}, + colors: const [ + Color(0xffEB8C90), + Color(0xffDE6C70), + ], + ).expanded, + 8.width, + DefaultButton( + LocaleKeys.approve.tr(), + () {}, + colors: const [ + Color(0xff32D892), + Color(0xff1AB170), + ], + ).expanded, + 8.width, + Container( + height: 43, + width: 43, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: MyColors.lightGreyE6Color, ), - ), + child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor), + ).onPress(() { + setState(() { + showFabOptions = true; + }); + }) ], ), ) ], ), - ), + IgnorePointer( + ignoring: !showFabOptions, + child: AnimatedOpacity( + opacity: showFabOptions ? 1 : 0, + duration: const Duration(milliseconds: 250), + child: Container( + padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75), + width: double.infinity, + height: double.infinity, + color: Colors.white.withOpacity(.67), + alignment: Alignment.bottomRight, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + myFab("Skip", "assets/images/skip.svg"), + 12.height, + myFab("Request Info", "assets/images/request_info.svg"), + 12.height, + myFab("Delegate", "assets/images/delegate.svg"), + ], + ), + ), + ).onPress(() { + setState(() { + showFabOptions = false; + }); + }), + ), + ], ), ); } + + Widget myTab(String title, int index) { + bool isSelected = (index == tabIndex); + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + title.toText12(color: isSelected ? Colors.white : Colors.white.withOpacity(.74), isCenter: true), + 4.height, + Container( + height: 8, + width: 8, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isSelected ? Colors.white : Colors.transparent, + ), + ).onPress(() { + setState(() { + showFabOptions = true; + }); + }) + ], + ).onPress(() { + controller.jumpToPage(index); + }).expanded; + } + + Widget myFab(String title, String icon) { + return Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + title.toText16(), + 14.width, + Container( + height: 43, + width: 43, + padding: const EdgeInsets.all(12), + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + child: SvgPicture.asset(icon), + ) + ], + ); + } } diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 06a545c..1e46783 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -1,29 +1,116 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; -import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:mohem_flutter_app/ui/app_bar.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; +import 'package:mohem_flutter_app/models/worklist_item_type_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:provider/provider.dart'; class WorkListScreen extends StatefulWidget { + WorkListScreen({Key? key}) : super(key: key); + @override - State createState() => _WorkListScreenState(); + _WorkListScreenState createState() { + return _WorkListScreenState(); + } } class _WorkListScreenState extends State { + List workListItemTypes = [ + WorkListItemTypeModelData( + value: 0, name: 'HR', fullName: 'Human Resource', active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'HRSSA', disable: false), + WorkListItemTypeModelData( + value: 0, name: 'MO', fullName: 'Move Order', active: false, color: [Color(0xff58DCFA), Color(0xff3CB9D5)], icon: "assets/images/miss_swipe.svg", key: 'INVMOA', disable: false), + WorkListItemTypeModelData( + value: 0, name: 'PR', fullName: 'Purchase Requisition', active: false, color: [Color(0xff48EACF), Color(0xff3DCAB3)], icon: "assets/images/miss_swipe.svg", key: 'REQAPPRV', disable: false), + WorkListItemTypeModelData( + value: 0, name: 'PO', fullName: 'Purchase Order', active: false, color: [Color(0xff5099E3), Color(0xff3670AA)], icon: "assets/images/miss_swipe.svg", key: 'POAPPRV', disable: false), + WorkListItemTypeModelData( + value: 0, name: 'ITG', fullName: 'ITG Forms', active: false, color: [Color(0xffEB8C90), Color(0xffDE6C70)], icon: "assets/images/miss_swipe.svg", key: 'ITG', disable: false), + WorkListItemTypeModelData( + value: 0, name: 'IC', fullName: 'Item Creation', active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'INVITEM', disable: false), + WorkListItemTypeModelData( + value: 0, name: 'STAMP', fullName: 'Stamp', active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'STAMP', disable: false), + ]; + + int workListItemIndex = 0; + + List? workList; + int pageNumber = 1; + + late DashboardProviderModel providerData; + + @override + void initState() { + super.initState(); + + providerData = Provider.of(context, listen: false); + workListItemTypes.forEach((workListElement) { + if (workListElement.key == "ITG") { + workListElement.value = providerData.itgFormsModel?.totalCount ?? 0; + } else { + var tempList = providerData.getOpenNotificationsList?.where((notificationElement) => notificationElement.itemType == workListElement.key).toList(); + if (tempList!.isNotEmpty) { + workListElement.value = tempList.first.openNtfNumber ?? 0; + } + } + }); + getWorkList(); + } + + ItgFormsModel? itgFormsModel; + int? itgRequestTypeIndex; + + void getWorkList() async { + try { + Utils.showLoading(context); + if (workListItemTypes[workListItemIndex].key == "ITG") { + itgFormsModel = await WorkListApiClient().GetITGTaskCountRequestType(); + List requestAllList = []; + for (int i = 0; i < (itgFormsModel?.requestType!.length ?? 0); i++) { + requestAllList = requestAllList + (itgFormsModel?.requestType![i].requestDetails ?? []); + } + itgFormsModel?.requestType!.insert(0, RequestType(requestDetails: requestAllList, requestTypeCode: "all", requestTypeName: "All")); + if ((itgFormsModel?.requestType?.length ?? 0) > 0) { + itgRequestTypeIndex = 0; + } + } else { + itgRequestTypeIndex = null; + workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex].key); + } + Utils.hideLoading(context); + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, null); + } + } + + @override + void dispose() { + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, - appBar: appBar( + appBar: AppBarWidget( context, title: LocaleKeys.workList.tr(), ), - body: Container( + body: SizedBox( width: double.infinity, height: double.infinity, child: Column( @@ -31,67 +118,151 @@ class _WorkListScreenState extends State { children: [ Container( width: double.infinity, - height: 2, - color: MyColors.darkWhiteColor, + height: 1, + color: MyColors.lightGreyEFColor, ), - Container( - width: double.infinity, + SizedBox( height: 40, - margin: EdgeInsets.only( - top: 21, - ), child: ListView.separated( itemBuilder: (context, index) { return Container( - padding: EdgeInsets.only( - left: 30, - right: 30, - ), + padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8), alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6), - color: tabList[index].isSelected - ? MyColors.darkIconColor - : MyColors.lightGreyEAColor, - ), - child: tabList[index].title.toText12( - color: tabList[index].isSelected - ? MyColors.white - : MyColors.black, - ), - ); - }, - separatorBuilder: (context, index) { - return 8.width; + decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: workListItemIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor), + child: ("${workListItemTypes[index].name} ${workListItemTypes[index].value > 0 ? "(${workListItemTypes[index].value})" : ""}") + .toText12(color: workListItemIndex == index ? MyColors.white : MyColors.black), + ).onPress(() { + if (workListItemIndex != index) { + workListItemIndex = index; + if (workListItemTypes[index].value == 0) { + workList = []; + } else { + workList = null; + } + setState(() {}); + if (workListItemTypes[index].value > 0) { + getWorkList(); + } + } + }); }, + separatorBuilder: (context, index) => 8.width, shrinkWrap: true, - itemCount: tabList.length, + itemCount: workListItemTypes.length, scrollDirection: Axis.horizontal, - padding: const EdgeInsets.only( - left: 21, - right: 21, + padding: const EdgeInsets.only(left: 21, right: 21), + ), + ).paddingOnly(top: 21, bottom: 21), + workListItemTypes[workListItemIndex].fullName.toSectionHeading().paddingOnly(left: 21, right: 21), + if (itgRequestTypeIndex != null) + SizedBox( + height: 40, + child: ListView.separated( + itemBuilder: (context, index) { + RequestType type = itgFormsModel!.requestType![index]; + return Container( + padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8), + alignment: Alignment.center, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: itgRequestTypeIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor), + child: ("${type.requestTypeName}").toText12(color: itgRequestTypeIndex == index ? MyColors.white : MyColors.black), + ).onPress(() { + if (itgRequestTypeIndex != index) { + itgRequestTypeIndex = index; + setState(() {}); + } + }); + }, + separatorBuilder: (context, index) => 8.width, + shrinkWrap: true, + itemCount: itgFormsModel?.requestType?.length ?? 0, + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only(left: 21, right: 21), ), + ).paddingOnly(top: 16, bottom: 16), + itgRequestTypeIndex != null + ? Expanded( + child: ListView.separated( + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return itgRowItem(workListItemTypes[workListItemIndex], itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails![index]); + }, + separatorBuilder: (context, index) => 12.height, + itemCount: itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails?.length ?? 0, + padding: EdgeInsets.only(top: 16, left: 21, right: 21), + ), + ) + : Expanded( + child: workList != null + ? ((workList!).isEmpty + ? "No History Available".toText16().center + : ListView.separated( + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return rowItem(workListItemTypes[workListItemIndex], workList![index]); + }, + separatorBuilder: (context, index) => 12.height, + itemCount: workList?.length ?? 0, + padding: EdgeInsets.only(top: 21, left: 21, right: 21), + )) + : const SizedBox(), + ), + ], + ), + ), + ); + } + + Widget itgRowItem(WorkListItemTypeModelData data, RequestDetails requestDetails) { + return InkWell( + onTap: () { + Navigator.pushNamed(context, AppRoutes.missingSwipe); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + gradient: LinearGradient(transform: GradientRotation(.218), begin: Alignment.topRight, end: Alignment.bottomRight, colors: data.color), ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [SvgPicture.asset("assets/images/miss_swipe.svg", width: 20, height: 20, color: Colors.white), 2.height, data.name.toText10(color: Colors.white)], + ).paddingAll(6), ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - LocaleKeys.human.toText12(), - LocaleKeys.resources.tr().toText24(isBold: true), - ], - ).paddingOnly(top: 24, left: 21, right: 21), - 24.height, + 8.width, Expanded( - child: ListView.separated( - itemBuilder: (context, index) { - return rowItem(typesList[index]); - }, - separatorBuilder: (context, index) { - return 12.height; - }, - itemCount: typesList.length, - padding: EdgeInsets.only(left: 21, right: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + requestDetails.title!.toText12(color: MyColors.grey57Color), + 10.height, + Row( + children: [ + DateUtil.formatDateToDate(DateUtil.convertStringToDate(requestDetails.modifiedDate!), false).toText10(color: MyColors.lightTextColor).expanded, + SvgPicture.asset( + "assets/images/arrow_next.svg", + color: MyColors.darkIconColor, + ) + ], + ), + ], ), ), ], @@ -100,14 +271,14 @@ class _WorkListScreenState extends State { ); } - Widget rowItem(Types types) { + Widget rowItem(WorkListItemTypeModelData data, WorkListResponseModel workData) { return InkWell( - onTap: (){ + onTap: () { Navigator.pushNamed(context, AppRoutes.missingSwipe); }, child: Container( width: double.infinity, - padding: EdgeInsets.all(12), + padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), @@ -126,39 +297,24 @@ class _WorkListScreenState extends State { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), - gradient: LinearGradient( - transform: GradientRotation(.46), - begin: Alignment.topRight, - end: Alignment.bottomRight, - colors: types.colors), + gradient: LinearGradient(transform: GradientRotation(.218), begin: Alignment.topRight, end: Alignment.bottomRight, colors: data.color), ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - "assets/images/miss_swipe.svg", - color: Colors.white, - ), - 2.height, - types.title.toText10(color: Colors.white) - ], + children: [SvgPicture.asset("assets/images/miss_swipe.svg", width: 20, height: 20, color: Colors.white), 2.height, data.name.toText10(color: Colors.white)], ).paddingAll(6), ), - 12.width, + 8.width, Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - "Missing Swipe Request".toText16(), - "Missing Swipe Request for Hussain, Mohammad has been approved" - .toText10(), - 12.height, + workData.sUBJECT!.toText12(color: MyColors.grey57Color), + 10.height, Row( children: [ - Expanded( - child: "07 Jan 2021" - .toText10(color: MyColors.lightTextColor)), + DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDate(workData.bEGINDATE!), false).toText10(color: MyColors.lightTextColor).expanded, SvgPicture.asset( "assets/images/arrow_next.svg", color: MyColors.darkIconColor, @@ -174,33 +330,3 @@ class _WorkListScreenState extends State { ); } } - -class Tabs { - String title; - bool isSelected; - - Tabs(this.title, this.isSelected); -} - -List tabList = [ - Tabs("All", true), - Tabs("HR", false), - Tabs("MO", false), - Tabs("PR", false), - Tabs("PO", false), -]; - -class Types { - String title; - List colors; - - Types(this.title, this.colors); -} - -List typesList = [ - Types("HR", [Color(0xff32D892), Color(0xff1AB170)]), - Types("ITG", [Color(0xffEB8C90), Color(0xffDE6C70)]), - Types("PO", [Color(0xff5099E3), Color(0xff3670AA)]), - Types("PR", [Color(0xff48EACF), Color(0xff3DCAB3)]), - Types("MO", [Color(0xff58DCFA), Color(0xff3CB9D5)]), -]; diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart new file mode 100644 index 0000000..f079f7f --- /dev/null +++ b/lib/widgets/app_bar_widget.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +AppBar AppBarWidget(BuildContext context, {required String title, bool showHomeButton = false}) { + return AppBar( + leadingWidth: 0, + // leading: GestureDetector( + // behavior: HitTestBehavior.opaque, + // onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context), + // child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + // ), + //titleSpacing: -1.44, + title: Row( + children: [ + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context), + child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + ), + 4.width, + title.toText24(color: MyColors.darkTextColor, isBold: true, considerHeight: false).expanded, + ], + ), + centerTitle: false, + elevation: 0, + backgroundColor: Colors.white, + actions: [ + if (showHomeButton) + IconButton( + onPressed: () { + // Navigator.pushAndRemoveUntil( + // context, + // MaterialPageRoute(builder: (context) => LandingPage()), + // (Route route) => false, + // ); + }, + icon: const Icon(Icons.home, color: MyColors.darkIconColor), + ), + ], + ); +} From 48a261d674bc728bcd71c27aef32764bee6843cd Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Wed, 2 Mar 2022 10:52:31 +0300 Subject: [PATCH 14/22] Dashboard API's 1.4 --- lib/provider/dashboard_provider_model.dart | 6 +- lib/ui/login/login_screen.dart | 2 +- pubspec.lock | 514 --------------------- pubspec.yaml | 6 +- 4 files changed, 7 insertions(+), 521 deletions(-) delete mode 100644 pubspec.lock diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index b52448e..1a83041 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -125,9 +125,9 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { GenericResponseModel? genericResponseModel = await DashbaordApiClient().getListMenu(); Map map = {}; print(jsonEncode(genericResponseModel!.listMenu)); - for (int i = 0; i < genericResponseModel!.listMenu!.length; i++) { - print(genericResponseModel!.listMenu![i]!.menuName ?? ""); - map[genericResponseModel!.listMenu![i]!.menuName ?? ""] = i.toString(); + for (int i = 0; i < genericResponseModel.listMenu!.length; i++) { + print(genericResponseModel.listMenu![i].menuName ?? ""); + map[genericResponseModel.listMenu![i].menuName ?? ""] = i.toString(); } logger.i(map); notifyListeners(); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 533e9ee..1ad1d62 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -128,7 +128,7 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { username.text="15153"; - password.text="Riyadh@1234"; + password.text="Ab123456@"; return Scaffold( body: Column( children: [ diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 58ce64a..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,514 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.0" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.8.2" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - easy_localization: - dependency: "direct main" - description: - name: easy_localization - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" - easy_logger: - dependency: transitive - description: - name: easy_logger - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.2" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_countdown_timer: - dependency: "direct main" - description: - name: flutter_countdown_timer - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - flutter_localizations: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - fluttertoast: - dependency: "direct main" - description: - name: fluttertoast - url: "https://pub.dartlang.org" - source: hosted - version: "8.0.8" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.4" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.0" - injector: - dependency: "direct main" - description: - name: injector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3" - lints: - dependency: transitive - description: - name: lints - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - local_auth: - dependency: "direct main" - description: - name: local_auth - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.9" - logger: - dependency: "direct main" - description: - name: logger - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.11" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - path_drawing: - dependency: transitive - description: - name: path_drawing - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - path_parsing: - dependency: transitive - description: - name: path_parsing - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - path_provider: - dependency: "direct main" - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.9" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.7" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.4" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.4" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - url: "https://pub.dartlang.org" - source: hosted - version: "8.3.0" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "3.7.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "4.4.0" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "6.0.1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.9" - shared_preferences_ios: - dependency: transitive - description: - name: shared_preferences_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" - shimmer: - dependency: "direct main" - description: - name: shimmer - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - sizer: - dependency: "direct main" - description: - name: sizer - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.15" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - universal_io: - dependency: transitive - description: - name: universal_io - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.4" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.1" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "5.3.1" -sdks: - dart: ">=2.14.0 <3.0.0" - flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index ca8fe9c..37a3352 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.16.0 <3.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -39,13 +39,13 @@ dependencies: provider: ^6.0.1 easy_localization: ^3.0.0 http: ^0.13.4 - permission_handler: ^8.3.0 + permission_handler: ^9.2.0 flutter_svg: ^1.0.0 sizer: ^2.0.15 local_auth: ^1.1.9 fluttertoast: ^8.0.8 shared_preferences: ^2.0.12 - firebase_messaging: ^11.2.6 + firebase_messaging: ^11.2.8 shimmer: ^2.0.0 logger: ^1.1.0 flutter_countdown_timer: ^4.1.0 From 68729ddbb9294650fefc85c81c878aeb0ce89bed Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Mon, 14 Mar 2022 15:41:23 +0300 Subject: [PATCH 15/22] NFC Attendance implement --- android/app/src/main/AndroidManifest.xml | 3 + assets/icons/nfc/ic_done.png | Bin 0 -> 18338 bytes assets/icons/nfc/ic_nfc.png | Bin 0 -> 19686 bytes lib/api/dashboard_api_client.dart | 24 ++ lib/app_state/app_state.dart | 2 +- lib/classes/app_permissions.dart | 30 ++ lib/classes/consts.dart | 4 +- lib/classes/utils.dart | 4 + lib/main.dart | 143 +++++++- lib/models/member_information_list_model.dart | 2 +- lib/provider/dashboard_provider_model.dart | 37 +- lib/ui/landing/dashboard_screen.dart | 10 +- lib/ui/landing/today_attendance_screen.dart | 334 ++++++++++++------ lib/ui/login/login_screen.dart | 8 +- lib/widgets/location/Location.dart | 249 +++++++++++++ lib/widgets/nfc/nfc_reader_sheet.dart | 187 ++++++++++ lib/widgets/swipe/nfc_reader_sheet.dart | 194 ++++++++++ pubspec.yaml | 12 + 18 files changed, 1105 insertions(+), 138 deletions(-) create mode 100644 assets/icons/nfc/ic_done.png create mode 100644 assets/icons/nfc/ic_nfc.png create mode 100644 lib/classes/app_permissions.dart create mode 100644 lib/widgets/location/Location.dart create mode 100644 lib/widgets/nfc/nfc_reader_sheet.dart create mode 100644 lib/widgets/swipe/nfc_reader_sheet.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 8d53eaf..7be27d5 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,9 @@ package="com.mohem_flutter_app"> + + + diff --git a/assets/icons/nfc/ic_done.png b/assets/icons/nfc/ic_done.png new file mode 100644 index 0000000000000000000000000000000000000000..5b802855ce8942032b0948c1fdaa56e885b4c78e GIT binary patch literal 18338 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 literal 0 HcmV?d00001 diff --git a/assets/icons/nfc/ic_nfc.png b/assets/icons/nfc/ic_nfc.png new file mode 100644 index 0000000000000000000000000000000000000000..274e1b8c0d81daca3127e8a2b6d0522b43d6bb8d GIT binary patch literal 19686 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 literal 0 HcmV?d00001 diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 76e2453..f4c583d 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_ import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:uuid/uuid.dart'; import 'api_client.dart'; @@ -89,4 +90,27 @@ class DashboardApiClient { return responseData; }, url, postParams); } + + //Mark Attendance + Future markAttendance({String lat = "0", String? long = "0", required int pointType, String nfcValue = "", bool isGpsRequired = false}) async { + String url = "${ApiConsts.swpRest}AuthenticateAndSwipeUserSupportNFC"; + var uuid = Uuid(); + // Generate a v4 (random) id + + Map postParams = { + "UID": uuid.v4(), //Mobile Id + "Latitude": lat, + "Longitude": long, + "QRValue": "", + "PointType": pointType, // NFC=2, Wifi = 3, QR= 1, + "NFCValue": nfcValue, + "WifiValue": "", + "IsGpsRequired": isGpsRequired + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 50aff0a..08d2f70 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -36,6 +36,7 @@ class AppState { bool isArabic(context) => EasyLocalization.of(context)?.locale.languageCode == "ar"; String? _username; + // todo ''sikander' added password for now, later will remove & improve String? password; @@ -43,7 +44,6 @@ class AppState { String? get getUserName => _username; - set setUserPassword(_password) => password = _password; MemberLoginListModel? _memberLoginList; diff --git a/lib/classes/app_permissions.dart b/lib/classes/app_permissions.dart new file mode 100644 index 0000000..a70342c --- /dev/null +++ b/lib/classes/app_permissions.dart @@ -0,0 +1,30 @@ +import 'package:permission_handler/permission_handler.dart'; + +class AppPermissions{ + static location(Function(bool) completion) { + Permission.location.isGranted.then((isGranted){ + if(!isGranted){ + Permission.location.request().then((granted){ + completion(granted == PermissionStatus.granted); + }); + } + completion(isGranted); + }); + + } + + static checkAll(Function(bool) completion){ + [ + Permission.location + ].request().then((value){ + + bool allGranted = false; + value.values.forEach((element) { + allGranted = allGranted && element == PermissionStatus.granted; + }); + + completion(allGranted); + + }); + } +} \ No newline at end of file diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index a11edec..a95e5b4 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,10 +1,12 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrlServices = baseUrl + "/services/"; // server + // static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; static String erpRest = baseUrlServices + "ERP.svc/REST/"; + static String swpRest = baseUrlServices + "SWP.svc/REST/"; static String user = baseUrlServices + "api/User/"; static String cocRest = baseUrlServices + "COCWS.svc/REST/"; } diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index ae8041f..fc942c4 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -46,6 +46,10 @@ class Utils { }); } + static Future delay(int millis) async { + return await Future.delayed(Duration(milliseconds: millis)); + } + static void hideLoading(BuildContext context) { if (_isLoadingVisible) { _isLoadingVisible = false; diff --git a/lib/main.dart b/lib/main.dart index 20759d9..29a8e17 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -8,6 +9,9 @@ import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/theme/app_theme.dart'; +import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:nfc_manager/nfc_manager.dart'; +import 'package:nfc_manager/platform_tags.dart'; import 'package:provider/provider.dart'; import 'package:sizer/sizer.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -25,7 +29,7 @@ Future main() async { await EasyLocalization.ensureInitialized(); await Firebase.initializeApp(); AppState().setPostParamsModel( - PostParamsModel(channel: 31, versionID: 3.2, mobileType: Platform.isAndroid ? "android" : "ios"), + PostParamsModel(channel: 31, versionID: 3.4, mobileType: Platform.isAndroid ? "android" : "ios"), ); runApp( EasyLocalization( @@ -77,3 +81,140 @@ class MyApp extends StatelessWidget { ); } } + +// class MyApp extends StatefulWidget { +// @override +// State createState() => MyAppState(); +// } +// +// class MyAppState extends State { +// ValueNotifier result = ValueNotifier(null); +// +// @override +// Widget build(BuildContext context) { +// return MaterialApp( +// home: Scaffold( +// appBar: AppBar(title: Text('NfcManager Plugin Example')), +// body: SafeArea( +// child: FutureBuilder( +// future: NfcManager.instance.isAvailable(), +// builder: (context, ss) => ss.data != true +// ? Center(child: Text('NfcManager.isAvailable(): ${ss.data}')) +// : Flex( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// direction: Axis.vertical, +// children: [ +// Flexible( +// flex: 2, +// child: Container( +// margin: EdgeInsets.all(4), +// constraints: BoxConstraints.expand(), +// decoration: BoxDecoration(border: Border.all()), +// child: SingleChildScrollView( +// child: ValueListenableBuilder( +// valueListenable: result, +// builder: (context, value, _) => Text('${value ?? ''}'), +// ), +// ), +// ), +// ), +// Flexible( +// flex: 3, +// child: GridView.count( +// padding: EdgeInsets.all(4), +// crossAxisCount: 2, +// childAspectRatio: 4, +// crossAxisSpacing: 4, +// mainAxisSpacing: 4, +// children: [ +// ElevatedButton(child: Text('Tag Read'), onPressed: _tagRead), +// ElevatedButton(child: Text('Ndef Write'), onPressed: _ndefWrite), +// ElevatedButton(child: Text('Ndef Write Lock'), onPressed: _ndefWriteLock), +// ], +// ), +// ), +// ], +// ), +// ), +// ), +// ), +// ); +// } +// +// void _tagRead() { +// showNfcReader( +// context, +// onNcfScan: (String? nfcId) {}, +// ); +// // NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { +// // result.value = tag.data; +// // print(tag.data); +// // var ndef = Ndef.from(tag); +// // +// // var f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); +// // final String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); +// // print(identifier); // => 0428fcf2255e81 +// // print(ndef!.additionalData); +// // +// // // onDiscovered callback +// // // final mifare = MiFare.from(tag); +// // // if (mifare == null) { +// // // print('Tag is not compatible with MiFare.'); +// // // return; +// // // } +// // // print(mifare.identifier); +// // // final String identifier = mifare.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); +// // // print(identifier); // => 0428fcf2255e81 +// // NfcManager.instance.stopSession(); +// // }); +// } +// +// void _ndefWrite() { +// NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { +// var ndef = Ndef.from(tag); +// if (ndef == null || !ndef.isWritable) { +// result.value = 'Tag is not ndef writable'; +// NfcManager.instance.stopSession(errorMessage: result.value); +// return; +// } +// +// NdefMessage message = NdefMessage([ +// NdefRecord.createText('Hello World!'), +// NdefRecord.createUri(Uri.parse('https://flutter.dev')), +// NdefRecord.createMime('text/plain', Uint8List.fromList('Hello'.codeUnits)), +// NdefRecord.createExternal('com.example', 'mytype', Uint8List.fromList('mydata'.codeUnits)), +// ]); +// +// try { +// await ndef.write(message); +// result.value = 'Success to "Ndef Write"'; +// NfcManager.instance.stopSession(); +// } catch (e) { +// result.value = e; +// NfcManager.instance.stopSession(errorMessage: result.value.toString()); +// return; +// } +// }); +// } +// +// void _ndefWriteLock() { +// NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { +// var ndef = Ndef.from(tag); +// if (ndef == null) { +// result.value = 'Tag is not ndef'; +// NfcManager.instance.stopSession(errorMessage: result.value.toString()); +// return; +// } +// +// try { +// await ndef.writeLock(); +// result.value = 'Success to "Ndef Write Lock"'; +// NfcManager.instance.stopSession(); +// } catch (e) { +// result.value = e; +// NfcManager.instance.stopSession(errorMessage: result.value.toString()); +// return; +// } +// }); +// } +// } diff --git a/lib/models/member_information_list_model.dart b/lib/models/member_information_list_model.dart index da95ed0..dc64e53 100644 --- a/lib/models/member_information_list_model.dart +++ b/lib/models/member_information_list_model.dart @@ -32,7 +32,7 @@ class MemberInformationListModel { String? fREQUENCY; String? fREQUENCYMEANING; int? fROMROWNUM; - String? gRADEID; + int? gRADEID; String? gRADENAME; String? hIREDATE; int? jOBID; diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index f15e244..52fb6ad 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -19,6 +19,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { //Attendance Tracking bool isAttendanceTrackingLoading = true; int endTime = 0, isTimeRemainingInSeconds = 0; + double progress = 0.0; GetAttendanceTracking? attendanceTracking; //Work List @@ -40,19 +41,27 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List? getMenuEntriesList; //Attendance Tracking API's & Methods - void fetchAttendanceTracking() async { + Future fetchAttendanceTracking() async { try { attendanceTracking = await DashboardApiClient().getAttendanceTracking(); + print("attendanceTracking:" + (attendanceTracking!.pRemainingHours).toString()); isAttendanceTrackingLoading = false; - isTimeRemainingInSeconds = calculateSeconds("00:00:00"); - endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; - print("isTimeRemainingInSeconds " + isTimeRemainingInSeconds.toString()); - print("endTime " + endTime.toString()); + // isTimeRemainingInSeconds = calculateSeconds( "00:00:00"); + if (attendanceTracking?.pSwipeIn != null) { + isTimeRemainingInSeconds = calculateSeconds(attendanceTracking!.pRemainingHours ?? "00:00:00"); + int totalShiftTimeInSeconds = calculateSeconds(attendanceTracking!.pScheduledHours ?? "00:00:00"); + print("totalShiftTimeInSeconds: " + totalShiftTimeInSeconds.toString()); + print("isTimeRemainingInSeconds: " + isTimeRemainingInSeconds.toString()); + progress = (isTimeRemainingInSeconds / totalShiftTimeInSeconds); + endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; + print("endTime " + endTime.toString()); + } - // notifyListeners(); + notifyListeners(); } catch (ex) { Utils.handleException(ex, null); } + return true; } int calculateSeconds(String time) { @@ -63,16 +72,18 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } update() { - isAttendanceTrackingLoading = !isAttendanceTrackingLoading; - isWorkListLoading = !isWorkListLoading; - attendanceTracking?.pSwipeIn = "a"; - isTimeRemainingInSeconds = calculateSeconds("00:10:30"); - endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; - notifyListeners(); + fetchAttendanceTracking(); + // isAttendanceTrackingLoading = !isAttendanceTrackingLoading; + // isWorkListLoading = !isWorkListLoading; + // attendanceTracking?.pSwipeIn = "a"; + // isTimeRemainingInSeconds = calculateSeconds("00:10:30"); + // endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; + // notifyListeners(); } ItgFormsModel? itgFormsModel; List? getOpenNotificationsList; + //Work List API's & Methods Future fetchWorkListCounter(context, {bool showLoading = false}) async { try { @@ -167,7 +178,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } - //Verify Menus by printing in log + // Verify Menus by printing in log // for(int i=0;i { ), LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), 9.height, - const ClipRRect( + ClipRRect( borderRadius: BorderRadius.all( Radius.circular(20), ), child: LinearProgressIndicator( - value: 0.7, + value: model.progress, minHeight: 8, valueColor: const AlwaysStoppedAnimation(Colors.white), backgroundColor: const Color(0xff196D73), @@ -184,8 +184,10 @@ class _DashboardScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.checkIn.tr().toText12(color: Colors.white), - (model.isTimeRemainingInSeconds == 0 ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true), - 4.height + (model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn) + .toString() + .toText14(color: Colors.white, isBold: true), + 4.height, ], ).paddingOnly(left: 12), ), diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index b2ab7aa..2008484 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -1,12 +1,25 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; +import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:nfc_manager/nfc_manager.dart'; +import 'package:provider/provider.dart'; + +import '../../provider/dashboard_provider_model.dart'; +import '../../widgets/location/Location.dart'; class TodayAttendanceScreen extends StatefulWidget { TodayAttendanceScreen({Key? key}) : super(key: key); @@ -18,14 +31,45 @@ class TodayAttendanceScreen extends StatefulWidget { } class _TodayAttendanceScreenState extends State { + ValueNotifier result = ValueNotifier(null); + late DashboardProviderModel data; + bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false; + @override void initState() { super.initState(); + checkAttendanceAvailablity(); + data = Provider.of(context, listen: false); + } + + checkAttendanceAvailablity() async { + bool isAvailable = await NfcManager.instance.isAvailable(); + setState(() { + AppState().privilegeListModel!.forEach((element) { + // Check availability + if (isAvailable) if (element.serviceName == "enableNFC") { + // if (element.previlege ?? false) + isNfcEnabled = true; + } else if (element.serviceName == "enableQR") { + if (element.previlege ?? false) isQrEnabled = true; + } else if (element.serviceName == "enableWIFI") { + if (element.previlege ?? false) isWifiEnabled = true; + } else if (element.serviceName == "enableLocatoinNFC") { + if (element.previlege ?? false) isNfcLocationEnabled = true; + } else if (element.serviceName == "enableLocationQR") { + if (element.previlege ?? false) isQrLocationEnabled = true; + } else if (element.serviceName == "enableLocationWIFI") { + if (element.previlege ?? false) isWifiLocationEnabled = true; + } + }); + }); } @override void dispose() { super.dispose(); + // Stop Session + NfcManager.instance.stopSession(); } @override @@ -37,123 +81,170 @@ class _TodayAttendanceScreenState extends State { icon: const Icon(Icons.arrow_back_ios, color: Colors.white), onPressed: () => Navigator.pop(context), ), - ), - backgroundColor: Colors.white, - body: ListView( - children: [ - Container( - color: MyColors.backgroundBlackColor, - padding: EdgeInsets.only(top: 4,left: 21, right: 21, bottom: 21), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "June 13, 2021".toText24(isBold: true, color: Colors.white), - LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), - 21.height, - Center( - child: CircularStepProgressBar( - totalSteps: 16 * 4, - currentStep: 16, - width: 216, - height: 216, - selectedColor: MyColors.gradiantEndColor, - unselectedColor: MyColors.grey70Color, - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - "08:58:15".toText32(color: Colors.white, isBold: true), - 19.height, - "Shift Time".tr().toText12(color: MyColors.greyACColor), - "08:00 - 17:00".toText22(color: Colors.white, isBold: true), - ], - ), - ), - ), - ), - ], - ), - ), - Container( - color: MyColors.backgroundBlackColor, - child: Stack( - children: [ - Container( - height: 187, - padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), - decoration: BoxDecoration( - borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), - gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Column( - children: [ - Row( - children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], - ), - 21.height, - Row( - children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], - ), - ], - ), - ), - Container( - width: double.infinity, - decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), - margin: EdgeInsets.only(top: 187 - 31), - padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - "Mark".tr().toText12(), - "Attendance".tr().toText24(), - "Select the method to mark the attendance".tr().toText12(color: Color(0xff535353)), - 24.height, - GridView( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - padding: EdgeInsets.zero, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), - children: [ - attendanceMethod("NFC", "assets/images/nfc.svg", () {}), - attendanceMethod("Wifi", "assets/images/wufu.svg", () {}), - ], - ) - ], - ), - ), - // Positioned( - // top: 187 - 21, - // child: Container( - // padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), - // decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), - // child: Column( - // children: [ - // Row( - // children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], - // ), - // 21.height, - // Row( - // children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], - // ), - // ], - // ), - // ), - // ), - ], + actions: [ + IconButton( + onPressed: () { + data.fetchAttendanceTracking(); + }, + icon: Icon( + Icons.ac_unit, + color: Colors.white, ), ) ], ), + backgroundColor: MyColors.backgroundBlackColor, + body: Consumer( + builder: (context, model, child) { + return (model.isAttendanceTrackingLoading + ? Center(child: CircularProgressIndicator()) + : ListView( + children: [ + Container( + color: MyColors.backgroundBlackColor, + padding: EdgeInsets.only(top: 4, left: 21, right: 21, bottom: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DateUtil.getWeekDayMonthDayYearDateFormatted(DateTime.now(), "en").toText24(isBold: true, color: Colors.white), + LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), + 21.height, + Center( + child: CircularStepProgressBar( + totalSteps: 16 * 4, + currentStep: (model.progress * 100).toInt(), + width: 216, + height: 216, + selectedColor: MyColors.gradiantEndColor, + unselectedColor: MyColors.grey70Color, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CountdownTimer( + endTime: model.endTime, + onEnd: null, + endWidget: "00:00:00".toText32(color: Colors.white, isBold: true), + textStyle: TextStyle(color: Colors.white, fontSize: 32, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1), + ), + 19.height, + "Shift Time".tr().toText12(color: MyColors.greyACColor), + (model.attendanceTracking!.pShtName ?? "00:00:00").toString().toText22(color: Colors.white, isBold: true), + ], + ), + ), + ), + ), + ], + ), + ), + Container( + color: MyColors.backgroundBlackColor, + child: Stack( + children: [ + Container( + height: 187, + padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), + gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Column( + children: [ + Row( + children: [ + commonStatusView("Check In", (model.attendanceTracking!.pSwipeIn) ?? "- - : - -"), + commonStatusView("Check Out", (model.attendanceTracking!.pSwipeOut) ?? "- - : - -") + ], + ), + 21.height, + Row( + children: [ + commonStatusView("Late In", (model.attendanceTracking!.pLateInHours) ?? "- - : - -"), + commonStatusView("Regular", (model.attendanceTracking!.pScheduledHours) ?? "- - : - -") + ], + ), + ], + ), + ), + Container( + width: double.infinity, + decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + margin: EdgeInsets.only(top: 187 - 31), + padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + "Mark".tr().toText12(), + "Attendance".tr().toText24(), + "Select the method to mark the attendance".tr().toText12(color: Color(0xff535353)), + 24.height, + GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.zero, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + children: [ + attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { + showNfcReader(context, onNcfScan: (String? nfcId) async { + print(nfcId); + Utils.showLoading(context); + try { + GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? ""); + bool status = await model.fetchAttendanceTracking(); + Utils.hideLoading(context); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, (msg) { + Utils.confirmDialog(context, msg); + }); + } + }); + // Location.getCurrentLocation((LatLng? latlng) { + // print(latlng!.longitude.toString()); + // }); + }), + attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () {}), + ], + ) + ], + ), + ), + // Positioned( + // top: 187 - 21, + // child: Container( + // padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), + // decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + // child: Column( + // children: [ + // Row( + // children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], + // ), + // 21.height, + // Row( + // children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], + // ), + // ], + // ), + // ), + // ), + ], + ), + ) + ], + )) + .animatedSwither(); + }, + ), ); } - Widget attendanceMethod(String title, String image, VoidCallback onPress) => Container( - padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), + Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ @@ -161,9 +252,26 @@ class _TodayAttendanceScreenState extends State { MyColors.gradiantStartColor, ]), ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [Expanded(child: SvgPicture.asset(image)), title.toText17(isBold: true, color: Colors.white)], + clipBehavior: Clip.antiAlias, + child: Stack( + children: [ + Container( + padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(child: SvgPicture.asset(image)), + title.toText17(isBold: true, color: Colors.white), + ], + ), + ), + if (!isEnabled) + Container( + width: double.infinity, + height: double.infinity, + color: Colors.grey.withOpacity(0.7), + ) + ], ), ).onPress(onPress); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 06ecb22..d5a6061 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -69,12 +69,12 @@ class _LoginScreenState extends State { } String? firebaseToken; - GetMobileLoginInfoListModel? loginInfo; + Future checkFirebaseToken() async { try { Utils.showLoading(context); firebaseToken = await _firebaseMessaging.getToken(); - loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + GetMobileLoginInfoListModel? loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); if (loginInfo == null) { Utils.hideLoading(context); print("Device token not found"); @@ -112,7 +112,7 @@ class _LoginScreenState extends State { } Utils.hideLoading(context); if (_autoLogin) { - Navigator.pushNamed(context, AppRoutes.verifyLastLogin, arguments: loginInfo); + Navigator.pushNamed(context, AppRoutes.verifyLastLogin); } else { Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken"); } @@ -128,7 +128,7 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { username.text="15153"; - password.text="Ab123456@"; + password.text="Xy12345@"; return Scaffold( body: Column( children: [ diff --git a/lib/widgets/location/Location.dart b/lib/widgets/location/Location.dart new file mode 100644 index 0000000..bd39e2e --- /dev/null +++ b/lib/widgets/location/Location.dart @@ -0,0 +1,249 @@ +import 'dart:async'; +import 'dart:math'; +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_directions_api/google_directions_api.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +// import 'package:geodesy/geodesy.dart' as geodesy; + +import '../../classes/app_permissions.dart'; +import '../../theme/colors.dart'; + + +//Created By Mr.Zohaib +class Location { + static _Map map = _Map(); + + static havePermission(Function(bool) callback) { + Geolocator.checkPermission().then((value) async { + if (value == LocationPermission.denied) { + value = await Geolocator.requestPermission(); + callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value)); + } else { + callback(true); + } + }); + } + + static isEnabled(Function(bool) callback) { + Geolocator.isLocationServiceEnabled().then((value) => callback(value)); + } + + static bool _listeningSettingChange = true; + + static listenGPS({bool change = true, Function(bool)? onChange}) async { + _listeningSettingChange = change; + if (change == false) return; + + Future.doWhile(() async { + await Utils.delay(1000); + var enable = await Geolocator.isLocationServiceEnabled(); + onChange!(enable); + return _listeningSettingChange; + }); + } + + static getCurrentLocation(Function(LatLng?) callback) { + done(Position position) { + //AppStorage.sp.saveLocation(position); + + LatLng? myCurrentLocation = LatLng(position.latitude, position.longitude); + callback(myCurrentLocation); + } + + AppPermissions.location((granted) { + + if (granted) + Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) { + if (value == null) { + Geolocator.getCurrentPosition().then((value) { + done(value); + }); + } else { + done(value); + } + }); + }); + } + + // static LatLng locationAwayFrom( + // {required LatLng loc1, num distanceMeters = 200.0, num bearing = 270.0}) { + // geodesy.LatLng l1 = geodesy.LatLng(loc1.latitude, loc1.longitude); + // geodesy.LatLng destinationPoint = geodesy.Geodesy() + // .destinationPointByDistanceAndBearing(l1, distanceMeters, bearing); + // return LatLng(destinationPoint.latitude, destinationPoint.longitude); + // } + + static Future distanceTo(LatLng destination) async { + var myLoc = await Geolocator.getLastKnownPosition(); + var distance = 0.0; + if (myLoc != null) { + distance = Geolocator.distanceBetween(destination.latitude, destination.longitude, myLoc.latitude, myLoc.longitude); + } + return distance; + } +} + +class _Map { + Marker createMarker( + String id, { + required LatLng coordinates, + BitmapDescriptor? icon, + VoidCallback? onTap, + }) { + final MarkerId markerId = MarkerId(id); + return Marker( + icon: icon ?? BitmapDescriptor.defaultMarker, + markerId: markerId, + position: coordinates, + flat: false, + // infoWindow: InfoWindow(title: id, snippet: '*'), + onTap: onTap, + ); + } + + CameraPosition initialCamera({required Completer mapController, LatLng? position, double zoom = 12}) { + position = position ?? LatLng(24.7249303, 46.5416656); + CameraPosition riyadhEye = CameraPosition( + target: position, + zoom: zoom, + ); + mapController.future.then((controller) { + controller.animateCamera(CameraUpdate.newCameraPosition(riyadhEye)); + }); + return riyadhEye; + } + + CameraPosition moveTo(LatLng location, {double zoom = 12, double direction = 0.0, required Completer mapController, bool? animation}) { + var camera = CameraPosition(target: location, zoom: zoom, bearing: direction); + mapController.future.then((controller) { + animation ?? false ? controller.animateCamera(CameraUpdate.newCameraPosition(camera)) : controller.moveCamera(CameraUpdate.newCameraPosition(camera)); + }); + return camera; + } + + moveCamera(CameraPosition camera, @required Completer mapController, bool animation) { + mapController.future.then((controller) { + animation ? controller.animateCamera(CameraUpdate.newCameraPosition(camera)) : controller.moveCamera(CameraUpdate.newCameraPosition(camera)); + }); + } + + scrollBy({double x = 0, double y = 0, required Completer mapController, bool animation = true}) { + var camera = CameraUpdate.scrollBy(x, y); + mapController.future.then((controller) { + animation ? controller.animateCamera(camera) : controller.moveCamera(camera); + }); + } + + goToCurrentLocation({Completer? mapController, double? direction = 0.0, bool? animation}) { + Location.getCurrentLocation((location) { + moveTo(location!, zoom: 17, mapController: mapController!, animation: animation, direction: direction!); + }); + } + + var routes = Map(); + + setRoutePolylines(LatLng? source, LatLng? destination, Set polylines, Completer mapController, Function(DirectionsRoute?) completion) { + if (source == null || destination == null) { + completion(null); + return; + } + + var origin = '${source.latitude},${source.longitude}'; + var destin = '${destination.latitude},${destination.longitude}'; + var routeId = '$origin->$destination'; + + createPolyline(DirectionsRoute results) { + List polylineCoordinates = results.overviewPath!.map((e) => LatLng(e.latitude, e.longitude)).toList(); + PolylineId id = PolylineId("route"); + Polyline polyline = Polyline( + polylineId: id, + color: accentColor, + width: 5, + jointType: JointType.round, + startCap: Cap.roundCap, + endCap: Cap.roundCap, + points: polylineCoordinates, + ); + + polylines.removeWhere((element) => true); + polylines.add(polyline); + + LatLngBounds bound = getBounds(coordinates: polylineCoordinates); + focusCameraToLatLngBounds(bound: bound, mapController: mapController, padding: 100); + completion(routes[routeId]); + } + + var availableRoute = routes[routeId]; + if (availableRoute == null) { + var request = DirectionsRequest(origin: origin, destination: destin); + DirectionsService().route(request, (response, status) { + if (status == DirectionsStatus.ok && response.routes!.isNotEmpty) { + routes[routeId] = response.routes!.first; + createPolyline(response.routes!.first); + } + }); + } else { + createPolyline(availableRoute); + } + } + + LatLngBounds getBounds({required List coordinates}) { + var lngs = coordinates.map((c) => c.longitude).toList(); + var lats = coordinates.map((c) => c.latitude).toList(); + + double bottomMost = lngs.reduce(min); + double topMost = lngs.reduce(max); + double leftMost = lats.reduce(min); + double rightMost = lats.reduce(max); + + LatLngBounds bounds = LatLngBounds( + northeast: LatLng(rightMost, topMost), + southwest: LatLng(leftMost, bottomMost), + ); + return bounds; + + double? x0, x1, y0, y1; + for (LatLng latLng in coordinates) { + if (x0 == null) { + x0 = x1 = latLng.latitude; + y0 = y1 = latLng.longitude; + } else { + if (latLng.latitude > x1!) x1 = latLng.latitude; + if (latLng.latitude < x0) x0 = latLng.latitude; + if (latLng.longitude > y1!) y1 = latLng.longitude; + if (latLng.longitude < y0!) y0 = latLng.longitude; + } + } + return LatLngBounds(northeast: LatLng(x1!, y1!), southwest: LatLng(x0!, y0!)); + } + + focusCameraToLatLngBounds({LatLngBounds? bound, Completer? mapController, double? padding}) async { + if (bound == null) return; + + CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, padding!); + final GoogleMapController controller = await mapController!.future; + controller.animateCamera(camera); + } + + focusCameraTo2Points({LatLng? point1, LatLng? point2, Completer? mapController, double? padding}) async { + var source = point1; + var destination = point2; + if (source != null && destination != null) { + // 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true. + LatLngBounds bound; + if (source.latitude <= destination.latitude) { + bound = LatLngBounds(southwest: source, northeast: destination); + } else { + bound = LatLngBounds(southwest: destination, northeast: source); + } + + if (bound == null) return; + + focusCameraToLatLngBounds(bound: bound, mapController: mapController, padding: padding); + } + } +} diff --git a/lib/widgets/nfc/nfc_reader_sheet.dart b/lib/widgets/nfc/nfc_reader_sheet.dart new file mode 100644 index 0000000..84397ba --- /dev/null +++ b/lib/widgets/nfc/nfc_reader_sheet.dart @@ -0,0 +1,187 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:nfc_manager/nfc_manager.dart'; +import 'package:nfc_manager/platform_tags.dart'; + +void showNfcReader(BuildContext context, {required Function(String? nfcId) onNcfScan}) { + showModalBottomSheet( + context: context, + enableDrag: false, + isDismissible: false, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), + ), + backgroundColor: Colors.white, + builder: (context) { + return NfcLayout( + onNcfScan: onNcfScan, + ); + }, + ); +} + +class NfcLayout extends StatefulWidget { + Function(String? nfcId) onNcfScan; + + NfcLayout({required this.onNcfScan}); + + @override + _NfcLayoutState createState() => _NfcLayoutState(); +} + +class _NfcLayoutState extends State { + bool _reading = false; + Widget? mainWidget; + String? nfcId; + + @override + void initState() { + super.initState(); + + NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { + print(tag.data); + var f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); + final String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); + // print(identifier); // => 0428fcf2255e81 + nfcId = identifier; + + setState(() { + _reading = true; + mainWidget = doneNfc(); + }); + + Future.delayed(const Duration(seconds: 1), () { + NfcManager.instance.stopSession(); + Navigator.pop(context); + widget.onNcfScan(nfcId); + }); + }); + } + + @override + Widget build(BuildContext context) { + (mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc(); + return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget); + } + + Widget scanNfc() { + return Container( + key: ValueKey(1), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Text( + "Ready To Scan", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 24, + ), + ), + SizedBox( + height: 30, + ), + Image.asset( + "assets/icons/nfc/ic_nfc.png", + height: MediaQuery.of(context).size.width / 3, + ), + SizedBox( + height: 30, + ), + Text( + "Approach an NFC Tag", + style: TextStyle( + fontSize: 18, + ), + ), + SizedBox( + height: 30, + ), + ButtonTheme( + minWidth: MediaQuery.of(context).size.width / 1.2, + height: 45.0, + buttonColor: Colors.grey[300], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + child: RaisedButton( + onPressed: () { + NfcManager.instance.stopSession(); + Navigator.pop(context); + }, + elevation: 0, + child: Text("CANCEL"), + ), + ), + SizedBox( + height: 30, + ), + ], + ), + ); + } + + Widget doneNfc() { + return Container( + key: ValueKey(2), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 30, + ), + Text( + "Successfully Scanned", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 24, + ), + ), + SizedBox( + height: 30, + ), + Image.asset( + "assets/icons/nfc/ic_done.png", + height: MediaQuery.of(context).size.width / 3, + ), + SizedBox( + height: 30, + ), + Text( + "Approach an NFC Tag", + style: TextStyle( + fontSize: 18, + ), + ), + SizedBox( + height: 30, + ), + ButtonTheme( + minWidth: MediaQuery.of(context).size.width / 1.2, + height: 45.0, + buttonColor: Colors.grey[300], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + child: RaisedButton( + // onPressed: () { + // _stream?.cancel(); + // widget.onNcfScan(nfcId); + // Navigator.pop(context); + // }, + onPressed: null, + elevation: 0, + child: Text("DONE"), + ), + ), + SizedBox( + height: 30, + ), + ], + ), + ); + } +} diff --git a/lib/widgets/swipe/nfc_reader_sheet.dart b/lib/widgets/swipe/nfc_reader_sheet.dart new file mode 100644 index 0000000..3dc357d --- /dev/null +++ b/lib/widgets/swipe/nfc_reader_sheet.dart @@ -0,0 +1,194 @@ +// import 'dart:async'; +// +// import 'package:flutter/material.dart'; +// +// +// void showNfcReader(BuildContext context, {Function onNcfScan}) { +// showModalBottomSheet( +// context: context, +// enableDrag: false, +// isDismissible: false, +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), +// ), +// backgroundColor: Colors.white, +// builder: (context) { +// return NfcLayout( +// onNcfScan: onNcfScan, +// ); +// }); +// } +// +// class NfcLayout extends StatefulWidget { +// Function onNcfScan; +// +// NfcLayout({this.onNcfScan}); +// +// @override +// _NfcLayoutState createState() => _NfcLayoutState(); +// } +// +// class _NfcLayoutState extends State { +// StreamSubscription _stream; +// bool _reading = false; +// Widget mainWidget; +// String nfcId; +// +// @override +// void initState() { +// super.initState(); +// +// setState(() { +// // _reading = true; +// // Start reading using NFC.readNDEF() +// _stream = NFC.readNDEF(once: false, throwOnUserCancel: false, readerMode: NFCDispatchReaderMode()).listen((NDEFMessage message) { +// setState(() { +// _reading = true; +// mainWidget = doneNfc(); +// }); +// Future.delayed(const Duration(milliseconds: 500), () { +// _stream?.cancel(); +// widget.onNcfScan(nfcId); +// Navigator.pop(context); +// }); +// print("read NDEF id: ${message.id}"); +// print("NFC Record " + message.payload); +// print("NFC Record Lenght " + message.records.length.toString()); +// print("NFC Record " + message.records.first.id); +// print("NFC Record " + message.records.first.payload); +// print("NFC Record " + message.records.first.data); +// print("NFC Record " + message.records.first.type); +// // widget.onNcfScan(message.id); +// nfcId = message.id; +// }, onError: (e) { +// // Check error handling guide below +// }); +// }); +// } +// +// @override +// Widget build(BuildContext context) { +// (mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc(); +// return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget); +// } +// +// Widget scanNfc() { +// return Container( +// key: ValueKey(1), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// SizedBox( +// height: 30, +// ), +// Text( +// "Ready To Scan", +// style: TextStyle( +// fontWeight: FontWeight.bold, +// fontSize: 24, +// ), +// ), +// SizedBox( +// height: 30, +// ), +// Image.asset( +// "assets/images/nfc/ic_nfc.png", +// height: MediaQuery.of(context).size.width / 3, +// ), +// SizedBox( +// height: 30, +// ), +// Text( +// "Approach an NFC Tag", +// style: TextStyle( +// fontSize: 18, +// ), +// ), +// SizedBox( +// height: 30, +// ), +// ButtonTheme( +// minWidth: MediaQuery.of(context).size.width / 1.2, +// height: 45.0, +// buttonColor: Colors.grey[300], +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(6), +// ), +// child: RaisedButton( +// onPressed: () { +// _stream?.cancel(); +// Navigator.pop(context); +// }, +// elevation: 0, +// child: Text("CANCEL"), +// ), +// ), +// SizedBox( +// height: 30, +// ), +// ], +// ), +// ); +// } +// +// Widget doneNfc() { +// return Container( +// key: ValueKey(2), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// SizedBox( +// height: 30, +// ), +// Text( +// "Successfully Scanned", +// style: TextStyle( +// fontWeight: FontWeight.bold, +// fontSize: 24, +// ), +// ), +// SizedBox( +// height: 30, +// ), +// Image.asset( +// "assets/images/nfc/ic_done.png", +// height: MediaQuery.of(context).size.width / 3, +// ), +// SizedBox( +// height: 30, +// ), +// Text( +// "Approach an NFC Tag", +// style: TextStyle( +// fontSize: 18, +// ), +// ), +// SizedBox( +// height: 30, +// ), +// ButtonTheme( +// minWidth: MediaQuery.of(context).size.width / 1.2, +// height: 45.0, +// buttonColor: Colors.grey[300], +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(6), +// ), +// child: RaisedButton( +// // onPressed: () { +// // _stream?.cancel(); +// // widget.onNcfScan(nfcId); +// // Navigator.pop(context); +// // }, +// onPressed: null, +// elevation: 0, +// child: Text("DONE"), +// ), +// ), +// SizedBox( +// height: 30, +// ), +// ], +// ), +// ); +// } +// } diff --git a/pubspec.yaml b/pubspec.yaml index 37a3352..d38cc5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -49,6 +49,16 @@ dependencies: shimmer: ^2.0.0 logger: ^1.1.0 flutter_countdown_timer: ^4.1.0 + nfc_manager: ^3.1.1 + uuid: ^3.0.6 + + # maps + google_maps_flutter: ^2.0.2 + google_maps_utils: ^1.4.0+1 + google_directions_api: ^0.9.0 + geolocator: any + # flutter_compass: ^0.6.1 + google_maps_flutter_web: ^0.3.2 dev_dependencies: @@ -84,6 +94,8 @@ flutter: - assets/images/ - assets/images/login/ - assets/images/logos/ + - assets/icons/nfc/ic_nfc.png + - assets/icons/nfc/ic_done.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. From 35d683a8ae2eca25970f8280e52e9fd2afbe9a40 Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Mon, 14 Mar 2022 16:14:15 +0300 Subject: [PATCH 16/22] NFC Attendance implement 1.0 --- lib/ui/login/login_screen.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index d5a6061..88caab9 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -69,12 +69,12 @@ class _LoginScreenState extends State { } String? firebaseToken; - + GetMobileLoginInfoListModel? loginInfo; Future checkFirebaseToken() async { try { Utils.showLoading(context); firebaseToken = await _firebaseMessaging.getToken(); - GetMobileLoginInfoListModel? loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); if (loginInfo == null) { Utils.hideLoading(context); print("Device token not found"); @@ -112,7 +112,7 @@ class _LoginScreenState extends State { } Utils.hideLoading(context); if (_autoLogin) { - Navigator.pushNamed(context, AppRoutes.verifyLastLogin); + Navigator.pushNamed(context, AppRoutes.verifyLastLogin, arguments: loginInfo); } else { Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken"); } @@ -125,10 +125,11 @@ class _LoginScreenState extends State { } } + @override Widget build(BuildContext context) { - username.text="15153"; - password.text="Xy12345@"; + username.text = "15153"; + password.text = "Xy12345@"; return Scaffold( body: Column( children: [ From eb3ddb3d9ef47579bf405d83a751739c24da4cc8 Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Sun, 20 Mar 2022 15:58:33 +0300 Subject: [PATCH 17/22] NFC Attendance implement 1.3 --- lib/api/login_api_client.dart | 2 +- lib/ui/landing/today_attendance_screen.dart | 37 ++++++++++++--------- lib/ui/login/login_screen.dart | 3 ++ lib/ui/login/verify_login_screen.dart | 5 ++- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart index 070fa27..2761ebe 100644 --- a/lib/api/login_api_client.dart +++ b/lib/api/login_api_client.dart @@ -79,7 +79,7 @@ class LoginApiClient { Future checkActivationCode(bool isDeviceNFC, String? mobileNumber, String activationCode, String? pUserName) async { String url = "${ApiConsts.erpRest}CheckActivationCode"; - Map postParams = {"isDeviceNFC": isDeviceNFC, "MobileNumber": mobileNumber, "activationCode": activationCode, "P_USER_NAME": pUserName}; + Map postParams = {"IsDeviceNFC": isDeviceNFC, "MobileNumber": mobileNumber, "activationCode": activationCode, "P_USER_NAME": pUserName}; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index 2008484..b1ce089 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -46,7 +46,7 @@ class _TodayAttendanceScreenState extends State { bool isAvailable = await NfcManager.instance.isAvailable(); setState(() { AppState().privilegeListModel!.forEach((element) { - // Check availability + print(element.serviceName.toString() + " " + element.previlege.toString()); // Check availability if (isAvailable) if (element.serviceName == "enableNFC") { // if (element.previlege ?? false) isNfcEnabled = true; @@ -190,21 +190,26 @@ class _TodayAttendanceScreenState extends State { gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), children: [ attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { - showNfcReader(context, onNcfScan: (String? nfcId) async { - print(nfcId); - Utils.showLoading(context); - try { - GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? ""); - bool status = await model.fetchAttendanceTracking(); - Utils.hideLoading(context); - } catch (ex) { - print(ex); - Utils.hideLoading(context); - Utils.handleException(ex, (msg) { - Utils.confirmDialog(context, msg); - }); - } - }); + if (isNfcLocationEnabled) { + print("nfc location enabled"); + } else { + print("nfc not location enabled"); + } + // showNfcReader(context, onNcfScan: (String? nfcId) async { + // print(nfcId); + // Utils.showLoading(context); + // try { + // GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? ""); + // bool status = await model.fetchAttendanceTracking(); + // Utils.hideLoading(context); + // } catch (ex) { + // print(ex); + // Utils.hideLoading(context); + // Utils.handleException(ex, (msg) { + // Utils.confirmDialog(context, msg); + // }); + // } + // }); // Location.getCurrentLocation((LatLng? latlng) { // print(latlng!.longitude.toString()); // }); diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 88caab9..944a11f 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -130,6 +130,9 @@ class _LoginScreenState extends State { Widget build(BuildContext context) { username.text = "15153"; password.text = "Xy12345@"; + + // username.text = "287742"; + // password.text = "509@Shafi"; return Scaffold( body: Column( children: [ diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index 8e9255f..7db2151 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -666,7 +666,7 @@ class _VerifyLoginScreenState extends State { (value) async { Utils.showLoading(context); try { - GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(true, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( AppState().memberLoginList?.pEMAILADDRESS ?? "", genericResponseModel?.pSESSIONID ?? 0, @@ -682,6 +682,9 @@ class _VerifyLoginScreenState extends State { AppState().setPrivilegeListModel = genericResponseModel!.privilegeList ?? []; AppState().setMemberInformationListModel = genericResponseModel.memberInformationList?.first; MemberInformationListModel.saveToPrefs(genericResponseModel.memberInformationList ?? []); + genericResponseModel.privilegeList!.forEach((element) { + print(element.serviceName.toString() + " " + element.previlege.toString()); // Check availability + }); PrivilegeListModel.saveToPrefs(genericResponseModel.privilegeList ?? []); Utils.saveStringFromPrefs(SharedPrefsConsts.username, AppState().getUserName!); Utils.saveStringFromPrefs(SharedPrefsConsts.password, AppState().password!); From 384aa8d9b4d49789a87dab33e455be1b80246d13 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 3 Apr 2022 16:24:33 +0300 Subject: [PATCH 18/22] wokrlist api's added & improvements --- assets/langs/ar-SA.json | 31 ++ assets/langs/en-US.json | 31 ++ lib/api/worklist/worklist_api_client.dart | 122 ++++- lib/classes/colors.dart | 3 +- lib/classes/date_uitl.dart | 4 + lib/extensions/widget_extensions.dart | 28 ++ lib/generated/codegen_loader.g.dart | 462 +++++++++++------- lib/generated/locale_keys.g.dart | 38 +- lib/models/generic_response_model.dart | 178 +++++-- ...llection_notification_body_list_model.dart | 97 ++++ lib/models/get_action_history_list_model.dart | 76 +++ .../get_basic_det_ntf_body_list_model.dart | 24 + .../get_mo_notification_body_list_model.dart | 104 ++++ .../get_notification_buttons_list_model.dart | 25 + ...stamp_ms_notification_body_list_model.dart | 132 +++++ ...ion_get_respond_attributes_list_model.dart | 24 + lib/models/subordinates_on_leaves_model.dart | 68 +++ lib/ui/login/login_screen.dart | 2 +- .../fragments/actions_fragment.dart | 149 +++--- .../fragments/detail_fragment.dart | 69 +++ .../fragments/info_fragments.dart | 109 +++-- .../fragments/request_fragment.dart | 5 +- .../missing_swipe/missing_swipe_screen.dart | 265 +++++++--- lib/ui/work_list/work_list_screen.dart | 4 +- lib/widgets/circular_avatar.dart | 26 +- 25 files changed, 1642 insertions(+), 434 deletions(-) create mode 100644 lib/models/get_absence_collection_notification_body_list_model.dart create mode 100644 lib/models/get_action_history_list_model.dart create mode 100644 lib/models/get_basic_det_ntf_body_list_model.dart create mode 100644 lib/models/get_mo_notification_body_list_model.dart create mode 100644 lib/models/get_notification_buttons_list_model.dart create mode 100644 lib/models/get_stamp_ms_notification_body_list_model.dart create mode 100644 lib/models/notification_get_respond_attributes_list_model.dart create mode 100644 lib/models/subordinates_on_leaves_model.dart create mode 100644 lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index e8892a8..38767b7 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -66,6 +66,37 @@ "whatsapp": "واتس اب", "reject": "يرفض", "approve": "يوافق", + "request": "طلب", + "actions": "أجراءات", + "delegate": "مندوب", + "request_info": "اطلب معلومات", + "attachments": "المرفقات", + "info": "معلومات", + "employeeNumber": "رقم الموظف", + "assignmentNumber": "رقم الواجب", + "employeeName": "اسم الموظف", + "scheduleDate": "تاريخ الجدول الزمني", + "shiftType": "نوع التحول", + "shift": "يحول", + "breakText": "استراحة", + "actualSwipeStart": "بدء التمرير الفعلي", + "actualSwipeEnd": "التمرير الفعلي للنهاية", + "approvedSwipeStart": "وافق انتقاد البدء", + "approvedSwipeStartReason": "تمت الموافقة على سبب بدء التمرير السريع", + "approvedSwipeEnd": "تمت الموافقة على تمرير النهاية", + "approvedSwipeEndReason": "الموافقة على سبب إنهاء التمرير", + "from": "من", + "to": "ل", + "sent": "أرسلت", + "closed": "مغلق", + "id": "هوية شخصية", + "responder": "المستجيب", + "jobTitle": "عنوان وظيفي", + "grade": "درجة", + "jobCategory": "تصنيف الوظيفة", + "category": "فئة", + "employeeEmailAddress": "عنوان البريد الإلكتروني للموظف", + "payrollBranch": "فرع الرواتب", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index f5b9b44..fecbf3d 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -66,6 +66,37 @@ "whatsapp": "Whatsapp", "reject": "Reject", "approve": "Approve", + "request": "Request", + "actions": "Actions", + "delegate": "Delegate", + "request_info": "Request Info", + "attachments": "Attachments", + "info": "Info.", + "employeeNumber": "Employee Number", + "assignmentNumber": "Assignment Number", + "employeeName": "Employee Name", + "scheduleDate": "Schedule Date", + "shiftType": "Shift Type", + "shift": "Shift", + "breakText": "Break", + "actualSwipeStart": "Actual Swipe Start", + "actualSwipeEnd": "Actual Swipe End", + "approvedSwipeStart": "Approved Swipe Start", + "approvedSwipeStartReason": "Approved Swipe Start Reason", + "approvedSwipeEnd": "Approved Swipe End", + "approvedSwipeEndReason": "Approved Swipe End Reason", + "from": "From", + "to": "To", + "sent": "Sent", + "closed": "Closed", + "id": "ID", + "responder": "Responder", + "jobTitle": "Job Title", + "grade": "Grade", + "jobCategory": "Job Category", + "category": "Category", + "employeeEmailAddress": "Employee Email Address", + "payrollBranch": "Payroll Branch", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index a473ba7..48fd13b 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -5,6 +5,13 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/member_information_list_model.dart'; +import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; +import 'package:mohem_flutter_app/models/subordinates_on_leaves_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; class WorkListApiClient { @@ -29,7 +36,7 @@ class WorkListApiClient { }, url, postParams); } - Future GetITGTaskCountRequestType() async { + Future getITGTaskCountRequestType() async { String url = "${ApiConsts.cocRest}ITGGetTaskCountRequestType"; Map postParams = {}; postParams.addAll(AppState().postParamsJson); @@ -38,4 +45,117 @@ class WorkListApiClient { return responseData; }, url, postParams); } + + Future getSubordinatesLeaves(String fromDate, String toDate) async { + String url = "${ApiConsts.erpRest}GET_SUBORDINATES_LEAVES"; + Map postParams = {"P_DATE_FROM": "/Date(1639861200000+0300)/", "P_DATE_TO": "/Date(1640120400000+0300)/"}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future> getAttachments(int pNotificationID) async { + String url = "${ApiConsts.erpRest}GET_ATTACHMENTS"; + Map postParams = {"P_NOTIFICATION_ID": pNotificationID}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getAttachementList ?? []; + }, url, postParams); + } + + Future> getActionHistory(int pNotificationID) async { + String url = "${ApiConsts.erpRest}GET_ACTION_HISTORY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getActionHistoryList ?? []; + }, url, postParams); + } + + Future> getNotificationButtons(int pNotificationID) async { + String url = "${ApiConsts.erpRest}GET_NOTIFICATION_BUTTONS"; + Map postParams = {"P_NOTIFICATION_ID": pNotificationID}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getNotificationButtonsList ?? []; + }, url, postParams); + } + + Future> notificationGetRespondAttributes(int pNotificationID) async { + String url = "${ApiConsts.erpRest}NOTIFICATION_GET_RESPOND_ATTRIBUTES"; + Map postParams = {"P_NOTIFICATION_ID": pNotificationID}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.notificationGetRespondAttributesList ?? []; + }, url, postParams); + } + + Future getBasicDetNTFBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_BASIC_DET_NTF_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getUserInformation(int pSelectedResopID) async { + String url = "${ApiConsts.erpRest}Get_UserInformation"; + Map postParams = { + "P_SELECTED_RESP_ID": pSelectedResopID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.memberInformationList![0]; + }, url, postParams); + } + + Future> getStampMsNotificationBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_STAMP_MS_NOTIFICATION_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getStampMsNotificationBodyList ?? []; + }, url, postParams); + } + + Future> getAbsenceNotificationBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_ABSENCE_NOTIFICATION_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getAbsenceCollectionNotificationBodyList ?? []; + }, url, postParams); + } } diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 0d80b05..6036534 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -6,10 +6,11 @@ class MyColors { static const Color normalTextColor = Color(0xff5A5A5A); static const Color lightTextColor = Color(0xffBFBFBF); static const Color gradiantStartColor = Color(0xff33c0a5); - static const Color gradiantEndColor = Color(0xff259db7 ); + static const Color gradiantEndColor = Color(0xff259db7); static const Color textMixColor = Color(0xff2BB8A6); static const Color backgroundColor = Color(0xffF8F8F8); static const Color grey57Color = Color(0xff575757); + static const Color grey67Color = Color(0xff676767); static const Color grey77Color = Color(0xff777777); static const Color grey70Color = Color(0xff707070); static const Color greyACColor = Color(0xffACACAC); diff --git a/lib/classes/date_uitl.dart b/lib/classes/date_uitl.dart index d0f4b1f..c350cb6 100644 --- a/lib/classes/date_uitl.dart +++ b/lib/classes/date_uitl.dart @@ -23,6 +23,10 @@ class DateUtil { return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date); } + static DateTime convertSimpleStringDateToDateddMMyyyy(String date) { + return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date); + } + static DateTime convertStringToDateNoTimeZone(String date) { // /Date(1585774800000+0300)/ if (date != null) { diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 5169f19..f511422 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:shimmer/shimmer.dart'; extension WidgetExtensions on Widget { @@ -36,4 +38,30 @@ extension WidgetExtensions on Widget { switchOutCurve: Curves.linearToEaseOut, child: this, ); + + Widget objectContainerView({String title = ""}) { + return Container( + padding: const EdgeInsets.only(top: 15, bottom: 15, left: 14, right: 14), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (title.isNotEmpty) title.toText16(), + if (title.isNotEmpty) 12.height, + this, + ], + ), + ); + } } diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index f4a2a6c..a555432 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -6,193 +6,289 @@ import 'dart:ui'; import 'package:easy_localization/easy_localization.dart' show AssetLoader; -class CodegenLoader extends AssetLoader { +class CodegenLoader extends AssetLoader{ const CodegenLoader(); @override - Future> load(String fullPath, Locale locale) { + Future> load(String fullPath, Locale locale ) { return Future.value(mapLocales[locale.toString()]); } - static const Map ar_SA = { - "mohemm": "Mohemm", - "english": "English", - "arabic": "Arabic", - "login": "تسجيل الدخول", - "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", - "username": "اسم المستخدم", - "password": "كلمة المرور", - "welcomeBack": "مرحبا بعودتك", - "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", - "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", - "verificationType": "نوع التحقق:", - "pleaseVerify": "ارجوك تحقق", - "verifyThroughFace": "تحقق من خلال الوجه", - "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", - "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", - "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", - "useAnotherAccount": "استخدم حسابا آخر", - "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", - "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", - "goodMorning": "صباح الخير", - "markAttendance": "علامة الحضور", - "timeLeftToday": "الوقت المتبقي اليوم", - "checkIn": "تحقق في", - "workList": "قائمة العمل", - "leaveBalance": "رصيد الاجازات", - "missingSwipes": "الضربات الشديدة في عداد المفقودين", - "ticketBalance": "رصيد التذكرة", - "other": "آخر", - "services": "خدمات", - "viewAllServices": "عرض جميع الخدمات", - "monthlyAttendance": "الحضور الشهري", - "workFromHome": "العمل من المنزل", - "ticketRequest": "طلب تذكرة", - "viewAllOffers": "مشاهدة جميع العروض", - "offers": "عروض & ", - "discounts": "الخصومات", - "newString": "جديد", - "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", - "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", - "confirmPassword": "تأكيد كلمة المرور", - "update": "تحديث", - "title": "عنوان", - "home": "مسكن", - "mySalary": "راتبي", - "createRequest": "إنشاء طلب", - "forgotPassword": "هل نسيت كلمة السر", - "employeeId": "هوية الموظف", - "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", - "changePassword": "تغيير كلمة المرور", - "ok": "موافق", - "confirm": "تؤكد", - "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", - "itemsForSale": "سلع للبيع", - "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", - "atLeastOneLowercase": "حرف صغير واحد على الأقل", - "atLeastOneUppercase": "حرف كبير واحد على الأقل", - "atLeastOneNumeric": "رقم واحد على الأقل", - "minimum8Characters": "8 أحرف على الأقل", - "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", - "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", - "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", - "sms": "رسالة قصيرة", - "fingerPrint": "بصمة", - "face": "التعرف على الوجه", - "whatsapp": "واتس اب", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "human": "Human", - "resources": "Resources", - "profile": { - "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"} - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "}, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} - }, - "reset_locale": "Reset Language" - }; - static const Map en_US = { - "mohemm": "Mohemm", - "english": "English", - "arabic": "Arabic", - "login": "Login", - "pleaseEnterLoginDetails": "Please enter the detail below to login", - "username": "Username", - "password": "Password", - "welcomeBack": "Welcome back", - "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", - "lastLoginDetails": "Last Login Details:", - "verificationType": "Verification Type:", - "pleaseVerify": "Please Verify", - "verifyThroughFace": "Verify Through Face", - "verifyThroughFingerprint": "Verify Through Fingerprint", - "verifyThroughSMS": "Verify Through SMS", - "verifyThroughWhatsapp": "Verify Through Whatsapp", - "useAnotherAccount": "Use Another Account", - "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", - "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "goodMorning": "Good Morning", - "markAttendance": "Mark Attendance", - "timeLeftToday": "Time Left Today", - "checkIn": "Check In", - "workList": "Work List", - "leaveBalance": "Leave Balance", - "missingSwipes": "Missing Swipes", - "ticketBalance": "Ticket Balance", - "other": "Other", - "services": "Services", - "viewAllServices": "View All Services", - "monthlyAttendance": "Monthly Attendance", - "workFromHome": "Work From Home", - "ticketRequest": "Ticket Request", - "viewAllOffers": "View All Offers", - "offers": "Offers & ", - "discounts": "Discounts", - "newString": "New", - "setTheNewPassword": "Set the new password", - "typeYourNewPasswordBelow": "Type your new password below", - "confirmPassword": "Confirm Password", - "update": "Update", - "title": "Title", - "home": "Home", - "mySalary": "My Salary", - "createRequest": "Create Request", - "forgotPassword": "Forgot Password", - "employeeId": "Employee ID", - "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", - "changePassword": "Change Password", - "ok": "OK", - "confirm": "Confirm", - "passwordChangedSuccessfully": "Password changed successfully", - "itemsForSale": "Items for Sale", - "doNotUseRecentPassword": "Do not use recent password", - "atLeastOneLowercase": "At least one lowercase", - "atLeastOneUppercase": "At least one uppercase", - "atLeastOneNumeric": "At least one numeric", - "minimum8Characters": "Minimum 8 characters", - "doNotAddRepeatingLetters": "Do not add repeating letters", - "itShouldContainSpecialCharacter": "It should contain special character", - "confirmPasswordMustMatch": "Confirm password must match", - "sms": "SMS", - "fingerPrint": "Fingerprint", - "face": "Face", - "whatsapp": "Whatsapp", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "human": "Human", - "resources": "Resources", - "profile": { - "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"} - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "}, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} - }, - "reset_locale": "Reset Language" - }; - static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; + static const Map ar_SA = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "تسجيل الدخول", + "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", + "username": "اسم المستخدم", + "password": "كلمة المرور", + "welcomeBack": "مرحبا بعودتك", + "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", + "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", + "verificationType": "نوع التحقق:", + "pleaseVerify": "ارجوك تحقق", + "verifyThroughFace": "تحقق من خلال الوجه", + "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", + "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", + "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", + "useAnotherAccount": "استخدم حسابا آخر", + "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", + "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", + "goodMorning": "صباح الخير", + "markAttendance": "علامة الحضور", + "timeLeftToday": "الوقت المتبقي اليوم", + "checkIn": "تحقق في", + "workList": "قائمة العمل", + "leaveBalance": "رصيد الاجازات", + "missingSwipes": "الضربات الشديدة في عداد المفقودين", + "ticketBalance": "رصيد التذكرة", + "other": "آخر", + "services": "خدمات", + "viewAllServices": "عرض جميع الخدمات", + "monthlyAttendance": "الحضور الشهري", + "workFromHome": "العمل من المنزل", + "ticketRequest": "طلب تذكرة", + "viewAllOffers": "مشاهدة جميع العروض", + "offers": "عروض & ", + "discounts": "الخصومات", + "newString": "جديد", + "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", + "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "confirmPassword": "تأكيد كلمة المرور", + "update": "تحديث", + "title": "عنوان", + "home": "مسكن", + "mySalary": "راتبي", + "createRequest": "إنشاء طلب", + "forgotPassword": "هل نسيت كلمة السر", + "employeeId": "هوية الموظف", + "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", + "changePassword": "تغيير كلمة المرور", + "ok": "موافق", + "confirm": "تؤكد", + "passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح", + "itemsForSale": "سلع للبيع", + "doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة", + "atLeastOneLowercase": "حرف صغير واحد على الأقل", + "atLeastOneUppercase": "حرف كبير واحد على الأقل", + "atLeastOneNumeric": "رقم واحد على الأقل", + "minimum8Characters": "8 أحرف على الأقل", + "doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة", + "itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص", + "confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور", + "sms": "رسالة قصيرة", + "fingerPrint": "بصمة", + "face": "التعرف على الوجه", + "whatsapp": "واتس اب", + "reject": "يرفض", + "approve": "يوافق", + "request": "طلب", + "actions": "أجراءات", + "delegate": "مندوب", + "request_info": "اطلب معلومات", + "attachments": "المرفقات", + "info": "معلومات", + "employeeNumber": "رقم الموظف", + "assignmentNumber": "رقم الواجب", + "employeeName": "اسم الموظف", + "scheduleDate": "تاريخ الجدول الزمني", + "shiftType": "نوع التحول", + "shift": "يحول", + "breakText": "استراحة", + "actualSwipeStart": "بدء التمرير الفعلي", + "actualSwipeEnd": "التمرير الفعلي للنهاية", + "approvedSwipeStart": "وافق انتقاد البدء", + "approvedSwipeStartReason": "تمت الموافقة على سبب بدء التمرير السريع", + "approvedSwipeEnd": "تمت الموافقة على تمرير النهاية", + "approvedSwipeEndReason": "الموافقة على سبب إنهاء التمرير", + "from": "من", + "to": "ل", + "sent": "أرسلت", + "closed": "مغلق", + "id": "هوية شخصية", + "responder": "المستجيب", + "jobTitle": "عنوان وظيفي", + "grade": "درجة", + "jobCategory": "تصنيف الوظيفة", + "category": "فئة", + "employeeEmailAddress": "عنوان البريد الإلكتروني للموظف", + "payrollBranch": "فرع الرواتب", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "بشري", + "resources": "موارد", + "details": "تفاصيل", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language" +}; +static const Map en_US = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "Login", + "pleaseEnterLoginDetails": "Please enter the detail below to login", + "username": "Username", + "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "newString": "New", + "setTheNewPassword": "Set the new password", + "typeYourNewPasswordBelow": "Type your new password below", + "confirmPassword": "Confirm Password", + "update": "Update", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", + "forgotPassword": "Forgot Password", + "employeeId": "Employee ID", + "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", + "changePassword": "Change Password", + "ok": "OK", + "confirm": "Confirm", + "passwordChangedSuccessfully": "Password changed successfully", + "itemsForSale": "Items for Sale", + "doNotUseRecentPassword": "Do not use recent password", + "atLeastOneLowercase": "At least one lowercase", + "atLeastOneUppercase": "At least one uppercase", + "atLeastOneNumeric": "At least one numeric", + "minimum8Characters": "Minimum 8 characters", + "doNotAddRepeatingLetters": "Do not add repeating letters", + "itShouldContainSpecialCharacter": "It should contain special character", + "confirmPasswordMustMatch": "Confirm password must match", + "sms": "SMS", + "fingerPrint": "Fingerprint", + "face": "Face", + "whatsapp": "Whatsapp", + "reject": "Reject", + "approve": "Approve", + "request": "Request", + "actions": "Actions", + "delegate": "Delegate", + "request_info": "Request Info", + "attachments": "Attachments", + "info": "Info.", + "employeeNumber": "Employee Number", + "assignmentNumber": "Assignment Number", + "employeeName": "Employee Name", + "scheduleDate": "Schedule Date", + "shiftType": "Shift Type", + "shift": "Shift", + "breakText": "Break", + "actualSwipeStart": "Actual Swipe Start", + "actualSwipeEnd": "Actual Swipe End", + "approvedSwipeStart": "Approved Swipe Start", + "approvedSwipeStartReason": "Approved Swipe Start Reason", + "approvedSwipeEnd": "Approved Swipe End", + "approvedSwipeEndReason": "Approved Swipe End Reason", + "from": "From", + "to": "To", + "sent": "Sent", + "closed": "Closed", + "id": "ID", + "responder": "Responder", + "jobTitle": "Job Title", + "grade": "Grade", + "jobCategory": "Job Category", + "category": "Category", + "employeeEmailAddress": "Employee Email Address", + "payrollBranch": "Payroll Branch", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "details": "Details", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language" +}; +static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 55e543b..faaea1c 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1,6 +1,6 @@ // DO NOT EDIT. This is code generated via package:easy_localization/generate.dart -abstract class LocaleKeys { +abstract class LocaleKeys { static const mohemm = 'mohemm'; static const english = 'english'; static const arabic = 'arabic'; @@ -65,14 +65,45 @@ abstract class LocaleKeys { static const fingerPrint = 'fingerPrint'; static const face = 'face'; static const whatsapp = 'whatsapp'; + static const reject = 'reject'; + static const approve = 'approve'; + static const request = 'request'; + static const actions = 'actions'; + static const delegate = 'delegate'; + static const request_info = 'request_info'; + static const attachments = 'attachments'; + static const info = 'info'; + static const employeeNumber = 'employeeNumber'; + static const assignmentNumber = 'assignmentNumber'; + static const employeeName = 'employeeName'; + static const scheduleDate = 'scheduleDate'; + static const shiftType = 'shiftType'; + static const shift = 'shift'; + static const breakText = 'breakText'; + static const actualSwipeStart = 'actualSwipeStart'; + static const actualSwipeEnd = 'actualSwipeEnd'; + static const approvedSwipeStart = 'approvedSwipeStart'; + static const approvedSwipeStartReason = 'approvedSwipeStartReason'; + static const approvedSwipeEnd = 'approvedSwipeEnd'; + static const approvedSwipeEndReason = 'approvedSwipeEndReason'; + static const from = 'from'; + static const to = 'to'; + static const sent = 'sent'; + static const closed = 'closed'; + static const id = 'id'; + static const responder = 'responder'; + static const jobTitle = 'jobTitle'; + static const grade = 'grade'; + static const jobCategory = 'jobCategory'; + static const category = 'category'; + static const employeeEmailAddress = 'employeeEmailAddress'; + static const payrollBranch = 'payrollBranch'; static const msg = 'msg'; static const msg_named = 'msg_named'; static const clickMe = 'clickMe'; static const human = 'human'; static const resources = 'resources'; static const details = 'details'; - static const reject = 'reject'; - static const approve = 'approve'; static const profile_reset_password_label = 'profile.reset_password.label'; static const profile_reset_password_username = 'profile.reset_password.username'; static const profile_reset_password_password = 'profile.reset_password.password'; @@ -83,4 +114,5 @@ abstract class LocaleKeys { static const gender_with_arg = 'gender.with_arg'; static const gender = 'gender'; static const reset_locale = 'reset_locale'; + } diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 0b5c497..956a0d0 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,14 +1,22 @@ +import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_basic_det_ntf_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; +import 'package:mohem_flutter_app/models/subordinates_on_leaves_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; import 'basic_member_information_model.dart'; -import 'get_mobile_login_info_list_model.dart'; import 'dashboard/get_accrual_balances_list_model.dart'; import 'dashboard/get_attendance_tracking_list_model.dart'; import 'dashboard/get_open_missing_swipes_list_model.dart'; import 'dashboard/get_open_notifications_list.dart'; import 'dashboard/list_menu.dart'; import 'dashboard/menu_entries.dart'; +import 'get_mobile_login_info_list_model.dart'; import 'member_information_list_model.dart'; import 'privilege_list_model.dart'; @@ -62,11 +70,11 @@ class GenericResponseModel { String? forgetPasswordTokenID; List? getAbsenceAttachmentsList; List? getAbsenceAttendanceTypesList; - List? getAbsenceCollectionNotificationBodyList; + List? getAbsenceCollectionNotificationBodyList; List? getAbsenceDffStructureList; List? getAbsenceTransactionList; List? getAccrualBalancesList; - List? getActionHistoryList; + List? getActionHistoryList; List? getAddressDffStructureList; List? getAddressNotificationBodyList; List? getApprovesList; @@ -74,7 +82,7 @@ class GenericResponseModel { GetAttendanceTracking? getAttendanceTrackingList; List? getBasicDetColsStructureList; List? getBasicDetDffStructureList; - List? getBasicDetNtfBodyList; + List? getBasicDetNtfBodyList; List? getCEICollectionNotificationBodyList; List? getCEIDFFStructureList; List? getCEITransactionList; @@ -109,8 +117,8 @@ class GenericResponseModel { List? getLookupValuesList; List? getMenuEntriesList; List? getMoItemHistoryList; - List? getMoNotificationBodyList; - List? getNotificationButtonsList; + List? getMoNotificationBodyList; + List? getNotificationButtonsList; List? getNotificationReassignModeList; List? getObjectValuesList; GetOpenMissingSwipesList? getOpenMissingSwipesList; @@ -135,10 +143,10 @@ class GenericResponseModel { List? getSITTransactionList; List? getScheduleShiftsDetailsList; List? getShiftTypesList; - List? getStampMsNotificationBodyList; + List? getStampMsNotificationBodyList; List? getStampNsNotificationBodyList; List? getSubordinatesAttdStatusList; - List? getSubordinatesLeavesList; + List? getSubordinatesLeavesList; List? getSubordinatesLeavesTotalVacationsList; List? getSummaryOfPaymentList; List? getSwipesList; @@ -190,15 +198,15 @@ class GenericResponseModel { String? mohemmWifiPassword; String? mohemmWifiSSID; String? notificationAction; - String? notificationGetRespondAttributesList; - String? notificationRespondRolesList; + List? notificationGetRespondAttributesList; + List? notificationRespondRolesList; int? oracleOutPutNumber; String? pASSWORDEXPIREDMSG; String? pCOUNTRYCODE; String? pCOUNTRYNAME; String? pDESCFLEXCONTEXTCODE; String? pDESCFLEXCONTEXTNAME; - Null? pForm; + String? pForm; String? pINFORMATION; int? pMBLID; String? pNUMOFSUBORDINATES; @@ -239,7 +247,7 @@ class GenericResponseModel { String? submitPhonesTransactionList; String? submitSITTransactionList; String? submitTermTransactionList; - String? subordinatesOnLeavesList; + List? subordinatesOnLeavesList; String? sumbitAbsenceTransactionList; String? tokenID; String? updateAttachmentList; @@ -568,11 +576,25 @@ class GenericResponseModel { forgetPasswordTokenID = json['ForgetPasswordTokenID']; getAbsenceAttachmentsList = json['GetAbsenceAttachmentsList']; getAbsenceAttendanceTypesList = json['GetAbsenceAttendanceTypesList']; - getAbsenceCollectionNotificationBodyList = json['GetAbsenceCollectionNotificationBodyList']; + + if (json['GetAbsenceCollectionNotificationBodyList'] != null) { + getAbsenceCollectionNotificationBodyList = []; + json['GetAbsenceCollectionNotificationBodyList'].forEach((v) { + getAbsenceCollectionNotificationBodyList!.add(new GetAbsenceCollectionNotificationBodyList.fromJson(v)); + }); + } + getAbsenceDffStructureList = json['GetAbsenceDffStructureList']; getAbsenceTransactionList = json['GetAbsenceTransactionList']; getAccrualBalancesList = json["GetAccrualBalancesList"] == null ? null : List.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x))); - getActionHistoryList = json['GetActionHistoryList']; + + if (json['GetActionHistoryList'] != null) { + getActionHistoryList = []; + json['GetActionHistoryList'].forEach((v) { + getActionHistoryList!.add(GetActionHistoryList.fromJson(v)); + }); + } + getAddressDffStructureList = json['GetAddressDffStructureList']; getAddressNotificationBodyList = json['GetAddressNotificationBodyList']; getApprovesList = json['GetApprovesList']; @@ -580,7 +602,14 @@ class GenericResponseModel { getAttendanceTrackingList = json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]); getBasicDetColsStructureList = json['GetBasicDetColsStructureList']; getBasicDetDffStructureList = json['GetBasicDetDffStructureList']; - getBasicDetNtfBodyList = json['GetBasicDetNtfBodyList']; + + if (json['GetBasicDetNtfBodyList'] != null) { + getBasicDetNtfBodyList = []; + json['GetBasicDetNtfBodyList'].forEach((v) { + getBasicDetNtfBodyList!.add(new GetBasicDetNtfBodyList.fromJson(v)); + }); + } + getCEICollectionNotificationBodyList = json['GetCEICollectionNotificationBodyList']; getCEIDFFStructureList = json['GetCEIDFFStructureList']; getCEITransactionList = json['GetCEITransactionList']; @@ -615,8 +644,21 @@ class GenericResponseModel { getLookupValuesList = json['GetLookupValuesList']; getMenuEntriesList = json["GetMenuEntriesList"] == null ? null : List.from(json["GetMenuEntriesList"].map((x) => GetMenuEntriesList.fromJson(x))); getMoItemHistoryList = json['GetMoItemHistoryList']; - getMoNotificationBodyList = json['GetMoNotificationBodyList']; - getNotificationButtonsList = json['GetNotificationButtonsList']; + + if (json['GetMoNotificationBodyList'] != null) { + getMoNotificationBodyList = []; + json['GetMoNotificationBodyList'].forEach((v) { + getMoNotificationBodyList!.add(new GetMoNotificationBodyList.fromJson(v)); + }); + } + + if (json['GetNotificationButtonsList'] != null) { + getNotificationButtonsList = []; + json['GetNotificationButtonsList'].forEach((v) { + getNotificationButtonsList!.add(new GetNotificationButtonsList.fromJson(v)); + }); + } + getNotificationReassignModeList = json['GetNotificationReassignModeList']; getObjectValuesList = json['GetObjectValuesList']; getOpenMissingSwipesList = json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); @@ -641,10 +683,24 @@ class GenericResponseModel { getSITTransactionList = json['GetSITTransactionList']; getScheduleShiftsDetailsList = json['GetScheduleShiftsDetailsList']; getShiftTypesList = json['GetShiftTypesList']; - getStampMsNotificationBodyList = json['GetStampMsNotificationBodyList']; + + if (json['GetStampMsNotificationBodyList'] != null) { + getStampMsNotificationBodyList = []; + json['GetStampMsNotificationBodyList'].forEach((v) { + getStampMsNotificationBodyList!.add(new GetStampMsNotificationBodyList.fromJson(v)); + }); + } + getStampNsNotificationBodyList = json['GetStampNsNotificationBodyList']; getSubordinatesAttdStatusList = json['GetSubordinatesAttdStatusList']; - getSubordinatesLeavesList = json['GetSubordinatesLeavesList']; + + if (json['GetSubordinatesLeavesList'] != null) { + getSubordinatesLeavesList = []; + json['GetSubordinatesLeavesList'].forEach((v) { + getSubordinatesLeavesList!.add(SubordinatesLeavesList.fromJson(v)); + }); + } + getSubordinatesLeavesTotalVacationsList = json['GetSubordinatesLeavesTotalVacationsList']; getSummaryOfPaymentList = json['GetSummaryOfPaymentList']; getSwipesList = json['GetSwipesList']; @@ -703,7 +759,7 @@ class GenericResponseModel { if (json['Mohemm_GetMobileLoginInfoList'] != null) { mohemmGetMobileLoginInfoList = []; json['Mohemm_GetMobileLoginInfoList'].forEach((v) { - mohemmGetMobileLoginInfoList!.add(new GetMobileLoginInfoListModel.fromJson(v)); + mohemmGetMobileLoginInfoList!.add(GetMobileLoginInfoListModel.fromJson(v)); }); } mohemmGetPatientIDList = json['Mohemm_GetPatientID_List']; @@ -713,8 +769,21 @@ class GenericResponseModel { mohemmWifiPassword = json['Mohemm_Wifi_Password']; mohemmWifiSSID = json['Mohemm_Wifi_SSID']; notificationAction = json['NotificationAction']; - notificationGetRespondAttributesList = json['NotificationGetRespondAttributesList']; - notificationRespondRolesList = json['NotificationRespondRolesList']; + + if (json['NotificationGetRespondAttributesList'] != null) { + notificationGetRespondAttributesList = []; + json['NotificationGetRespondAttributesList'].forEach((v) { + notificationGetRespondAttributesList!.add(NotificationGetRespondAttributesList.fromJson(v)); + }); + } + + if (json['NotificationRespondRolesList'] != null) { + notificationRespondRolesList = []; + json['NotificationGetRespondAttributesList'].forEach((v) { + // notificationRespondRolesList!.add(v); + }); + } + oracleOutPutNumber = json['OracleOutPutNumber']; pASSWORDEXPIREDMSG = json['PASSWORD_EXPIRED_MSG']; pCOUNTRYCODE = json['P_COUNTRY_CODE']; @@ -769,7 +838,14 @@ class GenericResponseModel { submitPhonesTransactionList = json['SubmitPhonesTransactionList']; submitSITTransactionList = json['SubmitSITTransactionList']; submitTermTransactionList = json['SubmitTermTransactionList']; - subordinatesOnLeavesList = json['SubordinatesOnLeavesList']; + + if (json['SubordinatesOnLeavesList'] != null) { + subordinatesOnLeavesList = []; + json['GetSubordinatesLeavesList'].forEach((v) { + subordinatesOnLeavesList!.add(SubordinatesLeavesList.fromJson(v)); + }); + } + sumbitAbsenceTransactionList = json['SumbitAbsenceTransactionList']; tokenID = json['TokenID']; updateAttachmentList = json['UpdateAttachmentList']; @@ -849,11 +925,19 @@ class GenericResponseModel { data['ForgetPasswordTokenID'] = this.forgetPasswordTokenID; data['GetAbsenceAttachmentsList'] = this.getAbsenceAttachmentsList; data['GetAbsenceAttendanceTypesList'] = this.getAbsenceAttendanceTypesList; - data['GetAbsenceCollectionNotificationBodyList'] = this.getAbsenceCollectionNotificationBodyList; + + if (this.getAbsenceCollectionNotificationBodyList != null) { + data['GetAbsenceCollectionNotificationBodyList'] = this.getAbsenceCollectionNotificationBodyList!.map((v) => v.toJson()).toList(); + } + data['GetAbsenceDffStructureList'] = this.getAbsenceDffStructureList; data['GetAbsenceTransactionList'] = this.getAbsenceTransactionList; data['GetAccrualBalancesList'] = this.getAccrualBalancesList; - data['GetActionHistoryList'] = this.getActionHistoryList; + + if (this.getActionHistoryList != null) { + data['GetActionHistoryList'] = this.getActionHistoryList!.map((v) => v.toJson()).toList(); + } + data['GetAddressDffStructureList'] = this.getAddressDffStructureList; data['GetAddressNotificationBodyList'] = this.getAddressNotificationBodyList; data['GetApprovesList'] = this.getApprovesList; @@ -861,7 +945,11 @@ class GenericResponseModel { data['GetAttendanceTrackingList'] = this.getAttendanceTrackingList; data['GetBasicDetColsStructureList'] = this.getBasicDetColsStructureList; data['GetBasicDetDffStructureList'] = this.getBasicDetDffStructureList; - data['GetBasicDetNtfBodyList'] = this.getBasicDetNtfBodyList; + + if (this.getBasicDetNtfBodyList != null) { + data['GetBasicDetNtfBodyList'] = this.getBasicDetNtfBodyList!.map((v) => v.toJson()).toList(); + } + data['GetCEICollectionNotificationBodyList'] = this.getCEICollectionNotificationBodyList; data['GetCEIDFFStructureList'] = this.getCEIDFFStructureList; data['GetCEITransactionList'] = this.getCEITransactionList; @@ -896,8 +984,15 @@ class GenericResponseModel { data['GetLookupValuesList'] = this.getLookupValuesList; data['GetMenuEntriesList'] = this.getMenuEntriesList; data['GetMoItemHistoryList'] = this.getMoItemHistoryList; - data['GetMoNotificationBodyList'] = this.getMoNotificationBodyList; - data['GetNotificationButtonsList'] = this.getNotificationButtonsList; + + if (this.getMoNotificationBodyList != null) { + data['GetMoNotificationBodyList'] = this.getMoNotificationBodyList!.map((v) => v.toJson()).toList(); + } + + if (this.getNotificationButtonsList != null) { + data['GetNotificationButtonsList'] = this.getNotificationButtonsList!.map((v) => v.toJson()).toList(); + } + data['GetNotificationReassignModeList'] = this.getNotificationReassignModeList; data['GetObjectValuesList'] = this.getObjectValuesList; data['GetOpenMissingSwipesList'] = this.getOpenMissingSwipesList; @@ -922,10 +1017,19 @@ class GenericResponseModel { data['GetSITTransactionList'] = this.getSITTransactionList; data['GetScheduleShiftsDetailsList'] = this.getScheduleShiftsDetailsList; data['GetShiftTypesList'] = this.getShiftTypesList; - data['GetStampMsNotificationBodyList'] = this.getStampMsNotificationBodyList; + + if (this.getStampMsNotificationBodyList != null) { + data['GetStampMsNotificationBodyList'] = this.getStampMsNotificationBodyList!.map((v) => v.toJson()).toList(); + } + data['GetStampNsNotificationBodyList'] = this.getStampNsNotificationBodyList; data['GetSubordinatesAttdStatusList'] = this.getSubordinatesAttdStatusList; data['GetSubordinatesLeavesList'] = this.getSubordinatesLeavesList; + + if (this.getSubordinatesLeavesList != null) { + data['GetSubordinatesLeavesList'] = this.getSubordinatesLeavesList!.map((v) => v.toJson()).toList(); + } + data['GetSubordinatesLeavesTotalVacationsList'] = this.getSubordinatesLeavesTotalVacationsList; data['GetSummaryOfPaymentList'] = this.getSummaryOfPaymentList; data['GetSwipesList'] = this.getSwipesList; @@ -985,8 +1089,15 @@ class GenericResponseModel { data['Mohemm_Wifi_Password'] = this.mohemmWifiPassword; data['Mohemm_Wifi_SSID'] = this.mohemmWifiSSID; data['NotificationAction'] = this.notificationAction; - data['NotificationGetRespondAttributesList'] = this.notificationGetRespondAttributesList; - data['NotificationRespondRolesList'] = this.notificationRespondRolesList; + + if (notificationGetRespondAttributesList != null) { + data['NotificationGetRespondAttributesList'] = notificationGetRespondAttributesList!.map((v) => v.toJson()).toList(); + } + + if (notificationRespondRolesList != null) { + data['NotificationRespondRolesList'] = notificationRespondRolesList!.map((v) => v).toList(); + } + data['OracleOutPutNumber'] = this.oracleOutPutNumber; data['PASSWORD_EXPIRED_MSG'] = this.pASSWORDEXPIREDMSG; data['P_COUNTRY_CODE'] = this.pCOUNTRYCODE; @@ -1037,6 +1148,11 @@ class GenericResponseModel { data['SubmitSITTransactionList'] = this.submitSITTransactionList; data['SubmitTermTransactionList'] = this.submitTermTransactionList; data['SubordinatesOnLeavesList'] = this.subordinatesOnLeavesList; + + if (this.subordinatesOnLeavesList != null) { + data['SubordinatesOnLeavesList'] = this.subordinatesOnLeavesList!.map((v) => v.toJson()).toList(); + } + data['SumbitAbsenceTransactionList'] = this.sumbitAbsenceTransactionList; data['TokenID'] = this.tokenID; data['UpdateAttachmentList'] = this.updateAttachmentList; diff --git a/lib/models/get_absence_collection_notification_body_list_model.dart b/lib/models/get_absence_collection_notification_body_list_model.dart new file mode 100644 index 0000000..4ac1f27 --- /dev/null +++ b/lib/models/get_absence_collection_notification_body_list_model.dart @@ -0,0 +1,97 @@ + +class GetAbsenceCollectionNotificationBodyList { + List? collectionNotification; + + GetAbsenceCollectionNotificationBodyList({this.collectionNotification}); + + GetAbsenceCollectionNotificationBodyList.fromJson(Map json) { + if (json['Collection_Notification'] != null) { + collectionNotification = []; + json['Collection_Notification'].forEach((v) { + collectionNotification!.add(new CollectionNotification.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.collectionNotification != null) { + data['Collection_Notification'] = + this.collectionNotification!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class CollectionNotification { + String? aCTION; + String? aPPLICATIONCOLUMNNAME; + String? dATATYPE; + String? dATEVALUE; + String? dESCFLEXCONTEXTCODE; + String? dESCFLEXNAME; + String? dISPLAYFLAG; + int? nUMBERVALUE; + String? pREVSEGMENTVALUEDSP; + String? sEGMENTNAME; + String? sEGMENTPROMPT; + int? sEGMENTSEQNUM; + String? sEGMENTVALUEDSP; + int? tRANSACTIONNUMBER; + String? vARCHAR2VALUE; + + CollectionNotification( + {this.aCTION, + this.aPPLICATIONCOLUMNNAME, + this.dATATYPE, + this.dATEVALUE, + this.dESCFLEXCONTEXTCODE, + this.dESCFLEXNAME, + this.dISPLAYFLAG, + this.nUMBERVALUE, + this.pREVSEGMENTVALUEDSP, + this.sEGMENTNAME, + this.sEGMENTPROMPT, + this.sEGMENTSEQNUM, + this.sEGMENTVALUEDSP, + this.tRANSACTIONNUMBER, + this.vARCHAR2VALUE}); + + CollectionNotification.fromJson(Map json) { + aCTION = json['ACTION']; + aPPLICATIONCOLUMNNAME = json['APPLICATION_COLUMN_NAME']; + dATATYPE = json['DATATYPE']; + dATEVALUE = json['DATE_VALUE']; + dESCFLEXCONTEXTCODE = json['DESC_FLEX_CONTEXT_CODE']; + dESCFLEXNAME = json['DESC_FLEX_NAME']; + dISPLAYFLAG = json['DISPLAY_FLAG']; + nUMBERVALUE = json['NUMBER_VALUE']; + pREVSEGMENTVALUEDSP = json['PREV_SEGMENT_VALUE_DSP']; + sEGMENTNAME = json['SEGMENT_NAME']; + sEGMENTPROMPT = json['SEGMENT_PROMPT']; + sEGMENTSEQNUM = json['SEGMENT_SEQ_NUM']; + sEGMENTVALUEDSP = json['SEGMENT_VALUE_DSP']; + tRANSACTIONNUMBER = json['TRANSACTION_NUMBER']; + vARCHAR2VALUE = json['VARCHAR2_VALUE']; + } + + Map toJson() { + final Map data = new Map(); + data['ACTION'] = this.aCTION; + data['APPLICATION_COLUMN_NAME'] = this.aPPLICATIONCOLUMNNAME; + data['DATATYPE'] = this.dATATYPE; + data['DATE_VALUE'] = this.dATEVALUE; + data['DESC_FLEX_CONTEXT_CODE'] = this.dESCFLEXCONTEXTCODE; + data['DESC_FLEX_NAME'] = this.dESCFLEXNAME; + data['DISPLAY_FLAG'] = this.dISPLAYFLAG; + data['NUMBER_VALUE'] = this.nUMBERVALUE; + data['PREV_SEGMENT_VALUE_DSP'] = this.pREVSEGMENTVALUEDSP; + data['SEGMENT_NAME'] = this.sEGMENTNAME; + data['SEGMENT_PROMPT'] = this.sEGMENTPROMPT; + data['SEGMENT_SEQ_NUM'] = this.sEGMENTSEQNUM; + data['SEGMENT_VALUE_DSP'] = this.sEGMENTVALUEDSP; + data['TRANSACTION_NUMBER'] = this.tRANSACTIONNUMBER; + data['VARCHAR2_VALUE'] = this.vARCHAR2VALUE; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_action_history_list_model.dart b/lib/models/get_action_history_list_model.dart new file mode 100644 index 0000000..c89a974 --- /dev/null +++ b/lib/models/get_action_history_list_model.dart @@ -0,0 +1,76 @@ +class GetActionHistoryList { + String? aCTION; + String? aCTIONCODE; + String? eMAILADDRESS; + String? eMPLOYEEIMAGE; + int? fROMROWNUM; + bool? isFavorite; + String? nAME; + String? nOTE; + String? nOTIFICATIONDATE; + int? nOTIFICATIONID; + int? nOOFROWS; + String? pOSITIONTITLE; + int? rOWNUM; + int? sEQUENCE; + int? tOROWNUM; + String? uSERNAME; + + GetActionHistoryList( + {this.aCTION, + this.aCTIONCODE, + this.eMAILADDRESS, + this.eMPLOYEEIMAGE, + this.fROMROWNUM, + this.isFavorite, + this.nAME, + this.nOTE, + this.nOTIFICATIONDATE, + this.nOTIFICATIONID, + this.nOOFROWS, + this.pOSITIONTITLE, + this.rOWNUM, + this.sEQUENCE, + this.tOROWNUM, + this.uSERNAME}); + + GetActionHistoryList.fromJson(Map json) { + aCTION = json['ACTION']; + aCTIONCODE = json['ACTION_CODE']; + eMAILADDRESS = json['EMAIL_ADDRESS']; + eMPLOYEEIMAGE = json['EMPLOYEE_IMAGE']; + fROMROWNUM = json['FROM_ROW_NUM']; + isFavorite = json['IsFavorite']; + nAME = json['NAME']; + nOTE = json['NOTE']; + nOTIFICATIONDATE = json['NOTIFICATION_DATE']; + nOTIFICATIONID = json['NOTIFICATION_ID']; + nOOFROWS = json['NO_OF_ROWS']; + pOSITIONTITLE = json['POSITION_TITLE']; + rOWNUM = json['ROW_NUM']; + sEQUENCE = json['SEQUENCE']; + tOROWNUM = json['TO_ROW_NUM']; + uSERNAME = json['USER_NAME']; + } + + Map toJson() { + final Map data = new Map(); + data['ACTION'] = this.aCTION; + data['ACTION_CODE'] = this.aCTIONCODE; + data['EMAIL_ADDRESS'] = this.eMAILADDRESS; + data['EMPLOYEE_IMAGE'] = this.eMPLOYEEIMAGE; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['IsFavorite'] = this.isFavorite; + data['NAME'] = this.nAME; + data['NOTE'] = this.nOTE; + data['NOTIFICATION_DATE'] = this.nOTIFICATIONDATE; + data['NOTIFICATION_ID'] = this.nOTIFICATIONID; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['POSITION_TITLE'] = this.pOSITIONTITLE; + data['ROW_NUM'] = this.rOWNUM; + data['SEQUENCE'] = this.sEQUENCE; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['USER_NAME'] = this.uSERNAME; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_basic_det_ntf_body_list_model.dart b/lib/models/get_basic_det_ntf_body_list_model.dart new file mode 100644 index 0000000..afdcd29 --- /dev/null +++ b/lib/models/get_basic_det_ntf_body_list_model.dart @@ -0,0 +1,24 @@ +class GetBasicDetNtfBodyList { + String? prevSegmentValueDsp; + String? segmentPrompt; + String? segmentValueDsp; + String? updatedFlag; + + GetBasicDetNtfBodyList({this.prevSegmentValueDsp, this.segmentPrompt, this.segmentValueDsp, this.updatedFlag}); + + GetBasicDetNtfBodyList.fromJson(Map json) { + prevSegmentValueDsp = json['PREV_SEGMENT_VALUE_DSP']; + segmentPrompt = json['SEGMENT_PROMPT']; + segmentValueDsp = json['SEGMENT_VALUE_DSP']; + updatedFlag = json['UPDATED_FLAG']; + } + + Map toJson() { + final Map data = new Map(); + data['PREV_SEGMENT_VALUE_DSP'] = this.prevSegmentValueDsp; + data['SEGMENT_PROMPT'] = this.segmentPrompt; + data['SEGMENT_VALUE_DSP'] = this.segmentValueDsp; + data['UPDATED_FLAG'] = this.updatedFlag; + return data; + } +} diff --git a/lib/models/get_mo_notification_body_list_model.dart b/lib/models/get_mo_notification_body_list_model.dart new file mode 100644 index 0000000..613d10f --- /dev/null +++ b/lib/models/get_mo_notification_body_list_model.dart @@ -0,0 +1,104 @@ +class GetMoNotificationBodyList { + String? dATEREQUIRED; + String? dESCRIPTION; + String? fROMLOCATOR; + int? fROMROWNUM; + String? fROMSUBINVENTORY; + String? iTEMCODE; + int? iTEMID; + int? lINENUMBER; + String? lINESTATUS; + int? nOOFROWS; + String? oPERATINGUNIT; + String? oRGANIZATIONCODE; + String? oRGANIZATIONNAME; + int? oRGID; + int? qUANTITY; + int? rOWNUM; + String? sHIPTOLOCATION; + String? sTATUSDATE; + String? tOLOCATOR; + int? tOROWNUM; + String? tOSUBINVENTORY; + String? tRANSACTIONTYPENAME; + String? uOM; + + GetMoNotificationBodyList( + {this.dATEREQUIRED, + this.dESCRIPTION, + this.fROMLOCATOR, + this.fROMROWNUM, + this.fROMSUBINVENTORY, + this.iTEMCODE, + this.iTEMID, + this.lINENUMBER, + this.lINESTATUS, + this.nOOFROWS, + this.oPERATINGUNIT, + this.oRGANIZATIONCODE, + this.oRGANIZATIONNAME, + this.oRGID, + this.qUANTITY, + this.rOWNUM, + this.sHIPTOLOCATION, + this.sTATUSDATE, + this.tOLOCATOR, + this.tOROWNUM, + this.tOSUBINVENTORY, + this.tRANSACTIONTYPENAME, + this.uOM}); + + GetMoNotificationBodyList.fromJson(Map json) { + dATEREQUIRED = json['DATE_REQUIRED']; + dESCRIPTION = json['DESCRIPTION']; + fROMLOCATOR = json['FROM_LOCATOR']; + fROMROWNUM = json['FROM_ROW_NUM']; + fROMSUBINVENTORY = json['FROM_SUBINVENTORY']; + iTEMCODE = json['ITEM_CODE']; + iTEMID = json['ITEM_ID']; + lINENUMBER = json['LINE_NUMBER']; + lINESTATUS = json['LINE_STATUS']; + nOOFROWS = json['NO_OF_ROWS']; + oPERATINGUNIT = json['OPERATING_UNIT']; + oRGANIZATIONCODE = json['ORGANIZATION_CODE']; + oRGANIZATIONNAME = json['ORGANIZATION_NAME']; + oRGID = json['ORG_ID']; + qUANTITY = json['QUANTITY']; + rOWNUM = json['ROW_NUM']; + sHIPTOLOCATION = json['SHIP_TO_LOCATION']; + sTATUSDATE = json['STATUS_DATE']; + tOLOCATOR = json['TO_LOCATOR']; + tOROWNUM = json['TO_ROW_NUM']; + tOSUBINVENTORY = json['TO_SUBINVENTORY']; + tRANSACTIONTYPENAME = json['TRANSACTION_TYPE_NAME']; + uOM = json['UOM']; + } + + Map toJson() { + final Map data = new Map(); + data['DATE_REQUIRED'] = this.dATEREQUIRED; + data['DESCRIPTION'] = this.dESCRIPTION; + data['FROM_LOCATOR'] = this.fROMLOCATOR; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['FROM_SUBINVENTORY'] = this.fROMSUBINVENTORY; + data['ITEM_CODE'] = this.iTEMCODE; + data['ITEM_ID'] = this.iTEMID; + data['LINE_NUMBER'] = this.lINENUMBER; + data['LINE_STATUS'] = this.lINESTATUS; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['OPERATING_UNIT'] = this.oPERATINGUNIT; + data['ORGANIZATION_CODE'] = this.oRGANIZATIONCODE; + data['ORGANIZATION_NAME'] = this.oRGANIZATIONNAME; + data['ORG_ID'] = this.oRGID; + data['QUANTITY'] = this.qUANTITY; + data['ROW_NUM'] = this.rOWNUM; + data['SHIP_TO_LOCATION'] = this.sHIPTOLOCATION; + data['STATUS_DATE'] = this.sTATUSDATE; + data['TO_LOCATOR'] = this.tOLOCATOR; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['TO_SUBINVENTORY'] = this.tOSUBINVENTORY; + data['TRANSACTION_TYPE_NAME'] = this.tRANSACTIONTYPENAME; + data['UOM'] = this.uOM; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_notification_buttons_list_model.dart b/lib/models/get_notification_buttons_list_model.dart new file mode 100644 index 0000000..a6b29d2 --- /dev/null +++ b/lib/models/get_notification_buttons_list_model.dart @@ -0,0 +1,25 @@ +class GetNotificationButtonsList { + String? bUTTONACTION; + String? bUTTONICON; + String? bUTTONLABEL; + int? bUTTONSEQ; + + GetNotificationButtonsList( + {this.bUTTONACTION, this.bUTTONICON, this.bUTTONLABEL, this.bUTTONSEQ}); + + GetNotificationButtonsList.fromJson(Map json) { + bUTTONACTION = json['BUTTON_ACTION']; + bUTTONICON = json['BUTTON_ICON']; + bUTTONLABEL = json['BUTTON_LABEL']; + bUTTONSEQ = json['BUTTON_SEQ']; + } + + Map toJson() { + final Map data = new Map(); + data['BUTTON_ACTION'] = this.bUTTONACTION; + data['BUTTON_ICON'] = this.bUTTONICON; + data['BUTTON_LABEL'] = this.bUTTONLABEL; + data['BUTTON_SEQ'] = this.bUTTONSEQ; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_stamp_ms_notification_body_list_model.dart b/lib/models/get_stamp_ms_notification_body_list_model.dart new file mode 100644 index 0000000..dbead87 --- /dev/null +++ b/lib/models/get_stamp_ms_notification_body_list_model.dart @@ -0,0 +1,132 @@ +class GetStampMsNotificationBodyList { + int? aCTUALWOBHRS; + int? aCTUALWOBSEC; + String? aPPROVEDENDREASONDESC; + String? aPPROVEDSTARTDATETIME; + String? aPPROVEDSTARTREASON; + String? aPPROVEDSTARTTIME; + int? aSSIGNMENTID; + int? aSSIGNMENTNUMBER; + String? bREAKNAME; + String? bUSINESSGROUPID; + String? eMPLOYEENAME; + int? eMPLOYEENUMBER; + String? eMPLOYMENTCATEGORY; + int? pAYROLLID; + String? pAYROLLNAME; + String? sCHEDULEDATE; + int? sEQNO; + String? sHTACTUALENDDATETIME; + String? sHTACTUALENDTIME; + String? sHTACTUALHRS; + int? sHTACTUALSEC; + String? sHTACTUALSTARTDATETIME; + String? sHTACTUALSTARTTIME; + String? sHTCODE; + int? sHTID; + String? sHTNAME; + String? sHTTYPE; + String? sHTTYPEDESC; + int? sUPERVISORID; + int? tKPERSONID; + + GetStampMsNotificationBodyList( + {this.aCTUALWOBHRS, + this.aCTUALWOBSEC, + this.aPPROVEDENDREASONDESC, + this.aPPROVEDSTARTDATETIME, + this.aPPROVEDSTARTREASON, + this.aPPROVEDSTARTTIME, + this.aSSIGNMENTID, + this.aSSIGNMENTNUMBER, + this.bREAKNAME, + this.bUSINESSGROUPID, + this.eMPLOYEENAME, + this.eMPLOYEENUMBER, + this.eMPLOYMENTCATEGORY, + this.pAYROLLID, + this.pAYROLLNAME, + this.sCHEDULEDATE, + this.sEQNO, + this.sHTACTUALENDDATETIME, + this.sHTACTUALENDTIME, + this.sHTACTUALHRS, + this.sHTACTUALSEC, + this.sHTACTUALSTARTDATETIME, + this.sHTACTUALSTARTTIME, + this.sHTCODE, + this.sHTID, + this.sHTNAME, + this.sHTTYPE, + this.sHTTYPEDESC, + this.sUPERVISORID, + this.tKPERSONID}); + + GetStampMsNotificationBodyList.fromJson(Map json) { + aCTUALWOBHRS = json['ACTUAL_WOB_HRS']; + aCTUALWOBSEC = json['ACTUAL_WOB_SEC']; + aPPROVEDENDREASONDESC = json['APPROVED_END_REASON_DESC']; + aPPROVEDSTARTDATETIME = json['APPROVED_START_DATETIME']; + aPPROVEDSTARTREASON = json['APPROVED_START_REASON']; + aPPROVEDSTARTTIME = json['APPROVED_START_TIME']; + aSSIGNMENTID = json['ASSIGNMENT_ID']; + aSSIGNMENTNUMBER = json['ASSIGNMENT_NUMBER']; + bREAKNAME = json['BREAK_NAME']; + bUSINESSGROUPID = json['BUSINESS_GROUP_ID']; + eMPLOYEENAME = json['EMPLOYEE_NAME']; + eMPLOYEENUMBER = json['EMPLOYEE_NUMBER']; + eMPLOYMENTCATEGORY = json['EMPLOYMENT_CATEGORY']; + pAYROLLID = json['PAYROLL_ID']; + pAYROLLNAME = json['PAYROLL_NAME']; + sCHEDULEDATE = json['SCHEDULE_DATE']; + sEQNO = json['SEQ_NO']; + sHTACTUALENDDATETIME = json['SHT_ACTUAL_END_DATETIME']; + sHTACTUALENDTIME = json['SHT_ACTUAL_END_TIME']; + sHTACTUALHRS = json['SHT_ACTUAL_HRS']; + sHTACTUALSEC = json['SHT_ACTUAL_SEC']; + sHTACTUALSTARTDATETIME = json['SHT_ACTUAL_START_DATETIME']; + sHTACTUALSTARTTIME = json['SHT_ACTUAL_START_TIME']; + sHTCODE = json['SHT_CODE']; + sHTID = json['SHT_ID']; + sHTNAME = json['SHT_NAME']; + sHTTYPE = json['SHT_TYPE']; + sHTTYPEDESC = json['SHT_TYPE_DESC']; + sUPERVISORID = json['SUPERVISOR_ID']; + tKPERSONID = json['TK_PERSON_ID']; + } + + Map toJson() { + final Map data = new Map(); + data['ACTUAL_WOB_HRS'] = this.aCTUALWOBHRS; + data['ACTUAL_WOB_SEC'] = this.aCTUALWOBSEC; + data['APPROVED_END_REASON_DESC'] = this.aPPROVEDENDREASONDESC; + data['APPROVED_START_DATETIME'] = this.aPPROVEDSTARTDATETIME; + data['APPROVED_START_REASON'] = this.aPPROVEDSTARTREASON; + data['APPROVED_START_TIME'] = this.aPPROVEDSTARTTIME; + data['ASSIGNMENT_ID'] = this.aSSIGNMENTID; + data['ASSIGNMENT_NUMBER'] = this.aSSIGNMENTNUMBER; + data['BREAK_NAME'] = this.bREAKNAME; + data['BUSINESS_GROUP_ID'] = this.bUSINESSGROUPID; + data['EMPLOYEE_NAME'] = this.eMPLOYEENAME; + data['EMPLOYEE_NUMBER'] = this.eMPLOYEENUMBER; + data['EMPLOYMENT_CATEGORY'] = this.eMPLOYMENTCATEGORY; + data['PAYROLL_ID'] = this.pAYROLLID; + data['PAYROLL_NAME'] = this.pAYROLLNAME; + data['SCHEDULE_DATE'] = this.sCHEDULEDATE; + data['SEQ_NO'] = this.sEQNO; + data['SHT_ACTUAL_END_DATETIME'] = this.sHTACTUALENDDATETIME; + data['SHT_ACTUAL_END_TIME'] = this.sHTACTUALENDTIME; + data['SHT_ACTUAL_HRS'] = this.sHTACTUALHRS; + data['SHT_ACTUAL_SEC'] = this.sHTACTUALSEC; + data['SHT_ACTUAL_START_DATETIME'] = this.sHTACTUALSTARTDATETIME; + data['SHT_ACTUAL_START_TIME'] = this.sHTACTUALSTARTTIME; + data['SHT_CODE'] = this.sHTCODE; + data['SHT_ID'] = this.sHTID; + data['SHT_NAME'] = this.sHTNAME; + data['SHT_TYPE'] = this.sHTTYPE; + data['SHT_TYPE_DESC'] = this.sHTTYPEDESC; + data['SUPERVISOR_ID'] = this.sUPERVISORID; + data['TK_PERSON_ID'] = this.tKPERSONID; + return data; + } +} diff --git a/lib/models/notification_get_respond_attributes_list_model.dart b/lib/models/notification_get_respond_attributes_list_model.dart new file mode 100644 index 0000000..9810e24 --- /dev/null +++ b/lib/models/notification_get_respond_attributes_list_model.dart @@ -0,0 +1,24 @@ +class NotificationGetRespondAttributesList { + String? attributeDisplayName; + String? attributeFormat; + String? attributeName; + String? attributeType; + + NotificationGetRespondAttributesList({this.attributeDisplayName, this.attributeFormat, this.attributeName, this.attributeType}); + + NotificationGetRespondAttributesList.fromJson(Map json) { + attributeDisplayName = json['ATTRIBUTE_DISPLAY_NAME']; + attributeFormat = json['ATTRIBUTE_FORMAT']; + attributeName = json['ATTRIBUTE_NAME']; + attributeType = json['ATTRIBUTE_TYPE']; + } + + Map toJson() { + final Map data = {}; + data['ATTRIBUTE_DISPLAY_NAME'] = attributeDisplayName; + data['ATTRIBUTE_FORMAT'] = attributeFormat; + data['ATTRIBUTE_NAME'] = attributeName; + data['ATTRIBUTE_TYPE'] = attributeType; + return data; + } +} diff --git a/lib/models/subordinates_on_leaves_model.dart b/lib/models/subordinates_on_leaves_model.dart new file mode 100644 index 0000000..d6437f3 --- /dev/null +++ b/lib/models/subordinates_on_leaves_model.dart @@ -0,0 +1,68 @@ +class SubordinatesLeavesList { + String? aBSENCEATTENDANCETYPENAME; + String? cALENDARENTRYDESC; + String? dATEEND; + String? dATESTART; + String? eMPLOYEEIMAGE; + String? eMPLOYEENAME; + String? eMPLOYEENUMBER; + String? eVENTDATE; + String? lEAVETYPE; + int? oRGANIZATIONID; + String? oRGANIZATIONNAME; + String? pOSITIONTITLE; + String? rEPLACEMENTNAME; + String? sTATUS; + + SubordinatesLeavesList( + {this.aBSENCEATTENDANCETYPENAME, + this.cALENDARENTRYDESC, + this.dATEEND, + this.dATESTART, + this.eMPLOYEEIMAGE, + this.eMPLOYEENAME, + this.eMPLOYEENUMBER, + this.eVENTDATE, + this.lEAVETYPE, + this.oRGANIZATIONID, + this.oRGANIZATIONNAME, + this.pOSITIONTITLE, + this.rEPLACEMENTNAME, + this.sTATUS}); + + SubordinatesLeavesList.fromJson(Map json) { + aBSENCEATTENDANCETYPENAME = json['ABSENCE_ATTENDANCE_TYPE_NAME']; + cALENDARENTRYDESC = json['CALENDAR_ENTRY_DESC']; + dATEEND = json['DATE_END']; + dATESTART = json['DATE_START']; + eMPLOYEEIMAGE = json['EMPLOYEE_IMAGE']; + eMPLOYEENAME = json['EMPLOYEE_NAME']; + eMPLOYEENUMBER = json['EMPLOYEE_NUMBER']; + eVENTDATE = json['EVENT_DATE']; + lEAVETYPE = json['LEAVE_TYPE']; + oRGANIZATIONID = json['ORGANIZATION_ID']; + oRGANIZATIONNAME = json['ORGANIZATION_NAME']; + pOSITIONTITLE = json['POSITION_TITLE']; + rEPLACEMENTNAME = json['REPLACEMENT_NAME']; + sTATUS = json['STATUS']; + } + + Map toJson() { + final Map data = new Map(); + data['ABSENCE_ATTENDANCE_TYPE_NAME'] = this.aBSENCEATTENDANCETYPENAME; + data['CALENDAR_ENTRY_DESC'] = this.cALENDARENTRYDESC; + data['DATE_END'] = this.dATEEND; + data['DATE_START'] = this.dATESTART; + data['EMPLOYEE_IMAGE'] = this.eMPLOYEEIMAGE; + data['EMPLOYEE_NAME'] = this.eMPLOYEENAME; + data['EMPLOYEE_NUMBER'] = this.eMPLOYEENUMBER; + data['EVENT_DATE'] = this.eVENTDATE; + data['LEAVE_TYPE'] = this.lEAVETYPE; + data['ORGANIZATION_ID'] = this.oRGANIZATIONID; + data['ORGANIZATION_NAME'] = this.oRGANIZATIONNAME; + data['POSITION_TITLE'] = this.pOSITIONTITLE; + data['REPLACEMENT_NAME'] = this.rEPLACEMENTNAME; + data['STATUS'] = this.sTATUS; + return data; + } +} diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index d98fda8..964c633 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -128,7 +128,7 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { username.text = "15153"; - password.text = "a123a123a123"; + password.text = "Xy12345@"; return Scaffold( body: Column( children: [ diff --git a/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart index 9c2de89..bd722b7 100644 --- a/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart @@ -1,39 +1,46 @@ +import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/ui/work_list/sheets/delegate_sheet.dart'; import 'package:mohem_flutter_app/ui/work_list/sheets/request_more_info_sheet.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; -import 'package:mohem_flutter_app/extensions/int_extensions.dart'; -import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; -import 'dart:math' as math; class ActionsFragment extends StatelessWidget { + List actionHistoryList; + + ActionsFragment(this.actionHistoryList, {Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Container( width: double.infinity, height: double.infinity, child: ListView.separated( - itemCount: actionsList.length, + itemCount: actionHistoryList.length, padding: EdgeInsets.all(21), itemBuilder: (context, index) { - return showItem(context, actionsList[index]); + return showItem(context, actionHistoryList[index]); }, separatorBuilder: (BuildContext context, int index) { - return 16.height; + return 12.height; }, ), ); } - Widget showItem(BuildContext context, Color color) { + Widget showItem(BuildContext context, GetActionHistoryList actionHistory) { return Container( width: double.infinity, decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(15), + borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: const Color(0xff000000).withOpacity(.05), @@ -47,94 +54,54 @@ class ActionsFragment extends StatelessWidget { clipBehavior: Clip.antiAlias, children: [ Positioned( - left: -21, + left: -20, + top: -10, child: Transform.rotate( - angle: 125, + angle: 15, child: Container( - width: 60, - height: 20, - color: color, + width: 50, + height: 30, + color: getStatusColor(actionHistory.aCTIONCODE!), ), ), ), Column( children: [ - Padding( - padding: const EdgeInsets.only(left: 12, right: 12, top: 12), - child: Column( - children: [ - Row( + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CircularAvatar(url: actionHistory.eMPLOYEEIMAGE ?? "", isImageBase64: true, height: 34, width: 34), + 9.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - CircularAvatar(), - 12.width, - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Mahmoud Shrouf".toText16(), - 6.height, - "Missing Swipe Request for Hussain, Mohammad has been approved" - .toText12(), - 3.height, - Row( - children: [ - "Submitted".toText10(), - 12.width, - "On 07 Jan 2021" - .toText12(color: MyColors.lightTextColor) - ], - ) - ], - ), + actionHistory.nAME!.toText16(), + if ((actionHistory.nOTE ?? "").isNotEmpty) actionHistory.nOTE!.toText12(color: MyColors.grey57Color), + 4.height, + Row( + children: [ + actionHistory.aCTION!.toText10(), + 8.width, + if (actionHistory.nOTIFICATIONDATE!.isNotEmpty) + DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDateddMMyyyy(actionHistory.nOTIFICATIONDATE!), false).toText12(color: MyColors.lightTextColor), + ], ) ], ), - ], - ), - ), - 12.height, - Container( - width: double.infinity, - height: 1, - color: MyColors.lightTextColor, - ), + ) + ], + ).paddingOnly(top: 19, left: 16, right: 16, bottom: 12), + Container(width: double.infinity, height: 1, color: MyColors.lightGreyEFColor), Row( children: [ - Expanded( - child: InkWell( - onTap: () { - showMyBottomSheet(context, - child: RequestMoreInfoSheet()); - }, - child: Center( - child: "Request Info" - .toText12(isBold: true) - .paddingOnly( - left: 21, right: 21, top: 8, bottom: 8), - ), - ), - ), - Center( - child: Container( - width: 1, - height: 45, - color: MyColors.lightTextColor, - ), - ), - Expanded( - child: InkWell( - onTap: () { - showMyBottomSheet(context, child: DelegateSheet()); - }, - child: Center( - child: "Delegate" - .toText12( - color: MyColors.gradiantEndColor, isBold: true) - .paddingOnly( - left: 21, right: 21, top: 8, bottom: 8), - ), - ), - ), + LocaleKeys.request_info.tr().toText12(color: MyColors.grey67Color).center.paddingOnly(top: 6, bottom: 6).onPress(() { + showMyBottomSheet(context, child: RequestMoreInfoSheet()); + }).expanded, + Container(width: 1, height: 30, color: MyColors.lightGreyEFColor), + LocaleKeys.delegate.tr().toText12(color: MyColors.gradiantEndColor).center.paddingOnly(top: 6, bottom: 6).onPress(() { + showMyBottomSheet(context, child: DelegateSheet()); + }).expanded, ], ), ], @@ -143,6 +110,20 @@ class ActionsFragment extends StatelessWidget { ), ); } + + Color getStatusColor(String code) { + if (code == "SUBMIT") { + return const Color(0xff2E303A); + } else if (code == "REJECTED") { + return const Color(0xffD02127); + } else if (code == "APPROVED") { + return const Color(0xff1FA269); + } else if (code == "REQUEST_INFO") { + return const Color(0xff2E303A); + } else { + return const Color(0xff2E303A); + } + } } List actionsList = [ diff --git a/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart new file mode 100644 index 0000000..9e42459 --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart @@ -0,0 +1,69 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/member_information_list_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; + +class DetailFragment extends StatefulWidget { + WorkListResponseModel? workListData; + MemberInformationListModel? memberInformationListModel; + DetailFragment(this.workListData, this.memberInformationListModel); + @override + State createState() => _DetailFragmentState(); +} + +class _DetailFragmentState extends State { + bool isOpened = false; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + detailListItem(LocaleKeys.from.tr(), widget.workListData!.fROMUSER ?? ""), + detailListItem(LocaleKeys.to.tr(), widget.workListData!.tOUSER ?? ""), + detailListItem(LocaleKeys.sent.tr(), widget.workListData!.bEGINDATE ?? ""), + detailListItem(LocaleKeys.closed.tr(), widget.workListData!.eNDDATE ?? ""), + detailListItem(LocaleKeys.id.tr(), widget.workListData!.nOTIFICATIONID?.toString() ?? ""), + detailListItem(LocaleKeys.responder.tr(), widget.workListData!.rESPONDER ?? ""), + ], + ).objectContainerView(), + 12.height, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + detailListItem(LocaleKeys.employeeNumber.tr(), widget.memberInformationListModel!.eMPLOYEENUMBER ?? ""), + detailListItem(LocaleKeys.employeeName.tr(), + (AppState().isArabic(context) ? widget.memberInformationListModel!.eMPLOYEEDISPLAYNAMEAr : widget.memberInformationListModel!.eMPLOYEEDISPLAYNAMEEn) ?? ""), + detailListItem(LocaleKeys.jobTitle.tr(), widget.memberInformationListModel!.pOSITIONNAME ?? ""), + detailListItem(LocaleKeys.grade.tr(), widget.memberInformationListModel!.gRADENAME ?? ""), + detailListItem(LocaleKeys.jobCategory.tr(), widget.memberInformationListModel!.pOSITIONNAME?.toString() ?? ""), + detailListItem(LocaleKeys.category.tr(), widget.memberInformationListModel!.eMPLOYMENTCATEGORYMEANING ?? ""), + detailListItem(LocaleKeys.employeeEmailAddress.tr(), widget.memberInformationListModel!.eMPLOYEEEMAILADDRESS ?? ""), + detailListItem(LocaleKeys.payrollBranch.tr(), widget.memberInformationListModel!.pAYROLLNAME ?? ""), + ], + ).objectContainerView(), + ], + ).paddingAll(21); + } + + Widget detailListItem(String title, String value) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "$title:".toText12(isBold: true, color: const Color(0xff2D3238)), + 6.width, + (value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor).expanded, + ], + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart index b115df9..e7c26cf 100644 --- a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -1,69 +1,80 @@ +import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; class InfoFragment extends StatelessWidget { + List? getAbsenceCollectionNotifications; + List? getStampNotifications; + + InfoFragment({this.getAbsenceCollectionNotifications, this.getStampNotifications}); + @override Widget build(BuildContext context) { return Container( width: double.infinity, height: double.infinity, - child: Column( + child: ListView( + padding: const EdgeInsets.all(21), children: [ - Container( - width: double.infinity, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - margin: EdgeInsets.all(21), - padding: EdgeInsets.only(top: 21, bottom: 21, right: 16, left: 16), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: "Info Details".toText16(), - ), - // Icon(Icons.keyboard_arrow_down_rounded), - ], - ), - Column( - children: [ - 12.height, - showItem("From:", "Alma Linde Mendoza"), - showItem("To:", "Al Yabis, Norah"), - showItem("Sent:", "1/26/2020 10:41:07 AM"), - showItem("ID:", "30581045"), - showItem("Closed:", "-"), - ], - ), - ], - ), - ), + if ((getAbsenceCollectionNotifications?.length ?? 0) > 0) + getAbsenceCollectionNotificationsListView(getAbsenceCollectionNotifications ?? []).objectContainerView(title: "Absence Notifications"), + if ((getStampNotifications?.length ?? 0) > 0) getStampNotificationsListView(getStampNotifications ?? []).objectContainerView(title: "Stamp Notifications") ], ), ); } - Widget showItem(String title, String value) { - return Padding( - padding: const EdgeInsets.only(top: 2, bottom: 2), - child: Row( - children: [ - title.toText12(isBold: true), - 6.width, - title.toText12(isBold: false, color: MyColors.normalTextColor), - ], - ), + Widget getAbsenceCollectionNotificationsListView(List list) { + List dataList = list.isEmpty ? [] : (list.first.collectionNotification ?? []); + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => detailListItem(dataList[index].sEGMENTPROMPT!, dataList[index].sEGMENTVALUEDSP!), + separatorBuilder: (cxt, index) => 4.height, + itemCount: dataList.length); + } + + Widget getStampNotificationsListView(List list) { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + detailListItem(LocaleKeys.employeeNumber.tr(), list[index].eMPLOYEENUMBER.toString()), + detailListItem(LocaleKeys.assignmentNumber.tr(), list[index].aSSIGNMENTNUMBER.toString()), + detailListItem(LocaleKeys.employeeName.tr(), list[index].eMPLOYEENAME.toString()), + detailListItem(LocaleKeys.scheduleDate.tr(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(list[index].sCHEDULEDATE.toString()), false)), + detailListItem(LocaleKeys.shiftType.tr(), list[index].sHTTYPEDESC.toString()), + detailListItem(LocaleKeys.shift.tr(), list[index].sHTNAME.toString()), + detailListItem(LocaleKeys.breakText.tr(), list[index].bREAKNAME.toString()), + detailListItem(LocaleKeys.actualSwipeStart.tr(), list[index].sHTACTUALSTARTTIME.toString()), + detailListItem(LocaleKeys.actualSwipeEnd.tr(), list[index].sHTACTUALENDTIME.toString()), + detailListItem(LocaleKeys.approvedSwipeStart.tr(), list[index].aPPROVEDSTARTTIME.toString()), + detailListItem(LocaleKeys.approvedSwipeStartReason.tr(), list[index].aPPROVEDSTARTREASON.toString()), + detailListItem(LocaleKeys.approvedSwipeEnd.tr(), ""), + detailListItem(LocaleKeys.approvedSwipeEndReason.tr(), list[index].aPPROVEDENDREASONDESC.toString()), + ], + ), + separatorBuilder: (cxt, index) => 18.height, + itemCount: list.length); + } + + Widget detailListItem(String title, String value) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "$title:".toText12(isBold: true, color: const Color(0xff2D3238)), + 6.width, + (value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor).expanded, + ], ); } } diff --git a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart index f87995a..f5a639b 100644 --- a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; class RequestFragment extends StatefulWidget { @override @@ -53,8 +53,7 @@ class _RequestFragmentState extends State { showItem("Organization Code:", "SWD"), showItem("From Subinventory:", "SWD_MSPS"), showItem("To Subinventory:", "SWD_MSPS"), - showItem("Ship To Location :", - "SWD 11206-E.R. (Emergency Room)"), + showItem("Ship To Location :", "SWD 11206-E.R. (Emergency Room)"), showItem("Unit:", "Each"), showItem("Date Required:", "12/23/2019 4:54:04 PM"), showItem("Status Date:", "12/23/2019 4:54:04 PM"), diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart index 0a27afc..8d88404 100644 --- a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -1,13 +1,26 @@ +import 'dart:convert'; + import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/member_information_list_model.dart'; +import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/actions_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/attachments_fragment.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/detail_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_fragments.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; @@ -27,6 +40,22 @@ class _MissingSwipeScreenState extends State { PageController controller = PageController(); bool showFabOptions = false; + WorkListResponseModel? workListData; + MemberInformationListModel? memberInformationListModel; + List notificationButtonsList = []; + List actionHistoryList = []; + List getStampNotifications = []; + List? getAbsenceCollectionNotifications; + List getNotificationRespondAttributes = []; + + GenericResponseModel? getBasicNTFBody; + GenericResponseModel? getICBody; + GenericResponseModel? subordinatesLeavesModel; + + bool isCloseAvailable = false; + bool isApproveAvailable = false; + bool isRejectAvailable = false; + @override void initState() { super.initState(); @@ -37,8 +66,44 @@ class _MissingSwipeScreenState extends State { super.dispose(); } + void getData() async { + try { + Utils.showLoading(context); + if (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") { + memberInformationListModel = await WorkListApiClient().getUserInformation(-999); + } + if (workListData!.iTEMTYPE == "HRSSA") { + getBasicNTFBody = await WorkListApiClient().getBasicDetNTFBody(workListData!.nOTIFICATIONID!, -999); + getAbsenceCollectionNotifications = await WorkListApiClient().getAbsenceNotificationBody(workListData!.nOTIFICATIONID!, -999); + subordinatesLeavesModel = await WorkListApiClient().getSubordinatesLeaves("", ""); + } + if (workListData!.iTEMTYPE == "STAMP") { + getStampNotifications = await WorkListApiClient().getStampMsNotificationBody(workListData!.nOTIFICATIONID!, -999); + } + getNotificationRespondAttributes = await WorkListApiClient().notificationGetRespondAttributes(workListData!.nOTIFICATIONID!); + notificationButtonsList = await WorkListApiClient().getNotificationButtons(workListData!.nOTIFICATIONID!); + actionHistoryList = await WorkListApiClient().getActionHistory(workListData!.nOTIFICATIONID!); + + if (notificationButtonsList.isNotEmpty) { + isCloseAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "CLOSE"); + isApproveAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "APPROVED"); + isRejectAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "REJECTED"); + } + Utils.hideLoading(context); + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, null); + } + } + @override Widget build(BuildContext context) { + if (workListData == null) { + workListData = ModalRoute.of(context)!.settings.arguments as WorkListResponseModel; + getData(); + } + return Scaffold( appBar: AppBarWidget(context, title: LocaleKeys.details.tr()), backgroundColor: Colors.white, @@ -65,76 +130,86 @@ class _MissingSwipeScreenState extends State { ), child: Row( children: [ - myTab("Request", 0), - myTab("Actions", 1), - myTab("Attachments", 2), - myTab("Info.", 3), + myTab(LocaleKeys.info.tr(), 0), + (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 1) : myTab(LocaleKeys.request.tr(), 1), + myTab(LocaleKeys.actions.tr(), 2), + myTab(LocaleKeys.attachments.tr(), 3), ], ), ), - Expanded( - child: PageView( - controller: controller, - onPageChanged: (pageIndex) { - setState(() { - tabIndex = pageIndex; - }); - }, - children: [ - RequestFragment(), - ActionsFragment(), - AttachmentsFragment(), - InfoFragment(), - ], - ), - ), - Container( - padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21), - decoration: const BoxDecoration( - color: Colors.white, - border: Border( - top: BorderSide( - color: MyColors.lightGreyEFColor, - width: 1.0, + PageView( + controller: controller, + onPageChanged: (pageIndex) { + setState(() { + tabIndex = pageIndex; + }); + }, + children: [ + InfoFragment(getAbsenceCollectionNotifications: getAbsenceCollectionNotifications, getStampNotifications: getStampNotifications), + (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? DetailFragment(workListData, memberInformationListModel) : RequestFragment(), + ActionsFragment(actionHistoryList), + AttachmentsFragment(), + ], + ).expanded, + if (isApproveAvailable || isRejectAvailable || isCloseAvailable) + Container( + padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21), + decoration: const BoxDecoration( + color: Colors.white, + border: Border( + top: BorderSide( + color: MyColors.lightGreyEFColor, + width: 1.0, + ), ), ), - ), - child: Row( - children: [ - DefaultButton( - LocaleKeys.reject.tr(), - () {}, - colors: const [ - Color(0xffEB8C90), - Color(0xffDE6C70), - ], - ).expanded, - 8.width, - DefaultButton( - LocaleKeys.approve.tr(), - () {}, - colors: const [ - Color(0xff32D892), - Color(0xff1AB170), - ], - ).expanded, - 8.width, - Container( - height: 43, - width: 43, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: MyColors.lightGreyE6Color, - ), - child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor), - ).onPress(() { - setState(() { - showFabOptions = true; - }); - }) - ], - ), - ) + child: Row( + children: [ + if (isRejectAvailable) + DefaultButton( + LocaleKeys.reject.tr(), + () {}, + colors: const [ + Color(0xffEB8C90), + Color(0xffDE6C70), + ], + ).expanded, + if (isApproveAvailable && isRejectAvailable) 8.width, + if (isApproveAvailable) + DefaultButton( + LocaleKeys.approve.tr(), + () {}, + colors: const [ + Color(0xff32D892), + Color(0xff1AB170), + ], + ).expanded, + if (isCloseAvailable) + DefaultButton( + LocaleKeys.ok.tr(), + () {}, + colors: const [ + Color(0xff32D892), + Color(0xff1AB170), + ], + ).expanded, + 8.width, + Container( + height: 43, + width: 43, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: MyColors.lightGreyE6Color, + ), + child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor), + ).onPress(() { + setState(() { + showFabOptions = true; + }); + }) + ], + ), + ) ], ), IgnorePointer( @@ -143,7 +218,7 @@ class _MissingSwipeScreenState extends State { opacity: showFabOptions ? 1 : 0, duration: const Duration(milliseconds: 250), child: Container( - padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75), + padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75 - 12), width: double.infinity, height: double.infinity, color: Colors.white.withOpacity(.67), @@ -154,9 +229,7 @@ class _MissingSwipeScreenState extends State { children: [ myFab("Skip", "assets/images/skip.svg"), 12.height, - myFab("Request Info", "assets/images/request_info.svg"), - 12.height, - myFab("Delegate", "assets/images/delegate.svg"), + ...viewApiButtonsList(notificationButtonsList), ], ), ), @@ -168,9 +241,54 @@ class _MissingSwipeScreenState extends State { ), ], ), + floatingActionButton: (!isApproveAvailable && !isRejectAvailable && !isCloseAvailable) + ? Container( + height: 43, + width: 43, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: MyColors.lightGreyE6Color, + ), + child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor), + ).onPress(() { + setState(() { + showFabOptions = true; + }); + }) + : null, ); } + List viewApiButtonsList(List notificationButtonsList) { + List fabs = []; + for (int i = 0; i < notificationButtonsList.length; i++) { + if (notificationButtonsList[i].bUTTONACTION! == "REJECTED" || notificationButtonsList[i].bUTTONACTION! == "APPROVED" || notificationButtonsList[i].bUTTONACTION! == "CLOSE") { + continue; + } + fabs.add(myFab(notificationButtonsList[i].bUTTONLABEL!, notificationButtonsList[i].bUTTONICON ?? "", isIconAsset: false) + .paddingOnly(bottom: 12) + .onPress(() => handleFabAction(notificationButtonsList[i]))); + } + return fabs; + } + + void handleFabAction(GetNotificationButtonsList notificationButton) { + switch (notificationButton.bUTTONACTION) { + case "DELEGATE": + // do something + break; + case "REQUEST_INFO": + // do something else + break; + case "RFC": + // do something else + break; + case "UPDATE_ACTION": + // do something else + break; + } + } + Widget myTab(String title, int index) { bool isSelected = (index == tabIndex); return Column( @@ -197,7 +315,7 @@ class _MissingSwipeScreenState extends State { }).expanded; } - Widget myFab(String title, String icon) { + Widget myFab(String title, String icon, {bool isIconAsset = true}) { return Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, @@ -220,7 +338,12 @@ class _MissingSwipeScreenState extends State { ], ), ), - child: SvgPicture.asset(icon), + child: isIconAsset + ? SvgPicture.asset(icon) + : Image.memory( + base64Decode(icon), + fit: BoxFit.cover, + ), ) ], ); diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 1e46783..49fb8ac 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -76,7 +76,7 @@ class _WorkListScreenState extends State { try { Utils.showLoading(context); if (workListItemTypes[workListItemIndex].key == "ITG") { - itgFormsModel = await WorkListApiClient().GetITGTaskCountRequestType(); + itgFormsModel = await WorkListApiClient().getITGTaskCountRequestType(); List requestAllList = []; for (int i = 0; i < (itgFormsModel?.requestType!.length ?? 0); i++) { requestAllList = requestAllList + (itgFormsModel?.requestType![i].requestDetails ?? []); @@ -274,7 +274,7 @@ class _WorkListScreenState extends State { Widget rowItem(WorkListItemTypeModelData data, WorkListResponseModel workData) { return InkWell( onTap: () { - Navigator.pushNamed(context, AppRoutes.missingSwipe); + Navigator.pushNamed(context, AppRoutes.missingSwipe, arguments: workData); }, child: Container( width: double.infinity, diff --git a/lib/widgets/circular_avatar.dart b/lib/widgets/circular_avatar.dart index cd60e06..ad94052 100644 --- a/lib/widgets/circular_avatar.dart +++ b/lib/widgets/circular_avatar.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; class CircularAvatar extends StatelessWidget { @@ -5,8 +7,9 @@ class CircularAvatar extends StatelessWidget { final double radius; final double width; final double height; + final bool isImageBase64; - CircularAvatar({Key? key, this.radius = 70.0, this.width = 70, this.height = 60, this.url}) : super(key: key); + CircularAvatar({Key? key, this.radius = 70.0, this.width = 70, this.height = 60, this.url, this.isImageBase64 = false}) : super(key: key); @override Widget build(BuildContext context) { @@ -15,10 +18,23 @@ class CircularAvatar extends StatelessWidget { height: height, decoration: BoxDecoration( shape: BoxShape.circle, - image: DecorationImage( - fit: BoxFit.cover, - image: NetworkImage(url ?? "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png"), - ), + image: isImageBase64 + ? null + : DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(url ?? "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png"), + ), + ), + child: isImageBase64 ? imageFromBase64String(url!) : null, + ); + } + + Widget imageFromBase64String(String base64String) { + return ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.memory( + base64Decode(base64String), + fit: BoxFit.cover, ), ); } From a4fb526b684d2988d27e4a600aa793ede37f031f Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Wed, 6 Apr 2022 12:22:00 +0300 Subject: [PATCH 19/22] NFC Attendance implement 1.4 --- lib/dialogs/otp_dialog.dart | 1 + lib/ui/landing/today_attendance_screen.dart | 59 ++++++++++++--------- lib/ui/login/login_screen.dart | 2 +- lib/ui/login/verify_last_login_screen.dart | 12 +++++ 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index d82cf9c..3789980 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -226,3 +226,4 @@ class OtpDialog { // } } } + diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index b1ce089..cfba3fd 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -33,7 +33,7 @@ class TodayAttendanceScreen extends StatefulWidget { class _TodayAttendanceScreenState extends State { ValueNotifier result = ValueNotifier(null); late DashboardProviderModel data; - bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false; + bool isNfcEnabled = true, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false; @override void initState() { @@ -47,14 +47,14 @@ class _TodayAttendanceScreenState extends State { setState(() { AppState().privilegeListModel!.forEach((element) { print(element.serviceName.toString() + " " + element.previlege.toString()); // Check availability - if (isAvailable) if (element.serviceName == "enableNFC") { - // if (element.previlege ?? false) - isNfcEnabled = true; + + if (element.serviceName == "enableNFC") { + if (isAvailable) if (element.previlege ?? false) isNfcEnabled = true; } else if (element.serviceName == "enableQR") { if (element.previlege ?? false) isQrEnabled = true; } else if (element.serviceName == "enableWIFI") { if (element.previlege ?? false) isWifiEnabled = true; - } else if (element.serviceName == "enableLocatoinNFC") { + } else if (element.serviceName!.trim() == "enableLocationNFC") { if (element.previlege ?? false) isNfcLocationEnabled = true; } else if (element.serviceName == "enableLocationQR") { if (element.previlege ?? false) isQrLocationEnabled = true; @@ -191,28 +191,13 @@ class _TodayAttendanceScreenState extends State { children: [ attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { if (isNfcLocationEnabled) { - print("nfc location enabled"); + Location.getCurrentLocation((LatLng? latlng) { + print(latlng!.longitude.toString()); + performNfcAttendance(model, lat: latlng.latitude.toString() ?? "", lng: latlng.longitude.toString() ?? ""); + }); } else { - print("nfc not location enabled"); + performNfcAttendance(model); } - // showNfcReader(context, onNcfScan: (String? nfcId) async { - // print(nfcId); - // Utils.showLoading(context); - // try { - // GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? ""); - // bool status = await model.fetchAttendanceTracking(); - // Utils.hideLoading(context); - // } catch (ex) { - // print(ex); - // Utils.hideLoading(context); - // Utils.handleException(ex, (msg) { - // Utils.confirmDialog(context, msg); - // }); - // } - // }); - // Location.getCurrentLocation((LatLng? latlng) { - // print(latlng!.longitude.toString()); - // }); }), attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () {}), ], @@ -249,6 +234,30 @@ class _TodayAttendanceScreenState extends State { ); } + Future performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { + if (isNfcLocationEnabled) { + print("nfc location enabled"); + } else { + print("nfc not location enabled"); + } + + showNfcReader(context, onNcfScan: (String? nfcId) async { + print(nfcId); + Utils.showLoading(context); + try { + GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng); + bool status = await model.fetchAttendanceTracking(); + Utils.hideLoading(context); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, (msg) { + Utils.confirmDialog(context, msg); + }); + } + }); + } + Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 944a11f..ad4e3c2 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -75,6 +75,7 @@ class _LoginScreenState extends State { Utils.showLoading(context); firebaseToken = await _firebaseMessaging.getToken(); loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + loginInfo!.deviceToken = firebaseToken; if (loginInfo == null) { Utils.hideLoading(context); print("Device token not found"); @@ -125,7 +126,6 @@ class _LoginScreenState extends State { } } - @override Widget build(BuildContext context) { username.text = "15153"; diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 52ec751..3a7ce86 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -246,6 +248,16 @@ class _VerifyLastLoginScreenState extends State { Utils.showLoading(context); try { GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); + GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( + AppState().memberLoginList?.pEMAILADDRESS ?? "", + genericResponseModel?.pSESSIONID ?? 0, + genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "", + _flag, + AppState().memberLoginList?.pMOBILENUMBER ?? "", + AppState().getUserName!, + mobileLoginInfoListModel!.deviceToken!, + Platform.isAndroid ? "android" : "ios"); + if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); // Navigator.pop(context); From a431913bb62d7bb8168ff00cc91c680ae97a9ed9 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 14 Apr 2022 14:45:03 +0300 Subject: [PATCH 20/22] purchase order & move order, item history & quotation analysis added. --- assets/langs/ar-SA.json | 74 ++++++ assets/langs/en-US.json | 74 ++++++ lib/api/worklist/worklist_api_client.dart | 95 ++++++- lib/app_state/app_state.dart | 9 +- lib/classes/utils.dart | 17 +- lib/config/routes.dart | 3 + lib/extensions/int_extensions.dart | 2 + lib/generated/codegen_loader.g.dart | 148 +++++++++++ lib/generated/locale_keys.g.dart | 74 ++++++ lib/models/generic_response_model.dart | 82 ++++-- lib/models/get_attachement_list_model.dart | 72 ++++++ .../get_mo_Item_history_list_model.dart | 100 ++++++++ .../get_po_Item_history_list_model.dart | 92 +++++++ .../get_po_notification_body_list_model.dart | 242 ++++++++++++++++++ .../get_quotation_analysis_list_model.dart | 84 ++++++ lib/models/member_information_list_model.dart | 2 +- lib/models/notification_action_model.dart | 18 ++ lib/provider/dashboard_provider_model.dart | 22 +- lib/ui/landing/dashboard_screen.dart | 6 +- lib/ui/login/forgot_password_screen.dart | 2 +- lib/ui/login/login_screen.dart | 5 +- lib/ui/login/new_password_screen.dart | 2 +- lib/ui/login/verify_last_login_screen.dart | 13 +- lib/ui/login/verify_login_screen.dart | 4 +- lib/ui/screens/tangheem_detail_screen.dart | 4 +- lib/ui/work_list/item_history_screen.dart | 182 +++++++++++++ .../fragments/attachments_fragment.dart | 93 ++++--- .../fragments/detail_fragment.dart | 51 ++-- .../fragments/info_fragments.dart | 100 ++++++-- .../fragments/request_fragment.dart | 169 +++++++----- .../missing_swipe/missing_swipe_screen.dart | 110 ++++++-- lib/ui/work_list/work_list_screen.dart | 42 ++- .../dialogs/accept_reject_input_dialog.dart | 103 ++++++++ lib/widgets/item_detail_view_widget.dart | 23 ++ 34 files changed, 1875 insertions(+), 244 deletions(-) create mode 100644 lib/models/get_attachement_list_model.dart create mode 100644 lib/models/get_mo_Item_history_list_model.dart create mode 100644 lib/models/get_po_Item_history_list_model.dart create mode 100644 lib/models/get_po_notification_body_list_model.dart create mode 100644 lib/models/get_quotation_analysis_list_model.dart create mode 100644 lib/models/notification_action_model.dart create mode 100644 lib/ui/work_list/item_history_screen.dart create mode 100644 lib/widgets/dialogs/accept_reject_input_dialog.dart create mode 100644 lib/widgets/item_detail_view_widget.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 38767b7..daf43ef 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -66,6 +66,8 @@ "whatsapp": "واتس اب", "reject": "يرفض", "approve": "يوافق", + "cancel": "إلغاء", + "requestedItems": "العناصر المطلوبة", "request": "طلب", "actions": "أجراءات", "delegate": "مندوب", @@ -97,6 +99,78 @@ "category": "فئة", "employeeEmailAddress": "عنوان البريد الإلكتروني للموظف", "payrollBranch": "فرع الرواتب", + "yourChangeHasBeenSavedSuccessfully": "تم حفظ التغيير الخاص بك بنجاح", + "code": "شفرة", + "unit": "وحدة", + "quantity": "كمية", + "dateRequired": "التاريخ مطلوب", + "lineStatus": "حالة الخط", + "statusDate": "تاريخ الحالة", + "transactionType": "نوع المعاملة", + "operatingUnit": "وحدة التشغيل", + "organizationCode": "كود المنظمة", + "organization": "منظمة", + "fromSubInventory": "من الجرد الفرعي", + "fromLocator": "من محدد المواقع", + "toSubInventory": "إلى الجرد الفرعي", + "toLocator": "إلى محدد المواقع", + "shipToLocator": "شحن إلى محدد المواقع", + "itemHistory": "تاريخ العنصر", + "mfg": "مبدع", + "lineType": "نوع الخط", + "price": "السعر", + "lineAmount": "مبلغ الخط", + "lineDiscount": "خصم الخط٪", + "needByDate": "القادمة إلى الأمام", + "promisedDate": "التسجيل وعد", + "deliverToLocation": "تسليم إلى الموقع", + "requisitionNumber": "رقم الطلب", + "requester": "مقدم الطلب", + "quotationAnalysis": "تحليل الاقتباس", + "subject": "موضوعات", + "description": "وصف", + "supplier": "المورد", + "site": "موقع", + "buyer": "مشتر", + "preparer": "معد", + "creationDate": "تاريخ الإنشاء", + "shipToLocation": "الشحن الى الموقع", + "quotationNumber": "رقم الإقتباس", + "quotationDate": "تاريخ الاقتباس", + "paymentTerms": "شروط الدفع", + "currency": "عملة", + "grossAmount": "المبلغ الإجمالي", + "discountAmount": "مقدار الخصم", + "customDuty": "الرسوم الجمركية", + "shipHandle": "مقبض السفينة", + "otherCharges": "رسوم أخرى", + "totalPOAmountWithVAT": "إجمالي مبلغ الشراء مع ضريبة القيمة المضافة", + "totalPOAmountInWords": "إجمالي مبلغ أمر الشراء بالكلمات", + "requestNumber": "رقم الطلب", + "uom": "UOM", + "operatingCode": "كود التشغيل", + "poNumber": "PO عدد", + "revision": "مراجعة", + "quantityOrdered": "الكمية المطلوبة", + "quantityReceived": "الكمية المستلمة", + "bonusQuantity": "كمية المكافأة", + "purchasePrice": "سعر الشراء", + "discountPer": "خصم ٪", + "balanceQuantity": "كمية التوازن", + "netPrice": "السعر الصافي", + "closureStatus": "حالة الإغلاق", + "quotationNetPrice": "صافي سعر الاقتباس", + "quotationUOM": "اقتباس UOM", + "quotationQty": "اقتباس الكمية", + "itemCode": "رمز الصنف", + "vendorName": "اسم البائع", + "quotationMFGPartNumber": "رقم الجزء MFG الاقتباس", + "quotationDeliveryDate": "تاريخ تسليم عرض الأسعار", + "quotationBonusQuantity": "كمية مكافأة الاقتباس", + "quotationLineTotal": "مجموع خط الاقتباس", + "rfqUOM": "RFQ UOM", + "rfqQty": "RFQ الكمية", + "rfqNumber": "رقم RFQ", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index fecbf3d..f39f530 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -66,6 +66,8 @@ "whatsapp": "Whatsapp", "reject": "Reject", "approve": "Approve", + "cancel": "Cancel", + "requestedItems": "Requested Items", "request": "Request", "actions": "Actions", "delegate": "Delegate", @@ -97,6 +99,78 @@ "category": "Category", "employeeEmailAddress": "Employee Email Address", "payrollBranch": "Payroll Branch", + "yourChangeHasBeenSavedSuccessfully": "Your change has been saved successfully", + "code": "Code", + "unit": "Unit", + "quantity": "Quantity", + "dateRequired": "Date Required", + "lineStatus": "Line Status", + "statusDate": "Status Date", + "transactionType": "Transaction Type", + "operatingUnit": "Operating Unit", + "organizationCode": "Organization Code", + "organization": "Organization", + "fromSubInventory": "From Sub Inventory", + "fromLocator": "From Locator", + "toSubInventory": "To Sub Inventory", + "toLocator": "To Locator", + "shipToLocator": "Ship To Locator", + "itemHistory": "Item History", + "mfg": "MFG", + "lineType": "Line Type", + "price": "Price", + "lineAmount": "Line Amount", + "lineDiscount": "Line Discount %", + "needByDate": "Need By Date", + "promisedDate": "Promised Date", + "deliverToLocation": "Deliver To Location", + "requisitionNumber": "Requisition Number", + "requester": "Requester", + "subject": "Subject", + "quotationAnalysis": "Quotation Analysis", + "description": "Description", + "supplier": "Supplier", + "site": "Site", + "buyer": "Buyer", + "preparer": "Preparer", + "creationDate": "Creation Date", + "shipToLocation": "Ship To Location", + "quotationNumber": "Quotation Number", + "quotationDate": "Quotation Date", + "paymentTerms": "Payment Terms", + "currency": "Currency", + "grossAmount": "Gross Amount", + "discountAmount": "Discount Amount", + "customDuty": "Custom Duty", + "shipHandle": "Ship Handle", + "otherCharges": "Other Charges", + "totalPOAmountWithVAT": "Total PO Amount With VAT", + "totalPOAmountInWords": "Total PO Amount In Words", + "requestNumber": "Request Number", + "uom": "UOM", + "operatingCode": "Operating Code", + "poNumber": "PO Number", + "revision": "Revision", + "quantityOrdered": "Quantity Ordered", + "quantityReceived": "Quantity Received", + "bonusQuantity": "Bonus Quantity", + "purchasePrice": "Purchase Price", + "discountPer": "Discount %", + "balanceQuantity": "Balance Quantity", + "netPrice": "Net Price", + "closureStatus": "Closure Status", + "quotationNetPrice": "Quotation Net Price", + "quotationUOM": "Quotation UOM", + "quotationQty": "Quotation Qty", + "itemCode": "item Code", + "vendorName": "Vendor Name", + "quotationMFGPartNumber": "Quotation MFG Part Number", + "quotationDeliveryDate": "Quotation Delivery Date", + "quotationBonusQuantity": "Quotation Bonus Quantity", + "quotationLineTotal": "Quotation Line Total", + "rfqUOM": "RFQ UOM", + "rfqQty": "RFQ Qty", + "rfqNumber": "RFQ Number", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index 48fd13b..625e700 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -7,11 +7,16 @@ import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; +import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; -import 'package:mohem_flutter_app/models/subordinates_on_leaves_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; class WorkListApiClient { @@ -56,7 +61,7 @@ class WorkListApiClient { }, url, postParams); } - Future> getAttachments(int pNotificationID) async { + Future> getAttachments(int pNotificationID) async { String url = "${ApiConsts.erpRest}GET_ATTACHMENTS"; Map postParams = {"P_NOTIFICATION_ID": pNotificationID}; postParams.addAll(AppState().postParamsJson); @@ -115,7 +120,7 @@ class WorkListApiClient { }, url, postParams); } - Future getUserInformation(int pSelectedResopID) async { + Future getUserInformation(int pSelectedResopID, String selectedEmployeeNumber) async { String url = "${ApiConsts.erpRest}Get_UserInformation"; Map postParams = { "P_SELECTED_RESP_ID": pSelectedResopID, @@ -123,6 +128,7 @@ class WorkListApiClient { "P_PAGE_NUM": 1, }; postParams.addAll(AppState().postParamsJson); + postParams["P_SELECTED_EMPLOYEE_NUMBER"] = selectedEmployeeNumber; return await ApiClient().postJsonForObject((json) { GenericResponseModel responseData = GenericResponseModel.fromJson(json); return responseData.memberInformationList![0]; @@ -158,4 +164,87 @@ class WorkListApiClient { return responseData.getAbsenceCollectionNotificationBodyList ?? []; }, url, postParams); } + + Future postNotificationActions(Map postParams) async { + String url = "${ApiConsts.erpRest}NOTIFICATION_ACTIONS"; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future> getMoNotificationBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_MO_NOTIFICATION_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getMoNotificationBodyList ?? []; + }, url, postParams); + } + + Future getPoNotificationBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_PO_NOTIFICATION_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getPoNotificationBodyList; + }, url, postParams); + } + + Future> getMoItemHistory(int pItemID, int pOrgID) async { + String url = "${ApiConsts.erpRest}GET_MO_ITEM_HISTORY"; + Map postParams = { + "P_ITEM_ID": pItemID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + "P_ORG_ID": pOrgID, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getMoItemHistoryList ?? []; + }, url, postParams); + } + + Future> getPoItemHistory(int pItemID) async { + String url = "${ApiConsts.erpRest}GET_PO_ITEM_HISTORY"; + Map postParams = { + "P_ITEM_ID": pItemID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getPoItemHistoryList ?? []; + }, url, postParams); + } + + Future> getQuotationAnalysis(int pItemID, int pPoHeaderId) async { + String url = "${ApiConsts.erpRest}GET_QUOTATION_ANALYSIS"; + Map postParams = { + "P_ITEM_ID": pItemID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + "P_PO_HEADER_ID": pPoHeaderId, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getQuotationAnalysisList ?? []; + }, url, postParams); + } } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 50aff0a..89493ee 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -3,6 +3,7 @@ import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; class AppState { static final AppState _instance = AppState._internal(); @@ -43,7 +44,6 @@ class AppState { String? get getUserName => _username; - set setUserPassword(_password) => password = _password; MemberLoginListModel? _memberLoginList; @@ -63,4 +63,11 @@ class AppState { List? get privilegeListModel => _privilegeListModel; set setPrivilegeListModel(List? _privilegeListModel) => this._privilegeListModel = _privilegeListModel; + + List? workList; + + set setWorkList(List? _workList) => workList = _workList; + + int? workListIndex; + set setWorkListIndex(int? _workListIndex) => workListIndex = _workListIndex; } diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index ae8041f..3b200f5 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; // import 'package:fluttertoast/fluttertoast.dart'; import 'package:mohem_flutter_app/exceptions/api_exception.dart'; @@ -64,7 +65,7 @@ class Utils { return await prefs.setString(key, value); } - static void handleException(dynamic exception, Function(String)? onErrorMessage) { + static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) { String errorMessage; if (exception is APIException) { if (exception.message == APIException.UNAUTHORIZED) { @@ -78,7 +79,19 @@ class Utils { if (onErrorMessage != null) { onErrorMessage(errorMessage); } else { - showToast(errorMessage); + if (errorMessage.contains("User session is not valid")) { + showDialog( + context: cxt, + builder: (cxt) => ConfirmDialog( + message: errorMessage, + onTap: (){ + Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route route) => false); + }, + ), + ); + } else { + showToast(errorMessage); + } } } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 3eba985..9ae9bc7 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -6,6 +6,7 @@ import 'package:mohem_flutter_app/ui/login/login_screen.dart'; import 'package:mohem_flutter_app/ui/login/new_password_screen.dart'; import 'package:mohem_flutter_app/ui/login/verify_last_login_screen.dart'; import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; +import 'package:mohem_flutter_app/ui/work_list/item_history_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/missing_swipe_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart'; @@ -26,6 +27,7 @@ class AppRoutes { //Work List static const String workList = "/workList"; static const String missingSwipe = "/missingSwipe"; + static const String itemHistory = "/itemHistory"; static final Map routes = { login: (context) => LoginScreen(), @@ -39,5 +41,6 @@ class AppRoutes { //Work List workList: (context) => WorkListScreen(), missingSwipe: (context) => MissingSwipeScreen(), + itemHistory: (context) => ItemHistoryScreen(), }; } diff --git a/lib/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart index 9b90b2f..215f8d9 100644 --- a/lib/extensions/int_extensions.dart +++ b/lib/extensions/int_extensions.dart @@ -4,4 +4,6 @@ extension IntExtensions on int { Widget get height => SizedBox(height: toDouble()); Widget get width => SizedBox(width: toDouble()); + + Widget get makeItSquare => SizedBox(width: toDouble(), height: toDouble()); } diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index a555432..30fa6f7 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -82,6 +82,8 @@ class CodegenLoader extends AssetLoader{ "whatsapp": "واتس اب", "reject": "يرفض", "approve": "يوافق", + "cancel": "إلغاء", + "requestedItems": "العناصر المطلوبة", "request": "طلب", "actions": "أجراءات", "delegate": "مندوب", @@ -113,6 +115,78 @@ class CodegenLoader extends AssetLoader{ "category": "فئة", "employeeEmailAddress": "عنوان البريد الإلكتروني للموظف", "payrollBranch": "فرع الرواتب", + "yourChangeHasBeenSavedSuccessfully": "تم حفظ التغيير الخاص بك بنجاح", + "code": "شفرة", + "unit": "وحدة", + "quantity": "كمية", + "dateRequired": "التاريخ مطلوب", + "lineStatus": "حالة الخط", + "statusDate": "تاريخ الحالة", + "transactionType": "نوع المعاملة", + "operatingUnit": "وحدة التشغيل", + "organizationCode": "كود المنظمة", + "organization": "منظمة", + "fromSubInventory": "من الجرد الفرعي", + "fromLocator": "من محدد المواقع", + "toSubInventory": "إلى الجرد الفرعي", + "toLocator": "إلى محدد المواقع", + "shipToLocator": "شحن إلى محدد المواقع", + "itemHistory": "تاريخ العنصر", + "mfg": "مبدع", + "lineType": "نوع الخط", + "price": "السعر", + "lineAmount": "مبلغ الخط", + "lineDiscount": "خصم الخط٪", + "needByDate": "القادمة إلى الأمام", + "promisedDate": "التسجيل وعد", + "deliverToLocation": "تسليم إلى الموقع", + "requisitionNumber": "رقم الطلب", + "requester": "مقدم الطلب", + "quotationAnalysis": "تحليل الاقتباس", + "subject": "موضوعات", + "description": "وصف", + "supplier": "المورد", + "site": "موقع", + "buyer": "مشتر", + "preparer": "معد", + "creationDate": "تاريخ الإنشاء", + "shipToLocation": "الشحن الى الموقع", + "quotationNumber": "رقم الإقتباس", + "quotationDate": "تاريخ الاقتباس", + "paymentTerms": "شروط الدفع", + "currency": "عملة", + "grossAmount": "المبلغ الإجمالي", + "discountAmount": "مقدار الخصم", + "customDuty": "الرسوم الجمركية", + "shipHandle": "مقبض السفينة", + "otherCharges": "رسوم أخرى", + "totalPOAmountWithVAT": "إجمالي مبلغ الشراء مع ضريبة القيمة المضافة", + "totalPOAmountInWords": "إجمالي مبلغ أمر الشراء بالكلمات", + "requestNumber": "رقم الطلب", + "uom": "UOM", + "operatingCode": "كود التشغيل", + "poNumber": "PO عدد", + "revision": "مراجعة", + "quantityOrdered": "الكمية المطلوبة", + "quantityReceived": "الكمية المستلمة", + "bonusQuantity": "كمية المكافأة", + "purchasePrice": "سعر الشراء", + "discountPer": "خصم ٪", + "balanceQuantity": "كمية التوازن", + "netPrice": "السعر الصافي", + "closureStatus": "حالة الإغلاق", + "quotationNetPrice": "صافي سعر الاقتباس", + "quotationUOM": "اقتباس UOM", + "quotationQty": "اقتباس الكمية", + "itemCode": "رمز الصنف", + "vendorName": "اسم البائع", + "quotationMFGPartNumber": "رقم الجزء MFG الاقتباس", + "quotationDeliveryDate": "تاريخ تسليم عرض الأسعار", + "quotationBonusQuantity": "كمية مكافأة الاقتباس", + "quotationLineTotal": "مجموع خط الاقتباس", + "rfqUOM": "RFQ UOM", + "rfqQty": "RFQ الكمية", + "rfqNumber": "رقم RFQ", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", @@ -220,6 +294,8 @@ static const Map en_US = { "whatsapp": "Whatsapp", "reject": "Reject", "approve": "Approve", + "cancel": "Cancel", + "requestedItems": "Requested Items", "request": "Request", "actions": "Actions", "delegate": "Delegate", @@ -251,6 +327,78 @@ static const Map en_US = { "category": "Category", "employeeEmailAddress": "Employee Email Address", "payrollBranch": "Payroll Branch", + "yourChangeHasBeenSavedSuccessfully": "Your change has been saved successfully", + "code": "Code", + "unit": "Unit", + "quantity": "Quantity", + "dateRequired": "Date Required", + "lineStatus": "Line Status", + "statusDate": "Status Date", + "transactionType": "Transaction Type", + "operatingUnit": "Operating Unit", + "organizationCode": "Organization Code", + "organization": "Organization", + "fromSubInventory": "From Sub Inventory", + "fromLocator": "From Locator", + "toSubInventory": "To Sub Inventory", + "toLocator": "To Locator", + "shipToLocator": "Ship To Locator", + "itemHistory": "Item History", + "mfg": "MFG", + "lineType": "Line Type", + "price": "Price", + "lineAmount": "Line Amount", + "lineDiscount": "Line Discount %", + "needByDate": "Need By Date", + "promisedDate": "Promised Date", + "deliverToLocation": "Deliver To Location", + "requisitionNumber": "Requisition Number", + "requester": "Requester", + "subject": "Subject", + "quotationAnalysis": "Quotation Analysis", + "description": "Description", + "supplier": "Supplier", + "site": "Site", + "buyer": "Buyer", + "preparer": "Preparer", + "creationDate": "Creation Date", + "shipToLocation": "Ship To Location", + "quotationNumber": "Quotation Number", + "quotationDate": "Quotation Date", + "paymentTerms": "Payment Terms", + "currency": "Currency", + "grossAmount": "Gross Amount", + "discountAmount": "Discount Amount", + "customDuty": "Custom Duty", + "shipHandle": "Ship Handle", + "otherCharges": "Other Charges", + "totalPOAmountWithVAT": "Total PO Amount With VAT", + "totalPOAmountInWords": "Total PO Amount In Words", + "requestNumber": "Request Number", + "uom": "UOM", + "operatingCode": "Operating Code", + "poNumber": "PO Number", + "revision": "Revision", + "quantityOrdered": "Quantity Ordered", + "quantityReceived": "Quantity Received", + "bonusQuantity": "Bonus Quantity", + "purchasePrice": "Purchase Price", + "discountPer": "Discount %", + "balanceQuantity": "Balance Quantity", + "netPrice": "Net Price", + "closureStatus": "Closure Status", + "quotationNetPrice": "Quotation Net Price", + "quotationUOM": "Quotation UOM", + "quotationQty": "Quotation Qty", + "itemCode": "item Code", + "vendorName": "Vendor Name", + "quotationMFGPartNumber": "Quotation MFG Part Number", + "quotationDeliveryDate": "Quotation Delivery Date", + "quotationBonusQuantity": "Quotation Bonus Quantity", + "quotationLineTotal": "Quotation Line Total", + "rfqUOM": "RFQ UOM", + "rfqQty": "RFQ Qty", + "rfqNumber": "RFQ Number", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index faaea1c..3dbdb7c 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -67,6 +67,8 @@ abstract class LocaleKeys { static const whatsapp = 'whatsapp'; static const reject = 'reject'; static const approve = 'approve'; + static const cancel = 'cancel'; + static const requestedItems = 'requestedItems'; static const request = 'request'; static const actions = 'actions'; static const delegate = 'delegate'; @@ -98,6 +100,78 @@ abstract class LocaleKeys { static const category = 'category'; static const employeeEmailAddress = 'employeeEmailAddress'; static const payrollBranch = 'payrollBranch'; + static const yourChangeHasBeenSavedSuccessfully = 'yourChangeHasBeenSavedSuccessfully'; + static const code = 'code'; + static const unit = 'unit'; + static const quantity = 'quantity'; + static const dateRequired = 'dateRequired'; + static const lineStatus = 'lineStatus'; + static const statusDate = 'statusDate'; + static const transactionType = 'transactionType'; + static const operatingUnit = 'operatingUnit'; + static const organizationCode = 'organizationCode'; + static const organization = 'organization'; + static const fromSubInventory = 'fromSubInventory'; + static const fromLocator = 'fromLocator'; + static const toSubInventory = 'toSubInventory'; + static const toLocator = 'toLocator'; + static const shipToLocator = 'shipToLocator'; + static const itemHistory = 'itemHistory'; + static const mfg = 'mfg'; + static const lineType = 'lineType'; + static const price = 'price'; + static const lineAmount = 'lineAmount'; + static const lineDiscount = 'lineDiscount'; + static const needByDate = 'needByDate'; + static const promisedDate = 'promisedDate'; + static const deliverToLocation = 'deliverToLocation'; + static const requisitionNumber = 'requisitionNumber'; + static const requester = 'requester'; + static const quotationAnalysis = 'quotationAnalysis'; + static const subject = 'subject'; + static const description = 'description'; + static const supplier = 'supplier'; + static const site = 'site'; + static const buyer = 'buyer'; + static const preparer = 'preparer'; + static const creationDate = 'creationDate'; + static const shipToLocation = 'shipToLocation'; + static const quotationNumber = 'quotationNumber'; + static const quotationDate = 'quotationDate'; + static const paymentTerms = 'paymentTerms'; + static const currency = 'currency'; + static const grossAmount = 'grossAmount'; + static const discountAmount = 'discountAmount'; + static const customDuty = 'customDuty'; + static const shipHandle = 'shipHandle'; + static const otherCharges = 'otherCharges'; + static const totalPOAmountWithVAT = 'totalPOAmountWithVAT'; + static const totalPOAmountInWords = 'totalPOAmountInWords'; + static const requestNumber = 'requestNumber'; + static const uom = 'uom'; + static const operatingCode = 'operatingCode'; + static const poNumber = 'poNumber'; + static const revision = 'revision'; + static const quantityOrdered = 'quantityOrdered'; + static const quantityReceived = 'quantityReceived'; + static const bonusQuantity = 'bonusQuantity'; + static const purchasePrice = 'purchasePrice'; + static const discountPer = 'discountPer'; + static const balanceQuantity = 'balanceQuantity'; + static const netPrice = 'netPrice'; + static const closureStatus = 'closureStatus'; + static const quotationNetPrice = 'quotationNetPrice'; + static const quotationUOM = 'quotationUOM'; + static const quotationQty = 'quotationQty'; + static const itemCode = 'itemCode'; + static const vendorName = 'vendorName'; + static const quotationMFGPartNumber = 'quotationMFGPartNumber'; + static const quotationDeliveryDate = 'quotationDeliveryDate'; + static const quotationBonusQuantity = 'quotationBonusQuantity'; + static const quotationLineTotal = 'quotationLineTotal'; + static const rfqUOM = 'rfqUOM'; + static const rfqQty = 'rfqQty'; + static const rfqNumber = 'rfqNumber'; static const msg = 'msg'; static const msg_named = 'msg_named'; static const clickMe = 'clickMe'; diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 956a0d0..138d686 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,10 +1,16 @@ import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; import 'package:mohem_flutter_app/models/get_basic_det_ntf_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/models/notification_action_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; import 'package:mohem_flutter_app/models/subordinates_on_leaves_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; @@ -78,7 +84,7 @@ class GenericResponseModel { List? getAddressDffStructureList; List? getAddressNotificationBodyList; List? getApprovesList; - List? getAttachementList; + List? getAttachementList; GetAttendanceTracking? getAttendanceTrackingList; List? getBasicDetColsStructureList; List? getBasicDetDffStructureList; @@ -116,7 +122,7 @@ class GenericResponseModel { List? getItemTypesList; List? getLookupValuesList; List? getMenuEntriesList; - List? getMoItemHistoryList; + List? getMoItemHistoryList; List? getMoNotificationBodyList; List? getNotificationButtonsList; List? getNotificationReassignModeList; @@ -132,10 +138,10 @@ class GenericResponseModel { List? getPendingReqFunctionsList; List? getPerformanceAppraisalList; List? getPhonesNotificationBodyList; - List? getPoItemHistoryList; - List? getPoNotificationBodyList; + List? getPoItemHistoryList; + GetPoNotificationBodyList? getPoNotificationBodyList; List? getPrNotificationBodyList; - List? getQuotationAnalysisList; + List? getQuotationAnalysisList; List? getRFCEmployeeListList; List? getRespondAttributeValueList; List? getSITCollectionNotificationBodyList; @@ -197,7 +203,7 @@ class GenericResponseModel { bool? mohemmIsInsertBusinessCardEnable; String? mohemmWifiPassword; String? mohemmWifiSSID; - String? notificationAction; + NotificationAction? notificationAction; List? notificationGetRespondAttributesList; List? notificationRespondRolesList; int? oracleOutPutNumber; @@ -598,7 +604,13 @@ class GenericResponseModel { getAddressDffStructureList = json['GetAddressDffStructureList']; getAddressNotificationBodyList = json['GetAddressNotificationBodyList']; getApprovesList = json['GetApprovesList']; - getAttachementList = json['GetAttachementList']; + + if (json['GetAttachementList'] != null) { + getAttachementList = []; + json['GetAttachementList'].forEach((v) { + getAttachementList!.add(new GetAttachementList.fromJson(v)); + }); + } getAttendanceTrackingList = json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]); getBasicDetColsStructureList = json['GetBasicDetColsStructureList']; getBasicDetDffStructureList = json['GetBasicDetDffStructureList']; @@ -643,7 +655,12 @@ class GenericResponseModel { getItemTypesList = json['GetItemTypesList']; getLookupValuesList = json['GetLookupValuesList']; getMenuEntriesList = json["GetMenuEntriesList"] == null ? null : List.from(json["GetMenuEntriesList"].map((x) => GetMenuEntriesList.fromJson(x))); - getMoItemHistoryList = json['GetMoItemHistoryList']; + if (json['GetMoItemHistoryList'] != null) { + getMoItemHistoryList = []; + json['GetMoItemHistoryList'].forEach((v) { + getMoItemHistoryList!.add(new GetMoItemHistoryList.fromJson(v)); + }); + } if (json['GetMoNotificationBodyList'] != null) { getMoNotificationBodyList = []; @@ -672,10 +689,20 @@ class GenericResponseModel { getPendingReqFunctionsList = json['GetPendingReqFunctionsList']; getPerformanceAppraisalList = json['GetPerformanceAppraisalList']; getPhonesNotificationBodyList = json['GetPhonesNotificationBodyList']; - getPoItemHistoryList = json['GetPoItemHistoryList']; - getPoNotificationBodyList = json['GetPoNotificationBodyList']; + if (json['GetPoItemHistoryList'] != null) { + getPoItemHistoryList = []; + json['GetPoItemHistoryList'].forEach((v) { + getPoItemHistoryList!.add(new GetPoItemHistoryList.fromJson(v)); + }); + } + getPoNotificationBodyList = json['GetPoNotificationBodyList'] != null ? new GetPoNotificationBodyList.fromJson(json['GetPoNotificationBodyList']) : null; getPrNotificationBodyList = json['GetPrNotificationBodyList']; - getQuotationAnalysisList = json['GetQuotationAnalysisList']; + if (json['GetQuotationAnalysisList'] != null) { + getQuotationAnalysisList = []; + json['GetQuotationAnalysisList'].forEach((v) { + getQuotationAnalysisList!.add(new GetQuotationAnalysisList.fromJson(v)); + }); + } getRFCEmployeeListList = json['GetRFCEmployeeListList']; getRespondAttributeValueList = json['GetRespondAttributeValueList']; getSITCollectionNotificationBodyList = json['GetSITCollectionNotificationBodyList']; @@ -768,8 +795,7 @@ class GenericResponseModel { mohemmIsInsertBusinessCardEnable = json['Mohemm_IsInsertBusinessCardEnable']; mohemmWifiPassword = json['Mohemm_Wifi_Password']; mohemmWifiSSID = json['Mohemm_Wifi_SSID']; - notificationAction = json['NotificationAction']; - + notificationAction = json['NotificationAction'] != null ? NotificationAction.fromJson(json['NotificationAction']) : null; if (json['NotificationGetRespondAttributesList'] != null) { notificationGetRespondAttributesList = []; json['NotificationGetRespondAttributesList'].forEach((v) { @@ -780,7 +806,7 @@ class GenericResponseModel { if (json['NotificationRespondRolesList'] != null) { notificationRespondRolesList = []; json['NotificationGetRespondAttributesList'].forEach((v) { - // notificationRespondRolesList!.add(v); + // notificationRespondRolesList!.add(v); }); } @@ -941,7 +967,11 @@ class GenericResponseModel { data['GetAddressDffStructureList'] = this.getAddressDffStructureList; data['GetAddressNotificationBodyList'] = this.getAddressNotificationBodyList; data['GetApprovesList'] = this.getApprovesList; - data['GetAttachementList'] = this.getAttachementList; + + if (this.getAttachementList != null) { + data['GetAttachementList'] = this.getAttachementList!.map((v) => v.toJson()).toList(); + } + data['GetAttendanceTrackingList'] = this.getAttendanceTrackingList; data['GetBasicDetColsStructureList'] = this.getBasicDetColsStructureList; data['GetBasicDetDffStructureList'] = this.getBasicDetDffStructureList; @@ -983,7 +1013,9 @@ class GenericResponseModel { data['GetItemTypesList'] = this.getItemTypesList; data['GetLookupValuesList'] = this.getLookupValuesList; data['GetMenuEntriesList'] = this.getMenuEntriesList; - data['GetMoItemHistoryList'] = this.getMoItemHistoryList; + if (this.getMoItemHistoryList != null) { + data['GetMoItemHistoryList'] = this.getMoItemHistoryList!.map((v) => v.toJson()).toList(); + } if (this.getMoNotificationBodyList != null) { data['GetMoNotificationBodyList'] = this.getMoNotificationBodyList!.map((v) => v.toJson()).toList(); @@ -1006,10 +1038,17 @@ class GenericResponseModel { data['GetPendingReqFunctionsList'] = this.getPendingReqFunctionsList; data['GetPerformanceAppraisalList'] = this.getPerformanceAppraisalList; data['GetPhonesNotificationBodyList'] = this.getPhonesNotificationBodyList; - data['GetPoItemHistoryList'] = this.getPoItemHistoryList; - data['GetPoNotificationBodyList'] = this.getPoNotificationBodyList; + if (this.getPoItemHistoryList != null) { + data['GetPoItemHistoryList'] = this.getPoItemHistoryList!.map((v) => v.toJson()).toList(); + } + + if (this.getPoNotificationBodyList != null) { + data['GetPoNotificationBodyList'] = this.getPoNotificationBodyList!.toJson(); + } data['GetPrNotificationBodyList'] = this.getPrNotificationBodyList; - data['GetQuotationAnalysisList'] = this.getQuotationAnalysisList; + if (this.getQuotationAnalysisList != null) { + data['GetQuotationAnalysisList'] = this.getQuotationAnalysisList!.map((v) => v.toJson()).toList(); + } data['GetRFCEmployeeListList'] = this.getRFCEmployeeListList; data['GetRespondAttributeValueList'] = this.getRespondAttributeValueList; data['GetSITCollectionNotificationBodyList'] = this.getSITCollectionNotificationBodyList; @@ -1088,7 +1127,10 @@ class GenericResponseModel { data['Mohemm_IsInsertBusinessCardEnable'] = this.mohemmIsInsertBusinessCardEnable; data['Mohemm_Wifi_Password'] = this.mohemmWifiPassword; data['Mohemm_Wifi_SSID'] = this.mohemmWifiSSID; - data['NotificationAction'] = this.notificationAction; + + if (this.notificationAction != null) { + data['NotificationAction'] = this.notificationAction!.toJson(); + } if (notificationGetRespondAttributesList != null) { data['NotificationGetRespondAttributesList'] = notificationGetRespondAttributesList!.map((v) => v.toJson()).toList(); diff --git a/lib/models/get_attachement_list_model.dart b/lib/models/get_attachement_list_model.dart new file mode 100644 index 0000000..79c43bb --- /dev/null +++ b/lib/models/get_attachement_list_model.dart @@ -0,0 +1,72 @@ +class GetAttachementList { + int? aTTACHEDDOCUMENTID; + int? cATEGORYID; + int? dATATYPEID; + int? dOCUMENTID; + String? eNTITYNAME; + String? fILECONTENTTYPE; + String? fILEDATA; + int? fILEID; + String? fILENAME; + String? pK1VALUE; + String? pK2VALUE; + String? pK3VALUE; + String? pK4VALUE; + String? pK5VALUE; + int? sEQNUM; + + GetAttachementList( + {this.aTTACHEDDOCUMENTID, + this.cATEGORYID, + this.dATATYPEID, + this.dOCUMENTID, + this.eNTITYNAME, + this.fILECONTENTTYPE, + this.fILEDATA, + this.fILEID, + this.fILENAME, + this.pK1VALUE, + this.pK2VALUE, + this.pK3VALUE, + this.pK4VALUE, + this.pK5VALUE, + this.sEQNUM}); + + GetAttachementList.fromJson(Map json) { + aTTACHEDDOCUMENTID = json['ATTACHED_DOCUMENT_ID']; + cATEGORYID = json['CATEGORY_ID']; + dATATYPEID = json['DATATYPE_ID']; + dOCUMENTID = json['DOCUMENT_ID']; + eNTITYNAME = json['ENTITY_NAME']; + fILECONTENTTYPE = json['FILE_CONTENT_TYPE']; + fILEDATA = json['FILE_DATA']; + fILEID = json['FILE_ID']; + fILENAME = json['FILE_NAME']; + pK1VALUE = json['PK1_VALUE']; + pK2VALUE = json['PK2_VALUE']; + pK3VALUE = json['PK3_VALUE']; + pK4VALUE = json['PK4_VALUE']; + pK5VALUE = json['PK5_VALUE']; + sEQNUM = json['SEQ_NUM']; + } + + Map toJson() { + final Map data = new Map(); + data['ATTACHED_DOCUMENT_ID'] = this.aTTACHEDDOCUMENTID; + data['CATEGORY_ID'] = this.cATEGORYID; + data['DATATYPE_ID'] = this.dATATYPEID; + data['DOCUMENT_ID'] = this.dOCUMENTID; + data['ENTITY_NAME'] = this.eNTITYNAME; + data['FILE_CONTENT_TYPE'] = this.fILECONTENTTYPE; + data['FILE_DATA'] = this.fILEDATA; + data['FILE_ID'] = this.fILEID; + data['FILE_NAME'] = this.fILENAME; + data['PK1_VALUE'] = this.pK1VALUE; + data['PK2_VALUE'] = this.pK2VALUE; + data['PK3_VALUE'] = this.pK3VALUE; + data['PK4_VALUE'] = this.pK4VALUE; + data['PK5_VALUE'] = this.pK5VALUE; + data['SEQ_NUM'] = this.sEQNUM; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_mo_Item_history_list_model.dart b/lib/models/get_mo_Item_history_list_model.dart new file mode 100644 index 0000000..3604322 --- /dev/null +++ b/lib/models/get_mo_Item_history_list_model.dart @@ -0,0 +1,100 @@ +class GetMoItemHistoryList { + String? dATEREQUIRED; + String? dESCRIPTION; + String? fROMLOCATOR; + int? fROMROWNUM; + String? fROMSUBINVENTORYCODE; + String? iTEMCODE; + String? lINESTATUSDIS; + int? nOOFROWS; + String? oPERATINGUNITNAME; + String? oRGANIZATIONCODE; + int? oRGANIZATIONID; + String? oRGANIZATIONNAME; + int? qUANTITY; + String? rEQUESTNUMBER; + int? rOWNUM; + String? sHIPTOLOCATION; + String? sTATUSDATE; + String? tOLOCATOR; + int? tOROWNUM; + String? tOSUBINVENTORYCODE; + String? tRANSACTIONTYPENAME; + String? uNITOFMEASURE; + + GetMoItemHistoryList( + {this.dATEREQUIRED, + this.dESCRIPTION, + this.fROMLOCATOR, + this.fROMROWNUM, + this.fROMSUBINVENTORYCODE, + this.iTEMCODE, + this.lINESTATUSDIS, + this.nOOFROWS, + this.oPERATINGUNITNAME, + this.oRGANIZATIONCODE, + this.oRGANIZATIONID, + this.oRGANIZATIONNAME, + this.qUANTITY, + this.rEQUESTNUMBER, + this.rOWNUM, + this.sHIPTOLOCATION, + this.sTATUSDATE, + this.tOLOCATOR, + this.tOROWNUM, + this.tOSUBINVENTORYCODE, + this.tRANSACTIONTYPENAME, + this.uNITOFMEASURE}); + + GetMoItemHistoryList.fromJson(Map json) { + dATEREQUIRED = json['DATE_REQUIRED']; + dESCRIPTION = json['DESCRIPTION']; + fROMLOCATOR = json['FROM_LOCATOR']; + fROMROWNUM = json['FROM_ROW_NUM']; + fROMSUBINVENTORYCODE = json['FROM_SUBINVENTORY_CODE']; + iTEMCODE = json['ITEM_CODE']; + lINESTATUSDIS = json['LINE_STATUS_DIS']; + nOOFROWS = json['NO_OF_ROWS']; + oPERATINGUNITNAME = json['OPERATING_UNIT_NAME']; + oRGANIZATIONCODE = json['ORGANIZATION_CODE']; + oRGANIZATIONID = json['ORGANIZATION_ID']; + oRGANIZATIONNAME = json['ORGANIZATION_NAME']; + qUANTITY = json['QUANTITY']; + rEQUESTNUMBER = json['REQUEST_NUMBER']; + rOWNUM = json['ROW_NUM']; + sHIPTOLOCATION = json['SHIP_TO_LOCATION']; + sTATUSDATE = json['STATUS_DATE']; + tOLOCATOR = json['TO_LOCATOR']; + tOROWNUM = json['TO_ROW_NUM']; + tOSUBINVENTORYCODE = json['TO_SUBINVENTORY_CODE']; + tRANSACTIONTYPENAME = json['TRANSACTION_TYPE_NAME']; + uNITOFMEASURE = json['UNIT_OF_MEASURE']; + } + + Map toJson() { + final Map data = new Map(); + data['DATE_REQUIRED'] = this.dATEREQUIRED; + data['DESCRIPTION'] = this.dESCRIPTION; + data['FROM_LOCATOR'] = this.fROMLOCATOR; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['FROM_SUBINVENTORY_CODE'] = this.fROMSUBINVENTORYCODE; + data['ITEM_CODE'] = this.iTEMCODE; + data['LINE_STATUS_DIS'] = this.lINESTATUSDIS; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['OPERATING_UNIT_NAME'] = this.oPERATINGUNITNAME; + data['ORGANIZATION_CODE'] = this.oRGANIZATIONCODE; + data['ORGANIZATION_ID'] = this.oRGANIZATIONID; + data['ORGANIZATION_NAME'] = this.oRGANIZATIONNAME; + data['QUANTITY'] = this.qUANTITY; + data['REQUEST_NUMBER'] = this.rEQUESTNUMBER; + data['ROW_NUM'] = this.rOWNUM; + data['SHIP_TO_LOCATION'] = this.sHIPTOLOCATION; + data['STATUS_DATE'] = this.sTATUSDATE; + data['TO_LOCATOR'] = this.tOLOCATOR; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['TO_SUBINVENTORY_CODE'] = this.tOSUBINVENTORYCODE; + data['TRANSACTION_TYPE_NAME'] = this.tRANSACTIONTYPENAME; + data['UNIT_OF_MEASURE'] = this.uNITOFMEASURE; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_po_Item_history_list_model.dart b/lib/models/get_po_Item_history_list_model.dart new file mode 100644 index 0000000..d51861b --- /dev/null +++ b/lib/models/get_po_Item_history_list_model.dart @@ -0,0 +1,92 @@ +class GetPoItemHistoryList { + int? bALANCEQUANTITY; + int? bONUSQUANTITY; + String? bUYER; + String? cLOSEDCODE; + String? cREATIONDATE; + int? dISCOUNTPERCENTAGE; + int? fROMROWNUM; + int? iTEMID; + int? nETPRICE; + int? nOOFROWS; + String? oUNAME; + String? pONUMBER; + int? pURCHASEPRICE; + int? qUANTITYORDERED; + int? qUANTITYRECEIVED; + int? rEVISIONNUM; + int? rOWNUM; + String? sUPPLIER; + int? tOROWNUM; + String? uOM; + + GetPoItemHistoryList( + {this.bALANCEQUANTITY, + this.bONUSQUANTITY, + this.bUYER, + this.cLOSEDCODE, + this.cREATIONDATE, + this.dISCOUNTPERCENTAGE, + this.fROMROWNUM, + this.iTEMID, + this.nETPRICE, + this.nOOFROWS, + this.oUNAME, + this.pONUMBER, + this.pURCHASEPRICE, + this.qUANTITYORDERED, + this.qUANTITYRECEIVED, + this.rEVISIONNUM, + this.rOWNUM, + this.sUPPLIER, + this.tOROWNUM, + this.uOM}); + + GetPoItemHistoryList.fromJson(Map json) { + bALANCEQUANTITY = json['BALANCE_QUANTITY']; + bONUSQUANTITY = json['BONUS_QUANTITY']; + bUYER = json['BUYER']; + cLOSEDCODE = json['CLOSED_CODE']; + cREATIONDATE = json['CREATION_DATE']; + dISCOUNTPERCENTAGE = json['DISCOUNT_PERCENTAGE']; + fROMROWNUM = json['FROM_ROW_NUM']; + iTEMID = json['ITEM_ID']; + nETPRICE = json['NET_PRICE']; + nOOFROWS = json['NO_OF_ROWS']; + oUNAME = json['OU_NAME']; + pONUMBER = json['PO_NUMBER']; + pURCHASEPRICE = json['PURCHASE_PRICE']; + qUANTITYORDERED = json['QUANTITY_ORDERED']; + qUANTITYRECEIVED = json['QUANTITY_RECEIVED']; + rEVISIONNUM = json['REVISION_NUM']; + rOWNUM = json['ROW_NUM']; + sUPPLIER = json['SUPPLIER']; + tOROWNUM = json['TO_ROW_NUM']; + uOM = json['UOM']; + } + + Map toJson() { + final Map data = new Map(); + data['BALANCE_QUANTITY'] = this.bALANCEQUANTITY; + data['BONUS_QUANTITY'] = this.bONUSQUANTITY; + data['BUYER'] = this.bUYER; + data['CLOSED_CODE'] = this.cLOSEDCODE; + data['CREATION_DATE'] = this.cREATIONDATE; + data['DISCOUNT_PERCENTAGE'] = this.dISCOUNTPERCENTAGE; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['ITEM_ID'] = this.iTEMID; + data['NET_PRICE'] = this.nETPRICE; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['OU_NAME'] = this.oUNAME; + data['PO_NUMBER'] = this.pONUMBER; + data['PURCHASE_PRICE'] = this.pURCHASEPRICE; + data['QUANTITY_ORDERED'] = this.qUANTITYORDERED; + data['QUANTITY_RECEIVED'] = this.qUANTITYRECEIVED; + data['REVISION_NUM'] = this.rEVISIONNUM; + data['ROW_NUM'] = this.rOWNUM; + data['SUPPLIER'] = this.sUPPLIER; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['UOM'] = this.uOM; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_po_notification_body_list_model.dart b/lib/models/get_po_notification_body_list_model.dart new file mode 100644 index 0000000..7b5c1cb --- /dev/null +++ b/lib/models/get_po_notification_body_list_model.dart @@ -0,0 +1,242 @@ + +class GetPoNotificationBodyList { + List? pOHeader; + List? pOLines; + String? pINFORMATION; + String? pQUESTION; + + GetPoNotificationBodyList( + {this.pOHeader, this.pOLines, this.pINFORMATION, this.pQUESTION}); + + GetPoNotificationBodyList.fromJson(Map json) { + if (json['POHeader'] != null) { + pOHeader = []; + json['POHeader'].forEach((v) { + pOHeader!.add(new POHeader.fromJson(v)); + }); + } + if (json['POLines'] != null) { + pOLines = []; + json['POLines'].forEach((v) { + pOLines!.add(new POLines.fromJson(v)); + }); + } + pINFORMATION = json['P_INFORMATION']; + pQUESTION = json['P_QUESTION']; + } + + Map toJson() { + final Map data = new Map(); + if (this.pOHeader != null) { + data['POHeader'] = this.pOHeader!.map((v) => v.toJson()).toList(); + } + if (this.pOLines != null) { + data['POLines'] = this.pOLines!.map((v) => v.toJson()).toList(); + } + data['P_INFORMATION'] = this.pINFORMATION; + data['P_QUESTION'] = this.pQUESTION; + return data; + } +} + +class POHeader { + String? bUYER; + String? cOMMENTS; + String? cREATIONDATE; + String? cURRENCYNAME; + int? cUSTOMDUTY; + int? dISCOUNTAMOUNT; + int? gROSSAMOUNT; + String? lOCCUR; + int? lOCCURTOTPOAMT; + int? oTHERCHARGES; + String? pAYMENTTERMS; + String? pONUMBER; + String? pREPARER; + String? qUOTATIONDATE; + String? qUOTATIONNUMBER; + int? sALESTAX; + int? sHIPHANDLE; + String? sHIPTOLOCATIONNAME; + int? tOTALPODISCOUNT; + int? tOTPOAMT; + String? tOTPOAMTWORD; + String? vENDORNAME; + String? vENDORSITECODE; + + POHeader( + {this.bUYER, + this.cOMMENTS, + this.cREATIONDATE, + this.cURRENCYNAME, + this.cUSTOMDUTY, + this.dISCOUNTAMOUNT, + this.gROSSAMOUNT, + this.lOCCUR, + this.lOCCURTOTPOAMT, + this.oTHERCHARGES, + this.pAYMENTTERMS, + this.pONUMBER, + this.pREPARER, + this.qUOTATIONDATE, + this.qUOTATIONNUMBER, + this.sALESTAX, + this.sHIPHANDLE, + this.sHIPTOLOCATIONNAME, + this.tOTALPODISCOUNT, + this.tOTPOAMT, + this.tOTPOAMTWORD, + this.vENDORNAME, + this.vENDORSITECODE}); + + POHeader.fromJson(Map json) { + bUYER = json['BUYER']; + cOMMENTS = json['COMMENTS']; + cREATIONDATE = json['CREATION_DATE']; + cURRENCYNAME = json['CURRENCY_NAME']; + cUSTOMDUTY = json['CUSTOM_DUTY']; + dISCOUNTAMOUNT = json['DISCOUNT_AMOUNT']; + gROSSAMOUNT = json['GROSS_AMOUNT']; + lOCCUR = json['LOC_CUR']; + lOCCURTOTPOAMT = json['LOC_CUR_TOT_PO_AMT']; + oTHERCHARGES = json['OTHER_CHARGES']; + pAYMENTTERMS = json['PAYMENT_TERMS']; + pONUMBER = json['PO_NUMBER']; + pREPARER = json['PREPARER']; + qUOTATIONDATE = json['QUOTATION_DATE']; + qUOTATIONNUMBER = json['QUOTATION_NUMBER']; + sALESTAX = json['SALES_TAX']; + sHIPHANDLE = json['SHIP_HANDLE']; + sHIPTOLOCATIONNAME = json['SHIP_TO_LOCATION_NAME']; + tOTALPODISCOUNT = json['TOTAL_PO_DISCOUNT']; + tOTPOAMT = json['TOT_PO_AMT']; + tOTPOAMTWORD = json['TOT_PO_AMT_WORD']; + vENDORNAME = json['VENDOR_NAME']; + vENDORSITECODE = json['VENDOR_SITE_CODE']; + } + + Map toJson() { + final Map data = new Map(); + data['BUYER'] = this.bUYER; + data['COMMENTS'] = this.cOMMENTS; + data['CREATION_DATE'] = this.cREATIONDATE; + data['CURRENCY_NAME'] = this.cURRENCYNAME; + data['CUSTOM_DUTY'] = this.cUSTOMDUTY; + data['DISCOUNT_AMOUNT'] = this.dISCOUNTAMOUNT; + data['GROSS_AMOUNT'] = this.gROSSAMOUNT; + data['LOC_CUR'] = this.lOCCUR; + data['LOC_CUR_TOT_PO_AMT'] = this.lOCCURTOTPOAMT; + data['OTHER_CHARGES'] = this.oTHERCHARGES; + data['PAYMENT_TERMS'] = this.pAYMENTTERMS; + data['PO_NUMBER'] = this.pONUMBER; + data['PREPARER'] = this.pREPARER; + data['QUOTATION_DATE'] = this.qUOTATIONDATE; + data['QUOTATION_NUMBER'] = this.qUOTATIONNUMBER; + data['SALES_TAX'] = this.sALESTAX; + data['SHIP_HANDLE'] = this.sHIPHANDLE; + data['SHIP_TO_LOCATION_NAME'] = this.sHIPTOLOCATIONNAME; + data['TOTAL_PO_DISCOUNT'] = this.tOTALPODISCOUNT; + data['TOT_PO_AMT'] = this.tOTPOAMT; + data['TOT_PO_AMT_WORD'] = this.tOTPOAMTWORD; + data['VENDOR_NAME'] = this.vENDORNAME; + data['VENDOR_SITE_CODE'] = this.vENDORSITECODE; + return data; + } +} + +class POLines { + String? dELIVERTOLOCATION; + int? fROMROWNUM; + String? iTEMCODE; + String? iTEMDESCRIPTION; + int? iTEMID; + int? lINEAMOUNT; + int? lINEDISCPERCENTAGE; + int? lINENUM; + String? lINETYPE; + String? mFG; + String? nEEDBYDATE; + int? nOOFROWS; + int? pOHEADERID; + String? pROMISEDDATE; + String? pRNUM; + int? qUANTITY; + String? rEQUESTOR; + int? rOWNUM; + int? tOROWNUM; + int? uNITPRICE; + String? uOM; + + POLines( + {this.dELIVERTOLOCATION, + this.fROMROWNUM, + this.iTEMCODE, + this.iTEMDESCRIPTION, + this.iTEMID, + this.lINEAMOUNT, + this.lINEDISCPERCENTAGE, + this.lINENUM, + this.lINETYPE, + this.mFG, + this.nEEDBYDATE, + this.nOOFROWS, + this.pOHEADERID, + this.pROMISEDDATE, + this.pRNUM, + this.qUANTITY, + this.rEQUESTOR, + this.rOWNUM, + this.tOROWNUM, + this.uNITPRICE, + this.uOM}); + + POLines.fromJson(Map json) { + dELIVERTOLOCATION = json['DELIVER_TO_LOCATION']; + fROMROWNUM = json['FROM_ROW_NUM']; + iTEMCODE = json['ITEM_CODE']; + iTEMDESCRIPTION = json['ITEM_DESCRIPTION']; + iTEMID = json['ITEM_ID']; + lINEAMOUNT = json['LINE_AMOUNT']; + lINEDISCPERCENTAGE = json['LINE_DISC_PERCENTAGE']; + lINENUM = json['LINE_NUM']; + lINETYPE = json['LINE_TYPE']; + mFG = json['MFG']; + nEEDBYDATE = json['NEED_BY_DATE']; + nOOFROWS = json['NO_OF_ROWS']; + pOHEADERID = json['PO_HEADER_ID']; + pROMISEDDATE = json['PROMISED_DATE']; + pRNUM = json['PR_NUM']; + qUANTITY = json['QUANTITY']; + rEQUESTOR = json['REQUESTOR']; + rOWNUM = json['ROW_NUM']; + tOROWNUM = json['TO_ROW_NUM']; + uNITPRICE = json['UNIT_PRICE']; + uOM = json['UOM']; + } + + Map toJson() { + final Map data = new Map(); + data['DELIVER_TO_LOCATION'] = this.dELIVERTOLOCATION; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['ITEM_CODE'] = this.iTEMCODE; + data['ITEM_DESCRIPTION'] = this.iTEMDESCRIPTION; + data['ITEM_ID'] = this.iTEMID; + data['LINE_AMOUNT'] = this.lINEAMOUNT; + data['LINE_DISC_PERCENTAGE'] = this.lINEDISCPERCENTAGE; + data['LINE_NUM'] = this.lINENUM; + data['LINE_TYPE'] = this.lINETYPE; + data['MFG'] = this.mFG; + data['NEED_BY_DATE'] = this.nEEDBYDATE; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['PO_HEADER_ID'] = this.pOHEADERID; + data['PROMISED_DATE'] = this.pROMISEDDATE; + data['PR_NUM'] = this.pRNUM; + data['QUANTITY'] = this.qUANTITY; + data['REQUESTOR'] = this.rEQUESTOR; + data['ROW_NUM'] = this.rOWNUM; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['UNIT_PRICE'] = this.uNITPRICE; + data['UOM'] = this.uOM; + return data; + } +} \ No newline at end of file diff --git a/lib/models/get_quotation_analysis_list_model.dart b/lib/models/get_quotation_analysis_list_model.dart new file mode 100644 index 0000000..c0be32d --- /dev/null +++ b/lib/models/get_quotation_analysis_list_model.dart @@ -0,0 +1,84 @@ +class GetQuotationAnalysisList { + int? fROMROWNUM; + String? iTEMCODE; + String? iTEMDESC; + int? nOOFROWS; + String? qUOTBONUSQTY; + String? qUOTDELIVERYDATE; + int? qUOTLINETOTAL; + String? qUOTMFGPARTNUM; + String? qUOTNUM; + int? qUOTQTY; + int? qUOTUNITPRICE; + String? qUOTUOM; + String? rFQNUM; + int? rFQQTY; + String? rFQUOM; + int? rOWNUM; + int? tOROWNUM; + String? vENDORNAME; + + GetQuotationAnalysisList( + {this.fROMROWNUM, + this.iTEMCODE, + this.iTEMDESC, + this.nOOFROWS, + this.qUOTBONUSQTY, + this.qUOTDELIVERYDATE, + this.qUOTLINETOTAL, + this.qUOTMFGPARTNUM, + this.qUOTNUM, + this.qUOTQTY, + this.qUOTUNITPRICE, + this.qUOTUOM, + this.rFQNUM, + this.rFQQTY, + this.rFQUOM, + this.rOWNUM, + this.tOROWNUM, + this.vENDORNAME}); + + GetQuotationAnalysisList.fromJson(Map json) { + fROMROWNUM = json['FROM_ROW_NUM']; + iTEMCODE = json['ITEM_CODE']; + iTEMDESC = json['ITEM_DESC']; + nOOFROWS = json['NO_OF_ROWS']; + qUOTBONUSQTY = json['QUOT_BONUS_QTY']; + qUOTDELIVERYDATE = json['QUOT_DELIVERY_DATE']; + qUOTLINETOTAL = json['QUOT_LINE_TOTAL']; + qUOTMFGPARTNUM = json['QUOT_MFG_PART_NUM']; + qUOTNUM = json['QUOT_NUM']; + qUOTQTY = json['QUOT_QTY']; + qUOTUNITPRICE = json['QUOT_UNIT_PRICE']; + qUOTUOM = json['QUOT_UOM']; + rFQNUM = json['RFQ_NUM']; + rFQQTY = json['RFQ_QTY']; + rFQUOM = json['RFQ_UOM']; + rOWNUM = json['ROW_NUM']; + tOROWNUM = json['TO_ROW_NUM']; + vENDORNAME = json['VENDOR_NAME']; + } + + Map toJson() { + final Map data = new Map(); + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['ITEM_CODE'] = this.iTEMCODE; + data['ITEM_DESC'] = this.iTEMDESC; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['QUOT_BONUS_QTY'] = this.qUOTBONUSQTY; + data['QUOT_DELIVERY_DATE'] = this.qUOTDELIVERYDATE; + data['QUOT_LINE_TOTAL'] = this.qUOTLINETOTAL; + data['QUOT_MFG_PART_NUM'] = this.qUOTMFGPARTNUM; + data['QUOT_NUM'] = this.qUOTNUM; + data['QUOT_QTY'] = this.qUOTQTY; + data['QUOT_UNIT_PRICE'] = this.qUOTUNITPRICE; + data['QUOT_UOM'] = this.qUOTUOM; + data['RFQ_NUM'] = this.rFQNUM; + data['RFQ_QTY'] = this.rFQQTY; + data['RFQ_UOM'] = this.rFQUOM; + data['ROW_NUM'] = this.rOWNUM; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['VENDOR_NAME'] = this.vENDORNAME; + return data; + } +} \ No newline at end of file diff --git a/lib/models/member_information_list_model.dart b/lib/models/member_information_list_model.dart index da95ed0..dc64e53 100644 --- a/lib/models/member_information_list_model.dart +++ b/lib/models/member_information_list_model.dart @@ -32,7 +32,7 @@ class MemberInformationListModel { String? fREQUENCY; String? fREQUENCYMEANING; int? fROMROWNUM; - String? gRADEID; + int? gRADEID; String? gRADENAME; String? hIREDATE; int? jOBID; diff --git a/lib/models/notification_action_model.dart b/lib/models/notification_action_model.dart new file mode 100644 index 0000000..a1214e1 --- /dev/null +++ b/lib/models/notification_action_model.dart @@ -0,0 +1,18 @@ +class NotificationAction { + String? pRETURNMSG; + String? pRETURNSTATUS; + + NotificationAction({this.pRETURNMSG, this.pRETURNSTATUS}); + + NotificationAction.fromJson(Map json) { + pRETURNMSG = json['P_RETURN_MSG']; + pRETURNSTATUS = json['P_RETURN_STATUS']; + } + + Map toJson() { + final Map data = new Map(); + data['P_RETURN_MSG'] = this.pRETURNMSG; + data['P_RETURN_STATUS'] = this.pRETURNSTATUS; + return data; + } +} \ No newline at end of file diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index f15e244..9fab4b9 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -40,7 +40,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List? getMenuEntriesList; //Attendance Tracking API's & Methods - void fetchAttendanceTracking() async { + void fetchAttendanceTracking(context) async { try { attendanceTracking = await DashboardApiClient().getAttendanceTracking(); isAttendanceTrackingLoading = false; @@ -51,7 +51,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // notifyListeners(); } catch (ex) { - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } @@ -90,12 +90,12 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { logger.wtf(ex); if (showLoading) Utils.hideLoading(context); notifyListeners(); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } //Missing Siwpe API's & Methods - Future fetchMissingSwipe() async { + Future fetchMissingSwipe(context) async { try { GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenMissingSwipes(); isMissingSwipeLoading = false; @@ -105,12 +105,12 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { isMissingSwipeLoading = false; logger.wtf(ex); notifyListeners(); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } //Leave and Ticket Balance API's & Methods - Future fetchLeaveTicketBalance() async { + Future fetchLeaveTicketBalance(context) async { try { GenericResponseModel? genericResponseModel = await DashboardApiClient().getAccrualBalances(); isLeaveTicketBalanceLoading = false; @@ -121,7 +121,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { isLeaveTicketBalanceLoading = false; logger.wtf(ex); notifyListeners(); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } @@ -140,7 +140,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } catch (ex) { logger.wtf(ex); notifyListeners(); - Utils.handleException(ex, null); + Utils.handleException(ex, null, null); } } @@ -155,7 +155,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } catch (ex) { logger.wtf(ex); notifyListeners(); - Utils.handleException(ex, null); + Utils.handleException(ex, null, null); } } @@ -176,4 +176,8 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { // } return menus; } + + void notify() { + notifyListeners(); + } } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index f7260cf..53f36f7 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -32,10 +32,10 @@ class _DashboardScreenState extends State { void initState() { super.initState(); data = Provider.of(context, listen: false); - data.fetchAttendanceTracking(); + data.fetchAttendanceTracking(context); data.fetchWorkListCounter(context); - data.fetchMissingSwipe(); - data.fetchLeaveTicketBalance(); + data.fetchMissingSwipe(context); + data.fetchLeaveTicketBalance(context); // data.fetchMenuEntries(); } diff --git a/lib/ui/login/forgot_password_screen.dart b/lib/ui/login/forgot_password_screen.dart index 17b105f..f058d43 100644 --- a/lib/ui/login/forgot_password_screen.dart +++ b/lib/ui/login/forgot_password_screen.dart @@ -69,7 +69,7 @@ class _ForgotPasswordScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 964c633..cdcdb94 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -75,6 +75,7 @@ class _LoginScreenState extends State { Utils.showLoading(context); firebaseToken = await _firebaseMessaging.getToken(); loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + loginInfo!.deviceToken = firebaseToken; if (loginInfo == null) { Utils.hideLoading(context); print("Device token not found"); @@ -87,7 +88,7 @@ class _LoginScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } @@ -119,7 +120,7 @@ class _LoginScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, (msg) { + Utils.handleException(ex, context, (msg) { Utils.confirmDialog(context, msg); }); } diff --git a/lib/ui/login/new_password_screen.dart b/lib/ui/login/new_password_screen.dart index e0a8f94..7f011e7 100644 --- a/lib/ui/login/new_password_screen.dart +++ b/lib/ui/login/new_password_screen.dart @@ -46,7 +46,7 @@ class _NewPasswordScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, (msg) { + Utils.handleException(ex, context, (msg) { Utils.confirmDialog(context, msg); }); } diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 52ec751..21f4cf6 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -246,6 +248,15 @@ class _VerifyLastLoginScreenState extends State { Utils.showLoading(context); try { GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); + GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( + AppState().memberLoginList?.pEMAILADDRESS ?? "", + genericResponseModel?.pSESSIONID ?? 0, + genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "", + _flag, + AppState().memberLoginList?.pMOBILENUMBER ?? "", + AppState().getUserName!, + mobileLoginInfoListModel!.deviceToken!, + Platform.isAndroid ? "android" : "ios"); if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); // Navigator.pop(context); @@ -256,7 +267,7 @@ class _VerifyLastLoginScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } }, () => { diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index 8e9255f..5fb0d1f 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -692,7 +692,7 @@ class _VerifyLoginScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } }, () => { @@ -702,7 +702,7 @@ class _VerifyLoginScreenState extends State { } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } }, diff --git a/lib/ui/screens/tangheem_detail_screen.dart b/lib/ui/screens/tangheem_detail_screen.dart index b4ca256..0f4ea7b 100644 --- a/lib/ui/screens/tangheem_detail_screen.dart +++ b/lib/ui/screens/tangheem_detail_screen.dart @@ -99,7 +99,7 @@ // setState(() {}); // } catch (ex) { // print(ex); -// Utils.handleException(ex, null); +// Utils.handleException(ex, context, null); // Utils.hideLoading(context); // } // } @@ -132,7 +132,7 @@ // Utils.hideLoading(context); // Navigator.pop(context); // } catch (ex) { -// Utils.handleException(ex, null); +// Utils.handleException(ex, context, null); // Utils.hideLoading(context); // } // } diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart new file mode 100644 index 0000000..904e578 --- /dev/null +++ b/lib/ui/work_list/item_history_screen.dart @@ -0,0 +1,182 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; + +class ItemHistoryScreenParams { + String? title; + bool isItemHistory; + bool isMO; + int? pItemId; + int? pPoHeaderId; + int? pOrgId; + + ItemHistoryScreenParams({@required this.title, this.isItemHistory = true, this.isMO = true, this.pItemId, this.pPoHeaderId, this.pOrgId}); +} + +class ItemHistoryScreen extends StatefulWidget { + ItemHistoryScreen({Key? key}) : super(key: key); + + @override + _ItemHistoryScreenState createState() { + return _ItemHistoryScreenState(); + } +} + +class _ItemHistoryScreenState extends State { + ItemHistoryScreenParams? _screenParams; + + List moItemHistoryList = []; + List poItemHistoryList = []; + List quotationAnalysisList = []; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void loadData() { + if (_screenParams == null) { + _screenParams = ModalRoute.of(context)!.settings.arguments as ItemHistoryScreenParams; + getDataFromApi(); + } + } + + void getDataFromApi() async { + try { + Utils.showLoading(context); + if (_screenParams!.isItemHistory) { + if (_screenParams!.isMO) { + moItemHistoryList = await WorkListApiClient().getMoItemHistory(_screenParams!.pItemId!, _screenParams!.pOrgId!); + } else { + poItemHistoryList = await WorkListApiClient().getPoItemHistory(_screenParams!.pItemId!); + } + } else { + quotationAnalysisList = await WorkListApiClient().getQuotationAnalysis(_screenParams!.pItemId!, _screenParams!.pPoHeaderId!); + } + + Utils.hideLoading(context); + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + @override + Widget build(BuildContext context) { + loadData(); + return Scaffold( + appBar: AppBarWidget(context, title: _screenParams?.title ?? ""), + backgroundColor: Colors.white, + body: ListView( + padding: const EdgeInsets.all(21), + physics: const BouncingScrollPhysics(), + children: [ + if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(), + if (poItemHistoryList.isNotEmpty) loadPoItemHistoryData(), + if (quotationAnalysisList.isNotEmpty) loadQuotationAnalysisData() + ], + ), + ); + } + + Widget loadMoItemHistoryData() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.requestNumber.tr(), moItemHistoryList[index].rEQUESTNUMBER ?? ""), + ItemDetailView(LocaleKeys.uom.tr(), moItemHistoryList[index].uNITOFMEASURE ?? ""), + ItemDetailView(LocaleKeys.quantity.tr(), moItemHistoryList[index].qUANTITY?.toString() ?? ""), + ItemDetailView(LocaleKeys.dateRequired.tr(), moItemHistoryList[index].dATEREQUIRED ?? ""), + ItemDetailView(LocaleKeys.lineStatus.tr(), moItemHistoryList[index].lINESTATUSDIS ?? ""), + ItemDetailView(LocaleKeys.statusDate.tr(), moItemHistoryList[index].sTATUSDATE ?? ""), + ItemDetailView(LocaleKeys.transactionType.tr(), moItemHistoryList[index].tRANSACTIONTYPENAME ?? ""), + ItemDetailView(LocaleKeys.organization.tr(), moItemHistoryList[index].oRGANIZATIONNAME ?? ""), + ItemDetailView(LocaleKeys.operatingCode.tr(), moItemHistoryList[index].oRGANIZATIONCODE ?? ""), + ItemDetailView(LocaleKeys.operatingUnit.tr(), moItemHistoryList[index].oPERATINGUNITNAME ?? ""), + ItemDetailView(LocaleKeys.fromSubInventory.tr(), moItemHistoryList[index].fROMSUBINVENTORYCODE ?? ""), + ItemDetailView(LocaleKeys.fromLocator.tr(), moItemHistoryList[index].fROMLOCATOR ?? ""), + ItemDetailView(LocaleKeys.toSubInventory.tr(), moItemHistoryList[index].tOSUBINVENTORYCODE ?? ""), + ItemDetailView(LocaleKeys.toLocator.tr(), moItemHistoryList[index].tOLOCATOR ?? ""), + ItemDetailView(LocaleKeys.shipToLocation.tr(), moItemHistoryList[index].sHIPTOLOCATION ?? ""), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 12.height, + itemCount: moItemHistoryList.length); + } + + Widget loadPoItemHistoryData() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.operatingUnit.tr(), poItemHistoryList[index].oUNAME ?? ""), + ItemDetailView(LocaleKeys.poNumber.tr(), poItemHistoryList[index].pONUMBER ?? ""), + ItemDetailView(LocaleKeys.revision.tr(), poItemHistoryList[index].rEVISIONNUM?.toString() ?? ""), + ItemDetailView(LocaleKeys.creationDate.tr(), poItemHistoryList[index].cREATIONDATE ?? ""), + ItemDetailView(LocaleKeys.supplier.tr(), poItemHistoryList[index].sUPPLIER ?? ""), + ItemDetailView(LocaleKeys.buyer.tr(), poItemHistoryList[index].bUYER ?? ""), + ItemDetailView(LocaleKeys.uom.tr(), poItemHistoryList[index].uOM ?? ""), + ItemDetailView(LocaleKeys.quantityOrdered.tr(), poItemHistoryList[index].qUANTITYORDERED?.toString() ?? ""), + ItemDetailView(LocaleKeys.quantityReceived.tr(), poItemHistoryList[index].qUANTITYRECEIVED?.toString() ?? ""), + ItemDetailView(LocaleKeys.bonusQuantity.tr(), poItemHistoryList[index].bONUSQUANTITY?.toString() ?? ""), + ItemDetailView(LocaleKeys.purchasePrice.tr(), poItemHistoryList[index].pURCHASEPRICE?.toString() ?? ""), + ItemDetailView(LocaleKeys.discountPer.tr(), poItemHistoryList[index].dISCOUNTPERCENTAGE?.toString() ?? ""), + ItemDetailView(LocaleKeys.balanceQuantity.tr(), poItemHistoryList[index].bALANCEQUANTITY?.toString() ?? ""), + ItemDetailView(LocaleKeys.netPrice.tr(), poItemHistoryList[index].nETPRICE?.toString() ?? ""), + ItemDetailView(LocaleKeys.closureStatus.tr(), poItemHistoryList[index].cLOSEDCODE ?? ""), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 12.height, + itemCount: poItemHistoryList.length); + } + + Widget loadQuotationAnalysisData() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.quotationNumber.tr(), quotationAnalysisList[index].qUOTNUM ?? ""), + ItemDetailView(LocaleKeys.vendorName.tr(), quotationAnalysisList[index].vENDORNAME ?? ""), + ItemDetailView(LocaleKeys.itemCode.tr(), quotationAnalysisList[index].iTEMCODE ?? ""), + ItemDetailView(LocaleKeys.description.tr(), quotationAnalysisList[index].iTEMDESC ?? ""), + ItemDetailView(LocaleKeys.quotationQty.tr(), quotationAnalysisList[index].qUOTQTY?.toString() ?? ""), + ItemDetailView(LocaleKeys.quotationUOM.tr(), quotationAnalysisList[index].qUOTUOM ?? ""), + ItemDetailView(LocaleKeys.quotationNetPrice.tr(), quotationAnalysisList[index].qUOTUNITPRICE?.toString() ?? ""), + ItemDetailView(LocaleKeys.quotationLineTotal.tr(), quotationAnalysisList[index].qUOTLINETOTAL?.toString() ?? ""), + ItemDetailView(LocaleKeys.quotationBonusQuantity.tr(), quotationAnalysisList[index].qUOTBONUSQTY ?? ""), + ItemDetailView(LocaleKeys.quotationDeliveryDate.tr(), quotationAnalysisList[index].qUOTDELIVERYDATE ?? ""), + ItemDetailView(LocaleKeys.quotationMFGPartNumber.tr(), quotationAnalysisList[index].qUOTMFGPARTNUM ?? ""), + ItemDetailView(LocaleKeys.rfqNumber.tr(), quotationAnalysisList[index].rFQNUM ?? ""), + ItemDetailView(LocaleKeys.rfqQty.tr(), quotationAnalysisList[index].rFQQTY?.toString() ?? ""), + ItemDetailView(LocaleKeys.rfqUOM.tr(), quotationAnalysisList[index].rFQUOM ?? ""), + ], + ).objectContainerView(title: "${quotationAnalysisList[index].iTEMCODE}-${quotationAnalysisList[index].iTEMDESC}" ?? ""), + separatorBuilder: (cxt, index) => 12.height, + itemCount: quotationAnalysisList.length); + } +} diff --git a/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart index 652eba8..692f5d8 100644 --- a/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart @@ -1,61 +1,54 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; class AttachmentsFragment extends StatelessWidget { + final List getAttachmentList; + + AttachmentsFragment(this.getAttachmentList); + @override Widget build(BuildContext context) { - return Container( - width: double.infinity, - height: double.infinity, - child: ListView.separated( - itemCount: 2, - padding: EdgeInsets.all(21), - itemBuilder: (context, index) { - return showItem(attachmentsList[index]); - }, - separatorBuilder: (BuildContext context, int index) { - return 21.height; - }, - ), - ); + return ListView.separated( + itemCount: getAttachmentList.length, + itemBuilder: (context, index) { + return Row( + children: [ + SvgPicture.asset(determineFileIcon(getAttachmentList[index].fILECONTENTTYPE ?? "")), + 12.width, + (getAttachmentList[index].fILENAME?.capitalizeFirstofEach ?? "").toText16().expanded, + ], + ).objectContainerView().onPress(() {}); + }, + separatorBuilder: (BuildContext context, int index) => 12.height, + ).paddingAll(21); } - Widget showItem(Attachments attachments) { - return Container( - width: double.infinity, - padding: EdgeInsets.all(21), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - child: Row( - children: [ - SvgPicture.asset(attachments.icon), - 12.width, - attachments.title.toText16() - ], - ), - ); + String determineFileIcon(String fileContentType) { + String icon = ""; + switch (fileContentType) { + case "pdf": + icon = "assets/images/pdf.svg"; + break; + case "xls": + icon = "assets/images/xls.svg"; + break; + case "xlsx": + icon = "assets/images/xls.svg"; + break; + case "png": + icon = "assets/images/png.svg"; + break; + case "jpg": + icon = "assets/images/jpg.svg"; + break; + case "jpeg": + icon = "assets/images/jpg.svg"; + break; + } + return icon; } } - -class Attachments { - String title; - String icon; - - Attachments(this.title, this.icon); -} - -List attachmentsList = [ - Attachments("Attachment File Name.png", "assets/images/png.svg"), - Attachments("Attachment File Name.pdf", "assets/images/pdf.svg"), -]; diff --git a/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart index 9e42459..a8e6282 100644 --- a/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/detail_fragment.dart @@ -8,11 +8,14 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; +import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; class DetailFragment extends StatefulWidget { WorkListResponseModel? workListData; MemberInformationListModel? memberInformationListModel; + DetailFragment(this.workListData, this.memberInformationListModel); + @override State createState() => _DetailFragmentState(); } @@ -28,12 +31,12 @@ class _DetailFragmentState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - detailListItem(LocaleKeys.from.tr(), widget.workListData!.fROMUSER ?? ""), - detailListItem(LocaleKeys.to.tr(), widget.workListData!.tOUSER ?? ""), - detailListItem(LocaleKeys.sent.tr(), widget.workListData!.bEGINDATE ?? ""), - detailListItem(LocaleKeys.closed.tr(), widget.workListData!.eNDDATE ?? ""), - detailListItem(LocaleKeys.id.tr(), widget.workListData!.nOTIFICATIONID?.toString() ?? ""), - detailListItem(LocaleKeys.responder.tr(), widget.workListData!.rESPONDER ?? ""), + ItemDetailView(LocaleKeys.from.tr(), widget.workListData!.fROMUSER ?? ""), + ItemDetailView(LocaleKeys.to.tr(), widget.workListData!.tOUSER ?? ""), + ItemDetailView(LocaleKeys.sent.tr(), widget.workListData!.bEGINDATE ?? ""), + ItemDetailView(LocaleKeys.closed.tr(), widget.workListData!.eNDDATE ?? ""), + ItemDetailView(LocaleKeys.id.tr(), widget.workListData!.nOTIFICATIONID?.toString() ?? ""), + ItemDetailView(LocaleKeys.responder.tr(), widget.workListData!.rESPONDER ?? ""), ], ).objectContainerView(), 12.height, @@ -41,29 +44,29 @@ class _DetailFragmentState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - detailListItem(LocaleKeys.employeeNumber.tr(), widget.memberInformationListModel!.eMPLOYEENUMBER ?? ""), - detailListItem(LocaleKeys.employeeName.tr(), - (AppState().isArabic(context) ? widget.memberInformationListModel!.eMPLOYEEDISPLAYNAMEAr : widget.memberInformationListModel!.eMPLOYEEDISPLAYNAMEEn) ?? ""), - detailListItem(LocaleKeys.jobTitle.tr(), widget.memberInformationListModel!.pOSITIONNAME ?? ""), - detailListItem(LocaleKeys.grade.tr(), widget.memberInformationListModel!.gRADENAME ?? ""), - detailListItem(LocaleKeys.jobCategory.tr(), widget.memberInformationListModel!.pOSITIONNAME?.toString() ?? ""), - detailListItem(LocaleKeys.category.tr(), widget.memberInformationListModel!.eMPLOYMENTCATEGORYMEANING ?? ""), - detailListItem(LocaleKeys.employeeEmailAddress.tr(), widget.memberInformationListModel!.eMPLOYEEEMAILADDRESS ?? ""), - detailListItem(LocaleKeys.payrollBranch.tr(), widget.memberInformationListModel!.pAYROLLNAME ?? ""), + ItemDetailView(LocaleKeys.employeeNumber.tr(), widget.memberInformationListModel!.eMPLOYEENUMBER ?? ""), + ItemDetailView(LocaleKeys.employeeName.tr(), + (AppState().isArabic(context) ? widget.memberInformationListModel!.eMPLOYEENAMEAr : widget.memberInformationListModel!.eMPLOYEENAMEEn) ?? ""), + ItemDetailView(LocaleKeys.jobTitle.tr(), makePositionName(widget.memberInformationListModel!.pOSITIONNAME ?? "")), + ItemDetailView(LocaleKeys.grade.tr(), widget.memberInformationListModel!.gRADENAME ?? ""), + ItemDetailView(LocaleKeys.jobCategory.tr(), makePositionName(widget.memberInformationListModel!.pOSITIONNAME ?? "")), + ItemDetailView(LocaleKeys.category.tr(), widget.memberInformationListModel!.eMPLOYMENTCATEGORYMEANING ?? ""), + ItemDetailView(LocaleKeys.employeeEmailAddress.tr(), widget.memberInformationListModel!.eMPLOYEEEMAILADDRESS ?? ""), + ItemDetailView(LocaleKeys.payrollBranch.tr(), widget.memberInformationListModel!.pAYROLLNAME ?? ""), ], ).objectContainerView(), ], ).paddingAll(21); } - Widget detailListItem(String title, String value) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "$title:".toText12(isBold: true, color: const Color(0xff2D3238)), - 6.width, - (value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor).expanded, - ], - ); + String makePositionName(String job) { + String jobName = ""; + List list = job.split(".").toList(); + if (list.length > 1) { + list.removeLast(); + jobName = list.join(" "); + } + return jobName; } + } diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart index e7c26cf..d9ac454 100644 --- a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -7,13 +7,18 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/worklist_response_model.dart'; +import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; class InfoFragment extends StatelessWidget { + WorkListResponseModel? workListData; + List poHeaderList; List? getAbsenceCollectionNotifications; List? getStampNotifications; - InfoFragment({this.getAbsenceCollectionNotifications, this.getStampNotifications}); + InfoFragment({this.workListData, this.poHeaderList = const [], this.getAbsenceCollectionNotifications, this.getStampNotifications}); @override Widget build(BuildContext context) { @@ -23,20 +28,72 @@ class InfoFragment extends StatelessWidget { child: ListView( padding: const EdgeInsets.all(21), children: [ + if ((workListData?.iTEMTYPE ?? "") == "INVMOA") + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.from.tr(), workListData!.fROMUSER ?? ""), + ItemDetailView(LocaleKeys.to.tr(), workListData!.tOUSER ?? ""), + ItemDetailView(LocaleKeys.sent.tr(), workListData!.bEGINDATE ?? ""), + ItemDetailView(LocaleKeys.closed.tr(), workListData!.eNDDATE ?? ""), + ItemDetailView(LocaleKeys.id.tr(), workListData!.nOTIFICATIONID?.toString() ?? ""), + ItemDetailView(LocaleKeys.responder.tr(), workListData!.rESPONDER ?? ""), + ItemDetailView(LocaleKeys.subject.tr(), workListData!.sUBJECT ?? ""), + ], + ).objectContainerView(), if ((getAbsenceCollectionNotifications?.length ?? 0) > 0) getAbsenceCollectionNotificationsListView(getAbsenceCollectionNotifications ?? []).objectContainerView(title: "Absence Notifications"), - if ((getStampNotifications?.length ?? 0) > 0) getStampNotificationsListView(getStampNotifications ?? []).objectContainerView(title: "Stamp Notifications") + if ((getStampNotifications?.length ?? 0) > 0) getStampNotificationsListView(getStampNotifications ?? []).objectContainerView(title: "Stamp Notifications"), + if (poHeaderList.isNotEmpty) getPoNotificationsListView() ], ), ); } + Widget getPoNotificationsListView() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.description.tr(), workListData!.fROMUSER ?? ""), + ItemDetailView(LocaleKeys.from.tr(), workListData!.fROMUSER ?? ""), + ItemDetailView(LocaleKeys.to.tr(), workListData!.tOUSER ?? ""), + ItemDetailView(LocaleKeys.sent.tr(), workListData!.bEGINDATE ?? ""), + ItemDetailView(LocaleKeys.closed.tr(), workListData!.eNDDATE ?? ""), + ItemDetailView(LocaleKeys.id.tr(), workListData!.nOTIFICATIONID?.toString() ?? ""), + ItemDetailView(LocaleKeys.supplier.tr(), poHeaderList[index].vENDORNAME ?? ""), + ItemDetailView(LocaleKeys.site.tr(), poHeaderList[index].vENDORSITECODE ?? ""), + ItemDetailView(LocaleKeys.buyer.tr(), poHeaderList[index].bUYER ?? ""), + ItemDetailView(LocaleKeys.preparer.tr(), poHeaderList[index].pREPARER ?? ""), + ItemDetailView(LocaleKeys.creationDate.tr(), poHeaderList[index].cREATIONDATE ?? ""), + ItemDetailView(LocaleKeys.shipToLocation.tr(), poHeaderList[index].sHIPTOLOCATIONNAME ?? ""), + ItemDetailView(LocaleKeys.quotationNumber.tr(), poHeaderList[index].qUOTATIONNUMBER ?? ""), + ItemDetailView(LocaleKeys.quotationDate.tr(), poHeaderList[index].qUOTATIONDATE ?? ""), + ItemDetailView(LocaleKeys.paymentTerms.tr(), poHeaderList[index].pAYMENTTERMS ?? ""), + ItemDetailView(LocaleKeys.currency.tr(), poHeaderList[index].cURRENCYNAME ?? ""), + ItemDetailView(LocaleKeys.grossAmount.tr(), poHeaderList[index].gROSSAMOUNT?.toString() ?? ""), + ItemDetailView(LocaleKeys.discountAmount.tr(), poHeaderList[index].dISCOUNTAMOUNT?.toString() ?? ""), + ItemDetailView(LocaleKeys.customDuty.tr(), poHeaderList[index].cUSTOMDUTY?.toString() ?? ""), + ItemDetailView(LocaleKeys.shipHandle.tr(), poHeaderList[index].sHIPHANDLE?.toString() ?? ""), + ItemDetailView(LocaleKeys.otherCharges.tr(), poHeaderList[index].oTHERCHARGES?.toString() ?? ""), + ItemDetailView(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].qUOTATIONDATE ?? ""), + ItemDetailView(LocaleKeys.totalPOAmountInWords.tr(), poHeaderList[index].tOTPOAMTWORD ?? ""), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 4.height, + itemCount: poHeaderList.length); + } + Widget getAbsenceCollectionNotificationsListView(List list) { List dataList = list.isEmpty ? [] : (list.first.collectionNotification ?? []); return ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (cxt, index) => detailListItem(dataList[index].sEGMENTPROMPT!, dataList[index].sEGMENTVALUEDSP!), + itemBuilder: (cxt, index) => ItemDetailView(dataList[index].sEGMENTPROMPT!, dataList[index].sEGMENTVALUEDSP!), separatorBuilder: (cxt, index) => 4.height, itemCount: dataList.length); } @@ -48,33 +105,22 @@ class InfoFragment extends StatelessWidget { itemBuilder: (cxt, index) => Column( mainAxisSize: MainAxisSize.min, children: [ - detailListItem(LocaleKeys.employeeNumber.tr(), list[index].eMPLOYEENUMBER.toString()), - detailListItem(LocaleKeys.assignmentNumber.tr(), list[index].aSSIGNMENTNUMBER.toString()), - detailListItem(LocaleKeys.employeeName.tr(), list[index].eMPLOYEENAME.toString()), - detailListItem(LocaleKeys.scheduleDate.tr(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(list[index].sCHEDULEDATE.toString()), false)), - detailListItem(LocaleKeys.shiftType.tr(), list[index].sHTTYPEDESC.toString()), - detailListItem(LocaleKeys.shift.tr(), list[index].sHTNAME.toString()), - detailListItem(LocaleKeys.breakText.tr(), list[index].bREAKNAME.toString()), - detailListItem(LocaleKeys.actualSwipeStart.tr(), list[index].sHTACTUALSTARTTIME.toString()), - detailListItem(LocaleKeys.actualSwipeEnd.tr(), list[index].sHTACTUALENDTIME.toString()), - detailListItem(LocaleKeys.approvedSwipeStart.tr(), list[index].aPPROVEDSTARTTIME.toString()), - detailListItem(LocaleKeys.approvedSwipeStartReason.tr(), list[index].aPPROVEDSTARTREASON.toString()), - detailListItem(LocaleKeys.approvedSwipeEnd.tr(), ""), - detailListItem(LocaleKeys.approvedSwipeEndReason.tr(), list[index].aPPROVEDENDREASONDESC.toString()), + ItemDetailView(LocaleKeys.employeeNumber.tr(), list[index].eMPLOYEENUMBER.toString()), + ItemDetailView(LocaleKeys.assignmentNumber.tr(), list[index].aSSIGNMENTNUMBER.toString()), + ItemDetailView(LocaleKeys.employeeName.tr(), list[index].eMPLOYEENAME.toString()), + ItemDetailView(LocaleKeys.scheduleDate.tr(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(list[index].sCHEDULEDATE.toString()), false)), + ItemDetailView(LocaleKeys.shiftType.tr(), list[index].sHTTYPEDESC.toString()), + ItemDetailView(LocaleKeys.shift.tr(), list[index].sHTNAME.toString()), + ItemDetailView(LocaleKeys.breakText.tr(), list[index].bREAKNAME.toString()), + ItemDetailView(LocaleKeys.actualSwipeStart.tr(), list[index].sHTACTUALSTARTTIME.toString()), + ItemDetailView(LocaleKeys.actualSwipeEnd.tr(), list[index].sHTACTUALENDTIME.toString()), + ItemDetailView(LocaleKeys.approvedSwipeStart.tr(), list[index].aPPROVEDSTARTTIME.toString()), + ItemDetailView(LocaleKeys.approvedSwipeStartReason.tr(), list[index].aPPROVEDSTARTREASON.toString()), + ItemDetailView(LocaleKeys.approvedSwipeEnd.tr(), ""), + ItemDetailView(LocaleKeys.approvedSwipeEndReason.tr(), list[index].aPPROVEDENDREASONDESC.toString()), ], ), separatorBuilder: (cxt, index) => 18.height, itemCount: list.length); } - - Widget detailListItem(String title, String value) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "$title:".toText12(isBold: true, color: const Color(0xff2D3238)), - 6.width, - (value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor).expanded, - ], - ); - } } diff --git a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart index f5a639b..9d1f8cf 100644 --- a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart @@ -1,86 +1,115 @@ +import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/ui/work_list/item_history_screen.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; -class RequestFragment extends StatefulWidget { - @override - State createState() => _RequestFragmentState(); -} +class RequestFragment extends StatelessWidget { + final List moNotificationBodyList; + final List poLinesList; -class _RequestFragmentState extends State { - bool isOpened = false; + RequestFragment({Key? key, this.moNotificationBodyList = const [], this.poLinesList = const []}) : super(key: key); @override Widget build(BuildContext context) { - return Container( - width: double.infinity, - height: double.infinity, - child: Column( - children: [ - Container( - width: double.infinity, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - margin: EdgeInsets.all(21), - padding: EdgeInsets.only(top: 21, bottom: 21, right: 16, left: 16), - child: Column( + return ListView( + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.all(21), + children: [ + if (moNotificationBodyList.isNotEmpty) moNotificationDataView(), + if (poLinesList.isNotEmpty) poLinesDataView(), + ], + ); + } + + Widget poLinesDataView() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ + ItemDetailView(LocaleKeys.code.tr(), poLinesList[index].iTEMCODE ?? ""), + ItemDetailView(LocaleKeys.mfg.tr(), poLinesList[index].uOM ?? ""), + ItemDetailView(LocaleKeys.lineType.tr(), poLinesList[index].qUANTITY?.toString() ?? ""), + ItemDetailView(LocaleKeys.unit.tr(), poLinesList[index].uOM ?? ""), + ItemDetailView(LocaleKeys.price.tr(), poLinesList[index].uNITPRICE?.toString() ?? ""), + ItemDetailView(LocaleKeys.lineAmount.tr(), poLinesList[index].lINEAMOUNT?.toString() ?? ""), + ItemDetailView(LocaleKeys.quantity.tr(), poLinesList[index].qUANTITY?.toString() ?? ""), + ItemDetailView(LocaleKeys.lineDiscount.tr(), poLinesList[index].lINEDISCPERCENTAGE?.toString() ?? ""), + ItemDetailView(LocaleKeys.needByDate.tr(), poLinesList[index].nEEDBYDATE ?? ""), + ItemDetailView(LocaleKeys.promisedDate.tr(), poLinesList[index].pROMISEDDATE ?? ""), + ItemDetailView(LocaleKeys.deliverToLocation.tr(), poLinesList[index].dELIVERTOLOCATION ?? ""), + ItemDetailView(LocaleKeys.requisitionNumber.tr(), poLinesList[index].rEQUESTOR ?? ""), + ItemDetailView(LocaleKeys.requester.tr(), poLinesList[index].pRNUM ?? ""), + 12.height, Row( children: [ - Expanded( - child: "Hardware Mobility 161 Messenger".toText16(), - ), - Icon(Icons.keyboard_arrow_down_rounded), + DefaultButton(LocaleKeys.itemHistory.tr(), () { + Navigator.pushNamed( + cxt, + AppRoutes.itemHistory, + arguments: ItemHistoryScreenParams(title: LocaleKeys.itemHistory.tr(), isMO: false, pItemId: poLinesList[index].iTEMID), + ); + }).expanded, + 12.width, + DefaultButton(LocaleKeys.quotationAnalysis.tr(), () { + Navigator.pushNamed( + cxt, + AppRoutes.itemHistory, + arguments: ItemHistoryScreenParams( + isItemHistory: false, isMO: false, title: LocaleKeys.quotationAnalysis.tr(), pItemId: poLinesList[index].iTEMID, pPoHeaderId: poLinesList[index].pOHEADERID), + ); + }).expanded, ], - ), - Column( - children: [ - 12.height, - showItem("Code:", "3188000067"), - showItem("Quantity:", "1"), - showItem("Line Status:", "Pending Approval"), - showItem("Transection Type:", "Move Order Issue:"), - showItem("Organization Code:", "SWD"), - showItem("From Subinventory:", "SWD_MSPS"), - showItem("To Subinventory:", "SWD_MSPS"), - showItem("Ship To Location :", "SWD 11206-E.R. (Emergency Room)"), - showItem("Unit:", "Each"), - showItem("Date Required:", "12/23/2019 4:54:04 PM"), - showItem("Status Date:", "12/23/2019 4:54:04 PM"), - showItem("Operation Unit:", "Sehat Al Sewedi"), - showItem("Organization:", "Sehat Al Sewedi"), - showItem("From Locator:", "-"), - showItem("To Locator :", "-"), - ], - ), + ) ], - ), - ), - ], - ), - ); + ).objectContainerView(title: poLinesList[index].iTEMDESCRIPTION!), + separatorBuilder: (cxt, index) => 12.height, + itemCount: poLinesList.length); } - Widget showItem(String title, String value) { - return Padding( - padding: const EdgeInsets.only(top: 2, bottom: 2), - child: Row( - children: [ - title.toText12(isBold: true), - 6.width, - title.toText12(isBold: false, color: MyColors.normalTextColor), - ], - ), - ); + Widget moNotificationDataView() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.code.tr(), moNotificationBodyList[index].iTEMCODE ?? ""), + ItemDetailView(LocaleKeys.unit.tr(), moNotificationBodyList[index].uOM ?? ""), + ItemDetailView(LocaleKeys.quantity.tr(), moNotificationBodyList[index].qUANTITY?.toString() ?? ""), + ItemDetailView(LocaleKeys.dateRequired.tr(), moNotificationBodyList[index].dATEREQUIRED ?? ""), + ItemDetailView(LocaleKeys.lineStatus.tr(), moNotificationBodyList[index].lINESTATUS ?? ""), + ItemDetailView(LocaleKeys.statusDate.tr(), moNotificationBodyList[index].sTATUSDATE ?? ""), + ItemDetailView(LocaleKeys.transactionType.tr(), moNotificationBodyList[index].tRANSACTIONTYPENAME ?? ""), + ItemDetailView(LocaleKeys.operatingUnit.tr(), moNotificationBodyList[index].oPERATINGUNIT ?? ""), + ItemDetailView(LocaleKeys.organizationCode.tr(), moNotificationBodyList[index].oRGANIZATIONCODE ?? ""), + ItemDetailView(LocaleKeys.organization.tr(), moNotificationBodyList[index].oRGANIZATIONNAME ?? ""), + ItemDetailView(LocaleKeys.fromSubInventory.tr(), moNotificationBodyList[index].fROMSUBINVENTORY ?? ""), + ItemDetailView(LocaleKeys.fromLocator.tr(), moNotificationBodyList[index].fROMLOCATOR ?? ""), + ItemDetailView(LocaleKeys.toSubInventory.tr(), moNotificationBodyList[index].tOSUBINVENTORY ?? ""), + ItemDetailView(LocaleKeys.toLocator.tr(), moNotificationBodyList[index].tOLOCATOR ?? ""), + ItemDetailView(LocaleKeys.shipToLocator.tr(), moNotificationBodyList[index].sHIPTOLOCATION ?? ""), + 12.height, + DefaultButton(LocaleKeys.itemHistory.tr(), () { + Navigator.pushNamed( + cxt, + AppRoutes.itemHistory, + arguments: ItemHistoryScreenParams(title: LocaleKeys.itemHistory.tr(), pItemId: moNotificationBodyList[index].iTEMID, pOrgId: moNotificationBodyList[index].oRGID), + ); + }) + ], + ).objectContainerView(title: moNotificationBodyList[index].dESCRIPTION ?? ""), + separatorBuilder: (cxt, index) => 12.height, + itemCount: moNotificationBodyList.length); } } diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart index 8d88404..02d06d3 100644 --- a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; @@ -13,7 +14,10 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; +import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; +import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; @@ -25,6 +29,7 @@ import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_frag import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/accept_reject_input_dialog.dart'; class MissingSwipeScreen extends StatefulWidget { MissingSwipeScreen({Key? key}) : super(key: key); @@ -44,13 +49,17 @@ class _MissingSwipeScreenState extends State { MemberInformationListModel? memberInformationListModel; List notificationButtonsList = []; List actionHistoryList = []; + List getAttachmentList = []; List getStampNotifications = []; + List getMoNotificationBodyList = []; List? getAbsenceCollectionNotifications; List getNotificationRespondAttributes = []; + NotificationGetRespondAttributesList? notificationNoteInput; GenericResponseModel? getBasicNTFBody; GenericResponseModel? getICBody; GenericResponseModel? subordinatesLeavesModel; + GetPoNotificationBodyList? getPoNotificationBody; bool isCloseAvailable = false; bool isApproveAvailable = false; @@ -70,7 +79,7 @@ class _MissingSwipeScreenState extends State { try { Utils.showLoading(context); if (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") { - memberInformationListModel = await WorkListApiClient().getUserInformation(-999); + memberInformationListModel = await WorkListApiClient().getUserInformation(-999, workListData!.sELECTEDEMPLOYEENUMBER!); } if (workListData!.iTEMTYPE == "HRSSA") { getBasicNTFBody = await WorkListApiClient().getBasicDetNTFBody(workListData!.nOTIFICATIONID!, -999); @@ -80,9 +89,19 @@ class _MissingSwipeScreenState extends State { if (workListData!.iTEMTYPE == "STAMP") { getStampNotifications = await WorkListApiClient().getStampMsNotificationBody(workListData!.nOTIFICATIONID!, -999); } + if (workListData!.iTEMTYPE == "INVMOA") { + getMoNotificationBodyList = await WorkListApiClient().getMoNotificationBody(workListData!.nOTIFICATIONID!, -999); + } + if (workListData!.iTEMTYPE == "POAPPRV") { + getPoNotificationBody = await WorkListApiClient().getPoNotificationBody(workListData!.nOTIFICATIONID!, -999); + } getNotificationRespondAttributes = await WorkListApiClient().notificationGetRespondAttributes(workListData!.nOTIFICATIONID!); + if (getNotificationRespondAttributes.isNotEmpty) { + notificationNoteInput = getNotificationRespondAttributes.first; + } notificationButtonsList = await WorkListApiClient().getNotificationButtons(workListData!.nOTIFICATIONID!); actionHistoryList = await WorkListApiClient().getActionHistory(workListData!.nOTIFICATIONID!); + getAttachmentList = await WorkListApiClient().getAttachments(workListData!.nOTIFICATIONID!); if (notificationButtonsList.isNotEmpty) { isCloseAvailable = notificationButtonsList.any((element) => element.bUTTONACTION == "CLOSE"); @@ -93,16 +112,20 @@ class _MissingSwipeScreenState extends State { setState(() {}); } catch (ex) { Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } - @override - Widget build(BuildContext context) { + void getDataFromState() { if (workListData == null) { - workListData = ModalRoute.of(context)!.settings.arguments as WorkListResponseModel; + workListData = AppState().workList![AppState().workListIndex!]; // ModalRoute.of(context)!.settings.arguments as WorkListResponseModel; getData(); } + } + + @override + Widget build(BuildContext context) { + getDataFromState(); return Scaffold( appBar: AppBarWidget(context, title: LocaleKeys.details.tr()), @@ -145,10 +168,19 @@ class _MissingSwipeScreenState extends State { }); }, children: [ - InfoFragment(getAbsenceCollectionNotifications: getAbsenceCollectionNotifications, getStampNotifications: getStampNotifications), - (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? DetailFragment(workListData, memberInformationListModel) : RequestFragment(), + InfoFragment( + poHeaderList: getPoNotificationBody?.pOHeader ?? [], + workListData: workListData, + getAbsenceCollectionNotifications: getAbsenceCollectionNotifications, + getStampNotifications: getStampNotifications), + (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") + ? DetailFragment(workListData, memberInformationListModel) + : RequestFragment( + moNotificationBodyList: getMoNotificationBodyList, + poLinesList: getPoNotificationBody?.pOLines ?? [], + ), ActionsFragment(actionHistoryList), - AttachmentsFragment(), + AttachmentsFragment(getAttachmentList), ], ).expanded, if (isApproveAvailable || isRejectAvailable || isCloseAvailable) @@ -168,26 +200,26 @@ class _MissingSwipeScreenState extends State { if (isRejectAvailable) DefaultButton( LocaleKeys.reject.tr(), - () {}, + () => performAction("REJECTED"), colors: const [ - Color(0xffEB8C90), - Color(0xffDE6C70), + Color(0xffE47A7E), + Color(0xffDE6D71), ], ).expanded, if (isApproveAvailable && isRejectAvailable) 8.width, if (isApproveAvailable) DefaultButton( LocaleKeys.approve.tr(), - () {}, + () => performAction("APPROVED"), colors: const [ - Color(0xff32D892), - Color(0xff1AB170), + Color(0xff28C884), + Color(0xff1BB271), ], ).expanded, if (isCloseAvailable) DefaultButton( LocaleKeys.ok.tr(), - () {}, + () => performAction("CLOSE"), colors: const [ Color(0xff32D892), Color(0xff1AB170), @@ -227,7 +259,16 @@ class _MissingSwipeScreenState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - myFab("Skip", "assets/images/skip.svg"), + myFab("Skip", "assets/images/skip.svg").onPress(() { + if (AppState().workList!.length - 1 > AppState().workListIndex!) { + AppState().setWorkListIndex = AppState().workListIndex! + 1; + workListData = null; + showFabOptions = false; + getDataFromState(); + } else if (AppState().workList!.length - 1 == AppState().workListIndex!) { + Navigator.pop(context); + } + }), 12.height, ...viewApiButtonsList(notificationButtonsList), ], @@ -348,4 +389,41 @@ class _MissingSwipeScreenState extends State { ], ); } + + void performAction(String actionMode) { + showDialog( + context: context, + builder: (cxt) => AcceptRejectInputDialog( + message: LocaleKeys.requestedItems.tr(), + notificationGetRespond: notificationNoteInput, + onTap: (note) { + Map payload = { + "P_ACTION_MODE": actionMode, + "P_APPROVER_INDEX": null, + "P_COMMENTS": "", + "P_FORWARD_TO_USER_NAME": "", + "P_NOTIFICATION_ID": workListData!.nOTIFICATIONID!, + "RespondAttributeList": [ + if (notificationNoteInput != null) {notificationNoteInput!.attributeName: note} + ], + }; + + performNotificationAction(payload); + }, + ), + ); + } + + void performNotificationAction(Map payload) async { + try { + Utils.showLoading(context); + GenericResponseModel model = await WorkListApiClient().postNotificationActions(payload); + Utils.hideLoading(context); + Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); + Navigator.pop(context, true); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } } diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 49fb8ac..fbc960e 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; @@ -56,6 +57,11 @@ class _WorkListScreenState extends State { super.initState(); providerData = Provider.of(context, listen: false); + calculateCounter(); + getWorkList(); + } + + void calculateCounter() { workListItemTypes.forEach((workListElement) { if (workListElement.key == "ITG") { workListElement.value = providerData.itgFormsModel?.totalCount ?? 0; @@ -66,7 +72,6 @@ class _WorkListScreenState extends State { } } }); - getWorkList(); } ItgFormsModel? itgFormsModel; @@ -88,12 +93,13 @@ class _WorkListScreenState extends State { } else { itgRequestTypeIndex = null; workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex].key); + AppState().setWorkList = workList; } Utils.hideLoading(context); setState(() {}); } catch (ex) { Utils.hideLoading(context); - Utils.handleException(ex, null); + Utils.handleException(ex, context, null); } } @@ -188,7 +194,7 @@ class _WorkListScreenState extends State { }, separatorBuilder: (context, index) => 12.height, itemCount: itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails?.length ?? 0, - padding: EdgeInsets.only(top: 16, left: 21, right: 21), + padding: const EdgeInsets.all(21), ), ) : Expanded( @@ -196,13 +202,13 @@ class _WorkListScreenState extends State { ? ((workList!).isEmpty ? "No History Available".toText16().center : ListView.separated( - physics: BouncingScrollPhysics(), + physics: const BouncingScrollPhysics(), itemBuilder: (context, index) { - return rowItem(workListItemTypes[workListItemIndex], workList![index]); + return rowItem(workListItemTypes[workListItemIndex], workList![index], index); }, separatorBuilder: (context, index) => 12.height, itemCount: workList?.length ?? 0, - padding: EdgeInsets.only(top: 21, left: 21, right: 21), + padding: const EdgeInsets.all(21), )) : const SizedBox(), ), @@ -271,10 +277,28 @@ class _WorkListScreenState extends State { ); } - Widget rowItem(WorkListItemTypeModelData data, WorkListResponseModel workData) { + Widget rowItem(WorkListItemTypeModelData data, WorkListResponseModel workData, int index) { return InkWell( - onTap: () { - Navigator.pushNamed(context, AppRoutes.missingSwipe, arguments: workData); + onTap: () async { + AppState().setWorkListIndex = index; + var data = workList![index]; + var shouldReloadData = await Navigator.pushNamed(context, AppRoutes.missingSwipe, arguments: workData); + if (shouldReloadData != null) { + workList!.remove(data); + AppState().setWorkList = workList; + if (data.iTEMTYPE == "ITG") { + } else { + providerData.getOpenNotificationsList?.forEach((element) { + if (element.itemType == data.iTEMTYPE) { + element.openNtfNumber = element.openNtfNumber! - 1; + } + }); + providerData.workListCounter = providerData.workListCounter - 1; + providerData.notify(); + } + calculateCounter(); + if (mounted) setState(() {}); + } }, child: Container( width: double.infinity, diff --git a/lib/widgets/dialogs/accept_reject_input_dialog.dart b/lib/widgets/dialogs/accept_reject_input_dialog.dart new file mode 100644 index 0000000..479a47b --- /dev/null +++ b/lib/widgets/dialogs/accept_reject_input_dialog.dart @@ -0,0 +1,103 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; + +class AcceptRejectInputDialog extends StatelessWidget { + final String? title; + final String? message; + final String? okTitle; + final NotificationGetRespondAttributesList? notificationGetRespond; + final Function(String) onTap; + + AcceptRejectInputDialog({Key? key, this.title, @required this.message, this.okTitle, required this.onTap, this.notificationGetRespond}) : super(key: key); + + String note = ""; + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.white, + shape: const RoundedRectangleBorder(), + insetPadding: const EdgeInsets.only(left: 21, right: 21), + child: Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Text( + title ?? LocaleKeys.confirm.tr(), + style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Color(0xff2B353E), height: 35 / 24, letterSpacing: -0.96), + ), + ), + ), + IconButton( + padding: EdgeInsets.zero, + icon: const Icon(Icons.close), + color: const Color(0xff2B353E), + constraints: const BoxConstraints(), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + Text( + message ?? "", + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff808080), letterSpacing: -0.48), + ), + if (notificationGetRespond != null) ...[ + 14.height, + InputWidget( + "Enter a Note", + notificationGetRespond!.attributeDisplayName!, + TextEditingController(), + isBackgroundEnable: true, + lines: 3, + onChange: (String note) { + this.note = note; + }, + ), + ], + 28.height, + Row( + children: [ + DefaultButton( + LocaleKeys.cancel.tr(), + () => Navigator.pop(context), + colors: const [MyColors.lightGreyEAColor, MyColors.lightGreyEAColor], + textColor: MyColors.darkTextColor, + ).expanded, + 10.width, + DefaultButton( + LocaleKeys.ok.tr(), + () { + Navigator.pop(context); + onTap(note); + }, + colors: const [ + Color(0xff28C884), + Color(0xff1BB271), + ], + ).expanded, + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/item_detail_view_widget.dart b/lib/widgets/item_detail_view_widget.dart new file mode 100644 index 0000000..99f77d7 --- /dev/null +++ b/lib/widgets/item_detail_view_widget.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +class ItemDetailView extends StatelessWidget { + final String title; + final String value; + const ItemDetailView(this.title, this.value, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "$title:".toText12(isBold: true, color: const Color(0xff2D3238)), + 6.width, + (value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor).expanded, + ], + ); + } +} From 807d4b40464a8f7cb4b858a91f1480118cdfcef7 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 20 Apr 2022 16:47:55 +0300 Subject: [PATCH 21/22] item creation added. --- assets/langs/ar-SA.json | 27 ++ assets/langs/en-US.json | 27 ++ lib/api/worklist/worklist_api_client.dart | 32 ++ lib/generated/codegen_loader.g.dart | 54 ++++ lib/generated/locale_keys.g.dart | 27 ++ lib/models/generic_response_model.dart | 27 +- ...get_item_creation_ntf_body_list_model.dart | 292 ++++++++++++++++++ ...stamp_ns_notification_body_list_model.dart | 61 ++++ lib/ui/work_list/item_history_screen.dart | 2 +- .../fragments/info_fragments.dart | 106 +++++-- .../fragments/request_fragment.dart | 46 ++- .../missing_swipe/missing_swipe_screen.dart | 19 +- 12 files changed, 684 insertions(+), 36 deletions(-) create mode 100644 lib/models/get_item_creation_ntf_body_list_model.dart create mode 100644 lib/models/get_stamp_ns_notification_body_list_model.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index daf43ef..4d1254f 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -177,6 +177,33 @@ "human": "بشري", "resources": "موارد", "details": "تفاصيل", + "noDataAvailable": "لا تتوافر بيانات", + "productName": "اسم المنتج", + "productDescription": "وصف المنتج", + "unitPrice": "سعر الوحده", + "manufacturerName": "اسم المصنع", + "manufacturerPartName": "اسم جزء الشركة المصنعة", + "supplierName": "اسم المورد", + "supplierContact": "الاتصال بالمورد", + "chargeToPatient": "المسؤول عن المريض", + "justification": "التبرير", + "itemDescription": "وصف السلعة", + "groupCode": "كود المجموعة", + "primaryUOM": "UOM الابتدائية", + "subgroupDescription": "وصف المجموعة الفرعية", + "subgroupCode": "رمز المجموعة الفرعية", + "groupDescription": "وصف المجموعة", + "templateName": "اسم القالب", + "itemCreationStatus": "حالة إنشاء العنصر", + "standardizationApprovalStatus": "حالة الموافقة على التقييس", + "standardizationApprovalRejectionReason": "سبب رفض الموافقة على التقييس", + "analyzedBy": "تحليل بواسطة", + "approvedDate": "تاريخ الموافقة", + "itemType": "نوع العنصر", + "relatedTo": "متعلق ب", + "requestDate": "تاريخ الطلب", + "analyzedDate": "تاريخ التحليل", + "urgent": "العاجلة", "profile": { "reset_password": { "label": "Reset Password", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index f39f530..5409977 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -177,6 +177,33 @@ "human": "Human", "resources": "Resources", "details": "Details", + "noDataAvailable": "No Data Available", + "productName": "Product Name", + "productDescription": "Product Description", + "unitPrice": "Unit Price", + "manufacturerName": "Manufacturer Name", + "manufacturerPartName": "Manufacturer Part Name", + "supplierName": "Supplier Name", + "supplierContact": "Supplier Contact", + "chargeToPatient": "Charge To Patient", + "justification": "Justification", + "itemDescription": "Item Description", + "groupCode": "Group Code", + "primaryUOM": "Primary UOM", + "subgroupDescription": "Subgroup Description", + "subgroupCode": "Subgroup Code", + "groupDescription": "Group Description", + "templateName": "Template Name", + "itemCreationStatus": "Item Creation Status", + "standardizationApprovalStatus": "Standardization Approval Status", + "standardizationApprovalRejectionReason": "Standardization Approval Rejection Reason", + "analyzedBy": "Analyzed By", + "approvedDate": "Approved Date", + "itemType": "Item Type", + "relatedTo": "Related To", + "requestDate": "Request Date", + "analyzedDate": "Analyzed Date", + "urgent": "Urgent", "profile": { "reset_password": { "label": "Reset Password", diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index 625e700..7435919 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; +import 'package:mohem_flutter_app/models/get_item_creation_ntf_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; @@ -15,6 +16,7 @@ import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ns_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; @@ -150,6 +152,21 @@ class WorkListApiClient { }, url, postParams); } + Future> getStampNsNotificationBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_STAMP_NS_NOTIFICATION_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getStampNsNotificationBodyList ?? []; + }, url, postParams); + } + Future> getAbsenceNotificationBody(int pNotificationID, int pTransactionID) async { String url = "${ApiConsts.erpRest}GET_ABSENCE_NOTIFICATION_BODY"; Map postParams = { @@ -247,4 +264,19 @@ class WorkListApiClient { return responseData.getQuotationAnalysisList ?? []; }, url, postParams); } + + Future getItemCreationNtfBody(int pNotificationID, int pTransactionID) async { + String url = "${ApiConsts.erpRest}GET_ITEM_CREATION_NTF_BODY"; + Map postParams = { + "P_NOTIFICATION_ID": pNotificationID, + "P_TRANSACTION_ID": pTransactionID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getItemCreationNtfBodyList; + }, url, postParams); + } } diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 30fa6f7..3bec4b3 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -193,6 +193,33 @@ class CodegenLoader extends AssetLoader{ "human": "بشري", "resources": "موارد", "details": "تفاصيل", + "noDataAvailable": "لا تتوافر بيانات", + "productName": "اسم المنتج", + "productDescription": "وصف المنتج", + "unitPrice": "سعر الوحده", + "manufacturerName": "اسم المصنع", + "manufacturerPartName": "اسم جزء الشركة المصنعة", + "supplierName": "اسم المورد", + "supplierContact": "الاتصال بالمورد", + "chargeToPatient": "المسؤول عن المريض", + "justification": "التبرير", + "itemDescription": "وصف السلعة", + "groupCode": "كود المجموعة", + "primaryUOM": "UOM الابتدائية", + "subgroupDescription": "وصف المجموعة الفرعية", + "subgroupCode": "رمز المجموعة الفرعية", + "groupDescription": "وصف المجموعة", + "templateName": "اسم القالب", + "itemCreationStatus": "حالة إنشاء العنصر", + "standardizationApprovalStatus": "حالة الموافقة على التقييس", + "standardizationApprovalRejectionReason": "سبب رفض الموافقة على التقييس", + "analyzedBy": "تحليل بواسطة", + "approvedDate": "تاريخ الموافقة", + "itemType": "نوع العنصر", + "relatedTo": "متعلق ب", + "requestDate": "تاريخ الطلب", + "analyzedDate": "تاريخ التحليل", + "urgent": "العاجلة", "profile": { "reset_password": { "label": "Reset Password", @@ -405,6 +432,33 @@ static const Map en_US = { "human": "Human", "resources": "Resources", "details": "Details", + "noDataAvailable": "No Data Available", + "productName": "Product Name", + "productDescription": "Product Description", + "unitPrice": "Unit Price", + "manufacturerName": "Manufacturer Name", + "manufacturerPartName": "Manufacturer Part Name", + "supplierName": "Supplier Name", + "supplierContact": "Supplier Contact", + "chargeToPatient": "Charge To Patient", + "justification": "Justification", + "itemDescription": "Item Description", + "groupCode": "Group Code", + "primaryUOM": "Primary UOM", + "subgroupDescription": "Subgroup Description", + "subgroupCode": "Subgroup Code", + "groupDescription": "Group Description", + "templateName": "Template Name", + "itemCreationStatus": "Item Creation Status", + "standardizationApprovalStatus": "Standardization Approval Status", + "standardizationApprovalRejectionReason": "Standardization Approval Rejection Reason", + "analyzedBy": "Analyzed By", + "approvedDate": "Approved Date", + "itemType": "Item Type", + "relatedTo": "Related To", + "requestDate": "Request Date", + "analyzedDate": "Analyzed Date", + "urgent": "Urgent", "profile": { "reset_password": { "label": "Reset Password", diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 3dbdb7c..43b5df8 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -178,6 +178,33 @@ abstract class LocaleKeys { static const human = 'human'; static const resources = 'resources'; static const details = 'details'; + static const noDataAvailable = 'noDataAvailable'; + static const productName = 'productName'; + static const productDescription = 'productDescription'; + static const unitPrice = 'unitPrice'; + static const manufacturerName = 'manufacturerName'; + static const manufacturerPartName = 'manufacturerPartName'; + static const supplierName = 'supplierName'; + static const supplierContact = 'supplierContact'; + static const chargeToPatient = 'chargeToPatient'; + static const justification = 'justification'; + static const itemDescription = 'itemDescription'; + static const groupCode = 'groupCode'; + static const primaryUOM = 'primaryUOM'; + static const subgroupDescription = 'subgroupDescription'; + static const subgroupCode = 'subgroupCode'; + static const groupDescription = 'groupDescription'; + static const templateName = 'templateName'; + static const itemCreationStatus = 'itemCreationStatus'; + static const standardizationApprovalStatus = 'standardizationApprovalStatus'; + static const standardizationApprovalRejectionReason = 'standardizationApprovalRejectionReason'; + static const analyzedBy = 'analyzedBy'; + static const approvedDate = 'approvedDate'; + static const itemType = 'itemType'; + static const relatedTo = 'relatedTo'; + static const requestDate = 'requestDate'; + static const analyzedDate = 'analyzedDate'; + static const urgent = 'urgent'; static const profile_reset_password_label = 'profile.reset_password.label'; static const profile_reset_password_username = 'profile.reset_password.username'; static const profile_reset_password_password = 'profile.reset_password.password'; diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index 138d686..1c19832 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -2,6 +2,7 @@ import 'package:mohem_flutter_app/models/get_absence_collection_notification_bod import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; import 'package:mohem_flutter_app/models/get_basic_det_ntf_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_item_creation_ntf_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; @@ -9,6 +10,7 @@ import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ns_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/notification_action_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; @@ -117,7 +119,7 @@ class GenericResponseModel { List? getFliexfieldStructureList; List? getHrCollectionNotificationBodyList; List? getHrTransactionList; - List? getItemCreationNtfBodyList; + GetItemCreationNtfBodyList? getItemCreationNtfBodyList; List? getItemTypeNotificationsList; List? getItemTypesList; List? getLookupValuesList; @@ -150,7 +152,7 @@ class GenericResponseModel { List? getScheduleShiftsDetailsList; List? getShiftTypesList; List? getStampMsNotificationBodyList; - List? getStampNsNotificationBodyList; + List? getStampNsNotificationBodyList; List? getSubordinatesAttdStatusList; List? getSubordinatesLeavesList; List? getSubordinatesLeavesTotalVacationsList; @@ -650,7 +652,9 @@ class GenericResponseModel { getFliexfieldStructureList = json['GetFliexfieldStructureList']; getHrCollectionNotificationBodyList = json['GetHrCollectionNotificationBodyList']; getHrTransactionList = json['GetHrTransactionList']; - getItemCreationNtfBodyList = json['GetItemCreationNtfBodyList']; + + getItemCreationNtfBodyList = json['GetItemCreationNtfBodyList'] != null ? new GetItemCreationNtfBodyList.fromJson(json['GetItemCreationNtfBodyList']) : null; + getItemTypeNotificationsList = json['GetItemTypeNotificationsList']; getItemTypesList = json['GetItemTypesList']; getLookupValuesList = json['GetLookupValuesList']; @@ -717,8 +721,13 @@ class GenericResponseModel { getStampMsNotificationBodyList!.add(new GetStampMsNotificationBodyList.fromJson(v)); }); } + if (json['GetStampNsNotificationBodyList'] != null) { + getStampNsNotificationBodyList = []; + json['GetStampNsNotificationBodyList'].forEach((v) { + getStampNsNotificationBodyList!.add(new GetStampNsNotificationBodyList.fromJson(v)); + }); + } - getStampNsNotificationBodyList = json['GetStampNsNotificationBodyList']; getSubordinatesAttdStatusList = json['GetSubordinatesAttdStatusList']; if (json['GetSubordinatesLeavesList'] != null) { @@ -1008,7 +1017,11 @@ class GenericResponseModel { data['GetFliexfieldStructureList'] = this.getFliexfieldStructureList; data['GetHrCollectionNotificationBodyList'] = this.getHrCollectionNotificationBodyList; data['GetHrTransactionList'] = this.getHrTransactionList; - data['GetItemCreationNtfBodyList'] = this.getItemCreationNtfBodyList; + + if (this.getItemCreationNtfBodyList != null) { + data['GetItemCreationNtfBodyList'] = this.getItemCreationNtfBodyList!.toJson(); + } + data['GetItemTypeNotificationsList'] = this.getItemTypeNotificationsList; data['GetItemTypesList'] = this.getItemTypesList; data['GetLookupValuesList'] = this.getLookupValuesList; @@ -1061,6 +1074,10 @@ class GenericResponseModel { data['GetStampMsNotificationBodyList'] = this.getStampMsNotificationBodyList!.map((v) => v.toJson()).toList(); } + if (this.getStampNsNotificationBodyList != null) { + data['GetStampNsNotificationBodyList'] = this.getStampNsNotificationBodyList!.map((v) => v.toJson()).toList(); + } + data['GetStampNsNotificationBodyList'] = this.getStampNsNotificationBodyList; data['GetSubordinatesAttdStatusList'] = this.getSubordinatesAttdStatusList; data['GetSubordinatesLeavesList'] = this.getSubordinatesLeavesList; diff --git a/lib/models/get_item_creation_ntf_body_list_model.dart b/lib/models/get_item_creation_ntf_body_list_model.dart new file mode 100644 index 0000000..83c81cb --- /dev/null +++ b/lib/models/get_item_creation_ntf_body_list_model.dart @@ -0,0 +1,292 @@ +class GetItemCreationNtfBodyList { + List? itemCreationHeader; + List? itemCreationLines; + String? pINFORMATION; + String? pQUESTION; + + GetItemCreationNtfBodyList({this.itemCreationHeader, this.itemCreationLines, this.pINFORMATION, this.pQUESTION}); + + GetItemCreationNtfBodyList.fromJson(Map json) { + if (json['ItemCreationHeader'] != null) { + itemCreationHeader = []; + json['ItemCreationHeader'].forEach((v) { + itemCreationHeader!.add(new ItemCreationHeader.fromJson(v)); + }); + } + if (json['ItemCreationLines'] != null) { + itemCreationLines = []; + json['ItemCreationLines'].forEach((v) { + itemCreationLines!.add(new ItemCreationLines.fromJson(v)); + }); + } + pINFORMATION = json['P_INFORMATION']; + pQUESTION = json['P_QUESTION']; + } + + Map toJson() { + final Map data = new Map(); + if (this.itemCreationHeader != null) { + data['ItemCreationHeader'] = this.itemCreationHeader!.map((v) => v.toJson()).toList(); + } + if (this.itemCreationLines != null) { + data['ItemCreationLines'] = this.itemCreationLines!.map((v) => v.toJson()).toList(); + } + data['P_INFORMATION'] = this.pINFORMATION; + data['P_QUESTION'] = this.pQUESTION; + return data; + } +} + +class ItemCreationHeader { + String? aNALYZEDBY; + int? aNALYZEDBYID; + String? aNALYZEDDATE; + String? aPPROVEDDATE; + String? cATEGORY; + int? cATEGORYID; + String? iTEMTYPE; + String? oPERATINGUNIT; + int? oRGID; + int? rELATEDID; + String? rELATEDTO; + String? rEQUESTER; + int? rEQUESTERID; + String? rEQUESTDATE; + String? sTATUS; + int? tRANSACTIONHEADERID; + String? uRGENTFLAG; + String? uRGENTFLAGDISP; + String? wFITEMKEYANALYSIS; + String? wFITEMKEYAPPROVAL; + String? wFITEMTYPE; + + ItemCreationHeader( + {this.aNALYZEDBY, + this.aNALYZEDBYID, + this.aNALYZEDDATE, + this.aPPROVEDDATE, + this.cATEGORY, + this.cATEGORYID, + this.iTEMTYPE, + this.oPERATINGUNIT, + this.oRGID, + this.rELATEDID, + this.rELATEDTO, + this.rEQUESTER, + this.rEQUESTERID, + this.rEQUESTDATE, + this.sTATUS, + this.tRANSACTIONHEADERID, + this.uRGENTFLAG, + this.uRGENTFLAGDISP, + this.wFITEMKEYANALYSIS, + this.wFITEMKEYAPPROVAL, + this.wFITEMTYPE}); + + ItemCreationHeader.fromJson(Map json) { + aNALYZEDBY = json['ANALYZED_BY']; + aNALYZEDBYID = json['ANALYZED_BY_ID']; + aNALYZEDDATE = json['ANALYZED_DATE']; + aPPROVEDDATE = json['APPROVED_DATE']; + cATEGORY = json['CATEGORY']; + cATEGORYID = json['CATEGORY_ID']; + iTEMTYPE = json['ITEM_TYPE']; + oPERATINGUNIT = json['OPERATING_UNIT']; + oRGID = json['ORG_ID']; + rELATEDID = json['RELATED_ID']; + rELATEDTO = json['RELATED_TO']; + rEQUESTER = json['REQUESTER']; + rEQUESTERID = json['REQUESTER_ID']; + rEQUESTDATE = json['REQUEST_DATE']; + sTATUS = json['STATUS']; + tRANSACTIONHEADERID = json['TRANSACTION_HEADER_ID']; + uRGENTFLAG = json['URGENT_FLAG']; + uRGENTFLAGDISP = json['URGENT_FLAG_DISP']; + wFITEMKEYANALYSIS = json['WF_ITEM_KEY_ANALYSIS']; + wFITEMKEYAPPROVAL = json['WF_ITEM_KEY_APPROVAL']; + wFITEMTYPE = json['WF_ITEM_TYPE']; + } + + Map toJson() { + final Map data = new Map(); + data['ANALYZED_BY'] = this.aNALYZEDBY; + data['ANALYZED_BY_ID'] = this.aNALYZEDBYID; + data['ANALYZED_DATE'] = this.aNALYZEDDATE; + data['APPROVED_DATE'] = this.aPPROVEDDATE; + data['CATEGORY'] = this.cATEGORY; + data['CATEGORY_ID'] = this.cATEGORYID; + data['ITEM_TYPE'] = this.iTEMTYPE; + data['OPERATING_UNIT'] = this.oPERATINGUNIT; + data['ORG_ID'] = this.oRGID; + data['RELATED_ID'] = this.rELATEDID; + data['RELATED_TO'] = this.rELATEDTO; + data['REQUESTER'] = this.rEQUESTER; + data['REQUESTER_ID'] = this.rEQUESTERID; + data['REQUEST_DATE'] = this.rEQUESTDATE; + data['STATUS'] = this.sTATUS; + data['TRANSACTION_HEADER_ID'] = this.tRANSACTIONHEADERID; + data['URGENT_FLAG'] = this.uRGENTFLAG; + data['URGENT_FLAG_DISP'] = this.uRGENTFLAGDISP; + data['WF_ITEM_KEY_ANALYSIS'] = this.wFITEMKEYANALYSIS; + data['WF_ITEM_KEY_APPROVAL'] = this.wFITEMKEYAPPROVAL; + data['WF_ITEM_TYPE'] = this.wFITEMTYPE; + return data; + } +} + +class ItemCreationLines { + String? cHARGETOPATIENT; + int? fROMROWNUM; + int? iNVENTORYITEMID; + String? iTEMCODE; + String? iTEMCREATIONSTATUS; + String? iTEMCREATIONSTATUSDISP; + String? iTEMDESCRIPTION; + String? iTEMGROUP; + String? iTEMGROUPCODE; + String? iTEMSUBGROUP; + String? iTEMSUBGROUPCODE; + String? iTEMTYPE; + String? jUSTIFICATION; + int? lINENUMBER; + int? nOOFROWS; + String? pRIMARYUOM; + String? pRIMARYUOMCODE; + String? pRODUCTDESCRIPTION; + String? pRODUCTNAME; + int? rOWNUM; + String? sTANARDSTATUSDISP; + int? sTANDARDMANUFACTURERID; + String? sTANDARDMANUFACTURERNAME; + String? sTANDARDMFGPARTNUM; + String? sTANDARDREJECTREASON; + String? sTANDARDSTATUS; + String? sUPPLIERCONTACT; + String? sUPPLIERNAME; + int? tEMPLATEID; + String? tEMPLATENAME; + int? tOROWNUM; + int? tRANSACTIONHEADERID; + int? tRANSACTIONLINEID; + int? uNITPRICE; + String? uSERMANUFACTURERNAME; + String? uSERMFGPARTNUM; + + ItemCreationLines( + {this.cHARGETOPATIENT, + this.fROMROWNUM, + this.iNVENTORYITEMID, + this.iTEMCODE, + this.iTEMCREATIONSTATUS, + this.iTEMCREATIONSTATUSDISP, + this.iTEMDESCRIPTION, + this.iTEMGROUP, + this.iTEMGROUPCODE, + this.iTEMSUBGROUP, + this.iTEMSUBGROUPCODE, + this.iTEMTYPE, + this.jUSTIFICATION, + this.lINENUMBER, + this.nOOFROWS, + this.pRIMARYUOM, + this.pRIMARYUOMCODE, + this.pRODUCTDESCRIPTION, + this.pRODUCTNAME, + this.rOWNUM, + this.sTANARDSTATUSDISP, + this.sTANDARDMANUFACTURERID, + this.sTANDARDMANUFACTURERNAME, + this.sTANDARDMFGPARTNUM, + this.sTANDARDREJECTREASON, + this.sTANDARDSTATUS, + this.sUPPLIERCONTACT, + this.sUPPLIERNAME, + this.tEMPLATEID, + this.tEMPLATENAME, + this.tOROWNUM, + this.tRANSACTIONHEADERID, + this.tRANSACTIONLINEID, + this.uNITPRICE, + this.uSERMANUFACTURERNAME, + this.uSERMFGPARTNUM}); + + ItemCreationLines.fromJson(Map json) { + cHARGETOPATIENT = json['CHARGE_TO_PATIENT']; + fROMROWNUM = json['FROM_ROW_NUM']; + iNVENTORYITEMID = json['INVENTORY_ITEM_ID']; + iTEMCODE = json['ITEM_CODE']; + iTEMCREATIONSTATUS = json['ITEM_CREATION_STATUS']; + iTEMCREATIONSTATUSDISP = json['ITEM_CREATION_STATUS_DISP']; + iTEMDESCRIPTION = json['ITEM_DESCRIPTION']; + iTEMGROUP = json['ITEM_GROUP']; + iTEMGROUPCODE = json['ITEM_GROUP_CODE']; + iTEMSUBGROUP = json['ITEM_SUBGROUP']; + iTEMSUBGROUPCODE = json['ITEM_SUBGROUP_CODE']; + iTEMTYPE = json['ITEM_TYPE']; + jUSTIFICATION = json['JUSTIFICATION']; + lINENUMBER = json['LINE_NUMBER']; + nOOFROWS = json['NO_OF_ROWS']; + pRIMARYUOM = json['PRIMARY_UOM']; + pRIMARYUOMCODE = json['PRIMARY_UOM_CODE']; + pRODUCTDESCRIPTION = json['PRODUCT_DESCRIPTION']; + pRODUCTNAME = json['PRODUCT_NAME']; + rOWNUM = json['ROW_NUM']; + sTANARDSTATUSDISP = json['STANARD_STATUS_DISP']; + sTANDARDMANUFACTURERID = json['STANDARD_MANUFACTURER_ID']; + sTANDARDMANUFACTURERNAME = json['STANDARD_MANUFACTURER_NAME']; + sTANDARDMFGPARTNUM = json['STANDARD_MFG_PART_NUM']; + sTANDARDREJECTREASON = json['STANDARD_REJECT_REASON']; + sTANDARDSTATUS = json['STANDARD_STATUS']; + sUPPLIERCONTACT = json['SUPPLIER_CONTACT']; + sUPPLIERNAME = json['SUPPLIER_NAME']; + tEMPLATEID = json['TEMPLATE_ID']; + tEMPLATENAME = json['TEMPLATE_NAME']; + tOROWNUM = json['TO_ROW_NUM']; + tRANSACTIONHEADERID = json['TRANSACTION_HEADER_ID']; + tRANSACTIONLINEID = json['TRANSACTION_LINE_ID']; + uNITPRICE = json['UNIT_PRICE']; + uSERMANUFACTURERNAME = json['USER_MANUFACTURER_NAME']; + uSERMFGPARTNUM = json['USER_MFG_PART_NUM']; + } + + Map toJson() { + final Map data = new Map(); + data['CHARGE_TO_PATIENT'] = this.cHARGETOPATIENT; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['INVENTORY_ITEM_ID'] = this.iNVENTORYITEMID; + data['ITEM_CODE'] = this.iTEMCODE; + data['ITEM_CREATION_STATUS'] = this.iTEMCREATIONSTATUS; + data['ITEM_CREATION_STATUS_DISP'] = this.iTEMCREATIONSTATUSDISP; + data['ITEM_DESCRIPTION'] = this.iTEMDESCRIPTION; + data['ITEM_GROUP'] = this.iTEMGROUP; + data['ITEM_GROUP_CODE'] = this.iTEMGROUPCODE; + data['ITEM_SUBGROUP'] = this.iTEMSUBGROUP; + data['ITEM_SUBGROUP_CODE'] = this.iTEMSUBGROUPCODE; + data['ITEM_TYPE'] = this.iTEMTYPE; + data['JUSTIFICATION'] = this.jUSTIFICATION; + data['LINE_NUMBER'] = this.lINENUMBER; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['PRIMARY_UOM'] = this.pRIMARYUOM; + data['PRIMARY_UOM_CODE'] = this.pRIMARYUOMCODE; + data['PRODUCT_DESCRIPTION'] = this.pRODUCTDESCRIPTION; + data['PRODUCT_NAME'] = this.pRODUCTNAME; + data['ROW_NUM'] = this.rOWNUM; + data['STANARD_STATUS_DISP'] = this.sTANARDSTATUSDISP; + data['STANDARD_MANUFACTURER_ID'] = this.sTANDARDMANUFACTURERID; + data['STANDARD_MANUFACTURER_NAME'] = this.sTANDARDMANUFACTURERNAME; + data['STANDARD_MFG_PART_NUM'] = this.sTANDARDMFGPARTNUM; + data['STANDARD_REJECT_REASON'] = this.sTANDARDREJECTREASON; + data['STANDARD_STATUS'] = this.sTANDARDSTATUS; + data['SUPPLIER_CONTACT'] = this.sUPPLIERCONTACT; + data['SUPPLIER_NAME'] = this.sUPPLIERNAME; + data['TEMPLATE_ID'] = this.tEMPLATEID; + data['TEMPLATE_NAME'] = this.tEMPLATENAME; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['TRANSACTION_HEADER_ID'] = this.tRANSACTIONHEADERID; + data['TRANSACTION_LINE_ID'] = this.tRANSACTIONLINEID; + data['UNIT_PRICE'] = this.uNITPRICE; + data['USER_MANUFACTURER_NAME'] = this.uSERMANUFACTURERNAME; + data['USER_MFG_PART_NUM'] = this.uSERMFGPARTNUM; + return data; + } +} diff --git a/lib/models/get_stamp_ns_notification_body_list_model.dart b/lib/models/get_stamp_ns_notification_body_list_model.dart new file mode 100644 index 0000000..4ce708c --- /dev/null +++ b/lib/models/get_stamp_ns_notification_body_list_model.dart @@ -0,0 +1,61 @@ + +class GetStampNsNotificationBodyList { + int? aSSIGNMENTID; + String? aSSIGNMENTNUMBER; + int? bUSINESSGROUPID; + String? eMPLOYEENAME; + String? eMPLOYEENUMBER; + String? eMPLOYMENTCATEGORY; + int? pAYROLLID; + String? pAYROLLNAME; + int? pERSONID; + String? sCHEDULEDATE; + int? sUPERVISORID; + int? tKPERSONID; + + GetStampNsNotificationBodyList( + {this.aSSIGNMENTID, + this.aSSIGNMENTNUMBER, + this.bUSINESSGROUPID, + this.eMPLOYEENAME, + this.eMPLOYEENUMBER, + this.eMPLOYMENTCATEGORY, + this.pAYROLLID, + this.pAYROLLNAME, + this.pERSONID, + this.sCHEDULEDATE, + this.sUPERVISORID, + this.tKPERSONID}); + + GetStampNsNotificationBodyList.fromJson(Map json) { + aSSIGNMENTID = json['ASSIGNMENT_ID']; + aSSIGNMENTNUMBER = json['ASSIGNMENT_NUMBER']; + bUSINESSGROUPID = json['BUSINESS_GROUP_ID']; + eMPLOYEENAME = json['EMPLOYEE_NAME']; + eMPLOYEENUMBER = json['EMPLOYEE_NUMBER']; + eMPLOYMENTCATEGORY = json['EMPLOYMENT_CATEGORY']; + pAYROLLID = json['PAYROLL_ID']; + pAYROLLNAME = json['PAYROLL_NAME']; + pERSONID = json['PERSON_ID']; + sCHEDULEDATE = json['SCHEDULE_DATE']; + sUPERVISORID = json['SUPERVISOR_ID']; + tKPERSONID = json['TK_PERSON_ID']; + } + + Map toJson() { + final Map data = new Map(); + data['ASSIGNMENT_ID'] = this.aSSIGNMENTID; + data['ASSIGNMENT_NUMBER'] = this.aSSIGNMENTNUMBER; + data['BUSINESS_GROUP_ID'] = this.bUSINESSGROUPID; + data['EMPLOYEE_NAME'] = this.eMPLOYEENAME; + data['EMPLOYEE_NUMBER'] = this.eMPLOYEENUMBER; + data['EMPLOYMENT_CATEGORY'] = this.eMPLOYMENTCATEGORY; + data['PAYROLL_ID'] = this.pAYROLLID; + data['PAYROLL_NAME'] = this.pAYROLLNAME; + data['PERSON_ID'] = this.pERSONID; + data['SCHEDULE_DATE'] = this.sCHEDULEDATE; + data['SUPERVISOR_ID'] = this.sUPERVISORID; + data['TK_PERSON_ID'] = this.tKPERSONID; + return data; + } +} \ No newline at end of file diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 904e578..6cf80ca 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -175,7 +175,7 @@ class _ItemHistoryScreenState extends State { ItemDetailView(LocaleKeys.rfqQty.tr(), quotationAnalysisList[index].rFQQTY?.toString() ?? ""), ItemDetailView(LocaleKeys.rfqUOM.tr(), quotationAnalysisList[index].rFQUOM ?? ""), ], - ).objectContainerView(title: "${quotationAnalysisList[index].iTEMCODE}-${quotationAnalysisList[index].iTEMDESC}" ?? ""), + ).objectContainerView(title: "${quotationAnalysisList[index].iTEMCODE}-${quotationAnalysisList[index].iTEMDESC}"), separatorBuilder: (cxt, index) => 12.height, itemCount: quotationAnalysisList.length); } diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart index d9ac454..df883c8 100644 --- a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -7,8 +7,10 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_item_creation_ntf_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ns_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; @@ -16,38 +18,50 @@ class InfoFragment extends StatelessWidget { WorkListResponseModel? workListData; List poHeaderList; List? getAbsenceCollectionNotifications; - List? getStampNotifications; + List? getStampMsNotifications; + List? getStampNsNotifications; + List itemCreationHeader; - InfoFragment({this.workListData, this.poHeaderList = const [], this.getAbsenceCollectionNotifications, this.getStampNotifications}); + InfoFragment( + {this.workListData, + this.poHeaderList = const [], + this.itemCreationHeader = const [], + this.getAbsenceCollectionNotifications, + this.getStampMsNotifications, + this.getStampNsNotifications}); @override Widget build(BuildContext context) { + List uiList = [ + if ((workListData?.iTEMTYPE ?? "") == "INVMOA") + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.from.tr(), workListData!.fROMUSER ?? ""), + ItemDetailView(LocaleKeys.to.tr(), workListData!.tOUSER ?? ""), + ItemDetailView(LocaleKeys.sent.tr(), workListData!.bEGINDATE ?? ""), + ItemDetailView(LocaleKeys.closed.tr(), workListData!.eNDDATE ?? ""), + ItemDetailView(LocaleKeys.id.tr(), workListData!.nOTIFICATIONID?.toString() ?? ""), + ItemDetailView(LocaleKeys.responder.tr(), workListData!.rESPONDER ?? ""), + ItemDetailView(LocaleKeys.subject.tr(), workListData!.sUBJECT ?? ""), + ], + ).objectContainerView(), + if ((getAbsenceCollectionNotifications?.length ?? 0) > 0) getAbsenceCollectionNotificationsListView(getAbsenceCollectionNotifications ?? []).objectContainerView(title: "Absence Notifications"), + if (getStampMsNotifications?.isNotEmpty ?? false) getStampMsNotificationsListView(getStampMsNotifications ?? []).objectContainerView(title: "Stamp Notifications"), + if (getStampNsNotifications?.isNotEmpty ?? false) getStampNsNotificationsListView(getStampNsNotifications ?? []).objectContainerView(title: "Stamp Notifications"), + if (poHeaderList.isNotEmpty) getPoNotificationsListView(), + if (itemCreationHeader.isNotEmpty) getItemCreationHeaderView() + ]; return Container( width: double.infinity, height: double.infinity, - child: ListView( - padding: const EdgeInsets.all(21), - children: [ - if ((workListData?.iTEMTYPE ?? "") == "INVMOA") - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - ItemDetailView(LocaleKeys.from.tr(), workListData!.fROMUSER ?? ""), - ItemDetailView(LocaleKeys.to.tr(), workListData!.tOUSER ?? ""), - ItemDetailView(LocaleKeys.sent.tr(), workListData!.bEGINDATE ?? ""), - ItemDetailView(LocaleKeys.closed.tr(), workListData!.eNDDATE ?? ""), - ItemDetailView(LocaleKeys.id.tr(), workListData!.nOTIFICATIONID?.toString() ?? ""), - ItemDetailView(LocaleKeys.responder.tr(), workListData!.rESPONDER ?? ""), - ItemDetailView(LocaleKeys.subject.tr(), workListData!.sUBJECT ?? ""), - ], - ).objectContainerView(), - if ((getAbsenceCollectionNotifications?.length ?? 0) > 0) - getAbsenceCollectionNotificationsListView(getAbsenceCollectionNotifications ?? []).objectContainerView(title: "Absence Notifications"), - if ((getStampNotifications?.length ?? 0) > 0) getStampNotificationsListView(getStampNotifications ?? []).objectContainerView(title: "Stamp Notifications"), - if (poHeaderList.isNotEmpty) getPoNotificationsListView() - ], - ), + child: uiList.isEmpty + ? LocaleKeys.noDataAvailable.tr().toText16().center + : ListView( + padding: const EdgeInsets.all(21), + children: uiList, + ), ); } @@ -98,7 +112,7 @@ class InfoFragment extends StatelessWidget { itemCount: dataList.length); } - Widget getStampNotificationsListView(List list) { + Widget getStampMsNotificationsListView(List list) { return ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -123,4 +137,44 @@ class InfoFragment extends StatelessWidget { separatorBuilder: (cxt, index) => 18.height, itemCount: list.length); } + + Widget getStampNsNotificationsListView(List list) { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.employeeNumber.tr(), list[index].eMPLOYEENUMBER.toString()), + ItemDetailView(LocaleKeys.assignmentNumber.tr(), list[index].aSSIGNMENTNUMBER.toString()), + ItemDetailView(LocaleKeys.employeeName.tr(), list[index].eMPLOYEENAME.toString()), + ItemDetailView(LocaleKeys.scheduleDate.tr(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(list[index].sCHEDULEDATE.toString()), false)), + ], + ), + separatorBuilder: (cxt, index) => 18.height, + itemCount: list.length); + } + + Widget getItemCreationHeaderView() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.operatingUnit.tr(), itemCreationHeader[index].oPERATINGUNIT?.toString() ?? ""), + ItemDetailView(LocaleKeys.category.tr(), itemCreationHeader[index].cATEGORY?.toString() ?? ""), + ItemDetailView(LocaleKeys.requester.tr(), itemCreationHeader[index].rEQUESTER?.toString() ?? ""), + ItemDetailView(LocaleKeys.analyzedBy.tr(), itemCreationHeader[index].aNALYZEDBY.toString() ?? ""), + ItemDetailView(LocaleKeys.approvedDate.tr(), itemCreationHeader[index].aPPROVEDDATE?.toString() ?? ""), + ItemDetailView(LocaleKeys.itemType.tr(), itemCreationHeader[index].iTEMTYPE?.toString() ?? ""), + ItemDetailView(LocaleKeys.relatedTo.tr(), itemCreationHeader[index].rELATEDTO?.toString() ?? ""), + ItemDetailView(LocaleKeys.requestDate.tr(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(itemCreationHeader[index].rEQUESTDATE.toString()), false) ?? ""), + ItemDetailView(LocaleKeys.analyzedDate.tr(), itemCreationHeader[index].aNALYZEDDATE?.toString() ?? ""), + ItemDetailView(LocaleKeys.urgent.tr(), itemCreationHeader[index].uRGENTFLAGDISP.toString() ?? ""), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 18.height, + itemCount: itemCreationHeader.length); + } } diff --git a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart index 9d1f8cf..5773ffa 100644 --- a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart @@ -4,6 +4,7 @@ import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/get_item_creation_ntf_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/ui/work_list/item_history_screen.dart'; @@ -12,9 +13,15 @@ import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; class RequestFragment extends StatelessWidget { final List moNotificationBodyList; + final List itemCreationLines; final List poLinesList; - RequestFragment({Key? key, this.moNotificationBodyList = const [], this.poLinesList = const []}) : super(key: key); + RequestFragment({ + Key? key, + this.moNotificationBodyList = const [], + this.itemCreationLines = const [], + this.poLinesList = const [], + }) : super(key: key); @override Widget build(BuildContext context) { @@ -24,6 +31,7 @@ class RequestFragment extends StatelessWidget { children: [ if (moNotificationBodyList.isNotEmpty) moNotificationDataView(), if (poLinesList.isNotEmpty) poLinesDataView(), + if (itemCreationLines.isNotEmpty) itemCreationLinesView(), ], ); } @@ -112,4 +120,40 @@ class RequestFragment extends StatelessWidget { separatorBuilder: (cxt, index) => 12.height, itemCount: moNotificationBodyList.length); } + + Widget itemCreationLinesView() { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ItemDetailView(LocaleKeys.productName.tr(), itemCreationLines[index].pRODUCTNAME ?? ""), + ItemDetailView(LocaleKeys.productDescription.tr(), itemCreationLines[index].pRODUCTDESCRIPTION ?? ""), + ItemDetailView(LocaleKeys.unitPrice.tr(), itemCreationLines[index].uNITPRICE?.toString() ?? ""), + ItemDetailView(LocaleKeys.manufacturerName.tr(), itemCreationLines[index].uSERMANUFACTURERNAME ?? ""), + ItemDetailView(LocaleKeys.manufacturerPartName.tr(), itemCreationLines[index].uSERMFGPARTNUM ?? ""), + ItemDetailView(LocaleKeys.supplierName.tr(), itemCreationLines[index].sUPPLIERNAME ?? ""), + ItemDetailView(LocaleKeys.supplierContact.tr(), itemCreationLines[index].sUPPLIERCONTACT ?? ""), + ItemDetailView(LocaleKeys.chargeToPatient.tr(), itemCreationLines[index].cHARGETOPATIENT ?? ""), + ItemDetailView(LocaleKeys.justification.tr(), itemCreationLines[index].jUSTIFICATION ?? ""), + ItemDetailView(LocaleKeys.itemCode.tr(), itemCreationLines[index].iTEMCODE ?? ""), + ItemDetailView(LocaleKeys.itemDescription.tr(), itemCreationLines[index].iTEMDESCRIPTION ?? ""), + ItemDetailView(LocaleKeys.groupCode.tr(), itemCreationLines[index].iTEMGROUPCODE ?? ""), + ItemDetailView(LocaleKeys.groupDescription.tr(), itemCreationLines[index].iTEMGROUP ?? ""), + ItemDetailView(LocaleKeys.subgroupCode.tr(), itemCreationLines[index].iTEMSUBGROUPCODE ?? ""), + ItemDetailView(LocaleKeys.subgroupDescription.tr(), itemCreationLines[index].iTEMSUBGROUP ?? ""), + ItemDetailView(LocaleKeys.primaryUOM.tr(), itemCreationLines[index].pRIMARYUOM ?? ""), + ItemDetailView(LocaleKeys.manufacturerName.tr(), itemCreationLines[index].sTANDARDMANUFACTURERNAME ?? ""), + ItemDetailView(LocaleKeys.manufacturerPartName.tr(), itemCreationLines[index].sTANDARDMFGPARTNUM ?? ""), + ItemDetailView(LocaleKeys.templateName.tr(), itemCreationLines[index].tEMPLATENAME ?? ""), + ItemDetailView(LocaleKeys.itemCreationStatus.tr(), itemCreationLines[index].iTEMCREATIONSTATUS ?? ""), + ItemDetailView(LocaleKeys.standardizationApprovalStatus.tr(), itemCreationLines[index].sTANDARDSTATUS ?? ""), + ItemDetailView(LocaleKeys.standardizationApprovalRejectionReason.tr(), itemCreationLines[index].sTANDARDREJECTREASON ?? ""), + ], + ).objectContainerView(title: itemCreationLines[index].iTEMDESCRIPTION!), + separatorBuilder: (cxt, index) => 12.height, + itemCount: itemCreationLines.length); + } } diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart index 02d06d3..4416c76 100644 --- a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -15,10 +15,12 @@ import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; +import 'package:mohem_flutter_app/models/get_item_creation_ntf_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_stamp_ns_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; import 'package:mohem_flutter_app/models/worklist_response_model.dart'; @@ -50,7 +52,8 @@ class _MissingSwipeScreenState extends State { List notificationButtonsList = []; List actionHistoryList = []; List getAttachmentList = []; - List getStampNotifications = []; + List getStampMsNotifications = []; + List getStampNsNotifications = []; List getMoNotificationBodyList = []; List? getAbsenceCollectionNotifications; List getNotificationRespondAttributes = []; @@ -60,6 +63,7 @@ class _MissingSwipeScreenState extends State { GenericResponseModel? getICBody; GenericResponseModel? subordinatesLeavesModel; GetPoNotificationBodyList? getPoNotificationBody; + GetItemCreationNtfBodyList? getItemCreationNtfBody; bool isCloseAvailable = false; bool isApproveAvailable = false; @@ -87,11 +91,18 @@ class _MissingSwipeScreenState extends State { subordinatesLeavesModel = await WorkListApiClient().getSubordinatesLeaves("", ""); } if (workListData!.iTEMTYPE == "STAMP") { - getStampNotifications = await WorkListApiClient().getStampMsNotificationBody(workListData!.nOTIFICATIONID!, -999); + if (workListData!.rEQUESTTYPE == "STAMP_MS") { + getStampMsNotifications = await WorkListApiClient().getStampMsNotificationBody(workListData!.nOTIFICATIONID!, -999); + } else { + getStampNsNotifications = await WorkListApiClient().getStampNsNotificationBody(workListData!.nOTIFICATIONID!, -999); + } } if (workListData!.iTEMTYPE == "INVMOA") { getMoNotificationBodyList = await WorkListApiClient().getMoNotificationBody(workListData!.nOTIFICATIONID!, -999); } + if (workListData!.iTEMTYPE == "INVITEM") { + getItemCreationNtfBody = await WorkListApiClient().getItemCreationNtfBody(workListData!.nOTIFICATIONID!, -999); + } if (workListData!.iTEMTYPE == "POAPPRV") { getPoNotificationBody = await WorkListApiClient().getPoNotificationBody(workListData!.nOTIFICATIONID!, -999); } @@ -172,12 +183,14 @@ class _MissingSwipeScreenState extends State { poHeaderList: getPoNotificationBody?.pOHeader ?? [], workListData: workListData, getAbsenceCollectionNotifications: getAbsenceCollectionNotifications, - getStampNotifications: getStampNotifications), + itemCreationHeader: getItemCreationNtfBody?.itemCreationHeader ?? [], + getStampMsNotifications: getStampMsNotifications), (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? DetailFragment(workListData, memberInformationListModel) : RequestFragment( moNotificationBodyList: getMoNotificationBodyList, poLinesList: getPoNotificationBody?.pOLines ?? [], + itemCreationLines: getItemCreationNtfBody?.itemCreationLines ?? [], ), ActionsFragment(actionHistoryList), AttachmentsFragment(getAttachmentList), From 9b5147b565a73533ca6e39d47bd6b241cef4acf8 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 10 May 2022 17:38:19 +0300 Subject: [PATCH 22/22] merge improvements --- lib/api/api_client.dart | 6 +++++- lib/app_state/app_state.dart | 4 ++++ lib/classes/utils.dart | 5 +++-- lib/provider/dashboard_provider_model.dart | 4 ++-- lib/ui/landing/dashboard_screen.dart | 2 +- lib/ui/landing/today_attendance_screen.dart | 11 +++++------ lib/ui/login/login_screen.dart | 4 +--- .../missing_swipe/fragments/info_fragments.dart | 4 ++-- 8 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index 17eac0d..3263bf4 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:http/io_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/exceptions/api_exception.dart'; import '../main.dart'; @@ -81,6 +82,9 @@ class ApiClient { logger.i("res: " + response.body); } var jsonData = jsonDecode(response.body); + if (jsonData["IsAuthenticated"] != null) { + AppState().setIsAuthenticated = jsonData["IsAuthenticated"]; + } if (jsonData["ErrorMessage"] == null) { return factoryConstructor(jsonData); } else { @@ -237,4 +241,4 @@ class ApiClient { } Future _post(url, {Map? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding)); - } +} diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 51337ff..de05b56 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -12,6 +12,10 @@ class AppState { factory AppState() => _instance; + bool isAuthenticated = false; + + set setIsAuthenticated(v) => isAuthenticated = v; + bool isLogged = false; set setLogged(v) => isLogged = v; diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index d3081d4..1634fd5 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/config/routes.dart'; // import 'package:fluttertoast/fluttertoast.dart'; @@ -83,12 +84,12 @@ class Utils { if (onErrorMessage != null) { onErrorMessage(errorMessage); } else { - if (errorMessage.contains("User session is not valid")) { + if (!AppState().isAuthenticated) { showDialog( context: cxt, builder: (cxt) => ConfirmDialog( message: errorMessage, - onTap: (){ + onTap: () { Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route route) => false); }, ), diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 61b66c6..9316182 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -71,8 +71,8 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { return ((hour * 60 * 60) + (mints * 60) + seconds); } - update() { - fetchAttendanceTracking(); + update(context) { + fetchAttendanceTracking(context); // isAttendanceTrackingLoading = !isAttendanceTrackingLoading; // isWorkListLoading = !isWorkListLoading; // attendanceTracking?.pSwipeIn = "a"; diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 4d9fdef..029da02 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -96,7 +96,7 @@ class _DashboardScreenState extends State { ], ), ).onPress(() { - data.update(); + data.update(context); }) ], ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index cfba3fd..6268425 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -42,7 +42,7 @@ class _TodayAttendanceScreenState extends State { data = Provider.of(context, listen: false); } - checkAttendanceAvailablity() async { + void checkAttendanceAvailablity() async { bool isAvailable = await NfcManager.instance.isAvailable(); setState(() { AppState().privilegeListModel!.forEach((element) { @@ -84,7 +84,7 @@ class _TodayAttendanceScreenState extends State { actions: [ IconButton( onPressed: () { - data.fetchAttendanceTracking(); + data.fetchAttendanceTracking(context); }, icon: Icon( Icons.ac_unit, @@ -192,8 +192,7 @@ class _TodayAttendanceScreenState extends State { attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { if (isNfcLocationEnabled) { Location.getCurrentLocation((LatLng? latlng) { - print(latlng!.longitude.toString()); - performNfcAttendance(model, lat: latlng.latitude.toString() ?? "", lng: latlng.longitude.toString() ?? ""); + performNfcAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); }); } else { performNfcAttendance(model); @@ -246,12 +245,12 @@ class _TodayAttendanceScreenState extends State { Utils.showLoading(context); try { GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng); - bool status = await model.fetchAttendanceTracking(); + bool status = await model.fetchAttendanceTracking(context); Utils.hideLoading(context); } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, (msg) { + Utils.handleException(ex, context, (msg) { Utils.confirmDialog(context, msg); }); } diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 9b09023..29fbbfe 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -75,18 +75,16 @@ class _LoginScreenState extends State { Utils.showLoading(context); firebaseToken = await _firebaseMessaging.getToken(); loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); - loginInfo!.deviceToken = firebaseToken; if (loginInfo == null) { Utils.hideLoading(context); - print("Device token not found"); return; } else { + loginInfo!.deviceToken = firebaseToken; await checkPrefs(); Utils.hideLoading(context); performLogin(); } } catch (ex) { - print(ex); Utils.hideLoading(context); Utils.handleException(ex, context, null); } diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart index df883c8..ba0e57e 100644 --- a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -165,13 +165,13 @@ class InfoFragment extends StatelessWidget { ItemDetailView(LocaleKeys.operatingUnit.tr(), itemCreationHeader[index].oPERATINGUNIT?.toString() ?? ""), ItemDetailView(LocaleKeys.category.tr(), itemCreationHeader[index].cATEGORY?.toString() ?? ""), ItemDetailView(LocaleKeys.requester.tr(), itemCreationHeader[index].rEQUESTER?.toString() ?? ""), - ItemDetailView(LocaleKeys.analyzedBy.tr(), itemCreationHeader[index].aNALYZEDBY.toString() ?? ""), + ItemDetailView(LocaleKeys.analyzedBy.tr(), itemCreationHeader[index].aNALYZEDBY?.toString() ?? ""), ItemDetailView(LocaleKeys.approvedDate.tr(), itemCreationHeader[index].aPPROVEDDATE?.toString() ?? ""), ItemDetailView(LocaleKeys.itemType.tr(), itemCreationHeader[index].iTEMTYPE?.toString() ?? ""), ItemDetailView(LocaleKeys.relatedTo.tr(), itemCreationHeader[index].rELATEDTO?.toString() ?? ""), ItemDetailView(LocaleKeys.requestDate.tr(), DateUtil.formatDateToDate(DateUtil.convertStringToDate(itemCreationHeader[index].rEQUESTDATE.toString()), false) ?? ""), ItemDetailView(LocaleKeys.analyzedDate.tr(), itemCreationHeader[index].aNALYZEDDATE?.toString() ?? ""), - ItemDetailView(LocaleKeys.urgent.tr(), itemCreationHeader[index].uRGENTFLAGDISP.toString() ?? ""), + ItemDetailView(LocaleKeys.urgent.tr(), itemCreationHeader[index].uRGENTFLAGDISP?.toString() ?? ""), ], ).objectContainerView(), separatorBuilder: (cxt, index) => 18.height,