Fix transaction creation

Signed-off-by: William Brawner <me@wbrawner.com>
This commit is contained in:
William Brawner 2020-03-22 21:59:02 +00:00
parent e4a3855d83
commit 3b72e1305b
3 changed files with 80 additions and 80 deletions

View file

@ -25,8 +25,8 @@ class TransactionController extends Controller
private $transactionMapper; private $transactionMapper;
private $userPermissionMapper; private $userPermissionMapper;
private $logger; private $logger;
private $DATE_FORMAT = DateTime::RFC3339_EXTENDED;
private const DATE_FORMAT = "Y-m-d\TH:i:s.v\Z"; private const DATE_FORMAT = "Y-m-d\TH:i:s.v\Z";
private const AMOUNT_REGEX = "/^(([\d]{1,3}[\,\.]?)?([\d]{3}([\.\,])?)+([\.\,][\d]{2})?|[\d]+)$/";
public function __construct( public function __construct(
$AppName, $AppName,
@ -120,7 +120,7 @@ class TransactionController extends Controller
$transaction->setDescription($description); $transaction->setDescription($description);
$transaction->setAmount($amount); $transaction->setAmount($amount);
$transaction->setExpense($expense); $transaction->setExpense($expense);
$dateTime = DateTime::createFromFormat($this->DATE_FORMAT, $date); $dateTime = DateTime::createFromFormat(self::DATE_FORMAT, $date);
if (!$dateTime) { if (!$dateTime) {
return new DataResponse(["message" => "Invalid date format: '$date'"], Http::STATUS_BAD_REQUEST); return new DataResponse(["message" => "Invalid date format: '$date'"], Http::STATUS_BAD_REQUEST);
} }
@ -173,7 +173,7 @@ class TransactionController extends Controller
$transaction->setDescription($description); $transaction->setDescription($description);
$transaction->setAmount($amount); $transaction->setAmount($amount);
$transaction->setExpense($expense); $transaction->setExpense($expense);
$dateTime = DateTime::createFromFormat($this->DATE_FORMAT, $date); $dateTime = DateTime::createFromFormat(self::DATE_FORMAT, $date);
if (!$dateTime) { if (!$dateTime) {
return new DataResponse([], Http::STATUS_BAD_REQUEST); return new DataResponse([], Http::STATUS_BAD_REQUEST);
} }
@ -240,7 +240,7 @@ class TransactionController extends Controller
); );
$startDateTime->setTime(0, 0, 0, 0); $startDateTime->setTime(0, 0, 0, 0);
} else { } else {
$startDateTime = DateTime::createFromFormat($this->DATE_FORMAT, $startDate); $startDateTime = DateTime::createFromFormat(self::DATE_FORMAT, $startDate);
} }
if (!$startDateTime) { if (!$startDateTime) {
return new DataResponse([], Http::STATUS_BAD_REQUEST); return new DataResponse([], Http::STATUS_BAD_REQUEST);
@ -255,7 +255,7 @@ class TransactionController extends Controller
); );
$endDateTime->setTime(23, 59, 59, 999); $endDateTime->setTime(23, 59, 59, 999);
} else { } else {
$endDateTime = DateTime::createFromFormat($this->DATE_FORMAT, $endDate); $endDateTime = DateTime::createFromFormat(self::DATE_FORMAT, $endDate);
} }
if (!$endDateTime) { if (!$endDateTime) {
return new DataResponse([], Http::STATUS_BAD_REQUEST); return new DataResponse([], Http::STATUS_BAD_REQUEST);

View file

@ -34,7 +34,7 @@ class Version000001Date20200204101200 extends SimpleMigrationStep {
'length' => 200 'length' => 200
]); ]);
$table->addColumn('description', 'string', [ $table->addColumn('description', 'string', [
'notnull' => true, 'notnull' => false,
'length' => 1000, 'length' => 1000,
]); ]);

View file

