Skip to content

Commit

Permalink
Enhancement: Add option to select in/out field during import (#1788)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jessseee authored Nov 5, 2023
1 parent a6dae39 commit be18891
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 27 deletions.
165 changes: 138 additions & 27 deletions packages/desktop-client/src/components/modals/ImportTransactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,22 @@ function getInitialMappings(transactions) {
),
);

let inOutField = key(
fields.find(
([name, value]) =>
name !== dateField &&
name !== amountField &&
name !== payeeField &&
name !== notesField,
),
);

return {
date: dateField,
amount: amountField,
payee: payeeField,
notes: notesField,
inOut: inOutField,
};
}

Expand All @@ -222,7 +233,14 @@ function parseAmount(amount, mapper) {
return value;
}

function parseAmountFields(trans, splitMode, flipAmount, multiplierAmount) {
function parseAmountFields(
trans,
splitMode,
inOutMode,
outValue,
flipAmount,
multiplierAmount,
) {
const multiplier = parseFloat(multiplierAmount) || 1.0;

if (splitMode) {
Expand All @@ -240,6 +258,16 @@ function parseAmountFields(trans, splitMode, flipAmount, multiplierAmount) {
inflow,
};
}
if (inOutMode) {
return {
amount:
parseAmount(trans.amount, n =>
trans.inOut === outValue ? Math.abs(n) * -1 : Math.abs(n),
) * multiplier,
outflow: null,
inflow: null,
};
}
return {
amount:
parseAmount(trans.amount, n => (flipAmount ? n * -1 : n)) * multiplier,
Expand All @@ -255,6 +283,8 @@ function Transaction({
parseDateFormat,
dateFormat,
splitMode,
inOutMode,
outValue,
flipAmount,
multiplierAmount,
}) {
Expand All @@ -269,6 +299,8 @@ function Transaction({
let { amount, outflow, inflow } = parseAmountFields(
transaction,
splitMode,
inOutMode,
outValue,
flipAmount,
multiplierAmount,
);
Expand Down Expand Up @@ -320,13 +352,24 @@ function Transaction({
</Field>
</>
) : (
<Field
width={90}
contentStyle={{ textAlign: 'right', ...styles.tnum }}
title={amount}
>
{amount}
</Field>
<>
{inOutMode && (
<Field
width={90}
contentStyle={{ textAlign: 'left', ...styles.tnum }}
title={transaction.inOut}
>
{transaction.inOut}
</Field>
)}
<Field
width={90}
contentStyle={{ textAlign: 'right', ...styles.tnum }}
title={amount}
>
{amount}
</Field>
</>
)}
</Row>
);
Expand Down Expand Up @@ -457,11 +500,43 @@ function MultiplierOption({
);
}

function InOutOption({
inOutMode,
outValue,
disabled,
onToggle,
onChangeText,
}) {
return (
<View style={{ flexDirection: 'row', gap: 10, height: 28 }}>
<CheckboxOption
id="form_inOut"
checked={inOutMode}
disabled={disabled}
onChange={onToggle}
>
{inOutMode
? 'in/out identifier'
: 'Select column to specify if amount goes in/out'}
</CheckboxOption>
{inOutMode && (
<Input
type="text"
value={outValue}
onUpdate={onChangeText}
placeholder="Value for out rows, i.e. Credit"
/>
)}
</View>
);
}

function FieldMappings({
transactions,
mappings,
onChange,
splitMode,
inOutMode,
hasHeaderRow,
}) {
if (transactions.length === 0) {
Expand Down Expand Up @@ -537,16 +612,30 @@ function FieldMappings({
</View>
</>
) : (
<View style={{ flex: 1 }}>
<SubLabel title="Amount" />
<SelectField
options={options}
value={mappings.amount}
onChange={name => onChange('amount', name)}
hasHeaderRow={hasHeaderRow}
firstTransaction={transactions[0]}
/>
</View>
<>
{inOutMode && (
<View style={{ flex: 1 }}>
<SubLabel title="In/Out" />
<SelectField
options={options}
value={mappings.inOut}
onChange={name => onChange('inOut', name)}
hasHeaderRow={hasHeaderRow}
firstTransaction={transactions[0]}
/>
</View>
)}
<View style={{ flex: 1 }}>
<SubLabel title="Amount" />
<SelectField
options={options}
value={mappings.amount}
onChange={name => onChange('amount', name)}
hasHeaderRow={hasHeaderRow}
firstTransaction={transactions[0]}
/>
</View>
</>
)}
</Stack>
</View>
Expand All @@ -569,6 +658,8 @@ export default function ImportTransactions({ modalProps, options }) {
let [filetype, setFileType] = useState(null);
let [fieldMappings, setFieldMappings] = useState(null);
let [splitMode, setSplitMode] = useState(false);
let [inOutMode, setInOutMode] = useState(false);
let [outValue, setOutValue] = useState('');
let [flipAmount, setFlipAmount] = useState(false);
let [multiplierEnabled, setMultiplierEnabled] = useState(false);
let { accountId, onImported } = options;
Expand Down Expand Up @@ -684,6 +775,8 @@ export default function ImportTransactions({ modalProps, options }) {

let isSplit = !splitMode;
setSplitMode(isSplit);
setInOutMode(false);
setFlipAmount(false);

// Run auto-detection on the fields to try to detect the fields
// automatically
Expand Down Expand Up @@ -749,6 +842,8 @@ export default function ImportTransactions({ modalProps, options }) {
let { amount } = parseAmountFields(
trans,
splitMode,
inOutMode,
outValue,
flipAmount,
multiplierAmount,
);
Expand All @@ -757,7 +852,7 @@ export default function ImportTransactions({ modalProps, options }) {
break;
}

let { inflow, outflow, ...finalTransaction } = trans;
let { inflow, outflow, inOut, ...finalTransaction } = trans;
finalTransactions.push({
...finalTransaction,
date,
Expand Down Expand Up @@ -812,6 +907,9 @@ export default function ImportTransactions({ modalProps, options }) {
{ name: 'Notes', width: 'flex' },
];

if (inOutMode) {
headers.push({ name: 'In/Out', width: 90, style: { textAlign: 'left' } });
}
if (splitMode) {
headers.push({ name: 'Outflow', width: 90, style: { textAlign: 'right' } });
headers.push({ name: 'Inflow', width: 90, style: { textAlign: 'right' } });
Expand Down Expand Up @@ -873,6 +971,8 @@ export default function ImportTransactions({ modalProps, options }) {
dateFormat={dateFormat}
fieldMappings={fieldMappings}
splitMode={splitMode}
inOutMode={inOutMode}
outValue={outValue}
flipAmount={flipAmount}
multiplierAmount={multiplierAmount}
/>
Expand Down Expand Up @@ -905,6 +1005,7 @@ export default function ImportTransactions({ modalProps, options }) {
onChange={onUpdateFields}
mappings={fieldMappings}
splitMode={splitMode}
inOutMode={inOutMode}
hasHeaderRow={hasHeaderRow}
/>
</View>
Expand Down Expand Up @@ -1018,19 +1119,29 @@ export default function ImportTransactions({ modalProps, options }) {
<CheckboxOption
id="form_flip"
checked={flipAmount}
disabled={splitMode}
disabled={splitMode || inOutMode}
onChange={() => setFlipAmount(!flipAmount)}
>
Flip amount
</CheckboxOption>
{filetype === 'csv' && (
<CheckboxOption
id="form_split"
checked={splitMode}
onChange={onSplitMode}
>
Split amount into separate inflow/outflow columns
</CheckboxOption>
<>
<CheckboxOption
id="form_split"
checked={splitMode}
disabled={inOutMode || flipAmount}
onChange={onSplitMode}
>
Split amount into separate inflow/outflow columns
</CheckboxOption>
<InOutOption
inOutMode={inOutMode}
outValue={outValue}
disabled={splitMode || flipAmount}
onToggle={() => setInOutMode(!inOutMode)}
onChangeText={setOutValue}
/>
</>
)}
<MultiplierOption
multiplierEnabled={multiplierEnabled}
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/1788.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [Jessseee]
---

Added option to select in/out field during import.

0 comments on commit be18891

Please sign in to comment.