integrating api in new flow

design_3.0_latest
muhammad.abbasi 1 year ago
parent acbf33e2a2
commit e8dc052d02

@ -1,12 +1,12 @@
class AppAsset{
static String loginTopBg = 'assets/images/login_top_bg.png';
static String askOtpIcon = 'assets/images/ask_otp_icon.svg';
static String askRequesterIcon = 'assets/images/ask_requester_icon.svg';
static String scanQrIcon = 'assets/images/scan_qr_icon.svg';
static String takeDevicePhotoIcon = 'assets/images/take_device_photo_icon.svg';
static String maintenanceIcon = 'assets/images/maintenance_icon.svg';
static String askOtpIcon = 'ask_otp_icon';
static String askRequesterIcon = 'ask_requester_icon';
static String scanQrIcon = 'scan_qr_icon';
static String takeDevicePhotoIcon = 'take_device_photo_icon';
static String maintenanceIcon = 'maintenance_icon';
static String retiredAssetIcon = 'assets/images/retired_asset_icon.svg';
static String sparePartIcon = 'assets/images/spare_part_icon.svg';
static String sparePartIcon = 'spare_part_icon';
static String editIcon = 'assets/images/edit_icon.svg';
static String deleteIcon = 'assets/images/delete_icon.svg';
static String overDueIcon = 'assets/images/overdue.svg';

@ -25,6 +25,12 @@ class URLs {
static get getSites => "$_baseUrl/Customer/GetCustomers"; // get
static get getSitesAutoComplete => "$_baseUrl/Customer/GetCustomersAutoComplete"; // get
static get getSiteAutoCompleteWithoutConditionSites => "$_baseUrl/Customer/GetCustomersAutoCompleteWithoutConditionSites"; // get
static get getDepartments => "$_baseUrl/Customer/GetDepartmentLookup"; // get
static get getAssets => "$_baseUrl/Asset/GetAssets"; // get
static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get
static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2
static get getAllRequestsAndCount => "$_baseUrl/CallRequest/GetAllRequestsAndCount"; // get
//service request new flow urls.
static get nurseDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseCount';
static get nurseDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseDetails';
static get nurseRejectUrl=> '$_baseUrl/ServiceRequest/NurseReject';
@ -45,12 +51,9 @@ class URLs {
static get createWorkOrderUrl=> '$_baseUrl/ServiceRequest/CreateWorkOrder';
static get updateActivitySparePartUrl=> '$_baseUrl/ServiceRequest/UpdateActivitySparePart';
static get assignEngineerToWorkOrderUrl=> '$_baseUrl/ServiceRequest/AssignEngineerToWorkOrder';
static get getDepartments => "$_baseUrl/Customer/GetDepartmentLookup"; // get
static get getAssets => "$_baseUrl/Asset/GetAssets"; // get
static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get
static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2
static get getAllRequestsAndCount => "$_baseUrl/CallRequest/GetAllRequestsAndCount"; // get
static get getArrivalVerificationTypeUrl=> '$_baseUrl/ArrivalVerificationType/GetArrivalVerificationType';
static get sendOtpUrl=> '$_baseUrl/SmsNotification/SendOTP/';
static get verifyOtpUrl=> '$_baseUrl/SmsNotification/VerifyOTP/';
// 08051
static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // get
static get getServiceRequestById => "$_baseUrl/CallRequest/GetCallRequestById"; // get
@ -102,7 +105,11 @@ class URLs {
static get getPpmElectricalSafety => "$_baseUrl/Lookups/GetLookup?lookupEnum=480"; // get for ppm po reason, in mobile there is no use of it.
static get getPpmTaskStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=403"; // get for ppm po reason, in mobile there is no use of it.
static get getPpmService => "$_baseUrl/Lookups/GetLookup?lookupEnum=34"; // get for ppm po reason, in mobile there is no use of it.
static get getServiceReportReasons => "$_baseUrl/Lookups/GetLookupReason?lookupEnum=505"; // get // for service
static get getServiceReportReasons => "$_baseUrl/Lookups/GetLookupReason?lookupEnum=505";
//TODO use this for testing ahmed create new apis for that
static get getServiceReportReasonsTest => "$_baseUrl/Lookups/GetLookup?lookupEnum=505";
static get getServiceReportRetirementTypeTest => "$_baseUrl/Lookups/GetLookup?lookupEnum=415";
static get getServiceReportTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=501"; // get
static get getServiceReportTypesForWO => "$_baseUrl/Lookups/GetLookup?lookupEnum=34"; // get
static get getServiceReportStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=521"; // get

@ -92,6 +92,7 @@ class PartsProvider extends ChangeNotifier {
} else {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {"partName": partName, "assetId": assetId});
}
print('response of get PartNo i got is ${response.body}');
List<SparePart> page = [];
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received

@ -423,6 +423,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
Future<CallRequest?> getCallRequestForWorkOrder({required String callId}) async {
Response response;
print('call id i got is ${callId}');
try {
response = await ApiManager.instance.get(URLs.getCallRequestForWorkOrder + "?callId=$callId");
stateCode = response.statusCode;

@ -0,0 +1,63 @@
import 'package:test_sa/models/enums/work_order_next_step.dart';
extension EnumExtensionsWorkOrder on WorkOrderNextStepEnum {
int getIntFromWorkOrderNextStepEnum() {
switch (this) {
case WorkOrderNextStepEnum.onlyView:
return 2;
case WorkOrderNextStepEnum.markedAsFixed:
return 3;
case WorkOrderNextStepEnum.nTakeAction:
return 5;
case WorkOrderNextStepEnum.eRejectAccept:
return 9;
case WorkOrderNextStepEnum.eFixRemotelyNeedVisit:
return 12;
case WorkOrderNextStepEnum.eArrived:
return 15;
case WorkOrderNextStepEnum.verifyAssetDetail:
return 16;
case WorkOrderNextStepEnum.activity:
return 17;
case WorkOrderNextStepEnum.endWorkFlow:
return 22;
case WorkOrderNextStepEnum.assetRetirementManagementApproval:
return 26;
}
}
}
extension IntExtensionsWorkOrder on int {
WorkOrderNextStepEnum toWorkOrderNextStepEnum() {
switch (this) {
case 2:
return WorkOrderNextStepEnum.onlyView;
case 3:
return WorkOrderNextStepEnum.markedAsFixed;
case 5:
return WorkOrderNextStepEnum.nTakeAction;
case 9:
return WorkOrderNextStepEnum.eRejectAccept;
case 12:
return WorkOrderNextStepEnum.eFixRemotelyNeedVisit;
case 15:
return WorkOrderNextStepEnum.eArrived;
case 16:
return WorkOrderNextStepEnum.verifyAssetDetail;
case 17:
return WorkOrderNextStepEnum.activity;
case 22:
return WorkOrderNextStepEnum.endWorkFlow;
case 26:
return WorkOrderNextStepEnum.assetRetirementManagementApproval;
default:
return WorkOrderNextStepEnum.onlyView;
}
}
}

@ -9,6 +9,8 @@
"done": "تم",
"exit": "إغلاق",
"requestDetails": "تفاصيل الطلب",
"retirementType": "نوع التقاعد",
"assetRetiredPendingOpManagementApproval": "تم تقاعد الأصل. في انتظار موافقة إدارة العمليات",
"historyLogs": "سجلات التاريخ",
"exitAlert": "هل انت متاكد من رغبتك في إغلاق التطبيق؟",
"signOut": "تسجيل الخروج",

@ -9,11 +9,13 @@
"done": "Done",
"exit": "Exit",
"exitAlert": "Are you sure you want to exit?",
"assetRetiredPendingOpManagementApproval": "Asset Retired. Pending OP Management Approval",
"signOut": "Sign Out",
"logoutAlert": "Are you sure you want to Sign Out?",
"language": "English",
"name": "Name",
"email": "Email",
"retirementType": "Retirement Type",
"phoneNumber": "Phone Number",
"password": "Password",
"confirmPassword": "Confirm Password",

@ -52,6 +52,7 @@ import 'package:test_sa/providers/service_request_providers/priority_provider.da
import 'package:test_sa/providers/service_request_providers/requested_through_provider.dart';
import 'package:test_sa/providers/service_request_providers/type_of_request_provider.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/providers/work_order/retirement_type_provider.dart';
import 'package:test_sa/providers/work_order/service_type_provider.dart';
import 'package:test_sa/providers/work_order/supplier_engineer_provider.dart';
import 'package:test_sa/providers/work_order/vendor_provider.dart';
@ -139,6 +140,7 @@ class MyApp extends StatelessWidget {
// ChangeNotifierProvider(create: (_) => PreventiveMaintenanceVisitsProvider()),
ChangeNotifierProvider(create: (_) => PpmProvider()),
ChangeNotifierProvider(create: (_) => PartsProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => ServiceReportReasonsProvider()),
//ChangeNotifierProvider(create: (_) => ServiceReportStatusProvider()),
@ -147,6 +149,7 @@ class MyApp extends StatelessWidget {
//ChangeNotifierProvider(create: (_) => ServiceReportTypesProvider()),
ChangeNotifierProvider(create: (_) => ServiceStatusProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportLastCallsProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => GasCylinderSizesProvider()),
///todo deleted
@ -156,6 +159,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => GasRefillProvider()),
ChangeNotifierProvider(create: (_) => AssetTransferProvider()),
ChangeNotifierProvider(create: (_) => AssetTransferStatusProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => AssignedToProvider()),
///todo deleted
@ -180,6 +184,7 @@ class MyApp extends StatelessWidget {
//ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportRepairLocationProvider()),
ChangeNotifierProvider(create: (_) => ServiceRequestFaultDescriptionProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => ServiceReportVisitOperatorProvider()),
///todo deleted
@ -196,10 +201,13 @@ class MyApp extends StatelessWidget {
/// Loan availability not required
ChangeNotifierProvider(create: (_) => LoanAvailabilityProvider()),
ChangeNotifierProvider(create: (_) => ReasonProvider()),
ChangeNotifierProvider(create: (_) => RetirementTypeProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => AssetTypesProvider()),
ChangeNotifierProvider(create: (_) => ServiceTypeProvider()),
ChangeNotifierProvider(create: (_) => PPMVisitStatusProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => PentryTaskStatusProvider()),
ChangeNotifierProvider(create: (_) => PPMDeviceStatusProvider()),
@ -209,6 +217,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => PpmServiceProvider()),
ChangeNotifierProvider(create: (_) => CommentsProvider()),
ChangeNotifierProvider(create: (_) => GasRefillCommentsProvider()),
///todo deleted
//ChangeNotifierProvider(create: (_) => RequestStatusProvider()),
ChangeNotifierProvider(create: (_) => VendorProvider()),
@ -233,19 +242,20 @@ class MyApp extends StatelessWidget {
routes: {
SplashPage.routeName: (_) => const SplashPage(),
LoginPage.routeName: (_) => const LoginPage(),
///todo deleted
//old.LandPage.id: (_) => const old.LandPage(),
LandPage.routeName: (_) => const LandPage(),
NewGasRefillRequestPage.routeName: (_) => const NewGasRefillRequestPage(),
ServiceRequestsPage.id: (_) => const ServiceRequestsPage(),
//ReportIssuesPage.id: (_) => ReportIssuesPage(),
RequestGasRefill.id: (_) => const RequestGasRefill(),
CreateServiceRequestPage.id: (_) => const CreateServiceRequestPage(),
// SingleHospitalPicker.id: (_) => SingleHospitalPicker(),
RequestGasRefill.id: (_) => const RequestGasRefill(),
CreateServiceRequestPage.id: (_) => const CreateServiceRequestPage(),
// SingleHospitalPicker.id: (_) => SingleHospitalPicker(),
MyAssetsPage.id: (_) => const MyAssetsPage(),
SingleDepartmentPicker.id: (_) => const SingleDepartmentPicker(),
NotificationsPage.id: (_) => const NotificationsPage(),
// FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(),
// FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(),
// PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
PpmPage.id: (_) => const PpmPage(),
TrackGasRefillPage.id: (_) => const TrackGasRefillPage(),
@ -254,13 +264,13 @@ class MyApp extends StatelessWidget {
// todo remove this class after work
// SearchSubWorkOrderPage.id: (_) => const SearchSubWorkOrderPage(),
CreateSubWorkOrderPage.id: (_) => const CreateSubWorkOrderPage(),
CreateSubWorkOrderPage.id: (_) => const CreateSubWorkOrderPage(),
WorkOrderListPage.id: (_) => WorkOrderListPage(),
AssetDetailPage.id: (_) => const AssetDetailPage(),
AssetSearchScreen.id: (_) => const AssetSearchScreen(),
AssetFilterScreen.id: (_) => const AssetFilterScreen(),
WorkOrderDetailsPage.id: (_) => const WorkOrderDetailsPage(),
UpdateServiceRequestPage.id: (_) => const UpdateServiceRequestPage(),
AssetSearchScreen.id: (_) => const AssetSearchScreen(),
AssetFilterScreen.id: (_) => const AssetFilterScreen(),
WorkOrderDetailsPage.id: (_) => const WorkOrderDetailsPage(),
UpdateServiceRequestPage.id: (_) => const UpdateServiceRequestPage(),
SettingsPage.id: (_) => const SettingsPage(),
ProfilePage.id: (_) => const ProfilePage(),
ReportBugPage.id: (_) => const ReportBugPage(),

@ -0,0 +1,12 @@
enum WorkOrderNextStepEnum {
onlyView, // 2
markedAsFixed, // 3
nTakeAction, // 5
eRejectAccept, // 9
eFixRemotelyNeedVisit, // 12
eArrived, // 15
verifyAssetDetail, // 16
activity, // 17
endWorkFlow, // 22
assetRetirementManagementApproval, //26
}

@ -1,42 +1,28 @@
class ActivityAssetRetiredModel {
import 'package:test_sa/models/lookup.dart';
class AssetRetiredHelperModel {
int? id;
int? workOrderId;
int? retirmentReasonId;
Lookup? retirmentReason;
String? retirementComment;
List<ActivityAssetToBeRetiredAttachments>?
activityAssetToBeRetiredAttachments;
activityAssetToBeRetiredAttachments=[];
ActivityAssetRetiredModel(
AssetRetiredHelperModel(
{this.id,
this.workOrderId,
this.retirmentReasonId,
this.retirmentReason,
this.retirementComment,
this.activityAssetToBeRetiredAttachments});
ActivityAssetRetiredModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
workOrderId = json['workOrderId'];
retirmentReasonId = json['retirmentReasonId'];
retirementComment = json['retirementComment'];
if (json['activityAssetToBeRetiredAttachments'] != null) {
activityAssetToBeRetiredAttachments =
<ActivityAssetToBeRetiredAttachments>[];
json['activityAssetToBeRetiredAttachments'].forEach((v) {
activityAssetToBeRetiredAttachments!
.add( ActivityAssetToBeRetiredAttachments.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['workOrderId'] = workOrderId;
data['retirmentReasonId'] = retirmentReasonId;
data['retirmentReasonId'] = retirmentReason?.id;
data['retirementComment'] = retirementComment;
if (activityAssetToBeRetiredAttachments != null) {
data['activityAssetToBeRetiredAttachments'] = this
.activityAssetToBeRetiredAttachments!
data['activityAssetToBeRetiredAttachments'] = activityAssetToBeRetiredAttachments!
.map((v) => v.toJson())
.toList();
}
@ -47,14 +33,7 @@ class ActivityAssetRetiredModel {
class ActivityAssetToBeRetiredAttachments {
int? id;
String? name;
ActivityAssetToBeRetiredAttachments({this.id, this.name});
ActivityAssetToBeRetiredAttachments.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;

@ -1,37 +1,29 @@
class ActivitySparePartModel {
import 'package:test_sa/models/service_request/spare_parts.dart';
class SparePartHelperModel {
int? id;
int? workOrderId;
int? partCatalogItemId;int? quantity;
int? partCatalogItemId;
SparePart? sparePart;
num? quantity;
String? comment;
List<SparePartAttachments>? sparePartAttachments;
ActivitySparePartModel({
SparePartHelperModel({
this.id,
this.workOrderId,
this.partCatalogItemId,
this.quantity,
this.sparePart,
this.comment,this.sparePartAttachments,
});
ActivitySparePartModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
workOrderId = json['workOrderId'];
partCatalogItemId = json['partCatalogItemId'];
quantity = json['quantity'];
comment = json['comment'];
if (json['acitiySparePartAttachments'] != null) {
sparePartAttachments = <SparePartAttachments>[];
json['acitiySparePartAttachments'].forEach((v) {
sparePartAttachments!.add(SparePartAttachments.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['workOrderId'] = workOrderId;
data['partCatalogItemId'] = partCatalogItemId;
data['partCatalogItemId'] = sparePart?.id;
data['quantity'] = quantity;
data['comment'] = comment;
if (sparePartAttachments != null) {

@ -1,18 +0,0 @@
class FixRemotely {
int? workOrderId;
DateTime? startDate;
DateTime? endDate;
int? workingHour;
String? comment;
FixRemotely({this.workOrderId, this.startDate, this.endDate, this.workingHour, this.comment});
factory FixRemotely.fromJson(Map<String, dynamic> json) {
return FixRemotely(
workOrderId: json['workOrderId'], startDate: DateTime.tryParse(json['startDate']), endDate: DateTime.tryParse(json['endDate']), workingHour: json['workingHour'], comment: json['comment']);
}
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'startDate': startDate?.toIso8601String(), 'endDate': endDate?.toIso8601String(), 'workingHour': workingHour, 'comment': comment};
}
}

@ -1,14 +0,0 @@
class MarkAsFixed {
int? workOrderId;
String? feedback;
MarkAsFixed({this.workOrderId, this.feedback});
factory MarkAsFixed.fromJson(Map<String, dynamic> json) {
return MarkAsFixed(workOrderId: json['workOrderId'], feedback: json['feedback']);
}
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'feedback': feedback};
}
}

@ -1,15 +0,0 @@
class NeedVisit {
int? workOrderId;
DateTime? visitDate;
String? comment;
NeedVisit({this.workOrderId, this.visitDate, this.comment});
factory NeedVisit.fromJson(Map<String, dynamic> json) {
return NeedVisit(workOrderId: json['workOrderId'], visitDate: DateTime.tryParse(json['visitDate']), comment: json['comment']);
}
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'visitDate': visitDate?.toIso8601String(), 'comment': comment};
}
}

@ -1,11 +0,0 @@
class NurseActionModel {
int? workOrderId;
String? feedback;
String? signatureNurse;
NurseActionModel({this.workOrderId, this.feedback, this.signatureNurse});
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'feedback': feedback, 'signatureNurse': signatureNurse};
}
}

@ -0,0 +1,143 @@
import 'package:test_sa/models/lookup.dart';
import '../../new_models/work_order_detail_model.dart';
class FixRemotelyHelperModel {
int? workOrderId;
DateTime? startDate;
DateTime? endDate;
int? workingHour;
String? comment;
FixRemotelyHelperModel({this.workOrderId, this.startDate, this.endDate, this.workingHour, this.comment});
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'startDate': startDate?.toIso8601String(), 'endDate': endDate?.toIso8601String(), 'workingHour': workingHour, 'comment': comment};
}
}
class WorkOrderHelperModel {
int? assetId;
int? equipmentStatusId;
int? priorityId;
int? problemDescriptionId;
String? comments;
String? voiceNote;
List<WorkOrderAttachments>? workOrderAttachments;
WorkOrderHelperModel(
{this.assetId,
this.equipmentStatusId,
this.priorityId,
this.problemDescriptionId,
this.comments,
this.voiceNote,
this.workOrderAttachments});
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['assetId'] = assetId;
data['equipmentStatusId'] = equipmentStatusId;
data['priorityId'] = priorityId;
data['problemDescriptionId'] = problemDescriptionId;
data['comments'] = comments;
data['voiceNote'] = voiceNote;
if (workOrderAttachments != null) {
data['workOrderAttachments'] =
workOrderAttachments!.map((v) => v.toJson()).toList();
}
return data;
}
}
class WorkOrderAttachments {
int? id;
String? name;
WorkOrderAttachments({this.id, this.name});
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
return data;
}
}
class EngineerUpdateWorkOrderHelperModel {
int? workOrderId;
Lookup?equipmentStatus;
String? returnToService;
Lookup? serviceType;
Lookup? loanAvailability;
num?loanAssetId;
WorkOrderAsset? loanAsset;
Lookup? failureReason;
Lookup? faultDescription;
String? solution;
EngineerUpdateWorkOrderHelperModel(
{this.workOrderId,
this.equipmentStatus,
this.failureReason,
this.faultDescription,
this.loanAvailability,
this.loanAssetId,
this.loanAsset,
this.serviceType,
this.solution,
this.returnToService,
});
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['workOrderId'] = workOrderId;
data['equipmentStatusId'] = equipmentStatus?.id;
data['returnToService'] = returnToService;
//TODO Bhaa need to confirm about this for testing use internal id 65
data['serviceTypeId'] = serviceType?.id;
data['serviceTypeId'] = 65;
data['loanAvailabilityId'] = loanAvailability?.id;
data['loanAssetId'] = loanAsset?.id;
data['failureReasonId'] = failureReason?.id;
data['faultDescriptionId'] = faultDescription?.id;
data['solution'] = solution;
return data;
}
}
class NurseActionHelperModel {
int? workOrderId;
String? feedback;
String? signatureNurse;
NurseActionHelperModel({this.workOrderId, this.feedback, this.signatureNurse});
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'feedback': feedback, 'signatureNurse': signatureNurse};
}
}
class NeedVisitHelperModel {
int? workOrderId;
DateTime? visitDate;
String? comment;
NeedVisitHelperModel({this.workOrderId, this.visitDate, this.comment});
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'visitDate': visitDate?.toIso8601String(), 'comment': comment};
}
}
class EngineerRejectHelperModel {
int? workOrderId;
String? feedback;
int? rejectReasonId;
Lookup? rejectionReason;
EngineerRejectHelperModel({this.workOrderId, this.feedback, this.rejectReasonId,this.rejectionReason});
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'feedback': feedback, 'rejectReasonId': rejectReasonId};
}
}

@ -1,116 +0,0 @@
class WorkOrderHModel {
int? assetId;
int? equipmentStatusId;
int? priorityId;
int? problemDescriptionId;
String? comments;
String? voiceNote;
List<WorkOrderAttachments>? workOrderAttachments;
WorkOrderHModel(
{this.assetId,
this.equipmentStatusId,
this.priorityId,
this.problemDescriptionId,
this.comments,
this.voiceNote,
this.workOrderAttachments});
WorkOrderHModel.fromJson(Map<String, dynamic> json) {
assetId = json['assetId'];
equipmentStatusId = json['equipmentStatusId'];
priorityId = json['priorityId'];
problemDescriptionId = json['problemDescriptionId'];
comments = json['comments'];
voiceNote = json['voiceNote'];
if (json['workOrderAttachments'] != null) {
workOrderAttachments = <WorkOrderAttachments>[];
json['workOrderAttachments'].forEach((v) {
workOrderAttachments!.add( WorkOrderAttachments.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['assetId'] = assetId;
data['equipmentStatusId'] = equipmentStatusId;
data['priorityId'] = priorityId;
data['problemDescriptionId'] = problemDescriptionId;
data['comments'] = comments;
data['voiceNote'] = voiceNote;
if (workOrderAttachments != null) {
data['workOrderAttachments'] =
workOrderAttachments!.map((v) => v.toJson()).toList();
}
return data;
}
}
class WorkOrderAttachments {
int? id;
String? name;
WorkOrderAttachments({this.id, this.name});
WorkOrderAttachments.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
return data;
}
}
class EngineerUpdateWorkOrderHModel {
int? workOrderId;
int? equipmentStatusId;
String? returnToService;
int? serviceTypeId;
int? loanAvailabilityId;
int? loanAssetId;
int? failureReasonId;
int? faultDescriptionId;
String? solution;
EngineerUpdateWorkOrderHModel(
{this.workOrderId,
this.equipmentStatusId,
this.returnToService,
this.serviceTypeId,
this.loanAvailabilityId,
this.loanAssetId,
this.failureReasonId,
this.faultDescriptionId,
this.solution});
EngineerUpdateWorkOrderHModel.fromJson(Map<String, dynamic> json) {
workOrderId = json['workOrderId'];
equipmentStatusId = json['equipmentStatusId'];
returnToService = json['returnToService'];
serviceTypeId = json['serviceTypeId'];
loanAvailabilityId = json['loanAvailabilityId'];
loanAssetId = json['loanAssetId'];
failureReasonId = json['failureReasonId'];
faultDescriptionId = json['faultDescriptionId'];
solution = json['solution'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['workOrderId'] = workOrderId;
data['equipmentStatusId'] = equipmentStatusId;
data['returnToService'] = returnToService;
data['serviceTypeId'] = serviceTypeId;
data['loanAvailabilityId'] = loanAvailabilityId;
data['loanAssetId'] = loanAssetId;
data['failureReasonId'] = failureReasonId;
data['faultDescriptionId'] = faultDescriptionId;
data['solution'] = solution;
return data;
}
}

@ -1,11 +1,15 @@
import 'package:test_sa/extensions/enum_extensions.dart';
import 'package:test_sa/models/enums/work_order_next_step.dart';
import 'base.dart';
class Lookup extends Base {
int? id; // Now nullable
int? value; // Now nullable
WorkOrderNextStepEnum? workOrderNextStepEnum; // Now nullable
String? name; // Now nullable
Lookup({this.id, this.value, this.name}) : super(identifier: id?.toString(), name: name);
Lookup({this.id, this.value, this.name, this.workOrderNextStepEnum}) : super(identifier: id?.toString(), name: name);
@override
bool operator ==(Object other) => identical(this, other) || other is Lookup && ((value != null && value == other.value) || (id != null && id == other.id));
@ -37,6 +41,7 @@ class Lookup extends Base {
if(parsedJson==null) return Lookup();
return Lookup(
name: parsedJson["name"],
workOrderNextStepEnum: parsedJson["value"] == null ? null : (parsedJson["value"] as int).toWorkOrderNextStepEnum(),
id: parsedJson["id"],
value: parsedJson["value"],
);

@ -0,0 +1,81 @@
class ArrivalVerificationTypeModel {
List<Data>? data;
String? message;
String? title;
String? innerMessage;
int? responseCode;
bool? isSuccess;
ArrivalVerificationTypeModel(
{this.data,
this.message,
this.title,
this.innerMessage,
this.responseCode,
this.isSuccess});
ArrivalVerificationTypeModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(Data.fromJson(v));
});
}
message = json['message'];
title = json['title'];
innerMessage = json['innerMessage'];
responseCode = json['responseCode'];
isSuccess = json['isSuccess'];
}
}
class Data {
int? assetGroupId;
int? verificationTypeId;
VerificationTypes? verificationTypes;
int? id;
String? createdBy;
String? createdDate;
dynamic modifiedBy;
dynamic modifiedDate;
Data(
{this.assetGroupId,
this.verificationTypeId,
this.verificationTypes,
this.id,
this.createdBy,
this.createdDate,
this.modifiedBy,
this.modifiedDate});
Data.fromJson(Map<String, dynamic> json) {
assetGroupId = json['assetGroupId'];
verificationTypeId = json['verificationTypeId'];
verificationTypes = json['verificationTypes'] != null
? VerificationTypes.fromJson(json['verificationTypes'])
: null;
id = json['id'];
createdBy = json['createdBy'];
createdDate = json['createdDate'];
modifiedBy = json['modifiedBy'];
modifiedDate = json['modifiedDate'];
}
}
class VerificationTypes {
int? id;
String? name;
int? value;
VerificationTypes({this.id, this.name, this.value});
VerificationTypes.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
value = json['value'];
}
}

@ -41,6 +41,7 @@ class WorkOrderDetail {
class WorkOrderData {
WorkOrderData({
this.requestId,
required this.workOrderNo,
required this.workOrderCreatedBy,
required this.requestedDate,
@ -77,57 +78,62 @@ class WorkOrderData {
required this.failureReasone,
required this.solution,
required this.totalWorkingHours,
this.needAVisitComment,
this.needAVisitDateTime,
required this.workOrderHistory,
required this.activities,
required this.activityAssetToBeRetireds,
});
final String? workOrderNo;
final AssignedEmployee? workOrderCreatedBy;
final DateTime? requestedDate;
final Asset? asset;
final Lookup? assetGroup;
final Lookup? manufacturer;
final Lookup? model;
final Lookup? assetNdModel;
final Site? site;
final Lookup? building;
final Lookup? floor;
final AssetGroup? department;
final int? room;
final Lookup? assetType;
final AssignedEmployee? assignedEmployee;
final String? lastActivityStatus;
final Lookup? status;
final Lookup? nextStep;
final int? assetVerificationType;
final List<WorkOrderContactPerson> workOrderContactPerson;
final Lookup? equipmentStatus;
final Lookup? priority;
final Lookup? requestedThrough;
final Lookup? typeofRequest;
final Lookup? loanAvailablity;
final Lookup? assetLoan;
final Lookup? safety;
final Lookup? problemDescription;
final String? comments;
final String? voiceNote;
final List<String> workOrderAttachments;
final String? returnToService;
final Lookup? serviceType;
final Lookup? failureReasone;
final Lookup? solution;
final String? totalWorkingHours;
final List<WorkOrderHistory> workOrderHistory;
final List<dynamic> activities;
final List<dynamic> activityAssetToBeRetireds;
int? requestId;
String? workOrderNo;
AssignedEmployee? workOrderCreatedBy;
DateTime? requestedDate;
WorkOrderAsset? asset;
Lookup? assetGroup;
Lookup? manufacturer;
Lookup? model;
Lookup? assetNdModel;
Site? site;
Lookup? building;
Lookup? floor;
AssetGroup? department;
int? room;
Lookup? assetType;
AssignedEmployee? assignedEmployee;
String? lastActivityStatus;
Lookup? status;
Lookup? nextStep;
int? assetVerificationType;
List<WorkOrderContactPerson> workOrderContactPerson;
Lookup? equipmentStatus;
Lookup? priority;
Lookup? requestedThrough;
Lookup? typeofRequest;
Lookup? loanAvailablity;
Lookup? assetLoan;
Lookup? safety;
Lookup? problemDescription;
String? comments;
String? voiceNote;
List<String> workOrderAttachments;
String? returnToService;
Lookup? serviceType;
Lookup? failureReasone;
Lookup? solution;
String? totalWorkingHours;
DateTime? needAVisitDateTime;
String?needAVisitComment;
List<WorkOrderHistory> workOrderHistory;
List<dynamic> activities;
List<dynamic> activityAssetToBeRetireds;
factory WorkOrderData.fromJson(Map<String, dynamic> json) {
return WorkOrderData(
requestId: json["id"],
workOrderNo: json["workOrderNo"],
workOrderCreatedBy: json["workOrderCreatedBy"] == null ? null : AssignedEmployee.fromJson(json["workOrderCreatedBy"]),
requestedDate: DateTime.tryParse(json["requestedDate"] ?? ""),
asset: json["asset"] == null ? null : Asset.fromJson(json["asset"]),
asset: json["asset"] == null ? null : WorkOrderAsset.fromJson(json["asset"]),
assetGroup: json["assetGroup"] == null ? null : Lookup.fromJson(json["assetGroup"]),
manufacturer: json["manufacturer"] == null ? null : Lookup.fromJson(json["manufacturer"]),
model: json["model"] == null ? null : Lookup.fromJson(json["model"]),
@ -162,15 +168,19 @@ class WorkOrderData {
totalWorkingHours: json["totalWorkingHours"],
workOrderHistory: json["workOrderHistory"] == null ? [] : List<WorkOrderHistory>.from(json["workOrderHistory"]!.map((x) => WorkOrderHistory.fromJson(x))),
activities: json["activities"] == null ? [] : List<dynamic>.from(json["activities"]!.map((x) => x)),
needAVisitDateTime: DateTime.tryParse(json["requestedDate"] ?? ""),
needAVisitComment: json["needAVisitComment"],
activityAssetToBeRetireds: json["activityAssetToBeRetireds"] == null ? [] : List<dynamic>.from(json["activityAssetToBeRetireds"]!.map((x) => x)),
);
}
Map<String, dynamic> toJson() =>
{
"id": requestId,
"workOrderNo": workOrderNo,
"workOrderCreatedBy": workOrderCreatedBy?.toJson(),
"requestedDate": requestedDate?.toIso8601String(),
"needAVisitDateTime": needAVisitDateTime?.toIso8601String(),
"asset": asset?.toJson(),
"assetGroup": assetGroup?.toJson(),
"manufacturer": manufacturer?.toJson(),
@ -204,23 +214,50 @@ class WorkOrderData {
"failureReasone": failureReasone?.toJson(),
"solution": solution?.toJson(),
"totalWorkingHours": totalWorkingHours,
"workOrderHistory": workOrderHistory.map((x) => x?.toJson()).toList(),
"workOrderHistory": workOrderHistory.map((x) => x.toJson()).toList(),
"activities": activities.map((x) => x).toList(),
"activityAssetToBeRetireds": activityAssetToBeRetireds.map((x) => x).toList(),
};
Map<String, dynamic> toFixRemotelyJson() {
return {'workOrderId': workOrderNo, 'startDate': workOrderHistory.isNotEmpty? workOrderHistory[0].fixRemotlyStartTime:'', 'endDate': workOrderHistory.isNotEmpty? workOrderHistory[0].fixRemotlyEndTime:'', 'workingHour':'', 'comment': comments};
}
//TODO feedback not defined...
Map<String, dynamic> toMarkAsFixedJson() {
return {'workOrderId': workOrderNo, 'feedback': comments};
}
Map<String, dynamic> toNeedVisitJson() {
return {'workOrderId': workOrderNo, 'visitDate': workOrderHistory.isNotEmpty? workOrderHistory[0].needAVisitDateTime:'', 'comment': comments};
}
//TODO signatureNurse not defined...
Map<String, dynamic> toNurseActionJson() {
return {'workOrderId': workOrderNo, 'feedback': '', 'signatureNurse': 'signatureNurse'};
}
Map<String, dynamic> toWorkOrderJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['workOrderId'] = requestId;
data['equipmentStatusId'] = equipmentStatus?.id;
data['returnToService'] = returnToService;
data['serviceTypeId'] = serviceType?.id;
data['loanAvailabilityId'] = loanAvailablity?.id;
data['loanAssetId'] = assetLoan?.id;
data['failureReasonId'] = failureReasone?.id;
data['faultDescriptionId'] = problemDescription?.id;
data['solution'] = solution;
return data;
}
}
class Asset {
Asset({
class WorkOrderAsset {
WorkOrderAsset({
required this.id,
required this.assetNumber,
});
final int? id;
final String? assetNumber;
int? id;
String? assetNumber;
factory Asset.fromJson(Map<String, dynamic> json) {
return Asset(
factory WorkOrderAsset.fromJson(Map<String, dynamic> json) {
return WorkOrderAsset(
id: json["id"],
assetNumber: json["assetNumber"],
);
@ -239,8 +276,8 @@ class AssetGroup {
required this.name,
});
final int? id;
final String? name;
int? id;
String? name;
factory AssetGroup.fromJson(Map<String, dynamic> json) {
return AssetGroup(
@ -264,10 +301,10 @@ class AssignedEmployee {
required this.languageId,
});
final dynamic userId;
final String? userName;
final String? email;
final int? languageId;
dynamic userId;
String? userName;
String? email;
int? languageId;
factory AssignedEmployee.fromJson(Map<String, dynamic> json) {
return AssignedEmployee(
@ -293,8 +330,8 @@ class Site {
required this.siteName,
});
final int? id;
final String? siteName;
int? id;
String? siteName;
factory Site.fromJson(Map<String, dynamic> json) {
return Site(
@ -322,14 +359,14 @@ class WorkOrderContactPerson {
required this.contactUser,
});
final int? id;
final String? name;
final String? employeeId;
final String? position;
final dynamic extension;
final String? email;
final dynamic mobilePhone;
final AssignedEmployee? contactUser;
int? id;
String? name;
String? employeeId;
String? position;
dynamic extension;
String? email;
dynamic mobilePhone;
AssignedEmployee? contactUser;
factory WorkOrderContactPerson.fromJson(Map<String, dynamic> json) {
return WorkOrderContactPerson(
@ -372,17 +409,17 @@ class WorkOrderHistory {
required this.needAVisitDateTime,
});
final int? id;
final Lookup? workorderStatus;
final dynamic activityStatus;
final DateTime? date;
final AssignedEmployee? user;
final Lookup? step;
final DateTime? fixRemotlyStartTime;
final DateTime? fixRemotlyEndTime;
final num? fixRemotlyWorkingHours;
final String? comments;
final DateTime? needAVisitDateTime;
int? id;
Lookup? workorderStatus;
dynamic activityStatus;
DateTime? date;
AssignedEmployee? user;
Lookup? step;
DateTime? fixRemotlyStartTime;
DateTime? fixRemotlyEndTime;
num? fixRemotlyWorkingHours;
String? comments;
DateTime? needAVisitDateTime;
factory WorkOrderHistory.fromJson(Map<String, dynamic> json) {
return WorkOrderHistory(

@ -180,34 +180,7 @@ class ServiceRequest {
}
return true;
}
Map<String, dynamic> toFixRemotelyJson() {
return {'workOrderId': id, 'startDate': startDate, 'endDate': endDate, 'workingHour': workingHours, 'comment': comments};
}
//TODO feedback not defined...
Map<String, dynamic> toMarkAsFixedJson() {
return {'workOrderId': id, 'feedback': comments};
}
Map<String, dynamic> toNeedVisitJson() {
return {'workOrderId': id, 'visitDate': visitDate, 'comment': comments};
}
//TODO signatureNurse not defined...
Map<String, dynamic> toNurseActionJson() {
return {'workOrderId': id, 'feedback': comments, 'signatureNurse': 'signatureNurse'};
}
//TODO workOrder fields not defined...
Map<String, dynamic> toWorkOrderJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['workOrderId'] = id;
data['equipmentStatusId'] = statusValue;
data['returnToService'] = 're';
data['serviceTypeId'] = 'se';
data['loanAvailabilityId'] = loanAvailability;
data['loanAssetId'] = loanAvailability?.id;
data['failureReasonId'] = faultDescription?.id;
data['faultDescriptionId'] = 'faultDescriptionId';
data['solution'] = 'solution';
return data;
}
}
class CallCreatedBy {

@ -28,6 +28,7 @@ class AppColor {
static const Color neutral110 = Color(0xffF3F5FB);
static const Color neutral120 = Color(0xff7D859A);
static const Color neutral130 = Color(0xffE0E0E0);
static const Color neutral140 = Color(0xffE6E6E6);
//background

@ -88,12 +88,14 @@ class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier
@override
Widget build(BuildContext context) {
provider = Provider.of<X>(widget.context, listen: true);
final isEmpty = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.isEmpty ?? true;
return AppLoadingManager(
isLoading: widget.loading ?? ((X == NullableLoadingProvider) ? false : provider?.loading ?? false),
// Provide default value if null
isFailedLoading: (X == NullableLoadingProvider) ? false : provider?.items == null,
stateCode: (X == NullableLoadingProvider) ? 200 : provider?.stateCode??0,
stateCode: (X == NullableLoadingProvider) ? 200 : provider?.stateCode ?? 0,
onRefresh: () async {
if (X != NullableLoadingProvider) {
provider?.reset();
@ -129,6 +131,7 @@ class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier
iconSize: 24,
isDense: true,
icon: const SizedBox.shrink(),
dropdownColor: AppColor.neutral100,
elevation: 0,
isExpanded: true,
hint: Text(

@ -16,6 +16,7 @@ import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/pages/land_page/calendar_page.dart';
import 'package:test_sa/new_views/pages/land_page/my_request/my_requests_page.dart';
import 'package:test_sa/new_views/pages/settings_page.dart';
import 'package:test_sa/service_request_latest/views/nurse/create_new_request_view.dart';
import 'package:test_sa/views/widgets/equipment/single_device_picker.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
@ -134,6 +135,9 @@ class _LandPageState extends State<LandPage> {
selectedIndex: currentPageIndex,
onPressed: (index) {
bool isEngineer = _userProvider!.user!.type == UsersTypes.engineer;
if(!isEngineer&&index==2){
Navigator.push(context, MaterialPageRoute(builder: (context)=>const CreateNewRequest()));
}
if (index == (!isEngineer ? 4 : 3)) {
showModalBottomSheet(
context: context,

@ -68,7 +68,7 @@ class ServiceRequestItemView extends StatelessWidget {
],
).toShadowContainer(context, showShadow: showShadow).onPress(() {
//Older code...
print('request id i got is ${request.id!}');
Navigator.of(context).push(MaterialPageRoute(builder: (_) => RequestDetailMain(requestId: request.id!)));
// Navigator.of(context).push(MaterialPageRoute(
// builder: (_) => const HistoryLogView()));

@ -19,8 +19,8 @@ class ReasonProvider extends LoadingListNotifier<Lookup> {
loading = true;
notifyListeners();
try {
print('get reson data called...$serviceRequestId');
Response response = await ApiManager.instance.get(URLs.getServiceReportReasons+"&serviceRequestId=$serviceRequestId");
//TODO change this url only used for testing till ahmed make a new api.. getServiceReportReasonsTest replace with getServiceReportReasons
Response response = await ApiManager.instance.get(URLs.getServiceReportReasonsTest+"&serviceRequestId=$serviceRequestId");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received

@ -0,0 +1,39 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import '../../controllers/api_routes/api_manager.dart';
import '../../controllers/api_routes/urls.dart';
import '../../models/lookup.dart';
class RetirementTypeProvider extends LoadingListNotifier<Lookup> {
String? serviceRequestId;
@override
Future getDate() async {
if (loading == true) return -2;
print('get data called...');
loading = true;
notifyListeners();
try {
//TODO change this url only used for testing till ahmed make a new api.. getServiceReportReasonsTest replace with getServiceReportReasons
Response response = await ApiManager.instance.get(URLs.getServiceReportRetirementTypeTest+"&serviceRequestId=$serviceRequestId");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
List categoriesListJson = json.decode(response.body)["data"];
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
loading = false;
print('loading value in provider is $loading');
notifyListeners();
return response.statusCode;
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -7,17 +7,16 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/helper_data_models/asset_retired/asset_retired_model.dart';
import 'package:test_sa/models/helper_data_models/spare_part/activity_spare_part_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/work_order_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/fix_remotely_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/mark_as_fixed_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/need_visit_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/nurse_action_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart';
import 'package:test_sa/models/new_models/arrival_verification_type_model.dart';
import 'package:test_sa/models/new_models/dashboard_detail.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
class RequestDetailProvider extends ChangeNotifier {
final pageItemNumber = 10;
void reset() {
nextPage = true;
stateCode = null;
@ -60,73 +59,63 @@ class RequestDetailProvider extends ChangeNotifier {
notifyListeners();
}
WorkOrderDetail? _currentWorkOrder;
FixRemotely? _fixRemotelyModel = FixRemotely();
NeedVisit? _needVisitModel = NeedVisit();
MarkAsFixed? _markAsFixed = MarkAsFixed();
ActivitySparePartModel? _activitySparePartModel = ActivitySparePartModel();
ActivityAssetRetiredModel? _activityAssetRetiredModel = ActivityAssetRetiredModel();
WorkOrderHModel _workOrderHModel = WorkOrderHModel();
WorkOrderHModel get workOrderHModel => _workOrderHModel;
//UI models
WorkOrderDetail? currentWorkOrder;
AssetRetiredHelperModel? assetRetiredHelperModel=AssetRetiredHelperModel();
SparePartHelperModel? sparePartHelperModel=SparePartHelperModel();
FixRemotelyHelperModel? fixRemotelyHelperModel=FixRemotelyHelperModel();
NeedVisitHelperModel? needVisitHelperModel=NeedVisitHelperModel();
NurseActionHelperModel? nurseActionHelperModel;
EngineerRejectHelperModel? engineerRejectHelperModel;
EngineerUpdateWorkOrderHelperModel? engineerUpdateWorkOrderHelperModel=EngineerUpdateWorkOrderHelperModel();
WorkOrderHelperModel? workOrderHelperModel;
set workOrderHModel(WorkOrderHModel value) {
_workOrderHModel = value;
void updateAssetRetiredHelperModel(AssetRetiredHelperModel? value) {
assetRetiredHelperModel = value;
notifyListeners();
}
ActivityAssetRetiredModel? get activityAssetRetiredModel => _activityAssetRetiredModel;
set activityAssetRetiredModel(ActivityAssetRetiredModel? value) {
_activityAssetRetiredModel = value;
void updateSparePartHelperModel(SparePartHelperModel? value) {
sparePartHelperModel = value;
notifyListeners();
}
ActivitySparePartModel? get activitySparePartModel => _activitySparePartModel;
set activitySparePartModel(ActivitySparePartModel? value) {
_activitySparePartModel = value;
void updateFixRemotelyHelperModel(FixRemotelyHelperModel? value) {
fixRemotelyHelperModel = value;
notifyListeners();
}
MarkAsFixed? get markAsFixed => _markAsFixed;
set markAsFixed(MarkAsFixed? value) {
_markAsFixed = value;
void updateNeedVisitHelperModel(NeedVisitHelperModel? value) {
needVisitHelperModel = value;
notifyListeners();
}
NurseActionModel? _nurseActionModel;
NurseActionModel? get nurseActionModel => _nurseActionModel;
set nurseActionModel(NurseActionModel? value) {
_nurseActionModel = value;
void updateNurseActionHelperModel(NurseActionHelperModel? value) {
nurseActionHelperModel = value;
notifyListeners();
}
NeedVisit? get needVisitModel => _needVisitModel;
set needVisitModel(NeedVisit? value) {
_needVisitModel = value;
void updateEngineerRejectHelperModel(EngineerRejectHelperModel? value) {
engineerRejectHelperModel = value;
notifyListeners();
}
FixRemotely? get fixRemotelyModel => _fixRemotelyModel;
set fixRemotelyModel(FixRemotely? value) {
_fixRemotelyModel = value;
void updateEngineerUpdateWorkOrderHelperModel(EngineerUpdateWorkOrderHelperModel? value) {
engineerUpdateWorkOrderHelperModel = value;
notifyListeners();
}
void updateWorkOrderHelperModel(WorkOrderHelperModel? value) {
workOrderHelperModel = value;
notifyListeners();
}
WorkOrderDetail? get currentWorkOrder => _currentWorkOrder;
set currentWorkOrder(WorkOrderDetail? value) {
_currentWorkOrder = value;
void updateCurrentWorkOrder(WorkOrderDetail? value) {
currentWorkOrder = value;
notifyListeners();
}
int? stateCode;
// true if there is next page in product list and false if not
@ -150,12 +139,12 @@ class RequestDetailProvider extends ChangeNotifier {
}
//create workOrder nurse .....
Future<int> createWorkOrder({required WorkOrderHModel workOrderHModel}) async {
Future<int> createWorkOrder() async {
isLoading = true;
try {
final response = await ApiManager.instance.post(
URLs.createWorkOrderUrl,
body: workOrderHModel.toJson(),
body: workOrderHelperModel!.toJson(),
);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
@ -180,7 +169,7 @@ class RequestDetailProvider extends ChangeNotifier {
final response = await ApiManager.instance.get(URLs.getWorkOrderByIdUrl + "?workOrderId=$id");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
_currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
}
isLoading = false;
notifyListeners();
@ -220,14 +209,10 @@ class RequestDetailProvider extends ChangeNotifier {
}
//engineerRejectWorkOrder......
Future<CommonResponseModel> engineerRejectWorkOrder({required String id, String? feedBack}) async {
Future<CommonResponseModel> engineerRejectWorkOrder() async {
try {
final body = {
"workOrderId": id,
"feedback": feedBack ?? '',
};
isLoading = true;
final response = await ApiManager.instance.post(URLs.engineerRejectUrl, body: body);
final response = await ApiManager.instance.post(URLs.engineerRejectUrl, body: engineerRejectHelperModel!.toJson());
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
@ -251,7 +236,7 @@ class RequestDetailProvider extends ChangeNotifier {
Future<CommonResponseModel> engineerFixRemotely() async {
try {
isLoading = true;
final response = await ApiManager.instance.post(URLs.engineerFixRemotlyUrl, body: fixRemotelyModel!.toJson());
final response = await ApiManager.instance.post(URLs.engineerFixRemotlyUrl, body: fixRemotelyHelperModel!.toJson());
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
@ -275,7 +260,7 @@ class RequestDetailProvider extends ChangeNotifier {
Future<CommonResponseModel> engineerNeedVisit() async {
try {
isLoading = true;
final response = await ApiManager.instance.post(URLs.engineerNeedVisitUrl, body: needVisitModel!.toJson());
final response = await ApiManager.instance.post(URLs.engineerNeedVisitUrl, body: needVisitHelperModel!.toJson());
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
@ -296,14 +281,14 @@ class RequestDetailProvider extends ChangeNotifier {
}
//engineerMarkAsFixed......
Future<CommonResponseModel> engineerMarkAsFixed() async {
Future<CommonResponseModel> engineerMarkAsFixed({required int workOrderId,required String feedback}) async {
try {
Map<String,dynamic> body = {'workOrderId': workOrderId, 'feedback': feedback};
isLoading = true;
final response = await ApiManager.instance.post(URLs.engineerMarkAsFixUrl, body: markAsFixed!.toJson());
final response = await ApiManager.instance.post(URLs.engineerMarkAsFixUrl, body: body);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
print('response of Engineer mark as fixed ${commonResponseModel.toJson()}');
notifyListeners();
isLoading = false;
return commonResponseModel;
@ -320,7 +305,7 @@ class RequestDetailProvider extends ChangeNotifier {
}
//engineer Confirm Arrive......
Future<CommonResponseModel> engineerConfirmArrive({required int workOrderId, required int verificationTypeId, required String photoInfo, required String otp}) async {
Future<CommonResponseModel> engineerConfirmArrival({required int workOrderId, required int verificationTypeId, required String photoInfo, required String otp}) async {
try {
Map<String, dynamic> body = {"workOrderId": workOrderId, "verificationTypeId": verificationTypeId, "photoInfo": photoInfo, "otp": otp};
isLoading = true;
@ -372,33 +357,34 @@ class RequestDetailProvider extends ChangeNotifier {
}
//engineerUpdateWorkOrder......
Future<CommonResponseModel> engineerUpdateWorkOrder({required EngineerUpdateWorkOrderHModel model}) async {
Future<void> engineerUpdateWorkOrder() async {
try {
isLoading = true;
final response = await ApiManager.instance.post(URLs.engineerUpdateWorkOrderUrl, body: model.toJson());
print('body to update work order is ${engineerUpdateWorkOrderHelperModel!.toJson()}');
final response = await ApiManager.instance.post(URLs.engineerUpdateWorkOrderUrl, body: engineerUpdateWorkOrderHelperModel!.toJson());
stateCode = response.statusCode;
print('response of the verify Asset detail is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) {
CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
updateCurrentWorkOrder(currentWorkOrder);
notifyListeners();
isLoading = false;
return commonResponseModel;
}
isLoading = false;
notifyListeners();
return CommonResponseModel();
} catch (e) {
log("engineer accept [error] : $e");
isLoading = false;
notifyListeners();
return CommonResponseModel();
}
}
//Nurse confirm reopen
Future<CommonResponseModel> nurseReject({required NurseActionModel model}) async {
Future<CommonResponseModel> nurseReject() async {
try {
isLoading = true;
final response = await ApiManager.instance.post(URLs.nurseRejectUrl, body: model.toJson());
final response = await ApiManager.instance.post(URLs.nurseRejectUrl, body: nurseActionHelperModel!.toJson());
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
@ -418,10 +404,10 @@ class RequestDetailProvider extends ChangeNotifier {
}
//Nurse confirm close
Future<CommonResponseModel> nurseConfirm({required NurseActionModel model}) async {
Future<CommonResponseModel> nurseConfirm() async {
try {
isLoading = true;
final response = await ApiManager.instance.post(URLs.nurseConfirmUrl, body: model.toJson());
final response = await ApiManager.instance.post(URLs.nurseConfirmUrl, body: nurseActionHelperModel!.toJson());
print('response i got is ${response.body}');
stateCode = response.statusCode;
@ -442,12 +428,12 @@ class RequestDetailProvider extends ChangeNotifier {
}
}
Future<int> updateActivitySparePart({required ActivitySparePartModel activitySparePartModel}) async {
Future<int> updateActivitySparePart() async {
isLoading = true;
try {
final response = await ApiManager.instance.post(
URLs.updateActivitySparePartUrl,
body: activitySparePartModel.toJson(),
body: sparePartHelperModel!.toJson(),
);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
@ -490,16 +476,17 @@ class RequestDetailProvider extends ChangeNotifier {
}
}
Future<int> createActivitySparePart({required ActivitySparePartModel activitySparePartModel}) async {
Future<int> createActivitySparePart() async {
isLoading = true;
try {
final response = await ApiManager.instance.post(
URLs.createActivitySparePartUrl,
body: activitySparePartModel.toJson(),
body: sparePartHelperModel!.toJson(),
);
stateCode = response.statusCode;
print('add sparepart activity response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) {
// request.engineerName = employee.name;
notifyListeners();
}
isLoading = false;
@ -511,17 +498,86 @@ class RequestDetailProvider extends ChangeNotifier {
return -1;
}
}
Future<int> createActivityAssetToBeRetired({required ActivityAssetRetiredModel activityAssetRetiredModel}) async {
//create asset retired request..
Future<int> createActivityAssetToBeRetired() async {
isLoading = true;
try {
final response = await ApiManager.instance.post(
URLs.createActivityAssetToBeRetiredUrl,
body: activityAssetRetiredModel.toJson(),
body: assetRetiredHelperModel!.toJson(),
);
print('response i got is ${response.body}');
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
updateCurrentWorkOrder(currentWorkOrder);
notifyListeners();
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
isLoading = false;
notifyListeners();
return -1;
}
}
//get Arrival type......
//TODO create a model when there is data in api...
Future<ArrivalVerificationTypeModel> getArrivalVerificationType() async {
ArrivalVerificationTypeModel arrivalVerificationTypeModel= ArrivalVerificationTypeModel();
try {
isLoading = true;
notifyListeners();
final response = await ApiManager.instance.get(URLs.getArrivalVerificationTypeUrl);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
arrivalVerificationTypeModel = ArrivalVerificationTypeModel.fromJson(json.decode(response.body));
}
isLoading = false;
notifyListeners();
return arrivalVerificationTypeModel;
} catch (e) {
log("getArrivalVerifaction [error] : $e");
isLoading = false;
notifyListeners();
return arrivalVerificationTypeModel;
}
}
//send otp..
Future<int?> sendOtp({required int workOrderId}) async {
isLoading = true;
try {
final response = await ApiManager.instance.postWithOutBody(
URLs.sendOtpUrl+ "$workOrderId",
);
stateCode = response.statusCode;
print('response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) {
notifyListeners();
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
isLoading = false;
notifyListeners();
return -1;
}
}
//verify otp..
Future<int> verifyOtp({required int workOrderId,required String otpCode}) async {
isLoading = true;
try {
final response = await ApiManager.instance.postWithOutBody(
URLs.verifyOtpUrl+'$workOrderId&$otpCode',
);
print('response i got is ${response.body}');
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// request.engineerName = employee.name;
notifyListeners();
}
isLoading = false;

@ -1,10 +1,19 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_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/main.dart';
import 'package:test_sa/models/enums/work_order_next_step.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/providers/work_order/reason_provider.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart';
import 'package:test_sa/service_request_latest/views/components/verify_arrival_view.dart';
import 'package:test_sa/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart';
class FooterActionButton {
static Widget footerContainer({required Widget child}) {
@ -18,10 +27,26 @@ class FooterActionButton {
);
}
static Widget requestDetailsFooterWidget({required int status, required BuildContext context}) {
switch (status) {
//accept reject...
case 1:
static Widget requestDetailsFooterWidget({required WorkOrderNextStepEnum workOrderNextStepStatus, required BuildContext context}) {
RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
switch (workOrderNextStepStatus) {
case WorkOrderNextStepEnum.onlyView:
return const SizedBox();
// TODO: Handle this case.
case WorkOrderNextStepEnum.markedAsFixed:
// TODO: Handle this case.
case WorkOrderNextStepEnum.nTakeAction:
return footerContainer(
child: AppFilledButton(
label: context.translation.takeAction,
// maxWidth: true,
buttonColor: AppColor.primary10,
onPressed: () async {
ServiceRequestBottomSheet.nurseTakeActionBottomSheet(context: context);
},
));
case WorkOrderNextStepEnum.eRejectAccept:
return footerContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -34,6 +59,14 @@ class FooterActionButton {
textColor: AppColor.red30,
showBorder: true,
onPressed: () async {
//TODO need to discuss getData is not called by default...
if (context.mounted) {
ReasonProvider reasonProvider = Provider.of<ReasonProvider>(context, listen: false);
reasonProvider.reset();
// reasonProvider.serviceRequestId = requestDetailProvider.currentServiceRequestId.toString();
reasonProvider.serviceRequestId = '3';
reasonProvider.getDate();
}
ServiceRequestBottomSheet.rejectRequestBottomSheet(context: context);
},
).expanded,
@ -44,13 +77,15 @@ class FooterActionButton {
label: context.translation.accept,
maxWidth: true,
buttonColor: AppColor.green70,
onPressed: () async {},
onPressed: () async {
requestDetailProvider.engineerAcceptWorkOrder(id: requestDetailProvider.currentWorkOrder!.data!.requestId.toString()).whenComplete(() {
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
});
},
).expanded,
],
));
break;
//need visit fixed remotely
case 2:
case WorkOrderNextStepEnum.eFixRemotelyNeedVisit:
return footerContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -77,65 +112,67 @@ class FooterActionButton {
).expanded,
],
));
break;
//verify Asset Details
case 3:
return footerContainer(
child: AppFilledButton(
label: context.translation.verify_asset_details,
// maxWidth: true,
buttonColor: AppColor.primary10,
onPressed: () async {},
));
break;
//Activities
case 4:
return footerContainer(
child: AppFilledButton(
label: context.translation.activities,
// maxWidth: true,
buttonColor: AppColor.neutral50,
onPressed: () async {
ServiceRequestBottomSheet.activityTypeBottomSheet(context: context);
},
));
break;
//I have arrived...
case 5:
case WorkOrderNextStepEnum.eArrived:
return footerContainer(
child: AppFilledButton(
label: context.translation.iHaveArrived,
//showIcon: true,
// icon: 'arrived_icon'.toSvgAsset(),
showIcon: true,
icon: 'arrived_icon'.toSvgAsset(),
buttonColor: AppColor.green70,
onPressed: () async {},
));
break;
//Close..
case 6:
return footerContainer(
child: AppFilledButton(
label: context.translation.close,
// maxWidth: true,
buttonColor: AppColor.primary10,
onPressed: () async {},
onPressed: () async {
Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyArrivalView()));
},
));
break;
//for nurse to take action...
case 7:
case WorkOrderNextStepEnum.verifyAssetDetail:
return footerContainer(
child: AppFilledButton(
label: context.translation.takeAction,
label: context.translation.verify_asset_details,
// maxWidth: true,
buttonColor: AppColor.primary10,
onPressed: () async {
ServiceRequestBottomSheet.nurseTakeActionBottomSheet(context: context);
Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyAssetDetails()));
},
));
break;
default:
case WorkOrderNextStepEnum.activity:
return footerContainer(
child: Column(
children: [
AppFilledButton(
label: context.translation.activities,
// maxWidth: true,
buttonColor: AppColor.neutral50,
onPressed: () async {
ServiceRequestBottomSheet.activityTypeBottomSheet(context: context);
},
),
8.height,
AppFilledButton(
label: context.translation.markAsFixed,
// maxWidth: true,
buttonColor: AppColor.green70,
onPressed: () async {
ServiceRequestBottomSheet.feedBackBottomSheet(context: context);
},
),
],
));
case WorkOrderNextStepEnum.endWorkFlow:
return const SizedBox();
// return footerContainer(
// child: AppFilledButton(
// label: context.translation.close,
// // maxWidth: true,
// buttonColor: AppColor.primary10,
// onPressed: () async {},
// ));
case WorkOrderNextStepEnum.assetRetirementManagementApproval:
return footerContainer(
child: AppFilledButton(
label: context.translation.assetRetiredPendingOpManagementApproval,
buttonColor: AppColor.neutral140,
onPressed: () async {
},
));
}
}
}

@ -9,9 +9,11 @@ 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/service_request/search_work_order.dart';
import 'package:test_sa/models/service_request/service_request.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';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart';
import 'package:test_sa/views/pages/user/requests/work_order/update_service_report.dart';
import 'package:test_sa/views/pages/user/requests/work_order/work_order_details_page.dart';
@ -25,120 +27,103 @@ class ActivitiesListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
// UserProvider _userProvider = Provider.of<UserProvider>(context);
// SettingProvider _settingProvider = Provider.of<SettingProvider>(context);
List<SearchWorkOrder> workOrders = [];
List<dynamic> activities = [];
UserProvider userProvider = Provider.of<UserProvider>(context);
return Scaffold(
appBar: DefaultAppBar(title: context.translation.activities),
//backgroundColor: const Color(0xfff8f9fb),
body: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestsProvider, child) {
return SafeArea(
child: FutureBuilder(
future: serviceRequestsProvider.searchWorkOrders(callId: serviceRequestsProvider.currentSelectedRequest!.requestCode!),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator());
workOrders = snap.data as List<SearchWorkOrder>;
return Column(
children: [
(workOrders.isEmpty)
? NoDataFound(message: context.translation.noDataFound).expanded
: ListView.separated(
padding: const EdgeInsets.all(16),
itemCount: workOrders.length,
separatorBuilder: (czt, index) => 8.height,
itemBuilder: (context, index) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StatusLabel(
label: workOrders[index].currentSituation!.name,
textColor: AppColor.getRequestStatusTextColorByName(context, workOrders[index].currentSituation!.name!),
backgroundColor: AppColor.getRequestStatusColorByName(context, workOrders[index].currentSituation!.name!),
),
8.height,
Text(serviceRequestsProvider.currentSelectedRequest!.requestCode!,
style: AppTextStyles.heading5.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50)),
Text(
'${context.translation.assetName}: ${workOrders[index].callRequest!.asset!.modelDefinition!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.currentSituation}: ${workOrders[index].currentSituation!.name}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
16.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
context.translation.viewDetails,
style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)),
),
4.width,
Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14)
],
),
],
).onPress(() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: workOrders[index], serviceRequest: serviceRequestsProvider.currentSelectedRequest)),
);
}).expanded,
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (userProvider.user!.type == UsersTypes.engineer &&
serviceRequestsProvider.currentSelectedRequest?.statusValue != 5 &&
serviceRequestsProvider.currentSelectedRequest?.statusValue != 3)
"edit".toSvgAsset(height: 48, width: 48).onPress(() {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => UpdateServiceReport(request: serviceRequestsProvider.currentSelectedRequest!, workOrder: workOrders[index])),
);
}),
if (userProvider.user!.type == UsersTypes.engineer &&
serviceRequestsProvider.currentSelectedRequest?.statusValue != 5 &&
serviceRequestsProvider.currentSelectedRequest?.statusValue != 3)
8.height,
Text(workOrders[index].visitDate?.toServiceRequestCardFormat ?? "",
textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : const Color(0xFF3B3D4A))),
],
)
],
).toShadowContainer(context);
},
).expanded,
if (userProvider.user!.type == UsersTypes.engineer &&
(serviceRequestsProvider.currentSelectedRequest?.statusValue != 5 && serviceRequestsProvider.currentSelectedRequest?.statusValue != 3))
AppFilledButton(
label: context.translation.createNewActivity,
maxWidth: true,
onPressed: () async {
ServiceRequestBottomSheet.fixRemotelyBottomSheet(context: context);
// bool shouldReloadData = (await showModalBottomSheet(
// context: context,
// useSafeArea: true,
// isScrollControlled: true,
// backgroundColor: Colors.transparent,
// // builder: (context) => ActivityTypeBottomSheet(),
// builder: (context) => FixRemotlyBottomSheet(),
// )) as bool;
// if (shouldReloadData ?? false) {
// // getServiceRequest();
// }
// Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequestsProvider.serviceRequest)));
},
).paddingOnly(start: 16, end: 16, bottom: 16)
],
);
},
),
body: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
activities = requestDetailProvider.currentWorkOrder!.data!.activities;
return Column(
children: [
(activities.isEmpty)
? NoDataFound(message: context.translation.noDataFound).expanded
: ListView.separated(
padding: const EdgeInsets.all(16),
itemCount: activities.length,
separatorBuilder: (czt, index) => 8.height,
itemBuilder: (context, index) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StatusLabel(
label: activities[index].currentSituation!.name,
textColor: AppColor.getRequestStatusTextColorByName(context, activities[index].currentSituation!.name!),
backgroundColor: AppColor.getRequestStatusColorByName(context, activities[index].currentSituation!.name!),
),
8.height,
//activity type...
Text(
'${activities[index].callRequest!.asset!.modelDefinition!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
2.height,
Text(
'${context.translation.workingHours}: ${activities[index].currentSituation?.workingHours}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
Text(
'${context.translation.date}: ${activities[index].currentSituation?.date}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
context.translation.viewDetails,
style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)),
),
4.width,
Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14)
],
),
],
).onPress(() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: activities[index], serviceRequest: ServiceRequest())),
);
}).expanded,
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
"edit".toSvgAsset(height: 48, width: 48).onPress(() {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => UpdateServiceReport(request: ServiceRequest(), workOrder: activities[index])),
);
}),
if (userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
8.height,
Text(activities[index].visitDate?.toServiceRequestCardFormat ?? "",
textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : const Color(0xFF3B3D4A))),
],
)
],
).toShadowContainer(context);
},
).expanded,
if (userProvider.user!.type == UsersTypes.engineer &&
(requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3))
AppFilledButton(
label: context.translation.createNewActivity,
maxWidth: true,
onPressed: () async {
ServiceRequestBottomSheet.activityTypeBottomSheet(context: context);
},
).paddingOnly(start: 16, end: 16, bottom: 16)
],
);
}),
);

@ -1,5 +1,4 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -11,25 +10,25 @@ import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/helper_data_models/workorder/nurse_action_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/service_request_providers/first_action_provider.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart';
import 'package:test_sa/service_request_latest/views/forms/spare_part/spare_part_request.dart';
import 'package:test_sa/service_request_latest/views/components/verify_arrival_view.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import '../../../../controllers/providers/api/service_requests_provider.dart';
import '../../../../new_views/app_style/app_color.dart';
import '../../../../new_views/common_widgets/app_filled_button.dart';
import '../../../../new_views/common_widgets/app_text_form_field.dart';
class ServiceRequestBottomSheet {
static buildBottomSheetParentWithConsumer({required BuildContext context, required Widget childWidget}) {
static buildBottomSheetParent({required BuildContext context, required Widget childWidget}) {
return showModalBottomSheet(
context: context,
useSafeArea: true,
@ -42,9 +41,9 @@ class ServiceRequestBottomSheet {
}
static Future fixRemotelyBottomSheet({required BuildContext context}) {
return buildBottomSheetParentWithConsumer(
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
childWidget: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@ -56,60 +55,93 @@ class ServiceRequestBottomSheet {
),
16.height,
ADatePicker(
label: context.translation.date,
label: context.translation.startDate,
hideShadow: true,
// height: 60.toScreenHeight,
backgroundColor: AppColor.neutral100,
date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""),
date: requestDetailProvider.fixRemotelyHelperModel?.startDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
if (selectedDate != null) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
//serviceRequestProvider.currentSelectedRequest?.date
if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) {
"Visit Date time must be greater then request date".showToast;
return;
}
serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime.toIso8601String();
serviceRequestProvider.updateCurrentSelectedRequest(serviceRequestProvider.currentSelectedRequest);
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
//serviceRequestProvider.currentSelectedRequest?.date
// if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) {
// "Visit Date time must be greater then request date".showToast;
// return;
// }
requestDetailProvider.fixRemotelyHelperModel?.startDate = selectedDateTime;
requestDetailProvider.updateFixRemotelyHelperModel(requestDetailProvider.fixRemotelyHelperModel);
// serviceRequestProvider.updateCurrentSelectedRequest(serviceRequestProvider.currentSelectedRequest);
}
});
},
),
8.height,
ADatePicker(
label: context.translation.endDate,
hideShadow: true,
// height: 60.toScreenHeight,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.fixRemotelyHelperModel?.endDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (requestDetailProvider.fixRemotelyHelperModel!.startDate!=null&&selectedDateTime.isBefore(requestDetailProvider.fixRemotelyHelperModel!.startDate!)) {
"End Date time must be greater then start date".showToast;
return;
}
});
}
requestDetailProvider.fixRemotelyHelperModel?.endDate = selectedDateTime;
requestDetailProvider.updateFixRemotelyHelperModel(requestDetailProvider.fixRemotelyHelperModel);
// serviceRequestProvider.updateCurrentSelectedRequest(serviceRequestProvider.currentSelectedRequest);
}
});
},
),
8.height,
SizedBox(
width: double.infinity,
height: 56.toScreenHeight,
// padding: EdgeInsets.symmetric(horizontal: 20.toScreenWidth, vertical: 10.toScreenHeight),
child: AppTimer(
label: context.translation.workingHours,
timer: TimerModel(),
decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral20 : AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
// boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
// enabled: serviceRequestProvider.currentSelectedRequest.date == null,
enabled: true,
onChange: (timer) async {
print('timer i got is ${timer.toString()}');
return true;
},
),
AppTextFormField(
labelText: context.translation.workingHours,
textInputType: TextInputType.number,
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100,
alignLabelWithHint: true,
onChange: (text) {
if(text.isNotEmpty){
requestDetailProvider.fixRemotelyHelperModel?.workingHour = int.parse(text);
}
},
onSaved: (text) {
if(text.isNotEmpty){
requestDetailProvider.fixRemotelyHelperModel?.workingHour = int.parse(text);
}
},
),
8.height,
AppTextFormField(
@ -120,10 +152,12 @@ class ServiceRequestBottomSheet {
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100,
alignLabelWithHint: true,
onChange: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.fixRemotelyHelperModel?.comment = text;
},
onSaved: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.fixRemotelyHelperModel?.comment = text;
},
),
16.height,
@ -151,7 +185,12 @@ class ServiceRequestBottomSheet {
label: context.translation.fixed,
buttonColor: AppColor.green70,
loading: false,
onPressed: () {},
onPressed: () {
//TODO after confirm from backend call the api and reset the model.
// requestDetailProvider.engineerFixRemotely();
// requestDetailProvider.fixRemotelyHelperModel = FixRemotelyHelperModel();
print('model i got is ${requestDetailProvider.fixRemotelyHelperModel?.toJson()}');
},
),
),
],
@ -293,10 +332,10 @@ class ServiceRequestBottomSheet {
}
static Future initialVisitBottomSheet({required BuildContext context}) {
return buildBottomSheetParentWithConsumer(
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
childWidget: Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return Column(
children: [
const SizedBox().indicatorWidget(),
@ -310,7 +349,7 @@ class ServiceRequestBottomSheet {
label: context.translation.visitDate,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.visitDate ?? ""),
date: requestDetailProvider.needVisitHelperModel?.visitDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
if (selectedDate != null) {
@ -327,82 +366,78 @@ class ServiceRequestBottomSheet {
selectedTime.hour,
selectedTime.minute,
);
if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) {
"Visit Date time must be greater then request date".showToast;
return;
}
serviceRequestProvider.currentSelectedRequest?.visitDate = selectedDateTime?.toIso8601String();
serviceRequestProvider.updateCurrentSelectedRequest(serviceRequestProvider.currentSelectedRequest);
requestDetailProvider.needVisitHelperModel?.visitDate = selectedDateTime;
requestDetailProvider.updateNeedVisitHelperModel(requestDetailProvider.needVisitHelperModel);
}
});
}
},
),
if (serviceRequestProvider.currentSelectedRequest?.firstAction?.id == 404 && Provider.of<SettingProvider>(context, listen: false).assetGroup?.id == 1) ...[
8.height,
Row(
children: [
ADatePicker(
label: context.translation.startDate,
date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""),
formatDateWithTime: true,
onDatePicker: (selectedDate) {
if (selectedDate != null) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (selectedDateTime != null) {
serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime?.toIso8601String();
}
}
});
}
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endDate,
date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.endDate ?? ""),
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
serviceRequestProvider.currentSelectedRequest?.endDate = selectedDateTime?.toIso8601String();
serviceRequestProvider.currentSelectedRequest?.workingHours = (((DateTime.parse(serviceRequestProvider.currentSelectedRequest!.endDate!)
.difference(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.startDate!))
.inSeconds ??
0) /
60) /
60)
.toStringAsFixed(2);
}
});
},
).expanded,
],
)
],
// if (serviceRequestProvider.currentSelectedRequest?.firstAction?.id == 404 && Provider.of<SettingProvider>(context, listen: false).assetGroup?.id == 1) ...[
// 8.height,
// Row(
// children: [
// ADatePicker(
// label: context.translation.startDate,
// date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""),
// formatDateWithTime: true,
// onDatePicker: (selectedDate) {
// if (selectedDate != null) {
// showTimePicker(
// context: context,
// initialTime: TimeOfDay.now(),
// ).then((selectedTime) {
// // Handle the selected date and time here.
// if (selectedTime != null) {
// DateTime selectedDateTime = DateTime(
// selectedDate.year,
// selectedDate.month,
// selectedDate.day,
// selectedTime.hour,
// selectedTime.minute,
// );
// if (selectedDateTime != null) {
// serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime?.toIso8601String();
// }
// }
// });
// }
// },
// ).expanded,
// 8.width,
// ADatePicker(
// label: context.translation.endDate,
// date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.endDate ?? ""),
// formatDateWithTime: true,
// onDatePicker: (selectedDate) {
// showTimePicker(
// context: context,
// initialTime: TimeOfDay.now(),
// ).then((selectedTime) {
// // Handle the selected date and time here.
// if (selectedTime != null) {
// DateTime selectedDateTime = DateTime(
// selectedDate.year,
// selectedDate.month,
// selectedDate.day,
// selectedTime.hour,
// selectedTime.minute,
// );
// serviceRequestProvider.currentSelectedRequest?.endDate = selectedDateTime?.toIso8601String();
// serviceRequestProvider.currentSelectedRequest?.workingHours = (((DateTime.parse(serviceRequestProvider.currentSelectedRequest!.endDate!)
// .difference(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.startDate!))
// .inSeconds ??
// 0) /
// 60) /
// 60)
// .toStringAsFixed(2);
// }
// });
// },
// ).expanded,
// ],
// )
// ],
8.height,
AppTextFormField(
labelText: context.translation.comments,
@ -412,23 +447,27 @@ class ServiceRequestBottomSheet {
textInputType: TextInputType.multiline,
alignLabelWithHint: true,
onChange: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.needVisitHelperModel?.comment = text;
},
onSaved: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.needVisitHelperModel?.comment = text;
},
),
12.height,
AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.primary10,
loading: serviceRequestProvider.isLoading ?? false,
loading: false,
onPressed: () async {
// formKey.currentState?.save();
requestDetailProvider.needVisitHelperModel?.workOrderId= requestDetailProvider.currentWorkOrder!.data!.requestId;
print('payload to set initial visit ${requestDetailProvider.needVisitHelperModel?.toJson()}');
//TODO reset model and call api after confirm form backend...
await requestDetailProvider.engineerNeedVisit().whenComplete((){
Navigator.pop(context);
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
requestDetailProvider.needVisitHelperModel = NeedVisitHelperModel();
});
// await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.serviceRequest);
// Navigator.pop(context, true);
Navigator.of(context).push(MaterialPageRoute(builder: (_) => VerifyArrivalView()));
},
),
16.height,
@ -588,9 +627,10 @@ class ServiceRequestBottomSheet {
}
static Future rejectRequestBottomSheet({required BuildContext context}) {
return buildBottomSheetParentWithConsumer(
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
childWidget: Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return Column(
children: [
const SizedBox().indicatorWidget(),
@ -599,17 +639,15 @@ class ServiceRequestBottomSheet {
child: context.translation.rejectionReason.heading4(context).paddingOnly(top: 21),
),
15.height,
SingleItemDropDownMenu<Lookup, FirstActionStatusProvider>(
SingleItemDropDownMenu<Lookup, ReasonProvider>(
context: context,
backgroundColor: AppColor.neutral100,
height: 56.toScreenHeight,
title: context.translation.reason,
initialValue: serviceRequestProvider.currentSelectedRequest?.firstAction,
//_serviceRequest.firstAction,
initialValue: requestDetailProvider.engineerRejectHelperModel?.rejectionReason,
onSelect: (value) {
serviceRequestProvider.currentSelectedRequest?.firstAction = value;
if (serviceRequestProvider.currentSelectedRequest?.firstAction?.value != 2) {
serviceRequestProvider.currentSelectedRequest?.visitDate = null;
if (value != null) {
requestDetailProvider.engineerRejectHelperModel?.rejectionReason = value;
requestDetailProvider.engineerRejectHelperModel?.rejectReasonId=value.id;
requestDetailProvider.updateEngineerRejectHelperModel(requestDetailProvider.engineerRejectHelperModel);
}
},
),
@ -621,105 +659,34 @@ class ServiceRequestBottomSheet {
alignLabelWithHint: true,
labelStyle: AppTextStyles.textFieldLabelStyle,
onChange: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.engineerRejectHelperModel?.feedback = text;
},
onSaved: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.engineerRejectHelperModel?.feedback = text;
requestDetailProvider.updateEngineerRejectHelperModel(requestDetailProvider.engineerRejectHelperModel);
},
),
16.height,
Consumer<ServiceRequestsProvider>(
builder: (context, snapshot, _) => AppFilledButton(
label: context.translation.reject,
maxWidth: true,
buttonColor: Colors.white54,
textColor: AppColor.red30,
showBorder: true,
loading: snapshot.isLoading ?? false,
onPressed: () async {
AppFilledButton(
label: context.translation.reject,
maxWidth: true,
buttonColor: Colors.white54,
textColor: AppColor.red30,
showBorder: true,
loading: requestDetailProvider.isLoading,
onPressed: () async {
requestDetailProvider.engineerRejectWorkOrder();
//Todo implement backend logic..
// serviceRequestProvider.serviceRequest.device = asset;
// await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.currentSelectedRequest);
Navigator.pop(context, true);
},
),
//Todo implement backend logic..
// serviceRequestProvider.serviceRequest.device = asset;
// await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.currentSelectedRequest);
Navigator.pop(context, true);
},
),
16.height,
],
);
}));
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
return showModalBottomSheet(
context: context,
useSafeArea: true,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: [
const SizedBox().indicatorWidget(),
Align(
alignment: AlignmentDirectional.centerStart,
child: context.translation.rejectionReason.heading4(context).paddingOnly(top: 21),
),
15.height,
SingleItemDropDownMenu<Lookup, FirstActionStatusProvider>(
context: context,
backgroundColor: AppColor.neutral100,
height: 56.toScreenHeight,
title: context.translation.reason,
initialValue: serviceRequestProvider.currentSelectedRequest?.firstAction,
//_serviceRequest.firstAction,
onSelect: (value) {
serviceRequestProvider.currentSelectedRequest?.firstAction = value;
if (serviceRequestProvider.currentSelectedRequest?.firstAction?.value != 2) {
serviceRequestProvider.currentSelectedRequest?.visitDate = null;
}
},
),
12.height,
AppTextFormField(
backgroundColor: AppColor.neutral100,
labelText: context.translation.comments,
textInputType: TextInputType.multiline,
alignLabelWithHint: true,
labelStyle: AppTextStyles.textFieldLabelStyle,
onChange: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
},
onSaved: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
},
),
16.height,
Consumer<ServiceRequestsProvider>(
builder: (context, snapshot, _) => AppFilledButton(
label: context.translation.reject,
maxWidth: true,
buttonColor: Colors.white54,
textColor: AppColor.red30,
showBorder: true,
loading: snapshot.isLoading ?? false,
onPressed: () async {
//Todo implement backend logic..
// serviceRequestProvider.serviceRequest.device = asset;
// await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.currentSelectedRequest);
Navigator.pop(context, true);
},
),
),
16.height,
],
),
),
).bottomSheetContainer(context);
}));
}
static Future activityTypeBottomSheet({required BuildContext context}) {
@ -727,48 +694,72 @@ class ServiceRequestBottomSheet {
{'heading': context.translation.sparePartRequest, 'subHeading': context.translation.sparePartRequestDetail, 'icon': AppAsset.sparePartIcon},
{'heading': context.translation.maintenanceRequest, 'subHeading': context.translation.sparePartRequestDetail, 'icon': AppAsset.maintenanceIcon},
];
Widget listItem({required BuildContext context, required String icon, required String heading, required String subHeading, required VoidCallback onTap}) {
return Card(
color: AppColor.neutral80,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
// Circular border radius
),
// color: Colors.white,
child: ListTile(
minVerticalPadding: 12.toScreenWidth,
horizontalTitleGap: 2.toScreenHeight,
onTap: onTap,
contentPadding: const EdgeInsets.all(8),
leading: SvgPicture.asset(icon),
title: Text(
heading,
style: AppTextStyles.heading6,
),
subtitle: Text(
subHeading,
style: AppTextStyles.bodyText2,
Widget customListItem({
required BuildContext context,
required String icon,
required String heading,
required String subHeading,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap, // Handles the tap
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14), // Circular border radius
),
color: AppColor.neutral80,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, // Align items at the top
children: [
// Icon Section
icon
.toSvgAsset(
width: 26,
color: AppColor.neutral120,
height: 29,
)
.paddingOnly(top: 8),
14.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
heading,
style: AppTextStyles.heading6.copyWith(color: AppColor.neutral50),
),
7.height,
Text(
subHeading,
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
],
).paddingOnly(end: 50),
),
],
).paddingAll(12),
),
);
}
void onItemTap({required int index, required ServiceRequest serviceRequest, required BuildContext context}) {
void onItemTap({required int index, required BuildContext context}) {
switch (index) {
case 0:
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const SparePartRequest()));
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const SparePartRequest()),
);
break;
case 1:
//push to specific screen...
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => ActivitiesListView()),
// );
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const MaintenanceRequestForm()),
);
break;
}
}
return buildBottomSheetParentWithConsumer(
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
return Column(
@ -787,60 +778,22 @@ class ServiceRequestBottomSheet {
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return listItem(
return customListItem(
icon: item['icon']!,
heading: item['heading']!,
subHeading: item['subHeading']!,
context: context,
onTap: () {
onItemTap(serviceRequest: serviceRequestProvider.currentSelectedRequest!, index: index, context: context);
onItemTap(index: index, context: context);
});
},
),
],
);
}));
return showModalBottomSheet(
context: context,
useSafeArea: true,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox().indicatorWidget(),
8.height,
Align(
alignment: AlignmentDirectional.centerStart,
child: context.translation.selectActivityType.bottomSheetHeadingTextStyle(context),
),
16.height,
ListView.builder(
shrinkWrap: true,
padding: EdgeInsets.zero,
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return listItem(
icon: item['icon']!,
heading: item['heading']!,
subHeading: item['subHeading']!,
context: context,
onTap: () {
onItemTap(serviceRequest: serviceRequestProvider.currentSelectedRequest!, index: index, context: context);
});
},
),
],
).bottomSheetContainer(context);
}));
}
static Future actionBottomSheet({required BuildContext context, required String title, String? button1Text, String? button2Text, VoidCallback? button1Tap, VoidCallback? button2Tap}) {
return buildBottomSheetParentWithConsumer(
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
return Column(
@ -862,7 +815,7 @@ class ServiceRequestBottomSheet {
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: button1Tap ??
() async {
() async {
Navigator.pop(context);
// await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.serviceRequest);
// Navigator.pop(context, true);
@ -881,7 +834,6 @@ class ServiceRequestBottomSheet {
);
}));
return showModalBottomSheet(
context: context,
useSafeArea: true,
@ -928,10 +880,10 @@ class ServiceRequestBottomSheet {
}
static Future feedBackBottomSheet({required BuildContext context}) {
return buildBottomSheetParentWithConsumer(
String feedback = '';
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
childWidget: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@ -950,10 +902,10 @@ class ServiceRequestBottomSheet {
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100,
alignLabelWithHint: true,
onChange: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
feedback = text;
},
onSaved: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
feedback = text;
},
),
16.height,
@ -961,7 +913,12 @@ class ServiceRequestBottomSheet {
label: context.translation.fixed,
buttonColor: AppColor.green70,
loading: false,
onPressed: () {},
onPressed: () {
print('feedback i got is ${feedback}');
//TODO uncommit this after testing...
// requestDetailProvider.engineerMarkAsFixed(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, feedback:feedback);
},
),
],
);
@ -1020,9 +977,9 @@ class ServiceRequestBottomSheet {
bool acknowledge = false;
Uint8List? newSignature;
String? nurseSignature;
return buildBottomSheetParentWithConsumer(
return buildBottomSheetParent(
context: context,
childWidget: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
childWidget: Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@ -1038,15 +995,15 @@ class ServiceRequestBottomSheet {
InkWell(
child: acknowledge
? const Icon(
Icons.check_box,
color: AppColor.primary10,
)
Icons.check_box,
color: AppColor.primary10,
)
: const Icon(
Icons.check_box_outline_blank,
color: AppColor.neutral120,
),
Icons.check_box_outline_blank,
color: AppColor.neutral120,
),
onTap: () {
acknowledge = !acknowledge;
acknowledge = !acknowledge;
},
),
6.width,
@ -1079,12 +1036,11 @@ class ServiceRequestBottomSheet {
showBorder: true,
onPressed: () async {
if (newSignature != null && acknowledge) {
//TODO replace provider with new provider and also check workorder id is not correct.
Provider.of<RequestDetailProvider>(context, listen: false).nurseReject(
model: NurseActionModel(
workOrderId: int.parse(serviceRequestProvider.currentSelectedRequest!.id!),
signatureNurse: nurseSignature,
));
requestDetailProvider.nurseActionHelperModel=NurseActionHelperModel(
workOrderId: int.parse(requestDetailProvider.currentWorkOrder!.data!.workOrderNo!),
signatureNurse: nurseSignature,
);
requestDetailProvider.nurseReject();
Navigator.pop(context);
}
},
@ -1099,11 +1055,11 @@ class ServiceRequestBottomSheet {
onPressed: () async {
if (newSignature != null && acknowledge) {
//TODO replace provider with new provider and also check workorder id is not correct.
Provider.of<RequestDetailProvider>(context, listen: false).nurseConfirm(
model: NurseActionModel(
workOrderId: int.parse(serviceRequestProvider.currentSelectedRequest!.id!),
signatureNurse: nurseSignature,
));
requestDetailProvider.nurseActionHelperModel=NurseActionHelperModel(
workOrderId: int.parse(requestDetailProvider.currentWorkOrder!.data!.workOrderNo!),
signatureNurse: nurseSignature,
);
requestDetailProvider.nurseConfirm();
Navigator.pop(context);
}
},

@ -10,6 +10,8 @@ import 'package:test_sa/extensions/string_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/enums/work_order_next_step.dart';
import 'package:test_sa/models/helper_data_models/asset_retired/asset_retired_model.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
@ -19,6 +21,7 @@ import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/service_request_latest/views/components/initial_visit_card.dart';
import 'package:test_sa/service_request_latest/views/components/timer_widget.dart';
import 'package:test_sa/service_request_latest/views/forms/asset_retired/asset_retired.dart';
import 'package:test_sa/service_request_latest/views/nurse/create_new_request_view.dart';
import 'package:test_sa/views/pages/user/requests/comments_bottom_sheet.dart';
import 'package:test_sa/views/pages/user/requests/update_service_request_page.dart';
@ -35,11 +38,10 @@ class WorkOrderDetailView extends StatelessWidget {
Widget build(BuildContext context) {
UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false);
return Consumer<RequestDetailProvider>(builder: (pContext, requestProvider, _) {
print(requestProvider?.currentWorkOrder?.toJson());
return requestProvider.isLoading
? const CircularProgressIndicator(color: AppColor.primary10).center
: requestProvider.currentWorkOrder == null
? NoDataFound()
? const NoDataFound()
: Stack(
children: [
Column(
@ -50,26 +52,29 @@ class WorkOrderDetailView extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
WorkOrderDetailCard(context, requestProvider.currentWorkOrder!.data!, _userProvider),
workOrderDetailCard(context, requestProvider.currentWorkOrder!.data!, _userProvider),
40.height,
// skipForLater(serviceRequestsProvider.currentSelectedRequest),
// 20.height,
const InitialVisitCard(),
//TODO need to get data from api ..
// const InitialVisitCard(),
20.height,
],
),
).expanded,
FooterActionButton.requestDetailsFooterWidget(status: 1, context: context),
FooterActionButton.requestDetailsFooterWidget(workOrderNextStepStatus: requestProvider.currentWorkOrder!.data!.nextStep!.workOrderNextStepEnum!, context: context),
],
),
const TimerWidget(),
// const TimerWidget(),
],
);
});
}
Widget WorkOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) {
Widget workOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) {
// print('callids i got is ${workOrder}')
print('work order next step value is ${workOrder.nextStep?.toJson()}');
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -274,300 +279,13 @@ class WorkOrderDetailView extends StatelessWidget {
// );
}),
//set condition for show asset detail button...
if (true) ...[
//assetRetiredButton(serviceRequest: serviceRequest),
if (workOrder.nextStep!.workOrderNextStepEnum==WorkOrderNextStepEnum.verifyAssetDetail||workOrder.nextStep!.workOrderNextStepEnum==WorkOrderNextStepEnum.activity) ...[
assetRetiredButton(context: context),
]
],
).toShadowContainer(context, padding: 0);
}
}
class RequestDetailView extends StatefulWidget {
static const String id = "/call-details";
ServiceRequest serviceRequest;
bool fromTabView = false;
RequestDetailView({Key? key, required this.serviceRequest, this.fromTabView = false}) : super(key: key);
@override
State<RequestDetailView> createState() => _RequestDetailViewState();
}
class _RequestDetailViewState extends State<RequestDetailView> {
@override
void initState() {
super.initState();
}
void getServiceRequest({@required dynamic requestId}) {
// setState(() {});
WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) async {
Provider.of<CommentsProvider>(context, listen: false).reset();
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
serviceRequestsProvider.currentSelectedRequest = await serviceRequestsProvider.getServiceRequestObjectById(requestId: requestId);
// setState(() {});
});
}
@override
Widget build(BuildContext context) {
UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false);
return !widget.fromTabView
? Scaffold(
appBar: DefaultAppBar(title: context.translation.serviceDetails),
body: Padding(
padding: EdgeInsets.only(top: 12.toScreenHeight),
child: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestsProvider, child) {
return requestDetailCard(serviceRequestsProvider: serviceRequestsProvider, userProvider: _userProvider);
}),
),
)
: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestsProvider, child) {
return requestDetailCard(serviceRequestsProvider: serviceRequestsProvider, userProvider: _userProvider);
});
}
Widget requestDetailCard({required ServiceRequestsProvider serviceRequestsProvider, required UserProvider userProvider}) {
return SafeArea(
child: serviceRequestsProvider.isDetialLoading
? const ALoading().center
: serviceRequestsProvider.currentSelectedRequest == null
? Text(
context.translation.noDataFound,
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
).center
: Stack(
children: [
SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
informationCard(serviceRequestsProvider.currentSelectedRequest!, userProvider),
40.height,
// skipForLater(serviceRequestsProvider.currentSelectedRequest),
// 20.height,
const InitialVisitCard(),
20.height,
],
),
),
FooterActionButton.requestDetailsFooterWidget(status: 7, context: context),
TimerWidget(),
],
),
);
}
Widget informationCard(ServiceRequest serviceRequest, UserProvider userProvider) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
StatusLabel(
label: serviceRequest.priority?.name,
id: serviceRequest.priority!.id!,
radius: 4,
textColor: AppColor.getPriorityStatusTextColor(context, serviceRequest.priority!.id!),
backgroundColor: AppColor.getPriorityStatusColor(context, serviceRequest.priority!.id!),
),
8.width,
StatusLabel(
radius: 4,
label: serviceRequest.statusLabel,
textColor: AppColor.getRequestStatusTextColor(context, serviceRequest.statusValue!),
backgroundColor: AppColor.getRequestStatusColor(context, serviceRequest.statusValue!),
),
1.width.expanded,
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (userProvider.user!.type == UsersTypes.normal_user)
context.translation.code.toSvgAsset(width: 48).onPress(() {
Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateServiceRequestPage(serviceRequest: serviceRequest)));
}),
if (userProvider.user!.type == UsersTypes.engineer) 16.height,
Text(
serviceRequest.date!.toServiceRequestCardFormat,
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
],
)
],
),
Text(
context.translation.assetDetails,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
'${context.translation.assetName}: ${serviceRequest.deviceEnName?.cleanupWhitespace?.capitalizeFirstOfEach}'.bodyText(context),
// 8.height,
Text(
'${context.translation.assetNumber}: ${serviceRequest.device?.assetNumber}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.equipmentStatus}: ${serviceRequest.defectType?.name}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.manufacture}: ${serviceRequest.device?.modelDefinition?.manufacturerName?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.model}: ${serviceRequest.device?.modelDefinition?.modelName?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.site}: ${serviceRequest.device?.site?.custName?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.building}: ${serviceRequest.device?.building?.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.floor}: ${serviceRequest.device?.floor?.name?.cleanupWhitespace?.capitalizeFirstOfEach ?? ""}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.department}: ${serviceRequest.device?.department?.departmentName?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.room}: ${(serviceRequest.device?.room?.name ?? "").cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
],
).expanded,
],
),
8.height,
const Divider().defaultStyle(context),
//... request details starts here....
Text(
context.translation.requestDetail,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
Text(
'${context.translation.requestType}: ${serviceRequest.type?.name}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.requestNo}: ${serviceRequest.requestCode}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
Text(
'${context.translation.requesterName}: ${serviceRequest.callCreatedBy?.name ?? "-"}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
8.height,
if ((serviceRequest.callComments ?? "").isNotEmpty) ...[
const Divider().defaultStyle(context),
8.height,
Text(
serviceRequest.callComments!,
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
),
],
if (serviceRequest.devicePhotos?.isNotEmpty ?? false) ...[
8.height,
const Divider().defaultStyle(context),
FilesList(images: serviceRequest.devicePhotos!),
],
if (serviceRequest.audio?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
16.height,
ASoundPlayer(audio: serviceRequest.audio!),
8.height,
],
],
).paddingOnly(start: 16, end: 16, top: 16, bottom: 8),
(userProvider.user!.type == UsersTypes.normal_user
? Container(
height: 50,
padding: const EdgeInsets.only(left: 16, right: 16),
alignment: Alignment.center,
width: double.infinity,
decoration: ShapeDecoration(
color: context.isDark ? AppColor.neutral50 : AppColor.neutral30,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
),
child: Row(
children: [
Text(
'${context.translation.commentHere}...',
style: AppTextStyles.heading6.copyWith(
color: (context.isDark ? AppColor.neutral30 : AppColor.neutral50).withOpacity(.6),
),
).expanded,
"comment_send".toSvgAsset(width: 24, color: context.isDark ? AppColor.primary50 : AppColor.primary70),
],
),
)
: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Divider().defaultStyle(context),
16.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
context.translation.viewComments,
style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)),
),
4.width,
Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14)
],
),
],
).paddingOnly(bottom: 16, start: 16, end: 16))
.onPress(() {
showModalBottomSheet(
context: context,
useSafeArea: true,
isScrollControlled: true,
useRootNavigator: true,
backgroundColor: Colors.transparent,
builder: (context) => CommentsBottomSheet(requestId: serviceRequest.id!),
);
}),
//set condition for show asset detail button...
if (true) ...[
assetRetiredButton(serviceRequest: serviceRequest),
]
],
).toShadowContainer(context, padding: 0);
}
Widget assetRetiredButton({required ServiceRequest serviceRequest}) {
Widget assetRetiredButton({required BuildContext context}) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.toScreenHeight, vertical: 12.toScreenWidth),
child: AppFilledButton(
@ -577,32 +295,333 @@ class _RequestDetailViewState extends State<RequestDetailView> {
textColor: AppColor.red30,
showBorder: true,
onPressed: () async {
// Navigator.push(context, MaterialPageRoute(builder: (context) => AssetRetired()));
Navigator.push(context, MaterialPageRoute(builder: (context) => CreateNewRequest()));
Navigator.push(context, MaterialPageRoute(builder: (context) => const AssetRetired()));
}),
);
}
Widget skipForLater(ServiceRequest serviceRequest) {
return Center(
child: InkWell(
onTap: () async {
try {
//use a common list
AllRequestsProvider allRequestProvider = Provider.of<AllRequestsProvider>(context, listen: false);
int index = allRequestProvider.requestDetailList!.requestsDetails!.indexWhere((element) => element.id.toString() == serviceRequest.id);
if (index != -1 && index != allRequestProvider.requestDetailList!.requestsDetails!.length) {
getServiceRequest(requestId: allRequestProvider.requestDetailList!.requestsDetails![index + 1].id.toString());
}
} catch (e) {
print(e);
}
},
child: Text(
context.translation.skipForLater,
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, decoration: TextDecoration.underline, fontSize: 16),
),
),
);
}
}
// class RequestDetailView extends StatefulWidget {
// static const String id = "/call-details";
// ServiceRequest serviceRequest;
// bool fromTabView = false;
//
// RequestDetailView({Key? key, required this.serviceRequest, this.fromTabView = false}) : super(key: key);
//
// @override
// State<RequestDetailView> createState() => _RequestDetailViewState();
// }
//
// class _RequestDetailViewState extends State<RequestDetailView> {
// @override
// void initState() {
// super.initState();
// }
//
// void getServiceRequest({@required dynamic requestId}) {
// // setState(() {});
// WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) async {
// Provider.of<CommentsProvider>(context, listen: false).reset();
// ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
// serviceRequestsProvider.currentSelectedRequest = await serviceRequestsProvider.getServiceRequestObjectById(requestId: requestId);
// // setState(() {});
// });
// }
//
// @override
// Widget build(BuildContext context) {
// UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false);
//
// return !widget.fromTabView
// ? Scaffold(
// appBar: DefaultAppBar(title: context.translation.serviceDetails),
// body: Padding(
// padding: EdgeInsets.only(top: 12.toScreenHeight),
// child: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestsProvider, child) {
// return requestDetailCard(serviceRequestsProvider: serviceRequestsProvider, userProvider: _userProvider);
// }),
// ),
// )
// : Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestsProvider, child) {
// return requestDetailCard(serviceRequestsProvider: serviceRequestsProvider, userProvider: _userProvider);
// });
// }
//
// Widget requestDetailCard({required ServiceRequestsProvider serviceRequestsProvider, required UserProvider userProvider}) {
// return SafeArea(
// child: serviceRequestsProvider.isDetialLoading
// ? const ALoading().center
// : serviceRequestsProvider.currentSelectedRequest == null
// ? Text(
// context.translation.noDataFound,
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ).center
// : Stack(
// children: [
// SingleChildScrollView(
// padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// informationCard(serviceRequestsProvider.currentSelectedRequest!, userProvider),
//
// 40.height,
// // skipForLater(serviceRequestsProvider.currentSelectedRequest),
// // 20.height,
// const InitialVisitCard(),
// 20.height,
// ],
// ),
// ),
// FooterActionButton.requestDetailsFooterWidget(status: 7, context: context),
// TimerWidget(),
// ],
// ),
// );
// }
//
// Widget informationCard(ServiceRequest serviceRequest, UserProvider userProvider) {
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// StatusLabel(
// label: serviceRequest.priority?.name,
// id: serviceRequest.priority!.id!,
// radius: 4,
// textColor: AppColor.getPriorityStatusTextColor(context, serviceRequest.priority!.id!),
// backgroundColor: AppColor.getPriorityStatusColor(context, serviceRequest.priority!.id!),
// ),
// 8.width,
// StatusLabel(
// radius: 4,
// label: serviceRequest.statusLabel,
// textColor: AppColor.getRequestStatusTextColor(context, serviceRequest.statusValue!),
// backgroundColor: AppColor.getRequestStatusColor(context, serviceRequest.statusValue!),
// ),
// 1.width.expanded,
// Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// if (userProvider.user!.type == UsersTypes.normal_user)
// context.translation.code.toSvgAsset(width: 48).onPress(() {
// Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateServiceRequestPage(serviceRequest: serviceRequest)));
// }),
// if (userProvider.user!.type == UsersTypes.engineer) 16.height,
// Text(
// serviceRequest.date!.toServiceRequestCardFormat,
// textAlign: TextAlign.end,
// style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
// ),
// ],
// )
// ],
// ),
// Text(
// context.translation.assetDetails,
// style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
// ),
// 8.height,
// '${context.translation.assetName}: ${serviceRequest.deviceEnName?.cleanupWhitespace?.capitalizeFirstOfEach}'.bodyText(context),
// // 8.height,
// Text(
// '${context.translation.assetNumber}: ${serviceRequest.device?.assetNumber}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
//
// Text(
// '${context.translation.equipmentStatus}: ${serviceRequest.defectType?.name}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.manufacture}: ${serviceRequest.device?.modelDefinition?.manufacturerName?.cleanupWhitespace?.capitalizeFirstOfEach}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.model}: ${serviceRequest.device?.modelDefinition?.modelName?.cleanupWhitespace?.capitalizeFirstOfEach}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.site}: ${serviceRequest.device?.site?.custName?.cleanupWhitespace?.capitalizeFirstOfEach}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.building}: ${serviceRequest.device?.building?.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.floor}: ${serviceRequest.device?.floor?.name?.cleanupWhitespace?.capitalizeFirstOfEach ?? ""}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.department}: ${serviceRequest.device?.department?.departmentName?.cleanupWhitespace?.capitalizeFirstOfEach}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.room}: ${(serviceRequest.device?.room?.name ?? "").cleanupWhitespace?.capitalizeFirstOfEach}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// ],
// ).expanded,
// ],
// ),
// 8.height,
// const Divider().defaultStyle(context),
//
// //... request details starts here....
// Text(
// context.translation.requestDetail,
// style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
// ),
// 8.height,
// Text(
// '${context.translation.requestType}: ${serviceRequest.type?.name}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.requestNo}: ${serviceRequest.requestCode}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// Text(
// '${context.translation.requesterName}: ${serviceRequest.callCreatedBy?.name ?? "-"}',
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
//
// 8.height,
// if ((serviceRequest.callComments ?? "").isNotEmpty) ...[
// const Divider().defaultStyle(context),
// 8.height,
// Text(
// serviceRequest.callComments!,
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
// ),
// ],
// if (serviceRequest.devicePhotos?.isNotEmpty ?? false) ...[
// 8.height,
// const Divider().defaultStyle(context),
// FilesList(images: serviceRequest.devicePhotos!),
// ],
// if (serviceRequest.audio?.isNotEmpty ?? false) ...[
// const Divider().defaultStyle(context),
// 16.height,
// ASoundPlayer(audio: serviceRequest.audio!),
// 8.height,
// ],
// ],
// ).paddingOnly(start: 16, end: 16, top: 16, bottom: 8),
// (userProvider.user!.type == UsersTypes.normal_user
// ? Container(
// height: 50,
// padding: const EdgeInsets.only(left: 16, right: 16),
// alignment: Alignment.center,
// width: double.infinity,
// decoration: ShapeDecoration(
// color: context.isDark ? AppColor.neutral50 : AppColor.neutral30,
// shape: const RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(20),
// bottomRight: Radius.circular(20),
// ),
// ),
// ),
// child: Row(
// children: [
// Text(
// '${context.translation.commentHere}...',
// style: AppTextStyles.heading6.copyWith(
// color: (context.isDark ? AppColor.neutral30 : AppColor.neutral50).withOpacity(.6),
// ),
// ).expanded,
// "comment_send".toSvgAsset(width: 24, color: context.isDark ? AppColor.primary50 : AppColor.primary70),
// ],
// ),
// )
// : Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const Divider().defaultStyle(context),
// 16.height,
// Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// Text(
// context.translation.viewComments,
// style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)),
// ),
// 4.width,
// Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14)
// ],
// ),
// ],
// ).paddingOnly(bottom: 16, start: 16, end: 16))
// .onPress(() {
// showModalBottomSheet(
// context: context,
// useSafeArea: true,
// isScrollControlled: true,
// useRootNavigator: true,
// backgroundColor: Colors.transparent,
// builder: (context) => CommentsBottomSheet(requestId: serviceRequest.id!),
// );
// }),
// //set condition for show asset detail button...
// if (true) ...[
// assetRetiredButton(serviceRequest: serviceRequest),
// ]
// ],
// ).toShadowContainer(context, padding: 0);
// }
//
// Widget assetRetiredButton({required ServiceRequest serviceRequest}) {
// return Padding(
// padding: EdgeInsets.symmetric(horizontal: 16.toScreenHeight, vertical: 12.toScreenWidth),
// child: AppFilledButton(
// label: context.translation.assetToBeRetired,
// maxWidth: true,
// buttonColor: Colors.white54,
// textColor: AppColor.red30,
// showBorder: true,
// onPressed: () async {
// // Navigator.push(context, MaterialPageRoute(builder: (context) => AssetRetired()));
// Navigator.push(context, MaterialPageRoute(builder: (context) => CreateNewRequest()));
// }),
// );
// }
//
// Widget skipForLater(ServiceRequest serviceRequest) {
// return Center(
// child: InkWell(
// onTap: () async {
// try {
// //use a common list
// AllRequestsProvider allRequestProvider = Provider.of<AllRequestsProvider>(context, listen: false);
// int index = allRequestProvider.requestDetailList!.requestsDetails!.indexWhere((element) => element.id.toString() == serviceRequest.id);
// if (index != -1 && index != allRequestProvider.requestDetailList!.requestsDetails!.length) {
// getServiceRequest(requestId: allRequestProvider.requestDetailList!.requestsDetails![index + 1].id.toString());
// }
// } catch (e) {
// print(e);
// }
// },
// child: Text(
// context.translation.skipForLater,
// style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, decoration: TextDecoration.underline, fontSize: 16),
// ),
// ),
// );
// }
// }

