version 0.7.4 - update pentry

add update pentry
add Defect Type and priority for service request
rename and remove unused fields
add search with asset number and view it in service request and ppm visit
merge-requests/22/head
MaximusAshraf 2 years ago
parent 2d2e22fa11
commit bba0b3d7d7

@ -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",
@ -97,8 +97,8 @@
"newServiceRequest": "New Service Request",
"newWord": "New",
"noDateFound": "No Date Found",
"noDeviceFound": "No Device Found",
"noHospitalFound": "No Client 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
@ -54,4 +56,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
}

@ -0,0 +1,18 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/models/visits/visit.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
class PentryController {
const PentryController._();
static const PentryController instance = PentryController._();
}

@ -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 [];
}

@ -109,8 +109,8 @@ 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());

@ -96,11 +96,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';
@ -54,6 +55,11 @@ class RegularVisitsProvider extends ChangeNotifier{
Response response;
//userId = 397.toString(); // testing id to view data
try{
print( Uri.parse(
"$host${URLs.getRegularVisits}?uid=${user.id}"
"&token=${user.token}"
"&page=${(visits?.length ?? 0) ~/pageItemNumber}${visitsSearch?.toSearchString()}" ?? ""
));
response = await get(
Uri.parse(
host+URLs.getRegularVisits
@ -76,7 +82,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();
@ -89,6 +95,7 @@ class RegularVisitsProvider extends ChangeNotifier{
nextPage = false;
}
}catch(error){
print(error);
isLoading = false;
stateCode = -1;
notifyListeners();
@ -137,5 +144,52 @@ class RegularVisitsProvider extends ChangeNotifier{
}
}
Future<Pentry> getPently({String host,User user,String id}) async {
Response response;
print(Uri.parse("$host${URLs.getPentry}/$id"),);
response = await get(
Uri.parse("$host${URLs.getPentry}/$id"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
print(response.body);
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;
print( Uri.parse(host+URLs.updatePentry + "/${visit.id}"),);
print(body);
response = await post(
Uri.parse(host+URLs.updatePentry + "/${visit.id}"),
body: body,
);
print(response.body);
if(response.statusCode >= 200 && response.statusCode < 300) {
visit.status = pentry.ppmVisitStatus;
notifyListeners();
}
return response.statusCode;
} catch(error) {
print(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';
@ -161,6 +161,8 @@ 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;
@ -173,7 +175,7 @@ class ServiceRequestsProvider extends ChangeNotifier{
host+URLs.createRequest),
body: body,
);
print(response.body);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if(serviceRequests != null)
@ -225,7 +227,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;

@ -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),
);
print(response.body);
_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) {
print(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),
);
print(response.body);
_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) {
print(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 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),
);
print(response.body);
_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) {
print(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),
);
print(response.body);
_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) {
print(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,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 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),
);
print(response.body);
_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) {
print(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;

@ -11,6 +11,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';
@ -33,6 +37,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';
@ -80,6 +85,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

@ -9,7 +9,6 @@ class User{
String password;
String email;
String image;
String hospitalID;
Hospital hospital;
Department department;
UsersTypes 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

@ -280,45 +280,46 @@ class _LandPageState extends State<LandPage> {
},
),
Expanded(
child: MaterialButton(
splashColor: AColors.secondaryColor.withOpacity(.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
8 * AppStyle.getScaleFactor(context)
),
color: AColors.onPrimaryColor
),
child: Icon(
Icons.phone_in_talk,
color: AColors.primaryColor ,
size: 32,
),
),
SizedBox(
width: 12 * AppStyle.getScaleFactor(context),
),
Text(
"${_subtitle.hotLine}\n15564",
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.white,
letterSpacing: 2.75,
fontWeight: FontWeight.bold
),
),
],
),
onPressed: (){
launch("tel:15564");
},
),
),
Spacer(),
// Expanded(
// child: MaterialButton(
// splashColor: AColors.secondaryColor.withOpacity(.5),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Container(
// padding: EdgeInsets.all(12),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(
// 8 * AppStyle.getScaleFactor(context)
// ),
// color: AColors.onPrimaryColor
// ),
// child: Icon(
// Icons.phone_in_talk,
// color: AColors.primaryColor ,
// size: 32,
// ),
// ),
// SizedBox(
// width: 12 * AppStyle.getScaleFactor(context),
// ),
// Text(
// "${_subtitle.hotLine}\n ",
//
// style: Theme.of(context).textTheme.headline6.copyWith(
// color: AColors.white,
// letterSpacing: 2.75,
// fontWeight: FontWeight.bold
// ),
// ),
// ],
// ),
// onPressed: (){
// //launch("tel:15564");
// },
// ),
// ),
AIconButton(
iconData: Icons.notifications,
onPressed: (){
@ -349,7 +350,6 @@ class _LandPageState extends State<LandPage> {
onPressed: (){
Navigator.of(context).pop();
Navigator.of(context).pushNamed(ProfilePage.id);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
@ -366,9 +366,7 @@ class _LandPageState extends State<LandPage> {
shape: BoxShape.circle
),
child: ClipOval(
child: ImageLoader(
url: "https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png",
),
child: Icon(Icons.person,size: 72,color: Theme.of(context).colorScheme.primary,),
),
),
Text(
@ -419,20 +417,20 @@ class _LandPageState extends State<LandPage> {
),
],
),
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: 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,

@ -24,6 +24,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";
@override
@ -120,9 +123,9 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
enable: false,
initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound,
hintText: _subtitle.hospital,
prefixIconData: FontAwesomeIcons.hospitalAlt,
prefixIconData: FontAwesomeIcons.hospital,
prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.subtitle1,
),
const SizedBox(height: 8,),
_userProvider.user.department == null ? SizedBox.shrink() :
@ -132,7 +135,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
hintText: _subtitle.unite,
prefixIconData: FontAwesomeIcons.hospitalUser,
prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.subtitle1,
),
const SizedBox(height: 8,),
DeviceButton(
@ -142,6 +145,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;
},
),
MultiImagesPicker(
label: _subtitle.deviceImages,
images: _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,192 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/data/pentry/pentry_controller.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/device_transfer_provider.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/device/device_transfer.dart';
import 'package:test_sa/models/device/device_transfer_info.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_button.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,60 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/data/pentry/pentry_controller.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) {
print(snapshot.error);
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,20 @@
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 +23,7 @@ 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 +45,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 +104,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,18 +14,17 @@ 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" :
date.toString().split(" ").first,
style: Theme.of(context).textTheme.subtitle2,
textScaleFactor: AppStyle.getScaleFactor(context),
),
onPressed: () async {

@ -43,65 +43,52 @@ 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(
horizontal: 16
),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color:AColors.black),
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
boxShadow: [
AppStyle.boxShadow
]
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)
),
child: TypeAheadField<Device>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
boxShadow: [
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,
),
suggestionsCallback: (vale) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
title: vale,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.serialNumber),
subtitle: Text(device.model+"/"+device.brand),
);
},
onSuggestionSelected: (device) {
_controller.text = device.serialNumber;
widget.onPick(device.id);
},
),
textInputAction: TextInputAction.search,
),
suggestionsCallback: (value) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
serialNumber: value,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.serialNumber),
subtitle: Text(device.model+"/"+device.brand),
);
},
onSuggestionSelected: (device) {
_controller.text = device.serialNumber;
widget.onPick(device.id);
},
),
);
}
}

