Merge remote-tracking branch 'origin/sikander-development' into zaid_development_new

design_3.0_demo_module
zaid_daoud 3 years ago
commit 0950639c22

@ -623,7 +623,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
return null; return null;
} }
} catch (error) { } catch (error) {
print(error);
return null; return null;
} }
} }

@ -1,5 +1,6 @@
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/fault_description.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
class ServiceRequest { class ServiceRequest {
@ -27,8 +28,9 @@ class ServiceRequest {
bool viewReport; bool viewReport;
String engineerMobile; String engineerMobile;
String deviceModel; String deviceModel;
String faultDescription; FaultDescription faultDescription;
String workPerformed;
//String workPerformed;
String visitDate; String visitDate;
DateTime nextVisitDate; DateTime nextVisitDate;
String jobSheetNumber; String jobSheetNumber;
@ -68,7 +70,7 @@ class ServiceRequest {
this.jobSheetNumber, this.jobSheetNumber,
this.visitDate, this.visitDate,
this.nextVisitDate, this.nextVisitDate,
this.workPerformed, //this.workPerformed,
this.reportID, this.reportID,
this.defectType, this.defectType,
this.priority, this.priority,
@ -116,11 +118,16 @@ class ServiceRequest {
viewReport: parsedJson["workOrder"] != null, viewReport: parsedJson["workOrder"] != null,
deviceModel: parsedJson["asset"]["modelDefinition"]["modelName"], deviceModel: parsedJson["asset"]["modelDefinition"]["modelName"],
engineerMobile: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["phone"], engineerMobile: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["phone"],
faultDescription: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["faultDescription"] : null, faultDescription: parsedJson["workOrder"] != null
? parsedJson["workOrder"]["faultDescription"] != null
? FaultDescription.fromJson(parsedJson["workOrder"]["faultDescription"])
: null
: null,
jobSheetNumber: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["jobSheetNumber"] : null, jobSheetNumber: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["jobSheetNumber"] : null,
visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? "").toString().split(" ").first, visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? "").toString().split(" ").first,
nextVisitDate: DateTime.tryParse(parsedJson["nextVisitDate"] ?? ""), nextVisitDate: DateTime.tryParse(parsedJson["nextVisitDate"] ?? ""),
workPerformed: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workPerformed"] : null, //workPerformed: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workPerformed"] : null,
device: Device.fromJson(parsedJson["asset"]), device: Device.fromJson(parsedJson["asset"]),
reviewComment: parsedJson["reviewComment"], reviewComment: parsedJson["reviewComment"],
type: Lookup.fromJson(parsedJson['typeofRequest']), type: Lookup.fromJson(parsedJson['typeofRequest']),

@ -65,6 +65,8 @@ class CreateRequestPageState extends State<CreateRequestPage> {
TextEditingController _maintenanceController, _commentController, _reviewCommentController; TextEditingController _maintenanceController, _commentController, _reviewCommentController;
DateTime _dateTime; DateTime _dateTime;
bool isFirstActionSubmitted = false;
@override @override
void initState() { void initState() {
_maintenanceController = TextEditingController(); _maintenanceController = TextEditingController();
@ -80,28 +82,29 @@ class CreateRequestPageState extends State<CreateRequestPage> {
} else { } else {
_serviceRequest = ServiceRequest(); _serviceRequest = ServiceRequest();
} }
_isLoading = true; isFirstActionSubmitted = _serviceRequest?.firstAction != null;
super.initState(); super.initState();
} }
getServiceRequestById(String id) async { //
try { // getServiceRequestById(String id) async {
ServiceRequest request = await _serviceRequestsProvider.getServiceRequestObjectById(requestId: id) ?? ""; // try {
_serviceRequest = request; // ServiceRequest request = await _serviceRequestsProvider.getServiceRequestObjectById(requestId: id) ?? "";
_device = _serviceRequest.device; // _serviceRequest = request;
_deviceImages.addAll(_serviceRequest.devicePhotos.map((e) { // _device = _serviceRequest.device;
return File(e); // _deviceImages.addAll(_serviceRequest.devicePhotos.map((e) {
}).toList()); // return File(e);
_showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit"; // }).toList());
if (_showDatePicker && _serviceRequest.visitDate != null) { // _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
_dateTime = DateTime.tryParse(_serviceRequest.visitDate); // if (_showDatePicker && _serviceRequest.visitDate != null) {
} // _dateTime = DateTime.tryParse(_serviceRequest.visitDate);
_isLoading = false; // }
} catch (ex) { // _isLoading = false;
_isLoading = false; // } catch (ex) {
} // _isLoading = false;
setState(() {}); // }
} // setState(() {});
// }
@override @override
void dispose() { void dispose() {
@ -121,10 +124,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context).subtitle;
if (_serviceRequestsProvider == null) { _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
getServiceRequestById(widget.serviceRequest.id);
}
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
@ -277,6 +277,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
if (widget.serviceRequest != null) if (widget.serviceRequest != null)
ServiceRequestedFirstAction( ServiceRequestedFirstAction(
initialValue: _serviceRequest.firstAction, initialValue: _serviceRequest.firstAction,
enabled: !isFirstActionSubmitted,
onSelect: (status) { onSelect: (status) {
_dateTime = null; _dateTime = null;
_serviceRequest.firstAction = status; _serviceRequest.firstAction = status;
@ -288,6 +289,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
if (_showDatePicker) if (_showDatePicker)
ADatePicker( ADatePicker(
date: _dateTime, date: _dateTime,
enable: !isFirstActionSubmitted,
from: DateTime.now(), from: DateTime.now(),
onDatePicker: (date) { onDatePicker: (date) {
_dateTime = date; _dateTime = date;
@ -400,7 +402,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
_serviceRequest.requestedThrough = Provider.of<ServiceRequestedThroughProvider>(context, listen: false).getDefaultItem(); _serviceRequest.requestedThrough = Provider.of<ServiceRequestedThroughProvider>(context, listen: false).getDefaultItem();
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_serviceRequest.devicePhotos = _deviceImages.map((e) => "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}").toList(); _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();
if (_serviceRequest.audio != null) { if (_serviceRequest.audio != null) {
if (_isLocalUrl(_serviceRequest.audio)) { if (_isLocalUrl(_serviceRequest.audio)) {
final File file = File(_serviceRequest.audio); final File file = File(_serviceRequest.audio);

@ -6,6 +6,7 @@ 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/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_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/user_types.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
@ -16,7 +17,9 @@ import 'package:test_sa/views/pages/user/requests/report/create_service_report.d
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart'; import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/images/images_list.dart'; import 'package:test_sa/views/widgets/images/images_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart';
@ -28,9 +31,9 @@ import 'report/future_service_report.dart';
class RequestDetailsPage extends StatelessWidget { class RequestDetailsPage extends StatelessWidget {
static const String id = "/call-details"; static const String id = "/call-details";
final ServiceRequest serviceRequest; ServiceRequest serviceRequest;
const RequestDetailsPage({Key key, this.serviceRequest}) : super(key: key); RequestDetailsPage({Key key, this.serviceRequest}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -39,404 +42,423 @@ class RequestDetailsPage extends StatelessWidget {
SettingProvider _settingProvider = Provider.of<SettingProvider>(context); SettingProvider _settingProvider = Provider.of<SettingProvider>(context);
List<SearchWorkOrder> workOrders = []; List<SearchWorkOrder> workOrders = [];
ServiceRequestsProvider _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); ServiceRequestsProvider _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_serviceRequestsProvider.getServiceRequestObjectById(requestId: serviceRequest.id);
return DefaultTabController( return DefaultTabController(
length: 2, length: 2,
child: Scaffold( child: Scaffold(
body: SafeArea( body: SafeArea(
child: Column( child: FutureBuilder(
children: [ future: _serviceRequestsProvider.getServiceRequestObjectById(requestId: serviceRequest.id),
Container( builder: (context, snap) {
color: AColors.primaryColor, if (snap.connectionState == ConnectionState.waiting) {
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), return const ALoading();
child: Row( } else if (snap.hasData) {
children: [ serviceRequest = snap.data;
ABackButton(), return Column(
Expanded( children: [
child: Center( Container(
child: Text( color: AColors.primaryColor,
_subtitle.details, padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), child: Row(
),
),
),
_userProvider.user.type == UsersTypes.normal_user
?
// AIconButton(
// iconData: Icons.warning_amber_rounded,
// color: AColors.white,
// buttonSize: 42,
// backgroundColor: AColors.deepOrange,
// onPressed: (){
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (_) => ReportIssuesPage(serviceRequest: serviceRequest,)
// )
// );
// },
// )
const SizedBox(
width: 48,
)
: AIconButton(
iconData: Icons.edit,
color: AColors.white,
buttonSize: 42,
backgroundColor: AColors.green,
onPressed: () async {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)),
);
// showModalBottomSheet(
// context: context,
// builder: (context) {
// return ServiceRequestsUpdateDialog(
// request: serviceRequest,
// );
// });
// DateTime picked = await showDatePicker(
// context: context,
// initialDate: DateTime.now(),
// firstDate: DateTime.now(),
// lastDate: DateTime.now().add(Duration(days: 182))
// );
// if(picked == null){return;}
// showDialog<void>(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context) {
// return CupertinoAlertDialog(
// title: Text(_subtitle.updatingDots),
// content: Center(child: CircularProgressIndicator()),
// );
// },
// );
// int status = await _serviceRequestsProvider.updateDate(
// user: _userProvider.user,
// host: _settingProvider.host,
// request: serviceRequest,
// newDate: picked.toString().split(" ").first
// );
// Navigator.of(context).pop();
// Fluttertoast.showToast(
// msg: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle),
// );
},
),
SizedBox(
width: 16,
)
],
),
),
serviceRequest.devicePhotos.isEmpty
? SizedBox.shrink()
: Column(
children: [
SizedBox(
height: 8,
),
MaterialButton(
padding: EdgeInsets.zero,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => Scaffold(
body: InteractiveViewer(
child: Center(
child: ImageLoader(
url: serviceRequest.devicePhotos.first,
boxFit: BoxFit.contain,
),
),
),
)));
},
child: SizedBox(
height: 140 * AppStyle.getScaleFactor(context),
width: MediaQuery.of(context).size.width,
child: ImageLoader(
url: serviceRequest.devicePhotos.first,
boxFit: BoxFit.cover,
),
),
),
SizedBox(height: 8),
SizedBox(
height: 60 * AppStyle.getScaleFactor(context),
child: ImagesList(
images: serviceRequest.devicePhotos,
),
),
],
),
TabBar(labelColor: AColors.primaryColor, tabs: [
Tab(
text: _subtitle.general,
),
Tab(
text: _subtitle.serviceRequestInformation,
),
]),
SizedBox(
height: 8,
),
Expanded(
child: TabBarView(
children: [
ListView(
padding: EdgeInsets.symmetric(horizontal: 16),
children: [
RequestInfoRow(
title: _subtitle.callId,
info: serviceRequest.requestCode,
),
RequestInfoRow(
title: "Asset Number",
info: serviceRequest.deviceNumber,
),
RequestInfoRow(
title: _subtitle.assetName,
info: serviceRequest.deviceEnName,
),
RequestInfoRow(
title: _subtitle.deviceModel,
info: serviceRequest.deviceModel,
),
RequestInfoRow(
title: _subtitle.engineerName,
info: serviceRequest.engineerName,
),
RequestInfoRow(
title: _subtitle.engineerPhone,
info: serviceRequest.engineerMobile,
),
RequestInfoRow(
title: _subtitle.date,
info: serviceRequest.date,
),
serviceRequest.nextVisitDate == null
? SizedBox.shrink()
: RequestInfoRow(
title: _subtitle.nextVisitDate,
info: DateFormat('EE dd/MM/yyyy').format(serviceRequest.nextVisitDate),
),
Row(
children: [ children: [
ABackButton(),
Expanded( Expanded(
child: Text( child: Center(
"${_subtitle.status} : ", child: Text(
style: Theme.of(context).textTheme.subtitle1, _subtitle.details,
textScaleFactor: AppStyle.getScaleFactor(context), style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
),
), ),
), ),
StatusLabel(label: serviceRequest.statusLabel, color: AColors.getRequestStatusColor(serviceRequest.statusValue)), _userProvider.user.type == UsersTypes.normal_user
?
// AIconButton(
// iconData: Icons.warning_amber_rounded,
// color: AColors.white,
// buttonSize: 42,
// backgroundColor: AColors.deepOrange,
// onPressed: (){
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (_) => ReportIssuesPage(serviceRequest: serviceRequest,)
// )
// );
// },
// )
const SizedBox(
width: 48,
)
: AIconButton(
iconData: Icons.edit,
color: AColors.white,
buttonSize: 42,
backgroundColor: AColors.green,
onPressed: () async {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)),
);
// showModalBottomSheet(
// context: context,
// builder: (context) {
// return ServiceRequestsUpdateDialog(
// request: serviceRequest,
// );
// });
// DateTime picked = await showDatePicker(
// context: context,
// initialDate: DateTime.now(),
// firstDate: DateTime.now(),
// lastDate: DateTime.now().add(Duration(days: 182))
// );
// if(picked == null){return;}
// showDialog<void>(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context) {
// return CupertinoAlertDialog(
// title: Text(_subtitle.updatingDots),
// content: Center(child: CircularProgressIndicator()),
// );
// },
// );
// int status = await _serviceRequestsProvider.updateDate(
// user: _userProvider.user,
// host: _settingProvider.host,
// request: serviceRequest,
// newDate: picked.toString().split(" ").first
// );
// Navigator.of(context).pop();
// Fluttertoast.showToast(
// msg: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle),
// );
},
),
SizedBox(
width: 16,
)
], ],
), ),
Divider( ),
color: Theme.of(context).primaryColor, serviceRequest.devicePhotos.isEmpty
), ? const SizedBox.shrink()
RequestInfoRow( : SizedBox(
title: _subtitle.hospital, height: 60 * AppStyle.getScaleFactor(context),
info: serviceRequest.hospitalName, child: FilesList(
), images: serviceRequest.devicePhotos,
RequestInfoRow( ),
title: _subtitle.unite, ).paddingOnly(top: 4, bottom: 4),
info: serviceRequest.departmentName,
// Column(
// children: [
// SizedBox(
// height: 8,
// ),
// MaterialButton(
// padding: EdgeInsets.zero,
// onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (_) => Scaffold(
// body: InteractiveViewer(
// child: Center(
// child: ImageLoader(
// url: serviceRequest.devicePhotos.first,
// boxFit: BoxFit.contain,
// ),
// ),
// ),
// )));
// },
// child: SizedBox(
// height: 140 * AppStyle.getScaleFactor(context),
// width: MediaQuery.of(context).size.width,
// child: ImageLoader(
// url: serviceRequest.devicePhotos.first,
// boxFit: BoxFit.cover,
// ),
// ),
// ),
// SizedBox(height: 8),
// SizedBox(
// height: 60 * AppStyle.getScaleFactor(context),
// child: FilesList(
// images: serviceRequest.devicePhotos,
// ),
// ),
// ],
// ),
TabBar(labelColor: AColors.primaryColor, tabs: [
Tab(
text: _subtitle.general,
), ),
// RequestInfoRow( Tab(
// title: _subtitle.deviceArName, text: _subtitle.serviceRequestInformation,
// content: serviceRequest.deviceArName,
// ),
// RequestInfoRow(
// title: _subtitle.deviceName,
// content: serviceRequest.deviceEnName,
// ),
RequestInfoRow(
title: _subtitle.maintenanceIssue,
content: serviceRequest.callComments,
), ),
if (serviceRequest.audio?.isNotEmpty == true) ]),
ASoundPlayer( SizedBox(
audio: serviceRequest.audio, height: 8,
), ),
// Expanded(
// Center( child: TabBarView(
// child: Padding( children: [
// padding: EdgeInsets.all(32), ListView(
// child: AButton( padding: EdgeInsets.symmetric(horizontal: 16),
// text: _subtitle.duplicateRequest,
// onPressed: () async {
// bool result = await showDialog(
// context: context,
// builder: (_) => AAlertDialog(
// title: _subtitle.duplicateAlert,
// content: _subtitle.duplicateAlertMessage,
// )
// );
// if(result == true){
// showDialog(
// context: context,
// builder: (context){
// return Center(child: CircularProgressIndicator());
// }
// );
// int status = await _serviceRequestsProvider.createDuplicatedReport(
// host: _settingProvider.host,
// user: _userProvider.user,
// request: serviceRequest
// );
// Navigator.of(context).pop();
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(
// HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle)
// )
// )
// );
// }
// },
// ),
// ),
// )
],
),
// workOrders.isEmpty ?
FutureBuilder(
future: _serviceRequestsProvider.searchWorkOrders(callId: serviceRequest.requestCode),
builder: (context, snap) {
workOrders = snap.data as List<SearchWorkOrder>;
if (snap.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator());
if (snap.connectionState == ConnectionState.done && (snap.data?.length ?? 0) != 0) {
return SingleChildScrollView(
child: Column(
children: [ children: [
ListView.separated( RequestInfoRow(
shrinkWrap: true, title: _subtitle.callId,
physics: const NeverScrollableScrollPhysics(), info: serviceRequest.requestCode,
padding: EdgeInsets.all(21), ),
itemCount: workOrders.length, RequestInfoRow(
separatorBuilder: (czt, index) => 21.height, title: "Asset Number",
itemBuilder: (context, index) { info: serviceRequest.deviceNumber,
Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; ),
Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; RequestInfoRow(
title: _subtitle.assetName,
return ElevatedButton( info: serviceRequest.deviceEnName,
style: ElevatedButton.styleFrom( ),
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), RequestInfoRow(
primary: itemColor.withOpacity(.7), title: _subtitle.deviceModel,
shape: RoundedRectangleBorder( info: serviceRequest.deviceModel,
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
),
),
//padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
onPressed: () {
// onPressed(request);
},
child: Column(
children: [
RequestInfoRow(
title: _subtitle.callId,
content: serviceRequest.requestCode,
),
RequestInfoRow(
title: _subtitle.orderWorkNumber,
info: workOrders[index].workOrderNo.toString(),
),
RequestInfoRow(
title: _subtitle.visitDate,
info: workOrders[index].visitDate,
),
RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee?.name ?? ""),
RequestInfoRow(
title: _subtitle.assetSN,
info: workOrders[index].callRequest.asset.assetSerialNo,
),
RequestInfoRow(
title: _subtitle.assetName,
info: workOrders[index].callRequest.asset.modelDefinition.assetName,
),
RequestInfoRow(
title: _subtitle.assetNumber,
info: workOrders[index].callRequest.asset.assetNumber,
),
RequestInfoRow(
title: _subtitle.model,
info: workOrders[index].callRequest.asset.modelDefinition.modelName,
),
RequestInfoRow(
title: _subtitle.site,
info: workOrders[index].callRequest.asset.site.custName,
),
RequestInfoRow(
title: "Call last Situation",
info: workOrders[index].currentSituation.name ?? '',
),
_userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null
? Padding(
padding: EdgeInsets.all(32),
child: AButton(
text: _subtitle.editServiceReport,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => FutureServiceReport(
request: serviceRequest,
workOrder: workOrders[index],
)),
);
},
),
)
: SizedBox.shrink(),
],
),
);
},
), ),
if (_userProvider.user.type == UsersTypes.engineer) RequestInfoRow(
Center( title: _subtitle.engineerName,
child: Padding( info: serviceRequest.engineerName,
padding: const EdgeInsets.all(32), ),
child: AButton( RequestInfoRow(
text: "Create Work Order", title: _subtitle.engineerPhone,
onPressed: () { info: serviceRequest.engineerMobile,
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); ),
}, RequestInfoRow(
title: _subtitle.date,
info: serviceRequest.date,
),
serviceRequest.nextVisitDate == null
? SizedBox.shrink()
: RequestInfoRow(
title: _subtitle.nextVisitDate,
info: DateFormat('EE dd/MM/yyyy').format(serviceRequest.nextVisitDate),
),
Row(
children: [
Expanded(
child: Text(
"${_subtitle.status} : ",
style: Theme.of(context).textTheme.subtitle1,
textScaleFactor: AppStyle.getScaleFactor(context),
), ),
), ),
StatusLabel(label: serviceRequest.statusLabel, color: AColors.getRequestStatusColor(serviceRequest.statusValue)),
],
),
Divider(
color: Theme.of(context).primaryColor,
),
RequestInfoRow(
title: _subtitle.hospital,
info: serviceRequest.hospitalName,
),
RequestInfoRow(
title: _subtitle.unite,
info: serviceRequest.departmentName,
),
// RequestInfoRow(
// title: _subtitle.deviceArName,
// content: serviceRequest.deviceArName,
// ),
// RequestInfoRow(
// title: _subtitle.deviceName,
// content: serviceRequest.deviceEnName,
// ),
RequestInfoRow(
title: _subtitle.maintenanceIssue,
content: serviceRequest.callComments,
),
if (serviceRequest.audio?.isNotEmpty == true)
ASoundPlayer(
audio: serviceRequest.audio,
), ),
//
// Center(
// child: Padding(
// padding: EdgeInsets.all(32),
// child: AButton(
// text: _subtitle.duplicateRequest,
// onPressed: () async {
// bool result = await showDialog(
// context: context,
// builder: (_) => AAlertDialog(
// title: _subtitle.duplicateAlert,
// content: _subtitle.duplicateAlertMessage,
// )
// );
// if(result == true){
// showDialog(
// context: context,
// builder: (context){
// return Center(child: CircularProgressIndicator());
// }
// );
// int status = await _serviceRequestsProvider.createDuplicatedReport(
// host: _settingProvider.host,
// user: _userProvider.user,
// request: serviceRequest
// );
// Navigator.of(context).pop();
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(
// HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle)
// )
// )
// );
// }
// },
// ),
// ),
// )
], ],
), ),
); // workOrders.isEmpty ?
} else { FutureBuilder(
return Column( future: _serviceRequestsProvider.searchWorkOrders(callId: serviceRequest.requestCode),
children: [ builder: (context, snap) {
Expanded( workOrders = snap.data as List<SearchWorkOrder>;
child: Center( if (snap.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator());
child: ASubTitle(_subtitle.dataNotFound), if (snap.connectionState == ConnectionState.done && (snap.data?.length ?? 0) != 0) {
), return SingleChildScrollView(
), child: Column(
if (_userProvider.user.type == UsersTypes.engineer) children: [
Center( ListView.separated(
child: Padding( shrinkWrap: true,
padding: const EdgeInsets.all(32), physics: const NeverScrollableScrollPhysics(),
child: AButton( padding: EdgeInsets.all(21),
text: "Create Work Order", itemCount: workOrders.length,
onPressed: () { separatorBuilder: (czt, index) => 21.height,
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); itemBuilder: (context, index) {
}, Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary;
Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary;
return ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
primary: itemColor.withOpacity(.7),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
),
),
//padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
onPressed: () {
// onPressed(request);
},
child: Column(
children: [
RequestInfoRow(
title: _subtitle.callId,
content: serviceRequest.requestCode,
),
RequestInfoRow(
title: _subtitle.orderWorkNumber,
info: workOrders[index].workOrderNo.toString(),
),
RequestInfoRow(
title: _subtitle.visitDate,
info: workOrders[index].visitDate,
),
RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee?.name ?? ""),
RequestInfoRow(
title: _subtitle.assetSN,
info: workOrders[index].callRequest.asset.assetSerialNo,
),
RequestInfoRow(
title: _subtitle.assetName,
info: workOrders[index].callRequest.asset.modelDefinition.assetName,
),
RequestInfoRow(
title: _subtitle.assetNumber,
info: workOrders[index].callRequest.asset.assetNumber,
),
RequestInfoRow(
title: _subtitle.model,
info: workOrders[index].callRequest.asset.modelDefinition.modelName,
),
RequestInfoRow(
title: _subtitle.site,
info: workOrders[index].callRequest.asset.site.custName,
),
RequestInfoRow(
title: "Call last Situation",
info: workOrders[index].currentSituation.name ?? '',
),
_userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null
? Padding(
padding: EdgeInsets.all(32),
child: AButton(
text: _subtitle.editServiceReport,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => FutureServiceReport(
request: serviceRequest,
workOrder: workOrders[index],
)),
);
},
),
)
: SizedBox.shrink(),
],
),
);
},
),
if (_userProvider.user.type == UsersTypes.engineer)
Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: AButton(
text: "Create Work Order",
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest)));
},
),
),
),
],
), ),
), );
), } else {
], return Column(
); children: [
} Expanded(
}, child: Center(
), child: ASubTitle(_subtitle.dataNotFound),
], ),
), ),
), if (_userProvider.user.type == UsersTypes.engineer)
], Center(
), child: Padding(
padding: const EdgeInsets.all(32),
child: AButton(
text: "Create Work Order",
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest)));
},
),
),
),
],
);
}
},
),
],
),
),
],
);
}
return const SizedBox();
}),
), ),
), ),
); );

