Skip to content

Commit

Permalink
Merge branch 'release/1.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
tcrasset committed Jan 1, 2021
2 parents 76914ae + 3152bfa commit 70a5cb9
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 76 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Version 1.1.2

- BUGFIX: Transactions between accounts now appear in both accounts

## Version 1.1.1

- FEATURE: Creating new payee show a dialog
Expand Down
9 changes: 6 additions & 3 deletions lib/appState.dart
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,12 @@ class AppState extends ChangeNotifier {
await computeToBeBudgeted();
notifyListeners();
} else if (transaction.subcatID == Constants.UNASSIGNED_SUBCAT_ID) {
// If the transaction amount is positive, the transaction will remove money from
// outAccount and input it into inAccount.
// Otherwise, it is reversed.
/// If the transaction amount is positive, the transaction will remove money from
/// [outAccount] and input it into [inAccount].
/// Otherwise, it is reversed.
/// [outAccount] is ALWAYS the one pointed to by accountID.
/// Therefore, [inAccount] will be the one defined by [-payee.id].
final Account outAccount =
accounts.singleWhere((account) => account.id == transaction.accountID);
outAccount.balance -= transaction.amount;
Expand Down
17 changes: 14 additions & 3 deletions lib/models/entries.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/// This file will contain the classes for the common objects used throughout the codebase, namely
/// [Payee], [MoneyTransaction], and [Account].
Expand Down Expand Up @@ -79,13 +78,25 @@ class MoneyTransaction {
this.accountID = json[DatabaseConstants.ACCOUNT_ID_OUTSIDE];
this.amount = json[DatabaseConstants.MONEYTRANSACTION_AMOUNT];
this.memo = json[DatabaseConstants.MONEYTRANSACTION_MEMO];
this.date = DateTime.fromMillisecondsSinceEpoch(json[DatabaseConstants.MONEYTRANSACTION_DATE]);
this.date = DateTime.fromMillisecondsSinceEpoch(
json[DatabaseConstants.MONEYTRANSACTION_DATE]);
}

@override
String toString() {
return super.toString() +
""" {id: $id, subcatID: $subcatID, payeeID: $payeeID, accountID: $accountID, amount: $amount, date: $date}""";
"""{id: $id, subcatID: $subcatID, payeeID: $payeeID, accountID: $accountID, amount: $amount, date: $date}\n""";
}

MoneyTransaction copy() {
return MoneyTransaction(
id: this.id,
subcatID: this.subcatID,
payeeID: this.payeeID,
accountID: this.accountID,
amount: this.amount,
memo: this.memo,
date: this.date);
}
}

