Merge remote-tracking branch 'origin/main_design2.0' into main_design2.0

# Conflicts:
#	lib/l10n/app_ar.arb
#	lib/l10n/app_en.arb
#	lib/new_views/common_widgets/single_item_drop_down_menu.dart
main_design2.0
nextwo 2 years ago
commit e21bde0153

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6572 2.34321C12.1569 0.842876 10.122 -1.58085e-08 8.00021 0C5.87842 1.58085e-08 3.84354 0.842877 2.34321 2.34321C0.842877 3.84354 1.58085e-08 5.87842 0 8.00021C-1.58085e-08 10.122 0.842876 12.1569 2.34321 13.6572C3.84354 15.1575 5.87842 16.0004 8.00021 16.0004C10.122 16.0004 12.1569 15.1575 13.6572 13.6572C15.1575 12.1569 16.0004 10.122 16.0004 8.00021C16.0004 5.87842 15.1575 3.84354 13.6572 2.34321ZM11.4572 10.3552C11.5405 10.4247 11.6085 10.5108 11.6567 10.608C11.7049 10.7052 11.7323 10.8114 11.7372 10.9198C11.7421 11.0281 11.7244 11.1364 11.6851 11.2375C11.6459 11.3387 11.586 11.4305 11.5093 11.5073C11.4325 11.584 11.3407 11.6439 11.2395 11.6831C11.1384 11.7224 11.0301 11.7401 10.9218 11.7352C10.8134 11.7303 10.7072 11.7029 10.61 11.6547C10.5128 11.6065 10.4267 11.5385 10.3572 11.4552L8.00021 9.10021L5.64521 11.4602C5.49549 11.5851 5.3045 11.6494 5.10976 11.6406C4.91502 11.6318 4.7306 11.5505 4.59276 11.4127C4.45492 11.2748 4.37361 11.0904 4.36481 10.8957C4.35601 10.7009 4.42036 10.5099 4.54521 10.3602L6.90021 8.00021L4.54021 5.64521C4.41536 5.49549 4.35101 5.3045 4.35981 5.10976C4.36861 4.91502 4.44992 4.7306 4.58776 4.59276C4.7256 4.45492 4.91002 4.37361 5.10476 4.36481C5.2995 4.35601 5.49049 4.42036 5.64021 4.54521L8.00021 6.90021L10.3552 4.54021C10.5049 4.41536 10.6959 4.35101 10.8907 4.35981C11.0854 4.36861 11.2698 4.44992 11.4077 4.58776C11.5455 4.7256 11.6268 4.91002 11.6356 5.10476C11.6444 5.2995 11.5801 5.49049 11.4552 5.64021L9.10021 8.00021L11.4572 10.3552Z" fill="#CA3332"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -1,14 +1,18 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/asset_transfer.dart'; import 'package:test_sa/models/device/asset_transfer.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import '../../../models/hospital.dart'; import '../../../models/hospital.dart';
import '../../../new_views/common_widgets/app_lazy_loading.dart';
class AssetTransferProvider extends ChangeNotifier { class AssetTransferProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
@ -117,51 +121,15 @@ class AssetTransferProvider extends ChangeNotifier {
} }
} }
Future<int> createRequest({ Future<void> createRequest({
@required String host, @required BuildContext context,
@required User user, @required AssetTransfer assetDestination,
@required AssetTransfer model, @required Device asset,
}) async { }) async {
Map<String, dynamic> body = {
"id": 0,
// "assetId": model.device.id ?? "",
"destSiteId": hospital.id ?? "",
"destDepartmentId": department.id ?? "",
// "senderSiteId": model.sender.client.id ?? "",
// "transferNo": 0,
// "transferCode": "string",
"destBuildingId": building?.id,
"destFloorId": floor.id,
"destRoom": room,
/////
// "senderBuildingId": model.device.destBuildingId,
// "senderFloorId": model.device.destFloorId,
// "senderDepartmentId": model.device.destDepartmentId,
// "senderRoom": model.device.destRoom,
// if (model?.sender?.attachments?.isNotEmpty ?? false)
// "senderAttachments":
// model?.sender?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(),
// "senderAssignedEmployeeId": "string",
// "senderMachineStatusId": 0,
// "senderComment": "string",
// "senderStartDate": "2023-06-11T09:21:56.453Z",
// "senderEndDate": "2023-06-11T09:21:56.453Z",
// "senderWorkingHours": "string",
// "senderTravelingHours": "string",
// "senderAttachmentName": "string",
// "receiverAssignedEmployeeId": "string",
// "receiverMachineStatusId": 0,
// "receiverComment": "string",
// "receiverStartDate": "2023-06-11T09:21:56.453Z",
// "receiverEndDate": "2023-06-11T09:21:56.453Z",
// "receiverWorkingHours": "string",
// "receiverTravelingHours": "string",
// "receiverAttachmentName": "string"
};
Response response; Response response;
try { try {
response = await ApiManager.instance.post(URLs.requestDeviceTransfer, body: body); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
response = await ApiManager.instance.post(URLs.requestDeviceTransfer, body: assetDestination.transferBody(asset: asset));
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
if (items != null) { if (items != null) {
@ -169,10 +137,14 @@ class AssetTransferProvider extends ChangeNotifier {
reset(); reset();
notifyListeners(); notifyListeners();
} }
Fluttertoast.showToast(msg: context.translation.createdSuccessfully);
} else {
Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest} :${json.decode(response.body)['message']}");
} }
return response.statusCode; Navigator.pop(context);
} catch (error) { } catch (error) {
return -1; Navigator.pop(context);
print(error);
} }
} }

@ -1,16 +1,20 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart'; import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/new_models/gas_refill_model.dart' as gasModel; import 'package:test_sa/models/new_models/gas_refill_model.dart' as gasModel;
import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import '../../../new_views/common_widgets/app_lazy_loading.dart';
class GasRefillProvider extends ChangeNotifier { class GasRefillProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 12; final pageItemNumber = 12;
@ -89,37 +93,19 @@ class GasRefillProvider extends ChangeNotifier {
} }
} }
Future<int> createModel({ Future<void> createModel({
@required BuildContext context,
@required User user, @required User user,
@required gasModel.GasRefillModel model, @required gasModel.GasRefillModel model,
}) async { }) async {
Map<String, dynamic> body = {
"uid": user.id.toString(),
"token": user.token ?? "",
"site": model.site?.toJson(),
"building": model.building != null ? {"id": model.building?.id, "name": model.building?.name, "value": model.building?.value} : null,
"floor": model.floor != null ? {"id": model.floor?.id, "name": model.floor?.name, "value": model.floor?.value} : null,
//if (expectedDateTime != null) "expectedDate": expectedDateTime?.toIso8601String(),
if (expectedDateTime != null) "expectedTime": expectedDateTime?.toIso8601String(),
if (timer?.startAt != null) "startDate": timer.startAt.toIso8601String(),
if (timer?.startAt != null) "startTime": timer.startAt.toIso8601String(),
if (timer?.endAt != null) "endDate": timer.endAt.toIso8601String(),
if (timer?.endAt != null) "endTime": timer.endAt.toIso8601String(),
"department": model.department?.toJson(),
"GazRefillNo": "GR-${DateTime.now().toString().split(" ").first}",
"status": model.status?.toJson(),
};
body["gazRefillDetails"] = model.gazRefillDetails
.map((model) => {
"gasType": model.gasType.toJson(),
"cylinderSize": model.cylinderSize.toJson(),
"cylinderType": model.cylinderType.toJson(),
"requestedQty": model.requestedQty,
})
.toList();
Response response; Response response;
try { try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
final body = model.toJson()
..addAll({
"uid": user.id.toString(),
"token": user.token ?? "",
});
response = await ApiManager.instance.post(URLs.requestGasRefill, body: body); response = await ApiManager.instance.post(URLs.requestGasRefill, body: body);
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
@ -127,11 +113,15 @@ class GasRefillProvider extends ChangeNotifier {
reset(); reset();
notifyListeners(); notifyListeners();
} }
Fluttertoast.showToast(msg: context.translation.createdSuccessfully);
Navigator.pop(context);
} else {
Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest} :${json.decode(response.body)['message']}");
} }
return response.statusCode; Navigator.pop(context);
} catch (error) { } catch (error) {
Navigator.pop(context);
print(error); print(error);
return -1;
} }
} }

