WIP Reimbursements/expenses
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import moment from 'moment';
|
||||
|
||||
export default class AddExpenseItemComponent extends Component {
|
||||
|
||||
// @tracked newExpense = Expense.create();
|
||||
@tracked amount = '0';
|
||||
@tracked currency = 'EUR';
|
||||
@tracked date = moment().startOf('hour').toDate();
|
||||
@tracked title = '';
|
||||
@tracked description = '';
|
||||
@tracked url = '';
|
||||
@tracked tags = '';
|
||||
|
||||
defaultDate = moment().startOf('hour').toDate();
|
||||
|
||||
// TODO fetch/apply exchange rate to (W)BTC
|
||||
currencies = [
|
||||
{ code: 'EUR' },
|
||||
{ code: 'USD' },
|
||||
{ code: 'GBP' }
|
||||
];
|
||||
|
||||
get submitButtonEnabled () {
|
||||
return true;
|
||||
}
|
||||
|
||||
get submitButtonDisabled () {
|
||||
return !this.submitButtonEnabled;
|
||||
}
|
||||
|
||||
setDefaultValues () {
|
||||
}
|
||||
|
||||
@action
|
||||
submit (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let dateInput = (this.date instanceof Array) ?
|
||||
this.date[0] : this.date;
|
||||
const [ date ] = dateInput.toISOString().split('T');
|
||||
|
||||
// TODO validate form
|
||||
const expense = {
|
||||
amount: parseFloat(this.amount),
|
||||
currency: this.currency,
|
||||
date: date,
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
url: this.url,
|
||||
tags: this.tags.split(',').map(t => t.trim())
|
||||
}
|
||||
|
||||
this.args.addExpenseItem(expense);
|
||||
this.resetProperties();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<form id="add-expense-item" onsubmit={{action "submit"}}>
|
||||
<fieldset class="horizontal">
|
||||
<label>
|
||||
<p class="label">Amount:</p>
|
||||
<p>
|
||||
{{input name="expense-amount" type="text"
|
||||
placeholder="10" value=this.amount}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Currency:</p>
|
||||
<p>
|
||||
<select required name="expense-currency"
|
||||
onchange={{action (mut this.currency)
|
||||
value="target.value"}}>
|
||||
<option value="" selected disabled hidden></option>
|
||||
{{#each this.currencies as |currency|}}
|
||||
<option value={{currency.code}} selected={{eq this.currency currency.code}}>{{currency.code}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</p>
|
||||
</label>
|
||||
</fieldset>
|
||||
<label>
|
||||
<p class="label">Date:</p>
|
||||
<p>
|
||||
{{ember-flatpickr
|
||||
date=this.date
|
||||
defaultDate=this.defaultDate
|
||||
maxDate=this.defaultDate
|
||||
enableTime=false
|
||||
onChange=(action (mut this.date))}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Title:</p>
|
||||
<p>
|
||||
{{input name="expense-title" type="text" value=this.title}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Description (optional):</p>
|
||||
<p>
|
||||
{{input name="expense-description" type="text" value=this.description}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">URL (optional):</p>
|
||||
<p>
|
||||
{{input name="expense-url" type="text" value=this.url}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Tags (comma-separated, optional):</p>
|
||||
<p>
|
||||
{{input name="expense-tags" type="text" value=this.tags}}
|
||||
</p>
|
||||
</label>
|
||||
|
||||
<p class="actions">
|
||||
{{input type="submit" value="Add" disabled=this.submitButtonDisabled
|
||||
class="green" title="Add item to reimbursement"}}
|
||||
</p>
|
||||
</form>
|
||||
@@ -5,40 +5,39 @@ import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { A } from '@ember/array';
|
||||
import Reimbursement from 'kredits-web/models/reimbursement';
|
||||
import Expense from 'kredits-web/models/expense';
|
||||
|
||||
export default class AddReimbursementComponent extends Component {
|
||||
@service kredits;
|
||||
|
||||
@alias('kredits.contributorsSorted') contributors;
|
||||
|
||||
@tracked recipientId = null;
|
||||
@tracked title = '';
|
||||
@tracked total = '0';
|
||||
@tracked expenses = A([]);;
|
||||
@tracked newExpense = Expense.create();
|
||||
@tracked expenses = A([]);
|
||||
@tracked expenseFormVisible = true;
|
||||
|
||||
// TODO fetch/apply exchange rate to (W)BTC
|
||||
currencies = [
|
||||
{ code: 'EUR' },
|
||||
{ code: 'USD' },
|
||||
{ code: 'GBP' }
|
||||
];
|
||||
|
||||
get typeofTotal() {
|
||||
return typeof this.total;
|
||||
}
|
||||
|
||||
get submitButtonEnabled() {
|
||||
get submitButtonEnabled () {
|
||||
return this.expenses.length > 0;
|
||||
}
|
||||
|
||||
get submitButtonDisabled() {
|
||||
get submitButtonDisabled () {
|
||||
return !this.submitButtonEnabled;
|
||||
}
|
||||
|
||||
@alias('kredits.contributorsSorted') contributors;
|
||||
@action
|
||||
showExpenseForm () {
|
||||
this.expenseFormVisible = true;
|
||||
}
|
||||
|
||||
@action
|
||||
submit(e) {
|
||||
addExpenseItem (expenseItem) {
|
||||
this.expenses.pushObject(expenseItem);
|
||||
this.expenseFormVisible = false;
|
||||
}
|
||||
|
||||
@action
|
||||
submit (e) {
|
||||
e.preventDefault();
|
||||
console.log('submit', e);
|
||||
// TODO
|
||||
|
||||
@@ -17,82 +17,41 @@
|
||||
</p>
|
||||
</label>
|
||||
|
||||
<h3>
|
||||
Expense items
|
||||
</h3>
|
||||
{{#each this.expenses as |expense|}}
|
||||
<table class="expense-list">
|
||||
<tr>
|
||||
<td class="description">{{expense.title}} – {{expense.description}}</td>
|
||||
<td class="amount">{{fmt-fiat-currency expense.amount expense.currency}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>TODO: date, url, tags</p>
|
||||
<h3>Expense items</h3>
|
||||
{{#if this.expenses}}
|
||||
<ul class="expense-list">
|
||||
{{#each this.expenses as |expense|}}
|
||||
<li>
|
||||
<div class="description" rowspan="2">
|
||||
<h4>
|
||||
<span class="date">{{expense.date}}:</span>
|
||||
<span class="title">{{expense.title}}</span>
|
||||
</h4>
|
||||
<p class="description">{{expense.description}}</p>
|
||||
</div>
|
||||
<div class="amount">
|
||||
{{fmt-fiat-currency expense.amount expense.currency}}
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="danger small">delete</button>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<p class="actions">
|
||||
<button onclick={{fn this.showExpenseForm}} class="green small">+ Add another item</button>
|
||||
</p>
|
||||
{{else}}
|
||||
<p>No line items yet.</p>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
<p class="actions">
|
||||
{{input type="submit" value="Submit" disabled=this.submitButtonDisabled
|
||||
title="Submit/propose this reimbursement"}}
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
New expense item
|
||||
</h3>
|
||||
<form id="add-expense-item">
|
||||
<fieldset class="horizontal">
|
||||
<label>
|
||||
<p class="label">Amount:</p>
|
||||
<p>
|
||||
{{input type="text" placeholder="10" value=this.newExpense.amount}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Currency:</p>
|
||||
<p>
|
||||
<select required onchange={{action (mut this.newExpense.currency) value="target.value"}}>
|
||||
<option value="" selected disabled hidden></option>
|
||||
{{#each this.currencies as |currency|}}
|
||||
<option value={{currency.code}} selected={{eq this.newExpense.currency currency.code}}>{{currency.code}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</p>
|
||||
</label>
|
||||
</fieldset>
|
||||
<label>
|
||||
<p class="label">Date:</p>
|
||||
<p>
|
||||
{{ember-flatpickr
|
||||
date=this.newExpense.date
|
||||
defaultDate=this.newExpense.defaultDate
|
||||
maxDate=this.newExpense.defaultDate
|
||||
enableTime=false
|
||||
onChange=(action (mut this.newExpense.date))}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Title:</p>
|
||||
<p>
|
||||
{{input type="text" value=this.newExpense.title}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">Description (optional):</p>
|
||||
<p>
|
||||
{{input type="text" value=this.newExpense.description}}
|
||||
</p>
|
||||
</label>
|
||||
<label>
|
||||
<p class="label">URL (optional):</p>
|
||||
<p>
|
||||
{{input type="text" value=this.newExpense.url}}
|
||||
</p>
|
||||
</label>
|
||||
|
||||
<p class="actions">
|
||||
{{input type="submit" value="Add" disabled=this.addButtonDisabled
|
||||
class="green" title="Add item to reimbursement"}}
|
||||
</p>
|
||||
</form>
|
||||
{{#if this.expenseFormVisible}}
|
||||
<h3>New expense item</h3>
|
||||
<AddExpenseItem @addExpenseItem={{fn this.addExpenseItem}} />
|
||||
{{/if}}
|
||||
</form>
|
||||
|
||||
@@ -11,14 +11,22 @@
|
||||
<!-- <img src="/img/bitcoin.svg" class="currency-logo"> -->
|
||||
{{sats-to-btc reimbursement.amount}}</span> <span class="symbol">WBTC</span>
|
||||
</p>
|
||||
<table>
|
||||
<ul class="expense-list">
|
||||
{{#each reimbursement.expenses as |expense|}}
|
||||
<tr>
|
||||
<td class="description">{{expense.title}} – {{expense.description}}</td>
|
||||
<td class="amount">{{fmt-fiat-currency expense.amount expense.currency}}</td>
|
||||
</tr>
|
||||
<li>
|
||||
<div class="description" rowspan="2">
|
||||
<h4>
|
||||
<span class="date">{{expense.date}}:</span>
|
||||
<span class="title">{{expense.title}}</span>
|
||||
</h4>
|
||||
<p class="description">{{expense.description}}</p>
|
||||
</div>
|
||||
<div class="amount">
|
||||
{{fmt-fiat-currency expense.amount expense.currency}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
Reference in New Issue
Block a user