@ -1,97 +1,97 @@
<template> <template>
<div> <div>
<div v-if="!loading" class="add-edit-transaction"> <div v-if="!loading" class="add-edit-transaction">
<h2>{{ transaction.id ? 'Edit' : 'Add' }} Transaction</h2> <h2>{{ transaction.id ? 'Edit' : 'Add' }} Transaction</h2>
<input v-model="transaction.name" type="text" placeholder="Name" title="Name" /> <input v-model="transaction.name" type="text" placeholder="Name" title="Name" />
<textarea v-model="transaction.description" placeholder="Description" title="Description"></textarea> <textarea v-model="transaction.description" placeholder="Description" title="Description"></textarea>
<input v-model.number="transaction.amount" type="number" placeholder="Amount" title="Amount" /> <input v-model.number="transaction.amount" type="number" placeholder="Amount" title="Amount" />
<DatetimePicker :value="transaction.date" type="datetime" /> <DatetimePicker :value="transaction.date" type="datetime" />
<div class="radio-container"> <div class="radio-container">
<input v-model="transaction.expense" type="radio" id="expense" :value="true" /> <input v-model="transaction.expense" type="radio" id="expense" :value="true" />
<label for="expense">Expense</label> <label for="expense">Expense</label>
<input v-model="transaction.expense" type="radio" id="income" :value="false" /> <input v-model="transaction.expense" type="radio" id="income" :value="false" />
<label for="income">Income</label> <label for="income">Income</label>
</div> </div>
<select v-model="transaction.budgetId" v-on:change="updateCategories()"> <select v-model="transaction.budgetId" v-on:change="updateCategories()">
<option disabled value>Select a budget</option> <option disabled value>Select a budget</option>
<option v-for="budget in budgets" :key="budget.id" :value="budget.id">{{ budget.name }}</option> <option v-for="budget in budgets" :key="budget.id" :value="budget.id">{{ budget.name }}</option>
</select> </select>
<select v-model="transaction.categoryId"> <select v-model="transaction.categoryId">
<option disabled value>Select a category</option> <option disabled value>Select a category</option>
<option <option
v-for="category in filteredCategories" v-for="category in filteredCategories"
:key="category.id" :key="category.id"
:value="category.id" :value="category.id"
>{{ category.name }}</option> >{{ category.name }}</option>
</select> </select>
<button @click="saveTransaction()">Save Transaction</button> <button @click="saveTransaction()">Save Transaction</button>
</div>
<div v-if="loading" class="icon-loading"></div>
</div> </div>
<div v-if="loading" class="icon-loading"></div>
</div>
</template> </template>
<script> <script>
import { DatetimePicker } from "@nextcloud/vue/dist/Components/DatetimePicker"; import { DatetimePicker } from "@nextcloud/vue/dist/Components/DatetimePicker";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
export default { export default {
name: "add-edit-transaction", name: "add-edit-transaction",
components: { components: {
DatetimePicker DatetimePicker
},
data: function() {
return {
saving: false
};
},
props: {
transaction: Object
},
computed: {
...mapGetters(["budgets"]),
filteredCategories: function(state) {
return this.$store.getters.categories.filter(function(category) {
return category.expense === state.transaction.expense;
});
}, },
loading: state => state.transaction === undefined || state.saving data: function() {
}, return {
methods: { saving: false
updateCategories() { };
if (!this.transaction) return;
this.$store.dispatch(
"addEditTransactionBudgetSelected",
this.transaction.budgetId
);
}, },
saveTransaction() { props: {
this.saving = true; transaction: Object
this.$store.dispatch("addEditTransactionSaveClicked", this.transaction); },
computed: {
...mapGetters(["budgets"]),
filteredCategories: function(state) {
return this.$store.getters.categories.filter(function(category) {
return category.expense === state.transaction.expense;
});
},
loading: state => state.transaction === undefined || state.saving
},
methods: {
updateCategories() {
if (!this.transaction) return;
this.$store.dispatch(
"addEditTransactionBudgetSelected",
this.transaction.budgetId
);
},
saveTransaction() {
this.saving = true;
this.$store.dispatch("transactionFormSaveClicked", this.transaction);
}
},
mounted() {
let transactionId;
if (this.transaction) {
transactionId = this.transaction.id;
}
this.updateCategories();
} }
},
mounted() {
let transactionId;
if (this.transaction) {
transactionId = this.transaction.id;
}
this.updateCategories();
}
}; };
</script> </script>
<style scoped> <style scoped>
.add-edit-transaction > * { .add-edit-transaction > * {
display: block; display: block;
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;
} }
.radio-container { .radio-container {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.radio-container label { .radio-container label {
margin-right: 1em; margin-right: 1em;
} }
.icon-loading { .icon-loading {
margin-top: 16px; margin-top: 16px;
} }
</style> </style>