Merge branch 'zaid-development' into 'master'
Restructuring Project Files & Supporting Null Safety See merge request haroon6138/cloudsolutions-atoms!3merge-requests/4/merge
commit
f4aef79fa7
@ -1,40 +0,0 @@
|
|||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
class HttpStatusManger{
|
|
||||||
static String getStatusMessage({
|
|
||||||
@required int status,
|
|
||||||
@required Subtitle subtitle,
|
|
||||||
String messageFor400,
|
|
||||||
String messageFor200,
|
|
||||||
}){
|
|
||||||
if(status == null)
|
|
||||||
// no status code - code error no need for subtitle
|
|
||||||
return "careful null status";
|
|
||||||
if(status == -1)
|
|
||||||
// client's request in process
|
|
||||||
return subtitle.currentlyServiceNotAvailable;
|
|
||||||
if(status == -2){
|
|
||||||
// client's request in process
|
|
||||||
return subtitle.waitUntilYourRequestComplete;
|
|
||||||
}else if(status >= 200 && status < 300){
|
|
||||||
// client's request was successfully received
|
|
||||||
return messageFor200 ?? subtitle.requestCompleteSuccessfully;
|
|
||||||
} else if(status >= 400 && status < 500){
|
|
||||||
// client's request have error
|
|
||||||
switch(status){
|
|
||||||
case 400:
|
|
||||||
return messageFor400 ?? subtitle.failedToCompleteRequest;
|
|
||||||
default:
|
|
||||||
return subtitle.failedToCompleteRequest;
|
|
||||||
}
|
|
||||||
} else if(status >= 500){
|
|
||||||
// server error
|
|
||||||
return subtitle.currentlyServiceNotAvailable;
|
|
||||||
} else {
|
|
||||||
// no error match so return default error
|
|
||||||
return subtitle.failedToCompleteRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,172 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:http/http.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/user.dart';
|
|
||||||
|
|
||||||
class GasRefillProvider extends ChangeNotifier{
|
|
||||||
|
|
||||||
// number of items call in each request
|
|
||||||
final pageItemNumber = 50;
|
|
||||||
|
|
||||||
//reset provider data
|
|
||||||
void reset(){
|
|
||||||
items = null;
|
|
||||||
nextPage = true;
|
|
||||||
stateCode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// state code of current request to defied error message
|
|
||||||
// like 400 customer request failed
|
|
||||||
// 500 service not available
|
|
||||||
int stateCode;
|
|
||||||
|
|
||||||
// true if there is next page in product list and false if not
|
|
||||||
bool nextPage = true;
|
|
||||||
|
|
||||||
// list of user requests
|
|
||||||
List<GasRefillModel> items;
|
|
||||||
|
|
||||||
// when requests in-process _loading = true
|
|
||||||
// done _loading = true
|
|
||||||
// failed _loading = false
|
|
||||||
bool isLoading;
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
/// for more details check http state manager
|
|
||||||
/// lib\controllers\http_status_manger\http_status_manger.dart
|
|
||||||
Future<int> getRequests ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
}) async {
|
|
||||||
if(isLoading == true)
|
|
||||||
return -2;
|
|
||||||
isLoading = true;
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
response = await get(
|
|
||||||
Uri.parse(
|
|
||||||
"$host${URLs.getGasRefill}?uid=${user.id}"
|
|
||||||
"&token=${user.token}&page=${(items?.length ?? 0) ~/pageItemNumber}"
|
|
||||||
),
|
|
||||||
headers: {
|
|
||||||
"Content-Type":"application/json; charset=utf-8"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(stateCode >= 200 && stateCode < 300) {
|
|
||||||
// client's request was successfully received
|
|
||||||
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
|
|
||||||
List<GasRefillModel> itemsPage = requestsListJson.map(
|
|
||||||
(request) => GasRefillModel.fromJson(request)).toList();
|
|
||||||
items ??= [];
|
|
||||||
items.addAll(itemsPage);
|
|
||||||
if(itemsPage.length == pageItemNumber){
|
|
||||||
nextPage = true;
|
|
||||||
}else{
|
|
||||||
nextPage = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isLoading = false;
|
|
||||||
notifyListeners();
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
isLoading = false;
|
|
||||||
stateCode = -1;
|
|
||||||
notifyListeners();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> createModel ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required GasRefillModel model,
|
|
||||||
}) async {
|
|
||||||
Map<String,dynamic> body = {
|
|
||||||
"uid": user.id.toString(),
|
|
||||||
"token": user.token ?? "",
|
|
||||||
"title": model.title ?? "",
|
|
||||||
"status": "0",//model.status.value.toString(),
|
|
||||||
};
|
|
||||||
|
|
||||||
body["details"] = jsonEncode(model.details.map((model) => {
|
|
||||||
"type": model.type.id?.toString(),
|
|
||||||
"size": model.cylinderSize?.id.toString(),
|
|
||||||
"requsted_qty": model.requestedQuantity.toString(),
|
|
||||||
}).toList());
|
|
||||||
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.requestGasRefill),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
if(items != null) {
|
|
||||||
items.insert(
|
|
||||||
0,
|
|
||||||
GasRefillModel.fromJson(
|
|
||||||
json.decode(utf8.decode(response.bodyBytes))[0]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> updateModel ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required GasRefillModel oldModel,
|
|
||||||
@required GasRefillModel newModel,
|
|
||||||
}) async {
|
|
||||||
Map<String,dynamic> body = {
|
|
||||||
"uid": user.id.toString(),
|
|
||||||
"token": user.token ?? "",
|
|
||||||
"title": newModel.title ?? "",
|
|
||||||
"status": newModel.status.id.toString(),
|
|
||||||
};
|
|
||||||
|
|
||||||
body["details"] = jsonEncode(newModel.details.map((model) => {
|
|
||||||
"type": model.type.id.toString(),
|
|
||||||
"size": model.cylinderSize.id.toString(),
|
|
||||||
"requsted_qty": model.requestedQuantity.toString(),
|
|
||||||
"deliverd_qty": model.deliveredQuantity.toString(),
|
|
||||||
}).toList());
|
|
||||||
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse("$host${URLs.updateGasRefill}/${newModel.id}"),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
oldModel.fromGasRefillModel(newModel);
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,422 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:test_sa/controllers/api_routes/urls.dart';
|
|
||||||
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
|
|
||||||
import 'package:test_sa/models/issue.dart';
|
|
||||||
import 'package:test_sa/models/lookup.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_search.dart';
|
|
||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:test_sa/models/timer_model.dart';
|
|
||||||
import 'package:test_sa/models/user.dart';
|
|
||||||
|
|
||||||
class ServiceRequestsProvider extends ChangeNotifier{
|
|
||||||
|
|
||||||
// number of items call in each request
|
|
||||||
final pageItemNumber = 50;
|
|
||||||
|
|
||||||
//reset provider data
|
|
||||||
void reset(){
|
|
||||||
serviceRequests = null;
|
|
||||||
nextPage = true;
|
|
||||||
stateCode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// state code of current request to defied error message
|
|
||||||
// like 400 customer request failed
|
|
||||||
// 500 service not available
|
|
||||||
int stateCode;
|
|
||||||
|
|
||||||
// true if there is next page in product list and false if not
|
|
||||||
bool nextPage = true;
|
|
||||||
|
|
||||||
// list of user requests
|
|
||||||
List<ServiceRequest> serviceRequests;
|
|
||||||
|
|
||||||
// when requests in-process _loading = true
|
|
||||||
// done _loading = true
|
|
||||||
// failed _loading = false
|
|
||||||
bool isLoading;
|
|
||||||
|
|
||||||
ServiceRequestSearch search = ServiceRequestSearch();
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
/// for more details check http state manager
|
|
||||||
/// lib\controllers\http_status_manger\http_status_manger.dart
|
|
||||||
Future<int> getRequests ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required String hospitalId,
|
|
||||||
}) async {
|
|
||||||
if(isLoading == true)
|
|
||||||
return -2;
|
|
||||||
isLoading = true;
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
response = await get(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.getServiceRequests
|
|
||||||
+"?uid=${user.id}"
|
|
||||||
+(hospitalId == null? "" :"&client_nid=$hospitalId")
|
|
||||||
+"&token=${user.token}"
|
|
||||||
"&page=${(serviceRequests?.length ?? 0) ~/pageItemNumber}"
|
|
||||||
+search?.toSearchString() ?? ""
|
|
||||||
),
|
|
||||||
headers: {
|
|
||||||
"Content-Type":"application/json; charset=utf-8"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
// client's request was successfully received
|
|
||||||
List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
|
|
||||||
List<ServiceRequest> _serviceRequestsPage = requestsListJson.map(
|
|
||||||
(request) => ServiceRequest.fromJson(request)).toList();
|
|
||||||
if(serviceRequests == null)
|
|
||||||
serviceRequests = [];
|
|
||||||
serviceRequests.addAll(_serviceRequestsPage);
|
|
||||||
if(_serviceRequestsPage.length == pageItemNumber){
|
|
||||||
nextPage = true;
|
|
||||||
}else{
|
|
||||||
nextPage = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isLoading = false;
|
|
||||||
notifyListeners();
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
isLoading = false;
|
|
||||||
stateCode = -1;
|
|
||||||
notifyListeners();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServiceRequest> getSingleServiceRequest({
|
|
||||||
@required String requestId,
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required Subtitle subtitle,
|
|
||||||
}) async {
|
|
||||||
String userData = '';
|
|
||||||
if(user != null){
|
|
||||||
userData += "&uid="+user.id;
|
|
||||||
userData += "&token="+user.token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
response = await get(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.getSingleServiceRequest
|
|
||||||
+'?call_nid=$requestId'
|
|
||||||
'$userData',)
|
|
||||||
);
|
|
||||||
}catch(error){
|
|
||||||
throw(HttpStatusManger.getStatusMessage(
|
|
||||||
status: -1, subtitle: subtitle));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the call to the server was successful, parse the JSON.
|
|
||||||
if (response.statusCode >= 200 && response.statusCode < 300){
|
|
||||||
// If the call to the server was successful, parse the JSON.
|
|
||||||
List jsonList = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
|
|
||||||
List<ServiceRequest> _requests = jsonList.map((i) => ServiceRequest.fromJson(i)).toList();
|
|
||||||
return _requests[0];
|
|
||||||
}else{
|
|
||||||
throw(HttpStatusManger.getStatusMessage(
|
|
||||||
status: response.statusCode, subtitle: subtitle));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> createRequest ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required ServiceRequest serviceRequest,
|
|
||||||
}) async {
|
|
||||||
|
|
||||||
var body = {
|
|
||||||
"uid": user.id,
|
|
||||||
"token": user.token ?? "",
|
|
||||||
"sn_id": serviceRequest.deviceId ?? "",
|
|
||||||
"date": (DateTime.now().millisecondsSinceEpoch).toString(),
|
|
||||||
"client": user.hospital.id ?? '',
|
|
||||||
"complaint": serviceRequest.maintenanceIssue,
|
|
||||||
"image": json.encode(serviceRequest.devicePhotos),
|
|
||||||
"priority": (serviceRequest.priority?.id).toString(),
|
|
||||||
"defect_types": (serviceRequest.defectType?.id).toString(),
|
|
||||||
};
|
|
||||||
if(serviceRequest.audio != null){
|
|
||||||
body["audio"] = serviceRequest.audio;
|
|
||||||
}
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.createRequest),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
if(serviceRequests != null)
|
|
||||||
serviceRequests.insert(
|
|
||||||
0,
|
|
||||||
ServiceRequest.fromJson(
|
|
||||||
json.decode(utf8.decode(response.bodyBytes))[0]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> createIssueReport ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required Issue issue,
|
|
||||||
}) async {
|
|
||||||
Response response;
|
|
||||||
Map<String,String> body = issue.toMap();
|
|
||||||
body["uid"] = user.id;
|
|
||||||
body["token"] = user.token;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(host+URLs.createReport),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> updateDate ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required String newDate,
|
|
||||||
@required Lookup employee,
|
|
||||||
@required ServiceRequest request,
|
|
||||||
}) async {
|
|
||||||
Response response;
|
|
||||||
Map<String,String> body = {};
|
|
||||||
body["uid"] = user.id;
|
|
||||||
body["token"] = user.token;
|
|
||||||
body["nid"] = request.id;
|
|
||||||
if(newDate != null) body["date"] = newDate;
|
|
||||||
if(employee != null) body["ass_emp"] = employee.id.toString();
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.updateRequestDate),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
request.engineerName = employee.label;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> createServiceReport ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required ServiceReport report,
|
|
||||||
@required ServiceRequest request,
|
|
||||||
}) async {
|
|
||||||
Response response;
|
|
||||||
Map<String,String> body = report.toMap();
|
|
||||||
body["uid"] = user.id;
|
|
||||||
body["token"] = user.token;
|
|
||||||
body["job_id"] = request.id;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.createServiceReport),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
reset();
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> createDuplicatedReport ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required ServiceRequest request,
|
|
||||||
}) async {
|
|
||||||
Response response;
|
|
||||||
String userData = '';
|
|
||||||
if(user != null){
|
|
||||||
userData += "&uid="+user.id;
|
|
||||||
userData += "&token="+user.token;
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
response = await get(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.createDuplicatedReport
|
|
||||||
+"?nid=${request.id}"
|
|
||||||
+userData),
|
|
||||||
);
|
|
||||||
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
reset();
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> updateServiceReport ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required ServiceReport report,
|
|
||||||
@required ServiceRequest request,
|
|
||||||
}) async {
|
|
||||||
Response response;
|
|
||||||
Map<String,String> body = report.toMap();
|
|
||||||
body["uid"] = user.id;
|
|
||||||
body["token"] = user.token;
|
|
||||||
body["job_id"] = request.id;
|
|
||||||
body["report_id"] = request.reportID;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.updateServiceReport),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
stateCode = response.statusCode;
|
|
||||||
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
reset();
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> updateServiceReportTimer ({
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required TimerModel timer,
|
|
||||||
@required ServiceRequest request,
|
|
||||||
}) async {
|
|
||||||
Response response;
|
|
||||||
Map<String,String> body = {};
|
|
||||||
body["uid"] = user.id;
|
|
||||||
body["token"] = user.token;
|
|
||||||
body["job_id"] = request.id;
|
|
||||||
body["start_time"] = (timer.startAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0);
|
|
||||||
body["end_time"] = (timer.endAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0);
|
|
||||||
body["working_hours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
|
|
||||||
body["report_id"] = request.reportID;
|
|
||||||
try{
|
|
||||||
response = await post(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.updateServiceReport),
|
|
||||||
body: body,
|
|
||||||
);
|
|
||||||
//stateCode = response.statusCode;
|
|
||||||
|
|
||||||
if(response.statusCode >= 200 && response.statusCode < 300) {
|
|
||||||
// reset();
|
|
||||||
// notifyListeners();
|
|
||||||
}
|
|
||||||
return response.statusCode;
|
|
||||||
|
|
||||||
} catch(error) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServiceReport> getSingleServiceReport({
|
|
||||||
@required String reportId,
|
|
||||||
@required String host,
|
|
||||||
@required User user,
|
|
||||||
@required Subtitle subtitle,
|
|
||||||
}) async {
|
|
||||||
String userData = '';
|
|
||||||
if(user != null){
|
|
||||||
userData += "&uid="+user.id;
|
|
||||||
userData += "&token="+user.token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Response response;
|
|
||||||
try{
|
|
||||||
|
|
||||||
response = await get(
|
|
||||||
Uri.parse(
|
|
||||||
host+URLs.getServiceReport
|
|
||||||
+'?report_id=$reportId'
|
|
||||||
'$userData',)
|
|
||||||
);
|
|
||||||
|
|
||||||
}catch(error){
|
|
||||||
throw(HttpStatusManger.getStatusMessage(
|
|
||||||
status: -1, subtitle: subtitle));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the call to the server was successful, parse the JSON.
|
|
||||||
if (response.statusCode >= 200 && response.statusCode < 300){
|
|
||||||
// If the call to the server was successful, parse the JSON.
|
|
||||||
return ServiceReport.fromJson(
|
|
||||||
json.decode(utf8.decode(response.bodyBytes)),reportId);
|
|
||||||
}else{
|
|
||||||
throw(HttpStatusManger.getStatusMessage(
|
|
||||||
status: response.statusCode, subtitle: subtitle));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:test_sa/core/enums.dart' show SupportedLanguagesEnum;
|
||||||
|
|
||||||
|
class AppLocalizations {
|
||||||
|
AppLocalizations._();
|
||||||
|
|
||||||
|
static List<Locale> supportedLocales =
|
||||||
|
SupportedLanguagesEnum.values.map((e) => Locale(e.name)).toList();
|
||||||
|
|
||||||
|
static List<LocalizationsDelegate> get delegates => const [
|
||||||
|
// AppLocalization.delegate,
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
];
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:test_sa/screens/login_screen/login_screen.dart';
|
||||||
|
import 'package:test_sa/screens/splash_screen/splash_screen.dart';
|
||||||
|
|
||||||
|
Map<String, Widget Function(BuildContext)> appRoutes = {
|
||||||
|
SplashScreen.routeName: (_) => const SplashScreen(),
|
||||||
|
LoginScreen.routeName: (_) => const LoginScreen(),
|
||||||
|
// LandPage.routeName: (_) => const LandPage(),
|
||||||
|
// Register.routeName: (_) => Register(),
|
||||||
|
// ProfilePage.routeName: (_) => ProfilePage(),
|
||||||
|
// ReportIssuesPage.routeName: (_) => const ReportIssuesPage(),
|
||||||
|
// RequestGasRefill.routeName: (_) => const RequestGasRefill(),
|
||||||
|
// CreateRequestPage.routeName: (_) => CreateRequestPage(),
|
||||||
|
// SingleHospitalPicker.routeName: (_) => SingleHospitalPicker(),
|
||||||
|
// SingleDevicePicker.routeName: (_) => SingleDevicePicker(),
|
||||||
|
// SingleDepartmentPicker.routeName: (_) => SingleDepartmentPicker(),
|
||||||
|
// ServiceRequestsPage.routeName: (_) => ServiceRequestsPage(),
|
||||||
|
// NotificationsPage.routeName: (_) => NotificationsPage(),
|
||||||
|
// FutureRequestServiceDetails.routeName: (_) =>
|
||||||
|
// FutureRequestServiceDetails(),
|
||||||
|
// PreventiveMaintenanceVisitsPage.routeName: (_) =>
|
||||||
|
// PreventiveMaintenanceVisitsPage(),
|
||||||
|
// RegularVisitsPage.routeName: (_) => RegularVisitsPage(),
|
||||||
|
// TrackGasRefillPage.routeName: (_) => const TrackGasRefillPage(),
|
||||||
|
// RequestDeviceTransfer.routeName: (_) =>
|
||||||
|
// const RequestDeviceTransfer(),
|
||||||
|
// TrackDeviceTransferPage.routeName: (_) =>
|
||||||
|
// const TrackDeviceTransferPage(),
|
||||||
|
};
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:test_sa/core/constants/app_colors.dart';
|
||||||
|
|
||||||
|
class AppTheme {
|
||||||
|
AppTheme._();
|
||||||
|
|
||||||
|
static get theme => ThemeData(
|
||||||
|
fontFamily: "Poppins",
|
||||||
|
canvasColor: AppColors.primaryColor,
|
||||||
|
scaffoldBackgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
primaryColor: AppColors.primaryColor,
|
||||||
|
indicatorColor: AppColors.primaryColor,
|
||||||
|
colorScheme: const ColorScheme.light(
|
||||||
|
primary: AppColors.primaryColor,
|
||||||
|
onPrimary: Colors.white,
|
||||||
|
secondary: AppColors.secondaryColor,
|
||||||
|
onSecondary: Colors.white,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
class ApiConstants {
|
||||||
|
ApiConstants._();
|
||||||
|
static const host2 = "http://194.163.164.213/atoms/api";
|
||||||
|
static const host1 = "https://atoms.hmg.com/api";
|
||||||
|
|
||||||
|
// API Routes
|
||||||
|
static const login = "/handle/user/login"; // post
|
||||||
|
static const register = "/handle/create/user"; // post
|
||||||
|
static const updateProfile = "/update/user/profile"; // post
|
||||||
|
static const getHospitals = "/handle/return/all/clients"; // get
|
||||||
|
static const getDepartments = "/handle/return/all/departments"; // get
|
||||||
|
static const getEquipment = "/handle/return/all/client/equipments"; // get ?client=208051
|
||||||
|
static const getServiceRequests = "/return/user/calls"; // get
|
||||||
|
|
||||||
|
static const getPreventiveMaintenanceVisits = "/return/user/calibrations"; // get
|
||||||
|
static const updatePreventiveMaintenanceVisits = "/update/user/calibrations"; // get
|
||||||
|
|
||||||
|
static const getRegularVisits = "/return/user/ppm"; // get
|
||||||
|
static const updateRegularVisits = "/update/user/ppm"; // get
|
||||||
|
|
||||||
|
static const getSingleServiceRequest = "/return/call/information"; // get
|
||||||
|
static const getNotifications = "/return/user/notification"; // get
|
||||||
|
static const getRecentNotifications = "/return/user/recent/notification"; // get
|
||||||
|
static const createRequest = "/handle/create/request"; // get
|
||||||
|
static const createReport = "/handle/create/report/issue"; // get
|
||||||
|
static const updateRequestDate = "/handle/update/request"; // get
|
||||||
|
|
||||||
|
// service report
|
||||||
|
static const createServiceReport = "/handle/create/service/report"; // get
|
||||||
|
static const updateServiceReport = "/handle/update/service/report"; // get
|
||||||
|
static const getServiceReport = "/handle/view/service/report"; // get
|
||||||
|
static const createDuplicatedReport = "/handle/duplicate/request"; // get
|
||||||
|
|
||||||
|
static const getServiceReportReasons = "/return/service/report/reasons"; // get
|
||||||
|
static const getServiceReportTypes = "/return/service/report/type"; // get
|
||||||
|
static const getServiceReportStatus = "/return/service/report/status"; // get
|
||||||
|
static const getServiceReportLastCalls = "/return/call/last/situation"; // get
|
||||||
|
static const getServiceTypes = "/return/service/type"; // get
|
||||||
|
static const getPartNumber = "/handle/return/all/parts"; // get
|
||||||
|
static const getServiceReportPriority = "/return/call/priority/list"; // get
|
||||||
|
static const getServiceReportDefectTypes = "/return/call/defect/type/list"; // get
|
||||||
|
|
||||||
|
//gas refill
|
||||||
|
static const getGasTypes = "/return/gas/refill/types"; // get
|
||||||
|
static const getGasCylinderSize = "/return/gas/refill/size/cylinder"; // get
|
||||||
|
static const getGasStatus = "/return/gas/refill/status"; // get
|
||||||
|
static const requestGasRefill = "/create/gas/refill"; // get
|
||||||
|
static const updateGasRefill = "/update/gas/refill/"; // get
|
||||||
|
static const getGasRefill = "/search/gas/refill"; // get
|
||||||
|
|
||||||
|
//device transfer
|
||||||
|
static const requestDeviceTransfer = "/create/transfer/asset"; // get
|
||||||
|
static const updateDeviceTransfer = "/update/transfer/asset"; // get
|
||||||
|
static const getDeviceTransfer = "/search/transfer/asset"; // get
|
||||||
|
|
||||||
|
// employee
|
||||||
|
static const getEmployees = "/return/assigned/employee"; // get
|
||||||
|
// pentry
|
||||||
|
static const getPentry = "/return/pentry/details"; // get
|
||||||
|
static const updatePentry = "/update/pentry/details"; // get
|
||||||
|
static const getPentryTaskStatus = "/return/pentry/task/status"; // get
|
||||||
|
static const getPentryVisitStatus = "/return/pentry/visit/status/list"; // get
|
||||||
|
static const getPentryStatus = "/return/pentry/status/list"; // get
|
||||||
|
// contacts
|
||||||
|
static const getPentryContacts = "/handle/return/all/contacts"; // get
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AppColors {
|
||||||
|
AppColors._();
|
||||||
|
|
||||||
|
static const Color white = Color(0xffffffff);
|
||||||
|
static const Color black = Color(0xff000000);
|
||||||
|
static const Color grey3A = Color(0xff2e303a);
|
||||||
|
static const Color grey = Color(0xffe1e7e7);
|
||||||
|
static const green = Colors.green;
|
||||||
|
static const Color orange = Colors.orange;
|
||||||
|
static const Color deepOrange = Colors.deepOrangeAccent;
|
||||||
|
static const Color red = Colors.red;
|
||||||
|
static const Color deepRed = Color(0xFFD32F2F);
|
||||||
|
static const Color scaffoldBackgroundColor = Color(0xffffffff);
|
||||||
|
static const Color secondaryColor = Color(0xff111427);
|
||||||
|
static const Color primaryColor = Color(0xff5bb0da);
|
||||||
|
static const Color cyan = Color(0xff4A8DB7);
|
||||||
|
static const Color onPrimaryColor = Color(0xffffffff);
|
||||||
|
static const Color inputFieldBackgroundColor = Color(0xfff5f5f5);
|
||||||
|
static const Color greyEF = Color(0xffEFEFEF);
|
||||||
|
|
||||||
|
static Color getRequestStatusColor(int id) {
|
||||||
|
switch (id) {
|
||||||
|
case 4:
|
||||||
|
return deepRed;
|
||||||
|
case 6:
|
||||||
|
return green;
|
||||||
|
case 5:
|
||||||
|
return orange;
|
||||||
|
case 8:
|
||||||
|
return green;
|
||||||
|
case 9:
|
||||||
|
return orange;
|
||||||
|
default:
|
||||||
|
return grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color getGasStatusColor(int id) {
|
||||||
|
switch (id) {
|
||||||
|
case 0:
|
||||||
|
return orange;
|
||||||
|
case 1:
|
||||||
|
return green;
|
||||||
|
default:
|
||||||
|
return grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
enum SupportedLanguagesEnum { ar, en }
|
||||||
|
|
||||||
|
enum RequestMethod { get, post, put, delete }
|
||||||
|
|
||||||
|
enum ApiExceptionsEnum {
|
||||||
|
badRequest(10),
|
||||||
|
unauthorized(10),
|
||||||
|
forbidden(10),
|
||||||
|
notFound(10),
|
||||||
|
internalServerError(10),
|
||||||
|
upgradeRequired(10),
|
||||||
|
badResponseFormat(10),
|
||||||
|
other(10),
|
||||||
|
timeout(10),
|
||||||
|
unknown(10);
|
||||||
|
|
||||||
|
final int statusCode;
|
||||||
|
|
||||||
|
const ApiExceptionsEnum(this.statusCode);
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
extension ContextExtension on BuildContext {}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:test_sa/core/constants/app_colors.dart';
|
||||||
|
|
||||||
|
extension NumExtension on num {
|
||||||
|
Widget get height => SizedBox(height: toDouble());
|
||||||
|
|
||||||
|
Widget get width => SizedBox(width: toDouble());
|
||||||
|
|
||||||
|
Widget get divider => Divider(
|
||||||
|
height: toDouble(),
|
||||||
|
thickness: toDouble(),
|
||||||
|
color: AppColors.greyEF,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get makeItSquare => SizedBox(width: toDouble(), height: toDouble());
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
extension StringExtension on String {}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
extension WidgetExtension on Widget {}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:test_sa/providers/settings_provider.dart';
|
||||||
|
|
||||||
|
class ProviderScope extends StatelessWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const ProviderScope({required this.child, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ChangeNotifierProvider(create: (_) => SettingsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => UserProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => HospitalsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => DevicesProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceRequestsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => DepartmentsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => NotificationsProvider()),
|
||||||
|
// ChangeNotifierProvider(
|
||||||
|
// create: (_) => PreventiveMaintenanceVisitsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => RegularVisitsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => PartsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceReportReasonsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceReportStatusProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceReportTypesProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceStatusProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceReportLastCallsProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => GasCylinderSizesProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => GasStatusProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => GasTypesProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => GasRefillProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => DeviceTransferProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => EmployeesProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => PentryTaskStatusProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => PentryVisitStatusProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => PentryStatusProvider()),
|
||||||
|
// ChangeNotifierProvider(create: (_) => ServiceRequestPriorityProvider()),
|
||||||
|
// ChangeNotifierProvider(
|
||||||
|
// create: (_) => ServiceRequestDefectTypesProvider()),
|
||||||
|
],
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:test_sa/core/enums.dart';
|
||||||
|
|
||||||
|
class ApiClient {
|
||||||
|
final String baseUrl, endPoint;
|
||||||
|
final RequestMethod requestMethod;
|
||||||
|
|
||||||
|
ApiClient.request({
|
||||||
|
required this.baseUrl,
|
||||||
|
required this.endPoint,
|
||||||
|
required this.requestMethod,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> execute({
|
||||||
|
Map<String, String>? headers,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Object? body,
|
||||||
|
}) async {
|
||||||
|
final url = Uri.tryParse(baseUrl + endPoint);
|
||||||
|
if (url != null) {
|
||||||
|
late http.Response response;
|
||||||
|
switch (requestMethod) {
|
||||||
|
case RequestMethod.get:
|
||||||
|
response = await http.get(url, headers: headers);
|
||||||
|
break;
|
||||||
|
case RequestMethod.post:
|
||||||
|
response = await http.post(url, headers: headers, body: body);
|
||||||
|
break;
|
||||||
|
case RequestMethod.put:
|
||||||
|
response = await http.put(url, headers: headers, body: body);
|
||||||
|
break;
|
||||||
|
case RequestMethod.delete:
|
||||||
|
response = await http.delete(url, headers: headers, body: body);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return await _handleResponse(response);
|
||||||
|
} else {
|
||||||
|
throw ApiExceptionsEnum.other;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> _handleResponse(http.Response response) {
|
||||||
|
print('status code ${response.statusCode} : ${response.request?.url}');
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
return jsonDecode(response.body);
|
||||||
|
} else if (response.statusCode == 401) {
|
||||||
|
throw ApiExceptionsEnum.unauthorized;
|
||||||
|
} else if (response.statusCode == 400) {
|
||||||
|
throw ApiExceptionsEnum.badRequest;
|
||||||
|
} else if (response.statusCode == 500) {
|
||||||
|
throw ApiExceptionsEnum.internalServerError;
|
||||||
|
}
|
||||||
|
throw ApiExceptionsEnum.unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:test_sa/core/enums.dart';
|
||||||
|
import 'package:test_sa/data/api/api_client.dart';
|
||||||
|
import 'package:test_sa/data/models/user_model.dart';
|
||||||
|
|
||||||
|
class UserService {
|
||||||
|
static UserService instance = UserService._internal();
|
||||||
|
|
||||||
|
UserService._internal();
|
||||||
|
|
||||||
|
Future<UserModel> getUser() async {
|
||||||
|
final response = await ApiClient.request(
|
||||||
|
baseUrl: 'baseUrl',
|
||||||
|
endPoint: 'endPoint',
|
||||||
|
requestMethod: RequestMethod.get,
|
||||||
|
).execute();
|
||||||
|
return UserModel.fromJson(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
class UserModel {
|
||||||
|
UserModel();
|
||||||
|
|
||||||
|
factory UserModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return UserModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,50 +0,0 @@
|
|||||||
import 'package:test_sa/models/device/device.dart';
|
|
||||||
import 'package:test_sa/models/device/device_transfer_info.dart';
|
|
||||||
|
|
||||||
class DeviceTransfer{
|
|
||||||
String id;
|
|
||||||
String userId;
|
|
||||||
String title;
|
|
||||||
Device device;
|
|
||||||
DeviceTransferInfo sender;
|
|
||||||
DeviceTransferInfo receiver;
|
|
||||||
|
|
||||||
DeviceTransfer({
|
|
||||||
this.id,
|
|
||||||
this.device,
|
|
||||||
this.title,
|
|
||||||
this.userId,
|
|
||||||
this.sender,
|
|
||||||
this.receiver,
|
|
||||||
});
|
|
||||||
|
|
||||||
bool validate(){
|
|
||||||
if(device == null) return false;
|
|
||||||
return receiver.validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
fromDeviceTransfer(DeviceTransfer old){
|
|
||||||
id = old.id;
|
|
||||||
title = old.title;
|
|
||||||
userId = old.userId;
|
|
||||||
device = Device.fromDevice(old.device);
|
|
||||||
final sender = DeviceTransferInfo();
|
|
||||||
sender.fromDetails(old.sender);
|
|
||||||
this.sender = sender;
|
|
||||||
final receiver = DeviceTransferInfo();
|
|
||||||
receiver.fromDetails(old.receiver);
|
|
||||||
this.receiver = receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
factory DeviceTransfer.fromJson(Map<String,dynamic> parsedJson){
|
|
||||||
return DeviceTransfer(
|
|
||||||
id: parsedJson["id"],
|
|
||||||
title: parsedJson["title"],
|
|
||||||
userId: parsedJson["uid"],
|
|
||||||
device: Device.fromJson(parsedJson["eq_sn"]),
|
|
||||||
sender: DeviceTransferInfo.fromJson(parsedJson,"sender_"),
|
|
||||||
receiver: DeviceTransferInfo.fromJson(parsedJson,"receiver_"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
import 'package:test_sa/models/department.dart';
|
|
||||||
import 'package:test_sa/models/hospital.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
|
|
||||||
class DeviceTransferInfo{
|
|
||||||
String userId;
|
|
||||||
String comment;
|
|
||||||
Hospital client;
|
|
||||||
Department department;
|
|
||||||
String workingHours;
|
|
||||||
String travelingHours;
|
|
||||||
String name;
|
|
||||||
String signature;
|
|
||||||
Lookup status;
|
|
||||||
|
|
||||||
DeviceTransferInfo({
|
|
||||||
this.userId,
|
|
||||||
this.comment,
|
|
||||||
this.department,
|
|
||||||
this.client,
|
|
||||||
this.name,
|
|
||||||
this.travelingHours,
|
|
||||||
this.workingHours,
|
|
||||||
this.signature,
|
|
||||||
this.status,
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String,String>toJson(bool isSender){
|
|
||||||
Map<String,String> body = {};
|
|
||||||
final baseKey = isSender ? "sender_" : "receiver_";
|
|
||||||
|
|
||||||
if(comment != null && comment.isNotEmpty) body["${baseKey}comment"] = comment;
|
|
||||||
if(workingHours != null && workingHours.isNotEmpty) body["${baseKey}working_hours"] = workingHours;
|
|
||||||
if(travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = comment;
|
|
||||||
if(status != null) body["${baseKey}status"] = status.id.toString();
|
|
||||||
if(signature != null && signature.isNotEmpty) body["${baseKey}image"] = signature;
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validate(){
|
|
||||||
if(client == null) return false;
|
|
||||||
if(department == null) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromDetails(DeviceTransferInfo old,{bool withSignature = true}){
|
|
||||||
userId = old.userId;
|
|
||||||
name = old.name;
|
|
||||||
client = Hospital.fromHospital(old.client);
|
|
||||||
department = Department.fromDepartment(old.department);
|
|
||||||
workingHours = old.workingHours;
|
|
||||||
travelingHours = old.travelingHours;
|
|
||||||
comment = old.comment;
|
|
||||||
if(withSignature) signature = old.signature;
|
|
||||||
status = old.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
factory DeviceTransferInfo.fromJson(Map<String,dynamic> parsedJson,String key){
|
|
||||||
return DeviceTransferInfo(
|
|
||||||
workingHours: parsedJson["${key}working_hours"],
|
|
||||||
travelingHours: parsedJson["${key}travel_hours"],
|
|
||||||
name: parsedJson["${key}name"],
|
|
||||||
signature: parsedJson["${key}image"],
|
|
||||||
userId: parsedJson["${key}id"],
|
|
||||||
comment: parsedJson["${key}comment"],
|
|
||||||
client: Hospital.fromJson(parsedJson["${key}client"]),
|
|
||||||
department: Department.fromJson(parsedJson["${key}department"]),
|
|
||||||
status: Lookup.fromJson(parsedJson["${key}status"]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
|
|
||||||
class GasRefillDetails{
|
|
||||||
Lookup type;
|
|
||||||
Lookup cylinderSize;
|
|
||||||
int requestedQuantity;
|
|
||||||
int deliveredQuantity;
|
|
||||||
|
|
||||||
GasRefillDetails({
|
|
||||||
this.type,
|
|
||||||
this.cylinderSize,
|
|
||||||
this.requestedQuantity,
|
|
||||||
this.deliveredQuantity,
|
|
||||||
});
|
|
||||||
|
|
||||||
bool validate(){
|
|
||||||
//if(cylinderSize == null) return false;
|
|
||||||
if(type == null) return false;
|
|
||||||
if(requestedQuantity == null) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
factory GasRefillDetails.fromJson(Map<String,dynamic> parsedJson){
|
|
||||||
return GasRefillDetails(
|
|
||||||
type: Lookup.fromJson(parsedJson["type"]),
|
|
||||||
|
|
||||||
cylinderSize: Lookup.fromJson(parsedJson["size"]),
|
|
||||||
requestedQuantity: parsedJson["requsted_qty"] == null
|
|
||||||
? 0 : int.tryParse(parsedJson["requsted_qty"].toString()) ?? 0,
|
|
||||||
deliveredQuantity: parsedJson["deliverd_qty"] == null
|
|
||||||
? 0 : int.tryParse(parsedJson["deliverd_qty"].toString()) ?? 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
factory GasRefillDetails.fromDetails(GasRefillDetails details){
|
|
||||||
return GasRefillDetails(
|
|
||||||
type: Lookup.fromStatus(details.type),
|
|
||||||
cylinderSize:Lookup.fromStatus(details.cylinderSize),
|
|
||||||
requestedQuantity: details.requestedQuantity,
|
|
||||||
deliveredQuantity: details.deliveredQuantity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
|
|
||||||
class GasRefillModel{
|
|
||||||
String id;
|
|
||||||
String userId;
|
|
||||||
String clientName;
|
|
||||||
String title;
|
|
||||||
Lookup status;
|
|
||||||
List<GasRefillDetails> details;
|
|
||||||
|
|
||||||
GasRefillModel({
|
|
||||||
this.id,
|
|
||||||
this.userId,
|
|
||||||
this.clientName,
|
|
||||||
this.title,
|
|
||||||
this.status,
|
|
||||||
this.details,
|
|
||||||
});
|
|
||||||
|
|
||||||
bool validate(){
|
|
||||||
if(title == null) return false;
|
|
||||||
if(status == null) return false;
|
|
||||||
if(details == null && details.isEmpty) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromGasRefillModel(GasRefillModel model){
|
|
||||||
id = model.id;
|
|
||||||
userId = model.userId;
|
|
||||||
clientName = model.clientName;
|
|
||||||
title = model.title;
|
|
||||||
status = Lookup.fromStatus(model.status);
|
|
||||||
details = model.details.map((e) => GasRefillDetails.fromDetails(e)).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
factory GasRefillModel.fromJson(Map<String,dynamic> parsedJson){
|
|
||||||
List<GasRefillDetails> details = [];
|
|
||||||
if(parsedJson["details"] != null){
|
|
||||||
List list = parsedJson["details"];
|
|
||||||
details = list.map((e) => GasRefillDetails.fromJson(e)).toList();
|
|
||||||
}
|
|
||||||
return GasRefillModel(
|
|
||||||
id: parsedJson["id"],
|
|
||||||
userId: parsedJson["uid"],
|
|
||||||
title: parsedJson["title"],
|
|
||||||
clientName: parsedJson["client"],
|
|
||||||
status: Lookup.fromJson(parsedJson["status"]),
|
|
||||||
details: details,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
|
|
||||||
class CalibrationTool{
|
|
||||||
Lookup assetsNumber;
|
|
||||||
DateTime dataOfTesting;
|
|
||||||
|
|
||||||
CalibrationTool({
|
|
||||||
this.assetsNumber,
|
|
||||||
this.dataOfTesting,
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String, String> toMap() {
|
|
||||||
return {
|
|
||||||
if(assetsNumber != null) 'assetsSN': (assetsNumber?.id).toString(),
|
|
||||||
if(dataOfTesting != null) 'dataOfTesting': (dataOfTesting.millisecondsSinceEpoch ~/ 1000).toString(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
factory CalibrationTool.fromMap(Map<String, dynamic> map) {
|
|
||||||
return CalibrationTool(
|
|
||||||
assetsNumber: Lookup.fromJson(map['assetsSN']),
|
|
||||||
dataOfTesting: map['dataOfTesting'] == null || map['dataOfTesting'] == "" ? null :
|
|
||||||
DateTime.fromMillisecondsSinceEpoch(int.tryParse(map['dataOfTesting']) * 1000),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
|
|
||||||
class Contact{
|
|
||||||
Lookup title;
|
|
||||||
Lookup contactPerson;
|
|
||||||
String job;
|
|
||||||
String email;
|
|
||||||
String telephone;
|
|
||||||
String landLine;
|
|
||||||
|
|
||||||
Contact({
|
|
||||||
this.title,
|
|
||||||
this.contactPerson,
|
|
||||||
this.job,
|
|
||||||
this.email,
|
|
||||||
this.telephone,
|
|
||||||
this.landLine
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String, String> toMap() {
|
|
||||||
return {
|
|
||||||
if (title != null) 'title': title.id.toString(),
|
|
||||||
if (contactPerson != null) 'contactPerson': contactPerson.id.toString(),
|
|
||||||
if (job != null) 'job': job,
|
|
||||||
if (email != null) 'email': email,
|
|
||||||
if (telephone != null) 'telephone': telephone,
|
|
||||||
if (landLine != null) 'landLine': landLine,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
factory Contact.fromMap(Map<String, dynamic> map) {
|
|
||||||
return Contact(
|
|
||||||
title: map['title'] as Lookup,
|
|
||||||
contactPerson: map['contactPerson'] as Lookup,
|
|
||||||
job: map['job'] as String,
|
|
||||||
email: map['email'] as String,
|
|
||||||
telephone: map['telephone'] as String,
|
|
||||||
landLine: map['landLine'] as String,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
|
|
||||||
class ContactTitle extends Lookup {
|
|
||||||
ContactTitle({
|
|
||||||
int id,
|
|
||||||
String label
|
|
||||||
}):super(id: id,label: label);
|
|
||||||
|
|
||||||
factory ContactTitle.fromMap(Map<String,dynamic> parsedJson){
|
|
||||||
return ContactTitle(
|
|
||||||
label: parsedJson["value"],
|
|
||||||
id: parsedJson["id"],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/models/pantry/calibration_tools.dart';
|
|
||||||
import 'package:test_sa/models/pantry/pm_kit.dart';
|
|
||||||
import 'package:test_sa/models/pantry/ppm_check_list.dart';
|
|
||||||
import 'package:test_sa/models/timer_model.dart';
|
|
||||||
|
|
||||||
class Pentry{
|
|
||||||
Lookup ppmVisitStatus;
|
|
||||||
Lookup status;
|
|
||||||
TimerModel timer;
|
|
||||||
DateTime actualVisitDate;
|
|
||||||
String travelingHours;
|
|
||||||
String image;
|
|
||||||
File imageFile;
|
|
||||||
// List<Contact> contacts;
|
|
||||||
List<PPMCheckList> ppmCheckLists;
|
|
||||||
List<CalibrationTool> calibrationTools;
|
|
||||||
List<PMKit> pmKits;
|
|
||||||
|
|
||||||
Pentry({
|
|
||||||
this.travelingHours,
|
|
||||||
this.timer,
|
|
||||||
this.status,
|
|
||||||
this.ppmVisitStatus,
|
|
||||||
this.actualVisitDate,
|
|
||||||
this.image,
|
|
||||||
this.imageFile,
|
|
||||||
// this.contacts,
|
|
||||||
this.ppmCheckLists,
|
|
||||||
this.calibrationTools,
|
|
||||||
this.pmKits,
|
|
||||||
});
|
|
||||||
|
|
||||||
bool validate(){
|
|
||||||
if(actualVisitDate == null) return false;
|
|
||||||
if(timer == null && timer.endAt != null) return false;
|
|
||||||
if(ppmVisitStatus == null) return false;
|
|
||||||
//if(status == null) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> toMap() {
|
|
||||||
Map<String, String> map = {};
|
|
||||||
map["visit_status"] = ppmVisitStatus?.id.toString();
|
|
||||||
if(status != null) map["pentry_status"] = status?.id.toString();
|
|
||||||
if(travelingHours != null) map["traveling_hours"] = travelingHours;
|
|
||||||
if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync());
|
|
||||||
map["actual_date"] = (actualVisitDate.millisecondsSinceEpoch / 1000).toStringAsFixed(0);
|
|
||||||
if(timer != null){
|
|
||||||
map["start_date"] = (timer.startAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0);
|
|
||||||
map["end_date"] = ((timer.endAt ?? DateTime.now()).millisecondsSinceEpoch / 1000).toStringAsFixed(0);
|
|
||||||
map["working_hours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
|
|
||||||
}
|
|
||||||
// if(contacts?.isNotEmpty == true) {
|
|
||||||
// for(int i = 0;i<contacts.length;i++){
|
|
||||||
// contacts[i].toMap().forEach((key, value) {
|
|
||||||
// body["contacts[$i].$key"] = value;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
map["ppmCheckLists"] = jsonEncode(ppmCheckLists.map((e) => e.toMap()).toList());
|
|
||||||
map["calibrationTools"] = jsonEncode(calibrationTools.map((e) => e.toMap()).toList());
|
|
||||||
map["pmKits"] = jsonEncode(pmKits.map((e) => e.toMap()).toList());
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
factory Pentry.fromMap(Map<String, dynamic> map) {
|
|
||||||
// List<Contact> contacts = [];
|
|
||||||
// if(map['contacts'] != null){
|
|
||||||
// contacts =(map['contacts'] as List<dynamic>)
|
|
||||||
// .map((e) => Contact.fromMap(e as Map<String, dynamic>))
|
|
||||||
// .toList();
|
|
||||||
// }
|
|
||||||
|
|
||||||
List<PMKit> pmKits = [];
|
|
||||||
if(map['pmKits'] != null){
|
|
||||||
pmKits =(map['pmKits'] as List<dynamic>)
|
|
||||||
.map((e) => PMKit.fromMap(e as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PPMCheckList> ppmCheckLists = [];
|
|
||||||
if(map['ppmCheckLists'] != null){
|
|
||||||
ppmCheckLists =(map['ppmCheckLists'] as List<dynamic>)
|
|
||||||
.map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<CalibrationTool> calibrationTools = [];
|
|
||||||
if(map['calibrationTools'] != null){
|
|
||||||
calibrationTools =(map['calibrationTools'] as List<dynamic>)
|
|
||||||
.map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
return Pentry(
|
|
||||||
status: Lookup.fromJson(map["pentry_status"]),
|
|
||||||
ppmVisitStatus: Lookup.fromJson(map["visit_status"]),
|
|
||||||
actualVisitDate: getDate(map["actual_date"]),
|
|
||||||
travelingHours: map["traveling_hours"],
|
|
||||||
timer: TimerModel(
|
|
||||||
startAt: getDate(map["start_date"]),
|
|
||||||
endAt: getDate(map["end_date"]),
|
|
||||||
durationInSecond: (int.tryParse(map["working_hours"] ?? "") ?? 0) * 60 *60
|
|
||||||
),
|
|
||||||
// contacts: contacts,
|
|
||||||
ppmCheckLists: ppmCheckLists,
|
|
||||||
calibrationTools: calibrationTools,
|
|
||||||
pmKits: pmKits,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDate(String date){
|
|
||||||
return date == null || date.isEmpty
|
|
||||||
? null : DateTime.fromMillisecondsSinceEpoch(int.tryParse(date) * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
class ServiceRequestSearch{
|
|
||||||
String deviceSerialNumber;
|
|
||||||
String deviceName;
|
|
||||||
String hospital;
|
|
||||||
String model;
|
|
||||||
int statusValue;
|
|
||||||
|
|
||||||
|
|
||||||
ServiceRequestSearch({
|
|
||||||
this.deviceSerialNumber,
|
|
||||||
this.statusValue,
|
|
||||||
this.deviceName,
|
|
||||||
this.model,
|
|
||||||
this.hospital,
|
|
||||||
});
|
|
||||||
|
|
||||||
fromSearch(ServiceRequestSearch newSearch){
|
|
||||||
deviceSerialNumber = newSearch.deviceSerialNumber;
|
|
||||||
statusValue = newSearch.statusValue;
|
|
||||||
hospital = newSearch.hospital;
|
|
||||||
model = newSearch.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
String toSearchString(){
|
|
||||||
String _search = "";
|
|
||||||
if(deviceSerialNumber != null && deviceSerialNumber.isNotEmpty){
|
|
||||||
_search += "&sn_id=$deviceSerialNumber";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(statusValue != null){
|
|
||||||
_search += "&status=$statusValue";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deviceName != null && deviceName.isNotEmpty){
|
|
||||||
_search += "&equipment_en_name=$deviceName";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hospital != null && hospital.isNotEmpty){
|
|
||||||
_search += "&client=$hospital";
|
|
||||||
}
|
|
||||||
if(model != null && model.isNotEmpty){
|
|
||||||
_search += "&model=$model";
|
|
||||||
}
|
|
||||||
return _search;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/models/visits/visit.dart';
|
|
||||||
|
|
||||||
class VisitsGroup{
|
|
||||||
String userId;
|
|
||||||
String workingHours;
|
|
||||||
String travelingHours;
|
|
||||||
String jobSheetNumber;
|
|
||||||
String image;
|
|
||||||
Lookup status;
|
|
||||||
Lookup taskStatus;
|
|
||||||
DateTime date;
|
|
||||||
List<Visit> visits;
|
|
||||||
|
|
||||||
VisitsGroup({
|
|
||||||
this.userId,
|
|
||||||
this.status,
|
|
||||||
this.date,
|
|
||||||
this.jobSheetNumber,
|
|
||||||
this.travelingHours,
|
|
||||||
this.workingHours,
|
|
||||||
this.visits,
|
|
||||||
this.image,
|
|
||||||
this.taskStatus,
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String,String> toJson(){
|
|
||||||
Map<String,String> jsonObject = {};
|
|
||||||
jsonObject["nids"] = visits.map((e) => e.id).toList().join(',');
|
|
||||||
if(status != null) jsonObject["status"] = status.id.toString();
|
|
||||||
if(date != null) jsonObject["date"] = date.toString().split(" ").first;
|
|
||||||
if(jobSheetNumber != null && jobSheetNumber.isNotEmpty)
|
|
||||||
jsonObject["job_sheet_no"] = jobSheetNumber;
|
|
||||||
if(travelingHours != null && travelingHours.isNotEmpty)
|
|
||||||
jsonObject["traveling_hours"] = travelingHours;
|
|
||||||
if(workingHours != null && workingHours.isNotEmpty)
|
|
||||||
jsonObject["working_hours"] = workingHours;
|
|
||||||
if(image != null) jsonObject["image"] = image;
|
|
||||||
if(taskStatus != null) jsonObject["task_status"] = taskStatus.id.toString();
|
|
||||||
return jsonObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingsProvider with ChangeNotifier {
|
||||||
|
Locale? _locale;
|
||||||
|
|
||||||
|
Locale? get locale => _locale;
|
||||||
|
|
||||||
|
set locale(Locale? value) {
|
||||||
|
_locale = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LoginScreen extends StatelessWidget {
|
||||||
|
static const routeName = '/loginScreen';
|
||||||
|
|
||||||
|
const LoginScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Scaffold();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
import 'package:flare_flutter/flare_actor.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:test_sa/screens/login_screen/login_screen.dart';
|
||||||
|
|
||||||
|
class SplashScreen extends StatelessWidget {
|
||||||
|
static const routeName = "/splashScreen";
|
||||||
|
|
||||||
|
const SplashScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
body: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 1.1,
|
||||||
|
child: FlareActor(
|
||||||
|
"assets/rives/atoms_splash.flr",
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
animation: "splash",
|
||||||
|
callback: (animation) async {
|
||||||
|
Navigator.of(context).pushNamed(LoginScreen.routeName);
|
||||||
|
// if (_settingProvider.isLoaded && _settingProvider.user != null) {
|
||||||
|
// _goToUserScreen(_settingProvider.user);
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,86 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
||||||
import 'package:flare_flutter/flare_actor.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/notification/notification_manger.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/models/app_notification.dart';
|
|
||||||
import 'package:test_sa/models/user.dart';
|
|
||||||
import 'package:test_sa/views/pages/user/land_page.dart';
|
|
||||||
|
|
||||||
import 'login.dart';
|
|
||||||
|
|
||||||
class SplashScreen extends StatefulWidget {
|
|
||||||
static const String id = '/splash';
|
|
||||||
const SplashScreen({Key key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SplashScreen> createState() => _SplashScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SplashScreenState extends State<SplashScreen> {
|
|
||||||
|
|
||||||
SettingProvider _settingProvider;
|
|
||||||
UserProvider _userProvider;
|
|
||||||
|
|
||||||
_goToUserScreen(User user){
|
|
||||||
_userProvider.user = user;
|
|
||||||
// Navigator.of(context).pushNamed(Login.id);
|
|
||||||
Navigator.of(context).pushNamed(LandPage.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
Firebase.initializeApp();
|
|
||||||
|
|
||||||
NotificationManger.initialisation(
|
|
||||||
(notificationDetails) {
|
|
||||||
AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload));
|
|
||||||
if(notification.path == null || notification.path.isEmpty)
|
|
||||||
return;
|
|
||||||
Navigator.pushNamed(
|
|
||||||
context,
|
|
||||||
notification.path,
|
|
||||||
arguments: notification.requestId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
, (id, title, body, payload) async {
|
|
||||||
});
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
_settingProvider = Provider.of<SettingProvider>(context,listen: false);
|
|
||||||
_userProvider = Provider.of<UserProvider>(context,listen: false);
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
body: Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: MediaQuery.of(context).size.width/1.1,
|
|
||||||
child: FlareActor(
|
|
||||||
"assets/rives/atoms_splash.flr",
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
animation: "splash",
|
|
||||||
callback: (animation) async {
|
|
||||||
print(await FirebaseMessaging.instance.getToken());
|
|
||||||
Navigator.of(context).pushNamed(Login.id);
|
|
||||||
if(_settingProvider.isLoaded && _settingProvider.user != null){
|
|
||||||
_goToUserScreen(_settingProvider.user);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
//const Center(child: CircularProgressIndicator())
|
|
||||||
|
|
||||||
// Image.asset("assets/images/logo.png",
|
|
||||||
// fit: BoxFit.contain,
|
|
||||||
// ),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/models/app_notification.dart';
|
|
||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:test_sa/views/pages/user/requests/future_request_service_details.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
|
|
||||||
import 'package:test_sa/views/widgets/notifications/notification_item.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
class NotificationsList extends StatelessWidget {
|
|
||||||
final List<AppNotification> notifications;
|
|
||||||
final bool nextPage;
|
|
||||||
final Future<void> Function() onLazyLoad;
|
|
||||||
|
|
||||||
const NotificationsList({Key key, this.notifications, this.nextPage, this.onLazyLoad}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Subtitle _subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
if(notifications.length == 0){
|
|
||||||
return NoItemFound(message: _subtitle.notificationsNotFound,);
|
|
||||||
}
|
|
||||||
return LazyLoading(
|
|
||||||
nextPage: nextPage,
|
|
||||||
onLazyLoad: onLazyLoad,
|
|
||||||
child: ListView.builder(
|
|
||||||
physics: BouncingScrollPhysics(),
|
|
||||||
itemCount: notifications.length,
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 8),
|
|
||||||
itemBuilder: (context,itemIndex){
|
|
||||||
return NotificationItem(
|
|
||||||
notification: notifications[itemIndex],
|
|
||||||
onPressed: (notification){
|
|
||||||
Navigator.of(context).pushNamed(
|
|
||||||
FutureRequestServiceDetails.id,
|
|
||||||
arguments: notification.requestId
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
|
|
||||||
class ATextFormField extends StatefulWidget {
|
|
||||||
final Function(String) onSaved;
|
|
||||||
final Function(String) validator;
|
|
||||||
final Function(String) onChange;
|
|
||||||
final bool obscureText;
|
|
||||||
final VoidCallback showPassword;
|
|
||||||
final String hintText;
|
|
||||||
final String labelText;
|
|
||||||
final TextInputType textInputType;
|
|
||||||
final String initialValue;
|
|
||||||
final TextStyle style;
|
|
||||||
final bool enable;
|
|
||||||
final TextAlign textAlign;
|
|
||||||
final FocusNode node;
|
|
||||||
final Widget suffixIcon;
|
|
||||||
final IconData prefixIconData;
|
|
||||||
final double prefixIconSize;
|
|
||||||
final TextEditingController controller;
|
|
||||||
final TextInputAction textInputAction;
|
|
||||||
final VoidCallback onAction;
|
|
||||||
|
|
||||||
const ATextFormField(
|
|
||||||
{Key key,
|
|
||||||
this.onSaved,
|
|
||||||
this.validator,
|
|
||||||
this.node,
|
|
||||||
this.onChange,
|
|
||||||
this.obscureText,
|
|
||||||
this.showPassword,
|
|
||||||
this.hintText,
|
|
||||||
this.labelText,
|
|
||||||
this.textInputType = TextInputType.text,
|
|
||||||
this.initialValue,
|
|
||||||
this.enable = true,
|
|
||||||
this.style,
|
|
||||||
this.textAlign,
|
|
||||||
this.suffixIcon,
|
|
||||||
this.prefixIconData,
|
|
||||||
this.prefixIconSize,
|
|
||||||
this.controller,
|
|
||||||
this.textInputAction,
|
|
||||||
this.onAction})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ATextFormField> createState() => _ATextFormFieldState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ATextFormFieldState extends State<ATextFormField> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
if (widget.controller != null) widget.controller.text = widget.initialValue;
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
height: widget.textInputType == TextInputType.multiline ? null : 50,
|
|
||||||
padding: EdgeInsets.only(left: 12, right: 12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color(0xfff5f5f5),
|
|
||||||
border: Border.all(
|
|
||||||
color: Color(0xffefefef),
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
|
|
||||||
),
|
|
||||||
child: TextFormField(
|
|
||||||
focusNode: widget.node,
|
|
||||||
enabled: widget.enable,
|
|
||||||
onSaved: widget.onSaved,
|
|
||||||
initialValue: widget.controller != null ? null : widget.initialValue,
|
|
||||||
validator: widget.validator,
|
|
||||||
onChanged: widget.onChange,
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
obscureText: widget.obscureText ?? false,
|
|
||||||
keyboardType: widget.textInputType,
|
|
||||||
maxLines: widget.textInputType == TextInputType.multiline ? null : 1,
|
|
||||||
obscuringCharacter: "●",
|
|
||||||
controller: widget.controller,
|
|
||||||
textInputAction: widget.textInputType == TextInputType.multiline ? null : widget.textInputAction ?? TextInputAction.next,
|
|
||||||
onEditingComplete: widget.onAction ?? () => FocusScope.of(context).nextFocus(),
|
|
||||||
// style: widget.style,
|
|
||||||
style: Theme.of(context).textTheme.bodyText1,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
suffixIconConstraints: BoxConstraints(minWidth: 0),
|
|
||||||
disabledBorder: InputBorder.none,
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
constraints: BoxConstraints(),
|
|
||||||
errorStyle: TextStyle(height: 0.3),
|
|
||||||
//contentPadding: EdgeInsets.only(left: 0),
|
|
||||||
hintText: widget.hintText,
|
|
||||||
labelText: widget.labelText,
|
|
||||||
//suffixIcon: widget.suffixIcon,
|
|
||||||
suffixIcon: widget.prefixIconData == null
|
|
||||||
? null
|
|
||||||
: Icon(widget.prefixIconData,
|
|
||||||
size: widget.prefixIconSize == null ? 20 * AppStyle.getScaleFactor(context) : (widget.prefixIconSize - 10) * AppStyle.getScaleFactor(context), color: Color(0xff2e303a))),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/models/device/device_transfer_info.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/requests/info_row.dart';
|
|
||||||
import 'package:test_sa/views/widgets/requests/request_status.dart';
|
|
||||||
class DeviceTransferInfoSection extends StatelessWidget {
|
|
||||||
final DeviceTransferInfo info;
|
|
||||||
final VoidCallback onEdit;
|
|
||||||
const DeviceTransferInfoSection({Key key, this.info, this.onEdit}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
RequestInfoRow(
|
|
||||||
title: subtitle.hospital,
|
|
||||||
info: info.client.name,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: subtitle.unite,
|
|
||||||
info: info.department.name,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: subtitle.engineerName,
|
|
||||||
info: info.name,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: subtitle.workingHours,
|
|
||||||
info: info.workingHours,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: subtitle.travelingHours,
|
|
||||||
info: info.travelingHours,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: "Comment",
|
|
||||||
info: info.comment,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: "Signature",
|
|
||||||
info: info.signature?.isEmpty != false
|
|
||||||
? subtitle.noDateFound : null,
|
|
||||||
contentWidget: info.signature?.isEmpty != false ? null :
|
|
||||||
ImageLoader(
|
|
||||||
url: info.signature,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: subtitle.status,
|
|
||||||
infoWidget: StatusLabel(
|
|
||||||
label: info.status?.label,
|
|
||||||
color: AColors.getGasStatusColor(info.status?.id)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/models/device/device_transfer.dart';
|
|
||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:test_sa/views/pages/device_transfer/device_transfer_details.dart';
|
|
||||||
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_item.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
|
|
||||||
class DeviceTransferList extends StatelessWidget {
|
|
||||||
final List<DeviceTransfer> items;
|
|
||||||
final bool nextPage;
|
|
||||||
final Future<void> Function() onLazyLoad;
|
|
||||||
|
|
||||||
const DeviceTransferList({Key key, this.items, this.nextPage, this.onLazyLoad}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
|
|
||||||
if(items.length == 0){
|
|
||||||
Subtitle subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
return NoItemFound(message: subtitle.noServiceRequestFound,);
|
|
||||||
}
|
|
||||||
return LazyLoading(
|
|
||||||
nextPage: nextPage,
|
|
||||||
onLazyLoad: onLazyLoad,
|
|
||||||
child: ListView.builder(
|
|
||||||
//physics: const BouncingScrollPhysics(),
|
|
||||||
itemCount: items.length,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16,vertical: 8),
|
|
||||||
itemBuilder: (context,itemIndex){
|
|
||||||
return DeviceTransferItem(
|
|
||||||
index: itemIndex,
|
|
||||||
item: items[itemIndex],
|
|
||||||
onPressed: (model){
|
|
||||||
Navigator.of(context).push(
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (_)=> DeviceTransferDetails(model: model,)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/controllers/validator/validator.dart';
|
|
||||||
import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
|
|
||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:test_sa/views/widgets/app_text_form_field.dart';
|
|
||||||
import 'package:test_sa/views/widgets/requests/info_row.dart';
|
|
||||||
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
|
|
||||||
import 'package:test_sa/views/widgets/titles/app_title.dart';
|
|
||||||
class GasRefillUpdateDetailsItem extends StatelessWidget {
|
|
||||||
|
|
||||||
final GasRefillDetails details;
|
|
||||||
final bool enableEdit;
|
|
||||||
final bool validate;
|
|
||||||
|
|
||||||
const GasRefillUpdateDetailsItem({Key key, this.details, this.enableEdit, this.validate}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Subtitle subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
ATitle(details.type.label),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: "Cylinder Size",
|
|
||||||
info: details.cylinderSize.label,
|
|
||||||
),
|
|
||||||
RequestInfoRow(
|
|
||||||
title: "Requested Quantity",
|
|
||||||
info: details.requestedQuantity.toStringAsFixed(0),
|
|
||||||
),
|
|
||||||
enableEdit ?
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
ASubTitle(subtitle.quantity),
|
|
||||||
if(validate && details.deliveredQuantity == null)
|
|
||||||
ASubTitle(subtitle.requiredWord,color: Colors.red,),
|
|
||||||
SizedBox(height: 4,),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: (details.deliveredQuantity ?? "").toString(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: Theme.of(context).textTheme.subtitle1,
|
|
||||||
validator: (value) =>
|
|
||||||
Validator.isNumeric(value)
|
|
||||||
? null : "allow numbers only",
|
|
||||||
textInputType: TextInputType.number,
|
|
||||||
onSaved: (value){
|
|
||||||
details.deliveredQuantity = int.tryParse(value);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
):
|
|
||||||
RequestInfoRow(
|
|
||||||
title: "Delivered Quantity",
|
|
||||||
info: details.deliveredQuantity.toStringAsFixed(0),
|
|
||||||
),
|
|
||||||
//SizedBox(height: 16,)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
class RequestInfoRow extends StatelessWidget {
|
|
||||||
final String title;
|
|
||||||
final String info;
|
|
||||||
final String content;
|
|
||||||
final Widget contentWidget;
|
|
||||||
final Widget infoWidget;
|
|
||||||
|
|
||||||
const RequestInfoRow({Key key, this.title, this.info,this.content, this.contentWidget, this.infoWidget}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if(info != null && info.isEmpty){
|
|
||||||
return SizedBox.shrink();
|
|
||||||
}
|
|
||||||
if(content != null && content.isEmpty){
|
|
||||||
return SizedBox.shrink();
|
|
||||||
}
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title + " : ",
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
//fontSize: 12
|
|
||||||
),
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
|
|
||||||
if(info != null)
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
info,
|
|
||||||
style: Theme.of(context).textTheme.bodyText2,
|
|
||||||
textAlign: TextAlign.right,
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if(infoWidget != null)
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
infoWidget,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
if(content != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
content ?? 'No data found',
|
|
||||||
style: Theme.of(context).textTheme.bodyText2,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if(contentWidget != null)
|
|
||||||
contentWidget,
|
|
||||||
Divider(color: Theme.of(context).primaryColor,),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/views/app_style/colors.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
class StatusLabel extends StatelessWidget {
|
|
||||||
final String label;
|
|
||||||
final Color color;
|
|
||||||
|
|
||||||
const StatusLabel({Key key, this.label, this.color}) : super(key: key);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 2,horizontal: 8),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color ?? Colors.green,
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppStyle.getBorderRadius(context)
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
AppStyle.boxShadow
|
|
||||||
]
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
label ?? "no status",
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: color.computeLuminance() > 0.5
|
|
||||||
? AColors.black : Colors.white,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,266 +0,0 @@
|
|||||||
import 'package:fluttertoast/fluttertoast.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/user_provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
|
|
||||||
import 'package:test_sa/models/enums/user_types.dart';
|
|
||||||
import 'package:test_sa/models/service_request/service_request.dart';
|
|
||||||
import 'package:test_sa/models/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/pages/user/requests/report/create_service_report.dart';
|
|
||||||
import 'package:test_sa/views/pages/user/requests/report/future_service_report.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
|
|
||||||
import 'package:test_sa/views/widgets/requests/request_status.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/views/widgets/timer/app_timer.dart';
|
|
||||||
|
|
||||||
import '../../../controllers/http_status_manger/http_status_manger.dart';
|
|
||||||
class ServiceRequestItem extends StatelessWidget {
|
|
||||||
final int index;
|
|
||||||
final ServiceRequest request;
|
|
||||||
final Function(ServiceRequest) onPressed;
|
|
||||||
const ServiceRequestItem({Key key, this.request, this.onPressed, this.index}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Subtitle _subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
User _user = Provider.of<UserProvider>(context,listen: false).user;
|
|
||||||
final servicesProvider = Provider.of<ServiceRequestsProvider>(context,listen: false);
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context,listen: false);
|
|
||||||
Color itemColor = index % 2 == 0
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Theme.of(context).colorScheme.onPrimary;
|
|
||||||
Color onItemColor = index % 2 != 0
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Theme.of(context).colorScheme.onPrimary;
|
|
||||||
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
|
|
||||||
primary: itemColor,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppStyle.getBorderRadius(context)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
//padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
|
|
||||||
onPressed: (){
|
|
||||||
onPressed(request);
|
|
||||||
},
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
//Placeholder(color: onItemColor,fallbackWidth: 80,fallbackHeight: 80,),
|
|
||||||
_user.type == UsersTypes.normal_user && request.devicePhotos.isEmpty ? SizedBox.shrink():
|
|
||||||
SizedBox(
|
|
||||||
width: 80,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
request.devicePhotos.isEmpty ? SizedBox.shrink():
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
height: 80,
|
|
||||||
width: 80,
|
|
||||||
child: ImageLoader(
|
|
||||||
url: request.devicePhotos.first,
|
|
||||||
boxFit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 24,),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
_user.type == UsersTypes.engineer ?
|
|
||||||
Material(
|
|
||||||
color: onItemColor,
|
|
||||||
elevation: 6,
|
|
||||||
shape: CircleBorder(),
|
|
||||||
child: IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.description,
|
|
||||||
color: itemColor,
|
|
||||||
size: 32,
|
|
||||||
),
|
|
||||||
onPressed: (){
|
|
||||||
Navigator.of(context).push(
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (_) => CreateServiceReport(
|
|
||||||
request: request,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
) :SizedBox.shrink(),
|
|
||||||
//SizedBox(height: 8,),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 8,),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: request.requestCode == null ? SizedBox.shrink():
|
|
||||||
Text(
|
|
||||||
request.requestCode ?? "-----",
|
|
||||||
style: Theme.of(context).textTheme.headline6.copyWith(
|
|
||||||
color: onItemColor,
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
request.engineerName == null ? SizedBox.shrink():
|
|
||||||
Text(
|
|
||||||
request.engineerName ?? "",
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: onItemColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Divider(color: onItemColor,),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: request.deviceModel == null ? SizedBox.shrink():
|
|
||||||
Text(
|
|
||||||
request.deviceModel ?? "Model not available",
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: onItemColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
request.engineerMobile == null ? SizedBox.shrink():
|
|
||||||
Text(
|
|
||||||
request.engineerMobile,
|
|
||||||
style: Theme.of(context).textTheme.subtitle1.copyWith(
|
|
||||||
color: onItemColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Divider(color: onItemColor,),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: request.deviceSerialNumber == null ? SizedBox.shrink():
|
|
||||||
Text(
|
|
||||||
request.deviceSerialNumber,
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: onItemColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
request.deviceEnName == null ? SizedBox.shrink():
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
request.deviceEnName,
|
|
||||||
style: Theme.of(context).textTheme.subtitle1.copyWith(
|
|
||||||
color: onItemColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
Divider(color: onItemColor,),
|
|
||||||
Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
child: Text(
|
|
||||||
request.maintenanceIssue ?? "No maintenance issue found",
|
|
||||||
style: Theme.of(context).textTheme.subtitle1.copyWith(
|
|
||||||
color: onItemColor
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Divider(color: onItemColor,),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
request.date ?? "Date not available",
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: onItemColor
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Spacer(),
|
|
||||||
StatusLabel(label: request.statusLabel,
|
|
||||||
color: AColors.getRequestStatusColor(request.statusValue)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
request.nextVisitDate == null ? SizedBox.shrink() :
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Divider(color: onItemColor,),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
_subtitle.nextVisitDate,
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: onItemColor
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Spacer(),
|
|
||||||
Text(
|
|
||||||
DateFormat('EE dd/MM/yyyy').format(request.nextVisitDate),
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: onItemColor
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/models/service_request/service_request.dart';
|
|
||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:test_sa/views/pages/user/requests/request_details.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
|
|
||||||
import 'package:test_sa/views/widgets/requests/service_request_item.dart';
|
|
||||||
class ServiceRequestsList extends StatelessWidget {
|
|
||||||
final List<ServiceRequest> requests;
|
|
||||||
final bool nextPage;
|
|
||||||
final Future<void> Function() onLazyLoad;
|
|
||||||
|
|
||||||
const ServiceRequestsList({Key key, this.requests, this.nextPage, this.onLazyLoad}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
|
|
||||||
Subtitle _subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
if(requests.length == 0){
|
|
||||||
return NoItemFound(message: _subtitle.noServiceRequestFound,);
|
|
||||||
}
|
|
||||||
return LazyLoading(
|
|
||||||
nextPage: nextPage,
|
|
||||||
onLazyLoad: onLazyLoad,
|
|
||||||
child: ListView.builder(
|
|
||||||
//physics: BouncingScrollPhysics(),
|
|
||||||
itemCount: requests.length,
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 8),
|
|
||||||
itemBuilder: (context,itemIndex){
|
|
||||||
return ServiceRequestItem(
|
|
||||||
index: itemIndex,
|
|
||||||
request: requests[itemIndex],
|
|
||||||
onPressed: (request){
|
|
||||||
Navigator.of(context).push(
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (_)=> RequestDetailsPage(serviceRequest: request,)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,149 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/http_status_manger/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/user_provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/settings/setting_provider.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/lookup.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/buttons/app_small_button.dart';
|
|
||||||
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
|
|
||||||
import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/employee/employee_mune.dart';
|
|
||||||
|
|
||||||
import '../app_text_form_field.dart';
|
|
||||||
|
|
||||||
class ServiceRequestsUpdateDialog extends StatefulWidget {
|
|
||||||
final ServiceRequest request;
|
|
||||||
const ServiceRequestsUpdateDialog({
|
|
||||||
Key key, this.request,
|
|
||||||
}) : super(key: key);
|
|
||||||
@override
|
|
||||||
State<ServiceRequestsUpdateDialog> createState() => _ServiceRequestsUpdateDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ServiceRequestsUpdateDialogState extends State<ServiceRequestsUpdateDialog>
|
|
||||||
with TickerProviderStateMixin{
|
|
||||||
|
|
||||||
DateTime _dateTime;
|
|
||||||
Lookup _employee;
|
|
||||||
Subtitle _subtitle;
|
|
||||||
UserProvider _userProvider;
|
|
||||||
SettingProvider _settingProvider;
|
|
||||||
ServiceRequestsProvider _serviceRequestsProvider;
|
|
||||||
|
|
||||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
||||||
|
|
||||||
_update() async {
|
|
||||||
if(_dateTime == null && _employee == null){
|
|
||||||
Fluttertoast.showToast(
|
|
||||||
msg: _subtitle.noDateFound,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showDialog<void>(
|
|
||||||
context: context,
|
|
||||||
barrierDismissible: false,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return CupertinoAlertDialog(
|
|
||||||
title: Text(_subtitle.updatingDots),
|
|
||||||
content: Center(child: CircularProgressIndicator()),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
int status = await _serviceRequestsProvider.updateDate(
|
|
||||||
user: _userProvider.user,
|
|
||||||
host: _settingProvider.host,
|
|
||||||
request: widget.request,
|
|
||||||
newDate: _dateTime?.toString()?.split(" ")?.first,
|
|
||||||
employee: _employee
|
|
||||||
);
|
|
||||||
if(status == 200) Navigator.of(context).pop();
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
Fluttertoast.showToast(
|
|
||||||
msg: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
_subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
_userProvider = Provider.of<UserProvider>(context,listen: false);
|
|
||||||
_settingProvider = Provider.of<SettingProvider>(context,listen: false);
|
|
||||||
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context,listen: false);
|
|
||||||
return Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
// height: MediaQuery.of(context).size.height / 1.2,
|
|
||||||
child: Form(
|
|
||||||
key: _formKey,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
ASmallButton(
|
|
||||||
text: _subtitle.cancel,
|
|
||||||
onPressed: (){
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
ASmallButton(
|
|
||||||
text: _subtitle.update,
|
|
||||||
onPressed: _update,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
_subtitle.date,
|
|
||||||
style: Theme.of(context).textTheme.subtitle1,
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ADatePicker(
|
|
||||||
date: _dateTime,
|
|
||||||
from: DateTime.now(),
|
|
||||||
onDatePicker: (date){
|
|
||||||
_dateTime = date;
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
EmployeeMenu(
|
|
||||||
initialValue: _employee,
|
|
||||||
onSelect: (employee){
|
|
||||||
_employee = employee;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/app_style/colors.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
|
|
||||||
class FilterItem extends StatelessWidget {
|
|
||||||
final bool isSelected;
|
|
||||||
final Lookup status;
|
|
||||||
final VoidCallback onSelected;
|
|
||||||
|
|
||||||
const FilterItem({
|
|
||||||
Key key,
|
|
||||||
this.status,
|
|
||||||
this.isSelected,
|
|
||||||
this.onSelected
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
Color getStatusColor(){
|
|
||||||
switch(status.id){
|
|
||||||
case 0: return AColors.green;
|
|
||||||
case 4: return AColors.deepRed;
|
|
||||||
case 6: return AColors.green;
|
|
||||||
case 5: return AColors.orange;
|
|
||||||
case 8: return AColors.green;
|
|
||||||
case 9: return AColors.orange;
|
|
||||||
default : return AColors.grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Opacity(
|
|
||||||
opacity: isSelected ? 1 : .5,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 30,
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppStyle.getBorderRadius(context)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
primary: getStatusColor(),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
status.label??"",
|
|
||||||
style: Theme.of(context).textTheme.bodyText1.copyWith(
|
|
||||||
color:getStatusColor().computeLuminance() > 0.5
|
|
||||||
? AColors.black : Colors.white,
|
|
||||||
),
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
onPressed:onSelected,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,188 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/models/service_request/service_request_search.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/buttons/app_small_button.dart';
|
|
||||||
import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field.dart';
|
|
||||||
|
|
||||||
import '../app_text_form_field.dart';
|
|
||||||
import 'filter_item.dart';
|
|
||||||
class ServiceRequestsSearchDialog extends StatefulWidget {
|
|
||||||
final ServiceRequestSearch initialSearchValue;
|
|
||||||
final bool expandedSearch;
|
|
||||||
final Function(ServiceRequestSearch) onSearch;
|
|
||||||
|
|
||||||
const ServiceRequestsSearchDialog({
|
|
||||||
Key key,
|
|
||||||
this.initialSearchValue,
|
|
||||||
this.expandedSearch,
|
|
||||||
this.onSearch
|
|
||||||
}) : super(key: key);
|
|
||||||
@override
|
|
||||||
_ServiceRequestsSearchDialogState createState() => _ServiceRequestsSearchDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ServiceRequestsSearchDialogState extends State<ServiceRequestsSearchDialog>
|
|
||||||
with TickerProviderStateMixin{
|
|
||||||
ServiceRequestSearch _search;
|
|
||||||
List<Lookup> status = [
|
|
||||||
Lookup(label: "New", id: 4,),
|
|
||||||
|
|
||||||
Lookup(label: "Repaired", id: 6,),
|
|
||||||
Lookup(label: "Repeated", id: 8),
|
|
||||||
Lookup(label: "Closed", id: 9,),
|
|
||||||
Lookup(label: "Under Repair", id: 5,),
|
|
||||||
];
|
|
||||||
|
|
||||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_search = ServiceRequestSearch();
|
|
||||||
_search.fromSearch(widget.initialSearchValue);
|
|
||||||
}
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Subtitle _subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
return SizedBox(
|
|
||||||
height: MediaQuery.of(context).size.height / 1.2,
|
|
||||||
child: Form(
|
|
||||||
key: _formKey,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
ASmallButton(
|
|
||||||
text: _subtitle.cancel,
|
|
||||||
onPressed: (){
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
ASmallButton(
|
|
||||||
text: _subtitle.search,
|
|
||||||
onPressed: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: _search.deviceSerialNumber,
|
|
||||||
hintText: _subtitle.serialNumber,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
onAction: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
onSaved: (value){
|
|
||||||
_search.deviceSerialNumber = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
HospitalAutoCompleteField(
|
|
||||||
initialValue: _search.hospital,
|
|
||||||
onSave: (value){
|
|
||||||
_search.hospital = value;
|
|
||||||
},
|
|
||||||
onSearch: (value){
|
|
||||||
_search.hospital = value;
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: _search.deviceName,
|
|
||||||
hintText: _subtitle.deviceName,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
onAction: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
onSaved: (value){
|
|
||||||
_search.deviceName = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: _search.model,
|
|
||||||
hintText: _subtitle.model,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
onAction: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
onSaved: (value){
|
|
||||||
_search.model = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 16 * AppStyle.getScaleFactor(context),),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
||||||
child: Wrap(
|
|
||||||
spacing: 10,
|
|
||||||
runSpacing: 10,
|
|
||||||
alignment: WrapAlignment.spaceEvenly,
|
|
||||||
children: List.generate(
|
|
||||||
status.length,
|
|
||||||
(index) {
|
|
||||||
bool isSelected = _search.statusValue == status[index].id;
|
|
||||||
return FilterItem(
|
|
||||||
isSelected: isSelected,
|
|
||||||
onSelected: (){
|
|
||||||
if(isSelected)
|
|
||||||
_search.statusValue = null;
|
|
||||||
else
|
|
||||||
_search.statusValue = status[index].id;
|
|
||||||
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
status: status[index],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
Visibility(
|
|
||||||
visible: widget.initialSearchValue.toSearchString().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,242 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:test_sa/controllers/localization/localization.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/models/subtitle.dart';
|
|
||||||
import 'package:test_sa/models/visits/visits_search.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/buttons/app_small_button.dart';
|
|
||||||
import 'package:test_sa/views/widgets/date_and_time/from_to_date_bar.dart';
|
|
||||||
import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field.dart';
|
|
||||||
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
|
|
||||||
|
|
||||||
import '../app_text_form_field.dart';
|
|
||||||
import 'filter_item.dart';
|
|
||||||
class VisitsSearchDialog extends StatefulWidget {
|
|
||||||
final VisitsSearch initialSearchValue;
|
|
||||||
final bool expandedSearch;
|
|
||||||
final Function(VisitsSearch) onSearch;
|
|
||||||
|
|
||||||
const VisitsSearchDialog({
|
|
||||||
Key key,
|
|
||||||
this.initialSearchValue,
|
|
||||||
this.expandedSearch,
|
|
||||||
this.onSearch
|
|
||||||
}) : super(key: key);
|
|
||||||
@override
|
|
||||||
_VisitsSearchDialogState createState() => _VisitsSearchDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _VisitsSearchDialogState extends State<VisitsSearchDialog>
|
|
||||||
with TickerProviderStateMixin{
|
|
||||||
VisitsSearch _search;
|
|
||||||
List<Lookup> status = [
|
|
||||||
Lookup(label: "Done", id: 0,),
|
|
||||||
Lookup(label: "Not Yet", id: 1),
|
|
||||||
Lookup(label: "On Hold", id: 2,),
|
|
||||||
];
|
|
||||||
|
|
||||||
List<Lookup> contactStatus = [
|
|
||||||
Lookup(label: "Hospital Employee", key: "H",),
|
|
||||||
Lookup(label: "Under Warranty", key: "CW"),
|
|
||||||
Lookup(label: "Under Maintenance Contract", key: "CC",),
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_search = VisitsSearch();
|
|
||||||
_search.fromSearch(widget.initialSearchValue);
|
|
||||||
}
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Subtitle _subtitle = AppLocalization.of(context).subtitle;
|
|
||||||
DateTime today = DateTime.now();
|
|
||||||
return SizedBox(
|
|
||||||
height: MediaQuery.of(context).size.height / 1.3,
|
|
||||||
child: Form(
|
|
||||||
key: _formKey,
|
|
||||||
child: ListView(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16),
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
ASmallButton(
|
|
||||||
text: _subtitle.cancel,
|
|
||||||
onPressed: (){
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
ASmallButton(
|
|
||||||
text: _subtitle.search,
|
|
||||||
onPressed: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: _search.deviceSerialNumber,
|
|
||||||
hintText: _subtitle.serialNumber,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
onAction: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
onSaved: (value){
|
|
||||||
_search.deviceSerialNumber = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
HospitalAutoCompleteField(
|
|
||||||
initialValue: _search.hospitalName,
|
|
||||||
onSave: (value){
|
|
||||||
_search.hospitalName = value;
|
|
||||||
},
|
|
||||||
onSearch: (value){
|
|
||||||
_search.hospitalName = value;
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: _search.brand,
|
|
||||||
hintText: _subtitle.brand,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
onAction: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
onSaved: (value){
|
|
||||||
_search.brand = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ATextFormField(
|
|
||||||
initialValue: _search.model,
|
|
||||||
hintText: _subtitle.model,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
onAction: (){
|
|
||||||
if(!_formKey.currentState.validate())
|
|
||||||
return;
|
|
||||||
_formKey.currentState.save();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
onSaved: (value){
|
|
||||||
_search.model = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ASubTitle(_subtitle.status),
|
|
||||||
SizedBox(height: 4.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
Wrap(
|
|
||||||
spacing: 10,
|
|
||||||
runSpacing: 10,
|
|
||||||
children: List.generate(
|
|
||||||
status.length,
|
|
||||||
(index) {
|
|
||||||
bool isSelected = _search.statusValue == status[index].id;
|
|
||||||
return FilterItem(
|
|
||||||
isSelected: isSelected,
|
|
||||||
onSelected: (){
|
|
||||||
if(isSelected)
|
|
||||||
_search.statusValue = null;
|
|
||||||
else
|
|
||||||
_search.statusValue = status[index].id;
|
|
||||||
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
status: status[index],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ASubTitle(_subtitle.contactStatus),
|
|
||||||
SizedBox(height: 4.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
Wrap(
|
|
||||||
spacing: 10,
|
|
||||||
runSpacing: 10,
|
|
||||||
children: List.generate(
|
|
||||||
contactStatus.length,
|
|
||||||
(index) {
|
|
||||||
bool isSelected = _search.contactStatus == contactStatus[index].key;
|
|
||||||
return FilterItem(
|
|
||||||
isSelected: isSelected,
|
|
||||||
onSelected: (){
|
|
||||||
if(isSelected)
|
|
||||||
_search.contactStatus = null;
|
|
||||||
else
|
|
||||||
_search.contactStatus = contactStatus[index].key;
|
|
||||||
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
status: contactStatus[index],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ASubTitle(_subtitle.actualDate),
|
|
||||||
SizedBox(height: 4.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
FromToDateBar(
|
|
||||||
from: _search.actualDateFrom ,
|
|
||||||
to: _search.actualDateTo,
|
|
||||||
onPickFrom: (date){
|
|
||||||
_search.actualDateFrom = date;
|
|
||||||
},
|
|
||||||
onPickTo: (date){
|
|
||||||
_search.actualDateTo = date;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
ASubTitle(_subtitle.expectDate),
|
|
||||||
SizedBox(height: 4.0 * AppStyle.getScaleFactor(context),),
|
|
||||||
FromToDateBar(
|
|
||||||
from: _search.expectedDateFrom ?? DateTime(today.year, today.month, 1),
|
|
||||||
to: _search.expectedDateTo ?? DateTime(today.year, (today.month +1).clamp(1, 12) , today.month == 12 ? 31 : 0),
|
|
||||||
onPickFrom: (date){
|
|
||||||
_search.expectedDateFrom = date;
|
|
||||||
},
|
|
||||||
onPickTo: (date){
|
|
||||||
_search.expectedDateTo = date;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: _search.toSearchString().isNotEmpty,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16),
|
|
||||||
child: AButton(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
text: _subtitle.clearSearch,
|
|
||||||
onPressed: (){
|
|
||||||
_search = VisitsSearch();
|
|
||||||
Navigator.of(context).pop(_search);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,239 +0,0 @@
|
|||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:audioplayers/audioplayers.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
|
|
||||||
import '../../app_style/colors.dart';
|
|
||||||
|
|
||||||
class ASoundPlayer extends StatefulWidget {
|
|
||||||
|
|
||||||
final String audio;
|
|
||||||
|
|
||||||
const ASoundPlayer({Key key, this.audio}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_ASoundPlayerState createState() => _ASoundPlayerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ASoundPlayerState extends State<ASoundPlayer> {
|
|
||||||
|
|
||||||
//FlutterSoundPlayer _myPlayer = FlutterSoundPlayer();
|
|
||||||
bool _sliderMoving = false;
|
|
||||||
Duration _audioTime;
|
|
||||||
Duration _audioPosition;
|
|
||||||
String _audio;
|
|
||||||
bool _isLocalFile = false;
|
|
||||||
bool _failedToLoad = false;
|
|
||||||
AudioPlayer _audioPlayer;
|
|
||||||
|
|
||||||
Widget _getAudioButton(){
|
|
||||||
switch(_audioPlayer.state){
|
|
||||||
case PlayerState.playing:
|
|
||||||
return IconButton(
|
|
||||||
icon: const Icon(Icons.pause_rounded),
|
|
||||||
onPressed: () async {
|
|
||||||
_failedToLoad = false;
|
|
||||||
await _audioPlayer.pause();
|
|
||||||
rebuild();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
case PlayerState.paused:
|
|
||||||
return IconButton(
|
|
||||||
icon: const Icon(Icons.play_arrow_rounded),
|
|
||||||
onPressed: () async {
|
|
||||||
_failedToLoad = false;
|
|
||||||
await _audioPlayer.resume();
|
|
||||||
rebuild();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
case PlayerState.completed:
|
|
||||||
return IconButton(
|
|
||||||
icon: const Icon(Icons.replay_rounded),
|
|
||||||
onPressed: () async {
|
|
||||||
_failedToLoad = false;
|
|
||||||
await _audioPlayer.stop();
|
|
||||||
await _audioPlayer.resume();
|
|
||||||
rebuild();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
case PlayerState.stopped:
|
|
||||||
return IconButton(
|
|
||||||
icon: Icon( _isLocalFile
|
|
||||||
? Icons.play_circle_fill_outlined
|
|
||||||
: Icons.download_rounded
|
|
||||||
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
_failedToLoad = false;
|
|
||||||
try {
|
|
||||||
await _audioPlayer.play(
|
|
||||||
_isLocalFile?
|
|
||||||
DeviceFileSource(_audio):UrlSource(_audio),
|
|
||||||
);
|
|
||||||
rebuild();
|
|
||||||
} on Exception catch (e) {
|
|
||||||
_failedToLoad = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
default: return IconButton(
|
|
||||||
icon: const Icon( Icons.replay_rounded),
|
|
||||||
onPressed: () async {
|
|
||||||
_failedToLoad = false;
|
|
||||||
try {
|
|
||||||
_audioPlayer.seek(const Duration(milliseconds: 0));
|
|
||||||
_audioPlayer.stop();
|
|
||||||
await _audioPlayer.play(
|
|
||||||
_isLocalFile?
|
|
||||||
DeviceFileSource(_audio):UrlSource(_audio),
|
|
||||||
);
|
|
||||||
rebuild();
|
|
||||||
} on Exception catch (e) {
|
|
||||||
_failedToLoad = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String format(Duration d) {
|
|
||||||
if(d == null)
|
|
||||||
return "00:00";
|
|
||||||
return d.toString().substring(2, 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuild(){
|
|
||||||
if (!mounted) return;
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _isLocalUrl(String url) {
|
|
||||||
if(url?.isEmpty != false) return false;
|
|
||||||
return url.startsWith("/") ||
|
|
||||||
url.startsWith("file://") ||
|
|
||||||
url.substring(1).startsWith(':\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_audioPlayer = AudioPlayer();
|
|
||||||
_audioPlayer.release();
|
|
||||||
_audio = widget.audio;
|
|
||||||
_isLocalFile = _isLocalUrl(_audio);
|
|
||||||
_audioPlayer.setReleaseMode(ReleaseMode.stop);
|
|
||||||
if(_isLocalFile){
|
|
||||||
_audioPlayer.setSourceDeviceFile(_audio).then((value) {rebuild();});
|
|
||||||
} else{
|
|
||||||
_audioPlayer.setReleaseMode(ReleaseMode.stop);
|
|
||||||
}
|
|
||||||
// set up listeners
|
|
||||||
_audioPlayer.onPositionChanged.listen((Duration duration) {
|
|
||||||
if(!_sliderMoving){
|
|
||||||
_audioPosition = duration;
|
|
||||||
rebuild();
|
|
||||||
}
|
|
||||||
//setState(() => position = p);
|
|
||||||
});
|
|
||||||
_audioPlayer.onPlayerStateChanged.listen((event) {
|
|
||||||
//_audioPosition = _audioTime;
|
|
||||||
rebuild();
|
|
||||||
});
|
|
||||||
_audioPlayer.onDurationChanged.listen((Duration duration) {
|
|
||||||
_audioTime = duration;
|
|
||||||
rebuild();
|
|
||||||
});
|
|
||||||
_audioPlayer.onSeekComplete.listen((event) {
|
|
||||||
rebuild();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
// _myPlayer.closeAudioSession();
|
|
||||||
_audioPlayer.release();
|
|
||||||
_audioPlayer.dispose();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if(_audio != widget.audio){
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
||||||
_audio = widget.audio;
|
|
||||||
if(_isLocalFile){
|
|
||||||
await _audioPlayer.setSourceDeviceFile(_audio);
|
|
||||||
}else{
|
|
||||||
await _audioPlayer.setSourceUrl(_audio);
|
|
||||||
}
|
|
||||||
_audioPlayer.seek(const Duration(milliseconds: 0));
|
|
||||||
_audioPlayer.stop();
|
|
||||||
rebuild();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Material(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: _getAudioButton()
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Slider(
|
|
||||||
value: _audioPosition?.inMilliseconds?.toDouble() ?? 0.0,
|
|
||||||
min: 0,
|
|
||||||
max: _audioTime?.inMilliseconds?.toDouble() ?? 60.0,
|
|
||||||
onChangeStart: (value){
|
|
||||||
_sliderMoving = true;
|
|
||||||
},
|
|
||||||
onChanged: (value){
|
|
||||||
_audioPosition = Duration(milliseconds: value.round());
|
|
||||||
rebuild();
|
|
||||||
},
|
|
||||||
onChangeEnd: (value){
|
|
||||||
_sliderMoving = false;
|
|
||||||
_audioPlayer.seek(Duration(milliseconds: value.round()));
|
|
||||||
rebuild();
|
|
||||||
}
|
|
||||||
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Visibility(
|
|
||||||
visible: _failedToLoad,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Failed to load",
|
|
||||||
style: Theme.of(context).textTheme.overline.copyWith(
|
|
||||||
color: AColors.red
|
|
||||||
),
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: _audioPlayer.state != PlayerState.stopped,
|
|
||||||
child: Text(
|
|
||||||
"${format(_audioPosition)}/${format(_audioTime)}",
|
|
||||||
style: Theme.of(context).textTheme.overline,
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/employee_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class EmployeeMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const EmployeeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<EmployeesProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_cylinder_size_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class GasCylinderSizeMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const GasCylinderSizeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<GasCylinderSizesProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_types_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class GasTypeMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const GasTypeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<GasTypesProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/app_style/colors.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
class MultiStatusMenu extends StatefulWidget {
|
|
||||||
final List<Lookup> statuses;
|
|
||||||
final List<Lookup> initialSelectedStatus;
|
|
||||||
final Function(List<Lookup>) onSelect;
|
|
||||||
|
|
||||||
const MultiStatusMenu({Key key, this.statuses, this.onSelect, this.initialSelectedStatus}) : super(key: key);
|
|
||||||
@override
|
|
||||||
_MultiStatusMenuState createState() => _MultiStatusMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MultiStatusMenuState extends State<MultiStatusMenu> {
|
|
||||||
|
|
||||||
List<Lookup> _selectedStatus = [];
|
|
||||||
TextEditingController _controller;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_controller = TextEditingController();
|
|
||||||
_selectedStatus.addAll(widget.initialSelectedStatus);
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_controller.clear();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Wrap(
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
|
||||||
alignment: WrapAlignment.start,
|
|
||||||
runAlignment: WrapAlignment.start,
|
|
||||||
children: List.generate(
|
|
||||||
_selectedStatus.length,
|
|
||||||
(index) {
|
|
||||||
final status = _selectedStatus[index];
|
|
||||||
return Container(
|
|
||||||
height: 36 * AppStyle.getScaleFactor(context),
|
|
||||||
margin: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)),
|
|
||||||
//padding: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
borderRadius: BorderRadius.circular(8)
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const SizedBox(width: 12,),
|
|
||||||
Text(
|
|
||||||
status.label,
|
|
||||||
style: Theme.of(context).textTheme.bodyText1.copyWith(
|
|
||||||
color:Theme.of(context).colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
color:Theme.of(context).colorScheme.onPrimary,
|
|
||||||
onPressed: (){
|
|
||||||
_selectedStatus.remove(status);
|
|
||||||
widget.onSelect(_selectedStatus);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.delete)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 16
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
border: Border.all(color:AColors.black),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
|
|
||||||
),
|
|
||||||
boxShadow: const [
|
|
||||||
AppStyle.boxShadow
|
|
||||||
]
|
|
||||||
),
|
|
||||||
child: TypeAheadField<Lookup>(
|
|
||||||
textFieldConfiguration: TextFieldConfiguration(
|
|
||||||
style: Theme.of(context).textTheme.subtitle1,
|
|
||||||
controller: _controller,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
disabledBorder: InputBorder.none,
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
),
|
|
||||||
suggestionsCallback: (vale) {
|
|
||||||
return widget.statuses.where((Lookup option) {
|
|
||||||
return option.label.toLowerCase().contains(_controller.text);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
itemBuilder: (context, part) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(part.label),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onSuggestionSelected: (status) {
|
|
||||||
_controller.clear();
|
|
||||||
if(!_selectedStatus.contains(status)){
|
|
||||||
_selectedStatus.add(status);
|
|
||||||
widget.onSelect(_selectedStatus);
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_status_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class PentryStatusMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const PentryStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<PentryStatusProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_task_status_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class PentryTaskStatusMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const PentryTaskStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<PentryTaskStatusProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_visit_status_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class PentryVisitsStatusMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const PentryVisitsStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<PentryVisitStatusProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
|
|
||||||
import 'package:test_sa/models/lookup.dart';
|
|
||||||
import 'package:test_sa/models/service_report.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class ServiceReportLastCallsMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final ServiceReport report;
|
|
||||||
|
|
||||||
const ServiceReportLastCallsMenu({
|
|
||||||
Key key,@required this.onSelect,@required this.report}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
ServiceReportLastCallsProvider _menuProvider = Provider.of<ServiceReportLastCallsProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: _menuProvider.isLoading,
|
|
||||||
isFailedLoading: _menuProvider.calls == null,
|
|
||||||
stateCode: _menuProvider.stateCode,
|
|
||||||
onRefresh: () async {},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: report?.callLastSituation,
|
|
||||||
statuses: _menuProvider.calls,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_reasons_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class ServiceReportReasonsMenu extends StatelessWidget {
|
|
||||||
final Lookup initialValue;
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
|
|
||||||
const ServiceReportReasonsMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
SettingProvider _settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
UserProvider _userProvider = Provider.of<UserProvider>(context);
|
|
||||||
ServiceReportReasonsProvider _menuProvider = Provider.of<ServiceReportReasonsProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: _menuProvider.isLoading,
|
|
||||||
isFailedLoading: _menuProvider.reasons == null,
|
|
||||||
stateCode: _menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
_menuProvider.reset();
|
|
||||||
await _menuProvider.getTypes(
|
|
||||||
user: _userProvider.user,
|
|
||||||
host: _settingProvider.host,
|
|
||||||
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: _menuProvider.reasons,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/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_status_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/models/service_report.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class ServiceReportStatusMenu extends StatefulWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final ServiceReport report;
|
|
||||||
|
|
||||||
const ServiceReportStatusMenu({Key key, this.onSelect, this.report}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ServiceReportStatusMenu> createState() => _ServiceReportStatusMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ServiceReportStatusMenuState extends State<ServiceReportStatusMenu> {
|
|
||||||
bool firstTime = true;
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
SettingProvider _settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
UserProvider _userProvider = Provider.of<UserProvider>(context);
|
|
||||||
ServiceReportStatusProvider _menuProvider = Provider.of<ServiceReportStatusProvider>(context);
|
|
||||||
ServiceReportLastCallsProvider _callsLastSituationsProvider = Provider.of<ServiceReportLastCallsProvider>(context,listen: false);
|
|
||||||
if(firstTime){
|
|
||||||
_callsLastSituationsProvider.reset();
|
|
||||||
|
|
||||||
firstTime = false;
|
|
||||||
}
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: _menuProvider.isLoading == true || _callsLastSituationsProvider.isLoading == true,
|
|
||||||
isFailedLoading: _menuProvider.statuses == null || _callsLastSituationsProvider.calls == null,
|
|
||||||
stateCode: _menuProvider.stateCode == null || _callsLastSituationsProvider.stateCode == null ? null:
|
|
||||||
max(_menuProvider.stateCode ?? 0,_callsLastSituationsProvider.stateCode ?? 0),
|
|
||||||
onRefresh: () async {
|
|
||||||
if(_menuProvider.stateCode == null){
|
|
||||||
_menuProvider.reset();
|
|
||||||
await _menuProvider.getTypes(
|
|
||||||
user: _userProvider.user,
|
|
||||||
host: _settingProvider.host
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await _callsLastSituationsProvider.getCalls(
|
|
||||||
user: _userProvider.user,
|
|
||||||
host: _settingProvider.host,
|
|
||||||
serviceStatus: widget.report.status?.id.toString()
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
statuses: _menuProvider.statuses,
|
|
||||||
initialStatus: widget.report.status,
|
|
||||||
onSelect: (status){
|
|
||||||
_callsLastSituationsProvider.getCalls(
|
|
||||||
user: _userProvider.user,
|
|
||||||
host: _settingProvider.host,
|
|
||||||
serviceStatus: status.id.toString()
|
|
||||||
);
|
|
||||||
widget.report.callLastSituation = null;
|
|
||||||
widget.onSelect(status);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class ServiceStatusMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const ServiceStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
SettingProvider _settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
UserProvider _userProvider = Provider.of<UserProvider>(context);
|
|
||||||
ServiceStatusProvider _menuProvider = Provider.of<ServiceStatusProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: _menuProvider.isLoading,
|
|
||||||
isFailedLoading: _menuProvider.statuses == null,
|
|
||||||
stateCode: _menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
_menuProvider.reset();
|
|
||||||
await _menuProvider.getTypes(
|
|
||||||
user: _userProvider.user,
|
|
||||||
host: _settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: _menuProvider.statuses,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_defect_types_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class ServiceRequestDefectTypesMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const ServiceRequestDefectTypesMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<ServiceRequestDefectTypesProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_priority_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/models/lookup.dart';
|
|
||||||
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
|
||||||
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
|
||||||
class ServiceRequestPriorityMenu extends StatelessWidget {
|
|
||||||
final Function(Lookup) onSelect;
|
|
||||||
final Lookup initialValue;
|
|
||||||
|
|
||||||
const ServiceRequestPriorityMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final settingProvider = Provider.of<SettingProvider>(context);
|
|
||||||
final userProvider = Provider.of<UserProvider>(context);
|
|
||||||
final menuProvider = Provider.of<ServiceRequestPriorityProvider>(context);
|
|
||||||
return LoadingManager(
|
|
||||||
isLoading: menuProvider.isLoading,
|
|
||||||
isFailedLoading: menuProvider.items == null,
|
|
||||||
stateCode: menuProvider.stateCode,
|
|
||||||
onRefresh: () async {
|
|
||||||
menuProvider.reset();
|
|
||||||
await menuProvider.getData(
|
|
||||||
user: userProvider.user,
|
|
||||||
host: settingProvider.host
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SingleStatusMenu(
|
|
||||||
initialStatus: initialValue,
|
|
||||||
statuses: menuProvider.items,
|
|
||||||
onSelect: onSelect,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/models/timer_model.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 AppTimer extends StatefulWidget {
|
|
||||||
final TimerModel timer;
|
|
||||||
final Future<bool> Function(TimerModel) onChange;
|
|
||||||
final TextStyle style;
|
|
||||||
const AppTimer({
|
|
||||||
Key key,
|
|
||||||
this.timer,
|
|
||||||
this.onChange,
|
|
||||||
this.style,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<AppTimer> createState() => _AppTimerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AppTimerState extends State<AppTimer> {
|
|
||||||
Timer _timer;
|
|
||||||
DateTime _startAt;
|
|
||||||
DateTime _endAt;
|
|
||||||
int _delay = 0;
|
|
||||||
bool _running = false;
|
|
||||||
bool _loading = false;
|
|
||||||
final ValueNotifier<String> _period = ValueNotifier("0:00:00");
|
|
||||||
|
|
||||||
_startTimer() async {
|
|
||||||
if (!_running) {
|
|
||||||
final time = DateTime.now();
|
|
||||||
bool result = await widget.onChange(
|
|
||||||
TimerModel(startAt: time,endAt: null,durationInSecond: _delay));
|
|
||||||
if(!result) return;
|
|
||||||
_running = true;
|
|
||||||
|
|
||||||
if(_endAt != null){
|
|
||||||
_delay += _endAt.difference(_startAt).inSeconds;
|
|
||||||
}
|
|
||||||
_startAt = time.subtract(Duration(seconds: _delay));
|
|
||||||
_endAt = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
||||||
if(_loading == true) return;
|
|
||||||
_period.value = (_endAt ?? DateTime.now()).difference(
|
|
||||||
_startAt
|
|
||||||
).toString().split(".").first;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_stopTimer() async {
|
|
||||||
final time = DateTime.now();
|
|
||||||
final tempStartAt = _startAt.add(Duration(seconds: _delay));
|
|
||||||
bool result = await widget.onChange(
|
|
||||||
TimerModel(startAt: tempStartAt,endAt: time,durationInSecond: _delay));
|
|
||||||
if(!result) return;
|
|
||||||
_running = false;
|
|
||||||
_endAt = time;
|
|
||||||
_startAt = tempStartAt;
|
|
||||||
_timer?.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
_onPressed() async {
|
|
||||||
_loading = true;
|
|
||||||
setState(() {});
|
|
||||||
if(!_running){
|
|
||||||
await _startTimer();
|
|
||||||
}else{
|
|
||||||
await _stopTimer();
|
|
||||||
}
|
|
||||||
_loading = false;
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_startAt = widget.timer?.startAt;
|
|
||||||
_endAt = widget.timer?.endAt;
|
|
||||||
_running = _startAt != null && _endAt == null;
|
|
||||||
_delay = (widget.timer?.durationInSecond ?? 0);
|
|
||||||
final difference = _startAt == null ? 0:
|
|
||||||
(_endAt ?? DateTime.now())?.difference(_startAt)?.inSeconds ?? 0;
|
|
||||||
_period.value = Duration(seconds: _running ? difference : _delay + difference).toString().split(".").first;
|
|
||||||
super.initState();
|
|
||||||
if(_running){_startTimer();}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
width: 100 * AppStyle.getScaleFactor(context),
|
|
||||||
height: 28 * AppStyle.getScaleFactor(context),
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
minimumSize: const Size(1, 1),
|
|
||||||
padding: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)),
|
|
||||||
backgroundColor: _running ? AColors.green[300] : AColors.grey,
|
|
||||||
foregroundColor: Colors.black
|
|
||||||
),
|
|
||||||
onPressed: _loading ? null : _onPressed,
|
|
||||||
child: _loading ? const SizedBox.square(
|
|
||||||
dimension: 18,child: CircularProgressIndicator(color: Colors.white,)):
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(_running ? Icons.pause : Icons.play_arrow),
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: ValueListenableBuilder<String>(
|
|
||||||
valueListenable: _period,
|
|
||||||
builder: (context,value,_){
|
|
||||||
return Text(value,
|
|
||||||
style: widget.style,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
class ATitle extends StatelessWidget {
|
|
||||||
final String text;
|
|
||||||
final EdgeInsets padding;
|
|
||||||
final bool center;
|
|
||||||
const ATitle(this.text, {Key key,this.padding,this.center= false}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: padding ?? EdgeInsets.symmetric(horizontal: 16,vertical: 8),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: center
|
|
||||||
? MainAxisAlignment.center
|
|
||||||
: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
text,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
class ExpandableInfoRow extends StatefulWidget {
|
|
||||||
final IconData iconData;
|
|
||||||
final String title;
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const ExpandableInfoRow({Key key, this.iconData, this.title, this.child}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_ExpandableInfoRowState createState() => _ExpandableInfoRowState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ExpandableInfoRowState extends State<ExpandableInfoRow>
|
|
||||||
with TickerProviderStateMixin{
|
|
||||||
bool _isExpanded = false;
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: (){
|
|
||||||
_isExpanded = !_isExpanded;
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
widget.iconData != null ?
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 8 * AppStyle.getScaleFactor(context),
|
|
||||||
vertical: 2 * AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
child: FaIcon(
|
|
||||||
widget.iconData,
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
size: 20 * AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
):SizedBox.shrink(),
|
|
||||||
Expanded(
|
|
||||||
flex: 2,
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
style: TextStyle(
|
|
||||||
//color: Theme.of(context).dividerColor,
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AnimatedSwitcher(
|
|
||||||
duration: Duration(milliseconds: 400),
|
|
||||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
|
||||||
return FadeTransition(
|
|
||||||
child: ScaleTransition(
|
|
||||||
child: child,
|
|
||||||
scale: animation
|
|
||||||
),
|
|
||||||
opacity: animation,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Icon(
|
|
||||||
_isExpanded
|
|
||||||
? Icons.keyboard_arrow_up
|
|
||||||
: Icons.keyboard_arrow_down,
|
|
||||||
key: ValueKey(_isExpanded
|
|
||||||
? "Icons.keyboard_arrow_up"
|
|
||||||
: "Icons.keyboard_arrow_down"),
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
size: 24 * AppStyle.getScaleFactor(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
AnimatedSize(
|
|
||||||
duration: Duration(milliseconds: 300),
|
|
||||||
child: Visibility(
|
|
||||||
visible: _isExpanded,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 8 * AppStyle.getScaleFactor(context)),
|
|
||||||
child: widget.child,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Divider(height: 2 * AppStyle.getScaleFactor(context),),
|
|
||||||
SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:test_sa/models/visits/visit.dart';
|
|
||||||
import 'package:test_sa/views/app_style/colors.dart';
|
|
||||||
import 'package:test_sa/views/app_style/sizing.dart';
|
|
||||||
class VisitStatusLabel extends StatelessWidget {
|
|
||||||
final Visit visit;
|
|
||||||
|
|
||||||
const VisitStatusLabel({Key key, this.visit}) : super(key: key);
|
|
||||||
|
|
||||||
Color getStatusColor(){
|
|
||||||
switch(visit.status.id){
|
|
||||||
case 0: return AColors.green;
|
|
||||||
case 1: return AColors.grey;
|
|
||||||
case 2: return AColors.grey;
|
|
||||||
default : return AColors.grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 2,horizontal: 8),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: getStatusColor(),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppStyle.getBorderRadius(context)
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
AppStyle.boxShadow
|
|
||||||
]
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
visit.status.label == null
|
|
||||||
|| visit.status.label.isEmpty
|
|
||||||
? "no status" :visit.status.label,
|
|
||||||
style: Theme.of(context).textTheme.subtitle2.copyWith(
|
|
||||||
color: getStatusColor().computeLuminance() > 0.5
|
|
||||||
? AColors.black : Colors.white,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import '../../models/subtitle.dart';
|
||||||
|
|
||||||
|
class HttpStatusManger {
|
||||||
|
static String getStatusMessage({
|
||||||
|
required int? status,
|
||||||
|
required Subtitle? subtitle,
|
||||||
|
String? messageFor400,
|
||||||
|
String? messageFor200,
|
||||||
|
}) {
|
||||||
|
if (status == null) {
|
||||||
|
return "careful null status";
|
||||||
|
}
|
||||||
|
if (status == -1) {
|
||||||
|
return subtitle?.currentlyServiceNotAvailable??"";
|
||||||
|
}
|
||||||
|
if (status == -2) {
|
||||||
|
// client's request in process
|
||||||
|
return subtitle?.waitUntilYourRequestComplete??"";
|
||||||
|
} else if (status >= 200 && status < 300) {
|
||||||
|
// client's request was successfully received
|
||||||
|
return messageFor200 ?? subtitle?.requestCompleteSuccessfully??"";
|
||||||
|
} else if (status >= 400 && status < 500) {
|
||||||
|
// client's request have error
|
||||||
|
switch (status) {
|
||||||
|
case 400:
|
||||||
|
return messageFor400 ?? subtitle?.failedToCompleteRequest??"";
|
||||||
|
default:
|
||||||
|
return subtitle?.failedToCompleteRequest??"";
|
||||||
|
}
|
||||||
|
} else if (status >= 500) {
|
||||||
|
// server error
|
||||||
|
return subtitle?.currentlyServiceNotAvailable??"";
|
||||||
|
} else {
|
||||||
|
// no error match so return default error
|
||||||
|
return subtitle?.failedToCompleteRequest??"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
|
||||||
|
import '../../../models/gas_refill/gas_refill_model.dart';
|
||||||
|
import '../../../models/user.dart';
|
||||||
|
import '../../api_routes/urls.dart';
|
||||||
|
|
||||||
|
class GasRefillProvider extends ChangeNotifier {
|
||||||
|
// number of items call in each request
|
||||||
|
final pageItemNumber = 50;
|
||||||
|
|
||||||
|
//reset provider data
|
||||||
|
void reset() {
|
||||||
|
items = null;
|
||||||
|
nextPage = true;
|
||||||
|
stateCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state code of current request to defied error message
|
||||||
|
// like 400 customer request failed
|
||||||
|
// 500 service not available
|
||||||
|
int? stateCode;
|
||||||
|
|
||||||
|
// true if there is next page in product list and false if not
|
||||||
|
bool nextPage = true;
|
||||||
|
|
||||||
|
// list of user requests
|
||||||
|
List<GasRefillModel>? items;
|
||||||
|
|
||||||
|
// when requests in-process _loading = true
|
||||||
|
// done _loading = true
|
||||||
|
// failed _loading = false
|
||||||
|
bool? isLoading;
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
/// for more details check http state manager
|
||||||
|
/// lib\controllers\http_status_manger\http_status_manger.dart
|
||||||
|
Future<int> getRequests({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
}) async {
|
||||||
|
if (isLoading == true) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
isLoading = true;
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await get(
|
||||||
|
Uri.parse("$host${URLs.getGasRefill}?uid=${user.id}"
|
||||||
|
"&token=${user.token}&page=${(items?.length ?? 0) ~/ pageItemNumber}"),
|
||||||
|
headers: {"Content-Type": "application/json; charset=utf-8"});
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (stateCode != null && stateCode! >= 200 && stateCode! < 300) {
|
||||||
|
// client's request was successfully received
|
||||||
|
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
|
||||||
|
List<GasRefillModel> itemsPage = requestsListJson
|
||||||
|
.map((request) => GasRefillModel.fromJson(request))
|
||||||
|
.toList();
|
||||||
|
items ??= [];
|
||||||
|
items?.addAll(itemsPage);
|
||||||
|
if (itemsPage.length == pageItemNumber) {
|
||||||
|
nextPage = true;
|
||||||
|
} else {
|
||||||
|
nextPage = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
isLoading = false;
|
||||||
|
stateCode = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> createModel({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required GasRefillModel model,
|
||||||
|
}) async {
|
||||||
|
Map<String, dynamic> body = {
|
||||||
|
"uid": user.id.toString(),
|
||||||
|
"token": user.token ?? "",
|
||||||
|
"title": model.title ?? "",
|
||||||
|
"status": "0", //model.status.value.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
body["details"] = jsonEncode(model.details
|
||||||
|
?.map((model) => {
|
||||||
|
"type": model.type?.id.toString(),
|
||||||
|
"size": model.cylinderSize?.id.toString(),
|
||||||
|
"requsted_qty": model.requestedQuantity.toString(),
|
||||||
|
})
|
||||||
|
.toList());
|
||||||
|
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse(host + URLs.requestGasRefill),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
final items = this.items;
|
||||||
|
if (items != null) {
|
||||||
|
items.insert(
|
||||||
|
0,
|
||||||
|
GasRefillModel.fromJson(
|
||||||
|
json.decode(utf8.decode(response.bodyBytes))[0]));
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> updateModel({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required GasRefillModel? oldModel,
|
||||||
|
required GasRefillModel newModel,
|
||||||
|
}) async {
|
||||||
|
Map<String, dynamic> body = {
|
||||||
|
"uid": user.id.toString(),
|
||||||
|
"token": user.token,
|
||||||
|
"title": newModel.title ?? "",
|
||||||
|
"status": newModel.status?.id.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
body["details"] = jsonEncode(newModel.details
|
||||||
|
?.map((model) => {
|
||||||
|
"type": model.type?.id.toString(),
|
||||||
|
"size": model.cylinderSize?.id.toString(),
|
||||||
|
"requsted_qty": model.requestedQuantity.toString(),
|
||||||
|
"deliverd_qty": model.deliveredQuantity.toString(),
|
||||||
|
})
|
||||||
|
.toList());
|
||||||
|
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse("$host${URLs.updateGasRefill}/${newModel.id}"),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
oldModel?.fromGasRefillModel(newModel);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,378 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
|
||||||
|
import '../../../models/issue.dart';
|
||||||
|
import '../../../models/lookup.dart';
|
||||||
|
import '../../../models/service_report.dart';
|
||||||
|
import '../../../models/service_request/service_request.dart';
|
||||||
|
import '../../../models/service_request/service_request_search.dart';
|
||||||
|
import '../../../models/subtitle.dart';
|
||||||
|
import '../../../models/timer_model.dart';
|
||||||
|
import '../../../models/user.dart';
|
||||||
|
import '../../api_routes/urls.dart';
|
||||||
|
import '../../http_status_manger/http_status_manger.dart';
|
||||||
|
|
||||||
|
class ServiceRequestsProvider extends ChangeNotifier {
|
||||||
|
// number of items call in each request
|
||||||
|
final pageItemNumber = 50;
|
||||||
|
|
||||||
|
//reset provider data
|
||||||
|
void reset() {
|
||||||
|
serviceRequests = null;
|
||||||
|
nextPage = true;
|
||||||
|
stateCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state code of current request to defied error message
|
||||||
|
// like 400 customer request failed
|
||||||
|
// 500 service not available
|
||||||
|
int? stateCode;
|
||||||
|
|
||||||
|
// true if there is next page in product list and false if not
|
||||||
|
bool? nextPage = true;
|
||||||
|
|
||||||
|
// list of user requests
|
||||||
|
List<ServiceRequest>? serviceRequests;
|
||||||
|
|
||||||
|
// when requests in-process _loading = true
|
||||||
|
// done _loading = true
|
||||||
|
// failed _loading = false
|
||||||
|
bool? isLoading;
|
||||||
|
|
||||||
|
ServiceRequestSearch? search = ServiceRequestSearch();
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
/// for more details check http state manager
|
||||||
|
/// lib\controllers\http_status_manger\http_status_manger.dart
|
||||||
|
Future<int> getRequests({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required String? hospitalId,
|
||||||
|
}) async {
|
||||||
|
if (isLoading == true) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
isLoading = true;
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await get(
|
||||||
|
Uri.parse(
|
||||||
|
"$host${URLs.getServiceRequests}?uid=${user.id}${hospitalId == null ? "" : "&client_nid=$hospitalId"}&token=${user.token}&page=${(serviceRequests?.length ?? 0) ~/ pageItemNumber}${search?.toSearchString()}",
|
||||||
|
),
|
||||||
|
headers: {"Content-Type": "application/json; charset=utf-8"},
|
||||||
|
);
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
// client's request was successfully received
|
||||||
|
List requestsListJson =
|
||||||
|
json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
|
||||||
|
List<ServiceRequest> _serviceRequestsPage = requestsListJson
|
||||||
|
.map((request) => ServiceRequest.fromJson(request))
|
||||||
|
.toList();
|
||||||
|
serviceRequests ??= [];
|
||||||
|
serviceRequests?.addAll(_serviceRequestsPage);
|
||||||
|
if (_serviceRequestsPage.length == pageItemNumber) {
|
||||||
|
nextPage = true;
|
||||||
|
} else {
|
||||||
|
nextPage = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
isLoading = false;
|
||||||
|
stateCode = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ServiceRequest> getSingleServiceRequest({
|
||||||
|
required String requestId,
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required Subtitle subtitle,
|
||||||
|
}) async {
|
||||||
|
String userData = '';
|
||||||
|
userData += "&uid=${user.id}";
|
||||||
|
userData += "&token=${user.token}";
|
||||||
|
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await get(Uri.parse(
|
||||||
|
'$host${URLs.getSingleServiceRequest}?call_nid=$requestId$userData',
|
||||||
|
));
|
||||||
|
} catch (error) {
|
||||||
|
throw (HttpStatusManger.getStatusMessage(status: -1, subtitle: subtitle) ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the call to the server was successful, parse the JSON.
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
// If the call to the server was successful, parse the JSON.
|
||||||
|
List jsonList =
|
||||||
|
json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
|
||||||
|
List<ServiceRequest> requests =
|
||||||
|
jsonList.map((i) => ServiceRequest.fromJson(i)).toList();
|
||||||
|
return requests[0];
|
||||||
|
} else {
|
||||||
|
throw (HttpStatusManger.getStatusMessage(
|
||||||
|
status: response.statusCode, subtitle: subtitle) ?? "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> createRequest({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required ServiceRequest serviceRequest,
|
||||||
|
}) async {
|
||||||
|
var body = {
|
||||||
|
"uid": user.id,
|
||||||
|
"token": user.token ?? "",
|
||||||
|
"sn_id": serviceRequest.deviceId ?? "",
|
||||||
|
"date": (DateTime.now().millisecondsSinceEpoch).toString(),
|
||||||
|
"client": user.hospital?.id ?? '',
|
||||||
|
"complaint": serviceRequest.maintenanceIssue,
|
||||||
|
"image": json.encode(serviceRequest.devicePhotos),
|
||||||
|
"priority": (serviceRequest.priority?.id).toString(),
|
||||||
|
"defect_types": (serviceRequest.defectType?.id).toString(),
|
||||||
|
};
|
||||||
|
body["audio"] = serviceRequest.audio;
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse(host + URLs.createRequest),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
final serviceRequests = this.serviceRequests;
|
||||||
|
if (serviceRequests != null) {
|
||||||
|
serviceRequests.insert(
|
||||||
|
0,
|
||||||
|
ServiceRequest.fromJson(
|
||||||
|
json.decode(utf8.decode(response.bodyBytes))[0],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> createIssueReport({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required Issue issue,
|
||||||
|
}) async {
|
||||||
|
Response response;
|
||||||
|
Map<String, String> body = issue.toMap();
|
||||||
|
body["uid"] = user.id??"";
|
||||||
|
body["token"] = user.token??"";
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse(host + URLs.createReport),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> updateDate({
|
||||||
|
required String? host,
|
||||||
|
required User? user,
|
||||||
|
required String? newDate,
|
||||||
|
required Lookup? employee,
|
||||||
|
required ServiceRequest? request,
|
||||||
|
}) async {
|
||||||
|
Response response;
|
||||||
|
Map<String, String> body = {};
|
||||||
|
body["uid"] = user?.id ?? '';
|
||||||
|
body["token"] = user?.token ?? '';
|
||||||
|
body["nid"] = request?.id ?? '';
|
||||||
|
body["date"] = newDate ?? '';
|
||||||
|
body["ass_emp"] = employee?.id.toString() ?? '';
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse((host ?? '') + URLs.updateRequestDate),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
request?.engineerName = employee?.label;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> createServiceReport({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required ServiceReport report,
|
||||||
|
required ServiceRequest request,
|
||||||
|
}) async {
|
||||||
|
Response response;
|
||||||
|
Map<String, String> body = report.toMap();
|
||||||
|
body["uid"] = user.id??"";
|
||||||
|
body["token"] = user.token??"";
|
||||||
|
body["job_id"] = request.id ?? '';
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse(host + URLs.createServiceReport),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
reset();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> createDuplicatedReport({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required ServiceRequest request,
|
||||||
|
}) async {
|
||||||
|
Response response;
|
||||||
|
String userData = '';
|
||||||
|
userData += "&uid=${user.id}";
|
||||||
|
userData += "&token=${user.token}";
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await get(
|
||||||
|
Uri.parse(
|
||||||
|
"$host${URLs.createDuplicatedReport}?nid=${request.id}$userData",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
reset();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> updateServiceReport({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required ServiceReport report,
|
||||||
|
required ServiceRequest request,
|
||||||
|
}) async {
|
||||||
|
Response response;
|
||||||
|
Map<String, String> body = report.toMap();
|
||||||
|
body["uid"] = user.id??"";
|
||||||
|
body["token"] = user.token??"";
|
||||||
|
body["job_id"] = request.id ?? '';
|
||||||
|
body["report_id"] = request.reportID ?? '';
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse(host + URLs.updateServiceReport),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
reset();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> updateServiceReportTimer({
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required TimerModel timer,
|
||||||
|
required ServiceRequest request,
|
||||||
|
}) async {
|
||||||
|
Response response;
|
||||||
|
Map<String, String> body = {};
|
||||||
|
body["uid"] = user.id??"";
|
||||||
|
body["token"] = user.token??"";
|
||||||
|
body["job_id"] = request.id ?? '';
|
||||||
|
body["start_time"] = ((timer.startAt?.millisecondsSinceEpoch ?? 0) / 1000)
|
||||||
|
.toStringAsFixed(0);
|
||||||
|
body["end_time"] =
|
||||||
|
((timer.endAt?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
|
||||||
|
body["working_hours"] =
|
||||||
|
((timer.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5);
|
||||||
|
body["report_id"] = request.reportID ?? '';
|
||||||
|
try {
|
||||||
|
response = await post(
|
||||||
|
Uri.parse(host + URLs.updateServiceReport),
|
||||||
|
body: body,
|
||||||
|
);
|
||||||
|
//stateCode = response.statusCode;
|
||||||
|
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
// reset();
|
||||||
|
// notifyListeners();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ServiceReport> getSingleServiceReport({
|
||||||
|
required String reportId,
|
||||||
|
required String host,
|
||||||
|
required User user,
|
||||||
|
required Subtitle subtitle,
|
||||||
|
}) async {
|
||||||
|
String userData = '';
|
||||||
|
userData += "&uid=${user.id}";
|
||||||
|
userData += "&token=${user.token}";
|
||||||
|
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await get(Uri.parse(
|
||||||
|
'$host${URLs.getServiceReport}?report_id=$reportId$userData',
|
||||||
|
));
|
||||||
|
} catch (error) {
|
||||||
|
throw (HttpStatusManger.getStatusMessage(
|
||||||
|
status: -1, subtitle: subtitle) ??
|
||||||
|
'');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the call to the server was successful, parse the JSON.
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
// If the call to the server was successful, parse the JSON.
|
||||||
|
return ServiceReport.fromJson(
|
||||||
|
json.decode(utf8.decode(response.bodyBytes)), reportId);
|
||||||
|
} else {
|
||||||
|
throw (HttpStatusManger.getStatusMessage(
|
||||||
|
status: response.statusCode,
|
||||||
|
subtitle: subtitle,
|
||||||
|
) ??
|
||||||
|
'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue