Add summary table to admin transactions
This commit is contained in:
		| @@ -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> | ||||||
| 					} | 					} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user