@ -7,18 +7,41 @@ 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/new_models/arrival_verification_type_model.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/service_request_latest/views/components/scan_qr_view.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/verify_otp_view.dart';
import 'package:test_sa/service_request_latest/views/forms/asset_retired/asset_retired.dart';
import 'package:test_sa/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart';
import 'package:test_sa/views/widgets/qr/scan_qr.dart';
import 'activities_list_view.dart';
class VerifyArrivalView extends StatelessWidget {
VerifyArrivalView({Key? key}) : super(key: key);
class VerifyArrivalView extends StatefulWidget {
const VerifyArrivalView({Key? key}) : super(key: key);
@override
State<VerifyArrivalView> createState() => _VerifyArrivalViewState();
}
class _VerifyArrivalViewState extends State<VerifyArrivalView> {
ArrivalVerificationTypeModel ? arrivalVerificationTypeModel;
@override
void initState() {
//TODO call this when all data is confirmed
// getInitialData();
super.initState();
}
Future<void> getInitialData() async{
RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context,listen: false);
arrivalVerificationTypeModel = await requestDetailProvider.getArrivalVerificationType();
}
Widget build(BuildContext context) {
//TODO replace the list with Api...
final List<Map<String, String>> items = [
{'heading': context.translation.scanQr, 'subHeading': context.translation.scanQrDetail, 'icon': AppAsset.scanQrIcon},
{'heading': context.translation.askRequester, 'subHeading': context.translation.askRequesterDetail, 'icon': AppAsset.askRequesterIcon},
@ -28,83 +51,108 @@ class VerifyArrivalView extends StatelessWidget {
return Scaffold(
appBar: DefaultAppBar(title: context.translation.verifyArrival),
//backgroundColor: const Color(0xfff8f9fb),
body: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestsProvider, child) {
body: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return SafeArea(
child: ListView.builder(
padding: EdgeInsets.symmetric(vertical: 12.toScreenHeight),
// padding: EdgeInsets.zero,
padding: EdgeInsets.zero,
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return listItem(
return customListItem(
icon: item['icon']!,
heading: item['heading']!,
subHeading: item['subHeading']!,
context: context,
onTap: () {
onItemTap(serviceRequest: serviceRequestsProvider.currentSelectedRequest!, index: index,context: context);
onItemTap(requestDetailProvider: requestDetailProvider, index: index, context: context);
});
},
),
).paddingOnly(start: 16, end: 16, top: 12, bottom: 12),
);
}),
);
}
Widget listItem({required BuildContext context, required String icon, required String heading, required String subHeading, required VoidCallback onTap}) {
return Padding(
padding: EdgeInsets.only(left: 16.toScreenWidth,right: 16.toScreenWidth,bottom: 12.toScreenHeight),
Widget customListItem({
required BuildContext context,
required String icon,
required String heading,
required String subHeading,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap, // Handles the tap
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14), // Circular border radius
),
color: Colors.white,
child:
ListTile(
minVerticalPadding: 12,
horizontalTitleGap: 10,
onTap: onTap,
// contentPadding: const EdgeInsets.all(12),
leading: SvgPicture.asset(icon),
title: Text(
heading,
style: AppTextStyles.heading5,
),
subtitle: Text(
subHeading,
style: AppTextStyles.bodyText,
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, // Align items at the top
children: [
// Icon Section
icon
.toSvgAsset(
width: 32,
color: AppColor.neutral120,
height: 29,
)
.paddingOnly(top: 8),
14.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
heading,
style: AppTextStyles.heading6.copyWith(color: AppColor.neutral50),
),
7.height,
Text(
subHeading,
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
],
).paddingOnly(end: 50),
),
],
).paddingAll(12),
),
);
}
void onItemTap({required int index, required ServiceRequest serviceRequest,required BuildContext context}) {
switch(index){
void onItemTap({required int index, required RequestDetailProvider requestDetailProvider, required BuildContext context}) {
switch (index) {
case 0:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ScanQrView()),
);
break;case 1:
//push to specific screen...
Navigator.push(
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => const ActivitiesListView()),
// );
break;
case 1:
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => const AssetRetired()),
// );
break;
case 2:
//TODO api has error need to fixed by ahmed...
// requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!);
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => ActivitiesListView()),
MaterialPageRoute(builder: (context) => const VerifyOtpView()),
);
break;case 2:
//push to specific screen...
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => const ScanQrView()),
// );
break;case 2:
//push to specific screen...
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => const ScanQrView()),
// );
break;
case 3:
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => const VerifyAssetDetails()),
// );
//push to specific screen...
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => const ScanQrView()),
// );
break;
}
// ScanQr

