import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; class API { late SharedPreferences pref; static final API _instance = API._internal(); factory API() { return _instance; } API._internal(); Future init() async { pref = await SharedPreferences.getInstance(); instance = pref.getString("instance") ?? ""; } bool isInit() { return pref.containsKey("token") && pref.containsKey("instance"); } void save(String instance, String token) { pref.setString("instance", instance); pref.setString("token", token); this.instance = instance; } String instance = ""; Future getRequest(String url) async { var resp = await http.get(Uri.parse(url), headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json; charset=UTF-8', 'Token': pref.getString("token")! }); return utf8.decode(resp.bodyBytes); } Future postRequest(String url, Map data) async { var resp = await http.post(Uri.parse(url), headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json; charset=UTF-8', 'Token': pref.getString("token")! }, body: jsonEncode(data)); return utf8.decode(resp.bodyBytes); } // /items Future> getItems() async { var resp = jsonDecode(await getRequest("$instance/items")); var lst = resp["items"]; return lst as List; } // /item///unique? Future> getUniqueField( String item, String variant, String field) async { var resp = jsonDecode( await getRequest("$instance/item/$item/$variant/unique?field=$field")); List ret = []; for (var e in resp as List) { ret.add(e); } return ret; } Future> getLocations() async { var resp = jsonDecode(await getRequest("$instance/locations")) as Map; return resp.map((key, value) => MapEntry(key, Location(value))); } Future getItem(String item) async { return Item(jsonDecode(await getRequest("$instance/item/$item"))); } Future getTransaction(String id) async { return Transaction( jsonDecode(await getRequest("$instance/transaction/$id"))); } Future> getTransactionsOfLocation(String location, {bool recursive = true}) async { var url = "$instance/location/$location/inventory"; if (recursive) { url += "?recursive=true"; } var resp = jsonDecode(await getRequest(url)) as List; return resp.map((x) => Transaction(x)).toList(); } Future> getConsumedItems(String item, String variant, {String? destination}) async { var url = "$instance/item/$item/$variant/demand"; if (destination != null) { url += "?destination=$destination"; } var resp = jsonDecode(await getRequest(url)) as List; return resp.map((x) => Transaction(x)).toList(); } // /item//inventory? Future> getInventory(String item) async { // todo : add origin param var resp = jsonDecode(await getRequest("$instance/item/$item/inventory")) as List; return resp.map((x) => Transaction(x)).toList(); } // /item///inventory Future> getInventoryOfVariant( String item, String variant) async { var resp = jsonDecode(await getRequest("$instance/item/$item/$variant/inventory")) as List; return resp.map((x) => Transaction(x)).toList(); } // /supply Future supplyItem(String item, String variant, String price, String? origin, String? location) async { if (origin!.isEmpty) { origin = null; } if (location!.isEmpty) { location = null; } var req = await postRequest("$instance/supply", { "item": item, "variant": variant, "price": price, "origin": origin, "location": location }); var resp = jsonDecode(req); return resp["uuid"]; } // /demand Future consumeItem( String transaction, String destination, String price) async { await postRequest("$instance/demand", {"uuid": transaction, "destination": destination, "price": price}); } // /item///stat Future getStat(String item, String variant) async { return ItemVariantStat( jsonDecode(await getRequest("$instance/item/$item/$variant/stat"))); } String getImageURL(String item) { return "$instance/$item/image"; } // /item///price_history? Future> getPriceHistory(String item, String variant, {String? origin}) async { var url = "$instance/item/$item/$variant/price_history"; if (origin != null) { url += "?origin=$origin"; } var resp = jsonDecode(await getRequest(url)) as List; return resp.map((x) => Price(x)).toList(); } Future getLatestPrice(String item, String variant, {String? origin}) async { var url = "$instance/item/$item/$variant/price_latest"; if (origin != null) { url += "?origin=$origin"; } var resp = jsonDecode(await getRequest(url)) as Map; return Price(resp); } // Flows // /flows Future> getFlows() async { var resp = jsonDecode(await getRequest("$instance/flows")) as Map; return resp.map((key, value) => MapEntry(key, FlowInfo(value))); } // /flow//info Future getFlowInfo(String id) async { return FlowInfo(jsonDecode(await getRequest("$instance/flow/$id/info"))); } // /flow/ Future startFlow(String id, {List? input}) async { var resp = jsonDecode(await postRequest("$instance/flow/$id", {"input": input})); return resp["uuid"]; } // /flow//end Future?> endFlow(String id, {Map? produced}) async { var resp = jsonDecode( await postRequest("$instance/$id/end", {"produced": produced})); if (produced != null) { return resp["produced"] as List; } return null; } // /flow//continue Future continueFlow(String id, {List? input}) async { var resp = jsonDecode( await postRequest("$instance/flow/$id/continue", {"input": input})); return resp["uuid"]; } Future> getExpiredItems() async { var resp = jsonDecode(await getRequest("$instance/items/expired")) as List; return resp.map((x) => Transaction(x)).toList(); } Future> getItemsUnderMin() async { var resp = jsonDecode(await getRequest("$instance/items/min")) as List; return resp.map((x) => MinItem(x)).toList(); } Future moveTransaction(String id, String new_location) async { jsonDecode(await postRequest( "$instance/transaction/$id/move", {"to": new_location})); } Future getLocation(String id) async { var resp = jsonDecode(await getRequest("$instance/location/$id")); return Location(resp); } } class FlowInfo { late String id; late String name; late List depends; late String? next; late List? produces; FlowInfo(Map json) { id = json["id"]; name = json["name"]; depends = json["depends"] as List; next = json["next"]; produces = json["produces"]; } } class Item { late String id; late String name; late String category; late Map variants; Item(Map json) { id = json["uuid"]; name = json["name"]; category = json["category"]; variants = {}; json["variants"].forEach((key, value) { variants[key] = ItemVariant(value); }); } } class ItemVariant { late String item; late String variant; late String name; int? min; int? expiry; ItemVariant(Map json) { item = json["item"]; variant = json["variant"]; name = json["name"]; min = json["min"]; expiry = json["expiry"]; } } class Price { late double value; late String currency; Price(Map json) { value = json["value"]; currency = json["currency"]; } } class Transaction { late String uuid; late String item; late String variant; late Price price; late String? origin; late int timestamp; late ConsumeInfo? consumed; late bool expired; Transaction(Map json) { uuid = json["uuid"]; item = json["item"]; variant = json["variant"]; price = Price(json["price"]); origin = json["origin"]; timestamp = json["timestamp"]; expired = json["expired"]; consumed = json["consumed"] != null ? ConsumeInfo(json["consumed"]) : null; } } class ConsumeInfo { late String destination; late Price price; late int timestamp; ConsumeInfo(Map json) { destination = json["destination"]; price = Price(json["price"]); timestamp = json["timestamp"]; } } class ItemVariantStat { late int amount; late double total_price; ItemVariantStat(Map json) { amount = json["amount"]; total_price = json["total_price"]; } } class Location { late String id; late String name; late String? parent; late LocationCondition? conditions; Location.zero() { id = ""; name = ""; parent = null; conditions = null; } Location(Map json) { id = json["id"]; name = json["name"]; parent = json["parent"]; conditions = json["conditions"] != null ? (json["conditions"]) : null; } String full_name_path(Map locations) { var name = this.name; if (parent != null) { name = "${locations[parent!]!.full_name_path(locations)} / $name"; } return name; } } class LocationCondition { late String temperature; LocationCondition(Map json) { temperature = json["temperature"]; } } class MinItem { late String item_variant; late int need; MinItem(Map json) { item_variant = json["item_variant"]; need = json["need"]; } }