From bb10e038c91a72b752b2f11824a677b93ddfc0ae Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 May 2021 19:03:49 +0200 Subject: also allow deleting individual refunds, tombstoned by their execution time --- .../src/operations/transactions.ts | 43 +++++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 02675adbd..02550a11e 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -42,7 +42,10 @@ import { getFundingPaytoUris } from "./reserves"; /** * Create an event ID from the type and the primary key for the event. */ -function makeEventId(type: TransactionType, ...args: string[]): string { +function makeEventId( + type: TransactionType | TombstoneTag, + ...args: string[] +): string { return type + ":" + args.map((x) => encodeURIComponent(x)).join(":"); } @@ -95,6 +98,7 @@ export async function getTransactions( Stores.planchets, Stores.recoupGroups, Stores.depositGroups, + Stores.tombstones, ], // Report withdrawals that are currently in progress. async (tx) => { @@ -282,7 +286,16 @@ export async function getTransactions( refundGroupKeys.add(groupKey); } - refundGroupKeys.forEach((groupKey: string) => { + for (const groupKey of refundGroupKeys.values()) { + const refundTombstoneId = makeEventId( + TombstoneTag.DeleteRefund, + pr.proposalId, + groupKey, + ); + const tombstone = await tx.get(Stores.tombstones, refundTombstoneId); + if (tombstone) { + continue; + } const refundTransactionId = makeEventId( TransactionType.Refund, pr.proposalId, @@ -326,7 +339,7 @@ export async function getTransactions( amountRaw: Amounts.stringify(amountRaw), pending: false, }); - }); + } }); tx.iter(Stores.tips).forEachAsync(async (tipRecord) => { @@ -374,6 +387,7 @@ export enum TombstoneTag { DeleteTip = "delete-tip", DeleteRefreshGroup = "delete-refresh-group", DeleteDepositGroup = "delete-deposit-group", + DeleteRefund = "delete-refund", } /** @@ -480,9 +494,26 @@ export async function deleteTransaction( }, ); } else if (type === TransactionType.Refund) { - // To delete refund transactions, the whole - // purchase should be deleted. - throw Error("refunds cannot be deleted"); + const proposalId = rest[0]; + const executionTimeStr = rest[1]; + + await ws.db.runWithWriteTransaction( + [Stores.proposals, Stores.purchases, Stores.tombstones], + async (tx) => { + const purchase = await tx.get(Stores.purchases, proposalId); + if (purchase) { + // This should just influence the history view, + // but won't delete any actual refund information. + await tx.put(Stores.tombstones, { + id: makeEventId( + TombstoneTag.DeleteRefund, + proposalId, + executionTimeStr, + ), + }); + } + }, + ); } else { throw Error(`can't delete a '${type}' transaction`); } -- cgit v1.2.3