@ -1,247 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/parts_provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_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/device/asset.dart';
import 'package:test_sa/models/service_request/service_report.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/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../../models/lookup.dart';
import '../../../../../models/service_request/spare_parts.dart';
import '../../../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../../../new_views/common_widgets/default_app_bar.dart';
import '../../../controllers/validator/validator.dart';
class VerifyAssetDetail extends StatefulWidget {
static const String id = "/verify-assets-detail";
const VerifyAssetDetail({Key? key}) : super(key: key);
@override
_VerifyAssetDetailState createState() => _VerifyAssetDetailState();
}
class _VerifyAssetDetailState extends State<VerifyAssetDetail> with TickerProviderStateMixin {
late UserProvider _userProvider;
late SettingProvider _settingProvider;
late ServiceRequestsProvider _serviceRequestsProvider;
late ServiceStatusProvider _assetTypeProvider;
late PartsProvider _partsProvider;
late ServiceReport _serviceReport;
bool _isLoading = false;
List<SparePart> _spareParts = [];
final List<File> _files = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final TextEditingController _faultController = TextEditingController();
final TextEditingController _workPreformedController = TextEditingController();
final TextEditingController _partQtyController = TextEditingController();
final TextEditingController _oracleNoController = TextEditingController();
@override
void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
super.initState();
if (context.mounted) {
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
Provider.of<ServiceReportLastCallsProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).serviceRequestId = serviceRequestsProvider.currentSelectedRequest!.id;
}
// _isLoading = true;
}
@override
void dispose() {
_faultController.dispose();
_workPreformedController.dispose();
_partQtyController.dispose();
super.dispose();
}
void getRequestForWorkOrder() async {
_isLoading = true;
setState(() {});
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
_serviceReport.callRequest = await _serviceRequestsProvider.getCallRequestForWorkOrder(callId: serviceRequestsProvider.currentSelectedRequest!.id!);
await _assetTypeProvider.getTypes();
_serviceReport.assignedEmployee = _serviceReport.callRequest?.assignedEmployee;
_serviceReport.equipmentStatus = _serviceReport.callRequest?.defectType;
_serviceReport.serviceType = Lookup(id: 65, name: "Interval", value: 1); // default value in service type as in web
_spareParts = await _partsProvider.getPartsList(assetId: serviceRequestsProvider.currentSelectedRequest!.deviceId!);
_isLoading = false;
setState(() {});
}
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
_partsProvider = Provider.of<PartsProvider>(context);
if (_serviceReport.callRequest == null) {
getRequestForWorkOrder();
}
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
(element) => element.value == _serviceReport.callRequest?.assetType,
orElse: null,
);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.verify_asset_details),
body: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
return SafeArea(
child: LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Form(
key: _formKey,
child: Column(
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
context.translation.sparePartDetails.heading5(context),
12.height,
SingleItemDropDownMenu<SparePart, NullableLoadingProvider>(
context: context,
title: context.translation.partNo,
staticData: _spareParts,
height: 80.toScreenHeight,
showShadow: false,
initialValue: serviceRequestProvider.initialSelectedSparePart.sparePart,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
onSelect: (part) {
serviceRequestProvider.initialSelectedSparePart = SparePartsWorkOrders(id: 0, sparePart: part, qty: 0);
},
),
15.height,
AppTextFormField(
controller: _partQtyController,
labelText: context.translation.quantity,
textInputType: TextInputType.number,
contentPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 20.toScreenHeight),
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: serviceRequestProvider.initialSelectedSparePart != null && serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
onSaved: (text) {
serviceRequestProvider.initialSelectedSparePart.qty = num.tryParse(text ?? "");
},
),
15.height,
AppTextFormField(
controller: _oracleNoController,
labelText: context.translation.oracleNo,
textInputType: TextInputType.number,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
onSaved: (text) {
//TODO set the values...
// serviceRequestProvider.initialSelectedSparePart. = num.tryParse(text ?? "");
},
),
15.height,
AppTextFormField(
initialValue: _serviceReport.comment,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
labelText: context.translation.description,
alignLabelWithHint: true,
labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.black10),
showWithoutDecoration: true,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceReport.comment = value;
},
),
15.height,
MultiFilesPicker(label: context.translation.attachQuotation, files: _files),
],
).paddingAll(12),
),
8.height,
],
),
).paddingAll(16).expanded,
FooterActionButton.footerContainer(child: AppFilledButton(
label: context.translation.addSparePartActivity,
buttonColor: AppColor.green70,
onPressed: () async {
ServiceRequestBottomSheet.actionBottomSheet(context: context, title: context.translation.addSparePartActionHeading);
// bool shouldReloadData = (await showModalBottomSheet(
// context: context,
// useSafeArea: true,
// isScrollControlled: true,
// backgroundColor: Colors.transparent,
// builder: (context) => ActionBottomSheet(title: context.translation.addSparePartActionHeading),
// )) as bool;
// if (shouldReloadData ?? false) {}
//TODO write add sparepart logic
// if ((!_formKey.currentState.validate()) || (!(await _serviceReport.validate(context)))) {
// setState(() {});
// return;
// }
// _formKey.currentState.save();
// _serviceReport.attachmentsWorkOrder ??= [];
// if (_files.isEmpty) _serviceReport.attachmentsWorkOrder = [];
// for (var file in _files) {
// _serviceReport.attachmentsWorkOrder.add(Attachment(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"));
// }
// final user = Provider.of<UserProvider>(context, listen: false).user;
// await _serviceRequestsProvider.createServiceReport(context, report: _serviceReport, request: serviceRequestProvider.serviceRequest, user: user);
},
)),
],
),
),
),
);
}),
);
}
}

