import React, { useState, useEffect, useRef } from 'react'; import { Link, useParams } from 'react-router-dom'; import moment from 'moment-timezone'; import ReactToPrint from 'react-to-print'; import './light.css'; import { Button, Container, Form, Grid, Header, Message, Segment, Table } from 'semantic-ui-react'; import { MembersDropdown } from './Members.js'; import { isAdmin, BasicTable, requester, useIsMobile } from './utils.js'; import { NotFound } from './Misc.js'; 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, value: input[name] || '', error: error[name], }); const accountOptions = [ { key: '0', text: 'Cash', value: 'Cash' }, { key: '1', text: 'Interac e-Transfer', value: 'Interac' }, { key: '2', text: 'Square', value: 'Square Pmt' }, //{ key: '3', text: 'Dream Payments (Debit/Credit)', value: 'Dream Pmt' }, { key: '4', text: 'Cheque', value: 'TD Chequing' }, //{ key: '5', text: 'Member Balance / Protocash', value: 'Member' }, { key: '6', text: 'Membership Adjustment / Clearing', value: 'Clearing' }, { key: '7', text: 'PayPal', value: 'PayPal' }, { key: '8', text: 'Protocoin', value: 'Protocoin' }, ]; const sourceOptions = [ { key: '0', text: 'Web (Spaceport)', value: 'Web' }, { key: '1', text: 'Database Edit', value: 'DB Edit' }, { key: '2', text: 'System', value: 'System' }, { key: '3', text: 'Receipt or Statement', value: 'Receipt or Stmt' }, { key: '4', text: 'Quicken Import', value: 'Quicken Import' }, { key: '5', text: 'PayPal IPN', value: 'PayPal IPN' }, { key: '6', text: 'Auto', value: 'Auto' }, { key: '7', text: 'Nexus Database Bulk', value: 'Nexus DB Bulk' }, { key: '8', text: 'IPN Trigger', value: 'IPN Trigger' }, { key: '9', text: 'Intranet Receipt', value: 'Intranet Receipt' }, { key: '10', text: 'Automatic', value: 'Automatic' }, { key: '11', text: 'Manual', value: 'Manual' }, ]; const categoryOptions = [ { key: '0', text: 'Membership Dues', value: 'Membership' }, { key: '1', text: 'Course Fee', value: 'OnAcct' }, { key: '2', text: 'Snacks / Pop / Coffee', value: 'Snacks' }, { key: '3', text: 'Donation (Explain in Memo)', value: 'Donation' }, { key: '4', text: 'Consumables (Explain in Memo)', value: 'Consumables' }, { key: '5', text: 'Purchase of Locker / Materials / Stock', value: 'Purchases' }, { key: '6', text: 'Purchase of Protocoin', value: 'Exchange' }, { key: '7', text: 'Reimbursement (Not for Refunds)', value: 'Reimburse' }, { key: '8', text: 'Other (Explain in Memo)', value: 'Other' }, ]; return (
{!!prevTransactions.length &&

These are from the same member, same day.

} {txError &&

Error checking for duplicate transactions.

} {input.account_type && (input.account_type === 'Protocoin' ? : )} {input?.account_type !== prevInput?.account_type && input?.account_type === 'PayPal' && Are you sure?

PayPal transactions are automatic. Double check there's no duplicate. They may take 24h to appear.

} {input?.account_type !== prevInput?.account_type && input?.account_type === 'Protocoin' && Are you sure?

Protocoin spending transactions are automatic. Do you want the "Purchase of Protocoin" category below?

{input.protocoin > 0 &&

Also, the value should be a negative number if they are spending Protocoin.

}
} {input.category === 'Membership' && } {input.category === 'Exchange' && }
); }; function EditTransaction(props) { const { transaction, setTransaction, token, refreshUser } = props; const [input, setInput] = useState(transaction); const [error, setError] = useState(false); const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const { id } = useParams(); const handleSubmit = (e) => { if (loading) return; setLoading(true); setSuccess(false); const data = { ...input, report_type: null, report_memo: '' }; requester('/transactions/'+id+'/', 'PUT', token, data) .then(res => { setLoading(false); setSuccess(true); setError(false); setInput(res); setTransaction(res); if (refreshUser) { refreshUser(); } }) .catch(err => { setLoading(false); console.log(err); setError(err.data); }); }; return (
Edit Transaction
{transaction.report_type ? 'Save & Unreport' : 'Save'} {success &&
Success!
}
); }; export function TransactionList(props) { const { transactions, noMember, noCategory, noDate, addRef } = props; const isMobile = useIsMobile(); return ( {!isMobile && {!noDate && Date} {!noMember && Member} Amount Method {!noCategory && Category} {!!addRef && Reference} Memo } {transactions.length ? transactions.map(x => {!noDate && {moment(x.date).format('ll')} } {!noMember && {x.member_id ? {x.member_name} : x.member_name } } {isMobile && 'Amount: '}{x.protocoin !== '0.00' ? '₱ ' + x.protocoin : '$ ' + x.amount} {isMobile && 'Method: '}{x.account_type} {!noCategory && {isMobile && 'Category: '}{x.category}} {!!addRef && {isMobile && 'Reference: '}{x.reference_number}} {x.memo || x.report_memo} ) : None }
); }; export function Transactions(props) { const { user } = props; return (
Your Transactions
); }; class TransactionTable extends React.Component { render() { const transaction = this.props.transaction; const user = this.props.user; return ( Member: {isAdmin(user) && transaction.member_id ? {transaction.member_name} : {transaction.member_name} } Number: {transaction.id} Date: {transaction.date} Amount: $ {transaction.amount} {transaction.protocoin !== '0.00' && Protocoin: ₱ {transaction.protocoin} } Category: {transaction.category} Method: {transaction.account_type} {/* Payment Method: {transaction.payment_method} */} Info Source: {transaction.info_source} Reference: {transaction.reference_number} Memo: {transaction.memo} Recorder: {transaction.recorder || 'System'} {!!transaction.report_type && Report Type: {transaction.report_type} } {!!transaction.report_memo && Report Memo: {transaction.report_memo} } ); } } class TransactionPrint extends React.Component { render() { const transaction = this.props.transaction; const user = this.props.user; return (
Protospace Transaction Receipt

Calgary Protospace Ltd.

Bay 108, 1530 - 27th Ave NE
Calgary, AB T2E 7S6
protospace.ca

Thank you!

); } } export function TransactionDetail(props) { const { token, user } = props; const { id } = useParams(); const ownTransaction = user.transactions.find(x => x.id === id); const [transaction, setTransaction] = useState(ownTransaction || false); const [error, setError] = useState(false); const printRef = useRef(); useEffect(() => { requester('/transactions/'+id+'/', 'GET', token) .then(res => { setTransaction(res); setError(false); }) .catch(err => { console.log(err); setError(true); }); }, [ownTransaction]); return ( {!error ? transaction ?
Transaction Receipt
} content={() => printRef.current} />
{isAdmin(user) ? :
Report Transaction

If there's anything wrong with this transaction or it was made in error please email the Protospace Directors:

directors@protospace.ca

Please include a link to this transaction and any relevant details.

}
:

Loading...

: }
); };