change Api structure for request gas refill page + solve null safety bugs faced it during restructure the code

merge-requests/13/head
nextwo 3 years ago
parent 7b31efc2ab
commit 1e06449d8d

@ -0,0 +1,94 @@
import 'dart:convert';
import 'package:test_sa/api/user_api_client.dart';
import '../controllers/api_routes/urls.dart';
import '../models/gas_refill/gas_refill_model.dart';
import 'api_client.dart';
class GasRefillApiClient{
static final GasRefillApiClient _instance =GasRefillApiClient._internal();
GasRefillApiClient._internal();
factory GasRefillApiClient() =>_instance;
Future<List<GasRefillModel>> getRequestPages({
required List items,
required int pageItemNumber
}) async {
final response = await ApiClient().getJsonForResponse(
"${URLs.host1}${URLs.getGasRefill}",//body
headers: {"Content-Type": "application/json; charset=utf-8"},
queryParameters: {
"uid":"${UserApiClient().user?.id}",
"token":"${UserApiClient().user?.token}",
"page":"${(items.length) ~/ pageItemNumber}",
}
);
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
return requestsListJson.map((request) => GasRefillModel.fromJson(request)).toList();
}
Future<GasRefillModel> createModel({
required GasRefillModel model,
}) async{
Map<String, dynamic> body = {
"uid": UserApiClient().user?.id.toString(),
"token": UserApiClient().user?.token ?? "",
"title": model.title ?? "",
"status": "0", //model.status.value.toString(),
};
body["details"] = jsonEncode(model.details
?.map((model) => {
"type": model.type?.id.toString(),
"size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
})
.toList());
final response = await ApiClient().postJsonForResponse(
"${URLs.host1}${URLs.requestGasRefill}",
body,
);
return GasRefillModel.fromJson(json.decode(utf8.decode(response.bodyBytes))[0]);
}
Future updateModel({
required GasRefillModel? oldModel,
required GasRefillModel newModel,
})async{
Map<String, dynamic> body = {
"uid": UserApiClient().user?.id.toString(),
"token": UserApiClient().user?.token,
"title": newModel.title,
"status": newModel.status?.id.toString(),
};
body["details"] = jsonEncode(newModel.details
?.map((model) => {
"type": model.type?.id.toString(),
"size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
"deliverd_qty": model.deliveredQuantity.toString(),
})
.toList());
final reponse = await ApiClient().postJsonForResponse(
"${URLs.host1}${URLs.updateGasRefill}/${newModel.id}",
body);
oldModel?.fromGasRefillModel(newModel);
}
}

