Merge remote-tracking branch 'origin/design_3.0_ppm_new_flow' into design_3.0_ppm_new_flow

# Conflicts:
#	lib/views/pages/user/ppm/update_ppm/wo_info_form.dart
design_3.0_latest
WaseemAbbasi22 8 months ago
commit e4dd92c4a9

@ -367,16 +367,16 @@ class CategoryTabs {
if (userType == UsersTypes.engineer) {
// tabs.add(CategoryTabs(label: 'Upcoming', tag: 0, id: 0));
// tabs.add(CategoryTabs('Open', 1));
tabs.add(CategoryTabs(label: 'UnAssigned Open', tag: 1, id: 1));
tabs.add(CategoryTabs(label: 'Assigned Open', tag: 1, id: 2));
tabs.add(CategoryTabs(label: 'UnAssigned', tag: 1, id: 1));
tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2));
tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3));
tabs.add(CategoryTabs(label: 'Completed', tag: 3, id: 4));
return tabs;
}
tabs.add(CategoryTabs(label: 'Open Request', tag: 1, id: 2));
tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2));
tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3));
tabs.add(CategoryTabs(label: 'Upcoming', tag: 3, id: 1));
tabs.add(CategoryTabs(label: 'Pending Acknowledgement', tag: 3, id: 1));
tabs.add(CategoryTabs(label: 'Canceled', tag: 6, id: 4));
return tabs;
}

@ -151,10 +151,9 @@
//
import 'package:flutter/material.dart';
import 'package:pie_chart/pie_chart.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:test_sa/dashboard_latest/dashboard_provider.dart';
import 'package:test_sa/controllers/providers/api/all_requests_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
@ -212,46 +211,44 @@ class ProgressFragment extends StatelessWidget {
child: Stack(
alignment: Alignment.center,
children: [
SfCircularChart(
tooltipBehavior: TooltipBehavior(
enable: true,
// elevation: 2,
color: context.isDark ? const Color(0xFF111427) : const Color(0xffF7F9FB),
textStyle: context.isDark ? null : const TextStyle(color: Colors.black87, fontSize: 12),
PieChart(
dataMap: {for (var v in chartData) v.x: v.y},
animationDuration: const Duration(milliseconds: 800),
chartLegendSpacing: 32,
chartRadius: MediaQuery.of(context).size.width / 3.2,
colorList: chartData.map((element) => element.color).toList(),
initialAngleInDegree: 270,
chartType: ChartType.ring,
ringStrokeWidth: 32,
centerWidget: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
context.translation.total,
style: AppTextStyles.heading5.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
Text(
"$total",
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
],
),
legendOptions: const LegendOptions(
showLegendsInRow: false,
legendPosition: LegendPosition.right,
showLegends: true,
legendTextStyle: TextStyle(
fontWeight: FontWeight.w500,
),
legend: const Legend(
//isVisible: true,
),
series: <CircularSeries>[
DoughnutSeries<ChartData, String>(
dataSource: chartData,
radius: "100%",
innerRadius: "60%",
pointColorMapper: (ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
dataLabelMapper: (ChartData data, _) => data.x,
dataLabelSettings: DataLabelSettings(
margin: const EdgeInsets.all(8),
isVisible: true,
textStyle: TextStyle(color: context.isDark ? Colors.white : AppColor.neutral20, fontSize: 12, fontWeight: FontWeight.w500),
labelPosition: ChartDataLabelPosition.outside,
),
)
]).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250).paddingAll(0).toShadowContainer(context),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
context.translation.total,
style: AppTextStyles.heading5.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
Text(
"$total",
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
],
),
),
chartValuesOptions: const ChartValuesOptions(
showChartValueBackground: false,
showChartValues: false,
showChartValuesInPercentage: false,
showChartValuesOutside: false,
decimalPlaces: 1,
),
).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250).paddingAll(0).toShadowContainer(context),
],
),
),

