Properly implement transaction deduplication

Using my superior HUMAN brain
Idiot ram stick
This commit is contained in:
2025-07-08 21:38:03 +02:00
parent 74dbaab169
commit 3820522f32
2 changed files with 28 additions and 44 deletions

View File

@@ -5,7 +5,7 @@ import { Textarea } from '@/components/ui/textarea';
import { Badge } from '@/components/ui/badge';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { parseTransactionLine, formatISK } from '@/utils/priceUtils';
import { parseTransactionLine, formatISK, PastedTransaction } from '@/utils/priceUtils';
import { IndTransactionRecordNoId, IndJobStatusOptions } from '@/lib/pbtypes';
import { IndJob } from '@/lib/types';
import { X } from 'lucide-react';
@@ -16,14 +16,9 @@ interface BatchTransactionFormProps {
jobs: IndJob[];
}
interface ParsedTransaction extends IndTransactionRecordNoId {
assignedJobId?: string;
isDuplicate?: boolean;
}
interface TransactionGroup {
itemName: string;
transactions: ParsedTransaction[];
transactions: PastedTransaction[];
totalQuantity: number;
totalValue: number;
}
@@ -59,13 +54,13 @@ const BatchTransactionForm: React.FC<BatchTransactionFormProps> = ({ onClose, on
return dateStr.replace('T', ' ');
};
const createTransactionKey = (parsed: ReturnType<typeof parseTransactionLine>): string => {
const createTransactionKey = (parsed: PastedTransaction): string => {
if (!parsed) return '';
const key = [
normalizeDate(parsed.date.toISOString()),
normalizeDate(parsed.date.toString()),
parsed.itemName,
parsed.quantity.toString(),
parsed.totalAmount.toString(),
parsed.totalPrice.toString(),
parsed.buyer,
parsed.location
].join('|');
@@ -87,33 +82,25 @@ const BatchTransactionForm: React.FC<BatchTransactionFormProps> = ({ onClose, on
const handlePaste = (value: string) => {
setPastedData(value);
const lines = value.trim().split('\n');
const pasteTransactionMap = new Map<string, ParsedTransaction>();
const pasteTransactionMap = new Map<string, PastedTransaction>();
// STEP 1: First combine all identical transactions within the pasted data
lines.forEach((line) => {
const parsed = parseTransactionLine(line);
const parsed: PastedTransaction | null = parseTransactionLine(line);
if (parsed) {
const transactionKey = createTransactionKey(parsed);
const transactionKey: string = createTransactionKey(parsed);
if (pasteTransactionMap.has(transactionKey)) {
// Merge with existing transaction in paste
const existing = pasteTransactionMap.get(transactionKey)!;
existing.quantity += parsed.quantity;
existing.totalPrice += Math.abs(parsed.totalAmount);
existing.totalPrice += Math.abs(parsed.totalPrice);
const newKey = createTransactionKey(existing);
pasteTransactionMap.set(newKey, existing);
pasteTransactionMap.delete(transactionKey); // Remove old key
} else {
// Add new transaction
const newTransaction: ParsedTransaction = {
date: parsed.date.toISOString(),
quantity: parsed.quantity,
itemName: parsed.itemName,
unitPrice: parsed.unitPrice,
totalPrice: Math.abs(parsed.totalAmount),
buyer: parsed.buyer,
location: parsed.location,
corporation: parsed.corporation,
wallet: parsed.wallet
};
pasteTransactionMap.set(transactionKey, newTransaction);
pasteTransactionMap.set(transactionKey, parsed);
}
}
});
@@ -124,6 +111,7 @@ const BatchTransactionForm: React.FC<BatchTransactionFormProps> = ({ onClose, on
const matchingJobId = findMatchingJob(transaction.itemName);
if (matchingJobId) {
relevantJobIds.add(matchingJobId);
transaction.assignedJobId = matchingJobId;
}
});
@@ -147,7 +135,7 @@ const BatchTransactionForm: React.FC<BatchTransactionFormProps> = ({ onClose, on
if (isDuplicate) {
duplicates++;
transaction.assignedJobId = undefined;
} else {
} else if (!!transaction.assignedJobId) {
transaction.assignedJobId = findMatchingJob(transaction.itemName);
}
});

View File

@@ -1,3 +1,4 @@
import { IndTransactionRecordNoId } from "@/lib/pbtypes";
export const parseISKAmount = (iskString: string): number => {
// Remove "ISK" and any extra whitespace
@@ -26,17 +27,12 @@ export const formatISK = (amount: number): string => {
return `${sign}${formatted} ISK`;
};
export const parseTransactionLine = (line: string): {
date: Date;
quantity: number;
itemName: string;
unitPrice: number;
totalAmount: number;
buyer?: string;
location?: string;
corporation?: string;
wallet?: string;
} | null => {
export type PastedTransaction = IndTransactionRecordNoId & {
assignedJobId?: string;
isDuplicate?: boolean;
}
export const parseTransactionLine = (line: string): PastedTransaction | null => {
try {
const parts = line.split('\t');
if (parts.length < 6) return null;
@@ -60,14 +56,14 @@ export const parseTransactionLine = (line: string): {
// Parse prices
const unitPrice = parseISKAmount(unitPriceStr);
const totalAmount = parseISKAmount(totalAmountStr);
const totalPrice = parseISKAmount(totalAmountStr);
return {
date,
date: date.toISOString(),
quantity,
itemName,
unitPrice,
totalAmount,
totalPrice,
buyer,
location,
corporation,