2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 13:36:50 +00:00

API post request now uses HttpClient

This commit is contained in:
Oliver Walters 2021-04-19 21:56:20 +10:00
parent 71340da068
commit b8c535560d
6 changed files with 118 additions and 103 deletions

View File

@ -388,22 +388,96 @@ class InvenTreeAPI {
return response; return response;
} }
// Perform a POST request /**
Future<http.Response> post(String url, {Map<String, dynamic> body}) async { * Perform a HTTP POST request
* Returns a json object (or null if unsuccessful)
*/
Future<dynamic> post(String url, {Map<String, dynamic> body, int expectedStatusCode=201}) async {
var _url = makeApiUrl(url); var _url = makeApiUrl(url);
var _headers = jsonHeaders(); var _headers = jsonHeaders();
print("POST: ${_url} -> ${body.toString()}"); print("POST: ${_url} -> ${body.toString()}");
var data = jsonEncode(body); var client = createClient(true);
return http.post(_url, HttpClientRequest request = await client.postUrl(Uri.parse(_url));
headers: _headers,
body: data, var data = json.encode(body);
);
// Set headers
// Ref: https://stackoverflow.com/questions/59713003/body-not-sending-using-map-in-flutter
request.headers.set('Accept', 'application/json');
request.headers.set('Content-type', 'application/json');
request.headers.set('Content-Length', data.length.toString());
if (profile != null) {
request.headers.set(
HttpHeaders.authorizationHeader,
_authorizationHeader(profile.username, profile.password)
);
}
// Add JSON data to the request
request.add(utf8.encode(data));
HttpClientResponse response = await request.close()
.timeout(Duration(seconds: 30))
.catchError((error) {
print("POST request returned error");
print("URL: ${_url}");
print("Error: ${error.toString()}");
var ctx = OneContext().context;
if (error is SocketException) {
showServerError(
I18N.of(ctx).connectionRefused,
error.toString()
);
} else if (error is TimeoutException) {
showTimeoutError(ctx);
} else {
showServerError(
I18N.of(ctx).serverError,
error.toString()
);
}
return null;
});
if (response == null) {
print("null response from POST ${_url}");
return null;
}
if (response.statusCode != expectedStatusCode) {
showStatusCodeError(response.statusCode);
return null;
}
// Convert the body of the response to a JSON object
String responseData = await response.transform(utf8.decoder).join();
try {
var data = json.decode(responseData);
return data;
} on FormatException {
print("JSON format exception!");
print("${responseData}");
showServerError(
"Format Exception",
"JSON data format exception:\n${responseData}"
);
return null;
}
} }
HttpClient _client(bool allowBadCert) { HttpClient createClient(bool allowBadCert) {
var client = new HttpClient(); var client = new HttpClient();
@ -433,7 +507,7 @@ class InvenTreeAPI {
* Perform a HTTP GET request * Perform a HTTP GET request
* Returns a json object (or null if did not complete) * Returns a json object (or null if did not complete)
*/ */
Future<dynamic> get(String url, {Map<String, String> params}) async { Future<dynamic> get(String url, {Map<String, String> params, int expectedStatusCode=200}) async {
var _url = makeApiUrl(url); var _url = makeApiUrl(url);
var _headers = defaultHeaders(); var _headers = defaultHeaders();
@ -455,9 +529,7 @@ class InvenTreeAPI {
print("GET: " + _url); print("GET: " + _url);
var client = _client(true); var client = createClient(true);
print("Created client");
HttpClientRequest request = await client.getUrl(Uri.parse(_url)); HttpClientRequest request = await client.getUrl(Uri.parse(_url));
@ -470,8 +542,6 @@ class InvenTreeAPI {
); );
} }
print("Created request: ${request.uri}");
HttpClientResponse response = await request.close() HttpClientResponse response = await request.close()
.timeout(Duration(seconds: 30)) .timeout(Duration(seconds: 30))
.catchError((error) { .catchError((error) {
@ -505,7 +575,7 @@ class InvenTreeAPI {
} }
// Check the status code of the response // Check the status code of the response
if (response.statusCode != 200) { if (response.statusCode != expectedStatusCode) {
showStatusCodeError(response.statusCode); showStatusCodeError(response.statusCode);
return null; return null;
} }

View File

@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:one_context/one_context.dart'; import 'package:one_context/one_context.dart';
import 'package:device_info/device_info.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:InvenTree/inventree/stock.dart'; import 'package:InvenTree/inventree/stock.dart';
@ -21,7 +20,6 @@ import 'package:InvenTree/widget/part_detail.dart';
import 'package:InvenTree/widget/stock_detail.dart'; import 'package:InvenTree/widget/stock_detail.dart';
import 'dart:io'; import 'dart:io';
import 'dart:convert';
class BarcodeHandler { class BarcodeHandler {
@ -88,49 +86,34 @@ class BarcodeHandler {
_controller.resumeCamera(); _controller.resumeCamera();
} }
Future<void> processBarcode(BuildContext context, QRViewController _controller, String barcode, {String url = "barcode/"}) { Future<void> processBarcode(BuildContext context, QRViewController _controller, String barcode, {String url = "barcode/"}) async {
this._context = context; this._context = context;
this._controller = _controller; this._controller = _controller;
print("Scanned barcode data: ${barcode}"); print("Scanned barcode data: ${barcode}");
// Send barcode request to server var data = await InvenTreeAPI().post(
InvenTreeAPI().post(
url, url,
body: { body: {
"barcode": barcode "barcode": barcode,
} },
).then((var response) { expectedStatusCode: 200
);
if (response.statusCode != 200) {
showStatusCodeError(response.statusCode);
_controller.resumeCamera();
return;
}
// Decode the response
final Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
_controller.resumeCamera();
onBarcodeUnknown(data);
} else if (data.containsKey('success')) {
_controller.resumeCamera();
onBarcodeMatched(data);
} else {
_controller.resumeCamera();
onBarcodeUnhandled(data);
}
}).timeout(
Duration(seconds: 5)
).catchError((error) {
showServerError(I18N.of(OneContext().context).error, error.toString());
_controller.resumeCamera();
if (data == null) {
return; return;
}); }
if (data.containsKey('error')) {
_controller.resumeCamera();
onBarcodeUnknown(data);
} else if (data.containsKey('success')) {
_controller.resumeCamera();
onBarcodeMatched(data);
} else {
_controller.resumeCamera();
onBarcodeUnhandled(data);
}
} }
} }

View File

@ -262,36 +262,13 @@ class InvenTreeModel {
InvenTreeModel _model; InvenTreeModel _model;
await api.post(URL, body: data).timeout(Duration(seconds: 10)).catchError((e) { var response = await api.post(URL, body: data);
print("Error during CREATE");
print(e.toString());
if (e is SocketException) {
showServerError(
I18N.of(context).connectionRefused,
e.toString()
);
}
else if (e is TimeoutException) {
showTimeoutError(context);
} else {
// Re-throw the error
throw e;
}
if (response == null) {
return null; return null;
}) }
.then((http.Response response) {
// Server should return HTTP_201_CREATED
if (response.statusCode == 201) {
var decoded = json.decode(response.body);
_model = createFromJson(decoded);
} else {
showStatusCodeError(response.statusCode);
}
});
return _model; return createFromJson(response);
} }
Future<InvenTreePageResponse> listPaginated(int limit, int offset, {Map<String, String> filters}) async { Future<InvenTreePageResponse> listPaginated(int limit, int offset, {Map<String, String> filters}) async {

View File

@ -437,31 +437,14 @@ class InvenTreeStockItem extends InvenTreeModel {
endpoint, endpoint,
body: { body: {
"item": { "item": {
"pk": "${pk}", "pk": "${pk}",
"quantity": "${q}", "quantity": "${q}",
}, },
"notes": notes ?? '', "notes": notes ?? '',
}).timeout(Duration(seconds: 10)).catchError((error) {
if (error is TimeoutException) {
showTimeoutError(context);
} else if (error is SocketException) {
showServerError(
I18N.of(context).connectionRefused,
error.toString()
);
} else {
// Re-throw the error
throw error;
} }
);
// Null response if error if (response == null) {
return null;
});
if (response == null) return false;
if (response.statusCode != 200) {
showStatusCodeError(response.statusCode);
return false; return false;
} }
@ -508,9 +491,13 @@ class InvenTreeStockItem extends InvenTreeModel {
data["item"]["quantity"] = "${quantity}"; data["item"]["quantity"] = "${quantity}";
} }
print("transfer stock!");
final response = await api.post("/stock/transfer/", body: data); final response = await api.post("/stock/transfer/", body: data);
return (response.statusCode == 200); print("transfer response: ${response}");
return response != null;
} }
} }

View File

@ -208,8 +208,6 @@ void showFormDialog(String title, {String acceptText, String cancelText, GlobalK
if (key.currentState.validate()) { if (key.currentState.validate()) {
key.currentState.save(); key.currentState.save();
print("Saving and closing the dialog");
// Close the dialog // Close the dialog
Navigator.pop(dialogContext); Navigator.pop(dialogContext);

View File

@ -247,7 +247,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
void _transferStock(BuildContext context, InvenTreeStockLocation location) async { void _transferStock(BuildContext context, InvenTreeStockLocation location) async {
double quantity = double.parse(_quantityController.text); double quantity = double.tryParse(_quantityController.text) ?? item.quantity;
String notes = _notesController.text; String notes = _notesController.text;
_quantityController.clear(); _quantityController.clear();