public static ParsedPosting fromLedgerAccount(LedgerTransactionAccount acc) {
ParsedPosting result = new ParsedPosting();
result.setPaccount(acc.getAccountName());
+
+ String comment = acc.getComment();
+ if (comment == null)
+ comment = "";
+ result.setPcomment(comment);
+
ArrayList<ParsedAmount> amounts = new ArrayList<>();
ParsedAmount amt = new ParsedAmount();
amt.setAcommodity((acc.getCurrency() == null) ? "" : acc.getCurrency());
public static ParsedPosting fromLedgerAccount(LedgerTransactionAccount acc) {
ParsedPosting result = new ParsedPosting();
result.setPaccount(acc.getAccountName());
+
+ String comment = acc.getComment();
+ if (comment == null)
+ comment = "";
+ result.setPcomment(comment);
+
ArrayList<ParsedAmount> amounts = new ArrayList<>();
ParsedAmount amt = new ParsedAmount();
amt.setAcommodity((acc.getCurrency() == null) ? "" : acc.getCurrency());
private float amount;
private boolean amountSet = false;
private String currency;
-
+ private String comment;
public LedgerTransactionAccount(String accountName, float amount) {
this(accountName, amount, null);
}
this.amountSet = true;
this.currency = currency;
}
-
public LedgerTransactionAccount(String accountName) {
this.accountName = accountName;
}
public LedgerTransactionAccount(LedgerTransactionAccount origin) {
// copy constructor
setAccountName(origin.getAccountName());
+ setComment(origin.getComment());
if (origin.isAmountSet())
setAmount(origin.getAmount());
currency = origin.getCurrency();
}
-
+ public String getComment() {
+ return comment;
+ }
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
public String getAccountName() {
return accountName;
}
import java.util.GregorianCalendar;
import java.util.Locale;
+import static net.ktnx.mobileledger.ui.activity.NewTransactionModel.ItemType;
+
class NewTransactionItemHolder extends RecyclerView.ViewHolder
implements DatePickerFragment.DatePickedListener, DescriptionSelectedCallback {
private final String decimalSeparator;
private TextView tvDate;
private AutoCompleteTextView tvDescription;
private AutoCompleteTextView tvAccount;
+ private TextView tvComment;
private TextView tvAmount;
private LinearLayout lHead;
private ViewGroup lAccount;
NewTransactionItemHolder(@NonNull View itemView, NewTransactionItemsAdapter adapter) {
super(itemView);
tvAccount = itemView.findViewById(R.id.account_row_acc_name);
+ tvComment = itemView.findViewById(R.id.comment);
tvAmount = itemView.findViewById(R.id.account_row_acc_amounts);
tvDate = itemView.findViewById(R.id.new_transaction_date);
tvDescription = itemView.findViewById(R.id.new_transaction_description);
try {
final int pos = getAdapterPosition();
adapter.updateFocusedItem(pos);
- if (v instanceof AutoCompleteTextViewWithClear) {
- adapter.noteFocusIsOnAccount(pos);
- }
- else {
- adapter.noteFocusIsOnAmount(pos);
+ switch (v.getId()) {
+ case R.id.account_row_acc_name:
+ adapter.noteFocusIsOnAccount(pos);
+ break;
+ case R.id.account_row_acc_amounts:
+ adapter.noteFocusIsOnAmount(pos);
+ break;
+ case R.id.comment:
+ adapter.noteFocusIsOnComment(pos);
+ break;
}
}
finally {
};
tvDescription.addTextChangedListener(tw);
tvAccount.addTextChangedListener(tw);
+ tvComment.addTextChangedListener(tw);
tvAmount.addTextChangedListener(amountWatcher);
// FIXME: react on locale changes
case transactionRow:
// do nothing if a row element already has the focus
if (!itemView.hasFocus()) {
- if (item.focusIsOnAmount()) {
- tvAmount.requestFocus();
- }
- else {
- focused = tvAccount.requestFocus();
- tvAccount.dismissDropDown();
- if (focused)
- Misc.showSoftKeyboard(
- (NewTransactionActivity) tvAccount.getContext());
+ switch (item.getFocusedElement()) {
+ case Amount:
+ tvAmount.requestFocus();
+ break;
+ case Comment:
+ tvComment.requestFocus();
+ break;
+ case Account:
+ focused = tvAccount.requestFocus();
+ tvAccount.dismissDropDown();
+ if (focused)
+ Misc.showSoftKeyboard(
+ (NewTransactionActivity) tvAccount.getContext());
+ break;
}
}
adapterPosition, layoutPosition, item.getType()
.toString()
.concat(item.getType() ==
- NewTransactionModel.ItemType.transactionRow
+ ItemType.transactionRow
? String.format(Locale.US,
"'%s'=%s",
item.getAccount()
item.setDescription(String.valueOf(tvDescription.getText()));
break;
case transactionRow:
- item.getAccount()
- .setAccountName(String.valueOf(tvAccount.getText()));
+ final LedgerTransactionAccount account = item.getAccount();
+ account.setAccountName(String.valueOf(tvAccount.getText()));
+
+ account.setComment(String.valueOf(tvComment.getText()));
// TODO: handle multiple amounts
String amount = String.valueOf(tvAmount.getText());
amount = amount.trim();
if (amount.isEmpty()) {
- item.getAccount()
- .resetAmount();
+ account.resetAmount();
}
else {
try {
amount = amount.replace(decimalSeparator, decimalDot);
- item.getAccount()
- .setAmount(Float.parseFloat(amount));
+ account.setAmount(Float.parseFloat(amount));
}
catch (NumberFormatException e) {
Logger.debug("new-trans", String.format(
"assuming amount is not set due to number format exception. " +
"input was '%s'", amount));
- item.getAccount()
- .resetAmount();
+ account.resetAmount();
}
}
case transactionRow:
LedgerTransactionAccount acc = item.getAccount();
tvAccount.setText(acc.getAccountName());
+ tvComment.setText(acc.getComment());
if (acc.isAmountSet()) {
tvAmount.setText(String.format("%1.2f", acc.getAmount()));
}
model.updateFocusedItem(position);
}
public void noteFocusIsOnAccount(int position) {
- model.noteFocusIsOnAccount(position);
+ model.noteFocusChanged(position, NewTransactionModel.FocusedElement.Account);
}
public void noteFocusIsOnAmount(int position) {
- model.noteFocusIsOnAmount(position);
+ model.noteFocusChanged(position, NewTransactionModel.FocusedElement.Amount);
+ }
+ public void noteFocusIsOnComment(int position) {
+ model.noteFocusChanged(position, NewTransactionModel.FocusedElement.Comment);
}
}
for (int i = 0; i < items.size(); i++) {
Item item = items.get(i);
LedgerTransactionAccount acc = item.getAccount();
- debug("submittable", String.format("Item %2d: [%4.2f] %s", i,
- acc.isAmountSet() ? acc.getAmount() : 0, acc.getAccountName()));
+ debug("submittable", String.format("Item %2d: [%4.2f] %s (%s)", i,
+ acc.isAmountSet() ? acc.getAmount() : 0, acc.getAccountName(),
+ acc.getComment()));
}
}
}
public void updateFocusedItem(int position) {
focusedItem.setValue(position);
}
- public void noteFocusIsOnAccount(int position) {
- getItem(position).setFocusIsOnAmount(false);
- }
- public void noteFocusIsOnAmount(int position) {
- getItem(position).setFocusIsOnAmount(true);
+ public void noteFocusChanged(int position, FocusedElement element) {
+ getItem(position).setFocusedElement(element);
}
public void swapItems(int one, int two) {
Collections.swap(items, one-1, two-1);
//==========================================================================================
- class Item extends Object {
+ enum FocusedElement {Account, Comment, Amount}
+
+ class Item {
private ItemType type;
private MutableLiveData<Date> date = new MutableLiveData<>();
private MutableLiveData<String> description = new MutableLiveData<>();
private MutableLiveData<String> amountHint = new MutableLiveData<>(null);
private NewTransactionModel model;
private MutableLiveData<Boolean> editable = new MutableLiveData<>(true);
- private boolean focusIsOnAmount = false;
+ private FocusedElement focusedElement = FocusedElement.Account;
public Item(NewTransactionModel model) {
this.model = model;
type = ItemType.bottomFiller;
this.account = account;
this.editable.setValue(true);
}
- public boolean focusIsOnAmount() {
- return focusIsOnAmount;
+ public FocusedElement getFocusedElement() {
+ return focusedElement;
+ }
+ public void setFocusedElement(FocusedElement focusedElement) {
+ this.focusedElement = focusedElement;
}
public NewTransactionModel getModel() {
return model;
public void stopObservingEditableFlag(Observer<Boolean> observer) {
editable.removeObserver(observer);
}
- public void setFocusIsOnAmount(boolean flag) {
- focusIsOnAmount = flag;
- }
}
}
--- /dev/null
+<!--
+ ~ Copyright Google Inc.
+ ~
+ ~ Licensed under the Apache License, version 2.0 ("the License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the license at:
+ ~
+ ~ https://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distribution under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ Modified/adapted by Damyan Ivanov for MoLe
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:autoMirrored="true"
+ android:tint="?colorPrimary"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M21.99,4c0,-1.1 -0.89,-2 -1.99,-2L4,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z" />
+</vector>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ntr_account"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:layout_height="wrap_content">
<net.ktnx.mobileledger.ui.AutoCompleteTextViewWithClear
android:id="@+id/account_row_acc_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- <EditText
- android:id="@+id/account_row_acc_amounts"
+ <TextView
+ android:id="@+id/comment_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="bottom|end"
- android:layout_weight="0"
- android:width="0dp"
- android:foregroundGravity="bottom"
- android:gravity="bottom|end"
- android:hint="@string/zero_amount"
+ android:alpha="0.5"
+ android:drawableStart="@drawable/ic_comment_black_24dp"
+ app:layout_constraintBottom_toBottomOf="@+id/comment"
+ app:layout_constraintStart_toStartOf="@+id/ntr_account"
+ app:layout_constraintTop_toBottomOf="@+id/account_row_acc_name" />
+
+ <EditText
+ android:id="@+id/comment"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="@string/transaction_account_comment_hint"
android:imeOptions="actionNext"
- android:inputType="numberSigned|numberDecimal|number"
- android:minWidth="80sp"
- android:selectAllOnFocus="true"
- android:textAlignment="viewEnd"
- app:layout_constraintEnd_toEndOf="parent"
+ android:inputType="text"
+ app:layout_constraintEnd_toEndOf="@+id/ntr_account"
+ app:layout_constraintStart_toEndOf="@id/comment_button"
app:layout_constraintTop_toBottomOf="@id/account_row_acc_name" />
+ <LinearLayout
+ android:id="@+id/amount_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/comment">
+
+ <EditText
+ android:id="@+id/account_row_acc_amounts"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|end"
+ android:layout_weight="0"
+ android:width="0dp"
+ android:foregroundGravity="bottom"
+ android:gravity="bottom|end"
+ android:hint="@string/zero_amount"
+ android:imeOptions="actionNext"
+ android:inputType="numberSigned|numberDecimal|number"
+ android:minWidth="80sp"
+ android:selectAllOnFocus="true"
+ android:textAlignment="viewEnd" />
+ </LinearLayout>
+
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
<string name="api_post_1_14">Version 1.15 and above</string>
<string name="api_auto">Detect automaticaly</string>
<string name="profile_api_version_title">Backend server version</string>
+ <string name="transaction_account_comment_hint">comment</string>
</resources>