From e212cf75b1bc824ac7b86a91d4408a91eb9f015e Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 1 Jul 2024 14:19:47 +0300 Subject: [PATCH] ppm multi timer added. --- lib/controllers/api_routes/urls.dart | 5 +- .../providers/api/ppm_provider.dart | 8 ++ lib/extensions/string_extensions.dart | 4 +- lib/models/ppm/ppm.dart | 71 ++++++++++++++---- lib/views/widgets/pentry/pentry_tbs_form.dart | 73 ++++++++++++++++++- lib/views/widgets/sound/record_sound.dart | 2 +- 6 files changed, 141 insertions(+), 22 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index b8b494a0..a35f2fc5 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -1,8 +1,8 @@ class URLs { URLs._(); - static const host1 = "https://atomsm.hmg.com"; // production url - // static const host1 = "https://atomsmdev.hmg.com"; // local UAT url + // static const host1 = "https://atomsm.hmg.com"; // production url + static const host1 = "https://atomsmdev.hmg.com"; // local UAT url static String _baseUrl = "$_host/mobile"; @@ -16,6 +16,7 @@ class URLs { // API Routes static get login => "$_baseUrl/MobileAuth/Login"; // web login + static get checkLoginValidation => "$_baseUrl/Account/Authenticate "; // web login // static get login => "$_baseUrl/MobileAuth/LoginIntegration"; // mobile login static get register => "$_baseUrl/handle/create/user"; // post static get updateProfile => "$_baseUrl/update/user/profile"; // post diff --git a/lib/controllers/providers/api/ppm_provider.dart b/lib/controllers/providers/api/ppm_provider.dart index d65ff04e..1570737b 100644 --- a/lib/controllers/providers/api/ppm_provider.dart +++ b/lib/controllers/providers/api/ppm_provider.dart @@ -170,6 +170,14 @@ class PpmProvider extends ChangeNotifier { @required Ppm ppm, }) async { try { + ppm.visitTimers.add( + VisitTimers( + id: 0, + startDateTime: ppm.tbsTimer?.startAt?.toIso8601String(), + endDateTime: ppm.tbsTimer?.endAt?.toIso8601String(), + workingHours: ((ppm.tbsTimer?.durationInSecond ?? 0) / 60 / 60), + ), + ); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); Response response; Map body = ppm.copyWith(assignedEmployeeId: user.userName, tbsTimer: ppm.tbsTimer).toJson(); diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 7c64135e..fa760b9e 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -16,7 +16,7 @@ extension StringExtensions on String { DateTime dateTime = DateTime.tryParse(this); return "${DateFormat('dd MMM, yyyy').format(dateTime)} ${DateFormat('hh:mm a').format(dateTime)}"; } catch (e) { - return "null"; + return ""; } } @@ -45,7 +45,7 @@ extension StringExtensions on String { sub = sub.replaceAll("fileName=", ""); return sub; } else { - this; + return this; } } catch (e) { return this; diff --git a/lib/models/ppm/ppm.dart b/lib/models/ppm/ppm.dart index 7dc945b3..d8e38785 100644 --- a/lib/models/ppm/ppm.dart +++ b/lib/models/ppm/ppm.dart @@ -12,6 +12,31 @@ import 'package:test_sa/models/ppm/ppm_contacts.dart'; import 'package:test_sa/models/ppm/ppm_kit.dart'; import 'package:test_sa/models/timer_model.dart'; +class VisitTimers { + int id; + String startDateTime; + String endDateTime; + double workingHours; + + VisitTimers({this.id, this.startDateTime, this.endDateTime, this.workingHours}); + + VisitTimers.fromJson(Map json) { + id = json['id']; + startDateTime = json['startDateTime']; + endDateTime = json['endDateTime']; + workingHours = json['workingHours']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['startDateTime'] = this.startDateTime; + data['endDateTime'] = this.endDateTime; + data['workingHours'] = this.workingHours; + return data; + } +} + class Ppm { Ppm({ this.id, @@ -37,6 +62,7 @@ class Ppm { this.vChecklists, this.files, this.visitStatusId, + this.visitTimers, this.startDate, this.endDate, this.workingHours, @@ -87,9 +113,9 @@ class Ppm { this.safetyName, this.siteId, this.siteName, - this. buildingName, - this. floorName, - this. roomName, + this.buildingName, + this.floorName, + this.roomName, this.supplierName, this.suppPerson, this.taskStatusName, @@ -151,18 +177,25 @@ class Ppm { }); } visitStatusId = json['visitStatusId']; + visitTimers = []; + if (json['visitTimers'] != null) { + json['visitTimers'].forEach((v) { + visitTimers.add(VisitTimers.fromJson(v)); + }); + } startDate = json['startDate']; endDate = json['endDate']; workingHours = json['workingHours']; - try { - tbsTimer = TimerModel(startAt: DateTime.tryParse(startDate ?? ""), endAt: DateTime.tryParse(endDate ?? "")); - if (tbsTimer.endAt != null && tbsTimer.startAt != null) { - tbsTimer.durationInSecond = (tbsTimer.endAt.difference(tbsTimer.startAt))?.inSeconds; - workingHours = (((tbsTimer.durationInSecond ?? 0) / 60) / 60).toStringAsFixed(2); - } - } catch (e) { - print(e.toString()); - } + tbsTimer= TimerModel(); + // try { + // tbsTimer = TimerModel(startAt: DateTime.tryParse(startDate ?? ""), endAt: DateTime.tryParse(endDate ?? "")); + // if (tbsTimer.endAt != null && tbsTimer.startAt != null) { + // tbsTimer.durationInSecond = (tbsTimer.endAt.difference(tbsTimer.startAt))?.inSeconds; + // workingHours = (((tbsTimer.durationInSecond ?? 0) / 60) / 60).toStringAsFixed(2); + // } + // } catch (e) { + // print(e.toString()); + // } travelingHours = json['travelingHours']; deviceStatusId = json['deviceStatusId']; comments = json['comments']; @@ -255,6 +288,8 @@ class Ppm { List vChecklists; List files; num visitStatusId; + + List visitTimers; String startDate; String endDate; String workingHours; @@ -347,6 +382,7 @@ class Ppm { List vChecklists, List files, num visitStatusId, + List visitTimers, String startDate, String endDate, String workingHours, @@ -437,6 +473,7 @@ class Ppm { vChecklists: vChecklists ?? this.vChecklists, files: files ?? this.files, visitStatusId: visitStatusId ?? this.visitStatusId, + visitTimers: visitTimers ?? this.visitTimers, startDate: startDate ?? this.startDate, endDate: endDate ?? this.endDate, workingHours: workingHours ?? this.workingHours, @@ -541,9 +578,12 @@ class Ppm { .toList(); } map['visitStatusId'] = visitStatusId; - map['startDate'] = tbsTimer?.startAt?.toIso8601String(); - map['endDate'] = tbsTimer?.endAt?.toIso8601String(); - map['workingHours'] = ((tbsTimer?.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5); + if (this.visitTimers != null) { + map['visitTimers'] = this.visitTimers.map((v) => v.toJson()).toList(); + } + // map['startDate'] = tbsTimer?.startAt?.toIso8601String(); + // map['endDate'] = tbsTimer?.endAt?.toIso8601String(); + // map['workingHours'] = ((tbsTimer?.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5); map['travelingHours'] = travelingHours; map['deviceStatusId'] = deviceStatusId; map['comments'] = comments; @@ -555,7 +595,6 @@ class Ppm { map['suppEndDate'] = externalEngineerTimer?.endAt?.toIso8601String(); map['suppWorkingHours'] = ((externalEngineerTimer?.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5); - map['taskStatusId'] = taskStatusId; map['engSignature'] = engSignature; map['nurseSignature'] = nurseSignature; diff --git a/lib/views/widgets/pentry/pentry_tbs_form.dart b/lib/views/widgets/pentry/pentry_tbs_form.dart index f30bceb5..88dc35e4 100644 --- a/lib/views/widgets/pentry/pentry_tbs_form.dart +++ b/lib/views/widgets/pentry/pentry_tbs_form.dart @@ -8,6 +8,7 @@ import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/models/ppm/ppm.dart'; import 'package:test_sa/models/ppm/ppm_attachment.dart'; import 'package:test_sa/models/service_request/supplier_details.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/ppm_asset_availability_provider.dart'; import 'package:test_sa/providers/ppm_electrical_safety_provider.dart'; @@ -43,6 +44,10 @@ class _PentryTBSFormState extends State { widget.model?.files ??= []; widget.model?.files = (widget.model.files ?? []).where((element) => element.attachmentName != null && element.attachmentName.isNotEmpty).toList(); + double totalWorkingHours = widget.model.visitTimers.fold(0.0, (sum, item) => sum + DateTime.parse(item.endDateTime).difference(DateTime.parse(item.startDateTime)).inSeconds); + + totalWorkingHours = totalWorkingHours; + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -66,6 +71,33 @@ class _PentryTBSFormState extends State { }, ), 8.height, + if (totalWorkingHours > 0.0) ...[ + Container( + height: 50.toScreenHeight, + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + color: context.isDark ? AppColor.neutral40 : AppColor.background(context), + borderRadius: BorderRadius.circular(10), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Total Working Time", + style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500), + ), + Text( + " ${formatDuration(totalWorkingHours.round())}", + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ), + 8.height, + ], AppTimer( label: context.translation.timer, timer: widget.model.tbsTimer, @@ -148,7 +180,6 @@ class _PentryTBSFormState extends State { }, ), 8.height, - if (widget.model?.typeOfServiceId == 66) ...[ SingleItemDropDownMenu( context: context, @@ -291,4 +322,44 @@ class _PentryTBSFormState extends State { ), ); } + + String formatDuration1(int seconds) { + int hours = seconds ~/ 3600; + int minutes = (seconds % 3600) ~/ 60; + + String formattedDuration = ''; + if (hours > 0) { + formattedDuration += '$hours hour${hours > 1 ? 's' : ''} '; + } + if (minutes > 0) { + formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} '; + } + if (formattedDuration.isEmpty) { + formattedDuration = 'Less than a minute'; + } + + return formattedDuration.trim(); + } + + String formatDuration(int seconds) { + int hours = seconds ~/ 3600; + int minutes = (seconds % 3600) ~/ 60; + int remainingSeconds = seconds % 60; + + String formattedDuration = ''; + if (hours > 0) { + formattedDuration += '$hours hour${hours > 1 ? 's' : ''} '; + } + if (minutes > 0) { + formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} '; + } + if (remainingSeconds > 0) { + formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} '; + } + if (formattedDuration.isEmpty) { + formattedDuration = 'Less than a second'; + } + + return formattedDuration.trim(); + } } diff --git a/lib/views/widgets/sound/record_sound.dart b/lib/views/widgets/sound/record_sound.dart index d01edc03..a3e7826b 100644 --- a/lib/views/widgets/sound/record_sound.dart +++ b/lib/views/widgets/sound/record_sound.dart @@ -162,7 +162,7 @@ class _RecordSoundState extends State { alignment: AlignmentDirectional.centerEnd, children: [ AppTextFormField( - enable: false, + enable: widget.enabled, controller: _timeController, labelText: context.translation.recordVoice, initialValue: (_timeController?.text?.isEmpty ?? true) ? "00:00" : _timeController?.text,