Skip to content

Commit

Permalink
Add ability to import categories from CSV
Browse files Browse the repository at this point in the history
  • Loading branch information
ScottFries committed Oct 16, 2023
1 parent cae2b9c commit f732053
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/desktop-client/src/components/accounts/Account.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ class AccountInternal extends PureComponent {
onImport = async () => {
const accountId = this.props.accountId;
const account = this.props.accounts.find(acct => acct.id === accountId);
const categories = await this.props.getCategories();

if (account) {
const res = await window.Actual.openFileDialog({
Expand All @@ -476,6 +477,7 @@ class AccountInternal extends PureComponent {
if (res) {
this.props.pushModal('import-transactions', {
accountId,
categories,
filename: res[0],
onImported: didChange => {
if (didChange) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,18 @@ function getInitialMappings(transactions) {
fields.find(([name, value]) => value.match(/^-?[.,\d]+$/)),
);

let categoryField = key(
fields.find(([name, value]) => name.toLowerCase().includes('category')),
);

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

Check warning on line 190 in packages/desktop-client/src/components/modals/ImportTransactions.js

View workflow job for this annotation

GitHub Actions / lint

Replace `([name,·value])·=>·name·!==·dateField·&&·name·!==·amountField·&&·name·!==·categoryField` with `⏎······([name,·value])·=>⏎········name·!==·dateField·&&·name·!==·amountField·&&·name·!==·categoryField,⏎····`
);

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

Check warning on line 196 in packages/desktop-client/src/components/modals/ImportTransactions.js

View workflow job for this annotation

GitHub Actions / lint

Replace `·name·!==·amountField·&&·name·!==·categoryField·&&` with `⏎········name·!==·amountField·&&⏎········name·!==·categoryField·&&⏎·······`
),
);

Expand All @@ -198,6 +202,7 @@ function getInitialMappings(transactions) {
amount: amountField,
payee: payeeField,
notes: notesField,
category: categoryField,
};
}

Expand Down Expand Up @@ -248,6 +253,19 @@ function parseAmountFields(trans, splitMode, flipAmount, multiplierAmount) {
};
}

function parseCategoryFields(trans, categories) {
let match = null;
for (let category of categories) {
if (category.id === trans.category) {
return null;
}
if (category.name === trans.category) {
match = category.id;
}
}
return match;
}

function Transaction({
transaction: rawTransaction,
fieldMappings,
Expand Down Expand Up @@ -302,6 +320,9 @@ function Transaction({
<Field width="flex" title={transaction.notes}>
{transaction.notes}
</Field>
<Field width="flex" title={transaction.category}>
{transaction.category}
</Field>
{splitMode ? (
<>
<Field
Expand Down Expand Up @@ -513,6 +534,17 @@ function FieldMappings({
firstTransaction={transactions[0]}
/>
</View>
<View style={{ flex: 1 }}>
<SubLabel title="Category" />
<SelectField
options={options}
value={mappings.category}
style={{ marginRight: 5 }}
onChange={name => onChange('category', name)}
hasHeaderRow={hasHeaderRow}
firstTransaction={transactions[0]}
/>
</View>
{splitMode ? (
<>
<View style={{ flex: 0.5 }}>
Expand Down Expand Up @@ -571,7 +603,7 @@ export default function ImportTransactions({ modalProps, options }) {
let [splitMode, setSplitMode] = useState(false);
let [flipAmount, setFlipAmount] = useState(false);
let [multiplierEnabled, setMultiplierEnabled] = useState(false);
let { accountId, onImported } = options;
let { accountId, categories, onImported } = options;

// This cannot be set after parsing the file, because changing it
// requires re-parsing the file. This is different from the other
Expand Down Expand Up @@ -757,6 +789,11 @@ export default function ImportTransactions({ modalProps, options }) {
break;
}

const category_id = parseCategoryFields(trans, categories.list);
if (category_id != null) {
trans.category = category_id;
}

let { inflow, outflow, ...finalTransaction } = trans;
finalTransactions.push({
...finalTransaction,
Expand Down Expand Up @@ -810,6 +847,7 @@ export default function ImportTransactions({ modalProps, options }) {
{ name: 'Date', width: 200 },
{ name: 'Payee', width: 'flex' },
{ name: 'Notes', width: 'flex' },
{ name: 'Category', width: 'flex' },
];

if (splitMode) {
Expand Down Expand Up @@ -847,7 +885,7 @@ export default function ImportTransactions({ modalProps, options }) {

<TableWithNavigator
items={transactions}
fields={['payee', 'amount']}
fields={['payee', 'catgory', 'amount']}
style={{ backgroundColor: theme.tableHeaderBackground }}
getItemKey={index => index}
renderEmpty={() => {
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/1801.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [ScottFries,blakegearin]
---

Add ability to import categories from CSV

0 comments on commit f732053

Please sign in to comment.