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

@ -37,6 +37,8 @@ class URLs{
static const getServiceReportLastCalls = "/return/call/last/situation"; // get static const getServiceReportLastCalls = "/return/call/last/situation"; // get
static const getServiceTypes = "/return/service/type"; // get static const getServiceTypes = "/return/service/type"; // get
static const getPartNumber = "/handle/return/all/parts"; // 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 //gas refill
static const getGasTypes = "/return/gas/refill/types"; // get static const getGasTypes = "/return/gas/refill/types"; // get
@ -54,4 +56,13 @@ class URLs{
// employee // employee
static const getEmployees = "/return/assigned/employee"; // get 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 String host,
@required User user, @required User user,
@required String hospitalId, @required String hospitalId,
@required String title}) async { String serialNumber,
String number,
}) async {
Response response; Response response;
try{ try{
response = await get( response = await get(
Uri.parse(host + URLs.getEquipment+"?client=$hospitalId" Uri.parse("$host${URLs.getEquipment}?client=$hospitalId"
+ ( title == null || title.isEmpty ? "" : "&name=$title" )), "${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) { if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); 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) { } catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return []; return [];
} }

@ -109,8 +109,8 @@ class GasRefillProvider extends ChangeNotifier{
}; };
body["details"] = jsonEncode(model.details.map((model) => { body["details"] = jsonEncode(model.details.map((model) => {
"type": model.type.id.toString(), "type": model.type.id?.toString(),
"size": model.cylinderSize.id.toString(), "size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(), "requsted_qty": model.requestedQuantity.toString(),
}).toList()); }).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 { Future<List<Hospital>> getHospitalsList ({String host,User user,String title}) async {
Response response; Response response;
try{ try{

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

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart'; 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/user.dart';
import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart'; import 'package:test_sa/models/visits/visits_group.dart';
@ -54,6 +55,11 @@ class RegularVisitsProvider extends ChangeNotifier{
Response response; Response response;
//userId = 397.toString(); // testing id to view data //userId = 397.toString(); // testing id to view data
try{ try{
print( Uri.parse(
"$host${URLs.getRegularVisits}?uid=${user.id}"
"&token=${user.token}"
"&page=${(visits?.length ?? 0) ~/pageItemNumber}${visitsSearch?.toSearchString()}" ?? ""
));
response = await get( response = await get(
Uri.parse( Uri.parse(
host+URLs.getRegularVisits host+URLs.getRegularVisits
@ -76,7 +82,7 @@ class RegularVisitsProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) { if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
try{ try{
List requestsListJson = json.decode(utf8.decode(response.bodyBytes)); List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<Visit> _visits = requestsListJson.map( List<Visit> _visits = requestsListJson.map(
(request) => Visit.fromJson(request) (request) => Visit.fromJson(request)
).toList(); ).toList();
@ -89,6 +95,7 @@ class RegularVisitsProvider extends ChangeNotifier{
nextPage = false; nextPage = false;
} }
}catch(error){ }catch(error){
print(error);
isLoading = false; isLoading = false;
stateCode = -1; stateCode = -1;
notifyListeners(); 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/api_routes/urls.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.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/issue.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/service_request/service_request_search.dart'; import 'package:test_sa/models/service_request/service_request_search.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
@ -161,6 +161,8 @@ class ServiceRequestsProvider extends ChangeNotifier{
"client": user.hospital.id ?? '', "client": user.hospital.id ?? '',
"complaint": serviceRequest.maintenanceIssue, "complaint": serviceRequest.maintenanceIssue,
"image": json.encode(serviceRequest.devicePhotos), "image": json.encode(serviceRequest.devicePhotos),
"priority": (serviceRequest.priority?.id).toString(),
"defect_types": (serviceRequest.defectType?.id).toString(),
}; };
if(serviceRequest.audio != null){ if(serviceRequest.audio != null){
body["audio"] = serviceRequest.audio; body["audio"] = serviceRequest.audio;
@ -173,7 +175,7 @@ class ServiceRequestsProvider extends ChangeNotifier{
host+URLs.createRequest), host+URLs.createRequest),
body: body, body: body,
); );
print(response.body);
stateCode = response.statusCode; stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) { if(response.statusCode >= 200 && response.statusCode < 300) {
if(serviceRequests != null) if(serviceRequests != null)
@ -225,7 +227,7 @@ class ServiceRequestsProvider extends ChangeNotifier{
@required String host, @required String host,
@required User user, @required User user,
@required String newDate, @required String newDate,
@required Status employee, @required Lookup employee,
@required ServiceRequest request, @required ServiceRequest request,
}) async { }) async {
Response response; Response response;

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

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

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

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart'; 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:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -24,8 +24,8 @@ class GasTypesProvider extends ChangeNotifier{
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Status> _items; List<Lookup> _items;
List<Status> get items => _items; List<Lookup> get items => _items;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
@ -55,7 +55,7 @@ class GasTypesProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) { if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); 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; _loading = false;
notifyListeners(); 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 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart'; 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:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -24,8 +24,8 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Status> _calls; List<Lookup> _calls;
List<Status> get calls => _calls; List<Lookup> get calls => _calls;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
@ -59,7 +59,7 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) { if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); 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; _loading = false;
notifyListeners(); 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 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart'; 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:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Status> _reasons; List<Lookup> _reasons;
List<Status> get reasons => _reasons; List<Lookup> get reasons => _reasons;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
@ -56,7 +56,7 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) { if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); 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; _loading = false;
notifyListeners(); notifyListeners();

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

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

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart'; 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:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -23,8 +23,8 @@ class ServiceStatusProvider extends ChangeNotifier{
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Status> _statuses; List<Lookup> _statuses;
List<Status> get statuses => _statuses; List<Lookup> get statuses => _statuses;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
@ -57,7 +57,7 @@ class ServiceStatusProvider extends ChangeNotifier{
if(response.statusCode >= 200 && response.statusCode < 300) { if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); 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; _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_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_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/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/app_style/colors.dart';
import 'package:test_sa/views/pages/login.dart'; import 'package:test_sa/views/pages/login.dart';
import 'package:test_sa/views/pages/register.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 'package:provider/provider.dart';
import 'controllers/providers/api/parts_provider.dart'; import 'controllers/providers/api/parts_provider.dart';
import 'controllers/providers/api/preventive_maintenance_visits_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_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_reasons_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_report_status_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: (_) => GasRefillProvider()),
ChangeNotifierProvider(create: (_) => DeviceTransferProvider()), ChangeNotifierProvider(create: (_) => DeviceTransferProvider()),
ChangeNotifierProvider(create: (_) => EmployeesProvider()), ChangeNotifierProvider(create: (_) => EmployeesProvider()),
ChangeNotifierProvider(create: (_) => PentryTaskStatusProvider()),
ChangeNotifierProvider(create: (_) => PentryVisitStatusProvider()),
ChangeNotifierProvider(create: (_) => PentryStatusProvider()),
ChangeNotifierProvider(create: (_) => ServiceRequestPriorityProvider()),
ChangeNotifierProvider(create: (_) => ServiceRequestDefectTypesProvider()),
], ],
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {

@ -1,6 +1,7 @@
class Device{ class Device{
String id; String id;
String serialNumber; String serialNumber;
String number;
String brand; String brand;
String model; String model;
DateTime productionDate; DateTime productionDate;
@ -13,6 +14,7 @@ class Device{
Device({ Device({
this.id, this.id,
this.serialNumber, this.serialNumber,
this.number,
this.brand, this.brand,
this.model, this.model,
this.productionDate, this.productionDate,
@ -27,6 +29,7 @@ class Device{
return Device( return Device(
id: parsedJson["nid"] ?? parsedJson["id"], id: parsedJson["nid"] ?? parsedJson["id"],
serialNumber: parsedJson["sn"] ?? parsedJson["value"], serialNumber: parsedJson["sn"] ?? parsedJson["value"],
number: parsedJson["asset_no"],
brand: parsedJson["brand"].toString(), brand: parsedJson["brand"].toString(),
model: parsedJson["model"].toString(), model: parsedJson["model"].toString(),
productionDate: getDateFromString(parsedJson["production_date"]), productionDate: getDateFromString(parsedJson["production_date"]),
@ -42,6 +45,7 @@ class Device{
return Device( return Device(
id: device.id, id: device.id,
serialNumber: device.serialNumber, serialNumber: device.serialNumber,
number: device.number,
brand: device.brand, brand: device.brand,
model: device.model, model: device.model,
productionDate: device.productionDate, 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.dart';
import 'package:test_sa/models/device/device_transfer_info.dart'; import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/status.dart'; import 'package:test_sa/models/lookup.dart';
class DeviceTransfer{ class DeviceTransfer{
String id; String id;

@ -2,7 +2,7 @@ import 'package:http/http.dart';
import 'package:test_sa/models/department.dart'; import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/status.dart'; import 'package:test_sa/models/lookup.dart';
class DeviceTransferInfo{ class DeviceTransferInfo{
String userId; String userId;
@ -13,7 +13,7 @@ class DeviceTransferInfo{
String travelingHours; String travelingHours;
String name; String name;
String signature; String signature;
Status status; Lookup status;
DeviceTransferInfo({ DeviceTransferInfo({
this.userId, this.userId,
@ -67,7 +67,7 @@ class DeviceTransferInfo{
comment: parsedJson["${key}comment"], comment: parsedJson["${key}comment"],
client: Hospital.fromJson(parsedJson["${key}client"]), client: Hospital.fromJson(parsedJson["${key}client"]),
department: Department.fromJson(parsedJson["${key}department"]), 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{ class GasRefillDetails{
Status type; Lookup type;
Status cylinderSize; Lookup cylinderSize;
int requestedQuantity; int requestedQuantity;
int deliveredQuantity; int deliveredQuantity;
@ -21,9 +21,9 @@ class GasRefillDetails{
} }
factory GasRefillDetails.fromJson(Map<String,dynamic> parsedJson){ factory GasRefillDetails.fromJson(Map<String,dynamic> parsedJson){
return GasRefillDetails( 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 requestedQuantity: parsedJson["requsted_qty"] == null
? 0 : int.tryParse(parsedJson["requsted_qty"].toString()) ?? 0, ? 0 : int.tryParse(parsedJson["requsted_qty"].toString()) ?? 0,
deliveredQuantity: parsedJson["deliverd_qty"] == null deliveredQuantity: parsedJson["deliverd_qty"] == null
@ -33,8 +33,8 @@ class GasRefillDetails{
factory GasRefillDetails.fromDetails(GasRefillDetails details){ factory GasRefillDetails.fromDetails(GasRefillDetails details){
return GasRefillDetails( return GasRefillDetails(
type: Status.fromStatus(details.type), type: Lookup.fromStatus(details.type),
cylinderSize:Status.fromStatus(details.cylinderSize), cylinderSize:Lookup.fromStatus(details.cylinderSize),
requestedQuantity: details.requestedQuantity, requestedQuantity: details.requestedQuantity,
deliveredQuantity: details.deliveredQuantity, deliveredQuantity: details.deliveredQuantity,
); );

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

@ -1,10 +1,10 @@
class Status{ class Lookup{
final String label; final String label;
final String key; final String key;
final int id; final int id;
const Status({ const Lookup({
this.label, this.label,
this.key, this.key,
this.id, this.id,
@ -12,7 +12,7 @@ class Status{
@override @override
bool operator == (Object other) => bool operator == (Object other) =>
identical(this, other) || other is Status && identical(this, other) || other is Lookup &&
key == other.key && key == other.key &&
id == other.id; id == other.id;
@ -20,17 +20,17 @@ class Status{
@override @override
int get hashCode => id.hashCode; int get hashCode => id.hashCode;
factory Status.fromStatus(Status old){ factory Lookup.fromStatus(Lookup old){
return Status( return Lookup(
label: old.label, label: old.label,
id: old.id, id: old.id,
key: old.key, 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; if(parsedJson["id"] == null && parsedJson["uid"] == null) return null;
return Status( return Lookup(
label: parsedJson["value"], label: parsedJson["value"],
id: parsedJson["id"] is int id: parsedJson["id"] is int
? parsedJson["id"] ? parsedJson["id"]
@ -38,8 +38,8 @@ class Status{
); );
} }
factory Status.fromServiceReportJson(Map<String,dynamic> parsedJson){ factory Lookup.fromIntIdJson(Map<String,dynamic> parsedJson){
return Status( return Lookup(
label: parsedJson["value"], label: parsedJson["value"],
id: parsedJson["id"], 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/device/device.dart';
import 'package:test_sa/models/part.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'; import 'package:test_sa/models/timer_model.dart';
class ServiceReport { class ServiceReport {
@ -10,11 +10,11 @@ class ServiceReport {
String operatingHours; String operatingHours;
DateTime visitDate; DateTime visitDate;
DateTime endDate; DateTime endDate;
Status serviceType; Lookup serviceType;
Status callLastSituation; Lookup callLastSituation;
Status status; Lookup status;
Status type; Lookup type;
Status reason; Lookup reason;
String faultDescription; String faultDescription;
String workPreformed; String workPreformed;
//String workHours; //String workHours;
@ -90,7 +90,6 @@ class ServiceReport {
} }
bool validate(){ bool validate(){
if(visitDate == null) return false; if(visitDate == null) return false;
if(serviceType == null) return false; if(serviceType == null) return false;
if(status == null) return false; if(status == null) return false;
@ -120,11 +119,11 @@ class ServiceReport {
} }
return ServiceReport( return ServiceReport(
id: id, id: id,
serviceType: Status.fromJson(parsedJson["service_type"]), serviceType: Lookup.fromJson(parsedJson["service_type"]),
callLastSituation: Status.fromJson(parsedJson["call_last_situtation"]), callLastSituation: Lookup.fromJson(parsedJson["call_last_situtation"]),
reason: Status.fromJson(parsedJson["reasons"]), reason: Lookup.fromJson(parsedJson["reasons"]),
status: Status.fromJson(parsedJson["service_report_status"]), status: Lookup.fromJson(parsedJson["service_report_status"]),
type: Status.fromJson(parsedJson["service_report_type"]), type: Lookup.fromJson(parsedJson["service_report_type"]),
faultDescription: parsedJson["fault_description"], faultDescription: parsedJson["fault_description"],
endDate:getDate(parsedJson["end_date"]), endDate:getDate(parsedJson["end_date"]),
invoiceCode: parsedJson["invoice_code"], invoiceCode: parsedJson["invoice_code"],

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

@ -9,7 +9,6 @@ class User{
String password; String password;
String email; String email;
String image; String image;
String hospitalID;
Hospital hospital; Hospital hospital;
Department department; Department department;
UsersTypes type; 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'; import 'package:test_sa/models/timer_model.dart';
class Visit{ class Visit{
@ -16,8 +16,9 @@ class Visit{
String employName; String employName;
String modelAndBrand; String modelAndBrand;
String contactStatus; String contactStatus;
Status status; Lookup status;
String assignTo; String assignTo;
String deviceNumber;
List<String> images; List<String> images;
Visit({ Visit({
@ -38,6 +39,7 @@ class Visit{
this.contactStatus, this.contactStatus,
this.images, this.images,
this.assignTo, this.assignTo,
this.deviceNumber,
}); });
factory Visit.fromJson(Map<String,dynamic> parsedJson){ factory Visit.fromJson(Map<String,dynamic> parsedJson){
@ -45,6 +47,7 @@ class Visit{
id: parsedJson["nid"], id: parsedJson["nid"],
serialNumber: parsedJson["title"], serialNumber: parsedJson["title"],
hospitalId: parsedJson["client"], hospitalId: parsedJson["client"],
deviceNumber: parsedJson["device_no"],
hospitalName: parsedJson["client_name"], hospitalName: parsedJson["client_name"],
deviceId: parsedJson["medical_equipment_nid"], deviceId: parsedJson["medical_equipment_nid"],
deviceSerialNumber: parsedJson["medical_equipment"], deviceSerialNumber: parsedJson["medical_equipment"],
@ -57,7 +60,7 @@ class Visit{
modelAndBrand: parsedJson["mode_brand"], modelAndBrand: parsedJson["mode_brand"],
contactStatus: parsedJson["contactStatus"], contactStatus: parsedJson["contactStatus"],
images: List<String>.from(parsedJson["images"] ?? []), images: List<String>.from(parsedJson["images"] ?? []),
status: Status( status: Lookup(
id: int.tryParse(parsedJson["status"] ?? "-1"), // actual value (0,1,2) id: int.tryParse(parsedJson["status"] ?? "-1"), // actual value (0,1,2)
label: parsedJson["status_value"] // text value 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'; import 'package:test_sa/models/visits/visit.dart';
class VisitsGroup{ class VisitsGroup{
@ -8,8 +8,8 @@ class VisitsGroup{
String travelingHours; String travelingHours;
String jobSheetNumber; String jobSheetNumber;
String image; String image;
Status status; Lookup status;
Status taskStatus; Lookup taskStatus;
DateTime date; DateTime date;
List<Visit> visits; List<Visit> visits;

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

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

@ -280,45 +280,46 @@ class _LandPageState extends State<LandPage> {
}, },
), ),
Expanded( Spacer(),
child: MaterialButton( // Expanded(
splashColor: AColors.secondaryColor.withOpacity(.5), // child: MaterialButton(
child: Row( // splashColor: AColors.secondaryColor.withOpacity(.5),
mainAxisAlignment: MainAxisAlignment.center, // child: Row(
children: [ // mainAxisAlignment: MainAxisAlignment.center,
Container( // children: [
padding: EdgeInsets.all(12), // Container(
decoration: BoxDecoration( // padding: EdgeInsets.all(12),
borderRadius: BorderRadius.circular( // decoration: BoxDecoration(
8 * AppStyle.getScaleFactor(context) // borderRadius: BorderRadius.circular(
), // 8 * AppStyle.getScaleFactor(context)
color: AColors.onPrimaryColor // ),
), // color: AColors.onPrimaryColor
child: Icon( // ),
Icons.phone_in_talk, // child: Icon(
color: AColors.primaryColor , // Icons.phone_in_talk,
size: 32, // color: AColors.primaryColor ,
), // size: 32,
), // ),
SizedBox( // ),
width: 12 * AppStyle.getScaleFactor(context), // SizedBox(
), // width: 12 * AppStyle.getScaleFactor(context),
Text( // ),
"${_subtitle.hotLine}\n15564", // Text(
// "${_subtitle.hotLine}\n ",
style: Theme.of(context).textTheme.headline6.copyWith( //
color: AColors.white, // style: Theme.of(context).textTheme.headline6.copyWith(
letterSpacing: 2.75, // color: AColors.white,
fontWeight: FontWeight.bold // letterSpacing: 2.75,
), // fontWeight: FontWeight.bold
), // ),
], // ),
), // ],
onPressed: (){ // ),
launch("tel:15564"); // onPressed: (){
}, // //launch("tel:15564");
), // },
), // ),
// ),
AIconButton( AIconButton(
iconData: Icons.notifications, iconData: Icons.notifications,
onPressed: (){ onPressed: (){
@ -349,7 +350,6 @@ class _LandPageState extends State<LandPage> {
onPressed: (){ onPressed: (){
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pushNamed(ProfilePage.id); Navigator.of(context).pushNamed(ProfilePage.id);
}, },
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -366,9 +366,7 @@ class _LandPageState extends State<LandPage> {
shape: BoxShape.circle shape: BoxShape.circle
), ),
child: ClipOval( child: ClipOval(
child: ImageLoader( child: Icon(Icons.person,size: 72,color: Theme.of(context).colorScheme.primary,),
url: "https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png",
),
), ),
), ),
Text( Text(
@ -419,20 +417,20 @@ class _LandPageState extends State<LandPage> {
), ),
], ],
), ),
DrawerItem( // DrawerItem(
icon: FontAwesomeIcons.linkedinIn, // icon: FontAwesomeIcons.linkedinIn,
title: _subtitle.linkedIn, // title: _subtitle.linkedIn,
onPressed: (){ // onPressed: (){
launch("https://www.linkedin.com/company/Test SA/"); // launch("https://www.linkedin.com/company/Test SA/");
}, // },
), // ),
DrawerItem( // DrawerItem(
icon: FontAwesomeIcons.globe, // icon: FontAwesomeIcons.globe,
title: _subtitle.ourWebsite, // title: _subtitle.ourWebsite,
onPressed: (){ // onPressed: (){
launch("https://www.Test SA.com/"); // launch("https://www.Test SA.com/");
}, // },
), // ),
DrawerItem( DrawerItem(
icon: Icons.share, icon: Icons.share,
title: _subtitle.shareApp, 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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/sound/record_sound.dart'; import 'package:test_sa/views/widgets/sound/record_sound.dart';
import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.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 { class CreateRequestPage extends StatefulWidget {
static final String id = "/create-request"; static final String id = "/create-request";
@override @override
@ -120,9 +123,9 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
enable: false, enable: false,
initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound, initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound,
hintText: _subtitle.hospital, hintText: _subtitle.hospital,
prefixIconData: FontAwesomeIcons.hospitalAlt, prefixIconData: FontAwesomeIcons.hospital,
prefixIconSize: 36, prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.subtitle1,
), ),
const SizedBox(height: 8,), const SizedBox(height: 8,),
_userProvider.user.department == null ? SizedBox.shrink() : _userProvider.user.department == null ? SizedBox.shrink() :
@ -132,7 +135,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
hintText: _subtitle.unite, hintText: _subtitle.unite,
prefixIconData: FontAwesomeIcons.hospitalUser, prefixIconData: FontAwesomeIcons.hospitalUser,
prefixIconSize: 36, prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.subtitle1,
), ),
const SizedBox(height: 8,), const SizedBox(height: 8,),
DeviceButton( DeviceButton(
@ -142,6 +145,24 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
setState(() {}); 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( MultiImagesPicker(
label: _subtitle.deviceImages, label: _subtitle.deviceImages,
images: _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/part.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/status.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
@ -68,7 +68,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
void initState() { void initState() {
_serviceReport = ServiceReport( _serviceReport = ServiceReport(
visitDate: DateTime.now(), visitDate: DateTime.now(),
type: const Status(id: 2), type: const Lookup(id: 2),
device: Device( device: Device(
id: widget.request.deviceId, id: widget.request.deviceId,
serialNumber: widget.request.deviceSerialNumber, serialNumber: widget.request.deviceSerialNumber,
@ -159,25 +159,25 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
Row( Row(
children: [ children: [
// Report Status // Report Status
Expanded( // Expanded(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
ASubTitle(_subtitle.reportType), // ASubTitle(_subtitle.reportType),
_validate && _serviceReport.type == null ? // _validate && _serviceReport.type == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,): // ASubTitle(_subtitle.requiredWord,color: Colors.red,):
const SizedBox.shrink(), // const SizedBox.shrink(),
const SizedBox(height: 4,), // const SizedBox(height: 4,),
ServiceReportTypeMenu( // ServiceReportTypeMenu(
initialValue: _serviceReport.type, // initialValue: _serviceReport.type,
onSelect: (status){ // onSelect: (status){
_serviceReport.type = status; // _serviceReport.type = status;
}, // },
), // ),
], // ],
), // ),
), // ),
const SizedBox(width: 8,), // const SizedBox(width: 8,),
// visit date // visit date
Expanded( Expanded(
child: Column( child: Column(
@ -490,9 +490,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
textAlign: TextAlign.center, textAlign: TextAlign.center,
hintText: "i.e 3, 3.5, 4", hintText: "i.e 3, 3.5, 4",
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
validator: (value) => // validator: (value) =>
Validator.isNumeric(value) // Validator.isNumeric(value)
? null : _subtitle.requiredWord, // ? null : _subtitle.requiredWord,
textInputType: TextInputType.number, textInputType: TextInputType.number,
onSaved: (value){ onSaved: (value){
_serviceReport.travelingHours = value; _serviceReport.travelingHours = value;
@ -507,29 +507,29 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// Operating Hours and Job Sheet Number // Operating Hours and Job Sheet Number
Row( Row(
children: [ children: [
Expanded( // Expanded(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
ASubTitle(_subtitle.operatingHours), // ASubTitle(_subtitle.operatingHours),
const SizedBox(height: 4,), // const SizedBox(height: 4,),
ATextFormField( // ATextFormField(
initialValue: _serviceReport?.operatingHours, // initialValue: _serviceReport?.operatingHours,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
hintText: "i.e 3, 3.5, 4", // hintText: "i.e 3, 3.5, 4",
style: Theme.of(context).textTheme.subtitle1, // style: Theme.of(context).textTheme.subtitle1,
validator: (value) => // validator: (value) =>
Validator.isNumeric(value) // Validator.isNumeric(value)
? null : _subtitle.requiredWord, // ? null : _subtitle.requiredWord,
textInputType: TextInputType.number, // textInputType: TextInputType.number,
onSaved: (value){ // onSaved: (value){
_serviceReport.operatingHours = value; // _serviceReport.operatingHours = value;
}, // },
), // ),
], // ],
), // ),
), // ),
const SizedBox(width: 8,), // const SizedBox(width: 8,),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, 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/part.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/status.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';

@ -182,6 +182,10 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.code, title: _subtitle.code,
info: serviceRequest.requestCode, info: serviceRequest.requestCode,
), ),
RequestInfoRow(
title: "Asset Number",
info: serviceRequest.deviceNumber,
),
RequestInfoRow( RequestInfoRow(
title: _subtitle.deviceSN, title: _subtitle.deviceSN,
info: serviceRequest.deviceSerialNumber, info: serviceRequest.deviceSerialNumber,
@ -230,10 +234,10 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.unite, title: _subtitle.unite,
info: serviceRequest.departmentName, info: serviceRequest.departmentName,
), ),
RequestInfoRow( // RequestInfoRow(
title: _subtitle.deviceArName, // title: _subtitle.deviceArName,
content: serviceRequest.deviceArName, // content: serviceRequest.deviceArName,
), // ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.deviceEnName, title: _subtitle.deviceEnName,
content: serviceRequest.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 'dart:io';
import 'package:test_sa/controllers/localization/localization.dart'; 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/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart'; import 'package:test_sa/models/visits/visits_group.dart';
@ -26,15 +26,15 @@ class UpdateVisitsGroupSheet extends StatefulWidget {
} }
class _UpdateVisitsGroupSheetState extends State<UpdateVisitsGroupSheet> { class _UpdateVisitsGroupSheetState extends State<UpdateVisitsGroupSheet> {
List<Status> status = [ List<Lookup> status = [
Status(label: "Done", id: 0,), Lookup(label: "Done", id: 0,),
Status(label: "Not Yet", id: 1), Lookup(label: "Not Yet", id: 1),
Status(label: "On Hold", id: 2,), Lookup(label: "On Hold", id: 2,),
]; ];
List<Status> taskStatus = [ List<Lookup> taskStatus = [
Status(label: "Passed", id: 0,), Lookup(label: "Passed", id: 0,),
Status(label: "Failed", id: 1), Lookup(label: "Failed", id: 1),
]; ];
VisitsGroup _group = VisitsGroup(); VisitsGroup _group = VisitsGroup();
File _image; File _image;

@ -1,15 +1,20 @@
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.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/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/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_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/images/images_list.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/visits/visit_status.dart'; import 'package:test_sa/views/widgets/visits/visit_status.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../controllers/providers/api/regular_visits_provider.dart';
class VisitDetailsPage extends StatelessWidget { class VisitDetailsPage extends StatelessWidget {
static final String id = "/visit-details"; static final String id = "/visit-details";
final Visit visit; final Visit visit;
@ -18,6 +23,7 @@ class VisitDetailsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context).subtitle;
final regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
child: Column( 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, title: _subtitle.code,
info: visit.serialNumber, info: visit.serialNumber,
), ),
RequestInfoRow(
title: "Asset Number",
info: visit.deviceNumber,
),
RequestInfoRow( RequestInfoRow(
title: _subtitle.deviceSN, title: _subtitle.deviceSN,
info: visit.deviceSerialNumber, info: visit.deviceSerialNumber,

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

@ -43,65 +43,52 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<DevicesProvider>(context); _devicesProvider = Provider.of<DevicesProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle; //Subtitle _subtitle = AppLocalization.of(context).subtitle;
return LoadingManager( return Container(
isLoading: _devicesProvider.isLoading, padding: const EdgeInsets.symmetric(
isFailedLoading: _devicesProvider.devices == null, horizontal: 16
stateCode: _devicesProvider.stateCode, ),
onRefresh: () async { decoration: BoxDecoration(
_devicesProvider.reset(); color: Colors.white,
await _devicesProvider.getEquipment( border: Border.all(color:AColors.black),
host: _settingProvider.host, borderRadius: BorderRadius.circular(
user: _userProvider.user, AppStyle.borderRadius * AppStyle.getScaleFactor(context)
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
]
), ),
child: TypeAheadField<Device>( boxShadow: [
textFieldConfiguration: TextFieldConfiguration( AppStyle.boxShadow
style: Theme.of(context).textTheme.headline6, ]
controller: _controller, ),
textAlign: TextAlign.center, child: TypeAheadField<Device>(
decoration: InputDecoration( textFieldConfiguration: TextFieldConfiguration(
border: InputBorder.none, style: Theme.of(context).textTheme.headline6,
disabledBorder: InputBorder.none, controller: _controller,
focusedBorder: InputBorder.none, textAlign: TextAlign.center,
enabledBorder: InputBorder.none, decoration: const InputDecoration(
), border: InputBorder.none,
textInputAction: TextInputAction.search, disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
), ),
suggestionsCallback: (vale) async { textInputAction: TextInputAction.search,
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);
},
),
), ),
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( child: Column(
children: [ children: [
SizedBox(height: 48,), const SizedBox(height: 48,),
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16),
child: ATextFormField( child: Column(
hintText: _subtitle.searchBySn, children: [
style: Theme.of(context).textTheme.headline6, ATextFormField(
suffixIcon: const Icon(Icons.search_rounded), hintText: _subtitle.searchBySn,
onChange: (value){ style: Theme.of(context).textTheme.subtitle1,
_searchableList.clear(); suffixIcon: const Icon(Icons.search_rounded),
_searchableList.addAll(_devicesProvider.devices.where( onChange: (value){
(element) => element.serialNumber.toLowerCase().contains( _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() value.toLowerCase()
) )
).toList()); ).toList());
setState(() {}); setState(() {});
}, },
),
],
), ),
), ),
Expanded( Expanded(

@ -9,18 +9,18 @@ import 'package:test_sa/views/widgets/hospitals/hospital_item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class AutoCompleteField extends StatefulWidget { class HospitalAutoCompleteField extends StatefulWidget {
final String initialValue; final String initialValue;
final Function(String) onSearch; final Function(String) onSearch;
final Function(String) onSave; 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 @override
_AutoCompleteFieldState createState() => _AutoCompleteFieldState(); _HospitalAutoCompleteFieldState createState() => _HospitalAutoCompleteFieldState();
} }
class _AutoCompleteFieldState extends State<AutoCompleteField> { class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
SettingProvider _settingProvider; SettingProvider _settingProvider;
TextEditingController _controller; TextEditingController _controller;
@ -56,7 +56,6 @@ class _AutoCompleteFieldState extends State<AutoCompleteField> {
] ]
), ),
child: TypeAheadField<Hospital>( child: TypeAheadField<Hospital>(
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.headline6,
onSubmitted: widget.onSave, onSubmitted: widget.onSave,

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

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

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

@ -251,57 +251,6 @@ class ServiceRequestItem extends StatelessWidget {
color: onItemColor 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/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.dart';
import 'package:test_sa/models/service_request/service_request_search.dart'; import 'package:test_sa/models/service_request/service_request_search.dart';
import 'package:test_sa/models/status.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.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/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.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:flutter/material.dart';
import 'package:test_sa/views/widgets/status/employee/employee_mune.dart'; import 'package:test_sa/views/widgets/status/employee/employee_mune.dart';
@ -33,7 +33,7 @@ class _ServiceRequestsUpdateDialogState extends State<ServiceRequestsUpdateDialo
with TickerProviderStateMixin{ with TickerProviderStateMixin{
DateTime _dateTime; DateTime _dateTime;
Status _employee; Lookup _employee;
Subtitle _subtitle; Subtitle _subtitle;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; 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/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class FilterItem extends StatelessWidget { class FilterItem extends StatelessWidget {
final bool isSelected; final bool isSelected;
final Status status; final Lookup status;
final VoidCallback onSelected; final VoidCallback onSelected;
const FilterItem({ const FilterItem({

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

@ -1,12 +1,12 @@
import 'package:test_sa/controllers/localization/localization.dart'; 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/subtitle.dart';
import 'package:test_sa/models/visits/visits_search.dart'; import 'package:test_sa/models/visits/visits_search.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.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/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/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:test_sa/views/widgets/titles/app_sub_title.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -31,16 +31,16 @@ class VisitsSearchDialog extends StatefulWidget {
class _VisitsSearchDialogState extends State<VisitsSearchDialog> class _VisitsSearchDialogState extends State<VisitsSearchDialog>
with TickerProviderStateMixin{ with TickerProviderStateMixin{
VisitsSearch _search; VisitsSearch _search;
List<Status> status = [ List<Lookup> status = [
Status(label: "Done", id: 0,), Lookup(label: "Done", id: 0,),
Status(label: "Not Yet", id: 1), Lookup(label: "Not Yet", id: 1),
Status(label: "On Hold", id: 2,), Lookup(label: "On Hold", id: 2,),
]; ];
List<Status> contactStatus = [ List<Lookup> contactStatus = [
Status(label: "Hospital Employee", key: "H",), Lookup(label: "Hospital Employee", key: "H",),
Status(label: "Under Warranty", key: "CW"), Lookup(label: "Under Warranty", key: "CW"),
Status(label: "Under Maintenance Contract", key: "CC",), Lookup(label: "Under Maintenance Contract", key: "CC",),
]; ];
@ -100,7 +100,7 @@ class _VisitsSearchDialogState extends State<VisitsSearchDialog>
}, },
), ),
SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),), SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
AutoCompleteField( HospitalAutoCompleteField(
initialValue: _search.hospitalName, initialValue: _search.hospitalName,
onSave: (value){ onSave: (value){
_search.hospitalName = 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/status_drop_down/employee/employee_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class EmployeeMenu extends StatelessWidget { class EmployeeMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final Status initialValue; final Lookup initialValue;
const EmployeeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const EmployeeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @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/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class GasCylinderSizeMenu extends StatelessWidget { class GasCylinderSizeMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final Status initialValue; final Lookup initialValue;
const GasCylinderSizeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const GasCylinderSizeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @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/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class GasStatusMenu extends StatelessWidget { class GasStatusMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final Status initialValue; final Lookup initialValue;
const GasStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const GasStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @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/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class GasTypeMenu extends StatelessWidget { class GasTypeMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final Status initialValue; final Lookup initialValue;
const GasTypeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const GasTypeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @override

@ -1,14 +1,14 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_typeahead/flutter_typeahead.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/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
class MultiStatusMenu extends StatefulWidget { class MultiStatusMenu extends StatefulWidget {
final List<Status> statuses; final List<Lookup> statuses;
final List<Status> initialSelectedStatus; final List<Lookup> initialSelectedStatus;
final Function(List<Status>) onSelect; final Function(List<Lookup>) onSelect;
const MultiStatusMenu({Key key, this.statuses, this.onSelect, this.initialSelectedStatus}) : super(key: key); const MultiStatusMenu({Key key, this.statuses, this.onSelect, this.initialSelectedStatus}) : super(key: key);
@override @override
@ -17,7 +17,7 @@ class MultiStatusMenu extends StatefulWidget {
class _MultiStatusMenuState extends State<MultiStatusMenu> { class _MultiStatusMenuState extends State<MultiStatusMenu> {
List<Status> _selectedStatus = []; List<Lookup> _selectedStatus = [];
TextEditingController _controller; TextEditingController _controller;
@override @override
@ -93,7 +93,7 @@ class _MultiStatusMenuState extends State<MultiStatusMenu> {
AppStyle.boxShadow AppStyle.boxShadow
] ]
), ),
child: TypeAheadField<Status>( child: TypeAheadField<Lookup>(
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
controller: _controller, controller: _controller,
@ -107,7 +107,7 @@ class _MultiStatusMenuState extends State<MultiStatusMenu> {
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
), ),
suggestionsCallback: (vale) { suggestionsCallback: (vale) {
return widget.statuses.where((Status option) { return widget.statuses.where((Lookup option) {
return option.label.toLowerCase().contains(_controller.text); 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/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/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ServiceReportLastCallsMenu extends StatelessWidget { class ServiceReportLastCallsMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final ServiceReport report; final ServiceReport report;
const ServiceReportLastCallsMenu({ 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/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/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ServiceReportReasonsMenu extends StatelessWidget { class ServiceReportReasonsMenu extends StatelessWidget {
final Status initialValue; final Lookup initialValue;
final Function(Status) onSelect; final Function(Lookup) onSelect;
const ServiceReportReasonsMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const ServiceReportReasonsMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @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/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/service_report.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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ServiceReportStatusMenu extends StatefulWidget { class ServiceReportStatusMenu extends StatefulWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final ServiceReport report; final ServiceReport report;
const ServiceReportStatusMenu({Key key, this.onSelect, this.report}) : super(key: key); 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/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/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ServiceReportTypeMenu extends StatelessWidget { class ServiceReportTypeMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final Status initialValue; final Lookup initialValue;
const ServiceReportTypeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const ServiceReportTypeMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SettingProvider _settingProvider = Provider.of<SettingProvider>(context); SettingProvider settingProvider = Provider.of<SettingProvider>(context);
UserProvider _userProvider = Provider.of<UserProvider>(context); UserProvider userProvider = Provider.of<UserProvider>(context);
ServiceReportTypesProvider _menuProvider = Provider.of<ServiceReportTypesProvider>(context); ServiceReportTypesProvider menuProvider = Provider.of<ServiceReportTypesProvider>(context);
return LoadingManager( return LoadingManager(
isLoading: _menuProvider.isLoading, isLoading: menuProvider.isLoading,
isFailedLoading: _menuProvider.types == null, isFailedLoading: menuProvider.types == null,
stateCode: _menuProvider.stateCode, stateCode: menuProvider.stateCode,
onRefresh: () async { onRefresh: () async {
_menuProvider.reset(); menuProvider.reset();
await _menuProvider.getTypes( await menuProvider.getTypes(
user: _userProvider.user, user: userProvider.user,
host: _settingProvider.host host: settingProvider.host
); );
onSelect(initialValue ?? _menuProvider.types?.last); onSelect(initialValue ?? menuProvider.types?.last);
}, },
child: SingleStatusMenu( child: SingleStatusMenu(
initialStatus: initialValue ?? _menuProvider.types?.last, initialStatus: initialValue ?? menuProvider.types?.last,
statuses: _menuProvider.types, statuses: menuProvider.types,
onSelect: onSelect, 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/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/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/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ServiceStatusMenu extends StatelessWidget { class ServiceStatusMenu extends StatelessWidget {
final Function(Status) onSelect; final Function(Lookup) onSelect;
final Status initialValue; final Lookup initialValue;
const ServiceStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const ServiceStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override @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/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SingleStatusMenu extends StatefulWidget { class SingleStatusMenu extends StatefulWidget {
final List<Status> statuses; final List<Lookup> statuses;
final Status initialStatus; final Lookup initialStatus;
final Function(Status) onSelect; final Function(Lookup) onSelect;
const SingleStatusMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); const SingleStatusMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key);
@override @override
@ -14,7 +14,7 @@ class SingleStatusMenu extends StatefulWidget {
class _SingleStatusMenuState extends State<SingleStatusMenu> { class _SingleStatusMenuState extends State<SingleStatusMenu> {
Status _selectedStatus; Lookup _selectedStatus;
@override @override
void didUpdateWidget(covariant SingleStatusMenu oldWidget) { void didUpdateWidget(covariant SingleStatusMenu oldWidget) {
@ -56,7 +56,7 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
AppStyle.boxShadow AppStyle.boxShadow
] ]
), ),
child: DropdownButton<Status>( child: DropdownButton<Lookup>(
value: _selectedStatus, value: _selectedStatus,
iconSize: 24, iconSize: 24,
elevation: 16, elevation: 16,
@ -69,15 +69,15 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
color: Theme.of(context).primaryColor color: Theme.of(context).primaryColor
), ),
underline: SizedBox.shrink(), underline: SizedBox.shrink(),
onChanged: (Status newValue) { onChanged: (Lookup newValue) {
setState(() { setState(() {
_selectedStatus = newValue; _selectedStatus = newValue;
}); });
widget.onSelect(newValue); widget.onSelect(newValue);
}, },
items: widget.statuses items: widget.statuses
.map<DropdownMenuItem<Status>>((Status value) { .map<DropdownMenuItem<Lookup>>((Lookup value) {
return DropdownMenuItem<Status>( return DropdownMenuItem<Lookup>(
value: value, value: value,
child: Text( child: Text(
value.label, value.label,

@ -30,19 +30,19 @@ class _AppTimerState extends State<AppTimer> {
final ValueNotifier<String> _period = ValueNotifier("0:00:00"); final ValueNotifier<String> _period = ValueNotifier("0:00:00");
_startTimer() async { _startTimer() async {
final time = DateTime.now(); if (!_running) {
bool result = await widget.onChange( final time = DateTime.now();
TimerModel(startAt: time,endAt: null,durationInSecond: _delay)); bool result = await widget.onChange(
if(!result) return; TimerModel(startAt: time,endAt: null,durationInSecond: _delay));
_running = true; if(!result) return;
_running = true;
if(_endAt != null){ if(_endAt != null){
_delay += _endAt.difference(_startAt).inSeconds; _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) { _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if(_loading == true) return; if(_loading == true) return;
@ -78,32 +78,13 @@ class _AppTimerState extends State<AppTimer> {
@override @override
void initState() { 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; _startAt = widget.timer?.startAt;
_endAt = widget.timer?.endAt; _endAt = widget.timer?.endAt;
_running = _startAt != null && _endAt == null; _running = _startAt != null && _endAt == null;
_delay = (widget.timer?.durationInSecond ?? 0); _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(); super.initState();
if(_running){_startTimer();} 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,), Divider(color: onItemColor,),
Row( Row(
children: [ 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. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.6.1+1 version: 0.7.4+1
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.7.0 <3.0.0"

Loading…
Cancel
Save