@ -1,23 +1,26 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/call_request_for_work_order_model.dart'; import 'package:test_sa/models/call_request_for_work_order_model.dart';
import 'package:test_sa/models/issue.dart'; import 'package:test_sa/models/issue.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.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/service_request/service_request_search.dart'; import 'package:test_sa/models/service_request/service_request_search.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/models/timer_model.dart';
import '../../../models/service_request/search_work_order.dart'; import '../../../models/service_request/search_work_order.dart';
import '../../../models/service_request/sub_work_order_details.dart'; import '../../../models/service_request/sub_work_order_details.dart';
import '../../../models/user.dart'; import '../../../models/user.dart';
import '../../../new_views/common_widgets/app_lazy_loading.dart';
class ServiceRequestsProvider extends ChangeNotifier { class ServiceRequestsProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
@ -131,7 +134,8 @@ class ServiceRequestsProvider extends ChangeNotifier {
} }
} }
Future<int> createRequest({ Future<void> createRequest({
@required BuildContext context,
@required String host, @required String host,
@required User user, @required User user,
@required ServiceRequest serviceRequest, @required ServiceRequest serviceRequest,
@ -140,7 +144,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
"id": 0, "id": 0,
"calNo": "", "calNo": "",
"callCreatedBy": {"id": user.userID, "name": user.userName ?? ""}, "callCreatedBy": {"id": user.userID, "name": user.userName ?? ""},
"assets": serviceRequest.deviceId == null ? [] : [serviceRequest.deviceId], "assets": serviceRequest.device?.id == null ? [] : [serviceRequest.device?.id],
"requestedDate": DateTime.now().toIso8601String(), "requestedDate": DateTime.now().toIso8601String(),
"requestedTime": DateTime.now().toIso8601String(), "requestedTime": DateTime.now().toIso8601String(),
"client": user.clientId, "client": user.clientId,
@ -177,27 +181,33 @@ class ServiceRequestsProvider extends ChangeNotifier {
if (serviceRequest.audio != null) { if (serviceRequest.audio != null) {
body["voiceNote"] = serviceRequest.audio; body["voiceNote"] = serviceRequest.audio;
} }
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
Response response; Response response;
//try { try {
response = await ApiManager.instance.post(URLs.createRequest, body: body); response = await ApiManager.instance.post(URLs.createRequest, body: body);
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
if (serviceRequests != null) { if (serviceRequests != null) {
var data = json.decode(utf8.decode(response.bodyBytes)); var data = json.decode(utf8.decode(response.bodyBytes));
if (data is List) { if (data is List) {
serviceRequests.insert(0, ServiceRequest.fromJson(data[0])); serviceRequests.insert(0, ServiceRequest.fromJson(data[0]));
} else { } else {
if (data["data"] != null && data["data"] == true) { if (data["data"] != null && data["data"] == true) {
// serviceRequests.insert(0, ServiceRequest.fromJson(data[0])); // serviceRequests.insert(0, ServiceRequest.fromJson(data[0]));
}
} }
} }
notifyListeners();
Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
Navigator.pop(context);
} else {
Fluttertoast.showToast(msg: "${context.translation.failedRequestMessage} :${json.decode(response.body)['message']}");
} }
notifyListeners(); Navigator.pop(context);
} catch (error) {
print(error);
Navigator.pop(context);
} }
return response.statusCode;
// } catch (error) {
// return -1;
// }
} }
Future<int> createIssueReport({ Future<int> createIssueReport({

@ -6,6 +6,8 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import '../../../new_views/common_widgets/app_lazy_loading.dart';
class UserProvider extends ChangeNotifier { class UserProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset() { void reset() {
@ -39,12 +41,13 @@ class UserProvider extends ChangeNotifier {
/// return state code if request complete may be 200, 404 or 403 /// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager /// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart /// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> login({@required User user}) async { Future<int> login({@required BuildContext context, @required User user}) async {
if (_loading == true) return -2; if (_loading == true) return -2;
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try { try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
response = await ApiManager.instance.post(URLs.login, body: await user.toLoginJson()); response = await ApiManager.instance.post(URLs.login, body: await user.toLoginJson());
_loading = false; _loading = false;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
@ -55,8 +58,10 @@ class UserProvider extends ChangeNotifier {
return response.statusCode; return response.statusCode;
} }
notifyListeners(); notifyListeners();
Navigator.pop(context);
return response.statusCode; return response.statusCode;
} catch (error) { } catch (error) {
Navigator.pop(context);
debugPrint(error); debugPrint(error);
_loading = false; _loading = false;
notifyListeners(); notifyListeners();

@ -250,7 +250,7 @@
"assetNo" : "رقم الجهاز", "assetNo" : "رقم الجهاز",
"manufacture" : "صناعة", "manufacture" : "صناعة",
"model" : "الطراز", "model" : "الطراز",
"serialNumber" : "الرقم التسلسلي", "Serial No" : "الرقم التسلسلي",
"device" : "الجهاز", "device" : "الجهاز",
"pickAsset" : "إختر جهاز", "pickAsset" : "إختر جهاز",
"filter" : "تصنيف", "filter" : "تصنيف",
@ -264,5 +264,11 @@
"recordVoice" : "تسجيل صوت", "recordVoice" : "تسجيل صوت",
"gasRefillDetails" : "تفاصيل اعادة تعبئة غاز", "gasRefillDetails" : "تفاصيل اعادة تعبئة غاز",
"updateRequest" : "تعديل الطلب", "updateRequest" : "تعديل الطلب",
"gasRefill" : "اعادة تعبئة غاز" "gasRefill" : "اعادة تعبئة غاز",
"recordVoice" : "تسجيل صوت",
"receiverName" : "اسم المستلم",
"receiverDetails" : "تفاصيل المستلم",
"requestedThrough" : "الطلب عبر",
"typeOfRequest" : "نوع الطلب",
"assetDetails" : "تفاصيل الجهاز"
} }

@ -250,7 +250,6 @@
"assetNo" : "Asset No.", "assetNo" : "Asset No.",
"manufacture" : "Manufacture", "manufacture" : "Manufacture",
"model" : "Model", "model" : "Model",
"serialNumber" : "Serial Number",
"serialNo" : "Serial No", "serialNo" : "Serial No",
"device" : "Device", "device" : "Device",
"pickAsset" : "Pick Asset", "pickAsset" : "Pick Asset",
@ -272,5 +271,9 @@
"updateRequest" : "Update Request", "updateRequest" : "Update Request",
"gasRefill" : "Gas Refill", "gasRefill" : "Gas Refill",
"recordVoice" : "Record Voice", "recordVoice" : "Record Voice",
"assetDetails" : "Asset Details" "assetDetails" : "Asset Details",
"receiverName" : "Receiver Name",
"receiverDetails" : "Receiver Details",
"requestedThrough" : "Requested Through",
"typeOfRequest" : "Type of Request"
} }

@ -45,7 +45,6 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqes
import 'package:test_sa/new_views/app_style/app_themes.dart'; import 'package:test_sa/new_views/app_style/app_themes.dart';
import 'package:test_sa/new_views/pages/land_page/land_page.dart'; import 'package:test_sa/new_views/pages/land_page/land_page.dart';
import 'package:test_sa/new_views/pages/login_page.dart'; import 'package:test_sa/new_views/pages/login_page.dart';
import 'package:test_sa/new_views/pages/new_transfer_request_page.dart';
import 'package:test_sa/new_views/pages/splash_page.dart'; import 'package:test_sa/new_views/pages/splash_page.dart';
import 'package:test_sa/providers/department_provider.dart'; import 'package:test_sa/providers/department_provider.dart';
import 'package:test_sa/providers/gas_request_providers/cylinder_size_provider.dart'; import 'package:test_sa/providers/gas_request_providers/cylinder_size_provider.dart';
@ -56,6 +55,8 @@ import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart';
import 'package:test_sa/providers/service_request_providers/priority_provider.dart'; import 'package:test_sa/providers/service_request_providers/priority_provider.dart';
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/views/pages/device_transfer/request_device_transfer.dart'; import 'package:test_sa/views/pages/device_transfer/request_device_transfer.dart';
import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart'; import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart';
import 'package:test_sa/views/pages/sub_workorder/create_sub_workorder_page.dart'; import 'package:test_sa/views/pages/sub_workorder/create_sub_workorder_page.dart';
@ -161,6 +162,8 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()), ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()),
ChangeNotifierProvider(create: (_) => PriorityProvider()), ChangeNotifierProvider(create: (_) => PriorityProvider()),
ChangeNotifierProvider(create: (_) => EquipmentStatusProvider()), ChangeNotifierProvider(create: (_) => EquipmentStatusProvider()),
ChangeNotifierProvider(create: (_) => RequestedThroughProvider()),
ChangeNotifierProvider(create: (_) => TypeOfRequestProvider()),
], ],
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
@ -183,7 +186,6 @@ class MyApp extends StatelessWidget {
old.LandPage.id: (_) => const old.LandPage(), old.LandPage.id: (_) => const old.LandPage(),
LandPage.routeName: (_) => const LandPage(), LandPage.routeName: (_) => const LandPage(),
NewGasRefillRequestPage.routeName: (_) => const NewGasRefillRequestPage(), NewGasRefillRequestPage.routeName: (_) => const NewGasRefillRequestPage(),
NewTransferRequestPage.routeName: (_) => const NewTransferRequestPage(),
ServiceRequestsPage.id: (_) => ServiceRequestsPage(), ServiceRequestsPage.id: (_) => ServiceRequestsPage(),
ReportIssuesPage.id: (_) => const ReportIssuesPage(), ReportIssuesPage.id: (_) => const ReportIssuesPage(),
RequestGasRefill.id: (_) => const RequestGasRefill(), RequestGasRefill.id: (_) => const RequestGasRefill(),

@ -1,3 +1,8 @@
import 'package:flutter/src/widgets/framework.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/device.dart';
import 'asset_transfer_attachment.dart'; import 'asset_transfer_attachment.dart';
class AssetTransfer { class AssetTransfer {
@ -220,4 +225,65 @@ class AssetTransfer {
} }
return map; return map;
} }
Map<String, dynamic> transferBody({Device asset}) {
final map = <String, dynamic>{};
map['id'] = 0;
map['transferNo'] = transferNo;
map['transferCode'] = transferCode;
map['assetId'] = asset?.id;
map['destSiteId'] = destSiteId;
map['destBuildingId'] = destBuildingId;
map['destFloorId'] = destFloorId;
map['destDepartmentId'] = destDepartmentId;
map['destRoom'] = destRoom;
map['senderSiteId'] = asset?.site?.id;
map['senderBuildingId'] = asset?.building?.id;
map['senderFloorId'] = asset?.floor?.id;
map['senderDepartmentId'] = asset?.department?.id;
map['senderRoom'] = asset?.room;
map['senderAssignedEmployeeId'] = senderAssignedEmployeeId;
map['senderMachineStatusId'] = senderMachineStatusId;
map['senderComment'] = senderComment;
map['senderStartDate'] = senderStartDate;
map['senderEndDate'] = senderEndDate;
map['senderWorkingHours'] = senderWorkingHours;
map['senderTravelingHours'] = senderTravelingHours;
map['senderEngSignature'] = senderEngSignature;
if (senderAttachments != null) {
map['senderAttachments'] = senderAttachments.map((v) => v.toJson()).toList();
}
map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId;
map['receiverMachineStatusId'] = receiverMachineStatusId;
map['receiverComment'] = receiverComment;
map['receiverStartDate'] = receiverStartDate;
map['receiverEndDate'] = receiverEndDate;
map['receiverWorkingHours'] = receiverWorkingHours;
map['receiverTravelingHours'] = receiverTravelingHours;
map['receiverEngSignature'] = receiverEngSignature;
if (receiverAttachments != null) {
map['receiverAttachments'] = receiverAttachments.map((v) => v.toJson()).toList();
}
return map;
}
Future<bool> validate(BuildContext context) async {
if (assetId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.device}");
return false;
} else if (destSiteId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.destinationSite}");
return false;
} else if (destBuildingId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.building}");
return false;
} else if (destFloorId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.floor}");
return false;
} else if (destDepartmentId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.department}");
return false;
}
return true;
}
} }