@ -164,13 +164,14 @@ extension CapExtension on String {
String get allInCaps => toUpperCase();
String get cleanupWhitespace => replaceAll(RegExp(r"\s+"), " ");
String get capitalizeFirstOfEach => trim().isNotEmpty
? trim().toLowerCase().split(" ").map((str) {
return str.trim()?.inCaps ?? "";
}).join(" ")
: "";
String get cleanupWhitespace => this;//replaceAll(RegExp(r"\s+"), " ");
String get capitalizeFirstOfEach => this;
//trim().isNotEmpty
// ? trim().toLowerCase().split(" ").map((str) {
// return str.trim()?.inCaps ?? "";
// }).join(" ")
// : "";
}
extension FilesExtension on String {

@ -4,6 +4,7 @@ import 'package:shimmer/shimmer.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/new_views/swipe_module/dialoge/acknowledge_work_dialog.dart';
import '../new_views/app_style/app_color.dart';
@ -54,6 +55,26 @@ extension WidgetExtensions on Widget {
Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this);
Widget handlePopScope(BuildContext _cxt, VoidCallback onSave) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (didPop) {
return;
}
showDialog(
context: _cxt,
builder: (BuildContext cxt) => AcknowledgeWorkDialog(
onSave: () => onSave(),
onDiscard: () {
Navigator.of(cxt).pop();
},
),
);
},
child: this);
}
Widget toShimmer({bool isShow = true, double radius = 20}) => isShow
? Shimmer.fromColors(
baseColor: const Color(0xffe8eff0),
@ -81,18 +102,19 @@ extension WidgetExtensions on Widget {
).toShadowContainer(context)
: this;
Widget toShadowContainer(BuildContext context, {bool showShadow = true,double borderRadius = 14, bool withShadow = true, Color? backgroundColor, double padding = 16, EdgeInsets? paddingObject}) => withShadow
? Container(
padding: paddingObject ?? EdgeInsets.all(padding),
width: double.infinity,
decoration: ShapeDecoration(
color: backgroundColor ?? AppColor.background(context),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(borderRadius)),
shadows: showShadow ? [boxShadowR14] : null,
),
child: this,
)
: this;
Widget toShadowContainer(BuildContext context, {bool showShadow = true, double borderRadius = 14, bool withShadow = true, Color? backgroundColor, double padding = 16, EdgeInsets? paddingObject}) =>
withShadow
? Container(
padding: paddingObject ?? EdgeInsets.all(padding),
width: double.infinity,
decoration: ShapeDecoration(
color: backgroundColor ?? AppColor.background(context),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(borderRadius)),
shadows: showShadow ? [boxShadowR14] : null,
),
child: this,
)
: this;
Widget bottomSheetContainer(BuildContext context, {EdgeInsets? padding}) => Container(
clipBehavior: Clip.antiAlias,

@ -304,7 +304,7 @@ class WorkOrderAssignedEmployee {
required this.languageId,
});
dynamic userId;
String userId;
String? userName;
String? email;
int? languageId;
@ -380,7 +380,7 @@ class Activities {
activityStatus = json['activityStatus'] != null ? Lookup.fromJson(json['activityStatus']) : null;
activityMaintenance = json['activityMaintenance'] != null ? ActivityMaintenance.fromJson(json['activityMaintenance']) : null;
if (activityMaintenance != null) {
activityType = 'Maintenance Request';
activityType = 'CM Activity';
}
activitySparePart = json['activitySparePart'] != null ? ActivitySparePart.fromJson(json['activitySparePart']) : null;
@ -527,9 +527,9 @@ class WorkOrderContactPerson {
String? name;
String? employeeId;
String? position;
dynamic extension;
String extension;
String? email;
dynamic mobilePhone;
String mobilePhone;
WorkOrderAssignedEmployee? contactUser;
factory WorkOrderContactPerson.fromJson(Map<String, dynamic> json) {

@ -15,6 +15,7 @@ class AppFilledButton extends StatelessWidget {
final Color? textColor;
final bool showBorder;
final double radius;
final int height;
final bool disableButton;
const AppFilledButton(
@ -25,6 +26,7 @@ class AppFilledButton extends StatelessWidget {
this.icon,
this.fontSize,
this.loading = false,
this.height = 56,
this.showBorder = false,
this.disableButton = false,
this.buttonColor,
@ -36,7 +38,7 @@ class AppFilledButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 56.toScreenHeight,
height: height.toScreenHeight,
width: maxWidth ? double.infinity : null,
alignment: Alignment.center,
decoration: BoxDecoration(

@ -4,6 +4,7 @@ import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/pages/land_page/land_page.dart';
import 'package:test_sa/new_views/swipe_module/dialoge/acknowledge_work_dialog.dart';
import '../app_style/app_color.dart';
@ -12,8 +13,9 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
final List<Widget>? actions;
final Function? onBackPress;
final bool showHomeActionButton;
final VoidCallback? onWillPopScope;
const DefaultAppBar({this.title, this.onBackPress, this.actions, this.showHomeActionButton = false, Key? key}) : super(key: key);
const DefaultAppBar({this.title, this.onBackPress, this.onWillPopScope, this.actions, this.showHomeActionButton = false, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -40,6 +42,18 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
title: Row(
children: [
const Icon(Icons.arrow_back_ios).onPress(() {
if (onWillPopScope != null) {
showDialog(
context: context,
builder: (BuildContext cxt) => AcknowledgeWorkDialog(
onSave: onWillPopScope!,
onDiscard: () {
Navigator.of(cxt).pop();
},
),
);
return;
}
if (onBackPress != null) {
onBackPress!();
} else {

@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/search_all_requests_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
@ -43,6 +45,7 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
@override
Widget build(BuildContext context) {
bool isEngineer = (Provider.of<UserProvider>(context, listen: false).user?.type) == UsersTypes.engineer;
if (search == null) {
search = SearchAllRequestsModel(
requestNumber: SearchByRequestNumberModel(context, controller: TextEditingController()),
@ -59,14 +62,17 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
context.translation.gasRefill: 2,
context.translation.deviceTransfer: 3,
context.translation.preventiveMaintenance: 4,
context.translation.recurrentWo: 5,
};
if (isEngineer) {
types.addAll({context.translation.recurrentWo: 5});
}
final statuses = {
context.translation.allRequests: 0,
"All WO": 0,
context.translation.open: 1,
context.translation.inProgress: 2,
context.translation.completed: 4,
context.translation.closed: 3,
"Canceled": 5,
};
return Scaffold(
appBar: DefaultAppBar(
@ -99,7 +105,7 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
context.translation.requestStatus.heading5(context),
"WO Status".heading5(context),
8.height,
RequestsTypeFilter(
initialValues: search?.statuses ?? [],
@ -116,7 +122,7 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
},
),
16.height,
context.translation.typeOfRequest.heading5(context),
"Type of WO".heading5(context),
8.height,
RequestsTypeFilter(
initialValues: search?.typeTransaction ?? [],
@ -155,7 +161,7 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
],
),
16.height,
"Archived Requests".heading5(context),
"Archived WO".heading5(context),
// 8.height,
Row(
children: [

@ -49,10 +49,11 @@ class PpmItemView extends StatelessWidget {
8.height,
(requestData?.typeTransaction ?? context.translation.ppmRequest).heading5(context),
8.height,
'${context.translation.assetName}: ${requestData!.assetName}'.bodyText(context),
'${context.translation.assetNumber}: ${requestData!.assetNumber}'.bodyText(context),
// '${context.translation.assetSN}: ${request.assetSN}'.bodyText(context),//todo ask ahmed
// '${context.translation.code}: ${request.code}'.bodyText(context),
'${context.translation.requestNo}: ${requestData!.requestNo}'.bodyText(context),
'PM No: ${requestData!.requestNo}'.bodyText(context),
16.height,
Row(
mainAxisSize: MainAxisSize.min,
@ -99,10 +100,11 @@ class PpmItemView extends StatelessWidget {
8.height,
(requestDetails?.nameOfType ?? context.translation.ppmRequest).heading5(context),
8.height,
'${context.translation.assetName}: ${requestDetails!.assetName}'.bodyText(context),
'${context.translation.assetNumber}: ${requestDetails!.assetNo}'.bodyText(context),
'${context.translation.assetSN}: ${requestDetails!.assetSN}'.bodyText(context),
// '${context.translation.code}: ${request.code}'.bodyText(context),
'${context.translation.requestNo}: ${requestDetails!.requestNo}'.bodyText(context),
'PM No: ${requestDetails!.requestNo}'.bodyText(context),
16.height,
Row(
mainAxisSize: MainAxisSize.min,

@ -55,7 +55,7 @@ class ServiceRequestItemView extends StatelessWidget {
'${context.translation.assetName}: ${requestData!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context),
// '${context.translation.assetNumber}: ${request.assetNo}'.bodyText(context),
// '${context.translation.requestType}: ${requestData!.requestTypeName}'.bodyText(context),
'${context.translation.requestNo}: ${requestData!.requestNo}'.bodyText(context),
'CM Number: ${requestData!.requestNo}'.bodyText(context),
if (requestData?.statusName == 'Canceled') ...[
'${context.translation.rejectionReason}: ${requestData!.rejectReason}'.bodyText(context),
],
@ -110,10 +110,12 @@ class ServiceRequestItemView extends StatelessWidget {
8.height,
(requestDetails!.nameOfType ?? context.translation.correctiveMaintenance).heading5(context),
8.height,
'${context.translation.assetName}: ${requestDetails!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context),
// '${context.translation.requestType}: ${requestDetails!.requestType}'.bodyText(context),
'CM Number: ${requestDetails!.requestNo}'.bodyText(context),
'${context.translation.assetNumber}: ${requestDetails!.assetNo}'.bodyText(context),
'${context.translation.requestType}: ${requestDetails!.requestType}'.bodyText(context),
'${context.translation.requestNo}: ${requestDetails!.requestNo}'.bodyText(context),
'${context.translation.assetName}: ${requestDetails!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context),
8.height,
Row(
// mainAxisSize: MainAxisSize.min,

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
class AcknowledgeWorkDialog extends StatelessWidget {
final String? title;
final String? message;
final String? okTitle;
final VoidCallback onSave;
final VoidCallback onDiscard;
const AcknowledgeWorkDialog(
{Key? key, this.title, this.message = "To prevent the risk of losing your changes, Please confirm Save or Discard", this.okTitle, required this.onSave, required this.onDiscard})
: super(key: key);
@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: [
const Text(
"Confirm",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black87, height: 35 / 24, letterSpacing: -0.96),
).paddingOnly(top: 16, bottom: 8),
message != null ? message!.heading5(context).custom(color: AppColor.neutral50) : const SizedBox(),
28.height,
Row(
children: [
AppFilledButton(
label: "Discard",
buttonColor: Colors.white54,
textColor: AppColor.red30,
height: 40,
showBorder: true,
onPressed: () {
Navigator.of(context).pop();
onDiscard();
},
).expanded,
16.width,
AppFilledButton(
label: "Save",
onPressed: () {
Navigator.of(context).pop();
onSave();
},
height: 40,
buttonColor: AppColor.green70,
).expanded,
],
),
],
),
),
);
}
}

@ -6,13 +6,13 @@ import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
class ConfirmDialog extends StatelessWidget {
final String ?title;
final String ?message;
final String ?okTitle;
final VoidCallback ?onTap;
final VoidCallback ?onCloseTap;
final String? title;
final String? message;
final String? okTitle;
final VoidCallback? onTap;
final VoidCallback? onCloseTap;
const ConfirmDialog({Key ?key, this.title, this.message, this.okTitle, this.onTap, this.onCloseTap}) : super(key: key);
const ConfirmDialog({Key? key, this.title, this.message, this.okTitle, this.onTap, this.onCloseTap}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -45,7 +45,7 @@ class ConfirmDialog extends StatelessWidget {
)
],
),
message!=null?message!.heading5(context).custom(color: AppColor.neutral70):const SizedBox(),
message != null ? message!.heading5(context).custom(color: AppColor.neutral70) : const SizedBox(),
28.height,
AppFilledButton(
label: okTitle ?? "OK",

@ -49,7 +49,7 @@ class AssetDetailCard extends StatelessWidget {
]),
6.height,
Text(
context.translation.assetSituation,
"Work Order Details",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
Text(

@ -837,14 +837,14 @@ class ServiceRequestBottomSheet {
}
static bool validateAssetSituation(ServiceRequestDetailProvider requestDetailProvider) {
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel!.equipmentStatus != null) {
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel!.equipmentStatus!.value == 1 || requestDetailProvider.engineerUpdateWorkOrderHelperModel!.equipmentStatus!.value == 2) {
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel!.returnToService == null) {
Fluttertoast.showToast(msg: "Return to service is required ", toastLength: Toast.LENGTH_LONG);
return false;
}
}
}
// if (requestDetailProvider.engineerUpdateWorkOrderHelperModel!.equipmentStatus != null) {
// if (requestDetailProvider.engineerUpdateWorkOrderHelperModel!.equipmentStatus!.value == 1 || requestDetailProvider.engineerUpdateWorkOrderHelperModel!.equipmentStatus!.value == 2) {
// if (requestDetailProvider.engineerUpdateWorkOrderHelperModel!.returnToService == null) {
// Fluttertoast.showToast(msg: "Return to service is required ", toastLength: Toast.LENGTH_LONG);
// return false;
// }
// }
// }
return true;
}

@ -1,4 +1,3 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
@ -65,6 +64,8 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
workOrderDetailCard(context, requestProvider.currentWorkOrder!.data!, _userProvider, requestProvider),
initialVisitCard(requestDetailProvider: requestProvider, userProvider: _userProvider),
assetDetailCard(requestDetailProvider: requestProvider, userProvider: _userProvider),
12.height,
contactInfoCard(context, requestProvider.currentWorkOrder!.data!),
20.height,
],
),
@ -382,6 +383,55 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
).toShadowContainer(context, padding: 0);
}
Widget contactInfoCard(BuildContext context, WorkOrderData workOrder) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Contact Info",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemBuilder: (cxt, index) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${workOrder.workOrderContactPerson[index].name}',
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
Text(
'${context.translation.employeeId}: ${workOrder.workOrderContactPerson[index].employeeId}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.telephone}: ${workOrder.workOrderContactPerson[index].mobilePhone}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'Job: ${workOrder.workOrderContactPerson[index].position}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.email}: ${workOrder.workOrderContactPerson[index].email}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'Extension: ${workOrder.workOrderContactPerson[index].extension}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
],
),
separatorBuilder: (cxt, index) => const Divider().defaultStyle(context),
itemCount: workOrder.workOrderContactPerson.length),
],
).toShadowContainer(context, padding: 16);
}
Widget assetRetiredButton({required BuildContext context}) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.toScreenHeight, vertical: 12.toScreenWidth),

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
@ -215,12 +214,14 @@ class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProv
}
},
),
12.height,
context.translation.solutions.heading6(context).custom(color: AppColor.neutral50),
8.height,
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.solution != null
? requestDetailProvider.engineerUpdateWorkOrderHelperModel!.solution!.bodyText2(context).custom(color: AppColor.neutral120)
: const SizedBox(),
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel?.solution != null) ...[
12.height,
context.translation.solutions.heading6(context).custom(color: AppColor.neutral50),
8.height,
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.solution != null
? requestDetailProvider.engineerUpdateWorkOrderHelperModel!.solution!.bodyText2(context).custom(color: AppColor.neutral120)
: const SizedBox(),
]
],
).toShadowContainer(context).paddingAll(16),
).expanded,

@ -49,7 +49,12 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
bool isUpdate = requestDetailProvider.activityMaintenanceHelperModel?.id != 0;
return Scaffold(
backgroundColor: AppColor.neutral110,
appBar: const DefaultAppBar(title: "CM Activity"),
appBar: DefaultAppBar(
title: "CM Activity",
onWillPopScope: () {
save(requestDetailProvider);
},
),
body: Stack(
children: [
DefaultTabController(
@ -97,48 +102,49 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
label: requestDetailProvider.activityMaintenanceHelperModel?.id != 0 ? context.translation.update : context.translation.addActivity, // Use the dynamic label
buttonColor: AppColor.primary10,
onPressed: () async {
//TODO add this as dropdown not added in design yet Bhaa need to confirm with hussain then.
// requestDetailProvider.activityMaintenanceHelperModel?.lastSituationId = 282;
if (validate(model: requestDetailProvider.activityMaintenanceHelperModel!)) {
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers = requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers ?? [];
requestDetailProvider.activityMaintenanceHelperModel?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers?.add(
ActivityMaintenanceTimers(
id: 0,
startTime: timer.startAt!.toIso8601String(), // Handle potential null
endTime: timer.endAt?.toIso8601String(), // Handle potential null
workingHours: ((durationInSecond) / 60 / 60),
),
);
});
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status = -1;
if (requestDetailProvider.activityMaintenanceHelperModel?.id == 0) {
status = await requestDetailProvider.createActivityMaintenanceRequest();
} else {
status = await requestDetailProvider.updateActivityMaintenance();
}
if (status == 200) {
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
Navigator.pop(context);
Navigator.pop(context);
} else {
Navigator.pop(context);
}
}
// Handle button press
save(requestDetailProvider);
},
),
),
],
),
);
).handlePopScope(context, () {
save(requestDetailProvider);
});
});
}
void save(ServiceRequestDetailProvider requestDetailProvider) async {
if (validate(model: requestDetailProvider.activityMaintenanceHelperModel!)) {
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers = requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers ?? [];
requestDetailProvider.activityMaintenanceHelperModel?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers?.add(
ActivityMaintenanceTimers(
id: 0,
startTime: timer.startAt!.toIso8601String(), // Handle potential null
endTime: timer.endAt?.toIso8601String(), // Handle potential null
workingHours: ((durationInSecond) / 60 / 60),
),
);
});
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status = -1;
if (requestDetailProvider.activityMaintenanceHelperModel?.id == 0) {
status = await requestDetailProvider.createActivityMaintenanceRequest();
} else {
status = await requestDetailProvider.updateActivityMaintenance();
}
if (status == 200) {
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
Navigator.pop(context);
Navigator.pop(context);
} else {
Navigator.pop(context);
}
}
}
bool validate({required ActivityMaintenanceHelperModel model}) {
if (model.activityStatus == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.activityStatus}");

@ -245,7 +245,7 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
controller: _descriptionController,
showSpeechToText: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
labelText: context.translation.description,
labelText: "Engineer Comment",
alignLabelWithHint: true,
showWithoutDecoration: true,
textInputType: TextInputType.multiline,

@ -97,7 +97,7 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
// '${context.translation.expectDate}: ${planPreventiveVisit.expectedDate?.toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.actualDate}: ${planPreventiveVisit.acutalDateOfVisit?.toIso8601String().toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
const Divider().defaultStyle(context),
'${context.translation.engineerName}: ${planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.assignedEmployee}: ${planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.site}: ${planPreventiveVisit.siteName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
'${context.translation.building}: ${planPreventiveVisit.buildingName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
'${context.translation.floor}: ${planPreventiveVisit.floorName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
@ -112,7 +112,7 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: null, planPreventiveVisit: planPreventiveVisit)));
getVisitData();
},
label: context.translation.updateRequest,
label: context.translation.updateWorkOrder,
).paddingAll(16)
]);
}),

