Add summary table to admin transactions
This commit is contained in:
parent
0e629151ba
commit
b5f69b6b98
|
@ -557,6 +557,31 @@ class TransactionViewSet(Base, List, Create, Retrieve, Update):
|
||||||
transaction.save()
|
transaction.save()
|
||||||
return Response(200)
|
return Response(200)
|
||||||
|
|
||||||
|
@action(detail=False, methods=['get'])
|
||||||
|
def summary(self, request):
|
||||||
|
txs = models.Transaction.objects
|
||||||
|
month = self.request.query_params.get('month', '')
|
||||||
|
|
||||||
|
try:
|
||||||
|
dt = datetime.datetime.strptime(month, '%Y-%m')
|
||||||
|
except ValueError:
|
||||||
|
raise exceptions.ValidationError(dict(month='Should be YYYY-MM.'))
|
||||||
|
|
||||||
|
txs = txs.filter(date__year=dt.year)
|
||||||
|
txs = txs.filter(date__month=dt.month)
|
||||||
|
txs = txs.exclude(category='Memberships:Fake Months')
|
||||||
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for category in ['Membership', 'Snacks', 'OnAcct', 'Donation', 'Consumables', 'Purchases']:
|
||||||
|
result.append(dict(
|
||||||
|
category = category,
|
||||||
|
dollar = txs.filter(category=category).aggregate(Sum('amount'))['amount__sum'] or 0,
|
||||||
|
protocoin = -1 * (txs.filter(category=category).aggregate(Sum('protocoin'))['protocoin__sum'] or 0),
|
||||||
|
))
|
||||||
|
|
||||||
|
return Response(result)
|
||||||
|
|
||||||
|
|
||||||
class UserView(views.APIView):
|
class UserView(views.APIView):
|
||||||
permission_classes = [AllowMetadata | IsAuthenticated]
|
permission_classes = [AllowMetadata | IsAuthenticated]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import './light.css';
|
import './light.css';
|
||||||
import { Container, Checkbox, Form, Header, Segment } from 'semantic-ui-react';
|
import { Container, Checkbox, Form, Header, Segment, Table } from 'semantic-ui-react';
|
||||||
import * as Datetime from 'react-datetime';
|
import * as Datetime from 'react-datetime';
|
||||||
import 'react-datetime/css/react-datetime.css';
|
import 'react-datetime/css/react-datetime.css';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
@ -42,12 +42,14 @@ export function AdminReportedTransactions(props) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let transactionsCache = false;
|
let transactionsCache = false;
|
||||||
|
let summaryCache = false;
|
||||||
let excludePayPalCache = false;
|
let excludePayPalCache = false;
|
||||||
|
|
||||||
export function AdminHistoricalTransactions(props) {
|
export function AdminHistoricalTransactions(props) {
|
||||||
const { token } = props;
|
const { token } = props;
|
||||||
const [input, setInput] = useState({ month: moment() });
|
const [input, setInput] = useState({ month: moment() });
|
||||||
const [transactions, setTransactions] = useState(transactionsCache);
|
const [transactions, setTransactions] = useState(transactionsCache);
|
||||||
|
const [summary, setSummary] = useState(summaryCache);
|
||||||
const [excludePayPal, setExcludePayPal] = useState(excludePayPalCache);
|
const [excludePayPal, setExcludePayPal] = useState(excludePayPalCache);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
|
@ -75,6 +77,19 @@ export function AdminHistoricalTransactions(props) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
setError(true);
|
setError(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
requester('/transactions/summary/?month=' + month, 'GET', token)
|
||||||
|
.then(res => {
|
||||||
|
setLoading(false);
|
||||||
|
setError(false);
|
||||||
|
setSummary(res);
|
||||||
|
summaryCache = res;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
setLoading(false);
|
||||||
|
console.log(err);
|
||||||
|
setError(true);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -96,10 +111,40 @@ export function AdminHistoricalTransactions(props) {
|
||||||
</Form.Button>
|
</Form.Button>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
</Form>
|
</Form>
|
||||||
|
{transactions && <p>Found {transactions.length} transactions.</p>}
|
||||||
|
|
||||||
|
{!error ?
|
||||||
|
summary && <div>
|
||||||
|
<Header size='small'>Summary</Header>
|
||||||
|
|
||||||
|
<Table basic='very'>
|
||||||
|
<Table.Header>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.HeaderCell>Category</Table.HeaderCell>
|
||||||
|
<Table.HeaderCell>Dollar</Table.HeaderCell>
|
||||||
|
<Table.HeaderCell>Protocoin</Table.HeaderCell>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Header>
|
||||||
|
|
||||||
|
<Table.Body>
|
||||||
|
{summary.map(x =>
|
||||||
|
<Table.Row key={x.category}>
|
||||||
|
<Table.Cell>{x.category}</Table.Cell>
|
||||||
|
<Table.Cell>{'$ ' + x.dollar.toFixed(2)}</Table.Cell>
|
||||||
|
<Table.Cell>{'₱ ' + x.protocoin.toFixed(2)}</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
)}
|
||||||
|
</Table.Body>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<p>Error loading summary.</p>
|
||||||
|
}
|
||||||
|
|
||||||
|
<p/>
|
||||||
|
|
||||||
{!error ?
|
{!error ?
|
||||||
transactions && <div>
|
transactions && <div>
|
||||||
<p>Found {transactions.length} transactions.</p>
|
|
||||||
{!!transactions.length &&
|
{!!transactions.length &&
|
||||||
<Header size='small'>{moment(transactions[0].date, 'YYYY-MM-DD').format('MMMM YYYY')} Transactions</Header>
|
<Header size='small'>{moment(transactions[0].date, 'YYYY-MM-DD').format('MMMM YYYY')} Transactions</Header>
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user