Merge With Majd [part #2]

main_design2.0
zaid_daoud 2 years ago
parent 984f46913a
commit 6caab58171

@ -1,7 +1,5 @@
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
@ -23,6 +21,7 @@ class ApiManager {
Future<http.Response> get(
String url, {
Map<String, String> headers,
enableToastMessage = true,
}) async {
headers ??= {};
@ -34,7 +33,7 @@ class ApiManager {
http.Response response = await http.get(_url, headers: headers);
if (jsonDecode(response.body) is Map<String, dynamic>) {
final message = jsonDecode(response.body)["message"];
if (message != null && message.toString().isNotEmpty) {
if (message != null && message.toString().isNotEmpty && enableToastMessage) {
Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG);
}
}

@ -87,6 +87,7 @@ class URLs {
static get requestDeviceTransfer => "$_baseUrl/AssetTransfer/AddAssetTransfer"; // get
static get updateDeviceTransfer => "$_baseUrl/AssetTransfer/UpdateAssetTransfer"; // get
static get getDeviceTransfer => "$_baseUrl/AssetTransfer/GetAssetTransfers"; // get
static get getAssetTransferById => "$_baseUrl/AssetTransfer/GetAssetTransferById"; // get
// employee
static get getEmployees => "$_baseUrl/Lookups/GetLookup?lookupEnum=33"; // get

@ -60,9 +60,11 @@ class DeviceTransferProvider extends ChangeNotifier {
Future<int> getRequests({
@required String host,
@required User user,
bool mostRecent,
}) async {
if (isLoading == true) return -2;
isLoading = true;
notifyListeners();
Response response;
try {
Map<String, dynamic> body = {};
@ -81,6 +83,7 @@ class DeviceTransferProvider extends ChangeNotifier {
List<DeviceTransfer> itemsPage = listJson.map((request) => DeviceTransfer.fromJson(request)).toList();
items ??= [];
items.addAll(itemsPage);
sortMostRecent(items, mostRecent);
print(listJson);
if (itemsPage.length == pageItemNumber) {
nextPage = true;
@ -99,6 +102,30 @@ class DeviceTransferProvider extends ChangeNotifier {
}
}
void sortMostRecent(List<DeviceTransfer> transfer, bool mostRecent) {
if (mostRecent != null) {
transfer.sort((prev, next) =>
(mostRecent ?? false) ? DateTime.tryParse(next.createdOn).compareTo(DateTime.tryParse(prev.createdOn)) : DateTime.tryParse(prev.createdOn).compareTo(DateTime.tryParse(next.createdOn)));
}
}
Future<DeviceTransfer> getRequestById({int assetTransferId}) async {
Response response;
try {
response = await ApiManager.instance.get(
URLs.getAssetTransferById + "?assetTransferId=$assetTransferId",
enableToastMessage: false,
);
if (response.statusCode >= 200 && response.statusCode < 300) {
return DeviceTransfer.fromJson(json.decode(response.body)["data"]);
}
return null;
} catch (error) {
print(error);
return null;
}
}
Future<int> createRequest({
@required String host,
@required User user,

@ -75,7 +75,7 @@ class DevicesProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List equipmentListJson = json.decode(response.body)["data"];
_devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device)).toList());
_devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device, startKeyWithDest: false)).toList());
nextPage = true;
} else {
nextPage = false;
@ -116,8 +116,8 @@ class DevicesProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List equipmentListJson = json.decode(response.body)["data"];
page = equipmentListJson.map((device) => Device.fromJson(device)).toList();
_devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device)).toList());
page = equipmentListJson.map((device) => Device.fromJson(device, startKeyWithDest: false)).toList();
_devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device, startKeyWithDest: false)).toList());
notifyListeners();
}
return page;

