Skip to content

Commit

Permalink
feat: submit multiple transactions from csv file
Browse files Browse the repository at this point in the history
  • Loading branch information
nikensss committed Apr 21, 2024
1 parent 31ea3af commit d1081ba
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
29 changes: 27 additions & 2 deletions src/app/dashboard/file/file-processing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '~
import { TransactionType } from '@prisma/client';
import { CheckSquareIcon, SquareIcon } from 'lucide-react';
import type { RouterOutputs } from '~/trpc/shared';
import currencySymbolMap from 'currency-symbol-map/map';
import { api } from '~/trpc/react.client';
import { useRouter } from 'next/navigation';
import { fromZonedTime } from 'date-fns-tz';

type Transaction = {
amount: number;
Expand All @@ -25,7 +27,10 @@ type Transaction = {
};

export function FileProcessing({ user }: { user: RouterOutputs['users']['get'] }) {
const router = useRouter();

const fileInput = useRef<HTMLInputElement>(null);
const [isLoading, setIsLoading] = useState(false);
const [stage, setStage] = useState<'select-file' | 'select-columns' | 'edit-rows'>('select-file'); // 'select-file' | 'select-columns
const [columns, setColumns] = useState<string[]>([]);
const [records, setRecords] = useState<Record<string, string | undefined>[]>([]);
Expand All @@ -37,6 +42,24 @@ export function FileProcessing({ user }: { user: RouterOutputs['users']['get'] }

const currencyFormatter = new Intl.NumberFormat('es-ES', { style: 'currency', currency: user.currency ?? 'EUR' });

const bulk = api.transactions.personal.bulk.useMutation({
onMutate: () => setIsLoading(true),
onSettled: () => setIsLoading(false),
onSuccess: () => router.push('/dashboard'),
});

function submit() {
const data = transactions.map((t) => ({
type: t.type,
amount: t.amount,
description: t.description,
tags: t.tags.split(',').map((tag) => tag.trim()),
date: user.timezone ? fromZonedTime(format(t.date, 'yyyy-MM-dd'), user.timezone) : t.date,
}));

bulk.mutate({ data });
}

return (
<>
<BlockTitle>From CSV file</BlockTitle>
Expand Down Expand Up @@ -250,7 +273,9 @@ export function FileProcessing({ user }: { user: RouterOutputs['users']['get'] }
))}
</TableBody>
</Table>
<Button className="mt-auto self-stretch">Save</Button>
<Button onClick={submit} disabled={isLoading} className="mt-auto self-stretch">
Save
</Button>
</>
) : null}
</BlockBody>
Expand Down
50 changes: 50 additions & 0 deletions src/server/api/routers/transactions/personal.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TransactionType } from '@prisma/client';
import { log } from 'next-axiom';
import { z } from 'zod';
import { toCents } from '~/lib/utils.client';
Expand Down Expand Up @@ -236,4 +237,53 @@ export const personalTransactionsRouter = createTRPCRouter({
return null;
}
}),

bulk: privateProcedure
.input(
z.object({
data: z.array(
z.object({
date: z.date(),
description: z.string(),
amount: z.number(),
type: z.nativeEnum(TransactionType),
tags: z.array(z.string()),
}),
),
}),
)
.mutation(async ({ ctx: { db, user }, input: { data } }) => {
for (const { date, amount, description, type, tags } of data) {
await db.tag.createMany({
data: tags.map((name) => ({ name, createdById: user.id })),
skipDuplicates: true,
});

const dbTags = await db.tag.findMany({
where: {
createdById: user.id,
name: { in: tags },
},
});

await db.personalTransaction.create({
data: {
user: { connect: { id: user.id } },
transaction: {
create: {
amount: toCents(amount),
date,
description,
type,
TransactionsTags: {
createMany: {
data: dbTags.map((tag) => ({ tagId: tag.id })),
},
},
},
},
},
});
}
}),
});

0 comments on commit d1081ba

Please sign in to comment.