pentry added.

merge-requests/1/head
Sikander Saleem 3 years ago
parent f2aba4b924
commit 14eceb7ae5

@ -64,7 +64,7 @@
"code": "Code",
"serialNumber": "Serial Number",
"add": "Add",
"brand": "Brand",
"brand": "manufacture",
"clearSearch": "Clear Search",
"closed": "Closed",
"create": "Create",
@ -84,8 +84,8 @@
"facebook": "facebook",
"faultDescription": "Fault Description",
"general": "General",
"hospital": "Client",
"hospitalRequired": "Client Required",
"hospital": "Site",
"hospitalRequired": "Site Required",
"hotLine": "Hot Line",
"jobSheetNumber": "Job Sheet Number",
"linkedIn": "linkedIn",
@ -96,9 +96,9 @@
"nameExist": "Name Exist",
"newServiceRequest": "New Service Request",
"newWord": "New",
"noDateFound": "No Data Found",
"noDeviceFound": "No Device Found",
"noHospitalFound": "No Client Found",
"noDateFound": "No Date Found",
"noDeviceFound": "No Asset Found",
"noHospitalFound": "No Site Found",
"noModelFound": "No Model Found",
"noServiceRequestFound": "No Service Request Found",
"noSnFound": "No SN Found",
@ -106,8 +106,8 @@
"notificationsNotFound": "Notifications Not Found",
"noUniteFound": "No Unit Found",
"ourWebsite": "Our Website",
"pickDevice": "Pick Device",
"pickHospital": "Pick Client",
"pickDevice": "Pick Asset",
"pickHospital": "Pick Site",
"pickUnite": "Pick Unit",
"policy": "Policy",
"reason1": "The engineer didn't confirm visit date with 2 hours from the request time",
@ -169,10 +169,10 @@
"attachImage": "Attach Image",
"callLastSituation": "Call's Last Situation",
"customer": "Customer",
"editServiceReport": "Edit Service Report",
"editServiceReport": "Edit Work Order",
"invoiceCode": "Invoice Code",
"invoiceNumber": "Invoice Number",
"newServiceReport": "New Service Report",
"newServiceReport": "New Work Order",
"number": "Number",
"operatingHours": "Operating Hours",
"partNumber": "Part Number",