@ -1,11 +1,14 @@
import 'package:flutter/material.dart';
import 'package:pinput/pinput.dart';
import 'package:provider/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/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/request_detail_main_view.dart';
class VerifyOtpView extends StatelessWidget {
const VerifyOtpView({Key? key}) : super(key: key);
@ -22,7 +25,6 @@ class VerifyOtpView extends StatelessWidget {
decoration: BoxDecoration(
color: AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.transparent),
),
);
return Scaffold(
@ -32,90 +34,97 @@ class VerifyOtpView extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
12.height,
SizedBox(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 16.toScreenWidth, bottom: 16.toScreenHeight, top: 12.toScreenHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
context.translation.verify.heading5(context),
12.height,
context.translation.otpSentToNumber.bodyText(context),
Padding(
padding: EdgeInsets.symmetric(
vertical: 50.toScreenHeight,
),
child: Center(
child: Pinput(
length: 4,
defaultPinTheme: defaultPinTheme,
focusedPinTheme: defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration?.copyWith(
border: Border.all(color: AppColor.neutral100),
),
),
onCompleted: (pin) => debugPrint(pin),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
context.translation.verify.heading6(context).custom(color: AppColor.black10),
7.height,
context.translation.otpSentToNumber.bodyText2(context).custom(color: AppColor.neutral120),
Center(
child: Pinput(
length: 4,
defaultPinTheme: defaultPinTheme,
focusedPinTheme: defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration?.copyWith(
border: Border.all(color: AppColor.neutral100),
),
),
Row(
children: [
context.translation.resendIn.bodyText(context),
7.width,
ValueListenableBuilder<String>(
//add actual timer value...
valueListenable: ValueNotifier("0:00"),
builder: (context, value, _) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
value.bodyText(context).custom(
color: context.isDark ? AppColor.neutral10 : AppColor.neutral20,
onCompleted: (pin) async {
debugPrint('pin i got is $pin');
RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
int? status;
status = await requestDetailProvider.verifyOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, otpCode: pin);
print('status i got is $status');
if (status == 200) {
await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
await requestDetailProvider.engineerConfirmArrival(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!,verificationTypeId: 3,photoInfo: '',otp: pin);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!)));
}
},
),
).paddingOnly(top: 24, bottom: 24),
Row(
children: [
context.translation.resendIn.bodyText2(context).custom(color: AppColor.neutral120),
7.width,
ValueListenableBuilder<String>(
//add actual timer value...
valueListenable: ValueNotifier("0:00"),
builder: (context, value, _) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
value.bodyText2(context).custom(
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
),
],
);
},
),
7.width,
InkWell(
onTap: (){
//other method check..
},
child: Text(context.translation.resend,style: const TextStyle(
color: AppColor.primary10,
decoration: TextDecoration.underline,
),),
],
);
},
),
7.width,
InkWell(
onTap: () {},
child: Text(
context.translation.resend,
style: TextStyle(
color: AppColor.primary10,
fontWeight: FontWeight.w500,
fontSize: 12.toScreenWidth,
decorationColor: AppColor.primary10,
decoration: TextDecoration.underline,
),
],
),
),
],
),
),
).toShadowContainer(context).paddingOnly(start: 16, end: 16),
Padding(
padding: EdgeInsets.only(left: 17.toScreenWidth, top: 24.toScreenHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
context.translation.havingTroubleReceivingOtp.heading6(context),
3.height,
InkWell(
onTap: (){
//other method check..
},
child: Text(context.translation.checkOutOtherMethods,style: const TextStyle(
],
).toShadowContainer(context),
24.height,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
context.translation.havingTroubleReceivingOtp.heading6(context).custom(color: AppColor.black10),
3.height,
InkWell(
onTap: () {
//other method check..
},
child: Text(
context.translation.checkOutOtherMethods,
style: TextStyle(
color: AppColor.primary10,
fontSize: 16.toScreenWidth,
fontWeight: FontWeight.w500,
decoration: TextDecoration.underline,
),),
decorationColor: AppColor.primary10,
),
),
],
),
),
],
)
],
),
).paddingOnly(start: 16, end: 16, top: 12),
),
);
}

