2019-07-18 09:26:37 +00:00
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
2019-07-18 11:05:09 +00:00
|
|
|
import 'package:charts_flutter/flutter.dart' as charts;
|
2019-07-18 09:26:37 +00:00
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
|
|
|
|
/// Customer graph types: https://dev.localspend.co.uk/api/v1/customer/graphs
|
|
|
|
/// - total_last_week
|
|
|
|
/// - avg_spend_last_week
|
|
|
|
/// - total_last_month
|
|
|
|
/// - avg_spend_last_month
|
|
|
|
|
|
|
|
|
|
|
|
/// Organisations' graphs types: to fetch, POST to https://dev.localspend.co.uk/api/stats/[name] as {"session_key":"[boop beep]"}
|
|
|
|
/// - organisations_all : organisation
|
|
|
|
/// - pies : organisation/pies
|
|
|
|
/// - snippets : organisation/snippets
|
|
|
|
/// - graphs : organisation/graphs
|
|
|
|
/// - {"graph":"customers_last_7_days","session_key":"[bleep]"}
|
|
|
|
/// - {"graph":"customers_last_30_days","session_key":"[blah]"}
|
|
|
|
/// - {"graph":"sales_last_7_days","session_key":"[bloop]"}
|
|
|
|
/// - {"graph":"sales_last_7_days","session_key":"[reee]"}
|
|
|
|
/// - {"graph":"purchases_last_7_days","session_key":"[yee]"}
|
|
|
|
/// - {"graph":"purchases_last_30_days","session_key":"[yah]"}
|
|
|
|
/// - {"graph":"purchases_all;","session_key":"[kappa]"} // I don't think this one works
|
|
|
|
///
|
|
|
|
/// HTTP POST request sample:
|
|
|
|
/// {"graph":"total_last_week","session_key":"blahblahblah"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OrganisationGraph {
|
|
|
|
OrganisationGraph(
|
2019-08-16 15:44:24 +00:00
|
|
|
this.chartType,
|
2019-08-21 15:50:26 +00:00
|
|
|
{this.graphsType = ""}
|
2019-08-16 15:44:24 +00:00
|
|
|
);
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
String graphsType = ""; // type of graph, eg customers_last_7_days, sales_last_30_days, purchases_last_30_days etc
|
|
|
|
String chartType; // type of chart, eg organisations_all, pies, snippets or graphs
|
|
|
|
|
|
|
|
List<charts.Series<TimeSeriesCustomersOrSales, DateTime>> graph;
|
|
|
|
|
|
|
|
List<TimeSeriesCustomersOrSales> cachedData;
|
2019-08-21 13:53:52 +00:00
|
|
|
|
2019-08-16 15:44:24 +00:00
|
|
|
bool loaded = false;
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
Future<void> getGraphData() async {
|
|
|
|
if (loaded) {
|
2019-08-19 14:23:58 +00:00
|
|
|
this.graph = [
|
2019-08-21 15:50:26 +00:00
|
|
|
new charts.Series<TimeSeriesCustomersOrSales, DateTime>(
|
|
|
|
id: 'Chart',
|
2019-08-19 14:23:58 +00:00
|
|
|
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
2019-08-21 15:50:26 +00:00
|
|
|
domainFn: (TimeSeriesCustomersOrSales spend, _) => spend.time,
|
|
|
|
measureFn: (TimeSeriesCustomersOrSales spend, _) =>
|
|
|
|
spend.numberOfStuff,
|
2019-08-19 14:23:58 +00:00
|
|
|
data: cachedData,
|
|
|
|
)
|
|
|
|
];
|
2019-08-21 15:50:26 +00:00
|
|
|
return null;
|
2019-08-19 14:23:58 +00:00
|
|
|
}
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
String url = "https://dev.localspend.co.uk/api/v1/organisation/";
|
2019-08-19 14:23:58 +00:00
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
if (!(this.chartType == "organisations_all")) {
|
|
|
|
url += this.chartType;
|
|
|
|
}
|
2019-08-19 14:23:58 +00:00
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
SharedPreferences preferences = await SharedPreferences.getInstance();
|
|
|
|
Map<String, String> body;
|
2019-08-19 14:23:58 +00:00
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
if (this.chartType == "graphs") {
|
|
|
|
body = {
|
|
|
|
'graph': this.graphsType,
|
|
|
|
'session_key': preferences.get('LastToken'),
|
|
|
|
};
|
2019-08-19 14:23:58 +00:00
|
|
|
} else {
|
2019-08-21 15:50:26 +00:00
|
|
|
body = {
|
|
|
|
'session_key': preferences.get('LastToken'),
|
|
|
|
};
|
2019-08-19 14:23:58 +00:00
|
|
|
}
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
print(url);
|
|
|
|
print(json.encode(body).toString());
|
2019-08-19 14:23:58 +00:00
|
|
|
|
|
|
|
final response = await http.post(
|
|
|
|
url,
|
|
|
|
body: json.encode(body),
|
|
|
|
);
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
try {
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
final responseJson = jsonDecode(response.body);
|
|
|
|
final List<dynamic> labels = responseJson['graph']['labels'];
|
|
|
|
final List<dynamic> data = responseJson['graph']['data'];
|
|
|
|
|
|
|
|
List<TimeSeriesCustomersOrSales> graphDataList = new List<
|
|
|
|
TimeSeriesCustomersOrSales>();
|
|
|
|
|
|
|
|
for (int i = 0; i < labels.length; i++) {
|
|
|
|
graphDataList.add(
|
|
|
|
new TimeSeriesCustomersOrSales(
|
|
|
|
data[i] * 1.00, DateTime.parse(labels[i])));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.cachedData = graphDataList;
|
|
|
|
this.loaded = true;
|
|
|
|
|
|
|
|
this.graph = [
|
|
|
|
new charts.Series<TimeSeriesCustomersOrSales, DateTime>(
|
|
|
|
id: 'Chart',
|
|
|
|
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
|
|
domainFn: (TimeSeriesCustomersOrSales spend, _) => spend.time,
|
|
|
|
measureFn: (TimeSeriesCustomersOrSales spend, _) =>
|
|
|
|
spend.numberOfStuff,
|
|
|
|
data: graphDataList,
|
|
|
|
)
|
|
|
|
];
|
|
|
|
return this.graph;
|
|
|
|
} else {
|
|
|
|
final errorMessage = json.decode(response.body)['message'];
|
|
|
|
print("Error: " + errorMessage);
|
|
|
|
this.graph = null;
|
2019-08-19 14:23:58 +00:00
|
|
|
}
|
2019-08-21 15:50:26 +00:00
|
|
|
} catch (error) {
|
|
|
|
print(error.toString());
|
2019-08-19 14:23:58 +00:00
|
|
|
}
|
2019-08-21 15:50:26 +00:00
|
|
|
|
2019-08-19 14:23:58 +00:00
|
|
|
}
|
2019-08-21 15:50:26 +00:00
|
|
|
|
2019-08-19 14:23:58 +00:00
|
|
|
}
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
class GraphData {
|
|
|
|
GraphData(
|
2019-08-19 14:23:58 +00:00
|
|
|
this.chartType,
|
|
|
|
);
|
|
|
|
|
2019-08-21 13:53:52 +00:00
|
|
|
var chartType;
|
|
|
|
List<charts.Series<dynamic, DateTime>> graph;
|
|
|
|
|
2019-08-19 14:23:58 +00:00
|
|
|
List<TimeSeriesSpend> cachedData;
|
|
|
|
bool loaded = false;
|
|
|
|
|
2019-08-21 15:50:26 +00:00
|
|
|
Future<List<charts.Series<dynamic, DateTime>>> setGraphData() async {
|
|
|
|
if (loaded) {
|
2019-08-16 15:44:24 +00:00
|
|
|
this.graph = [
|
|
|
|
new charts.Series<TimeSeriesSpend, DateTime>(
|
|
|
|
id: 'Spend',
|
|
|
|
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
|
|
domainFn: (TimeSeriesSpend spend, _) => spend.time,
|
|
|
|
measureFn: (TimeSeriesSpend spend, _) => spend.spend,
|
|
|
|
data: cachedData,
|
|
|
|
)
|
|
|
|
];
|
2019-08-21 15:50:26 +00:00
|
|
|
return null;
|
2019-08-16 15:44:24 +00:00
|
|
|
}
|
|
|
|
|
2019-08-20 12:54:45 +00:00
|
|
|
final url = "https://dev.localspend.co.uk/api/v1/customer/graphs";
|
2019-08-16 15:44:24 +00:00
|
|
|
SharedPreferences preferences = await SharedPreferences.getInstance();
|
|
|
|
|
|
|
|
Map<String, String> body = {
|
|
|
|
'graph': this.chartType,
|
|
|
|
'session_key': preferences.get('LastToken'),
|
|
|
|
};
|
|
|
|
|
|
|
|
final response = await http.post(
|
|
|
|
url,
|
|
|
|
body: json.encode(body),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
final responseJson = jsonDecode(response.body);
|
|
|
|
final List<dynamic> labels = responseJson['graph']['labels'];
|
|
|
|
final List<dynamic> data = responseJson['graph']['data'];
|
|
|
|
|
|
|
|
List<TimeSeriesSpend> timeSeriesSpendList = new List<TimeSeriesSpend>();
|
|
|
|
|
|
|
|
for (int i = 0; i < labels.length; i++) {
|
2019-08-21 13:53:52 +00:00
|
|
|
timeSeriesSpendList.add(
|
|
|
|
new TimeSeriesSpend(data[i] * 1.00, DateTime.parse(labels[i])));
|
2019-08-16 15:44:24 +00:00
|
|
|
// print(timeSeriesSpendList[i].time.toString() + " : " + timeSeriesSpendList[i].spend.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
cachedData = timeSeriesSpendList;
|
|
|
|
loaded = true;
|
|
|
|
|
|
|
|
this.graph = [
|
|
|
|
new charts.Series<TimeSeriesSpend, DateTime>(
|
|
|
|
id: 'Spend',
|
|
|
|
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
|
|
domainFn: (TimeSeriesSpend spend, _) => spend.time,
|
|
|
|
measureFn: (TimeSeriesSpend spend, _) => spend.spend,
|
|
|
|
data: timeSeriesSpendList,
|
|
|
|
)
|
|
|
|
];
|
2019-08-21 15:50:26 +00:00
|
|
|
return this.graph;
|
|
|
|
|
2019-08-16 15:44:24 +00:00
|
|
|
} else {
|
|
|
|
final errorMessage = json.decode(response.body)['message'];
|
|
|
|
print("Error: " + errorMessage);
|
|
|
|
|
|
|
|
this.graph = null;
|
2019-08-21 15:50:26 +00:00
|
|
|
return null;
|
2019-08-16 15:44:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<List<charts.Series<dynamic, DateTime>>> getGraphData() async {
|
|
|
|
if (loaded == true) {
|
|
|
|
return [
|
|
|
|
new charts.Series<TimeSeriesSpend, DateTime>(
|
|
|
|
id: 'Spend',
|
|
|
|
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
|
|
domainFn: (TimeSeriesSpend spend, _) => spend.time,
|
|
|
|
measureFn: (TimeSeriesSpend spend, _) => spend.spend,
|
|
|
|
data: cachedData,
|
|
|
|
)
|
|
|
|
];
|
|
|
|
}
|
2019-07-18 09:26:37 +00:00
|
|
|
|
2019-08-20 12:54:45 +00:00
|
|
|
final url = "https://dev.localspend.co.uk/api/v1/customer/graphs";
|
2019-07-18 09:26:37 +00:00
|
|
|
SharedPreferences preferences = await SharedPreferences.getInstance();
|
|
|
|
|
|
|
|
Map<String, String> body = {
|
2019-08-16 15:44:24 +00:00
|
|
|
'graph': this.chartType,
|
2019-07-18 09:26:37 +00:00
|
|
|
'session_key': preferences.get('LastToken'),
|
|
|
|
};
|
|
|
|
|
|
|
|
final response = await http.post(
|
|
|
|
url,
|
|
|
|
body: json.encode(body),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
final responseJson = jsonDecode(response.body);
|
2019-07-18 11:05:09 +00:00
|
|
|
final List<dynamic> labels = responseJson['graph']['labels'];
|
|
|
|
final List<dynamic> data = responseJson['graph']['data'];
|
2019-08-12 15:03:00 +00:00
|
|
|
|
2019-07-18 11:05:09 +00:00
|
|
|
List<TimeSeriesSpend> timeSeriesSpendList = new List<TimeSeriesSpend>();
|
|
|
|
|
|
|
|
for (int i = 0; i < labels.length; i++) {
|
2019-08-21 13:53:52 +00:00
|
|
|
timeSeriesSpendList.add(
|
|
|
|
new TimeSeriesSpend(data[i] * 1.00, DateTime.parse(labels[i])));
|
2019-08-16 15:44:24 +00:00
|
|
|
// print(timeSeriesSpendList[i].time.toString() + " : " + timeSeriesSpendList[i].spend.toString());
|
2019-07-18 11:05:09 +00:00
|
|
|
}
|
|
|
|
|
2019-08-16 15:44:24 +00:00
|
|
|
cachedData = timeSeriesSpendList;
|
|
|
|
loaded = true;
|
2019-08-12 15:03:00 +00:00
|
|
|
|
2019-07-18 11:05:09 +00:00
|
|
|
return [
|
|
|
|
new charts.Series<TimeSeriesSpend, DateTime>(
|
|
|
|
id: 'Spend',
|
|
|
|
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
|
|
domainFn: (TimeSeriesSpend spend, _) => spend.time,
|
|
|
|
measureFn: (TimeSeriesSpend spend, _) => spend.spend,
|
|
|
|
data: timeSeriesSpendList,
|
|
|
|
)
|
|
|
|
];
|
2019-07-18 09:26:37 +00:00
|
|
|
} else {
|
|
|
|
final errorMessage = json.decode(response.body)['message'];
|
|
|
|
print("Error: " + errorMessage);
|
2019-07-18 11:05:09 +00:00
|
|
|
|
|
|
|
return null;
|
2019-07-18 09:26:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-18 11:05:09 +00:00
|
|
|
class TimeSeriesSpend {
|
2019-08-21 13:53:52 +00:00
|
|
|
TimeSeriesSpend(this.spend, this.time);
|
|
|
|
|
2019-07-18 11:05:09 +00:00
|
|
|
final DateTime time;
|
2019-08-16 15:44:24 +00:00
|
|
|
final double spend;
|
2019-07-18 11:05:09 +00:00
|
|
|
}
|
2019-08-21 15:50:26 +00:00
|
|
|
|
|
|
|
class TimeSeriesCustomersOrSales {
|
|
|
|
TimeSeriesCustomersOrSales(this.numberOfStuff, this.time);
|
|
|
|
|
|
|
|
final DateTime time;
|
|
|
|
final double numberOfStuff;
|
|
|
|
}
|