@ -6,6 +6,7 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/models/user.dart';
class GasRefillProvider extends ChangeNotifier {
@ -47,9 +48,11 @@ class GasRefillProvider extends ChangeNotifier {
Future<int> getRequests({
@required String host,
@required User user,
bool mostRecent,
}) async {
if (isLoading == true) return -2;
isLoading = true;
notifyListeners();
Response response;
Map<String, dynamic> body = {};
@ -66,8 +69,13 @@ class GasRefillProvider extends ChangeNotifier {
// client's request was successfully received
List requestsListJson = json.decode(response.body)["data"];
List<GasRefillModel> itemsPage = requestsListJson.map((request) => GasRefillModel.fromJson(request)).toList();
items ??= [];
if (mostRecent != null) {
items = [];
} else {
items ??= [];
}
items.addAll(itemsPage);
sortMostRecent(items, mostRecent);
if (itemsPage.length == pageItemNumber) {
nextPage = true;
} else {
@ -86,12 +94,17 @@ class GasRefillProvider extends ChangeNotifier {
}
}
void sortMostRecent(List<GasRefillModel> models, bool mostRecent) {
if (mostRecent != null) {
models.sort((prev, next) => (mostRecent ?? false) ? next.title.compareTo(prev.title) : prev.title.compareTo(next.title));
}
}
Future<int> createModel({
@required String host,
@required User user,
@required GasRefillModel model,
}) async {
print("ss");
Map<String, dynamic> body = {
"uid": user.id.toString(),
"token": user.token ?? "",
@ -108,7 +121,6 @@ class GasRefillProvider extends ChangeNotifier {
"GazRefillNo": "GR-${DateTime.now().toString().split(" ").first}",
"status": model.status.toMap(),
};
print("ss1");
body["gazRefillDetails"] = model.details
.map((model) => {
"gasType": model.type.toMap(),
@ -121,7 +133,6 @@ class GasRefillProvider extends ChangeNotifier {
Response response;
try {
response = await ApiManager.instance.post(URLs.requestGasRefill, body: body);
print("ss2");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
if (items != null) {
@ -146,13 +157,14 @@ class GasRefillProvider extends ChangeNotifier {
"id": newModel.id,
"gazRefillNo": newModel.title ?? "",
"status": newModel.status.toMap(),
"expectedDate": oldModel.expectedDate?.toIso8601String(),
"expectedTime": oldModel.expectedDate?.toIso8601String(),
"startDate": startDate?.toIso8601String(),
"startTime": startDate?.toIso8601String(),
"endDate": endDate?.toIso8601String(),
"endTime": endDate?.toIso8601String(),
"workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60),
"expectedDate": newModel.expectedDate?.toIso8601String(),
"expectedTime": newModel.expectedDate?.toIso8601String(),
"startDate": newModel.startDate?.toIso8601String(),
"startTime": newModel.startDate?.toIso8601String(),
"endDate": newModel.endDate?.toIso8601String(),
"endTime": newModel.endDate?.toIso8601String(),
// "workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60),
'workingHours': newModel.workingHours,
"assignedEmployee": oldModel?.assignedEmployee?.id == null ? null : oldModel?.assignedEmployee?.toJson(),
"site": hospital?.toMap(),
"building": building?.toJson(includeFloors: false),
@ -198,4 +210,5 @@ class GasRefillProvider extends ChangeNotifier {
DateTime expectedDateTime;
DateTime startDate;
DateTime endDate;
TimerModel timer;
}

@ -93,17 +93,18 @@ class PartsProvider extends ChangeNotifier {
Future<List<Part>> getPartsList({String host, User user, String title}) async {
Response response;
try {
if (int.tryParse(title) != null)
if (int.tryParse(title) != null) {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partNo": title});
else
} else {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partName": title});
List<Part> _page = [];
}
List<Part> page = [];
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(response.body)["data"];
_page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
}
return _page;
return page;
} catch (error) {
return [];
}

@ -79,6 +79,7 @@ class RegularVisitsProvider extends ChangeNotifier {
List requestsListJson = json.decode(response.body)["data"];
List<Visit> _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList();
visits ??= [];
sortMostRecent(_visits);
visits.addAll(_visits);
if (_visits.length == pageItemNumber) {
nextPage = true;
@ -98,6 +99,12 @@ class RegularVisitsProvider extends ChangeNotifier {
return response.statusCode;
}
void sortMostRecent(List<Visit> visits) {
visits.sort((prev, next) => (visitsSearch.mostRecent ?? false)
? DateTime.tryParse(next.createdOn).compareTo(DateTime.tryParse(prev.createdOn))
: DateTime.tryParse(prev.createdOn).compareTo(DateTime.tryParse(next.createdOn)));
}
/// return -2 if request in progress
/// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403

@ -76,6 +76,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
List requestsListJson = json.decode(response.body)["data"];
List<ServiceRequest> serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList();
serviceRequests ??= [];
sortMostRecent(serviceRequestsPage);
serviceRequests.addAll(serviceRequestsPage);
if (serviceRequestsPage.length == pageItemNumber) {
nextPage = true;
@ -94,6 +95,12 @@ class ServiceRequestsProvider extends ChangeNotifier {
}
}
void sortMostRecent(List<ServiceRequest> requests) {
requests.sort(
(prev, next) => (search.mostRecent ?? false) ? DateTime.tryParse(next.date).compareTo(DateTime.tryParse(prev.date)) : DateTime.tryParse(prev.date).compareTo(DateTime.tryParse(next.date)),
);
}
Future<ServiceRequest> getSingleServiceRequest({
@required String requestId,
@required String host,

@ -35,7 +35,7 @@ class Device {
this.modelDefinition,
});
factory Device.fromJson(Map<String, dynamic> parsedJson) {
factory Device.fromJson(Map<String, dynamic> parsedJson, {bool startKeyWithDest = true}) {
print("parsedJson:$parsedJson");
return Device(
id: parsedJson["id"],
@ -44,10 +44,10 @@ class Device {
assetName: parsedJson["assetName"],
modelDefinition: ModelDefinition.fromJson(parsedJson["modelDefinition"]),
hospital: Hospital.fromJson(parsedJson["site"]),
destBuildingName: parsedJson["destBuildingName"],
destDepartmentName: parsedJson["destDepartmentName"],
destRoom: parsedJson["destRoom"],
destFloor: parsedJson["destFloor"],
destBuildingName: startKeyWithDest ? parsedJson["destBuildingName"] : parsedJson['building']['name'],
destDepartmentName: startKeyWithDest ? parsedJson["destDepartmentName"] : parsedJson['department']['departmentName'],
destRoom: startKeyWithDest ? parsedJson["destRoom"] : parsedJson['room'],
destFloor: startKeyWithDest ? parsedJson["destFloor"] : parsedJson['floor']['name'],
destSiteName: parsedJson['destSiteName']
// parsedJson["modelDefinition"] == null ? "" :
// parsedJson["modelDefinition"]["manufacturerName"],

@ -14,6 +14,7 @@ class DeviceTransfer {
Device device;
DeviceTransferInfo sender;
DeviceTransferInfo receiver;
String createdOn;
DeviceTransfer({
this.id,
@ -22,6 +23,7 @@ class DeviceTransfer {
this.userId,
this.sender,
this.receiver,
this.createdOn,
});
bool validate() {
@ -40,6 +42,7 @@ class DeviceTransfer {
final receiver = DeviceTransferInfo();
receiver.fromDetails(old.receiver);
this.receiver = receiver;
createdOn = old.createdOn;
}
factory DeviceTransfer.fromJson(Map<String, dynamic> parsedJson) {
@ -47,6 +50,7 @@ class DeviceTransfer {
id: parsedJson["id"],
title: parsedJson["transferCode"],
userId: parsedJson["uid"],
createdOn: parsedJson['createdOn'],
device: Device(
id: parsedJson["assetId"],
number: parsedJson["assetNumber"],

@ -22,7 +22,7 @@ class GasRefillModel {
String signatureEngineer;
Uint8List localNurseSignature;
Uint8List localEngineerSignature;
num workingHours;
DateTime startDate, endDate, expectedDate;
GasRefillModel({
@ -43,6 +43,7 @@ class GasRefillModel {
this.signatureEngineer,
this.localEngineerSignature,
this.localNurseSignature,
this.workingHours,
});
bool validate() {
@ -75,6 +76,7 @@ class GasRefillModel {
localNurseSignature = model.localNurseSignature;
signatureEngineer = model.signatureEngineer;
signatureNurse = model.signatureNurse;
workingHours = model.workingHours;
}
factory GasRefillModel.fromJson(Map<String, dynamic> parsedJson) {
@ -99,6 +101,7 @@ class GasRefillModel {
assignedEmployee: AssignedEmployee.fromJson(parsedJson['assignedEmployee'] ?? {}),
signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]),
signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]),
workingHours: parsedJson["workingHours"],
);
}
}

@ -48,42 +48,41 @@ class ServiceReport {
String reviewComment;
FaultDescription faultDescription;
ServiceReport({
this.id,
this.visitDate,
// this.endDate,
this.assetType,
this.equipmentStatus,
this.type,
this.faultDescriptionId,
this.workingHours,
this.travelingHours,
this.parts,
this.engineer,
this.workPreformed,
this.reason,
this.operatingHours,
this.callLastSituation,
this.currentSituation,
this.jobSheetNumber,
this.image,
this.device,
this.invoiceCode,
this.invoiceNumber,
this.quantity = "1",
this.timer,
this.signatureNurse,
this.signatureEngineer,
this.localNurseSignature,
this.localEngineerSignature,
this.comment,
this.repairLocation,
this.travelingExpense,
// this.startDate,
this.reviewComment,
this.faultDescription,
this.returnToService
});
ServiceReport(
{this.id,
this.visitDate,
// this.endDate,
this.assetType,
this.equipmentStatus,
this.type,
this.faultDescriptionId,
this.workingHours,
this.travelingHours,
this.parts,
this.engineer,
this.workPreformed,
this.reason,
this.operatingHours,
this.callLastSituation,
this.currentSituation,
this.jobSheetNumber,
this.image,
this.device,
this.invoiceCode,
this.invoiceNumber,
this.quantity = "1",
this.timer,
this.signatureNurse,
this.signatureEngineer,
this.localNurseSignature,
this.localEngineerSignature,
this.comment,
this.repairLocation,
this.travelingExpense,
// this.startDate,
this.reviewComment,
this.faultDescription,
this.returnToService});
Map<String, dynamic> toMap(ServiceRequest request) {
Map<String, dynamic> _map = {};
@ -228,7 +227,7 @@ class ServiceReport {
travelingHours: parsedJson["travelingHours"],
travelingExpense: parsedJson["travelingExpenses"],
visitDate: DateTime.tryParse(parsedJson["visitDate"]),
returnToService: DateTime.tryParse(parsedJson["replacementDate"]??""),
returnToService: DateTime.tryParse(parsedJson["replacementDate"] ?? ""),
workingHours: parsedJson["workingHours"],
timer: TimerModel(
startAt: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""),

@ -145,12 +145,12 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
text: _subtitle.edit,
onPressed: (_isSender || _isReceiver || false)
? () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer(
model: _model,
isSender: true,
)));
}
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer(
model: _model,
isSender: true,
)));
}
: null,
),
],
@ -171,12 +171,12 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
text: _subtitle.edit,
onPressed: (_isReceiver || false)
? () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer(
model: _model,
isSender: false,
)));
}
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer(
model: _model,
isSender: false,
)));
}
: null,
),
],

@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
@ -12,14 +10,13 @@ import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/departments/department_button.dart';
import 'package:test_sa/views/widgets/equipment/device_button.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../controllers/validator/validator.dart';
import '../../app_style/colors.dart';
import '../../widgets/app_text_form_field.dart';
import '../../widgets/gas_refill/building_type_menu.dart';
import '../../widgets/gas_refill/department_type_menu.dart';
@ -141,7 +138,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
// },
// ),
12.height,
const ASubTitle("Device"),
const ASubTitle("Asset"),
if (_validate && _formModel.device == null)
ASubTitle(
_subtitle.requiredWord,
@ -155,6 +152,45 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
setState(() {});
},
),
if (_formModel.device != null) 8.height,
if (_formModel.device != null) const ASubTitle("Asset Site"),
if (_formModel.device != null)
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)),
// boxShadow: const [
// AppStyle.boxShadow
// ]
),
child: ASubTitle(_formModel.device?.hospital?.name),
),
if (_formModel.device != null) 4.height,
if (_formModel.device != null && _formModel.device.destDepartmentName != null) const ASubTitle("Asset Department"),
if (_formModel.device != null && _formModel.device.destDepartmentName != null)
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)),
// boxShadow: const [
// AppStyle.boxShadow
// ]
),
child: ASubTitle(_formModel.device.destDepartmentName.toString()),
),
if (_formModel.device != null) 8.height,
// const SizedBox(height: 8,),
// const ASubTitle("Sender Department"),
// if(_validate && _formModel.senderDepartment == null)
@ -203,6 +239,8 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
Divider(
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 8),
const ASubTitle("Destination"),
const SizedBox(
height: 4,
),
@ -251,8 +289,8 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
},
),
const SizedBox(height: 8),
ASubTitle("Room"),
SizedBox(
const ASubTitle("Room"),
const SizedBox(
height: 4,
),
ATextFormField(

@ -9,6 +9,7 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_list.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/switch_button.dart';
class TrackDeviceTransferPage extends StatefulWidget {
static const String id = "/track-device-transfer";
@ -23,7 +24,7 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage> with
DeviceTransferProvider _deviceTransferProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
bool mostRecent = false;
@override
Widget build(BuildContext context) {
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context);
@ -72,6 +73,21 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage> with
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ASwitchButton(
title: "Most Recent",
value: mostRecent,
onChange: (value) async {
mostRecent = value;
await _deviceTransferProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
mostRecent: mostRecent,
);
},
),
),
Expanded(
child: DeviceTransferList(
nextPage: _deviceTransferProvider.nextPage,

@ -72,7 +72,6 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
);
_validate = false;
Navigator.of(context).pop();
Navigator.of(context).pop();
}
}

