Show possible duplicate transactions

This commit is contained in:
Tanner Collin 2023-10-12 06:49:54 +00:00
parent 0eaf52272a
commit ec502bdd15
3 changed files with 71 additions and 7 deletions

View File

@ -507,6 +507,8 @@ class TransactionViewSet(Base, List, Create, Retrieve, Update):
def get_queryset(self): def get_queryset(self):
queryset = models.Transaction.objects queryset = models.Transaction.objects
month = self.request.query_params.get('month', '') 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_paypal = self.request.query_params.get('exclude_paypal', '') == 'true'
exclude_snacks = self.request.query_params.get('exclude_snacks', '') == 'true' exclude_snacks = self.request.query_params.get('exclude_snacks', '') == 'true'
exclude_dues = self.request.query_params.get('exclude_dues', '') == '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__year=dt.year)
queryset = queryset.filter(date__month=dt.month) queryset = queryset.filter(date__month=dt.month)
queryset = queryset.exclude(category='Memberships:Fake Months') 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: else:
queryset = queryset.exclude(report_type__isnull=True) queryset = queryset.exclude(report_type__isnull=True)
queryset = queryset.exclude(report_type='') queryset = queryset.exclude(report_type='')
if member_id:
queryset = queryset.filter(user__member__id=member_id)
if exclude_paypal: if exclude_paypal:
queryset = queryset.exclude(account_type='PayPal') queryset = queryset.exclude(account_type='PayPal')

View File

@ -397,7 +397,11 @@ export function Home(props) {
<p>ORD3 printer: {printer3dStat('ord3')}</p> <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>} {user && <p>Hosting status: {closedStat()}</p>}
</div> </div>

View File

@ -12,10 +12,44 @@ export function TransactionEditor(props) {
const { token, input, setInput, error } = props; const { token, input, setInput, error } = props;
const [prevInput] = useState(input); const [prevInput] = useState(input);
const [prevTransactions, setPrevTransactions] = useState([]);
const [txError, setTxError] = useState(false);
const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value });
const handleChange = (e) => handleValues(e, e.currentTarget); 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) => ({ const makeProps = (name) => ({
name: name, name: name,
onChange: handleChange, onChange: handleChange,
@ -70,18 +104,27 @@ export function TransactionEditor(props) {
<MembersDropdown <MembersDropdown
token={token} token={token}
{...makeProps('member_id')} {...makeProps('member_id')}
onChange={handleValues} onChange={handleMemberValue}
initial={input.member_name} initial={input.member_name}
/> />
</Form.Field> </Form.Field>
<Form.Input <Form.Input
label='Date' label='Transaction Date (YYYY-MM-DD)'
fluid fluid
{...makeProps('date')} {...makeProps('date')}
onChange={handleDateValue}
/> />
</Form.Group> </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.Group widths='equal'>
<Form.Select <Form.Select
label='Payment Method' label='Payment Method'
@ -213,18 +256,19 @@ function EditTransaction(props) {
export function TransactionList(props) { export function TransactionList(props) {
const { transactions, noMember, noCategory } = props; const { transactions, noMember, noCategory, noDate, addRef } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return ( return (
<Table basic='very'> <Table basic='very'>
{!isMobile && <Table.Header> {!isMobile && <Table.Header>
<Table.Row> <Table.Row>
<Table.HeaderCell>Date</Table.HeaderCell> {!noDate && <Table.HeaderCell>Date</Table.HeaderCell>}
{!noMember && <Table.HeaderCell>Member</Table.HeaderCell>} {!noMember && <Table.HeaderCell>Member</Table.HeaderCell>}
<Table.HeaderCell>Amount</Table.HeaderCell> <Table.HeaderCell>Amount</Table.HeaderCell>
<Table.HeaderCell>Method</Table.HeaderCell> <Table.HeaderCell>Method</Table.HeaderCell>
{!noCategory && <Table.HeaderCell>Category</Table.HeaderCell>} {!noCategory && <Table.HeaderCell>Category</Table.HeaderCell>}
{!!addRef && <Table.HeaderCell>Reference</Table.HeaderCell>}
<Table.HeaderCell>Memo</Table.HeaderCell> <Table.HeaderCell>Memo</Table.HeaderCell>
</Table.Row> </Table.Row>
</Table.Header>} </Table.Header>}
@ -233,9 +277,10 @@ export function TransactionList(props) {
{transactions.length ? {transactions.length ?
transactions.map(x => transactions.map(x =>
<Table.Row key={x.id}> <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> <Link to={'/transactions/'+x.id}>{moment(x.date).format('ll')}</Link>
</Table.Cell> </Table.Cell>}
{!noMember && <Table.Cell> {!noMember && <Table.Cell>
{x.member_id ? {x.member_id ?
<Link to={'/members/'+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 style={{ minWidth: '8rem' }}>{isMobile && 'Amount: '}{x.protocoin !== '0.00' ? '₱ ' + x.protocoin : '$' + x.amount}</Table.Cell>
<Table.Cell>{isMobile && 'Method: '}{x.account_type}</Table.Cell> <Table.Cell>{isMobile && 'Method: '}{x.account_type}</Table.Cell>
{!noCategory && <Table.Cell>{isMobile && 'Category: '}{x.category}</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.Cell>{x.memo || x.report_memo}</Table.Cell>
</Table.Row> </Table.Row>
) )