@ -4,7 +4,6 @@ import 'dart:typed_data';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/enums/translation_keys.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/assigned_employee.dart'; import 'package:test_sa/models/new_models/assigned_employee.dart';
import 'package:test_sa/models/new_models/building.dart'; import 'package:test_sa/models/new_models/building.dart';
@ -126,8 +125,8 @@ class GasRefillModel {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final map = <String, dynamic>{}; final map = <String, dynamic>{};
map['id'] = id; map['id'] = id ?? 0;
map['gazRefillNo'] = gazRefillNo; map['gazRefillNo'] = "GR-${DateTime.now().toString().split(" ").first}";
map['expectedDate'] = expectedDate; map['expectedDate'] = expectedDate;
map['expectedTime'] = expectedTime; map['expectedTime'] = expectedTime;
map['startDate'] = startDate; map['startDate'] = startDate;
@ -247,7 +246,7 @@ class GasRefillDetails {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final map = <String, dynamic>{}; final map = <String, dynamic>{};
map['id'] = id; map['id'] = id ?? 0;
if (gasType != null) { if (gasType != null) {
map['gasType'] = gasType.toJson(); map['gasType'] = gasType.toJson();
} }

@ -152,6 +152,12 @@ class ServiceRequest {
} else if (defectType == null) { } else if (defectType == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.equipmentStatus}"); await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.equipmentStatus}");
return false; return false;
} else if (requestedThrough == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.requestedThrough}");
return false;
} else if (type == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.typeOfRequest}");
return false;
} }
return true; return true;
} }