@ -89,16 +89,16 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
int status = widget.gasRefillModel == null
? await _gasRefillProvider.createModel(
user: _userProvider.user,
host: _settingProvider.host,
model: _formModel,
)
user: _userProvider.user,
host: _settingProvider.host,
model: _formModel,
)
: await _gasRefillProvider.updateModel(
user: _userProvider.user,
host: _settingProvider.host,
oldModel: widget.gasRefillModel,
newModel: _formModel,
);
user: _userProvider.user,
host: _settingProvider.host,
oldModel: widget.gasRefillModel,
newModel: _formModel,
);
_isLoading = false;
setState(() {});
if (status >= 200 && status < 300) {

@ -10,6 +10,8 @@ import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_list.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../widgets/switch_button.dart';
class TrackGasRefillPage extends StatefulWidget {
static const String id = "/track-gas-refill";
@ -23,6 +25,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
GasRefillProvider _gasRefillProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
bool mostRecent = false;
@override
Widget build(BuildContext context) {
@ -59,11 +62,11 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
children: [
Row(
children: [
ABackButton(),
const ABackButton(),
Expanded(
child: Center(
child: Text(
_subtitle.serviceRequests,
"Gas Refill Requests",
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.grey3A, fontStyle: FontStyle.italic),
),
),
@ -76,6 +79,21 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ASwitchButton(
title: "Most Recent",
value: mostRecent,
onChange: (value) async {
mostRecent = value;
await _gasRefillProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
mostRecent: mostRecent,
);
},
),
),
Expanded(
child: GasRefillList(
nextPage: _gasRefillProvider.nextPage,

@ -23,7 +23,6 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.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/sub_workorder/search_sub_workorder_page.dart';
import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart';
import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart';
import 'package:test_sa/views/pages/user/requests/create_request.dart';
@ -199,7 +198,7 @@ class _LandPageState extends State<LandPage> {
},
),
LandPageItem(
text: "transfer Device",
text: "Transfer Asset",
icon: FontAwesomeIcons.rightLeft,
onPressed: () {
Navigator.of(context).pushNamed(RequestDeviceTransfer.id);
@ -212,14 +211,14 @@ class _LandPageState extends State<LandPage> {
Navigator.of(context).pushNamed(TrackDeviceTransferPage.id);
},
),
if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user)
LandPageItem(
text: "Search Work Order",
svgPath: "assets/images/sub_workorder_icon.svg",
onPressed: () {
Navigator.of(context).pushNamed(SearchSubWorkOrderPage.id);
},
),
// if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user)
// LandPageItem(
// text: "Search Work Order",
// svgPath: "assets/images/sub_workorder_icon.svg",
// onPressed: () {
// Navigator.of(context).pushNamed(SearchSubWorkOrderPage.id);
// },
// ),
],
),
],

@ -31,6 +31,8 @@ import 'package:test_sa/views/widgets/status/service_request/service_request_thr
import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_through_provider.dart';
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_type_provider.dart';
import '../../../widgets/date_and_time/date_picker.dart';
import '../../../widgets/status/service_request/service_request_first_action.dart';
import '../../../widgets/status/service_request/service_request_loan_availability.dart';
@ -205,10 +207,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
),
ServiceRequestedThroughMenu(
initialValue: _serviceRequest.requestedThrough,
onSelect: (status) {
_serviceRequest.requestedThrough = status;
},
enabled: widget.serviceRequest == null ? true : false,
enabled: false,
),
if (widget.serviceRequest != null) 12.height,
if (widget.serviceRequest != null) const ASubTitle("First Action"),
@ -330,6 +329,10 @@ class CreateRequestPageState extends State<CreateRequestPage> {
}
_formKey.currentState.save();
_serviceRequest.deviceId = _device?.id;
if (widget.serviceRequest == null) {
_serviceRequest.type = Provider.of<ServiceRequestTypeProvider>(context, listen: false).getDefaultItem();
}
_serviceRequest.requestedThrough = Provider.of<ServiceRequestedThroughProvider>(context, listen: false).getDefaultItem();
_isLoading = true;
setState(() {});
_serviceRequest.devicePhotos = _deviceImages.map((e) => "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}").toList();

@ -26,7 +26,6 @@ import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/parts/part_item.dart';
@ -722,7 +721,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
},
),
const SizedBox(height: 8),
ASubTitle("Solutions"),
ASubTitle(_subtitle.workPreformed),
const SizedBox(height: 4),
ATextFormField(
initialValue: _serviceReport?.workPreformed,

@ -56,6 +56,20 @@ class DeviceButton extends StatelessWidget {
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),
Text(
"${_subtitle.assetNumber} : ${device.number}",
style: Theme.of(context).textTheme.subtitle2,
),
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),
Text(
"${_subtitle.assetName} : ${device.modelDefinition.assetName}",
style: Theme.of(context).textTheme.subtitle2,
),
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';