@ -1,29 +1,24 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_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/device/asset.dart';
import 'package:test_sa/models/service_request/service_report.dart';
import 'package:test_sa/models/helper_data_models/asset_retired/asset_retired_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/app_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/providers/work_order/retirement_type_provider.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import '../../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../../../models/lookup.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
class AssetRetired extends StatefulWidget {
static const String id = "/asset-tobe-retired";
@ -34,62 +29,43 @@ class AssetRetired extends StatefulWidget {
}
class _AssetRetiredState extends State<AssetRetired> with TickerProviderStateMixin {
ServiceRequestsProvider? _serviceRequestsProvider;
ServiceStatusProvider ?_assetTypeProvider;
ServiceReport ?_serviceReport;
RequestDetailProvider? _requestDetailProvider;
RetirementTypeProvider? _retirementTypeProvider;
bool _isLoading = false;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
super.initState();
if (context.mounted) {
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
Provider.of<ServiceReportLastCallsProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).serviceRequestId = serviceRequestsProvider.currentSelectedRequest?.id;
_requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
_retirementTypeProvider = Provider.of<RetirementTypeProvider>(context, listen: false);
_requestDetailProvider?.assetRetiredHelperModel = AssetRetiredHelperModel(id: 0, workOrderId: _requestDetailProvider?.currentWorkOrder!.data!.requestId, activityAssetToBeRetiredAttachments: []);
_retirementTypeProvider?.serviceRequestId = _requestDetailProvider?.currentWorkOrder!.data!.requestId.toString();
WidgetsBinding.instance.addPostFrameCallback((_) {
_retirementTypeProvider?.getDate();
});
}
// _isLoading = true;
}
void getRequestForWorkOrder() async {
_isLoading = true;
setState(() {});
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
_serviceReport?.callRequest = await _serviceRequestsProvider?.getCallRequestForWorkOrder(callId: serviceRequestsProvider.currentSelectedRequest?.id??'0');
await _assetTypeProvider?.getTypes();
_serviceReport?.assignedEmployee = _serviceReport?.callRequest?.assignedEmployee;
_serviceReport?.equipmentStatus = _serviceReport?.callRequest?.defectType;
_serviceReport?.serviceType = Lookup(id: 65, name: "Interval", value: 1); // default value in service type as in web
_isLoading = false;
setState(() {});
}
@override
Widget build(BuildContext context) {
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
if (_serviceReport?.callRequest == null) {
getRequestForWorkOrder();
}
_serviceReport?.assetType = _assetTypeProvider?.statuses?.firstWhere(
(element) => element.value == _serviceReport?.callRequest?.assetType,
orElse: () => Lookup(),
);
// _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
// _assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
// if (_serviceReport?.callRequest == null) {
// getRequestForWorkOrder();
// }
// _serviceReport?.assetType = _assetTypeProvider?.statuses?.firstWhere(
// (element) => element.value == _serviceReport?.callRequest?.assetType,
// orElse: () => Lookup(),
// );
final List<File> _files = [];
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.assetToBeRetired),
body: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
body: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return SafeArea(
child: LoadingManager(
isLoading: _isLoading,
@ -105,16 +81,18 @@ class _AssetRetiredState extends State<AssetRetired> with TickerProviderStateMix
child: Column(
children: [
12.height,
SingleItemDropDownMenu<Lookup, ReasonProvider>(
//TODO replace with correct provider..
SingleItemDropDownMenu<Lookup, RetirementTypeProvider>(
context: context,
title: context.translation.failureReason,
title: context.translation.retirementType,
backgroundColor: AppColor.neutral100,
height: 56.toScreenHeight,
showShadow: false,
// initialValue: _subWorkOrders.reason,
initialValue: requestDetailProvider.assetRetiredHelperModel?.retirmentReason,
onSelect: (value) {
if (value != null) {
// _subWorkOrders.reason = value;
requestDetailProvider.assetRetiredHelperModel?.retirmentReason = value;
}
},
),
@ -127,19 +105,20 @@ class _AssetRetiredState extends State<AssetRetired> with TickerProviderStateMix
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100,
alignLabelWithHint: true,
onChange: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.assetRetiredHelperModel?.retirementComment = text;
},
onSaved: (text) {
serviceRequestProvider.currentSelectedRequest?.comments = text;
requestDetailProvider.assetRetiredHelperModel?.retirementComment = text;
},
),
23.height,
MultiFilesPicker(label: context.translation.attachFiles,
MultiFilesPicker(
label: context.translation.attachFiles,
files: _files,
buttonIcon: 'image-plus'.toSvgAsset(),
buttonIcon: 'image-plus'.toSvgAsset(),
),
],
).paddingOnly(start:13,end: 13,top: 14,bottom: 16),
).paddingOnly(start: 13, end: 13, top: 14, bottom: 16),
).paddingAll(16),
).expanded,
FooterActionButton.footerContainer(
@ -147,6 +126,15 @@ class _AssetRetiredState extends State<AssetRetired> with TickerProviderStateMix
label: context.translation.submit,
buttonColor: AppColor.primary10,
onPressed: () async {
for (var file in _files) {
requestDetailProvider.assetRetiredHelperModel?.activityAssetToBeRetiredAttachments
?.add(ActivityAssetToBeRetiredAttachments(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"));
}
// print('attachments i got is ${}');
//TODO uncommit this when all data is confirmed...
print('data i got is ${requestDetailProvider.assetRetiredHelperModel?.toJson()}');
requestDetailProvider.createActivityAssetToBeRetired();
Navigator.pop(context);
//
},
),

@ -1,29 +1,30 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/parts_provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/service_request/service_report.dart';
import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart';
import 'package:test_sa/models/new_models/work_order_detail_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/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart';
import 'package:test_sa/providers/service_request_providers/loan_availability_provider.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/equipment/pick_asset.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import '../../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../../../models/lookup.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
//TODO Have some details need to confirm from backend failure reason, fault description, solutions...
class VerifyAssetDetails extends StatefulWidget {
static const String id = "/verify-asset-detail";
@ -34,63 +35,61 @@ class VerifyAssetDetails extends StatefulWidget {
}
class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProviderStateMixin {
ServiceRequestsProvider? _serviceRequestsProvider;
ServiceStatusProvider ?_assetTypeProvider;
ServiceReport? _serviceReport;
RequestDetailProvider? _requestDetailProvider;
LoanAvailabilityProvider? _loanAvailabilityProvider;
ServiceRequestFaultDescriptionProvider? _faultDescriptionProvider;
EquipmentStatusProvider? _equipmentStatusProvider;
ReasonProvider? _reasonProvider;
bool _isLoading = false;
Asset? loanAvailabilityAsset;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
int _selectedValue = 1;
var loanAvailabilityAsset;
@override
void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
super.initState();
if (context.mounted) {
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
Provider.of<ServiceReportLastCallsProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).serviceRequestId = serviceRequestsProvider.currentSelectedRequest?.id;
}
// _isLoading = true;
scheduleMicrotask(() async {
await getInitialData();
});
// WidgetsBinding.instance.addPostFrameCallback((_) {
// });
}
void getRequestForWorkOrder() async {
Future<void> getInitialData() async {
//TODO ask skinder how to called getdata methods automatically...
_isLoading = true;
setState(() {});
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
_serviceReport?.callRequest = await _serviceRequestsProvider?.getCallRequestForWorkOrder(callId: serviceRequestsProvider.currentSelectedRequest?.id??'0');
await _assetTypeProvider?.getTypes();
_serviceReport?.assignedEmployee = _serviceReport?.callRequest?.assignedEmployee;
_serviceReport?.equipmentStatus = _serviceReport?.callRequest?.defectType;
_serviceReport?.serviceType = Lookup(id: 65, name: "Interval", value: 1); // default value in service type as in web
_requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
_reasonProvider = Provider.of<ReasonProvider>(context, listen: false);
_faultDescriptionProvider = Provider.of<ServiceRequestFaultDescriptionProvider>(context, listen: false);
_loanAvailabilityProvider = Provider.of<LoanAvailabilityProvider>(context, listen: false);
_equipmentStatusProvider = Provider.of<EquipmentStatusProvider>(context, listen: false);
_reasonProvider?.serviceRequestId = _requestDetailProvider?.currentWorkOrder!.data!.requestId.toString();
_reasonProvider?.getDate();
_equipmentStatusProvider?.getDate();
_loanAvailabilityProvider?.getDate();
//TODO no need to create seprate models just write a method in workorder model...
WorkOrderData currentWorkOrderData = _requestDetailProvider!.currentWorkOrder!.data!;
_requestDetailProvider?.engineerUpdateWorkOrderHelperModel = EngineerUpdateWorkOrderHelperModel(
workOrderId: currentWorkOrderData.requestId,
equipmentStatus: currentWorkOrderData.equipmentStatus,
loanAvailability: currentWorkOrderData.loanAvailablity,
failureReason: currentWorkOrderData.failureReasone,
faultDescription: currentWorkOrderData.problemDescription,
solution: currentWorkOrderData.solution?.name,
returnToService: currentWorkOrderData.returnToService,
serviceType: currentWorkOrderData.serviceType,
);
_requestDetailProvider?.updateEngineerUpdateWorkOrderHelperModel(_requestDetailProvider?.engineerUpdateWorkOrderHelperModel);
_isLoading = false;
setState(() {});
}
@override
Widget build(BuildContext context) {
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
if (_serviceReport?.callRequest == null) {
getRequestForWorkOrder();
}
_serviceReport?.assetType = _assetTypeProvider?.statuses?.firstWhere(
(element) => element.value == _serviceReport?.callRequest?.assetType,
orElse: () => Lookup(),
);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.verify_asset_details),
body: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
body: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return SafeArea(
child: LoadingManager(
isLoading: _isLoading,
@ -106,76 +105,68 @@ class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProv
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
context.translation.equipmentStatus.bodyText(context).custom(color: AppColor.black20),
12.height,
assetStatusWidget(context),
equipmentStatusWidget(context: context, workOrderData: requestDetailProvider.engineerUpdateWorkOrderHelperModel!),
24.height,
ADatePicker(
label: context.translation.returnToService,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""),
date: DateTime.tryParse(requestDetailProvider.engineerUpdateWorkOrderHelperModel?.returnToService ?? ""),
formatDateWithTime: true,
onDatePicker: (selectedDate) {
if (selectedDate != null) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime? selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (selectedDateTime != null) {
if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) {
"Visit Date time must be greater then request date".showToast;
return;
}
setState(() {
serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime.toIso8601String();
});
print('start date i got is ${serviceRequestProvider.currentSelectedRequest?.startDate}');
}
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime? selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel?.returnToService != null &&
selectedDateTime.isBefore(DateTime.parse(requestDetailProvider.engineerUpdateWorkOrderHelperModel!.returnToService!))) {
"Visit Date time must be greater then previous date".showToast;
return;
}
});
}
setState(() {
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.returnToService = selectedDateTime.toIso8601String();
});
}
});
},
),
8.height,
SingleItemDropDownMenu<Lookup, LoanAvailabilityProvider>(
context: context,
title: context.translation.loanAvailability,
backgroundColor: AppColor.neutral100,
height: 56.toScreenHeight,
initialValue: _serviceReport?.loanAvailablity,
initialValue: requestDetailProvider.engineerUpdateWorkOrderHelperModel?.loanAvailability,
onSelect: (status) {
if (status != null) {
setState(() {
_serviceReport?.loanAvailablity = status;
if (_serviceReport?.loanAvailablity?.value != 1) {
// loanAvailabilityAsset = null;
_serviceReport?.assetLoan = null;
}
});
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.loanAvailability = status;
if (status.value != 1) {
loanAvailabilityAsset = null;
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.loanAssetId = null;
}
}
setState(() {});
},
),
if (_serviceReport?.loanAvailablity?.value == 1) 8.height,
if (_serviceReport?.loanAvailablity?.value == 1)
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel?.loanAvailability?.value == 1) 8.height,
if (requestDetailProvider.engineerUpdateWorkOrderHelperModel?.loanAvailability?.value == 1)
PickAsset(
device: loanAvailabilityAsset, // ?? _serviceReport.device,
cardColor: AppColor.neutral100,
onPickAsset: (asset) {
if (asset != null) {
_serviceReport?.assetLoan = AssetInfo.fromJson(asset.toJson());
setState(() {
loanAvailabilityAsset = asset;
});
}
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.loanAssetId = asset.id;
setState(() {
loanAvailabilityAsset = asset;
});
},
),
8.height,
@ -185,44 +176,45 @@ class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProv
backgroundColor: AppColor.neutral100,
height: 56.toScreenHeight,
showShadow: false,
// initialValue: _subWorkOrders.reason,
initialValue: requestDetailProvider.engineerUpdateWorkOrderHelperModel?.failureReason,
onSelect: (value) {
if (value != null) {
// _subWorkOrders.reason = value;
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.failureReason = value;
}
},
),
8.height,
SingleItemDropDownMenu<Lookup, ReasonProvider>(
context: context,
title: context.translation.faultDescription,
backgroundColor: AppColor.neutral100,
height: 56.toScreenHeight,
showShadow: false,
// initialValue: _subWorkOrders.reason,
onSelect: (value) {
if (value != null) {
// _subWorkOrders.reason = value;
}
},
),
//TODO replace this with correct provider api will be provided by ahmed with solutions data as well...
// ServiceReportFaultDescription(
// requestId: requestDetailProvider.currentServiceRequestId?.toString(),
// initialValue: requestDetailProvider.engineerUpdateWorkOrderHelperModel.faultDescription,
// onSelect: (status) {
// requestDetailProvider.engineerUpdateWorkOrderHelperModel.faultDescription = status;
// _workPreformedController.text = _subWorkOrders.faultDescription?.workPerformed ?? "";
// },
// ),
11.height,
context.translation.solutions.heading6(context).custom(color: AppColor.neutral50),
11.height,
//TODO solution from api...
'Solution number one \nSolution number two'.heading6(context).custom(color: AppColor.neutral50),
requestDetailProvider.engineerUpdateWorkOrderHelperModel?.solution != null
? requestDetailProvider.engineerUpdateWorkOrderHelperModel!.solution!.heading6(context).custom(color: AppColor.neutral50)
: const SizedBox(),
],
).paddingOnly(start:13,end: 13,top: 16,bottom: 16),
).paddingOnly(top: 17,start: 14,end: 14),
).paddingOnly(start: 13, end: 13, top: 16, bottom: 16),
).paddingOnly(top: 17, start: 14, end: 14),
).expanded,
Container(
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth,vertical: 16.toScreenHeight),
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 16.toScreenHeight),
color: AppColor.white10,
child: AppFilledButton(
label: context.translation.verify_asset_details,
buttonColor: AppColor.primary10,
onPressed: () async {
//TODO uncommit this when all informations are confirmed...
print('model is ${requestDetailProvider.engineerUpdateWorkOrderHelperModel?.toJson()}');
await requestDetailProvider.engineerUpdateWorkOrder();
Navigator.pop(context);
},
),
),
@ -235,50 +227,47 @@ class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProv
);
}
Widget assetStatusWidget(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
radioButtonWidget(label: context.translation.up_and_running, value: 1),
radioButtonWidget(label: context.translation.partially_down, value: 2),
radioButtonWidget(label: context.translation.fully_down, value: 3),
],
);
}
Widget radioButtonWidget({required String label, required dynamic value}) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 20.toScreenWidth,
height: 40.toScreenHeight,
//TODO use the type required according data..
child:Radio<int>(
value: value,
groupValue: _selectedValue,
fillColor: WidgetStateProperty.resolveWith((states) {
// active
if (states.contains(WidgetState.selected)) {
return AppColor.primary10;
}
// inactive
return AppColor.neutral130;
}),
onChanged: (int ?value) {
setState(() {
_selectedValue = value!;
});
},
),
),
8.width,
Text(
label,
style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120),
),
13.width,
],
);
Widget equipmentStatusWidget({required BuildContext context, required EngineerUpdateWorkOrderHelperModel workOrderData}) {
return Consumer<EquipmentStatusProvider>(builder: (cxt, snapshot, _) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
context.translation.equipmentStatus.bodyText(context).custom(color: AppColor.black20),
8.height,
Wrap(
runSpacing: 8,
spacing: 8,
children: [
for (var element in snapshot.items)
Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 24,
height: 24,
child: Radio(
value: element,
activeColor: Colors.red,
fillColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) return AppColor.primary10;
return AppColor.neutral130;
}),
groupValue: workOrderData.equipmentStatus,
onChanged: (state) {
setState(() {
workOrderData.equipmentStatus = element;
});
}),
),
8.width,
Text(element.name ?? '', style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120)),
],
)
],
).toShimmer(isShow: snapshot.loading),
],
);
});
}
}