Expand Down
18 changes: 7 additions & 11 deletions lib/screens/addTransaction/addTransaction.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,7 @@ class _AddTransactionPageController extends State<AddTransactionPage> {

/// List of values to choose each value from, e.g. [_payee]
/// will be chosen from one of the [payees]
List<Payee> payees;
List<SubCategory> subcategories;
List<Account> accounts;
List payeesAndAccounts = [];
AppState appState;

@override
Expand All @@ -76,13 +73,7 @@ class _AddTransactionPageController extends State<AddTransactionPage> {
amountLength = 16;
// Load list of objects from the state/database
appState = Provider.of<AppState>(context, listen: false);
payees = appState.payees;
accounts = appState.accounts;
subcategories = appState.subcategories;

payeesAndAccounts.addAll(payees);
payeesAndAccounts.addAll(accounts);

// Set initial values of the transaction
_payee = null;
_account = null;
Expand Down Expand Up @@ -129,6 +120,11 @@ class _AddTransactionPageController extends State<AddTransactionPage> {
/// a [Payee], whose value is stored in [_payee] and whose
/// name is stored in [_payeeFieldName].
handleOnTapPayee() {

List payeesAndAccounts = [];
payeesAndAccounts.addAll(appState.payees);
payeesAndAccounts.addAll(appState.accounts);

Navigator.push(
context,
MaterialPageRoute(
Expand All @@ -151,7 +147,7 @@ class _AddTransactionPageController extends State<AddTransactionPage> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SelectValuePage(title: "Accounts", listEntries: accounts)),
builder: (context) => SelectValuePage(title: "Accounts", listEntries: appState.accounts)),
).then((returnElement) {
if (returnElement != null) {
setState(() {
Expand Down Expand Up @@ -233,7 +229,7 @@ class _AddTransactionPageController extends State<AddTransactionPage> {
// Input as payee ID the opposite of the account ID when we select
// an account instead of a payee in the 'Payee' field
print("_payee is of type ${_payee is Payee ? "Payee" : "Account"}");
int payeeId = _payee is Payee ? _payee.id : -_account.id;
int payeeId = _payee is Payee ? _payee.id : -_payee.id;

appState.addTransaction(
subcatId: _selectSubcatId(),
Expand Down
20 changes: 10 additions & 10 deletions lib/screens/addTransaction/selectValue.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ class SelectValuePageState extends State<SelectValuePage> {

@override
Widget build(BuildContext context) {
return new Scaffold(
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: new AppBar(
appBar: AppBar(
title: Text(widget.title),
),
body: new Column(
body: Column(
children: [
new Padding(
padding: new EdgeInsets.only(top: 20.0),
Padding(
padding: EdgeInsets.only(top: 20.0),
),
new TextField(
decoration: new InputDecoration(
TextField(
decoration: InputDecoration(
hintText: "Search something",
icon: Icon(Icons.search),
),
Expand All @@ -98,8 +98,8 @@ class SelectValuePageState extends State<SelectValuePage> {
context: context, defaultName: searchController.text),
),

new Expanded(
child: new ListView.separated(
Expanded(
child: ListView.separated(
shrinkWrap: true,
itemCount: widget.listEntries.length,
separatorBuilder: (BuildContext context, int index) =>
Expand All @@ -121,7 +121,7 @@ class SelectValuePageState extends State<SelectValuePage> {
title: item, onTap: () => handlePopContext(item));
}
// There is an error
return new Container();
return Container();
},
))
],
Expand Down
45 changes: 38 additions & 7 deletions lib/screens/showTransactions/components/transactionList.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:your_budget/appState.dart';
import 'package:your_budget/models/constants.dart';
import 'package:your_budget/models/entries.dart';
import 'package:your_budget/screens/showTransactions/components/transactionRow.dart';

Expand All @@ -25,26 +28,54 @@ class _TransactionListState extends State<TransactionList> {

@override
Widget build(BuildContext context) {
List<MoneyTransaction> transactionsOfAccount = widget.appState.transactions
.where((transaction) => transaction.accountID == this.widget.account.id)
.toList();
List<MoneyTransaction> transactionsOfAccount =
_getMoneyTransactions(
widget.appState.transactions, this.widget.account.id);

return new Container(
return Container(
child: Scrollbar(
isAlwaysShown: true,
controller: _scrollController,
child: new ListView.separated(
child: ListView.separated(
controller: _scrollController,
shrinkWrap: true,
itemCount: transactionsOfAccount.length,
separatorBuilder: (BuildContext context, int index) =>
Divider(height: 1, color: Colors.black12),
itemBuilder: (BuildContext context, int index) {
return Card(
child: TransactionRow(
transactionsOfAccount[index], widget.appState.allCategories, widget.isEditable));
child: TransactionRow(transactionsOfAccount[index],
widget.appState.allCategories, widget.isEditable));
},
),
));
}
}

List<MoneyTransaction> _getMoneyTransactions(
UnmodifiableListView<MoneyTransaction> transactions, int currentAccountId) {
/// Here, [currentAccountId] is the outgoingAccount.
List<MoneyTransaction> transactionsOfAccount = [];
for (var transaction in transactions) {
bool isAccountPayee = transaction.payeeID < 0;

bool currentAccountIsPayeeAccount =
-transaction.payeeID == currentAccountId;
bool currentAccountIsStandardAccount =
transaction.accountID == currentAccountId;

if ((currentAccountIsStandardAccount && !isAccountPayee) ||
(currentAccountIsPayeeAccount && isAccountPayee)) {
transactionsOfAccount.add(transaction);
} else if ((currentAccountIsStandardAccount && isAccountPayee)) {
// The transaction is reversed.i.e. removes money from outAccount(accountId)
// into inAccount(payeeId)
MoneyTransaction negativeAmountTransaction = transaction.copy();
negativeAmountTransaction.amount *= -1;
transactionsOfAccount.add(negativeAmountTransaction);
}
}

return transactionsOfAccount;
}
80 changes: 40 additions & 40 deletions lib/screens/showTransactions/components/transactionRow.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,53 +28,20 @@ class _TransactionRowState extends State<TransactionRow> {
final TextStyle subcategoryStyle =
TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, color: Colors.black);

TextStyle amountStyle;

void initState() {
amountStyle = TextStyle(
@override
Widget build(BuildContext context) {
String subcategoryName = "";
String payeeName;
TextStyle amountStyle = TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.w600,
color: widget.moneyTransaction.amount.isNegative
? Constants.RED_COLOR
: Constants.GREEN_COLOR);
super.initState();
}

@override
Widget build(BuildContext context) {
String subcategoryName = "";
String payeeName;
AppState appState = Provider.of<AppState>(context, listen: false);

if (appState.payees.isNotEmpty) {
// orElse is for starting balance
Payee payee = appState.payees
.singleWhere((payee) => payee.id == widget.moneyTransaction.payeeID, orElse: () => null);

payeeName = payee != null ? payee.name : "";
} else {
payeeName = "";
}

/// Extract name of subcategory associated to transaction [moneyTransaction]
if (widget.moneyTransaction.subcatID == Constants.UNASSIGNED_SUBCAT_ID) {
// Transfer between accounts
for (final Account account in appState.accounts) {
if (account.id == -widget.moneyTransaction.payeeID) {
subcategoryName = "To/From " + account.name;
}
}
} else if (widget.moneyTransaction.subcatID ==
Constants.TO_BE_BUDGETED_ID_IN_MONEYTRANSACTION) {
//Transaction into to be budgeted
subcategoryName = "To be budgeted";
} else {
// Transaction into subcategories
var correspondingSubcategory = widget.categories.singleWhere(
((cat) => cat is SubCategory && cat.id == widget.moneyTransaction.subcatID),
orElse: () => null);
subcategoryName = correspondingSubcategory != null ? correspondingSubcategory.name : "";
}
payeeName = _setPayeeName(appState);
subcategoryName = _setSubcategoryName(appState);

return widget.isEditable
? CheckedRow(
Expand All @@ -99,4 +66,37 @@ class _TransactionRowState extends State<TransactionRow> {
payeeName,
subcategoryStyle);
}

String _setSubcategoryName(AppState appState) {
/// Extract name of subcategory associated to transaction [moneyTransaction]
if (widget.moneyTransaction.subcatID == Constants.UNASSIGNED_SUBCAT_ID) {
// Transfer between accounts
for (final Account account in appState.accounts) {
if (account.id == -widget.moneyTransaction.payeeID) {
return "To/From " + account.name;
}
}
} else if (widget.moneyTransaction.subcatID ==
Constants.TO_BE_BUDGETED_ID_IN_MONEYTRANSACTION) {
//Transaction into to be budgeted
return "To be budgeted";
}
// Transaction into subcategories
var correspondingSubcategory = widget.categories.singleWhere(
((cat) => cat is SubCategory && cat.id == widget.moneyTransaction.subcatID),
orElse: () => null);
return correspondingSubcategory != null ? correspondingSubcategory.name : "";

}

String _setPayeeName(AppState appState) {
if (appState.payees.isNotEmpty) {
// orElse is for starting balance
Payee payee = appState.payees
.singleWhere((payee) => payee.id == widget.moneyTransaction.payeeID, orElse: () => null);

return payee != null ? payee.name : "";
}
return "";
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.1+11
version: 1.1.2+12

environment:
sdk: ">=2.7.0 <3.0.0"
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.1+11
1.1.2+12

0 comments on commit 70a5cb9

Please sign in to comment.