@ -88,22 +88,41 @@ 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(
hintText: _subtitle.searchBySn,
style: Theme.of(context).textTheme.headline6,
suffixIcon: const Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_devicesProvider.devices.where(
(element) => element.serialNumber.toLowerCase().contains(
child: Column(
children: [
ATextFormField(
hintText: _subtitle.searchBySn,
style: Theme.of(context).textTheme.subtitle1,
suffixIcon: const Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_devicesProvider.devices.where(
(element) => element.serialNumber.toLowerCase().contains(
value.toLowerCase()
)
).toList());
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(() {});
},
)
).toList());
setState(() {});
},
),
],
),
),
Expanded(

@ -9,18 +9,18 @@ import 'package:test_sa/views/widgets/hospitals/hospital_item.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.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;
@ -56,7 +56,6 @@ class _AutoCompleteFieldState extends State<AutoCompleteField> {
]
),
child: TypeAheadField<Hospital>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
onSubmitted: widget.onSave,

@ -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),
),
),

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

@ -10,9 +10,10 @@ import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
class AutoCompletePartsField extends StatefulWidget {
final String initialValue;
final bool clearAfterPick;
final Function(Part) onPick;
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();
@ -42,62 +43,54 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
_userProvider = Provider.of<UserProvider>(context);
_partsProvider = Provider.of<PartsProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle;
return LoadingManager(
isLoading: _partsProvider.isLoading,
isFailedLoading: _partsProvider.parts == null,
stateCode: _partsProvider.stateCode,
onRefresh: () async {
_partsProvider.reset();
await _partsProvider.getParts(
host: _settingProvider.host,
user: _userProvider.user,
);
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 16
),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color:AColors.black),
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
boxShadow: [
AppStyle.boxShadow
]
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)
),
child: TypeAheadField<Part>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.subtitle1,
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
boxShadow: const [
AppStyle.boxShadow
]
),
child: TypeAheadField<Part>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.subtitle1,
controller: _controller,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
suggestionsCallback: (vale) async {
return await _partsProvider.getPartsList(
host: _settingProvider.host,
title: vale
);
},
itemBuilder: (context, part) {
return ListTile(
title: Text(part.code),
subtitle: Text(part.name, style: Theme.of(context).textTheme.caption,),
);
},
onSuggestionSelected: (part) {
_controller.clear();
widget.onPick(part);
},
),
textInputAction: TextInputAction.search,
),
suggestionsCallback: (vale) async {
return await _partsProvider.getPartsList(
host: _settingProvider.host,
title: vale
);
},
itemBuilder: (context, part) {
return ListTile(
title: Text(part.code),
subtitle: Text(part.name, style: Theme.of(context).textTheme.caption,),
);
},
onSuggestionSelected: (part) {
if(widget.clearAfterPick){
_controller.clear();
} else{
_controller.text = part.code;
}
widget.onPick(part);
},
),
);
}
}