@ -80,7 +80,7 @@ class _BuildingTypeMenuState extends State<BuildingTypeMenu> {
return DropdownMenuItem<Buildings>(
value: value,
child: Text(
value.name,
value.name ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
color: Theme.of(context).primaryColor,
fontSize: 11,

@ -80,7 +80,7 @@ class _FloorTypeMenuState extends State<FloorTypeMenu> {
return DropdownMenuItem<Floors>(
value: value,
child: Text(
value.name,
value.name ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
color: Theme.of(context).primaryColor,
fontSize: 11,

@ -1,11 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.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/requests/request_status.dart';
@ -19,8 +15,7 @@ class GasRefillItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
User _user = Provider.of<UserProvider>(context, listen: false).user;
Subtitle subtitle = AppLocalization.of(context).subtitle;
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;
@ -28,7 +23,7 @@ class GasRefillItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 4),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
backgroundColor: itemColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
@ -49,14 +44,14 @@ class GasRefillItem extends StatelessWidget {
children: [
Text(
item.title ?? "-----",
style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold),
style: Theme.of(context).textTheme.titleLarge.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold),
),
Row(
children: [
Expanded(
child: Text(
_subtitle.hospital,
style: Theme.of(context).textTheme.subtitle2.copyWith(
subtitle.hospital,
style: Theme.of(context).textTheme.titleSmall.copyWith(
color: onItemColor,
),
),
@ -64,29 +59,48 @@ class GasRefillItem extends StatelessWidget {
if (item.clientName != null)
Text(
item.clientName,
style: Theme.of(context).textTheme.subtitle2.copyWith(
style: Theme.of(context).textTheme.titleSmall.copyWith(
color: onItemColor,
),
),
],
),
Divider(
color: onItemColor,
),
Divider(color: onItemColor),
Row(
children: [
Expanded(
child: Text(
_subtitle.status,
style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor,
),
),
child: Text(subtitle.status, style: Theme.of(context).textTheme.titleSmall.copyWith(color: onItemColor)),
),
if (item.status?.id != null) StatusLabel(label: item.status.name, color: AColors.getGasStatusColor(item.status.id)),
],
),
//Divider(color: onItemColor,),
if (item?.expectedDate != null) Divider(color: onItemColor),
if (item?.expectedDate != null)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Visit Date", style: Theme.of(context).textTheme.titleSmall.copyWith(color: onItemColor)),
Text(item.expectedDate.toIso8601String().split("T").first, style: Theme.of(context).textTheme.titleSmall.copyWith(color: onItemColor)),
],
),
if (item?.details?.isNotEmpty ?? false) Divider(color: onItemColor),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item?.details?.isNotEmpty ?? false) Text("Gas Type", style: Theme.of(context).textTheme.titleSmall.copyWith(color: onItemColor)),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: item.details
.map(
(gas) => gas?.type?.name?.isNotEmpty ?? false
? Text(gas?.type?.name, style: Theme.of(context).textTheme.titleSmall.copyWith(color: onItemColor))
: const SizedBox.shrink(),
)
.toList(),
)
],
),
],
),
),

