Show possible duplicate transactions

master
Tanner Collin 7 months ago
parent 0eaf52272a
commit ec502bdd15
  1. 14
      apiserver/apiserver/api/views.py
  2. 6
      webclient/src/Home.js
  3. 58
      webclient/src/Transactions.js

@ -507,6 +507,8 @@ class TransactionViewSet(Base, List, Create, Retrieve, Update):
def get_queryset(self):
queryset = models.Transaction.objects
month = self.request.query_params.get('month', '')
date = self.request.query_params.get('date', '')
member_id = self.request.query_params.get('member_id', '')
exclude_paypal = self.request.query_params.get('exclude_paypal', '') == 'true'
exclude_snacks = self.request.query_params.get('exclude_snacks', '') == 'true'
exclude_dues = self.request.query_params.get('exclude_dues', '') == 'true'
@ -520,10 +522,22 @@ class TransactionViewSet(Base, List, Create, Retrieve, Update):
queryset = queryset.filter(date__year=dt.year)
queryset = queryset.filter(date__month=dt.month)
queryset = queryset.exclude(category='Memberships:Fake Months')
elif date:
try:
dt = datetime.datetime.strptime(date, '%Y-%m-%d')
except ValueError:
raise exceptions.ValidationError(dict(date='Should be YYYY-MM-DD.'))
queryset = queryset.filter(date__year=dt.year)
queryset = queryset.filter(date__month=dt.month)
queryset = queryset.filter(date__day=dt.day)
queryset = queryset.exclude(category='Memberships:Fake Months')
else:
queryset = queryset.exclude(report_type__isnull=True)
queryset = queryset.exclude(report_type='')
if member_id:
queryset = queryset.filter(user__member__id=member_id)
if exclude_paypal:
queryset = queryset.exclude(account_type='PayPal')

@ -397,7 +397,11 @@ export function Home(props) {
<p>ORD3 printer: {printer3dStat('ord3')}</p>
{user && <p>Alarm status: {alarmStat()}</p>}
{user ?
<p>Alarm status: {alarmStat()}</p>
:
<p>Alarm status: Unauthorized</p>
}
{user && <p>Hosting status: {closedStat()}</p>}
</div>

@ -12,10 +12,44 @@ export function TransactionEditor(props) {
const { token, input, setInput, error } = props;
const [prevInput] = useState(input);
const [prevTransactions, setPrevTransactions] = useState([]);
const [txError, setTxError] = useState(false);
const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value });
const handleChange = (e) => handleValues(e, e.currentTarget);
const checkPrevTransactions = (member_id, date) => {
console.log(member_id, date);
const isValidISODate = /^\d{4}-\d{2}-\d{2}$/.test(date);
if (!member_id || !isValidISODate) {
return;
}
console.log('Checking previous transactions:', member_id, date);
requester('/transactions/?date=' + date + '&member_id=' + member_id, 'GET', token)
.then(res => {
setTxError(false);
setPrevTransactions(res.results);
})
.catch(err => {
console.log(err);
setTxError(true);
});
};
const handleMemberValue = (e, v) => {
checkPrevTransactions(v.value, input.date);
handleValues(e, v);
};
const handleDateValue = (e) => {
checkPrevTransactions(input.member_id, e.currentTarget.value);
handleChange(e);
};
const makeProps = (name) => ({
name: name,
onChange: handleChange,
@ -70,18 +104,27 @@ export function TransactionEditor(props) {
<MembersDropdown
token={token}
{...makeProps('member_id')}
onChange={handleValues}
onChange={handleMemberValue}
initial={input.member_name}
/>
</Form.Field>
<Form.Input
label='Date'
label='Transaction Date (YYYY-MM-DD)'
fluid
{...makeProps('date')}
onChange={handleDateValue}
/>
</Form.Group>
{!!prevTransactions.length && <Form.Field>
<label>Potential Duplicates</label>
<p>These are from the same member, same day.</p>
<TransactionList noMember noDate addRef transactions={prevTransactions} />
</Form.Field>}
{txError && <p>Error checking for duplicate transactions.</p>}
<Form.Group widths='equal'>
<Form.Select
label='Payment Method'
@ -213,18 +256,19 @@ function EditTransaction(props) {
export function TransactionList(props) {
const { transactions, noMember, noCategory } = props;
const { transactions, noMember, noCategory, noDate, addRef } = props;
const isMobile = useIsMobile();
return (
<Table basic='very'>
{!isMobile && <Table.Header>
<Table.Row>
<Table.HeaderCell>Date</Table.HeaderCell>
{!noDate && <Table.HeaderCell>Date</Table.HeaderCell>}
{!noMember && <Table.HeaderCell>Member</Table.HeaderCell>}
<Table.HeaderCell>Amount</Table.HeaderCell>
<Table.HeaderCell>Method</Table.HeaderCell>
{!noCategory && <Table.HeaderCell>Category</Table.HeaderCell>}
{!!addRef && <Table.HeaderCell>Reference</Table.HeaderCell>}
<Table.HeaderCell>Memo</Table.HeaderCell>
</Table.Row>
</Table.Header>}
@ -233,9 +277,10 @@ export function TransactionList(props) {
{transactions.length ?
transactions.map(x =>
<Table.Row key={x.id}>
<Table.Cell style={{ minWidth: '8rem' }}>
{!noDate && <Table.Cell style={{ minWidth: '8rem' }}>
<Link to={'/transactions/'+x.id}>{moment(x.date).format('ll')}</Link>
</Table.Cell>
</Table.Cell>}
{!noMember && <Table.Cell>
{x.member_id ?
<Link to={'/members/'+x.member_id}>
@ -248,6 +293,7 @@ export function TransactionList(props) {
<Table.Cell style={{ minWidth: '8rem' }}>{isMobile && 'Amount: '}{x.protocoin !== '0.00' ? '₱' + x.protocoin : '$' + x.amount}</Table.Cell>
<Table.Cell>{isMobile && 'Method: '}{x.account_type}</Table.Cell>
{!noCategory && <Table.Cell>{isMobile && 'Category: '}{x.category}</Table.Cell>}
{!!addRef && <Table.Cell>{isMobile && 'Reference: '}{x.reference_number}</Table.Cell>}
<Table.Cell>{x.memo || x.report_memo}</Table.Cell>
</Table.Row>
)

Loading…
Cancel
Save