@ -6,8 +6,9 @@ class ADatePicker extends StatelessWidget {
final DateTime from; final DateTime from;
final DateTime to; final DateTime to;
final Function(DateTime) onDatePicker; final Function(DateTime) onDatePicker;
final bool enable;
const ADatePicker({Key key, this.date, this.onDatePicker, this.from, this.to}) : super(key: key); const ADatePicker({Key key, this.date, this.onDatePicker, this.from, this.to, this.enable = true}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -19,14 +20,16 @@ class ADatePicker extends StatelessWidget {
borderRadius: BorderRadius.circular(12 * AppStyle.getScaleFactor(context)), borderRadius: BorderRadius.circular(12 * AppStyle.getScaleFactor(context)),
), ),
), ),
onPressed: enable
? () async {
DateTime picked = await showDatePicker(context: context, initialDate: DateTime.now(), firstDate: from ?? DateTime.now(), lastDate: to ?? DateTime.now().add(Duration(days: 365)));
onDatePicker(picked);
}
: null,
child: Text( child: Text(
date == null ? "Pick Date" : date.toString().split(" ").first, date == null ? "Pick Date" : date.toString().split(" ").first,
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
onPressed: () async {
DateTime picked = await showDatePicker(context: context, initialDate: DateTime.now(), firstDate: from ?? DateTime.now(), lastDate: to ?? DateTime.now().add(Duration(days: 365)));
onDatePicker(picked);
},
); );
} }
} }