@ -1,19 +1,25 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart';
import 'package:test_sa/api/gas_refill_api_client.dart';
import '../../../models/gas_refill/gas_refill_model.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
import '../loading_notifier.dart';
class GasRefillProvider extends ChangeNotifier {
class GasRefillProvider extends LoadingNotifier {
// number of items call in each request
final pageItemNumber = 50;
//reset provider data
void reset() {
items = null;
items.clear();
nextPage = true;
stateCode = null;
}
@ -27,134 +33,53 @@ class GasRefillProvider extends ChangeNotifier {
bool nextPage = true;
// list of user requests
List<GasRefillModel>? items;
// when requests in-process _loading = true
// done _loading = true
// failed _loading = false
bool? isLoading;
/// return -2 if request in progress
/// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getRequests({
required String host,
required User user,
}) async {
if (isLoading == true) {
return -2;
}
isLoading = true;
Response response;
try {
response = await get(
Uri.parse("$host${URLs.getGasRefill}?uid=${user.id}"
"&token=${user.token}&page=${(items?.length ?? 0) ~/ pageItemNumber}"),
headers: {"Content-Type": "application/json; charset=utf-8"});
stateCode = response.statusCode;
if (stateCode != null && stateCode! >= 200 && stateCode! < 300) {
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<GasRefillModel> itemsPage = requestsListJson.map((request) => GasRefillModel.fromJson(request)).toList();
items ??= [];
items?.addAll(itemsPage);
if (itemsPage.length == pageItemNumber) {
nextPage = true;
} else {
nextPage = false;
}
List<GasRefillModel> items=[];
Future getRequests() async {
waitApiRequest(() async {
items.addAll(await GasRefillApiClient().getRequestPages(items: items, pageItemNumber: pageItemNumber));
if (items.length == pageItemNumber) {
nextPage = true;
} else {
nextPage = false;
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
});
}
Future<int> createModel({
required String host,
required User user,
Future createModel({
required GasRefillModel model,
required BuildContext context
}) async {
Map<String, dynamic> body = {
"uid": user.id.toString(),
"token": user.token ?? "",
"title": model.title ?? "",
"status": "0", //model.status.value.toString(),
};
body["details"] = jsonEncode(model.details
?.map((model) => {
"type": model.type?.id.toString(),
"size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
})
.toList());
Response response;
try {
response = await post(
Uri.parse(host + URLs.requestGasRefill),
body: body,
);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
final items = this.items;
if (items != null) {
items.insert(0, GasRefillModel.fromJson(json.decode(utf8.decode(response.bodyBytes))[0]));
notifyListeners();
}
final subtitle = AppLocalization.of(context)?.subtitle;
waitApiRequest(() async {
items.insert(0, await GasRefillApiClient().createModel(model: model));
notifyListeners();
},
onError: (error){
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
},
onSuccess: (){
Fluttertoast.showToast(
msg: subtitle?.requestCompleteSuccessfully ?? "",
);
Navigator.of(context).pop();
}
return response.statusCode;
} catch (error) {
return -1;
}
);
}
Future<int> updateModel({
required String host,
required User user,
Future updateModel({
required GasRefillModel? oldModel,
required GasRefillModel newModel,
}) async {
Map<String, dynamic> body = {
"uid": user.id.toString(),
"token": user.token,
"title": newModel.title ?? "",
"status": newModel.status?.id.toString(),
};
body["details"] = jsonEncode(newModel.details
?.map((model) => {
"type": model.type?.id.toString(),
"size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
"deliverd_qty": model.deliveredQuantity.toString(),
})
.toList());
Response response;
try {
response = await post(
Uri.parse("$host${URLs.updateGasRefill}/${newModel.id}"),
body: body,
);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
oldModel?.fromGasRefillModel(newModel);
notifyListeners();
}
return response.statusCode;
} catch (error) {
return -1;
}
await GasRefillApiClient().updateModel(oldModel: oldModel, newModel: newModel);
}
}

@ -36,7 +36,7 @@ class Validator {
}
// Return true if String is valid Numeric. Otherwise, return false
static bool isNumeric(String s) {
static bool isNumeric(String? s) {
if (s == null) {
return false;
}

@ -36,8 +36,6 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
final GasRefillModel _model = GasRefillModel();
bool _enableEdit = false;
bool _validate = false;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
GasRefillProvider? _gasRefillProvider;
bool _isLoading = false;
Subtitle? _subtitle;
@ -53,7 +51,7 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
_isLoading = true;
setState(() {});
int? status = await _gasRefillProvider?.updateModel(user: UserApiClient().user ?? User(), host: _settingProvider?.host ?? "", newModel: _model, oldModel: widget.model);
int? status = await _gasRefillProvider?.updateModel( newModel: _model, oldModel: widget.model);
_isLoading = false;
setState(() {});
if (status != null && status >= 200 && status < 300) {
@ -80,8 +78,6 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context);
return Scaffold(
key: _scaffoldKey,

@ -33,8 +33,6 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
bool _isLoading = false;
bool _validate = false;
Subtitle? _subtitle;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
GasRefillProvider? _gasRefillProvider;
GasRefillDetails _currentDetails = GasRefillDetails(model: null);
final TextEditingController _requestedQuantityController = TextEditingController();
@ -48,33 +46,6 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
if (mounted) super.setState(() {});
}
_onSubmit() async {
if ((_formModel.details?.isEmpty ?? false)) {
if (!_addNewModel()) return;
}
_isLoading = true;
setState(() {});
int? status = await _gasRefillProvider?.createModel(
user: UserApiClient().user ?? User(),
host: _settingProvider?.host ?? "",
model: _formModel,
);
_isLoading = false;
setState(() {});
if (status != null && status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle?.requestCompleteSuccessfully ?? "",
);
Navigator.of(context).pop();
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
}
bool _addNewModel() {
_validate = true;
@ -106,8 +77,6 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
@ -203,11 +172,11 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
height: 4,
),
ATextFormField(
initialValue: (_currentDetails?.requestedQuantity ?? "").toString(),
initialValue: (_currentDetails.requestedQuantity??"").toString(),
textAlign: TextAlign.center,
controller: _requestedQuantityController,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) => Validator.isNumeric(value!) ? '' : "allow numbers only",
validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only",
textInputType: TextInputType.number,
onSaved: (value) {
_currentDetails.requestedQuantity = int.tryParse(value!);
@ -237,7 +206,17 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
const SizedBox(height: 16),
AButton(
text: _subtitle?.submit ?? "",
onPressed: _onSubmit,
onPressed: () async {
if ((_formModel.details?.isEmpty ?? false)) {
if (!_addNewModel()) return;
}
await _gasRefillProvider?.createModel(
model: _formModel,
context: context
);
},
),
const SizedBox(
height: 100,

@ -36,15 +36,12 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
return Scaffold(
body: SafeArea(
child: LoadingManager(
isLoading: _gasRefillProvider?.isLoading,
isLoading: _gasRefillProvider?.loading,
isFailedLoading: _gasRefillProvider?.items == null,
stateCode: _gasRefillProvider?.stateCode,
onRefresh: () async {
_gasRefillProvider?.reset();
await _gasRefillProvider?.getRequests(
user: UserApiClient().user ?? User(),
host: _settingProvider?.host ?? "",
);
await _gasRefillProvider?.getRequests();
},
child: Stack(
children: [
@ -78,10 +75,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
child: GasRefillList(
nextPage: _gasRefillProvider?.nextPage ?? false,
onLazyLoad: () async {
await _gasRefillProvider?.getRequests(
user: UserApiClient().user ?? User(),
host: _settingProvider?.host ?? "",
);
await _gasRefillProvider?.getRequests();
},
items: _gasRefillProvider?.items ?? [],
),

Loading…
Cancel
Save