@ -1,28 +1,23 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/parts_provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_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/service_request/service_report.dart';
import 'package:test_sa/models/helper_data_models/spare_part/activity_spare_part_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/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import '../../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../../../models/lookup.dart';
import '../../../../../../models/service_request/spare_parts.dart';
import '../../../../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
@ -31,87 +26,68 @@ import '../../../../controllers/validator/validator.dart';
class SparePartRequest extends StatefulWidget {
static const String id = "/spare-part-request";
const SparePartRequest({Key ?key}) : super(key: key);
const SparePartRequest({Key? key}) : super(key: key);
@override
_SparePartRequestState createState() => _SparePartRequestState();
}
class _SparePartRequestState extends State<SparePartRequest> with TickerProviderStateMixin {
UserProvider? _userProvider;
SettingProvider ?_settingProvider;
ServiceRequestsProvider? _serviceRequestsProvider;
ServiceStatusProvider? _assetTypeProvider;
RequestDetailProvider? _requestDetailProvider;
PartsProvider? _partsProvider;
ServiceReport? _serviceReport;
bool _isLoading = false;
List<SparePart> _spareParts = [];
final List<File> _files = [];
List<File> _files = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final TextEditingController _partQtyController = TextEditingController();
final TextEditingController _oracleNoController = TextEditingController();
final TextEditingController _descriptionController = TextEditingController();
@override
void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
super.initState();
if (context.mounted) {
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
Provider.of<ServiceReportLastCallsProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).serviceRequestId = serviceRequestsProvider.currentSelectedRequest!.id;
}
_partsProvider = Provider.of<PartsProvider>(context, listen: false);
_requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
scheduleMicrotask(() async {
_isLoading = true;
setState(() {});
_spareParts = await _partsProvider!.getPartsList(assetId: _requestDetailProvider?.currentWorkOrder?.data?.asset?.id);
_requestDetailProvider?.sparePartHelperModel = SparePartHelperModel(
id: 0,
workOrderId: _requestDetailProvider?.currentWorkOrder?.data?.requestId,
sparePartAttachments: [],
sparePart: SparePart(),
);
_isLoading = false;
setState(() {});
});
// _isLoading = true;
}
void restValues({required RequestDetailProvider requestDetailProvider}) {
requestDetailProvider.sparePartHelperModel = SparePartHelperModel(id: 0, workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, sparePartAttachments: []);
_partQtyController.clear();
_oracleNoController.clear();
_descriptionController.clear();
_files = [];
}
@override
void dispose() {
_partQtyController.dispose();
_oracleNoController.dispose();
_descriptionController.dispose();
super.dispose();
}
void getRequestForWorkOrder() async {
_isLoading = true;
setState(() {});
ServiceRequestsProvider serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
_serviceReport?.callRequest = await _serviceRequestsProvider?.getCallRequestForWorkOrder(callId: serviceRequestsProvider!.currentSelectedRequest!.id!);
await _assetTypeProvider?.getTypes();
_serviceReport?.assignedEmployee = _serviceReport?.callRequest?.assignedEmployee;
_serviceReport?.equipmentStatus = _serviceReport?.callRequest?.defectType;
_serviceReport?.serviceType = Lookup(id: 65, name: "Interval", value: 1); // default value in service type as in web
_spareParts = await _partsProvider!.getPartsList(assetId: serviceRequestsProvider.currentSelectedRequest!.deviceId);
_isLoading = false;
setState(() {});
}
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
_partsProvider = Provider.of<PartsProvider>(context);
if (_serviceReport?.callRequest == null) {
getRequestForWorkOrder();
}
_serviceReport?.assetType = _assetTypeProvider?.statuses?.firstWhere(
(element) => element.value == _serviceReport?.callRequest?.assetType,
orElse: () => Lookup(),
);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.sparePartRequest),
body: Consumer<ServiceRequestsProvider>(builder: (context, serviceRequestProvider, child) {
body: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return SafeArea(
child: LoadingManager(
isLoading: _isLoading,
@ -137,10 +113,14 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
title: context.translation.partNo,
staticData: _spareParts,
showShadow: false,
initialValue: serviceRequestProvider.initialSelectedSparePart.sparePart,
initialValue: requestDetailProvider.sparePartHelperModel?.sparePart,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
onSelect: (part) {
serviceRequestProvider.initialSelectedSparePart = SparePartsWorkOrders(id: 0, sparePart: part, qty: 0);
if (part != requestDetailProvider.sparePartHelperModel?.sparePart) {
restValues(requestDetailProvider: requestDetailProvider);
}
requestDetailProvider.sparePartHelperModel?.sparePart = part;
requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel);
},
),
12.height,
@ -151,14 +131,17 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null,
enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(value ?? "");
},
onSaved: (text) {
serviceRequestProvider.initialSelectedSparePart.qty = num.tryParse(text ?? "");
requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(text ?? "");
},
),
12.height,
@ -169,7 +152,7 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
textInputType: TextInputType.number,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null,
enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
@ -182,20 +165,26 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
),
12.height,
AppTextFormField(
initialValue: _serviceReport?.comment,
initialValue: requestDetailProvider.sparePartHelperModel?.comment,
labelStyle: AppTextStyles.textFieldLabelStyle,
controller: _descriptionController,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
labelText: context.translation.description,
alignLabelWithHint: true,
showWithoutDecoration: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.comment = value;
},
onSaved: (value) {
_serviceReport?.comment = value;
requestDetailProvider.sparePartHelperModel?.comment = value;
},
),
12.height,
MultiFilesPicker(label: context.translation.attachQuotation, files: _files,
buttonIcon: 'quotation_icon'.toSvgAsset(),
MultiFilesPicker(
label: context.translation.attachQuotation,
files: _files,
buttonIcon: 'quotation_icon'.toSvgAsset(),
buttonColor: AppColor.primary10,
),
],
@ -205,34 +194,18 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
],
),
).paddingAll(12).expanded,
FooterActionButton.footerContainer(child: AppFilledButton(
FooterActionButton.footerContainer(
child: AppFilledButton(
label: context.translation.addSparePartActivity,
buttonColor: AppColor.green70,
onPressed: () async {
ServiceRequestBottomSheet.actionBottomSheet(context: context, title: context.translation.addSparePartActionHeading);
// bool shouldReloadData = (await showModalBottomSheet(
// context: context,
// useSafeArea: true,
// isScrollControlled: true,
// backgroundColor: Colors.transparent,
// builder: (context) => ActionBottomSheet(title: context.translation.addSparePartActionHeading),
// )) as bool;
// if (shouldReloadData ?? false) {}
//TODO write add sparepart logic
// if ((!_formKey.currentState.validate()) || (!(await _serviceReport.validate(context)))) {
// setState(() {});
// return;
// }
// _formKey.currentState.save();
// _serviceReport.attachmentsWorkOrder ??= [];
// if (_files.isEmpty) _serviceReport.attachmentsWorkOrder = [];
// for (var file in _files) {
// _serviceReport.attachmentsWorkOrder.add(Attachment(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"));
// }
// final user = Provider.of<UserProvider>(context, listen: false).user;
// await _serviceRequestsProvider.createServiceReport(context, report: _serviceReport, request: serviceRequestProvider.serviceRequest, user: user);
for (var file in _files) {
requestDetailProvider.sparePartHelperModel?.sparePartAttachments
?.add(SparePartAttachments(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"));
}
print('model i got is ${requestDetailProvider.sparePartHelperModel?.toJson()}');
// TODO Api has issue call this function when it's solved.....
// requestDetailProvider.createActivitySparePart();
},
)),
],

@ -12,7 +12,7 @@ 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/helper_data_models/workorder/work_order_model.dart';
import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart';
import 'package:test_sa/models/service_request/pending_service_request_model.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
@ -358,15 +358,16 @@ class _CreateNewRequestState extends State<CreateNewRequest> with TickerProvider
for (var url in _deviceImages) {
}
_requestDetailProvider.workOrderHelperModel = WorkOrderHelperModel(
assetId: _serviceRequest.deviceId,
priorityId: _serviceRequest.priority?.id,
equipmentStatusId: _serviceRequest.defectType?.id,
voiceNote: _serviceRequest.audio,
comments: _serviceRequest.callComments,
//add attachments also...
);
await _requestDetailProvider.createWorkOrder(workOrderHModel: WorkOrderHModel(
assetId: _serviceRequest.deviceId,
priorityId: _serviceRequest.priority?.id,
equipmentStatusId: _serviceRequest.defectType?.id,
voiceNote: _serviceRequest.audio,
comments: _serviceRequest.callComments,
//add attachments also...
));
await _requestDetailProvider.createWorkOrder();
// await _serviceRequestsProvider.createRequest(
// context: context,

@ -416,6 +416,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
),
if (_subWorkOrders.loanAvailablity?.value == 1) 8.height,
if (_subWorkOrders.loanAvailablity?.value == 1)
PickAsset(
device: loanAvailabilityAsset, // ?? _serviceReport.device,
onPickAsset: (asset) {

@ -14,9 +14,10 @@ class PickAsset extends StatelessWidget {
final Asset? device; // Now nullable
final bool editable;
final bool showAssetInfo;
final Color?cardColor;
final bool forPPM;
const PickAsset({Key? key, this.editable = true, this.device, required this.onPickAsset, this.showAssetInfo = true, this.forPPM = false}) : super(key: key);
const PickAsset({Key? key, this.editable = true, this.device, required this.onPickAsset,this.cardColor, this.showAssetInfo = true, this.forPPM = false}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -25,7 +26,7 @@ class PickAsset extends StatelessWidget {
if (editable)
Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
color:cardColor?? Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
),

Loading…
Cancel
Save