Submit Recepit nearly working properly with API, corresponding view has relevant sections, still slightly more to do before working properly
This commit is contained in:
parent
ac4b122d07
commit
0c1cacde1e
4 changed files with 156 additions and 36 deletions
|
@ -53,7 +53,6 @@
|
||||||
\ls6\ilvl1\cf0 \ulnone {\listtext \uc0\u8259 }
|
\ls6\ilvl1\cf0 \ulnone {\listtext \uc0\u8259 }
|
||||||
\f1\b0 Categories\
|
\f1\b0 Categories\
|
||||||
{\listtext \uc0\u8259 }Recurring\
|
{\listtext \uc0\u8259 }Recurring\
|
||||||
{\listtext \uc0\u8259 }Sort out \'91essential purchase\'92 checkbox\'92s Y position\
|
|
||||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||||
\cf0 \
|
\cf0 \
|
||||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||||
|
|
|
@ -31,6 +31,7 @@ Future<LoginModel> submitReceiptAPI(
|
||||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
SharedPreferences preferences = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
Map<String, String> body = {
|
Map<String, String> body = {
|
||||||
|
'transaction_type' : "3",
|
||||||
'transaction_value': receipt.amount,
|
'transaction_value': receipt.amount,
|
||||||
'purchase_time': receipt.time,
|
'purchase_time': receipt.time,
|
||||||
'category': receipt.category,
|
'category': receipt.category,
|
||||||
|
@ -38,13 +39,15 @@ Future<LoginModel> submitReceiptAPI(
|
||||||
'organisation_name': receipt.organisationName,
|
'organisation_name': receipt.organisationName,
|
||||||
'recurring': receipt.recurring,
|
'recurring': receipt.recurring,
|
||||||
'street_name': receipt.street,
|
'street_name': receipt.street,
|
||||||
'town': receipt.town,
|
|
||||||
'postcode': receipt.postcode,
|
'postcode': receipt.postcode,
|
||||||
|
|
||||||
|
'town': receipt.town,
|
||||||
|
|
||||||
'session_key': preferences.get('LastToken'),
|
'session_key': preferences.get('LastToken'),
|
||||||
};
|
};
|
||||||
|
|
||||||
debugPrint('$body');
|
debugPrint('$body');
|
||||||
|
debugPrint(json.encode(body));
|
||||||
|
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
url,
|
url,
|
||||||
|
@ -64,7 +67,8 @@ Future<LoginModel> submitReceiptAPI(
|
||||||
showDialogSingleButton(
|
showDialogSingleButton(
|
||||||
context,
|
context,
|
||||||
"Unable to Submit Receipt",
|
"Unable to Submit Receipt",
|
||||||
"You may have supplied an invalid 'Email' / 'Password' combination. Please try again or email an administrator.",
|
// "You may have supplied an invalid 'Email' / 'Password' combination. Please try again or email an administrator.",
|
||||||
|
responseJson.toString(),
|
||||||
"OK");
|
"OK");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class LoginPage extends StatefulWidget {
|
||||||
class LoginPageState extends State<LoginPage> {
|
class LoginPageState extends State<LoginPage> {
|
||||||
final TextEditingController _emailController = TextEditingController();
|
final TextEditingController _emailController = TextEditingController();
|
||||||
final TextEditingController _passwordController = TextEditingController();
|
final TextEditingController _passwordController = TextEditingController();
|
||||||
String _welcomeString = "";
|
|
||||||
FocusNode focusNode; // added so focus can move automatically
|
FocusNode focusNode; // added so focus can move automatically
|
||||||
|
|
||||||
Future launchURL(String url) async {
|
Future launchURL(String url) async {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import 'package:intl/intl.dart';
|
||||||
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||||
|
|
||||||
const URL = "https://flutter.io/";
|
const URL = "https://flutter.io/";
|
||||||
const demonstration = true;
|
const demonstration = false;
|
||||||
|
|
||||||
class ReceiptPage extends StatefulWidget {
|
class ReceiptPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
@ -29,6 +29,8 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
final TextEditingController _typeController = TextEditingController();
|
final TextEditingController _typeController = TextEditingController();
|
||||||
final TextEditingController _orgController = TextEditingController();
|
final TextEditingController _orgController = TextEditingController();
|
||||||
|
|
||||||
|
FocusNode focusNode; // added so focus can move automatically
|
||||||
|
|
||||||
DateTime date;
|
DateTime date;
|
||||||
|
|
||||||
Future launchURL(String url) async {
|
Future launchURL(String url) async {
|
||||||
|
@ -47,6 +49,15 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_saveCurrentRoute("/ReceiptPageState");
|
_saveCurrentRoute("/ReceiptPageState");
|
||||||
|
|
||||||
|
focusNode = FocusNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
|
||||||
|
focusNode.dispose(); //disposes focus node when form disposed
|
||||||
}
|
}
|
||||||
|
|
||||||
_saveCurrentRoute(String lastRoute) async {
|
_saveCurrentRoute(String lastRoute) async {
|
||||||
|
@ -54,7 +65,7 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
await preferences.setString('LastPageRoute', lastRoute);
|
await preferences.setString('LastPageRoute', lastRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void submitReceipt(String amount, String time) async {
|
void submitReceipt(String amount, String time, String orgName) async {
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
||||||
|
|
||||||
if (demonstration)
|
if (demonstration)
|
||||||
|
@ -86,7 +97,10 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
|
|
||||||
// setting up 'receipt'
|
// setting up 'receipt'
|
||||||
receipt.amount = amount;
|
receipt.amount = amount;
|
||||||
receipt.time = time;
|
receipt.time = formatDate(time);
|
||||||
|
receipt.organisationName = orgName;
|
||||||
|
|
||||||
|
// receipt.essential = convertBoolToString(toConvert)
|
||||||
|
|
||||||
//TODO: initialise receipt with correct values from form
|
//TODO: initialise receipt with correct values from form
|
||||||
|
|
||||||
|
@ -97,6 +111,40 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String convertBoolToString(bool toConvert) {
|
||||||
|
if (toConvert)
|
||||||
|
{
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatDate(String date) {
|
||||||
|
// return "";
|
||||||
|
// should be in format:
|
||||||
|
// yyyy-MM-ddThh:mm:00.000+01:00
|
||||||
|
// eg 2019-07-05T10:24:00.000+01.00 (real life example, works)
|
||||||
|
|
||||||
|
// current format = "dd/MM/yyyy 'at' hh:mm"
|
||||||
|
|
||||||
|
var components = new List(5);
|
||||||
|
|
||||||
|
components[0] = (date.substring(0,2)); // dd
|
||||||
|
components[1] = (date.substring(3,5)); // MM
|
||||||
|
components[2] = (date.substring(6,10)); // yyyy
|
||||||
|
components[3] = (date.substring(14,16)); // hh
|
||||||
|
components[4] = (date.substring(17,19)); // mm
|
||||||
|
|
||||||
|
//print(components);
|
||||||
|
|
||||||
|
return (components[2] + "-" + components[1] + "-" + components[0]
|
||||||
|
+ "T" + components[3] + ":" + components[4] + ":00.000+01:00");
|
||||||
|
|
||||||
|
// Yes, there is probably a function to convert dates, but I didn't
|
||||||
|
// know that before writing this and it's done now so I'm keeping it.
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var drawer = Drawer();
|
var drawer = Drawer();
|
||||||
|
@ -127,16 +175,18 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
padding: EdgeInsets.fromLTRB(30.0, 0.0, 30.0, 0.0),
|
padding: EdgeInsets.fromLTRB(30.0, 0.0, 30.0, 0.0),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
// Container(
|
||||||
alignment: Alignment.topCenter,
|
// alignment: Alignment.topCenter,
|
||||||
child: Padding(
|
// child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 15.0),
|
// padding: EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 15.0),
|
||||||
child: Text(
|
// child: Text(
|
||||||
"Required Fields in bold",
|
// "Required fields are in bold",
|
||||||
style: TextStyle(fontSize: 20.0, color: Colors.black),
|
// style: TextStyle(fontSize: 20.0, color: Colors.black),
|
||||||
),
|
// ),
|
||||||
)),
|
// )),
|
||||||
Text(
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(0.0,25,0.0,0.0),
|
||||||
|
child : Text(
|
||||||
"Time of Transaction",
|
"Time of Transaction",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18.0,
|
fontSize: 18.0,
|
||||||
|
@ -144,9 +194,10 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
DateTimePickerFormField(
|
DateTimePickerFormField(
|
||||||
inputType: InputType.both,
|
inputType: InputType.both,
|
||||||
format: DateFormat("EEEE, MMMM d, yyyy 'at' h:mma"),
|
format: DateFormat("dd/MM/yyyy 'at' hh:mm"),
|
||||||
editable: true,
|
editable: true,
|
||||||
controller: _timeController,
|
controller: _timeController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
@ -154,7 +205,7 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
onChanged: (dt) => setState(() => date = dt),
|
onChanged: (dt) => setState(() => date = dt),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0),
|
padding: EdgeInsets.fromLTRB(0.0,25,0.0,0.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Amount",
|
"Amount",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -180,13 +231,83 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
onSubmitted: (_) {
|
onSubmitted: (_) {
|
||||||
submitReceipt(_amountController.text, _timeController.text);
|
FocusScope.of(context).requestFocus(focusNode);
|
||||||
|
// submitReceipt(_amountController.text, _timeController.text);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0),
|
padding: EdgeInsets.fromLTRB(0.0,25,0.0,0.0),
|
||||||
|
|
||||||
|
child : Container (
|
||||||
|
height: 22, // this should be the same height as text
|
||||||
|
|
||||||
|
child : ListView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
children: <Widget>[
|
||||||
|
|
||||||
|
Container(
|
||||||
|
child: Text(
|
||||||
|
"Organization Name",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
child : Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(5,0,0,4),
|
||||||
|
child: FlatButton(
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint("TODO: 'find organisation' dialog");
|
||||||
|
// Writing this before I forget tomorrow morning:
|
||||||
|
// Steps to fetch list of organisations with similar name:
|
||||||
|
// 1) record network activity (requests) of FoodLoop-Web webapp on Firefox
|
||||||
|
// 2) look at JSON files returned by server when 'organisation name' field's text updates/changes
|
||||||
|
// 3) look at requests sent to server when web textfield updates and send those from app
|
||||||
|
// 4) I'm tired
|
||||||
|
},
|
||||||
|
child: Text("Find",
|
||||||
|
style:
|
||||||
|
TextStyle(color: Colors.blue, fontSize: 18.0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: _orgController,
|
||||||
|
focusNode: focusNode,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Eg. Pear Trading',
|
||||||
|
),
|
||||||
|
// obscureText: true,
|
||||||
|
autocorrect: true,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
color: Colors.grey[800],
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
onSubmitted: (_) {
|
||||||
|
submitReceipt(_amountController.text,
|
||||||
|
_timeController.text, _orgController.text);
|
||||||
|
// TODO: Add 'find organisation' button which displays a dialog to, well, find the organisation's address or manual entry
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(0.0,25,0.0,0.0),
|
||||||
|
|
||||||
child : Container (
|
child : Container (
|
||||||
height: 18,
|
height: 18,
|
||||||
|
@ -209,16 +330,12 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
child : Padding(
|
child : Padding(
|
||||||
padding: EdgeInsets.fromLTRB(20.0, 0.0, 0, 0),
|
padding: EdgeInsets.fromLTRB(20.0, 0.0, 0, 0),
|
||||||
|
|
||||||
child: Checkbox(value: _essentialController.text.toLowerCase() == 'true', onChanged: (bool newValue) {
|
child: Checkbox(value:
|
||||||
|
_essentialController.text.toLowerCase() == 'true',
|
||||||
|
onChanged: (bool newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
var newValueString = "false";
|
_essentialController.text =
|
||||||
|
convertBoolToString(newValue);
|
||||||
if (newValue)
|
|
||||||
{
|
|
||||||
newValueString = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
_essentialController.text = newValueString;
|
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -236,7 +353,7 @@ class ReceiptPageState extends State<ReceiptPage> {
|
||||||
height: 65.0,
|
height: 65.0,
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
submitReceipt(_amountController.text, _timeController.text);
|
submitReceipt(_amountController.text, _timeController.text, _orgController.text);
|
||||||
},
|
},
|
||||||
child: Text("SUBMIT",
|
child: Text("SUBMIT",
|
||||||
style:
|
style:
|
||||||
|
|
Reference in a new issue