@ -41,7 +41,7 @@ class RecurrentTaskInfoWidget extends StatelessWidget {
2.height,
'${context.translation.taskNo}: ${model!.taskNo!}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.site}: ${model!.site!.siteName!}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.assignEngineer}: ${model!.engineer!.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.assignedEmployee}: ${model!.engineer!.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.scheduledDate}: ${model!.scheduleDate!.toMonthYearFormat}'.bodyText2(context).custom(color: AppColor.neutral120),
],
).toShadowContainer(context),

@ -48,7 +48,12 @@ class _RecurrentWorkOrderViewState extends State<RecurrentWorkOrderView> {
Widget build(BuildContext context) {
return Consumer<AllRequestsProvider>(builder: (context, requestProvider, child) {
return Scaffold(
appBar: DefaultAppBar(title: context.translation.recurrentWo),
appBar: DefaultAppBar(
title: context.translation.recurrentWo,
onWillPopScope: () {
_updateTask(context: context, status: 0);
},
),
body: allRequestsProvider!.isLoading
? const ALoading()
: requestProvider.recurrentWoData != null
@ -96,7 +101,9 @@ class _RecurrentWorkOrderViewState extends State<RecurrentWorkOrderView> {
],
)
: NoDataFound(message: context.translation.noDataFound).center,
);
).handlePopScope(context, () {
_updateTask(context: context, status: 0);
});
});
}
}

