mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 12:43:09 -05:00
Identify and fix broken transfers (#4216)
* show broken transfers * more detail * feat: add step to fix splits for fixing transfers with categories that should not be there * reword * update the setting * note * lint * typo * another misspelling --------- Co-authored-by: UnderKoen <koenvanstaveren@hotmail.com>
This commit is contained in:
@@ -18,14 +18,20 @@ function useRenderResults() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
function renderResults(results: Results) {
|
||||
const { numBlankPayees, numCleared, numDeleted, mismatchedSplits } =
|
||||
results;
|
||||
const {
|
||||
numBlankPayees,
|
||||
numCleared,
|
||||
numDeleted,
|
||||
numTransfersFixed,
|
||||
mismatchedSplits,
|
||||
} = results;
|
||||
const result: string[] = [];
|
||||
|
||||
if (
|
||||
numBlankPayees === 0 &&
|
||||
numCleared === 0 &&
|
||||
numDeleted === 0 &&
|
||||
numTransfersFixed === 0 &&
|
||||
mismatchedSplits.length === 0
|
||||
) {
|
||||
result.push(t('No split transactions found needing repair.'));
|
||||
@@ -51,6 +57,13 @@ function useRenderResults() {
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (numTransfersFixed > 0) {
|
||||
result.push(
|
||||
t('Fixed {{count}} transfers.', {
|
||||
count: numTransfersFixed,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (mismatchedSplits.length > 0) {
|
||||
const mismatchedSplitInfo = mismatchedSplits
|
||||
.map(t => `- ${t.date}`)
|
||||
@@ -83,7 +96,7 @@ function useRenderResults() {
|
||||
return { renderResults };
|
||||
}
|
||||
|
||||
export function FixSplits() {
|
||||
export function RepairTransactions() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [results, setResults] = useState<Results | null>(null);
|
||||
|
||||
@@ -108,7 +121,7 @@ export function FixSplits() {
|
||||
}}
|
||||
>
|
||||
<ButtonWithLoading isLoading={loading} onPress={onFix}>
|
||||
<Trans>Repair split transactions</Trans>
|
||||
<Trans>Repair transactions</Trans>
|
||||
</ButtonWithLoading>
|
||||
{results && renderResults(results)}
|
||||
</View>
|
||||
@@ -116,11 +129,11 @@ export function FixSplits() {
|
||||
>
|
||||
<Trans>
|
||||
<Text>
|
||||
<strong>Repair split transactions</strong> if you are experiencing
|
||||
bugs relating to split transactions and the “Reset budget cache”
|
||||
button above does not help, this tool may fix them. Some examples of
|
||||
bugs include seeing blank payees on splits or incorrect account
|
||||
balances. This tool does three things:
|
||||
<strong>Repair transactions</strong> if you are experiencing bugs
|
||||
relating to split transactions or transfers and the “Reset budget
|
||||
cache” button above does not help, this tool may fix them. Some
|
||||
examples of bugs include seeing blank payees on splits or incorrect
|
||||
account balances. This tool does four things:
|
||||
</Text>
|
||||
<ul style={{ margin: 0, paddingLeft: '1.5em' }}>
|
||||
<li style={{ marginBottom: '0.5em' }}>
|
||||
@@ -140,6 +153,10 @@ export function FixSplits() {
|
||||
amount. If not, these will be flagged below to allow you to easily
|
||||
locate and fix the amounts.
|
||||
</li>
|
||||
<li>
|
||||
Check if you have any budget transfers that erroneous contain a
|
||||
category, and remove the category.
|
||||
</li>
|
||||
</ul>
|
||||
</Trans>
|
||||
</Setting>
|
||||
@@ -30,9 +30,9 @@ import { BudgetTypeSettings } from './BudgetTypeSettings';
|
||||
import { EncryptionSettings } from './Encryption';
|
||||
import { ExperimentalFeatures } from './Experimental';
|
||||
import { ExportBudget } from './Export';
|
||||
import { FixSplits } from './FixSplits';
|
||||
import { FormatSettings } from './Format';
|
||||
import { LanguageSettings } from './LanguageSettings';
|
||||
import { RepairTransactions } from './RepairTransactions';
|
||||
import { ResetCache, ResetSync } from './Reset';
|
||||
import { ThemeSettings } from './Themes';
|
||||
import { AdvancedToggle, Setting } from './UI';
|
||||
@@ -209,7 +209,7 @@ export function Settings() {
|
||||
<AdvancedAbout />
|
||||
<ResetCache />
|
||||
<ResetSync />
|
||||
<FixSplits />
|
||||
<RepairTransactions />
|
||||
<ExperimentalFeatures />
|
||||
</AdvancedToggle>
|
||||
</View>
|
||||
|
||||
@@ -1445,7 +1445,9 @@ const Transaction = memo(function Transaction({
|
||||
: isOffBudget
|
||||
? 'Off budget'
|
||||
: isBudgetTransfer
|
||||
? 'Transfer'
|
||||
? categoryId != null
|
||||
? 'Needs Repair'
|
||||
: 'Transfer'
|
||||
: ''
|
||||
}
|
||||
valueStyle={valueStyle}
|
||||
|
||||
@@ -73,10 +73,30 @@ app.method('tools/fix-split-transactions', async () => {
|
||||
return subValue !== t.amount;
|
||||
});
|
||||
|
||||
// 5. Fix transfers that should not have categories
|
||||
const brokenTransfers = await db.all(`
|
||||
SELECT t1.id
|
||||
FROM v_transactions_internal t1
|
||||
JOIN accounts a1 ON t1.account = a1.id
|
||||
JOIN v_transactions_internal t2 ON t1.transfer_id = t2.id
|
||||
JOIN accounts a2 ON t2.account = a2.id
|
||||
WHERE a1.offbudget = a2.offbudget
|
||||
AND t1.category IS NOT NULL
|
||||
`);
|
||||
|
||||
await runMutator(async () => {
|
||||
const updated = brokenTransfers.map(row => ({
|
||||
id: row.id,
|
||||
category: null,
|
||||
}));
|
||||
await batchUpdateTransactions({ updated });
|
||||
});
|
||||
|
||||
return {
|
||||
numBlankPayees: blankPayeeRows.length,
|
||||
numCleared: clearedRows.length,
|
||||
numDeleted: deletedRows.length,
|
||||
numTransfersFixed: brokenTransfers.length,
|
||||
mismatchedSplits,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ export interface ToolsHandlers {
|
||||
numBlankPayees: number;
|
||||
numCleared: number;
|
||||
numDeleted: number;
|
||||
numTransfersFixed: number;
|
||||
mismatchedSplits: TransactionEntity[];
|
||||
}>;
|
||||
}
|
||||
|
||||
6
upcoming-release-notes/4216.md
Normal file
6
upcoming-release-notes/4216.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Enhancements
|
||||
authors: [youngcw, UnderKoen]
|
||||
---
|
||||
|
||||
Extend "fix splits" to also fix transfers that have categories and should not.
|
||||
Reference in New Issue
Block a user