@ -4,13 +4,12 @@ import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import '../../models/enums/translation_keys.dart';
import '../app_style/app_color.dart'; import '../app_style/app_color.dart';
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
final String title; final String title;
const DefaultAppBar({@required this.title, Key key}) : super(key: key); const DefaultAppBar({this.title, Key key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -23,7 +22,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
Navigator.of(context).pop(); Navigator.of(context).pop();
}), }),
Text( Text(
title, title ?? "",
style: AppTextStyles.heading3?.copyWith(fontWeight: FontWeight.w600, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), style: AppTextStyles.heading3?.copyWith(fontWeight: FontWeight.w600, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
).expanded, ).expanded,
], ],

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/models/enums/translation_keys.dart';
import 'package:test_sa/new_views/common_widgets/app_loading_manager.dart'; import 'package:test_sa/new_views/common_widgets/app_loading_manager.dart';
import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/loading_list_notifier.dart';
@ -47,7 +46,7 @@ class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier
return element == widget.initialValue; return element == widget.initialValue;
}); });
if (result?.isNotEmpty??false) _selectedItem = result.first; if (result?.isNotEmpty??false) _selectedItem = result.first;
if ((widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) {
widget.onSelect(_selectedItem); widget.onSelect(_selectedItem);
} }
} }
@ -70,7 +69,7 @@ class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier
} else { } else {
_selectedItem = null; _selectedItem = null;
} }
if ((widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) {
widget.onSelect(_selectedItem); widget.onSelect(_selectedItem);
} }
} else { } else {
@ -119,7 +118,7 @@ class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier
elevation: 0, elevation: 0,
isExpanded: true, isExpanded: true,
hint: Text( hint: Text(
context.translation.select, context.translation.select,
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
), ),
style: TextStyle(color: Theme.of(context).primaryColor), style: TextStyle(color: Theme.of(context).primaryColor),

@ -5,9 +5,7 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/translation_keys.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import '../../controllers/providers/api/user_provider.dart'; import '../../controllers/providers/api/user_provider.dart';
import '../../controllers/providers/settings/setting_provider.dart'; import '../../controllers/providers/settings/setting_provider.dart';
@ -98,9 +96,7 @@ class _LoginPageState extends State<LoginPage> {
Future<void> _login() async { Future<void> _login() async {
if (!_formKey.currentState.validate()) return; if (!_formKey.currentState.validate()) return;
_formKey.currentState.save(); _formKey.currentState.save();
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); int status = await _userProvider.login(context: context, user: _user);
int status = await _userProvider.login(user: _user);
Navigator.pop(context);
if (status >= 200 && status < 300 && _userProvider.user.isAuthenticated ?? false) { if (status >= 200 && status < 300 && _userProvider.user.isAuthenticated ?? false) {
_settingProvider.setUser(_userProvider.user); _settingProvider.setUser(_userProvider.user);

@ -6,7 +6,6 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/translation_keys.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/building.dart'; import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/department.dart'; import 'package:test_sa/models/new_models/department.dart';
@ -25,7 +24,6 @@ import 'package:test_sa/providers/loading_list_notifier.dart';
import '../../controllers/providers/api/gas_refill_provider.dart'; import '../../controllers/providers/api/gas_refill_provider.dart';
import '../../controllers/validator/validator.dart'; import '../../controllers/validator/validator.dart';
import '../common_widgets/app_lazy_loading.dart';
import '../common_widgets/default_app_bar.dart'; import '../common_widgets/default_app_bar.dart';
class NewGasRefillRequestPage extends StatefulWidget { class NewGasRefillRequestPage extends StatefulWidget {
@ -95,6 +93,7 @@ class _NewGasRefillRequestPageState extends State<NewGasRefillRequestPage> {
SingleItemDropDownMenu<Lookup, CylinderTypesProvider>( SingleItemDropDownMenu<Lookup, CylinderTypesProvider>(
context: context, context: context,
title: context.translation.cylinderType, title: context.translation.cylinderType,
initialValue: _currentDetails.cylinderType,
onSelect: (value) { onSelect: (value) {
_currentDetails.cylinderType = value; _currentDetails.cylinderType = value;
}, },
@ -103,6 +102,7 @@ class _NewGasRefillRequestPageState extends State<NewGasRefillRequestPage> {
SingleItemDropDownMenu<Lookup, CylinderSizeProvider>( SingleItemDropDownMenu<Lookup, CylinderSizeProvider>(
context: context, context: context,
title: context.translation.cylinderSize, title: context.translation.cylinderSize,
initialValue: _currentDetails.cylinderSize,
onSelect: (value) { onSelect: (value) {
_currentDetails.cylinderSize = value; _currentDetails.cylinderSize = value;
}, },
@ -115,6 +115,9 @@ class _NewGasRefillRequestPageState extends State<NewGasRefillRequestPage> {
onSelect: (value) { onSelect: (value) {
setState(() { setState(() {
_gasModel.site = value; _gasModel.site = value;
_gasModel?.building = null;
_gasModel?.floor = null;
_gasModel?.department = null;
}); });
}, },
), ),
@ -128,6 +131,8 @@ class _NewGasRefillRequestPageState extends State<NewGasRefillRequestPage> {
onSelect: (value) { onSelect: (value) {
setState(() { setState(() {
_gasModel.building = value; _gasModel.building = value;
_gasModel?.floor = null;
_gasModel?.department = null;
}); });
}, },
), ),
@ -141,6 +146,7 @@ class _NewGasRefillRequestPageState extends State<NewGasRefillRequestPage> {
onSelect: (value) { onSelect: (value) {
setState(() { setState(() {
_gasModel.floor = value; _gasModel.floor = value;
_gasModel?.department = null;
}); });
}, },
), ),
@ -242,18 +248,10 @@ class _NewGasRefillRequestPageState extends State<NewGasRefillRequestPage> {
Fluttertoast.showToast(msg: context.translation.youHaveToAddRequests); Fluttertoast.showToast(msg: context.translation.youHaveToAddRequests);
return; return;
} }
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); await Provider.of<GasRefillProvider>(context, listen: false).createModel(
final status = await Provider.of<GasRefillProvider>(context, listen: false).createModel( context: context,
user: Provider.of<UserProvider>(context, listen: false).user, user: Provider.of<UserProvider>(context, listen: false).user,
model: _gasModel, model: _gasModel,
); );
Navigator.pop(context);
if (status >= 200 && status < 300) {
Fluttertoast.showToast(msg: context.translation.createdSuccessfully);
Navigator.of(context).pop();
setState(() {});
} else {
Fluttertoast.showToast(msg: context.translation.failedToCompleteRequest);
}
} }
} }

@ -0,0 +1,36 @@
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 RequestedThroughProvider extends LoadingListNotifier<Lookup> {
@override
Future getDate() async {
if (loading == true) return -2;
loading = true;
notifyListeners();
loading = true;
notifyListeners();
try {
Response response = await ApiManager.instance.get(URLs.getServiceRequestThrough);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(response.body)["data"];
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
loading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -0,0 +1,36 @@
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 TypeOfRequestProvider extends LoadingListNotifier<Lookup> {
@override
Future getDate() async {
if (loading == true) return -2;
loading = true;
notifyListeners();
loading = true;
notifyListeners();
try {
Response response = await ApiManager.instance.get(URLs.getServiceRequestTypes);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(response.body)["data"];
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
loading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -3,23 +3,25 @@ import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/asset_transfer_provider.dart'; import 'package:test_sa/controllers/providers/api/asset_transfer_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/controllers/validator/validator.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.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_transfer.dart'; import 'package:test_sa/models/device/asset_transfer.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../models/new_models/building.dart';
import '../../../controllers/validator/validator.dart'; import '../../../models/new_models/site.dart';
import '../../app_style/colors.dart'; import '../../../new_views/common_widgets/app_filled_button.dart';
import '../../widgets/app_text_form_field.dart'; import '../../../new_views/common_widgets/default_app_bar.dart';
import '../../widgets/gas_refill/building_type_menu.dart'; import '../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../widgets/gas_refill/department_type_menu.dart'; import '../../../providers/gas_request_providers/site_provider.dart';
import '../../widgets/gas_refill/floor_type_menu.dart'; import '../../../providers/loading_list_notifier.dart';
import '../../widgets/hospitals/hospital_auto_complete_field_new.dart'; import '../../widgets/equipment/pick_asset.dart';
class RequestDeviceTransfer extends StatefulWidget { class RequestDeviceTransfer extends StatefulWidget {
static const String id = "/request-device-transfer"; static const String id = "/request-device-transfer";
@ -31,287 +33,148 @@ class RequestDeviceTransfer extends StatefulWidget {
} }
class _RequestDeviceTransferState extends State<RequestDeviceTransfer> { class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
bool _isLoading = false;
bool _validate = false;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
AssetTransferProvider _deviceTransferProvider; AssetTransferProvider _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController(); final TextEditingController _requestedQuantityController = TextEditingController();
final AssetTransfer _formModel = AssetTransfer(/*receiver: DeviceTransferInfo(), sender: DeviceTransferInfo()*/); final AssetTransfer _transferModel = AssetTransfer();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final TextEditingController _receiverNameController = TextEditingController(), _commentsController = TextEditingController();
final Device _assetDestination = Device();
Device _pickedAsset;
@override @override
void setState(VoidCallback fn) { void setState(VoidCallback fn) {
if (mounted) super.setState(() {}); if (mounted) super.setState(() {});
} }
_onSubmit() async { void _onSubmit() async {
_validate = true; _transferModel.assetId = _pickedAsset.id;
if (!_formKey.currentState.validate()) { _transferModel.destSiteId = _assetDestination.site?.id;
setState(() {}); _transferModel.destBuildingId = _assetDestination.building?.id;
return false; _transferModel.destFloorId = _assetDestination.floor?.id;
_transferModel.destDepartmentId = _assetDestination.department?.id;
if (!_formKey.currentState.validate() || !(await _transferModel.validate(context))) {
return;
} }
_formKey.currentState.save(); _formKey.currentState.save();
await _deviceTransferProvider.createRequest(context: context, assetDestination: _transferModel, asset: _pickedAsset);
// if (!_formModel.validate()) {
// setState(() {});
// return false;
// }
_isLoading = true;
setState(() {});
// _formModel.sender?.client?.id = _userProvider.user?.clientId;
int status = await _deviceTransferProvider.createRequest(
user: _userProvider.user,
host: _settingProvider.host,
model: _formModel,
);
_isLoading = false;
setState(() {});
if (status >= 200 && status < 300) {
// Fluttertoast.showToast(
// msg: _subtitle.requestCompleteSuccessfully,
// );
Navigator.of(context).pop();
}
// else {
// String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(
// content: Text(errorMessage),
// ));
// }
} }
@override @override
void dispose() { void dispose() {
_requestedQuantityController.dispose(); _requestedQuantityController.dispose();
_deviceTransferProvider.reset(); _deviceTransferProvider.reset();
_receiverNameController.dispose();
_commentsController.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context, listen: false);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context, listen: false);
_deviceTransferProvider = Provider.of<AssetTransferProvider>(context, listen: false); _deviceTransferProvider = Provider.of<AssetTransferProvider>(context, listen: false);
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.newTransferRequest),
body: Form( body: Form(
key: _formKey, key: _formKey,
child: SafeArea( child: SafeArea(
child: LoadingManager( child: Column(
isLoading: _isLoading, children: [
isFailedLoading: false, SingleChildScrollView(
stateCode: 200, child: Column(
onRefresh: () async {}, crossAxisAlignment: CrossAxisAlignment.start,
child: SingleChildScrollView( children: [
padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), 16.height,
child: Column( PickAsset(
crossAxisAlignment: CrossAxisAlignment.start, device: _pickedAsset,
children: [ onPickAsset: (asset) {
Center( _pickedAsset = asset;
child: Padding( setState(() {});
padding: const EdgeInsets.all(8.0), },
child: Text( ),
"Transfer Asset", 16.height,
style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold), context.translation.receiverDetails.heading5(context),
), 8.height,
AppTextFormField(
controller: _receiverNameController,
labelText: context.translation.receiverName,
validator: (text) => Validator.hasValue(text) ? null : context.translation.requiredField,
onSaved: (text) {},
),
8.height,
SingleItemDropDownMenu<Site, SiteProvider>(
context: context,
title: context.translation.destinationSite,
initialValue: _assetDestination?.site,
onSelect: (value) {
_assetDestination.site = value;
_assetDestination.building = null;
_assetDestination.floor = null;
_assetDestination.department = null;
setState(() {});
},
),
8.height,
SingleItemDropDownMenu<Building, NullableLoadingProvider>(
context: context,
title: context.translation.building,
initialValue: _assetDestination?.building,
enabled: _assetDestination?.site?.buildings?.isNotEmpty ?? false,
staticData: _assetDestination?.site?.buildings ?? [],
onSelect: (value) {
_assetDestination?.building = value;
_assetDestination?.floor = null;
_assetDestination?.department = null;
setState(() {});
},
),
8.height,
SingleItemDropDownMenu<Floor, NullableLoadingProvider>(
context: context,
title: context.translation.floor,
initialValue: _assetDestination?.floor,
enabled: _assetDestination?.building?.floors?.isNotEmpty ?? false,
staticData: _assetDestination?.building?.floors ?? [],
onSelect: (value) {
_assetDestination?.floor = value;
_assetDestination?.department = null;
setState(() {});
},
),
8.height,
SingleItemDropDownMenu<Department, NullableLoadingProvider>(
context: context,
title: context.translation.department,
initialValue: _assetDestination?.department,
enabled: _assetDestination?.floor?.departments?.isNotEmpty ?? false,
staticData: _assetDestination?.floor?.departments ?? [],
onSelect: (value) {
_assetDestination?.department = value;
},
), ),
), 16.height,
// const SizedBox(height: 8,), context.translation.comments.heading5(context),
// ASubTitle(_subtitle.title), 8.height,
// if(_validate && _formModel.title == null || _formModel.title?.isEmpty == true) AppTextFormField(
// ASubTitle(_subtitle.requiredWord,color: Colors.red,), controller: _commentsController,
// const SizedBox(height: 4,), labelText: context.translation.comments,
// ATextFormField( onSaved: (text) {
// initialValue: _formModel?.title, _transferModel.senderComment = text;
// textAlign: TextAlign.center, },
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.text,
// onSaved: (value){
// _formModel.title = value;
// },
// ),
12.height,
const ASubTitle("Asset"),
if (_validate /*&& _formModel.device == null*/)
ASubTitle(
context.translation.requiredWord,
color: Colors.red,
), ),
6.height, 100.height,
// DeviceButton( ],
// device: _formModel.device, ),
// onDevicePick: (device) { ).expanded,
// _formModel.device = device; AppFilledButton(label: context.translation.submitRequest, maxWidth: true, onPressed: _onSubmit)
// _formModel.sender.client = device.hospital; ],
// setState(() {}); ).paddingOnly(start: 16, end: 16, bottom: 24),
// },
// ),
// if (_formModel.device != null) 8.height,
// if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Site", value: _formModel.device.hospital?.name),
// if (_formModel.device != null) 4.height,
// if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Department", value: _formModel.device.destDepartmentName),
// if (_formModel.device != null) 4.height,
// if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Floor", value: _formModel.device.destFloor),
// if (_formModel.device != null) 4.height,
// if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Room", value: _formModel.device.destRoom),
// if (_formModel.device != null) 8.height,
// const SizedBox(height: 8,),
// const ASubTitle("Sender Department"),
// if(_validate && _formModel.senderDepartment == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
// const SizedBox(height: 4,),
// DepartmentButton(
// department: _formModel.senderDepartment,
// onDepartmentPick: (department){
// _formModel.senderDepartment = department;
// setState(() {});
// },
// ),
// 12.height,
// const ASubTitle("Destination Client"),
// if (_validate && _formModel.receiver.client == null)
// ASubTitle(
// _subtitle.requiredWord,
// color: Colors.red,
// ),
// 6.height,
// HospitalButton(
// hospital: _formModel.receiver.client,
// onHospitalPick: (hospital) {
// _formModel.receiver.client = hospital;
// setState(() {});
// },
// ),
// 12.height,
// const ASubTitle("Destination Department"),
// if (_validate && _formModel.receiver.department == null)
// ASubTitle(
// _subtitle.requiredWord,
// color: Colors.red,
// ),
// 6.height,
// DepartmentButton(
// department: _formModel.receiver.department,
// onDepartmentPick: (department) {
// _formModel.receiver.department = department;
// setState(() {});
// },
// ),
const SizedBox(
height: 4,
),
Divider(
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 8),
const ASubTitle("Destination"),
const SizedBox(
height: 4,
),
HospitalAutoCompleteField(
initialValue: _deviceTransferProvider.hospital?.name,
// onSave: (value){
// _search.hospital = value;
// },
onSearch: (value) {
_deviceTransferProvider.hospital = value;
_deviceTransferProvider.building = null;
_deviceTransferProvider.floor = null;
_deviceTransferProvider.department = null;
// _formModel.receiver.client = value;
setState(() {});
},
),
const SizedBox(
height: 8,
),
BuildingTypeMenu(
initialValue: _deviceTransferProvider?.building,
building: _deviceTransferProvider?.hospital?.buildings,
onSelect: (status) {
_deviceTransferProvider.building = status;
setState(() {});
},
),
const SizedBox(height: 8),
FloorTypeMenu(
initialValue: _deviceTransferProvider?.floor,
floors: _deviceTransferProvider?.building?.floors,
onSelect: (status) {
_deviceTransferProvider.floor = status;
setState(() {});
},
),
const SizedBox(height: 8),
DepartmentTypeMenu(
initialValue: _deviceTransferProvider?.department,
departments: _deviceTransferProvider?.floor?.departments,
onSelect: (status) {
_deviceTransferProvider.department = status;
// _formModel.receiver.department = Department(id: status.id, name: status.name);
setState(() {});
},
),
const SizedBox(height: 8),
const ASubTitle("Room"),
const SizedBox(
height: 4,
),
ATextFormField(
textAlign: TextAlign.center,
controller: _requestedQuantityController,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only",
textInputType: TextInputType.number,
onSaved: (value) {
_deviceTransferProvider.room = value;
},
),
12.height,
AButton(
text: context.translation.submit,
onPressed: _onSubmit,
),
const SizedBox(
height: 100,
)
],
),
),
),
), ),
), ),
); );
} }
} }
class AdditionalAssetInfo extends StatelessWidget {
final String title, value;
const AdditionalAssetInfo({@required this.title, @required this.value, Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(title ?? ""),
Container(
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
decoration: BoxDecoration(
color: AColors.inputFieldBackgroundColor,
border: Border.all(
color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: ASubTitle(value ?? ""),
),
],
);
}
}

@ -22,7 +22,6 @@ import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
import '../../../controllers/api_routes/http_status_manger.dart'; import '../../../controllers/api_routes/http_status_manger.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart'; import '../../../controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart';
import '../../widgets/app_text_form_field.dart'; import '../../widgets/app_text_form_field.dart';
import '../../widgets/buttons/app_back_button.dart'; import '../../widgets/buttons/app_back_button.dart';

@ -12,7 +12,6 @@ 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/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/pages/new_gas_refill_request_page.dart'; import 'package:test_sa/new_views/pages/new_gas_refill_request_page.dart';
import 'package:test_sa/new_views/pages/new_transfer_request_page.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/pages/device_transfer/track_device_transfer.dart'; import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart';
@ -27,6 +26,7 @@ import 'package:test_sa/views/widgets/drawer/drawer_item.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../widgets/land_page/land_page_item.dart'; import '../../widgets/land_page/land_page_item.dart';
import '../device_transfer/request_device_transfer.dart';
import 'requests/requests_page.dart'; import 'requests/requests_page.dart';
@Deprecated("Use the page which is inside the [new_views/pages/land_page] folder") @Deprecated("Use the page which is inside the [new_views/pages/land_page] folder")
@ -75,7 +75,7 @@ class _LandPageState extends State<LandPage> {
// _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); // _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
// _preventiveMaintenanceVisitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context); // _preventiveMaintenanceVisitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context);
// _regularVisitsProvider = Provider.of<RegularVisitsProvider>(context); // _regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
// //
if (firstTime) { if (firstTime) {
if (path != null) { if (path != null) {
Navigator.of(context).pushNamed("/" + path.split("/").first, arguments: path.split("/").last); Navigator.of(context).pushNamed("/" + path.split("/").first, arguments: path.split("/").last);
@ -147,7 +147,7 @@ class _LandPageState extends State<LandPage> {
mainAxisSpacing: 12, mainAxisSpacing: 12,
childAspectRatio: 1, childAspectRatio: 1,
children: [ children: [
/// enable this condition when the nurse account works /// todo [zaid] : enable this condition when the nurse account works
// if (_userProvider.user != null && _userProvider.user.type == UsersTypes.normal_user) // if (_userProvider.user != null && _userProvider.user.type == UsersTypes.normal_user)
LandPageItem( LandPageItem(
// text: _subtitle.newServiceRequest, // text: _subtitle.newServiceRequest,
@ -182,7 +182,7 @@ class _LandPageState extends State<LandPage> {
// Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id); // Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id);
// }, // },
// ), // ),
/// enable this condition when the nurse account works /// todo [zaid] : enable this condition when the nurse account works
// if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.engineer) // if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.engineer)
LandPageItem( LandPageItem(
text: "Request Gas Refill", text: "Request Gas Refill",
@ -203,8 +203,7 @@ class _LandPageState extends State<LandPage> {
text: "Transfer Asset", text: "Transfer Asset",
icon: FontAwesomeIcons.rightLeft, icon: FontAwesomeIcons.rightLeft,
onPressed: () { onPressed: () {
// Navigator.of(context).pushNamed(RequestDeviceTransfer.id); Navigator.of(context).pushNamed(RequestDeviceTransfer.id);
Navigator.of(context).pushNamed(NewTransferRequestPage.routeName);
}, },
), ),
LandPageItem( LandPageItem(
@ -215,7 +214,7 @@ class _LandPageState extends State<LandPage> {
}, },
), ),
/// enable this condition when the nurse account works /// todo [zaid] : enable this condition when the nurse account works
// if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user) // if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user)
LandPageItem( LandPageItem(
text: "Create Sub Work Order", text: "Create Sub Work Order",

@ -1,11 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_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/api/user_provider.dart';
@ -16,19 +12,20 @@ import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.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/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/providers/service_request_providers/requested_through_provider.dart';
import 'package:test_sa/views/widgets/equipment/pick_asset.dart'; import 'package:test_sa/views/widgets/equipment/pick_asset.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/sound/record_sound.dart'; import 'package:test_sa/views/widgets/sound/record_sound.dart';
import '../../../../models/lookup.dart'; import '../../../../models/lookup.dart';
import '../../../../new_views/app_style/app_color.dart'; import '../../../../new_views/app_style/app_color.dart';
import '../../../../new_views/common_widgets/app_dashed_button.dart';
import '../../../../new_views/common_widgets/app_lazy_loading.dart';
import '../../../../new_views/common_widgets/app_text_form_field.dart'; import '../../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../../new_views/common_widgets/default_app_bar.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart';
import '../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; import '../../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../../../providers/service_request_providers/equipment_status_provider.dart'; import '../../../../providers/service_request_providers/equipment_status_provider.dart';
import '../../../../providers/service_request_providers/priority_provider.dart'; import '../../../../providers/service_request_providers/priority_provider.dart';
import '../../../../providers/service_request_providers/type_of_request_provider.dart';
class CreateServiceRequestPage extends StatefulWidget { class CreateServiceRequestPage extends StatefulWidget {
static const String id = "/create-request"; static const String id = "/create-request";
@ -156,8 +153,30 @@ class CreateServiceRequestPageState extends State<CreateServiceRequestPage> {
}, },
), ),
8.height, 8.height,
AppDashedButton(title: _serviceRequest.devicePhotos?.first?.split("/")?.last ?? context.translation.attachImage, onPressed: _attachImage), Consumer<RequestedThroughProvider>(builder: (context, snapshot, _) {
16.height, return SingleItemDropDownMenu<Lookup, RequestedThroughProvider>(
context: context,
enabled: false,
title: context.translation.requestedThrough,
initialValue: snapshot.items?.firstWhere((element) => element.id == 375, orElse: () => null),
);
}),
8.height,
SingleItemDropDownMenu<Lookup, TypeOfRequestProvider>(
context: context,
title: context.translation.typeOfRequest,
initialValue: _serviceRequest?.type,
onSelect: (value) {
_serviceRequest.type = value;
},
),
8.height,
MultiFilesPicker(
label: context.translation.attachImage,
onlyImages: true,
files: _deviceImages,
),
((_serviceRequest.devicePhotos?.isNotEmpty ?? false) ? 16 : 8).height,
Align( Align(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: context.translation.callComments.heading5(context), child: context.translation.callComments.heading5(context),
@ -191,58 +210,8 @@ class CreateServiceRequestPageState extends State<CreateServiceRequestPage> {
); );
} }
_attachImage() async {
ImageSource source = await showDialog(
context: context,
builder: (dialogContext) => CupertinoAlertDialog(
actions: <Widget>[
TextButton(
child: Text(context.translation.pickFromCamera),
onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.camera);
},
),
TextButton(
child: Text(context.translation.pickFromGallery),
onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.gallery);
},
),
TextButton(
child: Text(context.translation.pickFromFiles),
onPressed: () async {
await _fromFilePicker();
Navigator.pop(context);
},
),
],
),
);
if (source == null) return;
final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
_serviceRequest.devicePhotos ??= [];
_serviceRequest.devicePhotos?.clear();
_serviceRequest.devicePhotos?.add(pickedFile.path);
setState(() {});
}
}
_fromFilePicker() async {
FilePickerResult result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'],
);
if (result?.files?.first != null) {
_serviceRequest.devicePhotos ??= [];
_serviceRequest.devicePhotos?.clear();
_serviceRequest.devicePhotos?.add(result?.files?.first?.path);
setState(() {});
}
}
Future<void> _submit() async { Future<void> _submit() async {
_serviceRequest?.requestedThrough = Provider.of<RequestedThroughProvider>(context, listen: false).items?.firstWhere((element) => element.id == 375, orElse: () => null);
if (_formKey.currentState.validate() && await _serviceRequest.validateNewRequest(context)) { if (_formKey.currentState.validate() && await _serviceRequest.validateNewRequest(context)) {
_formKey.currentState.save(); _formKey.currentState.save();
_serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();
@ -252,19 +221,12 @@ class CreateServiceRequestPageState extends State<CreateServiceRequestPage> {
_serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
} }
} }
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); await _serviceRequestsProvider.createRequest(
int status = await _serviceRequestsProvider.createRequest( context: context,
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
serviceRequest: _serviceRequest, serviceRequest: _serviceRequest,
); );
Navigator.of(context);
if (status >= 200 && status < 300) {
Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
Navigator.pop(context);
} else {
Fluttertoast.showToast(msg: context.translation.failedRequestMessage);
}
} }
} }
} }

@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
@ -17,7 +16,6 @@ import 'package:test_sa/models/engineer.dart';
import 'package:test_sa/models/part.dart'; import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.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/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/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
@ -59,7 +57,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
ServiceReport _serviceReport; ServiceReport _serviceReport;
bool _isLoading = false; bool _isLoading = false;
bool _showCommentField = false; bool _showCommentField = false;
final List<File> _files = []; final List<File> _files = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_provider.dart';
@ -18,7 +17,6 @@ import 'package:test_sa/models/engineer.dart';
import 'package:test_sa/models/part.dart'; import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.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/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/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
@ -60,7 +58,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
ServiceReport _serviceReport; ServiceReport _serviceReport;
bool _isLoading = false; bool _isLoading = false;
bool _showCommentField = false; bool _showCommentField = false;
List<File> _images = []; List<File> _images = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';

@ -5,170 +5,74 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_flat_button.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../../../new_views/common_widgets/app_dashed_button.dart';
import 'multi_image_picker_item.dart'; import 'multi_image_picker_item.dart';
class MultiFilesPicker extends StatefulWidget { class MultiFilesPicker extends StatefulWidget {
final String label; final String label;
final bool error; final bool error;
final List<File> files; final List<File> files;
final bool enabled; final bool enabled, onlyImages;
const MultiFilesPicker({Key key, this.files, this.label, this.error = false, this.enabled = true}) : super(key: key); const MultiFilesPicker({Key key, this.files, this.label, this.error = false, this.enabled = true, this.onlyImages = false}) : super(key: key);
@override @override
_MultiFilesPickerState createState() => _MultiFilesPickerState(); State<MultiFilesPicker> createState() => _MultiFilesPickerState();
} }
class _MultiFilesPickerState extends State<MultiFilesPicker> with TickerProviderStateMixin { class _MultiFilesPickerState extends State<MultiFilesPicker> {
Size _size;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_size = MediaQuery.of(context).size; return Column(
crossAxisAlignment: CrossAxisAlignment.start,
return (widget.enabled == false && (widget.files?.isEmpty ?? false)) children: [
? const SizedBox() AppDashedButton(title: widget.label, onPressed: (widget.enabled == false) ? () {} : onFilePicker),
: Container( 16.height,
padding: const EdgeInsets.all(12), if (widget.files?.isNotEmpty ?? false)
decoration: BoxDecoration( Wrap(
color: const Color(0xfff5f5f5), spacing: 8.toScreenWidth,
border: Border.all( children: List.generate(
color: const Color(0xffefefef), widget.files.length,
), (index) {
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), File image = widget.files[index];
), return MultiFilesPickerItem(
child: Column( file: image,
crossAxisAlignment: CrossAxisAlignment.start, enabled: widget.enabled,
children: [ onRemoveTap: (image) {
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),), if (!widget.enabled) {
Row( return;
children: [ }
Expanded( widget.files.remove(image);
child: Text( setState(() {});
widget.label ?? context.translation.images, },
style: Theme.of(context).textTheme.headline6.copyWith( );
fontSize: 14, },
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
if (widget.enabled)
AFlatButton(
text: context.translation.add,
onPressed: widget.enabled
? () {
// onImagePick(_subtitle);
onFilePicker(context.translation);
}
: null,
),
],
),
12.height,
AnimatedSize(
duration: const Duration(milliseconds: 400),
child: !widget.error
? const SizedBox.shrink()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.translation.imagesRequired,
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 14,
color: AColors.red,
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
],
),
),
AnimatedSwitcher(
duration: const Duration(milliseconds: 400),
child: Container(
key: ValueKey(widget.files.length),
width: _size.width,
height: 200 * AppStyle.getScaleFactor(context),
padding: EdgeInsets.all(
8 * AppStyle.getScaleFactor(context),
),
alignment: Alignment.topLeft,
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor, width: 2),
borderRadius: BorderRadius.circular(8 * AppStyle.getScaleFactor(context)),
),
child: widget.files.isEmpty && widget.enabled
? MaterialButton(
onPressed: widget.enabled
? () {
// onImagePick(_subtitle);
onFilePicker(context.translation);
}
: null,
child: Center(
child: Icon(
Icons.file_upload,
size: 48 * AppStyle.getScaleFactor(context),
color: Theme.of(context).primaryColor,
)),
)
: GridView.count(
crossAxisCount: 2,
//_size.width ~/ 80,
scrollDirection: Axis.horizontal,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(widget.files.length, (index) {
File _image = widget.files[index];
return MultiFilesPickerItem(
file: _image,
enabled: widget.enabled,
onRemoveTap: (image) {
if (!widget.enabled) {
return;
}
widget.files.remove(image);
setState(() {});
},
);
}),
),
),
),
],
), ),
); ),
],
);
} }
fromFilePicker(AppLocalizations subtitle) async { fromFilePicker() async {
FilePickerResult result = await FilePicker.platform.pickFiles( FilePickerResult result = await FilePicker.platform.pickFiles(
type: FileType.custom, type: FileType.custom,
allowMultiple: true, allowMultiple: true,
allowedExtensions: ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'], allowedExtensions: widget.onlyImages ? ['jpg', 'jpeg', 'png'] : ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'],
); );
if (result != null) { if (result != null) {
for (var path in result.paths) { for (var path in result.paths) {
widget.files.insert(0, File(path)); widget.files.add(File(path));
} }
setState(() {}); setState(() {});
} }
} }
onFilePicker(AppLocalizations subtitle) async { onFilePicker() async {
if (widget.files.length >= 5) { if (widget.files.length >= 5) {
Fluttertoast.showToast(msg: subtitle.maxImagesNumberIs5); Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5);
return; return;
} }
ImageSource source = await showDialog( ImageSource source = await showDialog(
@ -176,21 +80,21 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> with TickerProvider
builder: (dialogContext) => CupertinoAlertDialog( builder: (dialogContext) => CupertinoAlertDialog(
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: Text(subtitle.pickFromCamera), child: Text(context.translation.pickFromCamera),
onPressed: () { onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.camera); Navigator.of(dialogContext).pop(ImageSource.camera);
}, },
), ),
TextButton( TextButton(
child: Text(subtitle.pickFromGallery), child: Text(context.translation.pickFromGallery),
onPressed: () { onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.gallery); Navigator.of(dialogContext).pop(ImageSource.gallery);
}, },
), ),
TextButton( TextButton(
child: Text(subtitle.pickFromFiles), child: Text(context.translation.pickFromFiles),
onPressed: () async { onPressed: () async {
await fromFilePicker(subtitle); await fromFilePicker();
Navigator.pop(context); Navigator.pop(context);
}, },
), ),
@ -204,7 +108,7 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> with TickerProvider
if (pickedFile != null) { if (pickedFile != null) {
File fileImage = File(pickedFile.path); File fileImage = File(pickedFile.path);
if (fileImage != null) { if (fileImage != null) {
widget.files.insert(0, fileImage); widget.files.add(fileImage);
setState(() {}); setState(() {});
} }
} }

@ -3,10 +3,12 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.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/extensions/widget_extensions.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -22,72 +24,64 @@ class MultiFilesPickerItem extends StatelessWidget {
var isImage = file.path.split(".").last.toLowerCase() == "png" || file.path.split(".").last.toLowerCase() == "jpg" || file.path.split(".").last.toLowerCase() == "jpeg"; var isImage = file.path.split(".").last.toLowerCase() == "png" || file.path.split(".").last.toLowerCase() == "jpg" || file.path.split(".").last.toLowerCase() == "jpeg";
var isPdf = file.path.split(".").last.toLowerCase() == "pdf"; var isPdf = file.path.split(".").last.toLowerCase() == "pdf";
var isExcel = file.path.split(".").last.toLowerCase() == "xlsx"; var isExcel = file.path.split(".").last.toLowerCase() == "xlsx";
return Container( return SizedBox(
width: 80 * AppStyle.getScaleFactor(context), width: 54.toScreenWidth,
height: 80 * AppStyle.getScaleFactor(context), height: 51.toScreenWidth,
decoration: BoxDecoration( child: Stack(
boxShadow: [BoxShadow(color: isImage ? Colors.black38 : AColors.cyan.withOpacity(0.5), blurRadius: 2)], alignment: AlignmentDirectional.topEnd,
image: DecorationImage( children: [
image: isImage Container(
? (_isLocalUrl(file.path) ? FileImage(file) : NetworkImage(file.path)) margin: EdgeInsetsDirectional.only(top: 4.toScreenHeight, end: 6.toScreenWidth),
: AssetImage("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png"), decoration: BoxDecoration(
fit: BoxFit.cover, border: Border.all(width: 1, color: context.isDark ? AppColor.neutral30 : AppColor.neutral30),
), image: DecorationImage(
borderRadius: BorderRadius.circular(8), image: isImage
), ? (_isLocalUrl(file.path) ? FileImage(file) : NetworkImage(file.path))
child: MaterialButton( : AssetImage("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png"),
padding: EdgeInsets.zero, fit: BoxFit.cover,
onPressed: () async {
if (isImage) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Scaffold(
body: SafeArea(
child: Stack(
children: [
InteractiveViewer(
child: _isLocalUrl(file.path)
? Image.file(file)
: ImageLoader(
url: file.path,
boxFit: BoxFit.cover,
))
.center,
const ABackButton(),
],
),
),
),
), ),
); borderRadius: BorderRadius.circular(8),
} else if (_isLocalUrl(file.path)) { ),
OpenFile.open(file.path); child: MaterialButton(
} else { padding: EdgeInsets.zero,
if (!await launchUrl(Uri.parse(file.path), mode: LaunchMode.externalApplication)) { onPressed: () async {
Fluttertoast.showToast(msg: "UnExpected Error with file."); if (isImage) {
throw Exception('Could not launch '); Navigator.of(context).push(
} MaterialPageRoute(
} builder: (_) => Scaffold(
}, appBar: const DefaultAppBar(),
child: enabled body: SafeArea(
? Align( child: InteractiveViewer(
alignment: Alignment.topRight, child: _isLocalUrl(file.path)
child: IconButton( ? Image.file(file)
padding: const EdgeInsets.all(2.0), : ImageLoader(
icon: Container( url: file.path,
padding: const EdgeInsets.all(1), boxFit: BoxFit.cover,
decoration: BoxDecoration(color: Theme.of(context).scaffoldBackgroundColor.withOpacity(.3), borderRadius: BorderRadius.circular(8)), ),
child: const Icon( ).center,
Icons.remove_circle, ),
color: AColors.red, ),
), ),
), );
onPressed: () { } else if (_isLocalUrl(file.path)) {
onRemoveTap(file); OpenFile.open(file.path);
}, } else {
), if (!await launchUrl(Uri.parse(file.path), mode: LaunchMode.externalApplication)) {
) Fluttertoast.showToast(msg: "UnExpected Error with file.");
: const SizedBox(), throw Exception('Could not launch ');
}
}
},
),
),
if (enabled)
InkWell(
child: "remove".toSvgAsset(width: 16),
onTap: () {
onRemoveTap(file);
},
)
],
), ),
); );
} }

@ -2,7 +2,6 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.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/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/pantry/pentry.dart'; import 'package:test_sa/models/pantry/pentry.dart';
@ -35,7 +34,7 @@ class _PentryInfoFormState extends State<PentryInfoForm> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
widget.model?.files ??= []; widget.model?.files ??= [];
final userProvider = Provider.of<UserProvider>(context); final userProvider = Provider.of<UserProvider>(context);
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(

Loading…
Cancel
Save