@ -8,10 +8,12 @@ import 'package:test_sa/models/hospital.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/loaders/app_loading.dart';
class HospitalAutoCompleteField extends StatefulWidget {
final String initialValue;
final Function(Hospital) onSearch;
final bool enabled;
//final Function(Hospital) onSave;
@ -19,6 +21,7 @@ class HospitalAutoCompleteField extends StatefulWidget {
Key key,
this.onSearch,
this.initialValue,
this.enabled = true,
}) : super(key: key);
@override
@ -66,32 +69,41 @@ class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
// AppStyle.boxShadow
// ]
),
child: TypeAheadField<Hospital>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: _subtitle.hospital,
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
),
suggestionsCallback: (vale) async {
return await HospitalsProvider().getHospitalsListByVal(searchVal: _controller.text);
},
itemBuilder: (context, hospital) {
return ListTile(
title: Text(hospital.name),
);
},
onSuggestionSelected: (hospital) {
widget.onSearch(hospital);
},
),
child: widget.enabled
? TypeAheadField<Hospital>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: _subtitle.hospital,
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
),
suggestionsCallback: (vale) async {
return await HospitalsProvider().getHospitalsListByVal(searchVal: _controller.text);
},
itemBuilder: (context, hospital) {
return ListTile(
title: Text(hospital.name),
);
},
onSuggestionSelected: (hospital) {
widget.onSearch(hospital);
},
)
: widget.initialValue == null
? const Padding(
padding: EdgeInsets.all(8.0),
child: ALoading(),
)
: ListTile(
title: Center(child: Text(widget.initialValue)),
),
);
}
}