@ -0,0 +1,75 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:open_file/open_file.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:url_launcher/url_launcher.dart';
import 'image_item.dart';
import 'images_viewer.dart';
class FilesList extends StatelessWidget {
final List<String> images;
final EdgeInsets padding;
const FilesList({Key key, this.images, this.padding}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.separated(
padding: padding ?? EdgeInsets.symmetric(horizontal: 32 * AppStyle.getScaleFactor(context)),
scrollDirection: Axis.horizontal,
itemCount: images.length,
separatorBuilder: (context, itemIndex) => 8.width,
itemBuilder: (context, itemIndex) {
var isImage =
images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg";
var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf";
var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx";
return (isImage
? (_isLocalUrl(images[itemIndex])
? Image.file(File(images[itemIndex]))
: ImageLoader(
url: images[itemIndex],
boxFit: BoxFit.cover,
))
: Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png"))
.onPress(() async {
if (isImage) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Scaffold(
body: SafeArea(
child: Stack(
children: [
InteractiveViewer(child: Image(image: (_isLocalUrl(images[itemIndex]) ? FileImage(File(images[itemIndex])) : NetworkImage(images[itemIndex])))).center,
const ABackButton(),
],
),
),
),
),
);
} else if (_isLocalUrl(images[itemIndex])) {
OpenFile.open(images[itemIndex]);
} else {
if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) {
Fluttertoast.showToast(msg: "UnExpected Error with file.");
throw Exception('Could not launch ');
}
}
});
});
}
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
}