@ -1,5 +1,4 @@
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -9,7 +8,6 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model.dart';
import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
@ -44,8 +42,7 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
late PpmProvider ppmProvider;
_onSubmit({required int status}) async {
if(ppmProvider.validate()){
if (ppmProvider.validate()) {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
ppmProvider.planPreventiveVisit?.preventiveVisitAttachments = [];
for (var item in ppmProvider.ppmPlanAttachments) {
@ -67,7 +64,7 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
});
await ppmProvider.updateVisitByEngineer(status: status).whenComplete(() {
if(status==1){
if (status == 1) {
AllRequestsProvider allRequestsProvider = Provider.of<AllRequestsProvider>(context, listen: false);
allRequestsProvider.reset();
allRequestsProvider.getAllRequests(context, typeTransaction: 4);
@ -78,8 +75,6 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
Navigator.pop(context);
});
}
}
@override
@ -115,7 +110,12 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColor.neutral110,
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
appBar: DefaultAppBar(
title: context.translation.preventiveMaintenance,
onWillPopScope: () {
_onSubmit(status: 0);
},
),
key: _scaffoldKey,
body: SafeArea(
child: Column(
@ -158,6 +158,7 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
),
),
TabBarView(
physics: const NeverScrollableScrollPhysics(),
children: [
WoInfoForm(
planPreventiveVisit: _planPreventiveVisit,
@ -183,6 +184,24 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
).expanded,
Row(
children: [
if (tabIndex == 1) ...[
AppFilledButton(
buttonColor: _tabController!.index == 0 ? null:AppColor.background(context),
textColor: _tabController!.index == 0 ? null: AppColor.blueStatus(context),
showBorder: true,
disableButton: _tabController!.index == 0,
onPressed: () {
if (_tabController!.index == 0) {
return;
}
_tabController?.animateTo(_tabController!.index - 1);
setState(() {});
return;
},
label: context.translation.back,
).expanded,
8.width,
],
AppFilledButton(
buttonColor: AppColor.white60,
textColor: AppColor.neutral50,
@ -191,7 +210,7 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
},
label: context.translation.save,
).expanded,
16.width,
8.width,
AppFilledButton(
onPressed: () {
if (tabIndex == 0) {
@ -212,6 +231,8 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
],
),
),
);
).handlePopScope(context, () {
_onSubmit(status: 0);
});
}
}

@ -265,7 +265,7 @@ class _WoInfoFormState extends State<WoInfoForm> {
_timerWidget(context, totalWorkingHours),
8.height,
AppTextFormField(
labelText: context.translation.callComments,
labelText: context.translation.comment,
backgroundColor: AppColor.neutral100,
showShadow: false,
initialValue: (widget.planPreventiveVisit.comments ?? "").toString(),

@ -18,7 +18,7 @@ class PendingServiceRequestScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: DefaultAppBar(title: "Pending Requests (${pendingAssetServiceRequest.details!.length})"),
appBar: DefaultAppBar(title: "Pending WOs (${pendingAssetServiceRequest.details!.length})"),
body: ListView.separated(
itemCount: pendingAssetServiceRequest.details!.length,
padding: const EdgeInsets.all(16),

@ -25,7 +25,7 @@ class PendingRequestBottomSheet extends StatelessWidget {
"Alert!".heading4(context),
12.height,
Text(
"${pendingAssetServiceRequest.details!.length} pending service requests found",
"${pendingAssetServiceRequest.details!.length} pending corrective maintenance found",
style: TextStyle(
fontSize: 16.toScreenWidth,
fontWeight: FontWeight.w500,

@ -1213,6 +1213,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.2"
pie_chart:
dependency: "direct main"
description:
name: pie_chart
sha256: "58e6a46999ac938bfa1c3e5be414d6e149f037647197dca03ba3614324c12c82"
url: "https://pub.dev"
source: hosted
version: "5.4.0"
pinput:
dependency: "direct main"
description:
@ -1506,22 +1514,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
syncfusion_flutter_charts:
dependency: "direct main"
description:
name: syncfusion_flutter_charts
sha256: a755274a8786b200b7a05f7414168cd5858871db74d0f1de2e57b20a8aaeb7a4
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_flutter_core:
dependency: transitive
description:
name: syncfusion_flutter_core
sha256: "6e67726b85812afc7105725a23620b876ab7f6b04b8410e211330ffb8c2cdbe8"
url: "https://pub.dev"
source: hosted
version: "26.2.14"
synchronized:
dependency: transitive
description:

@ -79,11 +79,11 @@ dependencies:
image_cropper: ^8.0.2
flutter_timezone: ^3.0.1
device_calendar: ^4.3.3
pie_chart: ^5.4.0
badges: ^3.1.1
# buttons_tabbar: ^1.1.2
flutter_custom_month_picker: ^0.1.3
syncfusion_flutter_charts: ^26.2.14
local_auth: ^2.3.0
google_api_availability: ^5.0.0
huawei_push: ^6.5.0+300

Loading…
Cancel
Save