@ -0,0 +1,95 @@
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';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.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,100 @@
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/models/pantry/contact.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/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/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/status/pentry/pentry_task_status_mune.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,123 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.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/models/pantry/contact.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/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/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_status_mune.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_task_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,158 @@
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/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/views/app_style/colors.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/status/pentry/pentry_task_status_mune.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,119 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/pantry/contact.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/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,40 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/employee_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_status_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/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';
import 'package:flutter/material.dart';
import 'package:provider/provider.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,38 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/employee_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';
import 'package:flutter/material.dart';
import 'package:provider/provider.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,39 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/employee_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/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';
import 'package:flutter/material.dart';
import 'package:provider/provider.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,41 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/employee_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/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';
import 'package:flutter/material.dart';
import 'package:provider/provider.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,40 @@
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/employee_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_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';
import 'package:flutter/material.dart';
import 'package:provider/provider.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,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 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);
@override
@ -14,7 +14,7 @@ class SingleStatusMenu extends StatefulWidget {
class _SingleStatusMenuState extends State<SingleStatusMenu> {
Status _selectedStatus;
Lookup _selectedStatus;
@override
void didUpdateWidget(covariant SingleStatusMenu oldWidget) {
@ -56,7 +56,7 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
AppStyle.boxShadow
]
),
child: DropdownButton<Status>(
child: DropdownButton<Lookup>(
value: _selectedStatus,
iconSize: 24,
elevation: 16,
@ -69,15 +69,15 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
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>(
.map<DropdownMenuItem<Lookup>>((Lookup value) {
return DropdownMenuItem<Lookup>(
value: value,
child: Text(
value.label,

@ -30,19 +30,19 @@ class _AppTimerState extends State<AppTimer> {
final ValueNotifier<String> _period = ValueNotifier("0:00:00");
_startTimer() async {
final time = DateTime.now();
bool result = await widget.onChange(
TimerModel(startAt: time,endAt: null,durationInSecond: _delay));
if(!result) return;
_running = true;
if (!_running) {
final time = DateTime.now();
bool result = await widget.onChange(
TimerModel(startAt: time,endAt: null,durationInSecond: _delay));
if(!result) return;
_running = true;
if(_endAt != null){
_delay += _endAt.difference(_startAt).inSeconds;
if(_endAt != null){
_delay += _endAt.difference(_startAt).inSeconds;
}
_startAt = time.subtract(Duration(seconds: _delay));
_endAt = null;
}
_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();}
}

@ -108,15 +108,16 @@ class VisitItem extends StatelessWidget {
),
),
),
Text(
visit.modelAndBrand ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
color: onItemColor,
fontSize: 14,
),
),
],
),
Text(
visit.modelAndBrand ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
color: onItemColor,
fontSize: 14,
),
),
Divider(color: onItemColor,),
Row(
children: [

@ -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