save and complete api integrated for recurrent task

design_3.0_latest
WaseemAbbasi22 9 months ago
parent 99bcae1dc2
commit d181c81029

@ -80,8 +80,9 @@ class URLs {
static get swipeUrl=> '$_baseUrl/Swipe/Swipe';
static get getSwipeLastTransactionUrl=> '$_baseUrl/Swipe/GetLastTransaction';
static get getSwipeTransactionHistoryUrl=> '$_baseUrl/Swipe/GetTransactions';
static get getRecurrentPlanByIdUrl=> '$_baseUrl/PlanRecurrentTasks/GetPlanRecurrentTaskById';
//Recurrent plan Api...
static get getRecurrentPlanByIdUrl=> '$_baseUrl/PlanRecurrentTasks/GetPlanRecurrentTaskById';
static get updateRecurrentPlanUrl=> '$_baseUrl/PlanRecurrentTasks/UpdateTaskByEngineer';
//service request.....

@ -8,6 +8,7 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/ppm/recurrent_wo.dart';
import 'package:test_sa/models/timer_model.dart';
import '../../../models/search_all_requests_model.dart';
@ -19,6 +20,8 @@ class AllRequestsProvider extends ChangeNotifier {
bool isOverdueLoading = false;
bool isHighPriorityLoading = false;
bool isCalendarLoading = false;
bool isLoading = false;
bool _isFilterRequestLoading = false;
bool _isRequestCategoryLoading = false;
@ -50,12 +53,24 @@ class AllRequestsProvider extends ChangeNotifier {
AllRequestsAndCount? _requestDetailList;
AllRequestsAndCount? get allRequestsAndCount => _allRequestsAndCount;
AllRequestsAndCount? get highPriorityRequests => _highPriorityRequests;
AllRequestsAndCount? get overdueRequests => _overdueRequests;
// AllRequestsAndCount? get openRequests => _openRequests;
// AllRequestsAndCount? get completedRequests => _completedRequests;
AllRequestsAndCount? get requestDetailList => _requestDetailList;
RecurrentWoData? _recurrentWoData;
RecurrentWoData? get recurrentWoData => _recurrentWoData;
set recurrentWoData(RecurrentWoData? value) {
_recurrentWoData = value;
notifyListeners();
}
set requestDetailList(AllRequestsAndCount? value) {
_requestDetailList = value;
notifyListeners();
@ -117,10 +132,9 @@ class AllRequestsProvider extends ChangeNotifier {
SearchAllRequestsModel? searchedModel;
Future<int> getAllRequests(BuildContext context, {int? typeTransaction, SearchAllRequestsModel? search}) async {
print('loading value is $isAllLoading');
if (isAllLoading == true) return -2;
isAllLoading = true;
if (_allRequestsAndCount == null) notifyListeners();
if (_allRequestsAndCount == null) notifyListeners();
Response response;
try {
if (search != null) {
@ -130,7 +144,7 @@ class AllRequestsProvider extends ChangeNotifier {
}
final type = typeTransaction == null
? search?.typeTransaction == null || (search?.typeTransaction?.isEmpty ?? false)
? [1, 2, 3, 4,5]//added 5 to get recurrent wo ...
? [1, 2, 3, 4, 5] //added 5 to get recurrent wo ...
: search!.typeTransaction
: [typeTransaction];
List<int> status = (search?.statuses == null || (search?.statuses?.isEmpty ?? false)) ? (((search?.isArchived ?? false) ? [3] : [1, 2, 4])) : search!.statuses!;
@ -179,23 +193,51 @@ class AllRequestsProvider extends ChangeNotifier {
}
}
Future<RecurrentWo> getRecurrentWoById(BuildContext context, {required int id}) async {
Future<int> getRecurrentWoById({required int id}) async {
isLoading = true;
Response response;
try {
response = await ApiManager.instance.get(URLs.getRecurrentPlanByIdUrl + "?planRecurrentTaskId=$id");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
recurrentWoData = RecurrentWoData.fromJson(json.decode(response.body)["data"]);
notifyListeners();
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
throw (context.translation.failedToCompleteRequest);
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
if (response.statusCode >= 200 && response.statusCode < 300) {
RecurrentWo recurrentWo = RecurrentWo.fromJson(json.decode(response.body));
return recurrentWo;
}
} else {
throw (("${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}"));
Future<int> updateRecurrentWo({required int status}) async {
isLoading = true;
Response response;
try {
response = await ApiManager.instance.post(URLs.updateRecurrentPlanUrl, body: recurrentWoData!.toJson(status: status));
print('response i got back is ${response.body}');
stateCode = response.statusCode;
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
void updateRecurrentWoTimer({TimerModel? timer}) {
recurrentWoData?.recurrentWoTimerModel = timer;
notifyListeners();
}
Future<int> getCalendarRequests({required DateTime from, DateTime? to}) async {
if (isCalendarLoading == true) return -2;
isCalendarLoading = true;

@ -1,4 +1,5 @@
import 'package:test_sa/app_strings/app_asset.dart';
import 'package:test_sa/models/enums/recurrent_task_inspection_data_type.dart';
import 'package:test_sa/models/enums/swipe_type.dart';
import 'package:test_sa/models/enums/work_order_next_step.dart';
@ -94,6 +95,8 @@ extension IntExtensionsWorkOrder on int {
}
}
extension EnumExtensionsSwipeType on SwipeTypeEnum {
int getIntFromSwipeTypeEnum() {
switch (this) {
@ -106,3 +109,15 @@ extension EnumExtensionsSwipeType on SwipeTypeEnum {
}
}
}
extension StringExtensionsRecurrentTaskInpesctionDataType on String {
RecurrentTaskInspectionDataTypeEnum toRecurrentTaskInspectionDataTypeEnum() {
switch (this) {
case 'bool':
return RecurrentTaskInspectionDataTypeEnum.bool;
case 'number':
return RecurrentTaskInspectionDataTypeEnum.number;
default:
return RecurrentTaskInspectionDataTypeEnum.bool;
}
}
}

@ -0,0 +1,4 @@
enum RecurrentTaskInspectionDataTypeEnum {
bool, //bool
number, // number
}

@ -1,3 +1,5 @@
import 'package:test_sa/extensions/enum_extensions.dart';
import 'package:test_sa/models/enums/recurrent_task_inspection_data_type.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/timer_model.dart';
@ -9,16 +11,10 @@ class RecurrentWo {
int? responseCode;
bool? isSuccess;
RecurrentWo(
{this.recurrentWoData,
this.message,
this.title,
this.innerMessage,
this.responseCode,
this.isSuccess});
RecurrentWo({this.recurrentWoData, this.message, this.title, this.innerMessage, this.responseCode, this.isSuccess});
RecurrentWo.fromJson(Map<String, dynamic> json) {
recurrentWoData = json['data'] != null ? RecurrentWoData.fromJson(json['data']) : null;
recurrentWoData = json['data'] != null ? RecurrentWoData.fromJson(json['data']) : null;
message = json['message'];
title = json['title'];
innerMessage = json['innerMessage'];
@ -27,7 +23,7 @@ class RecurrentWo {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
final Map<String, dynamic> data = <String, dynamic>{};
if (recurrentWoData != null) {
data['data'] = recurrentWoData!.toJson();
}
@ -51,75 +47,74 @@ class RecurrentWoData {
Lookup? department;
Lookup? room;
List<PlanRecurrentMedicalTaskRooms>? planRecurrentMedicalTaskRooms;
List<Null>? planRecurrentTaskTimers;
List<PlanRecurrentTaskTimers>? planRecurrentTaskTimers;
TimerModel? recurrentWoTimerModel = TimerModel();
double? totalWorkingHours=0.0;
RecurrentWoData(
{this.id,
this.engineer,
this.scheduleDate,
this.status,
this.site,
this.building,
this.recurrentWoTimerModel,
this.floor,
this.department,
this.room,
this.planRecurrentMedicalTaskRooms,
this.planRecurrentTaskTimers});
this.engineer,
this.scheduleDate,
this.status,
this.site,
this.building,
this.recurrentWoTimerModel,
this.floor,
this.department,
this.room,
this.planRecurrentMedicalTaskRooms,
this.planRecurrentTaskTimers,
this.totalWorkingHours});
RecurrentWoData.fromJson(Map<String, dynamic> json) {
id = json['id'];
engineer = json['engineer'] != null
? new Engineer.fromJson(json['engineer'])
: null;
engineer = json['engineer'] != null ? new Engineer.fromJson(json['engineer']) : null;
scheduleDate = json['scheduleDate'];
status =
json['status'] != null ? Status.fromJson(json['status']) : null;
status = json['status'] != null ? Status.fromJson(json['status']) : null;
site = json['site'] != null ? Site.fromJson(json['site']) : null;
building= json["building"] == null ? null : Lookup.fromJson(json["building"]);
floor= json["floor"] == null ? null : Lookup.fromJson(json["floor"]);
department= json["department"] == null ? null : Lookup.fromJson(json["department"]);
room= json["room"] == null ? null : Lookup.fromJson(json["room"]);
building = json["building"] == null ? null : Lookup.fromJson(json["building"]);
floor = json["floor"] == null ? null : Lookup.fromJson(json["floor"]);
department = json["department"] == null ? null : Lookup.fromJson(json["department"]);
room = json["room"] == null ? null : Lookup.fromJson(json["room"]);
if (json['planRecurrentMedicalTaskRooms'] != null) {
planRecurrentMedicalTaskRooms = <PlanRecurrentMedicalTaskRooms>[];
json['planRecurrentMedicalTaskRooms'].forEach((v) {
planRecurrentMedicalTaskRooms!
.add(PlanRecurrentMedicalTaskRooms.fromJson(v));
planRecurrentMedicalTaskRooms!.add(PlanRecurrentMedicalTaskRooms.fromJson(v));
});
}
if (json['planRecurrentTaskTimers'] != null) {
//TODO match with exact data and replace...
// planRecurrentTaskTimers = <Null>[];
// json['planRecurrentTaskTimers'].forEach((v) {
// planRecurrentTaskTimers!.add(new Null.fromJson(v));
// });
planRecurrentTaskTimers = <PlanRecurrentTaskTimers>[];
json['planRecurrentTaskTimers'].forEach((v) {
planRecurrentTaskTimers?.add(PlanRecurrentTaskTimers.fromJson(v));
});
totalWorkingHours = json['planRecurrentTaskTimers'].fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endTime!).difference(DateTime.parse(item.startTime!)).inSeconds) ?? 0;
}
}
Map<String, dynamic> toJson() {
Map<String, dynamic> toJson({int? status = 0}) {
final Map<String, dynamic> data = <String, dynamic>{};
List taskRoomTabAttributesJson = [];
if (planRecurrentMedicalTaskRooms != null) {
taskRoomTabAttributesJson = planRecurrentMedicalTaskRooms
?.expand((room) => room.planRecurrentMedicalTaskRoomTabs ?? [])
.expand((tab) => tab.planRecurrentMedicalTaskRoomTabAttributes ?? [])
.map((attribute) => attribute.toJson())
.toList() ??
[];
}
data['id'] = id;
if (engineer != null) {
data['engineer'] = engineer!.toJson();
data['statusValue'] = status;
if (planRecurrentTaskTimers != null) {
data['planRecurrentTaskTimers'] = planRecurrentTaskTimers!.map((v) => v.toJson()).toList();
}
data['scheduleDate'] = scheduleDate;
if (status != null) {
data['status'] = status!.toJson();
if (taskRoomTabAttributesJson.isNotEmpty) {
data['attributes'] = taskRoomTabAttributesJson;
}
if (site != null) {
data['site'] = site!.toJson();
else{
data['attributes'] = [];
}
if (planRecurrentMedicalTaskRooms != null) {
data['planRecurrentMedicalTaskRooms'] =
planRecurrentMedicalTaskRooms!.map((v) => v.toJson()).toList();
}
if (planRecurrentTaskTimers != null) {
//TODO match with exact data and replace...
// data['planRecurrentTaskTimers'] =
// this.planRecurrentTaskTimers!.map((v) => v.toJson()).toList();
}
return data;
}
}
@ -131,12 +126,7 @@ class Engineer {
String? employeeId;
int? languageId;
Engineer(
{this.userId,
this.userName,
this.email,
this.employeeId,
this.languageId});
Engineer({this.userId, this.userName, this.email, this.employeeId, this.languageId});
Engineer.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
@ -147,12 +137,12 @@ class Engineer {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userId'] = this.userId;
data['userName'] = this.userName;
data['email'] = this.email;
data['employeeId'] = this.employeeId;
data['languageId'] = this.languageId;
final Map<String, dynamic> data = <String, dynamic>{};
data['userId'] = userId;
data['userName'] = userName;
data['email'] = email;
data['employeeId'] = employeeId;
data['languageId'] = languageId;
return data;
}
}
@ -171,10 +161,10 @@ class Status {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['value'] = this.value;
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['value'] = value;
return data;
}
}
@ -191,9 +181,9 @@ class Site {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['siteName'] = this.siteName;
final Map<String, dynamic> data = {};
data['id'] =id;
data['siteName'] = siteName;
return data;
}
}
@ -203,32 +193,27 @@ class PlanRecurrentMedicalTaskRooms {
Room? room;
List<PlanRecurrentMedicalTaskRoomTabs>? planRecurrentMedicalTaskRoomTabs;
PlanRecurrentMedicalTaskRooms(
{this.id, this.room, this.planRecurrentMedicalTaskRoomTabs});
PlanRecurrentMedicalTaskRooms({this.id, this.room, this.planRecurrentMedicalTaskRoomTabs});
PlanRecurrentMedicalTaskRooms.fromJson(Map<String, dynamic> json) {
id = json['id'];
room = json['room'] != null ? new Room.fromJson(json['room']) : null;
room = json['room'] != null ? Room.fromJson(json['room']) : null;
if (json['planRecurrentMedicalTaskRoomTabs'] != null) {
planRecurrentMedicalTaskRoomTabs = <PlanRecurrentMedicalTaskRoomTabs>[];
json['planRecurrentMedicalTaskRoomTabs'].forEach((v) {
planRecurrentMedicalTaskRoomTabs!
.add(new PlanRecurrentMedicalTaskRoomTabs.fromJson(v));
planRecurrentMedicalTaskRoomTabs!.add(PlanRecurrentMedicalTaskRoomTabs.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
if (this.room != null) {
data['room'] = this.room!.toJson();
final Map<String, dynamic> data = {};
data['id'] = id;
if (room != null) {
data['room'] = room!.toJson();
}
if (this.planRecurrentMedicalTaskRoomTabs != null) {
data['planRecurrentMedicalTaskRoomTabs'] = this
.planRecurrentMedicalTaskRoomTabs!
.map((v) => v.toJson())
.toList();
if (planRecurrentMedicalTaskRoomTabs != null) {
data['planRecurrentMedicalTaskRoomTabs'] = planRecurrentMedicalTaskRoomTabs!.map((v) => v.toJson()).toList();
}
return data;
}
@ -246,9 +231,9 @@ class Room {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['roomId'] = this.roomId;
final Map<String, dynamic> data = {};
data['id'] = id;
data['roomId'] = roomId;
return data;
}
}
@ -257,39 +242,29 @@ class PlanRecurrentMedicalTaskRoomTabs {
int? id;
String? tabName;
int? tabMedicalRoomId;
List<PlanRecurrentMedicalTaskRoomTabAttributes>?
planRecurrentMedicalTaskRoomTabAttributes;
List<PlanRecurrentMedicalTaskRoomTabAttributes>? planRecurrentMedicalTaskRoomTabAttributes;
PlanRecurrentMedicalTaskRoomTabs(
{this.id,
this.tabName,
this.tabMedicalRoomId,
this.planRecurrentMedicalTaskRoomTabAttributes});
PlanRecurrentMedicalTaskRoomTabs({this.id, this.tabName, this.tabMedicalRoomId, this.planRecurrentMedicalTaskRoomTabAttributes});
PlanRecurrentMedicalTaskRoomTabs.fromJson(Map<String, dynamic> json) {
id = json['id'];
tabName = json['tabName'];
tabMedicalRoomId = json['tabMedicalRoomId'];
if (json['planRecurrentMedicalTaskRoomTabAttributes'] != null) {
planRecurrentMedicalTaskRoomTabAttributes =
<PlanRecurrentMedicalTaskRoomTabAttributes>[];
planRecurrentMedicalTaskRoomTabAttributes = <PlanRecurrentMedicalTaskRoomTabAttributes>[];
json['planRecurrentMedicalTaskRoomTabAttributes'].forEach((v) {
planRecurrentMedicalTaskRoomTabAttributes!
.add(new PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(v));
planRecurrentMedicalTaskRoomTabAttributes!.add( PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tabName'] = this.tabName;
data['tabMedicalRoomId'] = this.tabMedicalRoomId;
if (this.planRecurrentMedicalTaskRoomTabAttributes != null) {
data['planRecurrentMedicalTaskRoomTabAttributes'] = this
.planRecurrentMedicalTaskRoomTabAttributes!
.map((v) => v.toJson())
.toList();
final Map<String, dynamic> data = {};
data['id'] = id;
data['tabName'] = tabName;
data['tabMedicalRoomId'] = tabMedicalRoomId;
if (planRecurrentMedicalTaskRoomTabAttributes != null) {
data['planRecurrentMedicalTaskRoomTabAttributes'] = planRecurrentMedicalTaskRoomTabAttributes!.map((v) => v.toJson()).toList();
}
return data;
}
@ -298,27 +273,20 @@ class PlanRecurrentMedicalTaskRoomTabs {
class PlanRecurrentMedicalTaskRoomTabAttributes {
int? id;
Attribute? attribute;
Null? attributeValue;
dynamic attributeValue;
PlanRecurrentMedicalTaskRoomTabAttributes(
{this.id, this.attribute, this.attributeValue});
PlanRecurrentMedicalTaskRoomTabAttributes({this.id, this.attribute, this.attributeValue});
PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(
Map<String, dynamic> json) {
PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(Map<String, dynamic> json) {
id = json['id'];
attribute = json['attribute'] != null
? new Attribute.fromJson(json['attribute'])
: null;
attributeValue = json['attributeValue'];
attribute = json['attribute'] != null ? Attribute.fromJson(json['attribute']) : null;
attributeValue = json['attributeValue'] ?? (json['attribute']['type'] == 'bool' ? (json['attributeValue']?.toString() == 'true') : json['attributeValue']);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
if (this.attribute != null) {
data['attribute'] = this.attribute!.toJson();
}
data['attributeValue'] = this.attributeValue;
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['attributeValue'] =attributeValue!=null? attributeValue.toString():attributeValue;
return data;
}
}
@ -327,20 +295,47 @@ class Attribute {
String? name;
String? type;
String? key;
RecurrentTaskInspectionDataTypeEnum? dataTypeEnum;
Attribute({this.name, this.type, this.key});
Attribute({this.name, this.type, this.key, this.dataTypeEnum});
Attribute.fromJson(Map<String, dynamic> json) {
name = json['name'];
type = json['type'];
dataTypeEnum = json['type'] == null ? null : (json['type'] as String).toRecurrentTaskInspectionDataTypeEnum();
key = json['key'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['type'] = this.type;
data['key'] = this.key;
final Map<String, dynamic> data = <String, dynamic>{};
data['name'] = name;
data['type'] = type;
data['key'] = key;
return data;
}
}
class PlanRecurrentTaskTimers {
int? id;
String? startTime;
String? endTime;
dynamic workingHours;
PlanRecurrentTaskTimers({this.id, this.startTime, this.endTime, this.workingHours});
PlanRecurrentTaskTimers.fromJson(Map<String, dynamic> json) {
id = json['id'];
startTime = json['startTime'];
endTime = json['endTime'];
workingHours = json['workingHours'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['startTime'] = startTime;
data['endTime'] = endTime;
data['workingHours'] = workingHours;
return data;
}
}
}

@ -60,10 +60,12 @@ class AppColor {
static const Color red50 = Color(0xffD02127);
static const Color red60 = Color(0xff8C050A);
static const Color red70 = Color(0xffF63939);
static const Color red80 = Color(0xfffdcdcd);
//green
static const Color green40 = Color(0xffBAFFE1);
static const Color green50 = Color(0xff62BE96);
static const Color green30 = Color(0xffd8efe5);
static const Color green60 = Color(0xff065E38);
static const Color green70 = Color(0xff54C166);
static const Color green15 = Color(0xff157D14);

@ -67,13 +67,9 @@ class RecurrentWoItemView extends StatelessWidget {
),
],
).toShadowContainer(context, withShadow: showShadow).onPress(() async {
print('data i got is ${requestDetails?.id}');
RecurrentWo recurrentWo = await Provider.of<AllRequestsProvider>(context,listen:false).getRecurrentWoById(context, id: requestDetails!.id!);
Navigator.of(context).push(MaterialPageRoute(builder: (_) => RecurrentWorkOrderView( recurrentWo: recurrentWo)));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => RecurrentWorkOrderView(taskId: requestDetails!.id)));
});
}
return SizedBox();
return const SizedBox();
}
}

@ -101,6 +101,7 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
print("timerProgress:$isRunning");
},
onChange: (timer) async {
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel = timer;
return true;
},

@ -101,12 +101,6 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
if (validate(model: requestDetailProvider.activityMaintenanceHelperModel!)) {
ActivityMaintenanceTimers model = ActivityMaintenanceTimers(
id: 0,
startTime: requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel?.startAt!.toIso8601String(), // Handle potential null
endTime: requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel?.endAt?.toIso8601String(), // Handle potential null
workingHours: ((requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel?.durationInSecond ?? 0) / 60 / 60),
);
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers =requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers??[];
requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers?.add(
ActivityMaintenanceTimers(

@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/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/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
@ -13,15 +15,14 @@ import 'package:test_sa/service_request_latest/utilities/service_request_utils.d
import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
class AssetInfoWidget extends StatelessWidget {
class RecurrentTaskAssetInfoWidget extends StatelessWidget {
final RecurrentWoData? model;
final RecurrentWoData? model; // Use `final` since it's a StatelessWidget
AssetInfoWidget({super.key, required this.model});
RecurrentTaskAssetInfoWidget({super.key, required this.model});
@override
Widget build(BuildContext context) {
double totalWorkingHours = 2.0;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -32,54 +33,72 @@ class AssetInfoWidget extends StatelessWidget {
if (model?.status != null)
StatusLabel(
label: model?.status?.name,
textColor: AppColor.getRequestStatusTextColorByName(context,model?.status?.name),
backgroundColor: AppColor.getRequestStatusColorByName(context,model?.status?.name),
textColor: AppColor.getRequestStatusTextColorByName(context, model?.status?.name),
backgroundColor: AppColor.getRequestStatusColorByName(context, model?.status?.name),
),
8.height,
// TODO need to replace this with correct data...
model!.site!.siteName!.bodyText(context).custom(color:AppColor.black10 ),
model!.site!.siteName!.bodyText(context).custom(color: AppColor.black10),
2.height,
'${context.translation.taskNo}: ${model!.site!.id!}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.taskNo}: ${model!.id!}'.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.assignEngineer}: ${model!.engineer!.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.scheduledDate}: ${model!.scheduleDate!.toMonthYearFormat}'.bodyText2(context).custom(color: AppColor.neutral120),
],
).toShadowContainer(context),
12.height,
model!.planRecurrentMedicalTaskRooms!.isEmpty? Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
model!.planRecurrentMedicalTaskRooms!.isEmpty
? Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildingInfoWidget(label: context.translation.department, value: model!.department!.name!.cleanupWhitespace.capitalizeFirstOfEach, context: context),
8.height,
buildingInfoWidget(label: context.translation.floor, value: model!.floor!.name!.cleanupWhitespace.capitalizeFirstOfEach, context: context),
8.height,
buildingInfoWidget(label: context.translation.room, value: model!.room!.name!.cleanupWhitespace.capitalizeFirstOfEach, context: context),
8.height,
_timerWidget(context, model!.totalWorkingHours!)
],
// ],
).toShadowContainer(context, padding: 12)
: _timerWidget(context, model!.totalWorkingHours!).toShadowContainer(context, padding: 12),
],
);
}
Widget _timerWidget(BuildContext context, double totalWorkingHours) {
return Consumer<AllRequestsProvider>(
builder: (context, snapshot,child) {
return Column(
children: [
buildingInfoWidget(label: context.translation.department, value: model!.department!.name!.cleanupWhitespace.capitalizeFirstOfEach,context: context),
8.height,
buildingInfoWidget(label: context.translation.floor, value: model!.floor!.name!.cleanupWhitespace.capitalizeFirstOfEach,context: context),
8.height,
buildingInfoWidget(label: context.translation.room, value: model!.room!.name!.cleanupWhitespace.capitalizeFirstOfEach,context: context),
8.height,
AppTimer(
label: context.translation.timer,
timer: model!.recurrentWoTimerModel,
width:double.infinity,
enabled: model!.recurrentWoTimerModel?.endAt == null,
timer: snapshot.recurrentWoData?.recurrentWoTimerModel,
width: double.infinity,
enabled: snapshot.recurrentWoData?.recurrentWoTimerModel?.endAt == null,
decoration: BoxDecoration(
color: AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
),
timerProgress: (isRunning) {},
onChange: (timer) async {
timer = timer;
snapshot.updateRecurrentWoTimer(timer: timer);
return true;
},
),
// if (totalWorkingHours > 0.0) ...[
11.height,
if (totalWorkingHours > 0.0) ...[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Total Working Time: ",
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: context.isDark ? null : AppColor.neutral20,
fontWeight: FontWeight.w500,
),
),
Text(
" ${ServiceRequestUtils.formatTimerDuration(totalWorkingHours.round())}",
@ -87,39 +106,39 @@ class AssetInfoWidget extends StatelessWidget {
),
],
),
],
8.height,
],
// ],
).toShadowContainer(context,padding: 12):const SizedBox(),
],
);
}
);
}
}
Widget buildingInfoWidget({required String label, required String value, required BuildContext context}) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
label,
style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral120),
),
3.height,
Text(
value,
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black10),
)
],
).toShadowContainer(context, backgroundColor: AppColor.neutral100, borderRadius: 10, paddingObject: EdgeInsets.all(12.toScreenHeight), showShadow: false);
}
Widget buildingInfoWidget({required String label, required String value, required BuildContext context}) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
label,
style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral120),
),
3.height,
Text(
value,
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black10),
)
],
).toShadowContainer(context, backgroundColor: AppColor.neutral100, borderRadius: 10, paddingObject: EdgeInsets.all(12.toScreenHeight), showShadow: false);
}
class DummyModel{
RequestsDetails? request;
Ppm? ppm;
TimerModel? timerModel = TimerModel();
double totalWorkingHours = 2;
class DummyModel {
RequestsDetails? request;
Ppm? ppm;
TimerModel? timerModel = TimerModel();
double totalWorkingHours = 2;
DummyModel(this.request,this.ppm,this.timerModel,this.totalWorkingHours);
DummyModel(this.request, this.ppm, this.timerModel, this.totalWorkingHours);
}

@ -1,10 +1,13 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:test_sa/dashboard_latest/dashboard_view.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/recurrent_task_inspection_data_type.dart';
import 'package:test_sa/models/ppm/recurrent_wo.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
class RoomInspectionCard extends StatefulWidget {
final PlanRecurrentMedicalTaskRoomTabs? inspectionModel;
@ -16,14 +19,11 @@ class RoomInspectionCard extends StatefulWidget {
}
class _RoomInspectionCardState extends State<RoomInspectionCard> {
late List<bool> inspectionValues; // Add a list to store the state of switches
late List<bool> inspectionValues;
@override
void initState() {
super.initState();
inspectionValues = widget.inspectionModel!.planRecurrentMedicalTaskRoomTabAttributes!
.map<bool>((inspectionType) => inspectionType.attributeValue != null)
.toList();
}
@override
@ -31,20 +31,30 @@ class _RoomInspectionCardState extends State<RoomInspectionCard> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.inspectionModel!.tabName!
.bodyText(context)
.custom(color: AppColor.neutral50, fontWeight: FontWeight.w600),
widget.inspectionModel!.tabName!.bodyText(context).custom(color: AppColor.neutral50, fontWeight: FontWeight.w600),
8.height,
Column(
children: widget.inspectionModel!.planRecurrentMedicalTaskRoomTabAttributes
?.asMap()
.entries
.map<Widget>((entry) => inspectionStatusRadioWidget(
index: entry.key,
label: entry.value.attribute!.name??'',
context: context,
))
.toList() ??
children: widget.inspectionModel!.planRecurrentMedicalTaskRoomTabAttributes?.asMap().entries.map<Widget>((entry) {
final model = entry.value;
final attribute = model.attribute;
switch (attribute?.dataTypeEnum) {
case RecurrentTaskInspectionDataTypeEnum.bool:
return inspectionStatusRadioWidget(
index: entry.key,
model: model,
context: context,
);
case RecurrentTaskInspectionDataTypeEnum.number:
return inspectionStatusNumberWidget(
index: entry.key,
model: model,
context: context,
);
default:
return const SizedBox.shrink(); // Handles any unexpected cases gracefully
}
}).toList() ??
[],
)
],
@ -53,39 +63,80 @@ class _RoomInspectionCardState extends State<RoomInspectionCard> {
Widget inspectionStatusRadioWidget({
required int index,
required String label,
required PlanRecurrentMedicalTaskRoomTabAttributes model,
required BuildContext context,
}) {
String status = inspectionValues[index] ? 'Pass' : 'Fail';
bool status = model.attributeValue;
String statusString = status ? 'Pass' : 'Fail';
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
label
.bodyText2(context)
.custom(color: AppColor.white936, fontWeight: FontWeight.w500),
status
.bodyText2(context)
.custom(color: AppColor.neutral120, fontWeight: FontWeight.w500),
model.attribute!.name!.bodyText2(context).custom(color: AppColor.white936, fontWeight: FontWeight.w500),
statusString.bodyText2(context).custom(color: AppColor.neutral120, fontWeight: FontWeight.w500),
],
),
CupertinoSwitch(
thumbColor:
inspectionValues[index] ? AppColor.green50 : AppColor.red30,
activeColor: inspectionValues[index]
? AppColor.green50.withOpacity(0.25)
: AppColor.red30.withOpacity(0.25),
value: inspectionValues[index],
onChanged: (state) {
setState(() {
inspectionValues[index] = state;
});
SizedBox(
height: 24.toScreenHeight,
width: 41.toScreenWidth,
child: CupertinoSwitch(
thumbColor: status ? AppColor.green50 : AppColor.red30,
activeColor: AppColor.green30,
trackColor: AppColor.red80,
value: status,
onChanged: (state) {
setState(() {
model.attributeValue = state;
status = state;
});
},
),
)
],
).paddingOnly(bottom: 12);
}
Widget inspectionStatusNumberWidget({
required int index,
required PlanRecurrentMedicalTaskRoomTabAttributes model,
required BuildContext context,
}) {
final border = OutlineInputBorder(
borderRadius: BorderRadius.circular(4), // Optional: Slight rounding
borderSide: const BorderSide(
color: AppColor.white70, // Border color
width: 1, // 1px border
),
);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
model.attribute!.name!.bodyText2(context).custom(color: AppColor.white936, fontWeight: FontWeight.w500),
TextFormField(
keyboardType: TextInputType.number,
initialValue: model.attributeValue??'',
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 5.toScreenWidth),
filled: true,
fillColor: AppColor.neutral100,
constraints: const BoxConstraints(
maxHeight: 30,
maxWidth: 50,
),
border: border,
enabledBorder: border,
focusedBorder: border,
),
onChanged: (value){
model.attributeValue=value;
},
),
],
).paddingOnly(bottom: 12);
}
}