@ -306,21 +306,22 @@ class _ServiceRequestsSearchDialogState extends State<ServiceRequestsSearchDialo
// ),
// ),
Visibility(
visible: widget.initialSearchValue.toMap().isNotEmpty,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: AButton(
padding: EdgeInsets.zero,
text: _subtitle.clearSearch,
onPressed: () {
_search = ServiceRequestSearch();
Navigator.of(context).pop(_search);
},
Visibility(
visible: widget.initialSearchValue.toMap().isNotEmpty,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: AButton(
padding: EdgeInsets.zero,
text: _subtitle.clearSearch,
onPressed: () {
_search = ServiceRequestSearch();
Navigator.of(context).pop(_search);
},
),
),
),
),
],
],
),
),
),
),

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:rive/rive.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
@ -72,6 +73,8 @@ class _RecordSoundState extends State<RecordSound> {
// await Permission.camera
PermissionStatus status = await Permission.microphone.request();
if (!status.isGranted) {
PermissionStatus status = await Permission.microphone.request();
Fluttertoast.showToast(msg: "Permission Denied");
return;
}
_rive.addController(SimpleAnimation('recording'));
@ -115,11 +118,11 @@ class _RecordSoundState extends State<RecordSound> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 12, right: 0),
padding: const EdgeInsets.only(left: 12, right: 0),
decoration: BoxDecoration(
color: Color(0xfff5f5f5),
color: const Color(0xfff5f5f5),
border: Border.all(
color: Color(0xffefefef),
color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),

@ -5,9 +5,9 @@ import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import 'package:test_sa/views/app_style/sizing.dart';
class SpeechToTextButton extends StatefulWidget {
final TextEditingController controller;
@ -23,7 +23,7 @@ class SpeechToTextButton extends StatefulWidget {
class _SpeechToTextButtonState extends State<SpeechToTextButton> {
bool _speechEnabled = false;
SettingProvider _settingProvider;
SpeechToText _speechToText = SpeechToText();
final SpeechToText _speechToText = SpeechToText();
/// This has to happen only once per app
void _initSpeech() async {
@ -64,12 +64,15 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
@override
void initState() {
_initSpeech();
widget.controller.addListener(() {
setState(() {});
});
super.initState();
}
@override
void setState(VoidCallback fn) {
if (!this.mounted) return;
if (!mounted) return;
super.setState(fn);
}
@ -77,17 +80,17 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
return Container(
padding: EdgeInsets.only(left: 12, right: 12),
padding: const EdgeInsets.only(left: 12, right: 12),
decoration: BoxDecoration(
color: Color(0xfff5f5f5),
color: const Color(0xfff5f5f5),
border: Border.all(
color: Color(0xffefefef),
color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: Row(
children: [
widget.mini ? SizedBox.shrink() : ASubTitle("Text To Speech"),
widget.mini ? const SizedBox.shrink() : const ASubTitle("Speech To Text"),
widget.controller.text.isNotEmpty && widget.enabled
? AIconButton2(
iconData: Icons.delete,
@ -96,8 +99,8 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
setState(() {});
},
)
: SizedBox.shrink(),
Spacer(),
: const SizedBox.shrink(),
const Spacer(),
TextButton(
onPressed: widget.enabled
? () {
@ -113,7 +116,7 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
child: Text(_settingProvider.speechToText)),
GestureDetector(
child: _speechToText.isListening
? Icon(
? const Icon(
Icons.fiber_manual_record,
color: Colors.red,
)
@ -127,7 +130,11 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
Fluttertoast.showToast(msg: "microphone not available");
return;
}
_startListening();
if (_speechToText.isListening) {
_stopListening();
} else {
_startListening();
}
}
: null,
),

@ -12,7 +12,6 @@ class ServiceRequestPriorityMenu extends StatelessWidget {
final Lookup initialValue;
final bool enabled;
const ServiceRequestPriorityMenu({Key key, this.onSelect, this.initialValue, this.enabled}) : super(key: key);
@override
Widget build(BuildContext context) {

@ -13,7 +13,6 @@ class ServiceRequestedThroughMenu extends StatelessWidget {
final bool enabled;
const ServiceRequestedThroughMenu({Key key, this.onSelect, this.initialValue, this.enabled = true}) : super(key: key);
@override
Widget build(BuildContext context) {
final settingProvider = Provider.of<SettingProvider>(context);
@ -28,7 +27,7 @@ class ServiceRequestedThroughMenu extends StatelessWidget {
await menuProvider.getData(user: userProvider.user, host: settingProvider.host);
},
child: SingleStatusMenu(
initialStatus: initialValue,
initialStatus: enabled ? initialValue : menuProvider.getDefaultItem(),
statuses: menuProvider.items,
onSelect: onSelect,
enabled: enabled,

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../app_style/colors.dart';
import '../app_style/sizing.dart';
class ASwitchButton extends StatelessWidget {
final String title;
final bool value;
final void Function(bool) onChange;
const ASwitchButton({
@required this.title,
@required this.value,
@required this.onChange,
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
margin: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
color: AColors.inputFieldBackgroundColor,
border: Border.all(
color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ASubTitle(title),
Switch.adaptive(
value: value,
activeColor: AColors.primaryColor,
onChanged: onChange,
),
],
),
);
}
}
Loading…
Cancel
Save