@ -1,9 +1,14 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:open_file/open_file.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:url_launcher/url_launcher.dart';
class MultiFilesPickerItem extends StatelessWidget { class MultiFilesPickerItem extends StatelessWidget {
final File file; final File file;
@ -31,7 +36,7 @@ class MultiFilesPickerItem extends StatelessWidget {
), ),
child: MaterialButton( child: MaterialButton(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
onPressed: () { onPressed: () async {
if (isImage) { if (isImage) {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
@ -39,7 +44,14 @@ class MultiFilesPickerItem extends StatelessWidget {
body: SafeArea( body: SafeArea(
child: Stack( child: Stack(
children: [ children: [
Center(child: isImage ? InteractiveViewer(child: Image(image: (_isLocalUrl(file.path) ? FileImage(file) : NetworkImage(file.path)))) : const SizedBox.shrink()), InteractiveViewer(
child: _isLocalUrl(file.path)
? Image.file(file)
: ImageLoader(
url: file.path,
boxFit: BoxFit.cover,
))
.center,
const ABackButton(), const ABackButton(),
], ],
), ),
@ -47,6 +59,13 @@ class MultiFilesPickerItem extends StatelessWidget {
), ),
), ),
); );
} else if (_isLocalUrl(file.path)) {
OpenFile.open(file.path);
} else {
if (!await launchUrl(Uri.parse(file.path), mode: LaunchMode.externalApplication)) {
Fluttertoast.showToast(msg: "UnExpected Error with file.");
throw Exception('Could not launch ');
}
} }
}, },
child: Align( child: Align(

@ -11,8 +11,9 @@ import '../../../../controllers/providers/api/status_drop_down/service_reqest/se
class ServiceRequestedFirstAction extends StatelessWidget { class ServiceRequestedFirstAction extends StatelessWidget {
final Function(Lookup) onSelect; final Function(Lookup) onSelect;
final Lookup initialValue; final Lookup initialValue;
final bool enabled;
const ServiceRequestedFirstAction({Key key, this.onSelect, this.initialValue}) : super(key: key); const ServiceRequestedFirstAction({Key key, this.onSelect, this.initialValue, this.enabled = true}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final settingProvider = Provider.of<SettingProvider>(context); final settingProvider = Provider.of<SettingProvider>(context);
@ -30,6 +31,7 @@ class ServiceRequestedFirstAction extends StatelessWidget {
initialStatus: initialValue, initialStatus: initialValue,
statuses: menuProvider.items, statuses: menuProvider.items,
onSelect: onSelect, onSelect: onSelect,
enabled: enabled,
), ),
); );
} }

@ -701,6 +701,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
open_file:
dependency: "direct main"
description:
name: open_file
sha256: a5a32d44acb7c899987d0999e1e3cbb0a0f1adebbf41ac813ec6d2d8faa0af20
url: "https://pub.dev"
source: hosted
version: "3.3.2"
package_info: package_info:
dependency: "direct main" dependency: "direct main"
description: description:

@ -64,6 +64,7 @@ dependencies:
file_picker: ^5.2.5 file_picker: ^5.2.5
record_mp3: ^2.1.0 record_mp3: ^2.1.0
path_provider: ^2.1.0 path_provider: ^2.1.0
open_file: ^3.3.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Loading…
Cancel
Save