@ -37,6 +37,8 @@ class URLs{
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
@ -53,5 +55,13 @@ class URLs{
// 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
}

@ -81,25 +81,25 @@ class DevicesProvider extends ChangeNotifier{
@required String host,
@required User user,
@required String hospitalId,
@required String title}) async {
String serialNumber,
String number,
}) async {
Response response;
try{
response = await get(
Uri.parse(host + URLs.getEquipment+"?client=$hospitalId"
+ ( title == null || title.isEmpty ? "" : "&name=$title" )),
Uri.parse("$host${URLs.getEquipment}?client=$hospitalId"
"${serialNumber?.isEmpty == false ? "&name=$serialNumber" :""}"
"${number?.isEmpty == false ? "&number=$number" : ""}"
),
);
_stateCode = response.statusCode;
List<Device> _page = [];
List<Device> page = [];
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
return _page;
return page;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return [];
}
@ -128,13 +128,10 @@ class DevicesProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
print(categoriesListJson.length);
_page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
print(_page.length);
}
return _page;
} catch(error) {
print(error);
_loading = false;
_stateCode = -1;
notifyListeners();

@ -54,10 +54,6 @@ class GasRefillProvider extends ChangeNotifier{
isLoading = true;
Response response;
try{
print( Uri.parse(
"$host${URLs.getGasRefill}?uid=${user.id}"
"&token=${user.token}&page=${(items?.length ?? 0) ~/pageItemNumber}"
));
response = await get(
Uri.parse(
"$host${URLs.getGasRefill}?uid=${user.id}"
@ -67,7 +63,6 @@ class GasRefillProvider extends ChangeNotifier{
"Content-Type":"application/json; charset=utf-8"
}
);
print(response.body);
stateCode = response.statusCode;
if(stateCode >= 200 && stateCode < 300) {
// client's request was successfully received
@ -87,7 +82,6 @@ class GasRefillProvider extends ChangeNotifier{
return response.statusCode;
} catch(error) {
print(error);
isLoading = false;
stateCode = -1;
notifyListeners();
@ -109,12 +103,11 @@ class GasRefillProvider extends ChangeNotifier{
};
body["details"] = jsonEncode(model.details.map((model) => {
"type": model.type.id.toString(),
"size": model.cylinderSize.id.toString(),
"type": model.type.id?.toString(),
"size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
}).toList());
print(body);
Response response;
try{
response = await post(
@ -123,7 +116,6 @@ class GasRefillProvider extends ChangeNotifier{
body: body,
);
print(response.body);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if(items != null) {
@ -139,7 +131,6 @@ class GasRefillProvider extends ChangeNotifier{
return response.statusCode;
} catch(error) {
print(error);
return -1;
}
@ -165,8 +156,6 @@ class GasRefillProvider extends ChangeNotifier{
"deliverd_qty": model.deliveredQuantity.toString(),
}).toList());
print(body);
print(Uri.parse("$host${URLs.updateGasRefill}/${newModel.id}"),);
Response response;
try{
response = await post(
@ -174,7 +163,6 @@ class GasRefillProvider extends ChangeNotifier{
body: body,
);
print(response.body);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
oldModel.fromGasRefillModel(newModel);
@ -183,7 +171,6 @@ class GasRefillProvider extends ChangeNotifier{
return response.statusCode;
} catch(error) {
print(error);
return -1;
}

@ -55,10 +55,6 @@ class HospitalsProvider extends ChangeNotifier{
notifyListeners();
Response response;
try{
print( Uri.parse(
host + URLs.getHospitals
+ "?page=${(_hospitals?.length ?? 0) ~/pageItemNumber}"
+ ( title == null || title.isEmpty ? "" : "&name=$title" )));
response = await get(
Uri.parse(
host + URLs.getHospitals
@ -96,11 +92,6 @@ class HospitalsProvider extends ChangeNotifier{
}
/// 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<List<Hospital>> getHospitalsList ({String host,User user,String title}) async {
Response response;
try{

@ -110,7 +110,6 @@ class PartsProvider extends ChangeNotifier{
"Content-Type":"application/json; charset=utf-8"
}
);
_stateCode = response.statusCode;
List<Part> _page = [];
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
@ -119,9 +118,6 @@ class PartsProvider extends ChangeNotifier{
}
return _page;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return [];
}

@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart';
@ -76,7 +77,7 @@ class RegularVisitsProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
try{
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<Visit> _visits = requestsListJson.map(
(request) => Visit.fromJson(request)
).toList();
@ -137,5 +138,46 @@ class RegularVisitsProvider extends ChangeNotifier{
}
}
Future<Pentry> getPently({String host,User user,String id}) async {
Response response;
response = await get(
Uri.parse("$host${URLs.getPentry}/$id"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
Pentry pantry;
if(response.statusCode >= 200 && response.statusCode < 300) {
pantry = Pentry.fromMap(json.decode(utf8.decode(response.bodyBytes)));
}
return pantry;
}
Future<int> updatePentry ({
@required String host,
@required User user,
@required Pentry pentry,
@required Visit visit,
}) async {
try{
Response response;
Map<String,String> body = pentry.toMap();
body["uid"] = user.id;
body["token"] = user.token;
response = await post(
Uri.parse(host+URLs.updatePentry + "/${visit.id}"),
body: body,
);
if(response.statusCode >= 200 && response.statusCode < 300) {
visit.status = pentry.ppmVisitStatus;
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
}
}

@ -3,10 +3,10 @@ import 'dart:convert';
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/status.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/models/user.dart';
@ -58,14 +58,6 @@ class ServiceRequestsProvider extends ChangeNotifier{
isLoading = true;
Response response;
try{
print( Uri.parse(
host+URLs.getServiceRequests
+"?uid=${user.id}"
+(hospitalId == null? "" :"&client_nid=$hospitalId")
+"&token=${user.token}"
"&page=${(serviceRequests?.length ?? 0) ~/pageItemNumber}"
+search?.toSearchString() ?? ""
));
response = await get(
Uri.parse(
host+URLs.getServiceRequests
@ -79,7 +71,6 @@ class ServiceRequestsProvider extends ChangeNotifier{
"Content-Type":"application/json; charset=utf-8"
}
);
print(response.body);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
@ -100,7 +91,6 @@ class ServiceRequestsProvider extends ChangeNotifier{
return response.statusCode;
} catch(error) {
print(error);
isLoading = false;
stateCode = -1;
notifyListeners();
@ -161,11 +151,12 @@ class ServiceRequestsProvider extends ChangeNotifier{
"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;
}
print(body);
Response response;
try{
response = await post(
@ -173,7 +164,6 @@ class ServiceRequestsProvider extends ChangeNotifier{
host+URLs.createRequest),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if(serviceRequests != null)
@ -188,7 +178,6 @@ class ServiceRequestsProvider extends ChangeNotifier{
return response.statusCode;
} catch(error) {
print(error);
return -1;
}
@ -225,7 +214,7 @@ class ServiceRequestsProvider extends ChangeNotifier{
@required String host,
@required User user,
@required String newDate,
@required Status employee,
@required Lookup employee,
@required ServiceRequest request,
}) async {
Response response;
@ -235,14 +224,12 @@ class ServiceRequestsProvider extends ChangeNotifier{
body["nid"] = request.id;
if(newDate != null) body["date"] = newDate;
if(employee != null) body["ass_emp"] = employee.id.toString();
print(body);
try{
response = await post(
Uri.parse(
host+URLs.updateRequestDate),
body: body,
);
print(response.body);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
request.engineerName = employee.label;
@ -377,7 +364,6 @@ class ServiceRequestsProvider extends ChangeNotifier{
host+URLs.updateServiceReport),
body: body,
);
print(response.body);
//stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class EmployeesProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _items;
List<Status> get items => _items;
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
@ -57,7 +57,7 @@ class EmployeesProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((type) => Status.fromJson(type)).toList();
_items = categoriesListJson.map((type) => Lookup.fromJson(type)).toList();
}
_loading = false;
notifyListeners();

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -24,8 +24,8 @@ class GasCylinderSizesProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _items;
List<Status> get items => _items;
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
@ -56,7 +56,7 @@ class GasCylinderSizesProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((item) => Status.fromJson(item)).toList();
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
_loading = false;
notifyListeners();

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -24,8 +24,8 @@ class GasStatusProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _items;
List<Status> get items => _items;
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
@ -55,7 +55,7 @@ class GasStatusProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((item) => Status.fromJson(item)).toList();
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
_loading = false;
notifyListeners();

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -24,8 +24,8 @@ class GasTypesProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _items;
List<Status> get items => _items;
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
@ -55,7 +55,7 @@ class GasTypesProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((item) => Status.fromJson(item)).toList();
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
_loading = false;
notifyListeners();

@ -0,0 +1,75 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class PentryStatusProvider extends ChangeNotifier{
//reset provider data
void reset(){
_items = null;
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
/// 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> getData ({String host,User user}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getPentryStatus),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -0,0 +1,75 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class PentryTaskStatusProvider extends ChangeNotifier{
//reset provider data
void reset(){
_items = null;
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
/// 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> getData ({String host,User user}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getPentryTaskStatus),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -0,0 +1,74 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class PentryVisitStatusProvider extends ChangeNotifier{
//reset provider data
void reset(){
_items = null;
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
/// 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> getData ({String host,User user}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getPentryVisitStatus),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -0,0 +1,75 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class ServiceRequestDefectTypesProvider extends ChangeNotifier{
//reset provider data
void reset(){
_items = null;
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
/// 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> getData ({String host,User user}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportDefectTypes),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -24,8 +24,8 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _calls;
List<Status> get calls => _calls;
List<Lookup> _calls;
List<Lookup> get calls => _calls;
// when categories in-process _loading = true
// done _loading = true
@ -59,7 +59,7 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_calls = categoriesListJson.map((type) => Status.fromServiceReportJson(type)).toList();
_calls = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();

@ -0,0 +1,74 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class ServiceRequestPriorityProvider extends ChangeNotifier{
//reset provider data
void reset(){
_items = null;
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
/// 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> getData ({String host,User user}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportPriority),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _reasons;
List<Status> get reasons => _reasons;
List<Lookup> _reasons;
List<Lookup> get reasons => _reasons;
// when categories in-process _loading = true
// done _loading = true
@ -56,7 +56,7 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_reasons = categoriesListJson.map((type) => Status.fromServiceReportJson(type)).toList();
_reasons = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class ServiceReportStatusProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _status;
List<Status> get statuses => _status;
List<Lookup> _status;
List<Lookup> get statuses => _status;
// when categories in-process _loading = true
// done _loading = true
@ -56,7 +56,7 @@ class ServiceReportStatusProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_status = categoriesListJson.map((type) => Status.fromServiceReportJson(type)).toList();
_status = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class ServiceReportTypesProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _types;
List<Status> get types => _types;
List<Lookup> _types;
List<Lookup> get types => _types;
// when categories in-process _loading = true
// done _loading = true
@ -57,7 +57,7 @@ class ServiceReportTypesProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_types = categoriesListJson.map((type) => Status.fromServiceReportJson(type)).toList();
_types = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
}
_loading = false;
notifyListeners();

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class ServiceStatusProvider extends ChangeNotifier{
// contain user data
// when user not login or register _user = null
List<Status> _statuses;
List<Status> get statuses => _statuses;
List<Lookup> _statuses;
List<Lookup> get statuses => _statuses;
// when categories in-process _loading = true
// done _loading = true
@ -57,7 +57,7 @@ class ServiceStatusProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_statuses = categoriesListJson.map((e) => Status.fromServiceReportJson(e)).toList();
_statuses = categoriesListJson.map((e) => Lookup.fromIntIdJson(e)).toList();
}
_loading = false;

@ -14,6 +14,10 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/employee/empl
import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_cylinder_size_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_status_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/status_drop_down/pentry/pentry_task_status_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/status_drop_down/report/service_report_defect_types_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/pages/login.dart';
import 'package:test_sa/views/pages/register.dart';
@ -36,6 +40,7 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
import 'controllers/providers/api/parts_provider.dart';
import 'controllers/providers/api/preventive_maintenance_visits_provider.dart';
import 'controllers/providers/api/status_drop_down/pentry/pentry_status_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_report_reasons_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_report_status_provider.dart';
@ -91,6 +96,11 @@ class MyApp extends StatelessWidget {
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: GestureDetector(
onTap: () {

@ -1,6 +1,7 @@
class Device{
String id;
String serialNumber;
String number;
String brand;
String model;
DateTime productionDate;
@ -13,6 +14,7 @@ class Device{
Device({
this.id,
this.serialNumber,
this.number,
this.brand,
this.model,
this.productionDate,
@ -27,6 +29,7 @@ class Device{
return Device(
id: parsedJson["nid"] ?? parsedJson["id"],
serialNumber: parsedJson["sn"] ?? parsedJson["value"],
number: parsedJson["asset_no"],
brand: parsedJson["brand"].toString(),
model: parsedJson["model"].toString(),
productionDate: getDateFromString(parsedJson["production_date"]),
@ -42,6 +45,7 @@ class Device{
return Device(
id: device.id,
serialNumber: device.serialNumber,
number: device.number,
brand: device.brand,
model: device.model,
productionDate: device.productionDate,

@ -3,7 +3,7 @@ import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
class DeviceTransfer{
String id;

@ -2,7 +2,7 @@ import 'package:http/http.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
class DeviceTransferInfo{
String userId;
@ -13,7 +13,7 @@ class DeviceTransferInfo{
String travelingHours;
String name;
String signature;
Status status;
Lookup status;
DeviceTransferInfo({
this.userId,
@ -67,7 +67,7 @@ class DeviceTransferInfo{
comment: parsedJson["${key}comment"],
client: Hospital.fromJson(parsedJson["${key}client"]),
department: Department.fromJson(parsedJson["${key}department"]),
status: Status.fromJson(parsedJson["${key}status"]),
status: Lookup.fromJson(parsedJson["${key}status"]),
);
}
}

@ -1,8 +1,8 @@
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
class GasRefillDetails{
Status type;
Status cylinderSize;
Lookup type;
Lookup cylinderSize;
int requestedQuantity;
int deliveredQuantity;
@ -21,9 +21,9 @@ class GasRefillDetails{
}
factory GasRefillDetails.fromJson(Map<String,dynamic> parsedJson){
return GasRefillDetails(
type: Status.fromJson(parsedJson["type"]),
type: Lookup.fromJson(parsedJson["type"]),
cylinderSize: Status.fromJson(parsedJson["size"]),
cylinderSize: Lookup.fromJson(parsedJson["size"]),
requestedQuantity: parsedJson["requsted_qty"] == null
? 0 : int.tryParse(parsedJson["requsted_qty"].toString()) ?? 0,
deliveredQuantity: parsedJson["deliverd_qty"] == null
@ -33,8 +33,8 @@ class GasRefillDetails{
factory GasRefillDetails.fromDetails(GasRefillDetails details){
return GasRefillDetails(
type: Status.fromStatus(details.type),
cylinderSize:Status.fromStatus(details.cylinderSize),
type: Lookup.fromStatus(details.type),
cylinderSize:Lookup.fromStatus(details.cylinderSize),
requestedQuantity: details.requestedQuantity,
deliveredQuantity: details.deliveredQuantity,
);

@ -1,12 +1,12 @@
import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
class GasRefillModel{
String id;
String userId;
String clientName;
String title;
Status status;
Lookup status;
List<GasRefillDetails> details;
GasRefillModel({
@ -30,7 +30,7 @@ class GasRefillModel{
userId = model.userId;
clientName = model.clientName;
title = model.title;
status = Status.fromStatus(model.status);
status = Lookup.fromStatus(model.status);
details = model.details.map((e) => GasRefillDetails.fromDetails(e)).toList();
}
@ -45,7 +45,7 @@ class GasRefillModel{
userId: parsedJson["uid"],
title: parsedJson["title"],
clientName: parsedJson["client"],
status: Status.fromJson(parsedJson["status"]),
status: Lookup.fromJson(parsedJson["status"]),
details: details,
);
}

@ -1,10 +1,10 @@
class Status{
class Lookup{
final String label;
final String key;
final int id;
const Status({
const Lookup({
this.label,
this.key,
this.id,
@ -12,7 +12,7 @@ class Status{
@override
bool operator == (Object other) =>
identical(this, other) || other is Status &&
identical(this, other) || other is Lookup &&
key == other.key &&
id == other.id;
@ -20,17 +20,17 @@ class Status{
@override
int get hashCode => id.hashCode;
factory Status.fromStatus(Status old){
return Status(
factory Lookup.fromStatus(Lookup old){
return Lookup(
label: old.label,
id: old.id,
key: old.key,
);
}
factory Status.fromJson(Map<String,dynamic> parsedJson){
factory Lookup.fromJson(Map<String,dynamic> parsedJson){
if(parsedJson["id"] == null && parsedJson["uid"] == null) return null;
return Status(
return Lookup(
label: parsedJson["value"],
id: parsedJson["id"] is int
? parsedJson["id"]
@ -38,8 +38,8 @@ class Status{
);
}
factory Status.fromServiceReportJson(Map<String,dynamic> parsedJson){
return Status(
factory Lookup.fromIntIdJson(Map<String,dynamic> parsedJson){
return Lookup(
label: parsedJson["value"],
id: parsedJson["id"],
);

@ -0,0 +1,26 @@
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),
);
}
}

@ -0,0 +1,41 @@
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,
);
}
}

@ -0,0 +1,15 @@
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"],
);
}
}

@ -0,0 +1,15 @@
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"],
);
}
}

@ -0,0 +1,121 @@
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/contact.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);
}
}

@ -0,0 +1,45 @@
import 'package:test_sa/models/lookup.dart';
class PMKit{
Lookup itemCode;
String itemName;
String preparationTimeFrame;
String kitFrequencyDemand;
String availability;
String quantityNeeded;
String quantityReserved;
PMKit({
this.itemCode,
this.itemName,
this.preparationTimeFrame,
this.kitFrequencyDemand,
this.availability,
this.quantityNeeded,
this.quantityReserved
});
Map<String, String> toMap() {
return {
if(itemCode != null) 'itemCode': (itemCode?.id).toString(),
if(itemName != null) 'itemName': itemName,
if(preparationTimeFrame != null) 'preparationTimeFrame': preparationTimeFrame,
if(kitFrequencyDemand != null) 'kitFrequencyDemand': kitFrequencyDemand,
if(availability != null) 'availability': availability,
if(quantityNeeded != null) 'quantityNeeded': quantityNeeded,
if(quantityReserved != null) 'quantityReserved': quantityReserved,
};
}
factory PMKit.fromMap(Map<String, dynamic> map) {
return PMKit(
itemCode: Lookup.fromJson(map['itemCode']),
itemName: map['itemName'] as String,
preparationTimeFrame: map['preparationTimeFrame'] as String,
kitFrequencyDemand: map['kitFrequencyDemand'] as String,
availability: map['availability'] as String,
quantityNeeded: map['quantityNeeded'] as String,
quantityReserved: map['quantityReserved'] as String,
);
}
}

@ -0,0 +1,33 @@
import 'package:test_sa/models/lookup.dart';
class PPMCheckList{
Lookup status;
String title;
String comment;
String measuredValue;
PPMCheckList({
this.title,
this.status,
this.comment,
this.measuredValue,
});
Map<String, String> toMap() {
return {
if(status != null) 'status': status?.id.toString(),
if(title != null) 'title': title,
if(comment != null) 'comment': comment,
if(measuredValue != null) 'measuredValue': measuredValue,
};
}
factory PPMCheckList.fromMap(Map<String, dynamic> map) {
return PPMCheckList(
status: Lookup.fromJson(map['status']),
title: map['title'] as String,
comment: map['comment'] as String,
measuredValue: map['measuredValue'] as String,
);
}
}

@ -2,7 +2,7 @@ import 'dart:convert';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/timer_model.dart';
class ServiceReport {
@ -10,11 +10,11 @@ class ServiceReport {
String operatingHours;
DateTime visitDate;
DateTime endDate;
Status serviceType;
Status callLastSituation;
Status status;
Status type;
Status reason;
Lookup serviceType;
Lookup callLastSituation;
Lookup status;
Lookup type;
Lookup reason;
String faultDescription;
String workPreformed;
//String workHours;
@ -90,7 +90,6 @@ class ServiceReport {
}
bool validate(){
if(visitDate == null) return false;
if(serviceType == null) return false;
if(status == null) return false;
@ -120,11 +119,11 @@ class ServiceReport {
}
return ServiceReport(
id: id,
serviceType: Status.fromJson(parsedJson["service_type"]),
callLastSituation: Status.fromJson(parsedJson["call_last_situtation"]),
reason: Status.fromJson(parsedJson["reasons"]),
status: Status.fromJson(parsedJson["service_report_status"]),
type: Status.fromJson(parsedJson["service_report_type"]),
serviceType: Lookup.fromJson(parsedJson["service_type"]),
callLastSituation: Lookup.fromJson(parsedJson["call_last_situtation"]),
reason: Lookup.fromJson(parsedJson["reasons"]),
status: Lookup.fromJson(parsedJson["service_report_status"]),
type: Lookup.fromJson(parsedJson["service_report_type"]),
faultDescription: parsedJson["fault_description"],
endDate:getDate(parsedJson["end_date"]),
invoiceCode: parsedJson["invoice_code"],

@ -1,3 +1,5 @@
import 'package:test_sa/models/lookup.dart';
import '../timer_model.dart';
class ServiceRequest{
@ -27,6 +29,9 @@ class ServiceRequest{
DateTime nextVisitDate;
String jobSheetNumber;
String reportID;
String deviceNumber;
Lookup priority;
Lookup defectType;
ServiceRequest({
this.id,
@ -55,6 +60,9 @@ class ServiceRequest{
this.nextVisitDate,
this.workPerformed,
this.reportID,
this.defectType,
this.priority,
this.deviceNumber,
});
@ -63,6 +71,7 @@ class ServiceRequest{
id: parsedJson["nid"],
requestCode: parsedJson["call_id"] ?? parsedJson["jobcode"] ,
hospitalName: parsedJson["call_client"],
deviceNumber: parsedJson["device_no"],
deviceId: parsedJson["deviceid"],
audio: parsedJson["audio"] ?? "",
deviceArName: parsedJson["equipment_arabic_name"] == false

@ -3,13 +3,12 @@ import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/hospital.dart';
class User{
class User {
String id;
String userName;
String password;
String email;
String image;
String hospitalID;
Hospital hospital;
Department department;
UsersTypes type;
@ -18,9 +17,8 @@ class User{
String token;
bool isActive;
User({
this.id,
User(
{this.id,
this.userName = "",
this.email = "",
this.password = "",
@ -31,80 +29,74 @@ class User{
this.type,
this.whatsApp,
this.token,
this.isActive = false
});
this.isActive = false});
Future<Map<String, dynamic>> toLoginJson() async {
if(FirebaseNotificationManger.token == null)
await FirebaseNotificationManger.getToken();
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
return {
"username":userName,
"pass":password,
"username": userName,
"pass": password,
"firebase_token": FirebaseNotificationManger?.token ?? "",
};
}
Map<String,dynamic> toUpdateProfileJson(){
Map<String,dynamic> jsonObject ={};
if(department?.id != null && department.id.isNotEmpty)
jsonObject["department"] = department.id;
if(whatsApp != null && whatsApp.isNotEmpty)
jsonObject["whatsapp"] = whatsApp;
if(phoneNumber != null && phoneNumber.isNotEmpty)
jsonObject["phone"] = phoneNumber;
Map<String, dynamic> toUpdateProfileJson() {
Map<String, dynamic> jsonObject = {};
if (department?.id != null && department.id.isNotEmpty) jsonObject["department"] = department.id;
if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp;
if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber;
return jsonObject;
}
Future<Map<String, dynamic>> toRegisterJson() async {
if(FirebaseNotificationManger.token == null)
await FirebaseNotificationManger.getToken();
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
return {
"username": userName,
"email":email,
"whatsapp":whatsApp,
"client":hospital.id,
"department":department?.id,
"phone":phoneNumber,
"pass":password,
"email": email,
"whatsapp": whatsApp,
"client": hospital.id,
"department": department?.id,
"phone": phoneNumber,
"pass": password,
"firebase_token": FirebaseNotificationManger?.token ?? "",
};
}
Map<String,dynamic> toJson(){
Map<String, dynamic> toJson() {
return {
"uid":id,
"uid": id,
"name": userName,
"email":email,
"token":token,
"phone":phoneNumber,
"whatsapp":whatsApp,
"client":hospital?.id,
"client_name":hospital?.name,
"department":department?.id,
"department_name":department?.name,
"password":password,
"picture":image,
"active":isActive ? 1 : 0,
"role": type == UsersTypes.engineer
? "field_engineer" : "normal_user" ,
"email": email,
"token": token,
"phone": phoneNumber,
"whatsapp": whatsApp,
"client": hospital?.id,
"client_name": hospital?.name,
"department": department?.id,
"department_name": department?.name,
"password": password,
"picture": image,
"active": isActive ? 1 : 0,
"role": type == UsersTypes.engineer ? "field_engineer" : "normal_user",
// "token":token, pass is token
};
}
factory User.fromJson(Map<String,dynamic> parsedJson){
factory User.fromJson(Map<String, dynamic> parsedJson) {
UsersTypes type;
switch(parsedJson["role"]){
case "field_engineer": type = UsersTypes.engineer; break;
default: type = UsersTypes.normal_user; break;
switch (parsedJson["role"]) {
case "field_engineer":
type = UsersTypes.engineer;
break;
default:
type = UsersTypes.normal_user;
break;
}
return User(
id: parsedJson["uid"],
userName: parsedJson["name"] ?? parsedJson["title"],
email: parsedJson["mail"] ?? parsedJson["email"],
hospital: Hospital(
id: parsedJson["client"],
name: parsedJson["client_name"]
),
hospital: Hospital(id: parsedJson["client"], name: parsedJson["client_name"]),
department: Department(
id: parsedJson["department"],
name: parsedJson["department_name"],
@ -114,7 +106,6 @@ class User{
whatsApp: parsedJson["whatsapp"],
token: parsedJson["token"],
isActive: parsedJson["active"] == "1",
type:type
);
type: type);
}
}

@ -1,4 +1,4 @@
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/timer_model.dart';
class Visit{
@ -16,8 +16,9 @@ class Visit{
String employName;
String modelAndBrand;
String contactStatus;
Status status;
Lookup status;
String assignTo;
String deviceNumber;
List<String> images;
Visit({
@ -38,6 +39,7 @@ class Visit{
this.contactStatus,
this.images,
this.assignTo,
this.deviceNumber,
});
factory Visit.fromJson(Map<String,dynamic> parsedJson){
@ -45,6 +47,7 @@ class Visit{
id: parsedJson["nid"],
serialNumber: parsedJson["title"],
hospitalId: parsedJson["client"],
deviceNumber: parsedJson["device_no"],
hospitalName: parsedJson["client_name"],
deviceId: parsedJson["medical_equipment_nid"],
deviceSerialNumber: parsedJson["medical_equipment"],
@ -57,7 +60,7 @@ class Visit{
modelAndBrand: parsedJson["mode_brand"],
contactStatus: parsedJson["contactStatus"],
images: List<String>.from(parsedJson["images"] ?? []),
status: Status(
status: Lookup(
id: int.tryParse(parsedJson["status"] ?? "-1"), // actual value (0,1,2)
label: parsedJson["status_value"] // text value
),

@ -1,5 +1,5 @@
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/visits/visit.dart';
class VisitsGroup{
@ -8,8 +8,8 @@ class VisitsGroup{
String travelingHours;
String jobSheetNumber;
String image;
Status status;
Status taskStatus;
Lookup status;
Lookup taskStatus;
DateTime date;
List<Visit> visits;

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
class AColors {
AColors._();
static const Color white = Color(0xffffffff);

@ -65,7 +65,7 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage>
Expanded(
child: Center(
child: Text(
_subtitle.serviceRequests,
"Device Transfer",
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.white,
fontStyle: FontStyle.italic

@ -279,8 +279,8 @@ class _LandPageState extends State<LandPage> {
padding: EdgeInsets.all(4),
decoration: BoxDecoration(border: Border.all(color: Theme.of(context).primaryColor, width: 2), shape: BoxShape.circle),
child: ClipOval(
child: ImageLoader(
url: "https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png",
child: ClipOval(
child: Icon(Icons.person,size: 72,color: Theme.of(context).colorScheme.primary,),
),
),
),
@ -345,27 +345,27 @@ class _LandPageState extends State<LandPage> {
launch("mailto:customerservice@Test SA.com");
},
),
DrawerItem(
icon: Icons.phone_in_talk,
title: "${_subtitle.hotLine} 15564",
onPressed: () {
launch("tel:15564");
},
),
DrawerItem(
icon: FontAwesomeIcons.linkedinIn,
title: _subtitle.linkedIn,
onPressed: () {
launch("https://www.linkedin.com/company/Test SA/");
},
),
DrawerItem(
icon: FontAwesomeIcons.globe,
title: _subtitle.ourWebsite,
onPressed: () {
launch("https://www.Test SA.com/");
},
),
// DrawerItem(
// icon: Icons.phone_in_talk,
// title: "${_subtitle.hotLine} 15564",
// onPressed: () {
// launch("tel:15564");
// },
// ),
// DrawerItem(
// icon: FontAwesomeIcons.linkedinIn,
// title: _subtitle.linkedIn,
// onPressed: () {
// launch("https://www.linkedin.com/company/Test SA/");
// },
// ),
// DrawerItem(
// icon: FontAwesomeIcons.globe,
// title: _subtitle.ourWebsite,
// onPressed: () {
// launch("https://www.Test SA.com/");
// },
// ),
DrawerItem(
icon: Icons.share,
title: _subtitle.shareApp,

@ -25,6 +25,9 @@ import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/sound/record_sound.dart';
import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_priority_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
class CreateRequestPage extends StatefulWidget {
static final String id = "/create-request";
@ -111,7 +114,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound,
hintText: _subtitle.hospital,
prefixIconData: FontAwesomeIcons.hospital,
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.subtitle1,
),
12.height,
_userProvider.user.department == null
@ -121,7 +124,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
initialValue: _userProvider.user.department?.name ?? _subtitle.noUniteFound,
hintText: _subtitle.unite,
prefixIconData: FontAwesomeIcons.hospitalUser,
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.subtitle1,
),
12.height,
DeviceButton(
@ -131,6 +134,24 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
setState(() {});
},
),
const SizedBox(height: 8,),
const ASubTitle("Priority"),
const SizedBox(height: 4,),
ServiceRequestPriorityMenu(
initialValue: _serviceRequest.priority,
onSelect: (status){
_serviceRequest.priority = status;
},
),
const SizedBox(height: 8,),
const ASubTitle("Defect Type"),
const SizedBox(height: 4,),
ServiceRequestDefectTypesMenu(
initialValue: _serviceRequest.defectType,
onSelect: (status){
_serviceRequest.defectType = status;
},
),
12.height,
MultiImagesPicker(
label: _subtitle.deviceImages,

@ -12,7 +12,7 @@ import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
@ -68,7 +68,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
void initState() {
_serviceReport = ServiceReport(
visitDate: DateTime.now(),
type: const Status(id: 2),
type: const Lookup(id: 2),
device: Device(
id: widget.request.deviceId,
serialNumber: widget.request.deviceSerialNumber,
@ -159,25 +159,25 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
Row(
children: [
// Report Status
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.reportType),
_validate && _serviceReport.type == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
const SizedBox.shrink(),
const SizedBox(height: 4,),
ServiceReportTypeMenu(
initialValue: _serviceReport.type,
onSelect: (status){
_serviceReport.type = status;
},
),
],
),
),
const SizedBox(width: 8,),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// ASubTitle(_subtitle.reportType),
// _validate && _serviceReport.type == null ?
// ASubTitle(_subtitle.requiredWord,color: Colors.red,):
// const SizedBox.shrink(),
// const SizedBox(height: 4,),
// ServiceReportTypeMenu(
// initialValue: _serviceReport.type,
// onSelect: (status){
// _serviceReport.type = status;
// },
// ),
// ],
// ),
// ),
// const SizedBox(width: 8,),
// visit date
Expanded(
child: Column(
@ -490,9 +490,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
textAlign: TextAlign.center,
hintText: "i.e 3, 3.5, 4",
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.isNumeric(value)
? null : _subtitle.requiredWord,
// validator: (value) =>
// Validator.isNumeric(value)
// ? null : _subtitle.requiredWord,
textInputType: TextInputType.number,
onSaved: (value){
_serviceReport.travelingHours = value;
@ -507,29 +507,29 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// Operating Hours and Job Sheet Number
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.operatingHours),
const SizedBox(height: 4,),
ATextFormField(
initialValue: _serviceReport?.operatingHours,
textAlign: TextAlign.center,
hintText: "i.e 3, 3.5, 4",
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.isNumeric(value)
? null : _subtitle.requiredWord,
textInputType: TextInputType.number,
onSaved: (value){
_serviceReport.operatingHours = value;
},
),
],
),
),
const SizedBox(width: 8,),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// ASubTitle(_subtitle.operatingHours),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: _serviceReport?.operatingHours,
// textAlign: TextAlign.center,
// hintText: "i.e 3, 3.5, 4",
// style: Theme.of(context).textTheme.subtitle1,
// validator: (value) =>
// Validator.isNumeric(value)
// ? null : _subtitle.requiredWord,
// textInputType: TextInputType.number,
// onSaved: (value){
// _serviceReport.operatingHours = value;
// },
// ),
// ],
// ),
// ),
// const SizedBox(width: 8,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,

@ -12,7 +12,7 @@ import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';

@ -182,6 +182,10 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.code,
info: serviceRequest.requestCode,
),
RequestInfoRow(
title: "Asset Number",
info: serviceRequest.deviceNumber,
),
RequestInfoRow(
title: _subtitle.deviceSN,
info: serviceRequest.deviceSerialNumber,
@ -230,10 +234,10 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.unite,
info: serviceRequest.departmentName,
),
RequestInfoRow(
title: _subtitle.deviceArName,
content: serviceRequest.deviceArName,
),
// RequestInfoRow(
// title: _subtitle.deviceArName,
// content: serviceRequest.deviceArName,
// ),
RequestInfoRow(
title: _subtitle.deviceEnName,
content: serviceRequest.deviceEnName,

@ -0,0 +1,187 @@
import 'package:flutter/material.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/regular_visits_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/pantry/pentry.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/pentry/pentry_calibration_tool_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_info_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_pm_kit_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_ppm_check_list_form.dart';
class EditPentry extends StatefulWidget {
final Pentry pentry;
final Visit visit;
const EditPentry({Key key,this.pentry, this.visit}) : super(key: key);
@override
State<EditPentry> createState() => _EditPentryState();
}
class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateMixin{
bool _isLoading = false;
bool _validate = false;
Subtitle _subtitle;
UserProvider _userProvider;
SettingProvider _settingProvider;
RegularVisitsProvider _regularVisitsProvider;
Pentry _pentry;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _tabController;
_onSubmit() async {
_validate = true;
if(!_pentry.validate()) {
setState(() { });
return;
}
_isLoading = true;
setState(() {});
int status = await _regularVisitsProvider.updatePentry(
user: _userProvider.user,
host: _settingProvider.host,
pentry: _pentry,
visit: widget.visit
);
_isLoading =false;
setState(() {});
if(status >= 200 && status < 300){
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
);
// Navigator.of(context).pop();
}else{
String errorMessage = HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
Fluttertoast.showToast(
msg: errorMessage,
);
}
}
@override
void initState() {
_pentry = widget.pentry;
_tabController = TabController(length: 4, vsync: this);
super.initState();
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Column(
children: [
Material(
color: Theme.of(context).colorScheme.primary,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: TabBar(
controller: _tabController,
isScrollable: true,
onTap: (index){
setState(() {});
},
tabs: const [
Tab(text: "PPM Check List",),
Tab(text: "Calibration Tools",),
Tab(text: "PK Kits",),
Tab(text: "Pentry",),
]),
),
),
Expanded(
child: Stack(
children: [
TabBarView(
physics: const NeverScrollableScrollPhysics(),
controller: _tabController,
children: [
PentryPPMCheckListForm(
models: _pentry.ppmCheckLists,
enableValidate: _validate,
),
PentryCalibrationToolForm(
models: _pentry.calibrationTools,
enableValidate: _validate,
),
PentryPMKitForm(
models: _pentry.pmKits,
enableValidate: _validate,
),
PentryInfoForm(
model: _pentry,
enableValidate: _validate,
)
],
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
if(_tabController.index != 0)
ASmallButton(
text: _subtitle.back,
onPressed: (){
_tabController.animateTo(_tabController.index - 1,);
setState(() {});
},
),
const Spacer(),
if(_tabController.index != _tabController.length -1)
ASmallButton(
text: _subtitle.next,
onPressed: (){
_tabController.animateTo(_tabController.index + 1,);
setState(() {});
},
),
if(_tabController.index == _tabController.length -1)
ASmallButton(
text: _subtitle.update,
onPressed: _onSubmit,
),
],
),
),
)
],
),
),
],
)
),
),
);
}
}

@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/regular_visits_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/pantry/pentry.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/pages/user/visits/pantry/edit_pentry.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/failed_loading.dart';
class FutureEditPentry extends StatefulWidget {
final Visit visit;
const FutureEditPentry({Key key, this.visit}) : super(key: key);
@override
State<FutureEditPentry> createState() => _FutureEditPentryState();
}
class _FutureEditPentryState extends State<FutureEditPentry> {
UserProvider _userProvider;
SettingProvider _settingProvider;
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
//String requestId = ModalRoute.of(context).settings.arguments;
Subtitle subtitle = AppLocalization.of(context).subtitle;
return Scaffold(
body: FutureBuilder<Pentry>(
future: RegularVisitsProvider().getPently(
user: _userProvider.user,
host: _settingProvider.host,
id: widget.visit.id
),
builder: (BuildContext context, AsyncSnapshot<Pentry> snapshot){
if(snapshot.hasError) {
return FailedLoading(
message: subtitle.failedToCompleteRequest,
onReload: (){setState(() {});},
);
}
if(snapshot.hasData){
return EditPentry(
pentry: snapshot.data,
visit: widget.visit,
);
}
return const Center(child: ALoading());
},
),
);
}
}

@ -2,7 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart';
@ -26,15 +26,15 @@ class UpdateVisitsGroupSheet extends StatefulWidget {
}
class _UpdateVisitsGroupSheetState extends State<UpdateVisitsGroupSheet> {
List<Status> status = [
Status(label: "Done", id: 0,),
Status(label: "Not Yet", id: 1),
Status(label: "On Hold", id: 2,),
List<Lookup> status = [
Lookup(label: "Done", id: 0,),
Lookup(label: "Not Yet", id: 1),
Lookup(label: "On Hold", id: 2,),
];
List<Status> taskStatus = [
Status(label: "Passed", id: 0,),
Status(label: "Failed", id: 1),
List<Lookup> taskStatus = [
Lookup(label: "Passed", id: 0,),
Lookup(label: "Failed", id: 1),
];
VisitsGroup _group = VisitsGroup();
File _image;

@ -1,15 +1,21 @@
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.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';
import 'package:test_sa/views/pages/user/visits/pantry/future_edit_pently.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/images/images_list.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/visits/visit_status.dart';
import 'package:flutter/material.dart';
import '../../../../controllers/providers/api/regular_visits_provider.dart';
class VisitDetailsPage extends StatelessWidget {
static final String id = "/visit-details";
final Visit visit;
@ -18,6 +24,8 @@ class VisitDetailsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
final regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
return Scaffold(
body: SafeArea(
child: Column(
@ -39,7 +47,18 @@ class VisitDetailsPage extends StatelessWidget {
),
),
),
SizedBox(width: 42,)
AIconButton(
iconData: Icons.edit,
color: AColors.white,
buttonSize: 42,
backgroundColor: AColors.green,
onPressed: () async {
Navigator.of(context).push(
MaterialPageRoute(builder: (_)=> FutureEditPentry(visit: visit,))
);
},
),
SizedBox(width: 16,)
],
),
),
@ -87,6 +106,10 @@ class VisitDetailsPage extends StatelessWidget {
title: _subtitle.code,
info: visit.serialNumber,
),
RequestInfoRow(
title: "Asset Number",
info: visit.deviceNumber,
),
RequestInfoRow(
title: _subtitle.deviceSN,
info: visit.deviceSerialNumber,

@ -14,13 +14,13 @@ class ADatePicker extends StatelessWidget {
Widget build(BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
textStyle: Theme.of(context).textTheme.subtitle2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
12 * AppStyle.getScaleFactor(context)
)
),
primary: AColors.white,
onPrimary: AColors.primaryColor,
),
),
child: Text(
date == null ? "Pick Date" :

@ -43,20 +43,8 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<DevicesProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle;
return LoadingManager(
isLoading: _devicesProvider.isLoading,
isFailedLoading: _devicesProvider.devices == null,
stateCode: _devicesProvider.stateCode,
onRefresh: () async {
_devicesProvider.reset();
await _devicesProvider.getEquipment(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId
);
},
child: Container(
padding: EdgeInsets.symmetric(
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 16
),
decoration: BoxDecoration(
@ -74,7 +62,7 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
style: Theme.of(context).textTheme.headline6,
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
decoration: const InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
@ -82,12 +70,12 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
),
textInputAction: TextInputAction.search,
),
suggestionsCallback: (vale) async {
suggestionsCallback: (value) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
title: vale,
serialNumber: value,
);
},
itemBuilder: (context, device) {
@ -101,7 +89,6 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
widget.onPick(device.id);
},
),
),
);
}
}

@ -88,12 +88,14 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
},
child: Column(
children: [
SizedBox(height: 48,),
const SizedBox(height: 48),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16),
child: ATextFormField(
child: Column(
children: [
ATextFormField(
hintText: _subtitle.searchBySn,
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.subtitle1,
suffixIcon: const Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
@ -105,6 +107,23 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
setState(() {});
},
),
const SizedBox(height: 8,),
ATextFormField(
hintText: "Search by Number",
style: Theme.of(context).textTheme.subtitle1,
suffixIcon: const Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_devicesProvider.devices.where(
(element) => element.number.toLowerCase().contains(
value.toLowerCase()
)
).toList());
setState(() {});
},
),
],
),
),
Expanded(
child: _searchableList.isEmpty ?

@ -10,18 +10,18 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_item.dart';
class AutoCompleteField extends StatefulWidget {
class HospitalAutoCompleteField extends StatefulWidget {
final String initialValue;
final Function(String) onSearch;
final Function(String) onSave;
const AutoCompleteField({Key key, this.onSearch, this.initialValue, this.onSave}) : super(key: key);
const HospitalAutoCompleteField({Key key, this.onSearch, this.initialValue, this.onSave}) : super(key: key);
@override
_AutoCompleteFieldState createState() => _AutoCompleteFieldState();
_HospitalAutoCompleteFieldState createState() => _HospitalAutoCompleteFieldState();
}
class _AutoCompleteFieldState extends State<AutoCompleteField> {
class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
SettingProvider _settingProvider;
TextEditingController _controller;

@ -70,7 +70,8 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
)
),
primary: Colors.grey[200],
//primary: Colors.grey[200],
textStyle: Theme.of(context).textTheme.overline,
padding: _image == null ? null : EdgeInsets.zero,
),
@ -78,7 +79,6 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
padding: const EdgeInsets.all(8.0),
child: Text(
_image == null ? _subtitle.pickImage : _image.path.split("/").last,
style: Theme.of(context).textTheme.overline,
textScaleFactor: AppStyle.getScaleFactor(context),
),
),

@ -50,7 +50,7 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
child: Text(
widget.label ?? _subtitle.images,
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 16,
fontSize: 14,
),
textScaleFactor: AppStyle.getScaleFactor(context),
),

@ -11,8 +11,9 @@ import 'package:provider/provider.dart';
class AutoCompletePartsField extends StatefulWidget {
final String initialValue;
final Function(Part) onPick;
final bool clearAfterPick;
const AutoCompletePartsField({Key key, this.initialValue, this.onPick}) : super(key: key);
const AutoCompletePartsField({Key key, this.initialValue, this.onPick, this.clearAfterPick = true}) : super(key: key);
@override
_AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState();
@ -54,7 +55,7 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
);
},
child: Container(
padding: EdgeInsets.symmetric(
padding: const EdgeInsets.symmetric(
horizontal: 16
),
decoration: BoxDecoration(
@ -63,7 +64,7 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
boxShadow: [
boxShadow: const [
AppStyle.boxShadow
]
),
@ -72,7 +73,7 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
style: Theme.of(context).textTheme.subtitle1,
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
decoration: const InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
@ -93,7 +94,11 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
);
},
onSuggestionSelected: (part) {
if(widget.clearAfterPick){
_controller.clear();
} else{
_controller.text = part.code;
}
widget.onPick(part);
},
),

@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_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/device/device.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 AutoCompleteDeviceNumberField extends StatefulWidget {
final Lookup initialValue;
final String hospitalId;
final Function(Lookup) onPick;
const AutoCompleteDeviceNumberField({Key key, this.initialValue, this.onPick, this.hospitalId}) : super(key: key);
@override
State<AutoCompleteDeviceNumberField> createState() => _AutoCompleteDeviceNumberFieldState();
}
class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumberField> {
SettingProvider _settingProvider;
DevicesProvider _devicesProvider;
UserProvider _userProvider;
TextEditingController _controller;
@override
void initState() {
_controller = TextEditingController(text: widget.initialValue?.label);
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<DevicesProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle;
return 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<Device>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
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) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
number: vale,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.number),
subtitle: Text("${device.model}/${device.brand}"),
);
},
onSuggestionSelected: (device) {
_controller.text = device.number;
widget.onPick(Lookup(id: int.tryParse(device.id),label: device.number));
},
),
);
}
}

@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/pantry/calibration_tools.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/pentry/auto_complete_fields/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
class PentryCalibrationToolForm extends StatefulWidget {
final List<CalibrationTool> models;
final bool enableValidate;
const PentryCalibrationToolForm({
Key key, this.models, this.enableValidate,
}) : super(key: key);
@override
State<PentryCalibrationToolForm> createState() => _PentryCalibrationToolFormState();
}
class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final userProvider = Provider.of<UserProvider>(context);
return ListView.builder(
padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context),
left: 12 * AppStyle.getScaleFactor(context),
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
itemCount: widget.models.length + 1,
itemBuilder: (context,index){
if(index == widget.models.length){
return AButton(
text: subtitle.add,
onPressed: (){
widget.models.add(CalibrationTool());
setState(() {});
},
);
}
final model = widget.models[index];
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ASubTitle("#${index+1}"),
if(index != 0)
ASmallButton(
color: Theme.of(context).colorScheme.error,
text: subtitle.delete,
onPressed: (){
widget.models.remove(model);
setState(() {});
},
),
],
),
const SizedBox(height: 8,),
const ASubTitle("Asset Number"),
const SizedBox(height: 4,),
AutoCompleteDeviceNumberField(
initialValue: model.assetsNumber,
hospitalId: userProvider.user.hospital.id,
onPick: (number){
model.assetsNumber = number;
},
),
const SizedBox(height: 8,),
const ASubTitle("Date of Testing"),
const SizedBox(height: 4,),
ADatePicker(
date: model.dataOfTesting,
onDatePicker: (date){
model.dataOfTesting =date;
setState(() {});
},
),
const SizedBox(height: 8,),
Divider(color: Theme.of(context).textTheme.titleMedium.color,),
],
);
}
);
}
}

@ -0,0 +1,114 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_status_mune.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_visit_status_mune.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
class PentryInfoForm extends StatefulWidget {
final Pentry model;
final bool enableValidate;
const PentryInfoForm({
Key key, this.model, this.enableValidate,
}) : super(key: key);
@override
State<PentryInfoForm> createState() => _PentryInfoFormState();
}
class _PentryInfoFormState extends State<PentryInfoForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final userProvider = Provider.of<UserProvider>(context);
return ListView(
padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context),
left: 12 * AppStyle.getScaleFactor(context),
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
const SizedBox(height: 8,),
const ASubTitle("PPM Visit Status"),
if(widget.enableValidate && widget.model.ppmVisitStatus == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
PentryVisitsStatusMenu(
initialValue: widget.model.ppmVisitStatus,
onSelect: (status){
widget.model.ppmVisitStatus = status;
},
),
const SizedBox(height: 8,),
const ASubTitle("Timer"),
if(widget.enableValidate && widget.model?.timer?.endAt == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
AppTimer(
timer: widget.model.timer,
onChange: (timer) async{
widget.model.timer = timer;
return true;
},
),
const SizedBox(height: 8,),
const ASubTitle("Status"),
// if(widget.enableValidate && widget.model.status == null)
// ASubTitle(subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
PentryStatusMenu(
initialValue: widget.model.status,
onSelect: (status){
widget.model.status = status;
},
),
const SizedBox(height: 8,),
const ASubTitle("Actual Visit Date"),
if(widget.enableValidate && widget.model.actualVisitDate == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
ADatePicker(
date: widget.model.actualVisitDate,
from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date){
if(date == null) return;
widget.model.actualVisitDate = date;
setState(() {});
},
),
const SizedBox(height: 8,),
const ASubTitle("Traveling Hours"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (widget.model.travelingHours ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
onChange: (value){
widget.model.travelingHours = value;
},
),
const SizedBox(height: 12,),
const ASubTitle("PPM Attachment"),
AMiniOneImagePicker(
//error: _validate && _serviceReport.image == null,
image: widget.model.imageFile,
onPick: (image){
widget.model.imageFile =image;
},
),
const SizedBox(height: 8,),
],
);
}
}

@ -0,0 +1,154 @@
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/pantry/pm_kit.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
class PentryPMKitForm extends StatefulWidget {
final List<PMKit> models;
final bool enableValidate;
const PentryPMKitForm({
Key key, this.models, this.enableValidate,
}) : super(key: key);
@override
State<PentryPMKitForm> createState() => _PentryPMKitFormState();
}
class _PentryPMKitFormState extends State<PentryPMKitForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
return ListView.builder(
padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context),
left: 12 * AppStyle.getScaleFactor(context),
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
itemCount: widget.models.length + 1,
itemBuilder: (context,index){
if(index == widget.models.length){
return AButton(
text: subtitle.add,
onPressed: (){
widget.models.add(PMKit());
setState(() {});
},
);
}
final model = widget.models[index];
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ASubTitle("#${index+1}"),
if(index != 0)
ASmallButton(
color: Theme.of(context).colorScheme.error,
text: subtitle.delete,
onPressed: (){
widget.models.remove(model);
setState(() {});
},
),
],
),
const SizedBox(height: 8,),
const ASubTitle("Item Code"),
const SizedBox(height: 4,),
AutoCompletePartsField(
clearAfterPick: false,
initialValue: (model.itemCode?.label ?? "").toString(),
onPick: (part){
model.itemCode = Lookup(id: int.tryParse(part.id),label: part.code);
},
),
const SizedBox(height: 8,),
const ASubTitle("Item Name"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.itemName ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.itemName = value;
},
),
const SizedBox(height: 8,),
const ASubTitle("Preparation Time Frame"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.preparationTimeFrame ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.preparationTimeFrame = value;
},
),
const SizedBox(height: 8,),
const ASubTitle("kit Frequency Demand"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.kitFrequencyDemand ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.kitFrequencyDemand = value;
},
),
const SizedBox(height: 8,),
const ASubTitle("Availability"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.availability ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.availability = value;
},
),
const SizedBox(height: 8,),
const ASubTitle("Quantity Needed"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.quantityNeeded ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
onChange: (value){
model.quantityNeeded = value;
},
),
const SizedBox(height: 8,),
const ASubTitle("Quantity Reserved"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.quantityReserved ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
onChange: (value){
model.quantityReserved = value;
},
),
const SizedBox(height: 8,),
Divider(color: Theme.of(context).textTheme.titleMedium.color,),
],
);
}
);
}
}

@ -0,0 +1,117 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_task_status_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
class PentryPPMCheckListForm extends StatefulWidget {
final List<PPMCheckList> models;
final bool enableValidate;
const PentryPPMCheckListForm({
Key key, this.models, this.enableValidate,
}) : super(key: key);
@override
State<PentryPPMCheckListForm> createState() => _PentryPPMCheckListFormState();
}
class _PentryPPMCheckListFormState extends State<PentryPPMCheckListForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
return ListView.builder(
padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context),
left: 12 * AppStyle.getScaleFactor(context),
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
itemCount: widget.models.length + 1,
itemBuilder: (context,index){
if(index == widget.models.length){
return AButton(
text: subtitle.add,
onPressed: (){
widget.models.add(PPMCheckList());
setState(() {});
},
);
}
final model = widget.models[index];
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ASubTitle("#${index+1}"),
if(index != 0)
ASmallButton(
color: Theme.of(context).colorScheme.error,
text: subtitle.delete,
onPressed: (){
widget.models.remove(model);
setState(() {});
},
),
],
),
const SizedBox(height: 8,),
const ASubTitle("Task"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.title ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.title = value;
},
),
const SizedBox(height: 8,),
ASubTitle(subtitle.status),
const SizedBox(height: 4,),
PentryTaskStatusMenu(
initialValue: model.status,
onSelect: (status){
model.status = status;
},
),
const SizedBox(height: 8,),
const ASubTitle("Comment"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.comment ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.comment = value;
},
),
const SizedBox(height: 8,),
const ASubTitle("Measured Value"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (model.measuredValue ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onChange: (value){
model.measuredValue = value;
},
),
const SizedBox(height: 8,),
Divider(color: Theme.of(context).textTheme.titleMedium.color,),
],
);
}
);
}
}

@ -1,5 +1,5 @@
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/status.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';
import 'package:flutter/material.dart';

@ -251,57 +251,6 @@ class ServiceRequestItem extends StatelessWidget {
color: onItemColor
),
),
],
),
],
),
if(request.viewReport)
Column(
children: [
const SizedBox(height: 8,),
Row(
children: [
Expanded(
child: Text(
"Work Duration",
style: Theme.of(context).textTheme.headline6.copyWith(
color: onItemColor,
fontSize: 14,
fontWeight: FontWeight.bold
),
),
),
// AppTimer(
// timer: request.timer,
// onChange: (timeModel) async {
//
// request.timer = timeModel;
// if(timeModel.endAt == null) return true;
// int status = await servicesProvider.updateServiceReportTimer(
// host: settingProvider.host,
// user: _user,
// timer: timeModel,
// request: request
// );
// if(status >= 200 && status < 300){
// return true;
// }else{
// String errorMessage = HttpStatusManger.getStatusMessage(
// status: status, subtitle: _subtitle);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(
// errorMessage
// ),
// )
// );
// return false;
// }
//
//
// },
// ),
],
),
],

@ -8,13 +8,13 @@ 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/status.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/auto_complete_field.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';
@ -33,7 +33,7 @@ class _ServiceRequestsUpdateDialogState extends State<ServiceRequestsUpdateDialo
with TickerProviderStateMixin{
DateTime _dateTime;
Status _employee;
Lookup _employee;
Subtitle _subtitle;
UserProvider _userProvider;
SettingProvider _settingProvider;

@ -1,11 +1,11 @@
import 'package:test_sa/models/status.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';
import 'package:flutter/material.dart';
class FilterItem extends StatelessWidget {
final bool isSelected;
final Status status;
final Lookup status;
final VoidCallback onSelected;
const FilterItem({

@ -1,11 +1,11 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/service_request/service_request_search.dart';
import 'package:test_sa/models/status.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/hospitals/auto_complete_field.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field.dart';
import 'package:flutter/material.dart';
import '../app_text_form_field.dart';
@ -28,13 +28,13 @@ class ServiceRequestsSearchDialog extends StatefulWidget {
class _ServiceRequestsSearchDialogState extends State<ServiceRequestsSearchDialog>
with TickerProviderStateMixin{
ServiceRequestSearch _search;
List<Status> status = [
Status(label: "New", id: 4,),
List<Lookup> status = [
Lookup(label: "New", id: 4,),
Status(label: "Repaired", id: 6,),
Status(label: "Repeated", id: 8),
Status(label: "Closed", id: 9,),
Status(label: "Under Repair", id: 5,),
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>();
@ -94,7 +94,7 @@ class _ServiceRequestsSearchDialogState extends State<ServiceRequestsSearchDialo
},
),
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
AutoCompleteField(
HospitalAutoCompleteField(
initialValue: _search.hospital,
onSave: (value){
_search.hospital = value;

@ -1,12 +1,12 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/status.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/auto_complete_field.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 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -31,16 +31,16 @@ class VisitsSearchDialog extends StatefulWidget {
class _VisitsSearchDialogState extends State<VisitsSearchDialog>
with TickerProviderStateMixin{
VisitsSearch _search;
List<Status> status = [
Status(label: "Done", id: 0,),
Status(label: "Not Yet", id: 1),
Status(label: "On Hold", id: 2,),
List<Lookup> status = [
Lookup(label: "Done", id: 0,),
Lookup(label: "Not Yet", id: 1),
Lookup(label: "On Hold", id: 2,),
];
List<Status> contactStatus = [
Status(label: "Hospital Employee", key: "H",),
Status(label: "Under Warranty", key: "CW"),
Status(label: "Under Maintenance Contract", key: "CC",),
List<Lookup> contactStatus = [
Lookup(label: "Hospital Employee", key: "H",),
Lookup(label: "Under Warranty", key: "CW"),
Lookup(label: "Under Maintenance Contract", key: "CC",),
];
@ -100,7 +100,7 @@ class _VisitsSearchDialogState extends State<VisitsSearchDialog>
},
),
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
AutoCompleteField(
HospitalAutoCompleteField(
initialValue: _search.hospitalName,
onSave: (value){
_search.hospitalName = value;

@ -1,14 +1,14 @@
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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class EmployeeMenu extends StatelessWidget {
final Function(Status) onSelect;
final Status initialValue;
final Function(Lookup) onSelect;
final Lookup initialValue;
const EmployeeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override

@ -3,14 +3,14 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/ga
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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class GasCylinderSizeMenu extends StatelessWidget {
final Function(Status) onSelect;
final Status initialValue;
final Function(Lookup) onSelect;
final Lookup initialValue;
const GasCylinderSizeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override

@ -3,14 +3,14 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/ga
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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class GasStatusMenu extends StatelessWidget {
final Function(Status) onSelect;
final Status initialValue;
final Function(Lookup) onSelect;
final Lookup initialValue;
const GasStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override

@ -4,14 +4,14 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/ga
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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class GasTypeMenu extends StatelessWidget {
final Function(Status) onSelect;
final Status initialValue;
final Function(Lookup) onSelect;
final Lookup initialValue;
const GasTypeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override

@ -1,14 +1,14 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:test_sa/models/status.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';
import 'package:flutter/material.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
class MultiStatusMenu extends StatefulWidget {
final List<Status> statuses;
final List<Status> initialSelectedStatus;
final Function(List<Status>) onSelect;
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
@ -17,7 +17,7 @@ class MultiStatusMenu extends StatefulWidget {
class _MultiStatusMenuState extends State<MultiStatusMenu> {
List<Status> _selectedStatus = [];
List<Lookup> _selectedStatus = [];
TextEditingController _controller;
@override
@ -93,7 +93,7 @@ class _MultiStatusMenuState extends State<MultiStatusMenu> {
AppStyle.boxShadow
]
),
child: TypeAheadField<Status>(
child: TypeAheadField<Lookup>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.subtitle1,
controller: _controller,
@ -107,7 +107,7 @@ class _MultiStatusMenuState extends State<MultiStatusMenu> {
textInputAction: TextInputAction.search,
),
suggestionsCallback: (vale) {
return widget.statuses.where((Status option) {
return widget.statuses.where((Lookup option) {
return option.label.toLowerCase().contains(_controller.text);
});
},

@ -0,0 +1,37 @@
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,
)
);
}
}

@ -0,0 +1,37 @@
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,
)
);
}
}

@ -0,0 +1,37 @@
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,12 +1,12 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ServiceReportLastCallsMenu extends StatelessWidget {
final Function(Status) onSelect;
final Function(Lookup) onSelect;
final ServiceReport report;
const ServiceReportLastCallsMenu({

@ -1,14 +1,14 @@
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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ServiceReportReasonsMenu extends StatelessWidget {
final Status initialValue;
final Function(Status) onSelect;
final Lookup initialValue;
final Function(Lookup) onSelect;
const ServiceReportReasonsMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override

@ -5,13 +5,13 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/report/servic
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_report.dart';
import 'package:test_sa/models/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ServiceReportStatusMenu extends StatefulWidget {
final Function(Status) onSelect;
final Function(Lookup) onSelect;
final ServiceReport report;
const ServiceReportStatusMenu({Key key, this.onSelect, this.report}) : super(key: key);

@ -1,36 +1,36 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ServiceReportTypeMenu extends StatelessWidget {
final Function(Status) onSelect;
final Status initialValue;
final Function(Lookup) onSelect;
final Lookup initialValue;
const ServiceReportTypeMenu({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);
ServiceReportTypesProvider _menuProvider = Provider.of<ServiceReportTypesProvider>(context);
SettingProvider settingProvider = Provider.of<SettingProvider>(context);
UserProvider userProvider = Provider.of<UserProvider>(context);
ServiceReportTypesProvider menuProvider = Provider.of<ServiceReportTypesProvider>(context);
return LoadingManager(
isLoading: _menuProvider.isLoading,
isFailedLoading: _menuProvider.types == null,
stateCode: _menuProvider.stateCode,
isLoading: menuProvider.isLoading,
isFailedLoading: menuProvider.types == null,
stateCode: menuProvider.stateCode,
onRefresh: () async {
_menuProvider.reset();
await _menuProvider.getTypes(
user: _userProvider.user,
host: _settingProvider.host
menuProvider.reset();
await menuProvider.getTypes(
user: userProvider.user,
host: settingProvider.host
);
onSelect(initialValue ?? _menuProvider.types?.last);
onSelect(initialValue ?? menuProvider.types?.last);
},
child: SingleStatusMenu(
initialStatus: initialValue ?? _menuProvider.types?.last,
statuses: _menuProvider.types,
initialStatus: initialValue ?? menuProvider.types?.last,
statuses: menuProvider.types,
onSelect: onSelect,
)
);

@ -1,14 +1,14 @@
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/status.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';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ServiceStatusMenu extends StatelessWidget {
final Function(Status) onSelect;
final Status initialValue;
final Function(Lookup) onSelect;
final Lookup initialValue;
const ServiceStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override

@ -0,0 +1,37 @@
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,
)
);
}
}

@ -0,0 +1,37 @@
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,12 +1,12 @@
import 'package:flutter/material.dart';
import 'package:test_sa/models/status.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 SingleStatusMenu extends StatefulWidget {
final List<Status> statuses;
final Status initialStatus;
final Function(Status) onSelect;
final List<Lookup> statuses;
final Lookup initialStatus;
final Function(Lookup) onSelect;
const SingleStatusMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key);
@ -15,7 +15,7 @@ class SingleStatusMenu extends StatefulWidget {
}
class _SingleStatusMenuState extends State<SingleStatusMenu> {
Status _selectedStatus;
Lookup _selectedStatus;
@override
void didUpdateWidget(covariant SingleStatusMenu oldWidget) {
@ -54,7 +54,7 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
// AppStyle.boxShadow
// ]
),
child: DropdownButton<Status>(
child: DropdownButton<Lookup>(
value: _selectedStatus,
iconSize: 24,
icon: Icon(Icons.keyboard_arrow_down_rounded),
@ -66,14 +66,14 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
),
style: TextStyle(color: Theme.of(context).primaryColor),
underline: SizedBox.shrink(),
onChanged: (Status newValue) {
onChanged: (Lookup newValue) {
setState(() {
_selectedStatus = newValue;
});
widget.onSelect(newValue);
},
items: widget.statuses.map<DropdownMenuItem<Status>>((Status value) {
return DropdownMenuItem<Status>(
items: widget.statuses.map<DropdownMenuItem<Lookup>>((Lookup value) {
return DropdownMenuItem<Lookup>(
value: value,
child: Text(
value.label,

@ -30,6 +30,7 @@ class _AppTimerState extends State<AppTimer> {
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));
@ -41,8 +42,7 @@ class _AppTimerState extends State<AppTimer> {
}
_startAt = time.subtract(Duration(seconds: _delay));
_endAt = null;
}
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if(_loading == true) return;
@ -78,32 +78,13 @@ class _AppTimerState extends State<AppTimer> {
@override
void initState() {
// TODO: implement initState
// if(widget.timer?.isNotEmpty == true){
// _startAt = widget.timer.last.startAt;
// _endAt = widget.timer.last.endAt;
// _running = _startAt != null && _endAt == null;
// print(_startAt);
// print(_endAt);
// print(_running);
// if(widget.timer.length != 1){
// for (int i = 0;i<widget.timer.length -1;i++) {
// _delay += widget.timer[i].endAt.difference(
// widget.timer[i].startAt).inSeconds;
// }
// if(!_running) {
// _startAt = _startAt.subtract(Duration(seconds: _delay));
// _period.value = (_endAt ?? DateTime.now()).difference(
// _startAt
// ).toString().split(".").first;
// }
// }
// }
_startAt = widget.timer?.startAt;
_endAt = widget.timer?.endAt;
_running = _startAt != null && _endAt == null;
_delay = (widget.timer?.durationInSecond ?? 0);
_period.value = Duration(seconds: _delay).toString().split(".").first;
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();}
}

@ -1,14 +1,14 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/visits/visit_status.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class VisitItem extends StatelessWidget {
final Visit visit;
final int index;
@ -17,62 +17,45 @@ class VisitItem extends StatelessWidget {
final Function(Visit) onPressed;
final Function(Visit) onLongPress;
final Function(Visit) onSelect;
const VisitItem({
Key key,
this.visit,
this.onPressed,
this.isSelected = false,
this.activeSelectMod = false,
this.onLongPress,
this.onSelect, this.index
}) : super(key: key);
const VisitItem({Key key, this.visit, this.onPressed, this.isSelected = false, this.activeSelectMod = false, this.onLongPress, this.onSelect, this.index}) : super(key: key);
@override
Widget build(BuildContext context) {
UserProvider _userProvider = Provider.of<UserProvider>(context);
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;
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;
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
primary: itemColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.getBorderRadius(context)
),
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
),
),
onPressed: (){
if(activeSelectMod && _userProvider.user.type == UsersTypes.engineer)
onPressed: () {
if (activeSelectMod && _userProvider.user.type == UsersTypes.engineer)
onSelect(visit);
else
onPressed(visit);
},
onLongPress: _userProvider.user.type == UsersTypes.engineer ? (){
onLongPress: _userProvider.user.type == UsersTypes.engineer
? () {
onLongPress(visit);
} : null,
child:Column(
}
: null,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
"S.N: "+visit.deviceSerialNumber ?? "No serial number",
style: Theme.of(context).textTheme.headline6.copyWith(
color: onItemColor,
fontSize: 16,
fontWeight: FontWeight.bold
),
"S.N: " + visit.deviceSerialNumber ?? "No serial number",
style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold),
),
),
AnimatedSwitcher(
@ -84,19 +67,21 @@ class VisitItem extends StatelessWidget {
height: 18,
child: Checkbox(
activeColor: Colors.black38,
value: isSelected,
onChanged: (value){
onChanged: (value) {
onSelect(visit);
}
}),
),
),
),
),
VisitStatusLabel(visit: visit,)
VisitStatusLabel(
visit: visit,
)
],
),
Divider(color: onItemColor,),
Divider(
color: onItemColor,
),
Row(
children: [
Expanded(
@ -108,6 +93,8 @@ class VisitItem extends StatelessWidget {
),
),
),
],
),
Text(
visit.modelAndBrand ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
@ -115,19 +102,15 @@ class VisitItem extends StatelessWidget {
fontSize: 14,
),
),
],
Divider(
color: onItemColor,
),
Divider(color: onItemColor,),
Row(
children: [
Expanded(
child: Text(
visit.employName ?? "No employ found",
style: Theme.of(context).textTheme.headline6.copyWith(
color: onItemColor,
fontSize: 14,
fontWeight: FontWeight.bold
),
style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 14, fontWeight: FontWeight.bold),
),
),
Text(
@ -139,7 +122,9 @@ class VisitItem extends StatelessWidget {
),
],
),
Divider(color: onItemColor,),
Divider(
color: onItemColor,
),
Row(
children: [
Expanded(
@ -151,7 +136,6 @@ class VisitItem extends StatelessWidget {
style: Theme.of(context).textTheme.headline6.copyWith(
color: onItemColor,
fontSize: 14,
),
),
Text(
@ -159,7 +143,6 @@ class VisitItem extends StatelessWidget {
style: Theme.of(context).textTheme.headline6.copyWith(
color: onItemColor,
fontSize: 14,
),
),
],

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.6.1+1
version: 0.7.4+1
environment:
sdk: ">=2.7.0 <3.0.0"

Loading…
Cancel
Save