@ -5,7 +5,6 @@ import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/ppm/recurrent_wo.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/dummy_data.dart';
import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_inspection_card.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
@ -25,57 +24,54 @@ class _RoomTabsWidgetState extends State<RoomTabsWidget> {
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.all(12.toScreenHeight),
padding: EdgeInsets.all(8.toScreenHeight),
height: 57.toScreenHeight,
width: double.infinity,
decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral50 : AppColor.white10,
borderRadius: BorderRadius.circular(10),
),
child: SingleChildScrollView(
child: ListView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: widget.model!.planRecurrentMedicalTaskRooms!.asMap().entries.map((entry) {
final int index = entry.key;
final String label = entry.value.room!.roomId!;
return GestureDetector(
onTap: () {
setState(() {
isLoading = true;
selectedIndex = index;
//TODO replace with api response delay...
Future.delayed(const Duration(seconds: 1)).whenComplete(() {
setState(() {
isLoading = false;
});
// mainAxisAlignment: MainAxisAlignment.spaceAround,
children: widget.model!.planRecurrentMedicalTaskRooms!.asMap().entries.map((entry) {
final int index = entry.key;
final String label = entry.value.room!.roomId!;
return GestureDetector(
onTap: () {
setState(() {
isLoading = true;
selectedIndex = index;
//TODO replace with api response delay...
Future.delayed(const Duration(seconds: 1)).whenComplete(() {
setState(() {
isLoading = false;
});
});
},
child: Container(
margin: EdgeInsets.only(right: 8.toScreenWidth),
padding: EdgeInsets.symmetric(
vertical: 20.toScreenHeight,
horizontal: 30.toScreenWidth,
),
alignment: Alignment.center,
decoration: BoxDecoration(
color: selectedIndex == index ? (context.isDark ? AppColor.neutral60 : AppColor.neutral110) : Colors.transparent,
borderRadius: BorderRadius.circular(7),
),
child: label.bodyText(context).custom(
color: selectedIndex == index ? (context.isDark ? AppColor.white10 : AppColor.black20) : (context.isDark ? AppColor.neutral30 : AppColor.black20),
fontWeight: FontWeight.w600,
),
});
},
child: Container(
// margin: EdgeInsets.only(right: 8.toScreenWidth),
height: 49.toScreenHeight,
padding: EdgeInsets.symmetric(
// vertical: 20.toScreenHeight,
horizontal: 30.toScreenWidth,
),
);
}).toList(),
),
alignment: Alignment.center,
decoration: BoxDecoration(
color: selectedIndex == index ? (context.isDark ? AppColor.neutral60 : AppColor.neutral110) : Colors.transparent,
borderRadius: BorderRadius.circular(7),
),
child: label.bodyText(context).custom(
color:AppColor.white936,
),
),
);
}).toList(),
),
),
12.height,
// Display the Selected Tab Content
isLoading
? SizedBox(height: 120.toScreenHeight, child: const ALoading().center)
: ListView(

@ -1,15 +1,12 @@
import 'package:flutter/cupertino.dart';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/ppm_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/widget_extensions.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/models/ppm/recurrent_wo.dart';
import 'package:test_sa/models/timer_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';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
@ -18,13 +15,14 @@ import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/compone
import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/dummy_data.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import '../../../../../../controllers/providers/api/all_requests_provider.dart';
import 'components/room_tabs_widget.dart';
class RecurrentWorkOrderView extends StatefulWidget {
static const String id = "/recurrent_wo";
final RecurrentWo recurrentWo;
final int? taskId;
const RecurrentWorkOrderView({Key? key, required this.recurrentWo}) : super(key: key);
RecurrentWorkOrderView({Key? key, required this.taskId}) : super(key: key);
@override
_RecurrentWorkOrderViewState createState() {
@ -33,15 +31,12 @@ class RecurrentWorkOrderView extends StatefulWidget {
}
class _RecurrentWorkOrderViewState extends State<RecurrentWorkOrderView> {
UserProvider? userProvider;
TimerModel? timerModel = TimerModel();
PpmProvider? ppmProvider;
// double totalWorkingHours = _requestDetailProvider?.activityMaintenanceHelperModel?.activityMaintenanceTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endTime!).difference(DateTime.parse(item.startTime!)).inSeconds) ?? 0;
double totalWorkingHours = 2.0;
AllRequestsProvider? allRequestsProvider;
@override
void initState() {
allRequestsProvider = Provider.of<AllRequestsProvider>(context, listen: false);
Provider.of<AllRequestsProvider>(context, listen: false).getRecurrentWoById(id: widget.taskId!);
super.initState();
}
@ -52,75 +47,102 @@ class _RecurrentWorkOrderViewState extends State<RecurrentWorkOrderView> {
@override
Widget build(BuildContext context) {
userProvider ??= Provider.of<UserProvider>(context, listen: false);
ppmProvider ??= Provider.of<PpmProvider>(context, listen: false);
print('data i got is ${widget.recurrentWo.recurrentWoData?.toJson()}');
RoomTabs.getRoomTabs();
return Scaffold(
appBar: DefaultAppBar(title: context.translation.recurrentWo),
//TODO refactor this after getting api...
body: widget.recurrentWo.recurrentWoData != null
? Stack(
children: [
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AssetInfoWidget(model: widget.recurrentWo.recurrentWoData),
16.height,
widget.recurrentWo.recurrentWoData!.planRecurrentMedicalTaskRooms!.isNotEmpty
? RoomTabsWidget(
model: widget.recurrentWo.recurrentWoData,
)
: const SizedBox(),
],
).paddingAll(12),
).paddingOnly(bottom: 85),
FooterActionButton.footerContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
return Consumer<AllRequestsProvider>(builder: (context, requestProvider, child) {
return Scaffold(
appBar: DefaultAppBar(title: context.translation.recurrentWo),
body: allRequestsProvider!.isLoading
? const ALoading()
: requestProvider.recurrentWoData != null
? Stack(
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: () async {
print('save clicked...');
},
).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () async {
print('complete clicked...');
},
).expanded,
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RecurrentTaskAssetInfoWidget(model: requestProvider.recurrentWoData),
// 8.height,
requestProvider.recurrentWoData!.planRecurrentMedicalTaskRooms!.isNotEmpty
? Column(
children: [
8.height,
RoomTabsWidget(
model: requestProvider.recurrentWoData,
),
],
)
: const SizedBox(),
],
).paddingAll(12),
).paddingOnly(bottom: 85),
FooterActionButton.footerContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: () => _updateTask(
context: context,
status: 0,
),
).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () => _updateTask(
context: context,
status: 1,
),
).expanded,
],
),
),
],
),
),
],
)
: NoDataFound(message: context.translation.noDataFound).center,
);
)
: NoDataFound(message: context.translation.noDataFound).center,
);
});
}
}
class RoomTabs {
String label;
int tag;
void _updateTask({required BuildContext context, required int status}) async {
AllRequestsProvider allRequestsProvider = Provider.of<AllRequestsProvider>(context, listen: false);
if(validate(model: allRequestsProvider.recurrentWoData!)){
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers = allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers ?? [];
final workingHours = allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt == null ? 0 : (allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt ?? DateTime.now()).difference(allRequestsProvider.recurrentWoData!.recurrentWoTimerModel!.startAt!).inSeconds;
print('working hours is ${workingHours}');
return;
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers?.add(
PlanRecurrentTaskTimers(
id: 0,
startTime: allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt?.toIso8601String(),
endTime: allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.endAt?.toIso8601String(),
workingHours: ((allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.durationInSecond ?? 0) / 60 / 60),
),
);
await allRequestsProvider.updateRecurrentWo(
status: status,
);
Navigator.pop(context);
}
RoomTabs({
required this.label,
required this.tag,
});
static List<RoomTabs> getRoomTabs() {
List<RoomTabs> roomTabs = [];
for (int i = 0; i < DummyData.roomData.length; i++) {
roomTabs.add(RoomTabs(label: DummyData.roomData[i]['name'], tag: i));
}
return roomTabs;
}
bool validate({required RecurrentWoData model}) {
if (model.recurrentWoTimerModel?.startAt == null) {
Fluttertoast.showToast(msg: "Working Hours Required");
return false;
}
if (model.recurrentWoTimerModel?.endAt == null) {
Fluttertoast.showToast(msg: "Please Stop The Timer");
return false;
}
return true;
}

Loading…
Cancel
Save