Skip to content

Commit 0b3218e

Browse files
authored
stocklist v.3.0 done (#1092)
* stocklist v.3.0 done * fixed errors * fixed more errors * migration squash
1 parent deb34f4 commit 0b3218e

File tree

17 files changed

+1009
-820
lines changed

17 files changed

+1009
-820
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `quantityIn` on the `drinkitembatch` table. All the data in the column will be lost.
5+
- You are about to drop the column `quantityOut` on the `drinkitembatch` table. All the data in the column will be lost.
6+
- Added the required column `quantity_delta` to the `drinkitembatch` table without a default value. This is not possible if the table is not empty.
7+
8+
*/
9+
-- AlterTable
10+
ALTER TABLE "drinkitem" ADD COLUMN "quantity_available" INTEGER DEFAULT 0;
11+
12+
-- AlterTable
13+
ALTER TABLE "drinkitembatch" DROP COLUMN "quantityIn",
14+
DROP COLUMN "quantityOut",
15+
ADD COLUMN "quantity_delta" INTEGER NOT NULL;

src/database/prisma/schema.prisma

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -469,20 +469,20 @@ model DrinkItem {
469469
systembolagetID Int @map("systembolaget_id")
470470
bottleEmptyWeight Int? @map("bottle_empty_weight")
471471
bottleFullWeight Int? @map("bottle_full_weight")
472+
quantityAvailable Int? @default(0) @map("quantity_available")
472473
stockLists DrinkItemBatch[]
473474
474475
@@map("drinkitem")
475476
}
476477

477478
model DrinkItemBatch {
478-
id String @id() @default(dbgenerated("gen_random_uuid()")) @db.Uuid()
479-
drinkItemId String @map("drink_item_id") @db.Uuid()
480-
item DrinkItem @relation(fields: [drinkItemId], references: [id])
481-
quantityIn Int?
482-
quantityOut Int?
483-
user String
484-
date DateTime
485-
nrBottles Int?
479+
id String @id() @default(dbgenerated("gen_random_uuid()")) @db.Uuid()
480+
drinkItemId String @map("drink_item_id") @db.Uuid()
481+
item DrinkItem @relation(fields: [drinkItemId], references: [id])
482+
quantityDelta Int @map("quantity_delta")
483+
user String
484+
date DateTime
485+
nrBottles Int?
486486
487487
@@map("drinkitembatch")
488488
}

src/database/schema.zmodel

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ model DrinkItem {
552552
systembolagetID Int @map("systembolaget_id")
553553
bottleEmptyWeight Int? @map("bottle_empty_weight")
554554
bottleFullWeight Int? @map("bottle_full_weight")
555+
quantityAvailable Int? @map("quantity_available") @default(0)
555556

556557
stockLists DrinkItemBatch[]
557558

@@ -563,14 +564,13 @@ model DrinkItem {
563564
}
564565

565566
model DrinkItemBatch {
566-
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
567-
drinkItemId String @map("drink_item_id") @db.Uuid
568-
item DrinkItem @relation(fields: [drinkItemId], references: [id])
569-
quantityIn Int?
570-
quantityOut Int?
571-
user String
572-
date DateTime
573-
nrBottles Int?
567+
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
568+
drinkItemId String @map("drink_item_id") @db.Uuid
569+
item DrinkItem @relation(fields: [drinkItemId], references: [id])
570+
quantityDelta Int @map("quantity_delta")
571+
user String
572+
date DateTime
573+
nrBottles Int?
574574

575575
@@allow("read", true)
576576
@@allow("create", has(auth().policies, "drinkitembatch:create"))

src/database/seed/.snaplet/dataModel.json

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4040,6 +4040,20 @@
40404040
"isId": false,
40414041
"maxLength": null
40424042
},
4043+
{
4044+
"id": "public.drinkitem.quantity_available",
4045+
"name": "quantity_available",
4046+
"columnName": "quantity_available",
4047+
"type": "int4",
4048+
"isRequired": false,
4049+
"kind": "scalar",
4050+
"isList": false,
4051+
"isGenerated": false,
4052+
"sequence": false,
4053+
"hasDefaultValue": true,
4054+
"isId": false,
4055+
"maxLength": null
4056+
},
40434057
{
40444058
"name": "drinkitembatch",
40454059
"type": "drinkitembatch",
@@ -4098,34 +4112,6 @@
40984112
"isId": false,
40994113
"maxLength": null
41004114
},
4101-
{
4102-
"id": "public.drinkitembatch.quantityIn",
4103-
"name": "quantityIn",
4104-
"columnName": "quantityIn",
4105-
"type": "int4",
4106-
"isRequired": false,
4107-
"kind": "scalar",
4108-
"isList": false,
4109-
"isGenerated": false,
4110-
"sequence": false,
4111-
"hasDefaultValue": false,
4112-
"isId": false,
4113-
"maxLength": null
4114-
},
4115-
{
4116-
"id": "public.drinkitembatch.quantityOut",
4117-
"name": "quantityOut",
4118-
"columnName": "quantityOut",
4119-
"type": "int4",
4120-
"isRequired": false,
4121-
"kind": "scalar",
4122-
"isList": false,
4123-
"isGenerated": false,
4124-
"sequence": false,
4125-
"hasDefaultValue": false,
4126-
"isId": false,
4127-
"maxLength": null
4128-
},
41294115
{
41304116
"id": "public.drinkitembatch.user",
41314117
"name": "user",
@@ -4168,6 +4154,20 @@
41684154
"isId": false,
41694155
"maxLength": null
41704156
},
4157+
{
4158+
"id": "public.drinkitembatch.quantity_delta",
4159+
"name": "quantity_delta",
4160+
"columnName": "quantity_delta",
4161+
"type": "int4",
4162+
"isRequired": true,
4163+
"kind": "scalar",
4164+
"isList": false,
4165+
"isGenerated": false,
4166+
"sequence": false,
4167+
"hasDefaultValue": false,
4168+
"isId": false,
4169+
"maxLength": null
4170+
},
41714171
{
41724172
"name": "drinkitem",
41734173
"type": "drinkitem",

src/lib/utils/getTotalInventoryValue.ts

Lines changed: 0 additions & 51 deletions
This file was deleted.

src/lib/utils/stocklistUtils.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { ExtendedPrisma } from "$lib/server/extendedPrisma";
2+
import type { DrinkGroup, DrinkQuantityType } from "@prisma/client";
3+
4+
type StockRow = {
5+
quantityType: DrinkQuantityType;
6+
name: string;
7+
price: number;
8+
group: DrinkGroup;
9+
systembolagetId: number;
10+
bottleEmptyWeight: number | null;
11+
bottleFullWeight: number | null;
12+
};
13+
14+
export async function inventoryValue(prisma: ExtendedPrisma) {
15+
const items = await prisma.drinkItem.findMany({
16+
where: {
17+
quantityAvailable: { gt: 0 },
18+
},
19+
});
20+
21+
let value = 0;
22+
23+
for (const item of items) {
24+
if (item.quantityType === "COUNTS") {
25+
value += (item.price / 100) * item.quantityAvailable!;
26+
} else {
27+
const bottleWeight = item.bottleEmptyWeight!;
28+
const liquidWeight = item.quantityAvailable! - bottleWeight;
29+
const bottlePrice = item.price / 100;
30+
const fullBottleLiquidWeight = item.bottleFullWeight! - bottleWeight;
31+
value += (liquidWeight / fullBottleLiquidWeight) * bottlePrice;
32+
}
33+
}
34+
return value;
35+
}
36+
37+
export async function readCSV(prisma: ExtendedPrisma, file: File) {
38+
const text = await file.text();
39+
40+
const lines = text.split(/\r?\n/).filter((l) => l.trim() !== "");
41+
42+
const cell = (arr: string[], i: number) => (arr[i] ?? "").trim();
43+
44+
const toNumberOrNull = (v: string): number | null =>
45+
v === "" ? null : Number(v);
46+
47+
const rows: StockRow[] = lines.slice(1).map((line) => {
48+
const values = line.split(",");
49+
50+
return {
51+
quantityType: cell(values, 0) as DrinkQuantityType,
52+
name: cell(values, 1),
53+
price: Number(cell(values, 2)),
54+
group: cell(values, 3) as DrinkGroup,
55+
systembolagetId: Number(cell(values, 4)),
56+
bottleEmptyWeight: toNumberOrNull(cell(values, 5)),
57+
bottleFullWeight: toNumberOrNull(cell(values, 6)),
58+
};
59+
});
60+
61+
return rows;
62+
}
Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,47 @@
1-
import type { PageServerLoad } from "./$types";
2-
import { getTotalInventoryValue } from "$lib/utils/getTotalInventoryValue";
1+
import { inventoryValue, readCSV } from "$lib/utils/stocklistUtils";
2+
import { fail } from "sveltekit-superforms";
3+
import type { Actions, PageServerLoad } from "./$types";
34

45
export const load: PageServerLoad = async ({ locals }) => {
56
const { prisma } = locals;
7+
const drinkItems = await prisma.drinkItem.findMany({
8+
where: {
9+
quantityAvailable: { gt: 0 },
10+
},
11+
});
12+
const currentInventoryValue = await inventoryValue(prisma);
613

7-
const { totalInventoryValue, grouped } = await getTotalInventoryValue(prisma);
14+
return { currentInventoryValue, drinkItems };
15+
};
16+
17+
export const actions: Actions = {
18+
readFile: async ({ request, locals }) => {
19+
const prisma = locals.prisma;
20+
const form = await request.formData();
21+
const file = form.get("upload");
22+
23+
if (!(file instanceof File)) {
24+
return fail(400, { message: "No file uploaded" });
25+
}
26+
27+
const items = await readCSV(prisma, file);
828

9-
return { totalInventoryValue, grouped };
29+
for (const item of items) {
30+
await prisma.drinkItem.create({
31+
data: {
32+
name: item.name,
33+
price: item.price * 100,
34+
group: item.group,
35+
systembolagetID: item.systembolagetId,
36+
quantityType: item.quantityType,
37+
bottleEmptyWeight: item.bottleEmptyWeight,
38+
bottleFullWeight: item.bottleFullWeight,
39+
},
40+
});
41+
}
42+
return {
43+
success: true,
44+
message: `Produkter skapade`,
45+
};
46+
},
1047
};

0 commit comments

Comments
 (0)